Diffstat (limited to 'core/launcher/transferserver.cpp') (more/less context) (show whitespace changes)
-rw-r--r-- | core/launcher/transferserver.cpp | 207 |
1 files changed, 153 insertions, 54 deletions
diff --git a/core/launcher/transferserver.cpp b/core/launcher/transferserver.cpp index 7294f9c..a6dab07 100644 --- a/core/launcher/transferserver.cpp +++ b/core/launcher/transferserver.cpp @@ -1,5 +1,5 @@ /********************************************************************** -** Copyright (C) 2000 Trolltech AS. All rights reserved. +** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ** -** This file is part of Qtopia Environment. +** This file is part of the Qtopia Environment. ** @@ -24,2 +24,9 @@ #include <stdlib.h> +#include <time.h> +#include <shadow.h> + +extern "C" { +#include <uuid/uuid.h> +#define UUID_H_INCLUDED +} @@ -39,4 +46,10 @@ #include <qpe/process.h> +#include <qpe/global.h> #include <qpe/config.h> +#include <qpe/contact.h> +#include <qpe/quuid.h> +#include <qpe/version.h> +#ifdef QWS #include <qpe/qcopenvelope_qws.h> +#endif @@ -65,3 +78,36 @@ void TransferServer::newConnection( int socket ) -bool accessAuthorized(QHostAddress peeraddress) +QString SyncAuthentication::serverId() +{ + Config cfg("Security"); + cfg.setGroup("Sync"); + QString r=cfg.readEntry("serverid"); + if ( r.isEmpty() ) { + uuid_t uuid; + uuid_generate( uuid ); + cfg.writeEntry("serverid",(r = QUuid( uuid ).toString())); + } + return r; +} + +QString SyncAuthentication::ownerName() +{ + QString vfilename = Global::applicationFileName("addressbook", + "businesscard.vcf"); + if (QFile::exists(vfilename)) { + Contact c; + c = Contact::readVCard( vfilename )[0]; + return c.fullName(); + } + + return ""; +} + +QString SyncAuthentication::loginName() +{ + struct passwd *pw; + pw = getpwuid( geteuid() ); + return QString::fromLocal8Bit( pw->pw_name ); +} + +int SyncAuthentication::isAuthorized(QHostAddress peeraddress) { @@ -69,16 +115,89 @@ bool accessAuthorized(QHostAddress peeraddress) cfg.setGroup("Sync"); - uint auth_peer = cfg.readNumEntry("auth_peer",0xc0a80100); + QString allowedstr = cfg.readEntry("auth_peer","192.168.1.0"); + QHostAddress allowed; + allowed.setAddress(allowedstr); + uint auth_peer = allowed.ip4Addr(); uint auth_peer_bits = cfg.readNumEntry("auth_peer_bits",24); - bool ok = (peeraddress.ip4Addr() & (((1<<auth_peer_bits)-1)<<(32-auth_peer_bits))) - == auth_peer; - /* Allows denial-of-service attack. - if ( !ok ) { - QMessageBox::warning(0,tr("Security"), - tr("<p>An attempt to access this device from %1 has been denied.") - .arg(peeraddress.toString())); + uint mask = auth_peer_bits >= 32 // shifting by 32 is not defined + ? 0xffffffff : (((1<<auth_peer_bits)-1)<<(32-auth_peer_bits)); + return (peeraddress.ip4Addr() & mask) == auth_peer; +} + +bool SyncAuthentication::checkUser( const QString& user ) +{ + if ( user.isEmpty() ) return FALSE; + QString euser = loginName(); + return user == euser; +} + +bool SyncAuthentication::checkPassword( const QString& password ) +{ +#ifdef ALLOW_UNIX_USER_FTP + // First, check system password... + + struct passwd *pw = 0; + struct spwd *spw = 0; + + pw = getpwuid( geteuid() ); + spw = getspnam( pw->pw_name ); + + QString cpwd = QString::fromLocal8Bit( pw->pw_passwd ); + if ( cpwd == "x" && spw ) + cpwd = QString::fromLocal8Bit( spw->sp_pwdp ); + + // Note: some systems use more than crypt for passwords. + QString cpassword = QString::fromLocal8Bit( crypt( password.local8Bit(), cpwd.local8Bit() ) ); + if ( cpwd == cpassword ) + return TRUE; +#endif + + static int lastdenial=0; + static int denials=0; + int now = time(0); + + // Detect old Qtopia Desktop (no password) + if ( password.isEmpty() ) { + if ( denials < 1 || now > lastdenial+600 ) { + QMessageBox::warning( 0,tr("Sync Connection"), + tr("<p>An unauthorized system is requesting access to this device." + "<p>If you are using a version of Qtopia Desktop older than 1.5.1, " + "please upgrade."), + tr("Deny") ); + denials++; + lastdenial=now; } - */ - return ok; + return FALSE; } + // Second, check sync password... + if ( password.left(6) == "Qtopia" ) { + QString cpassword = QString::fromLocal8Bit( crypt( password.mid(8).local8Bit(), "qp" ) ); + Config cfg("Security"); + cfg.setGroup("Sync"); + QString pwds = cfg.readEntry("Passwords"); + if ( QStringList::split(QChar(' '),pwds).contains(cpassword) ) + return TRUE; + + // Unrecognized system. Be careful... + + if ( (denials > 2 && now < lastdenial+600) + || QMessageBox::warning(0,tr("Sync Connection"), + tr("<p>An unrecognized system is requesting access to this device." + "<p>If you have just initiated a Sync for the first time, this is normal."), + tr("Allow"),tr("Deny"))==1 ) + { + denials++; + lastdenial=now; + return FALSE; + } else { + denials=0; + cfg.writeEntry("Passwords",pwds+" "+cpassword); + return TRUE; + } + } + + return FALSE; +} + + ServerPI::ServerPI( int socket, QObject *parent, const char* name ) @@ -94,3 +213,3 @@ ServerPI::ServerPI( int socket, QObject *parent, const char* name ) #ifndef INSECURE - if ( !accessAuthorized(peeraddress) ) { + if ( !SyncAuthentication::isAuthorized(peeraddress) ) { state = Forbidden; @@ -107,3 +226,3 @@ ServerPI::ServerPI( int socket, QObject *parent, const char* name ) - send( "220 Qtopia transfer service ready!" ); + send( "220 Qtopia " QPE_VERSION " FTP Server" ); state = Wait_USER; @@ -153,33 +272,2 @@ void ServerPI::read() -bool ServerPI::checkUser( const QString& user ) -{ - if ( user.isEmpty() ) return FALSE; - - struct passwd *pw; - pw = getpwuid( geteuid() ); - QString euser = QString::fromLocal8Bit( pw->pw_name ); - return user == euser; -} - -bool ServerPI::checkPassword( const QString& /* password */ ) -{ - // ### HACK for testing on local host - return true; - - /* - struct passwd *pw = 0; - struct spwd *spw = 0; - - pw = getpwuid( geteuid() ); - spw = getspnam( pw->pw_name ); - - QString cpwd = QString::fromLocal8Bit( pw->pw_passwd ); - if ( cpwd == "x" && spw ) - cpwd = QString::fromLocal8Bit( spw->sp_pwdp ); - - QString cpassword = QString::fromLocal8Bit( crypt( password.local8Bit(), cpwd.local8Bit() ) ); - return cpwd == cpassword; -*/ -} - bool ServerPI::checkReadFile( const QString& file ) @@ -256,3 +344,3 @@ void ServerPI::process( const QString& message ) - if ( cmd != "USER" || msg.count() < 2 || !checkUser( arg ) ) { + if ( cmd != "USER" || msg.count() < 2 || !SyncAuthentication::checkUser( arg ) ) { send( "530 Please login with USER and PASS" ); @@ -268,4 +356,3 @@ void ServerPI::process( const QString& message ) - if ( cmd != "PASS" || !checkPassword( arg ) ) { - //if ( cmd != "PASS" || msg.count() < 2 || !checkPassword( arg ) ) { + if ( cmd != "PASS" || !SyncAuthentication::checkPassword( arg ) ) { send( "530 Please login with USER and PASS" ); @@ -456,5 +543,7 @@ void ServerPI::process( const QString& message ) QFile file( absFilePath( args ) ) ; - if ( file.remove() ) + if ( file.remove() ) { send( "250 Requested file action okay, completed" ); - else + QCopEnvelope e("QPE/System", "linkChanged(QString)" ); + e << file.name(); + } else { send( "550 Requested action not taken" ); @@ -462,2 +551,3 @@ void ServerPI::process( const QString& message ) } + } @@ -636,5 +726,12 @@ void ServerPI::dtpCompleted() { - dtp->close(); - waitsocket = 0; send( "226 Closing data connection, file transfer successful" ); + if ( dtp->dtpMode() == ServerDTP::RetrieveFile ) { + QString fn = dtp->fileName(); + if ( fn.right(8)==".desktop" && fn.find("/Documents/")>=0 ) { + QCopEnvelope e("QPE/System", "linkChanged(QString)" ); + e << fn; + } + } + waitsocket = 0; + dtp->close(); } @@ -854,3 +951,3 @@ void ServerPI::timerEvent( QTimerEvent * ) -ServerDTP::ServerDTP( QObject *parent, const char* name ) +ServerDTP::ServerDTP( QObject *parent = 0, const char* name = 0) : QSocket( parent, name ), mode( Idle ), createTargzProc( 0 ), @@ -893,4 +990,6 @@ void ServerDTP::extractTarDone() qDebug("extract done"); +#ifndef QT_NO_COP QCopEnvelope e( "QPE/Desktop", "restoreDone(QString)" ); e << file.name(); +#endif } |