00001
00026 #ifdef HAVE_CONFIG_H
00027 #include <config.h>
00028 #endif
00029
00030 #include "networkaccount.h"
00031 #include "accountmanager.h"
00032 #include "kmkernel.h"
00033 #include "globalsettings.h"
00034
00035 #include <kconfig.h>
00036 #include <kio/global.h>
00037 #include <klocale.h>
00038 #include <kmessagebox.h>
00039 #include <kdebug.h>
00040 #include <kwallet.h>
00041 using KIO::MetaData;
00042 using KWallet::Wallet;
00043
00044 #include <climits>
00045
00046 namespace KMail {
00047
00048
00049
00050 static QMap<QString, int> s_serverConnections;
00051
00052 NetworkAccount::NetworkAccount( AccountManager * parent, const QString & name, uint id )
00053 : KMAccount( parent, name, id ),
00054 mSlave( 0 ),
00055 mAuth( "*" ),
00056 mPort( 0 ),
00057 mStorePasswd( false ),
00058 mUseSSL( false ),
00059 mUseTLS( false ),
00060 mAskAgain( false ),
00061 mPasswdDirty( false ),
00062 mStorePasswdInConfig( false )
00063 {
00064
00065 }
00066
00067 NetworkAccount::~NetworkAccount() {
00068
00069 }
00070
00071 void NetworkAccount::init() {
00072 KMAccount::init();
00073
00074 mSieveConfig = SieveConfig();
00075 mLogin = QString::null;
00076 mPasswd = QString::null;
00077 mAuth = "*";
00078 mHost = QString::null;
00079 mPort = defaultPort();
00080 mStorePasswd = false;
00081 mUseSSL = false;
00082 mUseTLS = false;
00083 mAskAgain = false;
00084 }
00085
00086
00087
00088
00089
00090
00091
00092 void NetworkAccount::setLogin( const QString & login ) {
00093 mLogin = login;
00094 }
00095
00096 QString NetworkAccount::passwd() const {
00097 if ( storePasswd() && mPasswd.isEmpty() )
00098 mOwner->readPasswords();
00099 return decryptStr( mPasswd );
00100 }
00101
00102 void NetworkAccount::setPasswd( const QString & passwd, bool storeInConfig ) {
00103 if ( mPasswd != encryptStr( passwd ) ) {
00104 mPasswd = encryptStr( passwd );
00105 mPasswdDirty = true;
00106 }
00107 setStorePasswd( storeInConfig );
00108 }
00109
00110 void NetworkAccount::clearPasswd() {
00111 setPasswd( "", false );
00112 }
00113
00114 void NetworkAccount::setAuth( const QString & auth ) {
00115 mAuth = auth;
00116 }
00117
00118 void NetworkAccount::setStorePasswd( bool store ) {
00119 if( mStorePasswd != store && store )
00120 mPasswdDirty = true;
00121 mStorePasswd = store;
00122 }
00123
00124 void NetworkAccount::setHost( const QString & host ) {
00125 mHost = host;
00126 }
00127
00128 void NetworkAccount::setPort( unsigned short int port ) {
00129 mPort = port;
00130 }
00131
00132 void NetworkAccount::setUseSSL( bool use ) {
00133 mUseSSL = use;
00134 }
00135
00136 void NetworkAccount::setUseTLS( bool use ) {
00137 mUseTLS = use;
00138 }
00139
00140 void NetworkAccount::setSieveConfig( const SieveConfig & config ) {
00141 mSieveConfig = config;
00142 }
00143
00144
00145
00146
00147
00148
00149
00150 void NetworkAccount::readConfig( KConfig & config ) {
00151 KMAccount::readConfig( config );
00152
00153 setLogin( config.readEntry( "login" ) );
00154
00155 if ( config.readNumEntry( "store-passwd", false ) ) {
00156 mStorePasswd = true;
00157 QString encpasswd = config.readEntry( "pass" );
00158 if ( encpasswd.isEmpty() ) {
00159 encpasswd = config.readEntry( "passwd" );
00160 if ( !encpasswd.isEmpty() ) encpasswd = importPassword( encpasswd );
00161 }
00162
00163 if ( !encpasswd.isEmpty() ) {
00164 setPasswd( decryptStr( encpasswd ), true );
00165
00166 if ( Wallet::isEnabled() ) {
00167 config.deleteEntry( "pass" );
00168 config.deleteEntry( "passwd" );
00169 mPasswdDirty = true;
00170 mStorePasswdInConfig = false;
00171 } else {
00172 mPasswdDirty = false;
00173 mStorePasswdInConfig = true;
00174 }
00175 } else {
00176
00177 if ( Wallet::isOpen( Wallet::NetworkWallet() ) )
00178 readPassword();
00179 }
00180
00181 } else {
00182 setPasswd( "", false );
00183 }
00184
00185 setHost( config.readEntry( "host" ) );
00186
00187 unsigned int port = config.readUnsignedNumEntry( "port", defaultPort() );
00188 if ( port > USHRT_MAX ) port = defaultPort();
00189 setPort( port );
00190
00191 setAuth( config.readEntry( "auth", "*" ) );
00192 setUseSSL( config.readBoolEntry( "use-ssl", false ) );
00193 setUseTLS( config.readBoolEntry( "use-tls", false ) );
00194
00195 mSieveConfig.readConfig( config );
00196 }
00197
00198 void NetworkAccount::writeConfig( KConfig & config ) {
00199 KMAccount::writeConfig( config );
00200
00201 config.writeEntry( "login", login() );
00202 config.writeEntry( "store-passwd", storePasswd() );
00203
00204 if ( storePasswd() ) {
00205
00206 bool passwdStored = false;
00207 if ( mPasswdDirty ) {
00208 Wallet *wallet = kmkernel->wallet();
00209 if ( wallet && wallet->writePassword( "account-" + QString::number(mId), passwd() ) == 0 ) {
00210 passwdStored = true;
00211 mPasswdDirty = false;
00212 mStorePasswdInConfig = false;
00213 }
00214 } else {
00215 passwdStored = !mStorePasswdInConfig;
00216 }
00217
00218
00219 if ( !passwdStored && ( mStorePasswdInConfig || KMessageBox::warningYesNo( 0,
00220 i18n("KWallet is not available. It is strongly recommended to use "
00221 "KWallet for managing your passwords.\n"
00222 "However, KMail can store the password in its configuration "
00223 "file instead. The password is stored in an obfuscated format, "
00224 "but should not be considered secure from decryption efforts "
00225 "if access to the configuration file is obtained.\n"
00226 "Do you want to store the password for account '%1' in the "
00227 "configuration file?").arg( name() ),
00228 i18n("KWallet Not Available"),
00229 KGuiItem( i18n("Store Password") ),
00230 KGuiItem( i18n("Do Not Store Password") ) )
00231 == KMessageBox::Yes ) ) {
00232 config.writeEntry( "pass", encryptStr( passwd() ) );
00233 mStorePasswdInConfig = true;
00234 }
00235 }
00236
00237
00238 if (!storePasswd() && !Wallet::keyDoesNotExist(
00239 Wallet::NetworkWallet(), "kmail", "account-" + QString::number(mId))) {
00240 Wallet *wallet = kmkernel->wallet();
00241 if (wallet)
00242 wallet->removeEntry( "account-" + QString::number(mId) );
00243 }
00244
00245 config.writeEntry( "host", host() );
00246 config.writeEntry( "port", static_cast<unsigned int>( port() ) );
00247 config.writeEntry( "auth", auth() );
00248 config.writeEntry( "use-ssl", useSSL() );
00249 config.writeEntry( "use-tls", useTLS() );
00250
00251 mSieveConfig.writeConfig( config );
00252 }
00253
00254
00255
00256
00257
00258
00259
00260 KURL NetworkAccount::getUrl() const {
00261 KURL url;
00262 url.setProtocol( protocol() );
00263 url.setUser( login() );
00264 url.setPass( passwd() );
00265 url.setHost( host() );
00266 url.setPort( port() );
00267 return url;
00268 }
00269
00270 MetaData NetworkAccount::slaveConfig() const {
00271 MetaData m;
00272 m.insert( "tls", useTLS() ? "on" : "off" );
00273 return m;
00274 }
00275
00276 void NetworkAccount::pseudoAssign( const KMAccount * a ) {
00277 KMAccount::pseudoAssign( a );
00278
00279 const NetworkAccount * n = dynamic_cast<const NetworkAccount*>( a );
00280 if ( !n ) return;
00281
00282 setLogin( n->login() );
00283 setPasswd( n->passwd(), n->storePasswd() );
00284 setHost( n->host() );
00285 setPort( n->port() );
00286 setAuth( n->auth() );
00287 setUseSSL( n->useSSL() );
00288 setUseTLS( n->useTLS() );
00289 setSieveConfig( n->sieveConfig() );
00290 }
00291
00292 void NetworkAccount::readPassword() {
00293 if ( !storePasswd() )
00294 return;
00295
00296
00297
00298 if ( Wallet::isOpen( Wallet::NetworkWallet() ) )
00299 {
00300 Wallet *wallet = kmkernel->wallet();
00301 if (!wallet || !wallet->hasEntry( "account-" + QString::number(mId) ) )
00302 return;
00303 }
00304 else
00305 {
00306 if (Wallet::keyDoesNotExist( Wallet::NetworkWallet(), "kmail", "account-" + QString::number(mId) ) )
00307 return;
00308 }
00309
00310 if ( kmkernel->wallet() ) {
00311 QString passwd;
00312 kmkernel->wallet()->readPassword( "account-" + QString::number(mId), passwd );
00313 setPasswd( passwd, true );
00314 mPasswdDirty = false;
00315 }
00316 }
00317
00318 void NetworkAccount::setCheckingMail( bool checking )
00319 {
00320 mCheckingMail = checking;
00321 if ( host().isEmpty() )
00322 return;
00323 if ( checking ) {
00324 if ( s_serverConnections.find( host() ) != s_serverConnections.end() )
00325 s_serverConnections[host()] += 1;
00326 else
00327 s_serverConnections[host()] = 1;
00328 kdDebug(5006) << "check mail started - connections for host "
00329 << host() << " now is "
00330 << s_serverConnections[host()] << endl;
00331 } else {
00332 if ( s_serverConnections.find( host() ) != s_serverConnections.end() &&
00333 s_serverConnections[host()] > 0 ) {
00334 s_serverConnections[host()] -= 1;
00335 kdDebug(5006) << "connections to server " << host()
00336 << " now " << s_serverConnections[host()] << endl;
00337 }
00338 }
00339 }
00340
00341 bool NetworkAccount::mailCheckCanProceed() const
00342 {
00343 bool offlineMode = KMKernel::isOffline();
00344
00345 kdDebug(5006) << "for host " << host()
00346 << " current connections="
00347 << (s_serverConnections.find(host())==s_serverConnections.end() ? 0 : s_serverConnections[host()])
00348 << " and limit is " << GlobalSettings::self()->maxConnectionsPerHost()
00349 << endl;
00350 bool connectionLimitForHostReached = !host().isEmpty()
00351 && GlobalSettings::self()->maxConnectionsPerHost() > 0
00352 && s_serverConnections.find( host() ) != s_serverConnections.end()
00353 && s_serverConnections[host()] >= GlobalSettings::self()->maxConnectionsPerHost();
00354 kdDebug(5006) << "connection limit reached: "
00355 << connectionLimitForHostReached << endl;
00356
00357 return ( !connectionLimitForHostReached && !offlineMode );
00358 }
00359
00360 void NetworkAccount::resetConnectionList( NetworkAccount* acct )
00361 {
00362 s_serverConnections[ acct->host() ] = 0;
00363 }
00364
00365 }
00366
00367 #include "networkaccount.moc"