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>
41using TDEIO::MetaData;
42using TDEWallet::Wallet;
43
44#include <climits>
45
46namespace 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