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.
The account manager is responsible for creating accounts of various types via the factory method crea...
folderdiaquotatab.h
Definition aboutdata.cpp:40