kmail

networkaccount.cpp
1 /*
2  * networkaccount.cpp
3  *
4  * Copyright (c) 2000-2002 Michael Haeckel <haeckel@kde.org>
5  * Copyright (c) 2002 Marc Mutz <mutz@kde.org>
6  *
7  * This file is based on work on pop3 and imap account implementations
8  * by Don Sanders <sanders@kde.org> and Michael Haeckel <haeckel@kde.org>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; version 2 of the License
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22  */
23 
24 
25 
26 #ifdef HAVE_CONFIG_H
27 #include <config.h>
28 #endif
29 
30 #include "networkaccount.h"
31 #include "accountmanager.h"
32 #include "kmkernel.h"
33 #include "globalsettings.h"
34 
35 #include <tdeconfig.h>
36 #include <tdeio/global.h>
37 #include <tdelocale.h>
38 #include <tdemessagebox.h>
39 #include <kdebug.h>
40 #include <tdewallet.h>
41 using TDEIO::MetaData;
42 using TDEWallet::Wallet;
43 
44 #include <climits>
45 
46 namespace KMail {
47 
48 
49  // for restricting number of concurrent connections to the same server
50  static TQMap<TQString, int> s_serverConnections;
51 
52  NetworkAccount::NetworkAccount( AccountManager * parent, const TQString & name, uint id )
53  : KMAccount( parent, name, id ),
54  mSlave( 0 ),
55  mAuth( "*" ),
56  mPort( 0 ),
57  mStorePasswd( false ),
58  mUseSSL( false ),
59  mUseTLS( false ),
60  mAskAgain( false ),
61  mPasswdDirty( false ),
62  mStorePasswdInConfig( false )
63  {
64 
65  }
66 
67  NetworkAccount::~NetworkAccount() {
68 
69  }
70 
71  void NetworkAccount::init() {
72  KMAccount::init();
73 
74  mSieveConfig = SieveConfig();
75  mLogin = TQString();
76  mPasswd = TQString();
77  mAuth = "*";
78  mHost = TQString();
79  mPort = defaultPort();
80  mStorePasswd = false;
81  mUseSSL = false;
82  mUseTLS = false;
83  mAskAgain = false;
84  }
85 
86  //
87  //
88  // Getters and Setters
89  //
90  //
91 
92  void NetworkAccount::setLogin( const TQString & login ) {
93  mLogin = login;
94  }
95 
96  TQString NetworkAccount::passwd() const {
97  if ( storePasswd() && mPasswd.isEmpty() )
98  mOwner->readPasswords();
99  return decryptStr( mPasswd );
100  }
101 
102  void NetworkAccount::setPasswd( const TQString & passwd, bool storeInConfig ) {
103  if ( mPasswd != encryptStr( passwd ) ) {
104  mPasswd = encryptStr( passwd );
105  mPasswdDirty = true;
106  }
107  setStorePasswd( storeInConfig );
108  }
109 
110  void NetworkAccount::clearPasswd() {
111  setPasswd( "", false );
112  }
113 
114  void NetworkAccount::setAuth( const TQString & auth ) {
115  mAuth = auth;
116  }
117 
118  void NetworkAccount::setStorePasswd( bool store ) {
119  if( mStorePasswd != store && store )
120  mPasswdDirty = true;
121  mStorePasswd = store;
122  }
123 
124  void NetworkAccount::setHost( const TQString & host ) {
125  mHost = host;
126  }
127 
128  void NetworkAccount::setPort( unsigned short int port ) {
129  mPort = port;
130  }
131 
132  void NetworkAccount::setUseSSL( bool use ) {
133  mUseSSL = use;
134  }
135 
136  void NetworkAccount::setUseTLS( bool use ) {
137  mUseTLS = use;
138  }
139 
140  void NetworkAccount::setSieveConfig( const SieveConfig & config ) {
141  mSieveConfig = config;
142  }
143 
144  //
145  //
146  // read/write config
147  //
148  //
149 
150  void NetworkAccount::readConfig( /*const*/ TDEConfig/*Base*/ & config ) {
151  KMAccount::readConfig( config );
152 
153  setLogin( config.readEntry( "login" ) );
154 
155  if ( config.readNumEntry( "store-passwd", false ) ) { // ### s/Num/Bool/
156  mStorePasswd = true;
157  TQString encpasswd = config.readEntry( "pass" );
158  if ( encpasswd.isEmpty() ) {
159  encpasswd = config.readEntry( "passwd" );
160  if ( !encpasswd.isEmpty() ) encpasswd = importPassword( encpasswd );
161  }
162 
163  if ( !encpasswd.isEmpty() ) {
164  setPasswd( decryptStr( encpasswd ), true );
165  // migrate to TDEWallet if available
166  if ( Wallet::isEnabled() ) {
167  config.deleteEntry( "pass" );
168  config.deleteEntry( "passwd" );
169  mPasswdDirty = true;
170  mStorePasswdInConfig = false;
171  } else {
172  mPasswdDirty = false; // set by setPasswd() on first read
173  mStorePasswdInConfig = true;
174  }
175  } else {
176  // read password if wallet is already open, otherwise defer to on-demand loading
177  if ( Wallet::isOpen( Wallet::NetworkWallet() ) )
178  readPassword();
179  }
180 
181  } else {
182  setPasswd( "", false );
183  }
184 
185  setHost( config.readEntry( "host" ) );
186 
187  unsigned int port = config.readUnsignedNumEntry( "port", defaultPort() );
188  if ( port > USHRT_MAX ) port = defaultPort();
189  setPort( port );
190 
191  setAuth( config.readEntry( "auth", "*" ) );
192  setUseSSL( config.readBoolEntry( "use-ssl", false ) );
193  setUseTLS( config.readBoolEntry( "use-tls", false ) );
194 
195  mSieveConfig.readConfig( config );
196  }
197 
198  void NetworkAccount::writeConfig( TDEConfig/*Base*/ & config ) /*const*/ {
199  KMAccount::writeConfig( config );
200 
201  config.writeEntry( "login", login() );
202  config.writeEntry( "store-passwd", storePasswd() );
203 
204  if ( storePasswd() ) {
205  // write password to the wallet if possbile and necessary
206  bool passwdStored = false;
207  if ( mPasswdDirty ) {
208  Wallet *wallet = kmkernel->wallet();
209  if ( wallet && wallet->writePassword( "account-" + TQString::number(mId), passwd() ) == 0 ) {
210  passwdStored = true;
211  mPasswdDirty = false;
212  mStorePasswdInConfig = false;
213  }
214  } else {
215  passwdStored = !mStorePasswdInConfig; // already in the wallet
216  }
217  // if wallet is not available, write to config file, since the account
218  // manager deletes this group, we need to write it always
219  if ( !passwdStored && ( mStorePasswdInConfig || KMessageBox::warningYesNo( 0,
220  i18n("TDEWallet is not available. It is strongly recommended to use "
221  "TDEWallet for managing your passwords.\n"
222  "However, KMail can store the password in its configuration "
223  "file instead. The password is stored in an obfuscated format, "
224  "but should not be considered secure from decryption efforts "
225  "if access to the configuration file is obtained.\n"
226  "Do you want to store the password for account '%1' in the "
227  "configuration file?").arg( name() ),
228  i18n("TDEWallet Not Available"),
229  KGuiItem( i18n("Store Password") ),
230  KGuiItem( i18n("Do Not Store Password") ) )
231  == KMessageBox::Yes ) ) {
232  config.writeEntry( "pass", encryptStr( passwd() ) );
233  mStorePasswdInConfig = true;
234  }
235  }
236 
237  // delete password from the wallet if password storage is disabled
238  if (!storePasswd() && !Wallet::keyDoesNotExist(
239  Wallet::NetworkWallet(), "kmail", "account-" + TQString::number(mId))) {
240  Wallet *wallet = kmkernel->wallet();
241  if (wallet)
242  wallet->removeEntry( "account-" + TQString::number(mId) );
243  }
244 
245  config.writeEntry( "host", host() );
246  config.writeEntry( "port", static_cast<unsigned int>( port() ) );
247  config.writeEntry( "auth", auth() );
248  config.writeEntry( "use-ssl", useSSL() );
249  config.writeEntry( "use-tls", useTLS() );
250 
251  mSieveConfig.writeConfig( config );
252  }
253 
254  //
255  //
256  // Network processing
257  //
258  //
259 
260  KURL NetworkAccount::getUrl() const {
261  KURL url;
262  url.setProtocol( protocol() );
263  url.setUser( login() );
264  url.setPass( passwd() );
265  url.setHost( host() );
266  url.setPort( port() );
267  return url;
268  }
269 
270  MetaData NetworkAccount::slaveConfig() const {
271  MetaData m;
272  m.insert( "tls", useTLS() ? "on" : "off" );
273  return m;
274  }
275 
276  void NetworkAccount::pseudoAssign( const KMAccount * a ) {
277  KMAccount::pseudoAssign( a );
278 
279  const NetworkAccount * n = dynamic_cast<const NetworkAccount*>( a );
280  if ( !n ) return;
281 
282  setLogin( n->login() );
283  setPasswd( n->passwd(), n->storePasswd() );
284  setHost( n->host() );
285  setPort( n->port() );
286  setAuth( n->auth() );
287  setUseSSL( n->useSSL() );
288  setUseTLS( n->useTLS() );
289  setSieveConfig( n->sieveConfig() );
290  }
291 
292  void NetworkAccount::readPassword() {
293  if ( !storePasswd() )
294  return;
295 
296  // ### workaround for broken Wallet::keyDoesNotExist() which returns wrong
297  // results for new entries without closing and reopening the wallet
298  if ( Wallet::isOpen( Wallet::NetworkWallet() ) )
299  {
300  Wallet *wallet = kmkernel->wallet();
301  if (!wallet || !wallet->hasEntry( "account-" + TQString::number(mId) ) )
302  return;
303  }
304  else
305  {
306  if (Wallet::keyDoesNotExist( Wallet::NetworkWallet(), "kmail", "account-" + TQString::number(mId) ) )
307  return;
308  }
309 
310  if ( kmkernel->wallet() ) {
311  TQString passwd;
312  kmkernel->wallet()->readPassword( "account-" + TQString::number(mId), passwd );
313  setPasswd( passwd, true );
314  mPasswdDirty = false;
315  }
316  }
317 
318  void NetworkAccount::setCheckingMail( bool checking )
319  {
320  mCheckingMail = checking;
321  if ( host().isEmpty() )
322  return;
323  if ( checking ) {
324  if ( s_serverConnections.find( host() ) != s_serverConnections.end() )
325  s_serverConnections[host()] += 1;
326  else
327  s_serverConnections[host()] = 1;
328  kdDebug(5006) << "check mail started - connections for host "
329  << host() << " now is "
330  << s_serverConnections[host()] << endl;
331  } else {
332  if ( s_serverConnections.find( host() ) != s_serverConnections.end() &&
333  s_serverConnections[host()] > 0 ) {
334  s_serverConnections[host()] -= 1;
335  kdDebug(5006) << "connections to server " << host()
336  << " now " << s_serverConnections[host()] << endl;
337  }
338  }
339 }
340 
341  bool NetworkAccount::mailCheckCanProceed() const
342  {
343  bool offlineMode = KMKernel::isOffline();
344 
345  kdDebug(5006) << "for host " << host()
346  << " current connections="
347  << (s_serverConnections.find(host())==s_serverConnections.end() ? 0 : s_serverConnections[host()])
348  << " and limit is " << GlobalSettings::self()->maxConnectionsPerHost()
349  << endl;
350  bool connectionLimitForHostReached = !host().isEmpty()
351  && GlobalSettings::self()->maxConnectionsPerHost() > 0
352  && s_serverConnections.find( host() ) != s_serverConnections.end()
353  && s_serverConnections[host()] >= GlobalSettings::self()->maxConnectionsPerHost();
354  kdDebug(5006) << "connection limit reached: "
355  << connectionLimitForHostReached << endl;
356 
357  return ( !connectionLimitForHostReached && !offlineMode );
358  }
359 
360  void NetworkAccount::resetConnectionList( NetworkAccount* acct )
361  {
362  s_serverConnections[ acct->host() ] = 0;
363  }
364 
365 } // namespace KMail
366 
367 #include "networkaccount.moc"
static bool isOffline()
Checks if the current network state is online or offline.
Definition: kmkernel.cpp:1278
The account manager is responsible for creating accounts of various types via the factory method crea...
folderdiaquotatab.h
Definition: aboutdata.cpp:40