• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.14.10 API Reference
  • KDE Home
  • Contact Us
 

mailtransport

  • mailtransport
transport.cpp
1/*
2 Copyright (c) 2006 - 2007 Volker Krause <vkrause@kde.org>
3
4 This library is free software; you can redistribute it and/or modify it
5 under the terms of the GNU Library General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or (at your
7 option) any later version.
8
9 This library is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
12 License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to the
16 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 02110-1301, USA.
18*/
19
20#include "transport.h"
21#include "transport_p.h"
22#include "legacydecrypt.h"
23#include "mailtransport_defs.h"
24#include "transportmanager.h"
25#include "transporttype_p.h"
26
27#include <QTimer>
28
29#include <KConfigGroup>
30#include <KDebug>
31#include <KLocalizedString>
32#include <KMessageBox>
33#include <KStringHandler>
34#include <KWallet/Wallet>
35
36#include <akonadi/agentinstance.h>
37#include <akonadi/agentmanager.h>
38
39using namespace MailTransport;
40using namespace KWallet;
41
42Transport::Transport( const QString &cfgGroup ) :
43 TransportBase( cfgGroup ), d( new TransportPrivate )
44{
45 kDebug() << cfgGroup;
46 d->passwordLoaded = false;
47 d->passwordDirty = false;
48 d->storePasswordInFile = false;
49 d->needsWalletMigration = false;
50 d->passwordNeedsUpdateFromWallet = false;
51 readConfig();
52}
53
54Transport::~Transport()
55{
56 delete d;
57}
58
59bool Transport::isValid() const
60{
61 return ( id() > 0 ) && !host().isEmpty() && port() <= 65536;
62}
63
64QString Transport::password()
65{
66 if ( !d->passwordLoaded && requiresAuthentication() && storePassword() &&
67 d->password.isEmpty() ) {
68 readPassword();
69 }
70 return d->password;
71}
72
73void Transport::setPassword( const QString &passwd )
74{
75 d->passwordLoaded = true;
76 if ( d->password == passwd ) {
77 return;
78 }
79 d->passwordDirty = true;
80 d->password = passwd;
81}
82
83void Transport::forceUniqueName()
84{
85 QStringList existingNames;
86 foreach ( Transport *t, TransportManager::self()->transports() ) {
87 if ( t->id() != id() ) {
88 existingNames << t->name();
89 }
90 }
91 int suffix = 1;
92 QString origName = name();
93 while ( existingNames.contains( name() ) ) {
94 setName( i18nc( "%1: name; %2: number appended to it to make "
95 "it unique among a list of names", "%1 #%2", origName, suffix ) );
96 ++suffix;
97 }
98
99}
100
101void Transport::updatePasswordState()
102{
103 Transport *original = TransportManager::self()->transportById( id(), false );
104 if ( original == this ) {
105 kWarning() << "Tried to update password state of non-cloned transport.";
106 return;
107 }
108 if ( original ) {
109 d->password = original->d->password;
110 d->passwordLoaded = original->d->passwordLoaded;
111 d->passwordDirty = original->d->passwordDirty;
112 } else {
113 kWarning() << "Transport with this ID not managed by transport manager.";
114 }
115}
116
117bool Transport::isComplete() const
118{
119 return !requiresAuthentication() || !storePassword() || d->passwordLoaded;
120}
121
122QString Transport::authenticationTypeString() const
123{
124 return Transport::authenticationTypeString( authenticationType() );
125}
126
127QString Transport::authenticationTypeString( int type )
128{
129 switch ( type ) {
130 case EnumAuthenticationType::LOGIN:
131 return QLatin1String( "LOGIN" );
132 case EnumAuthenticationType::PLAIN:
133 return QLatin1String( "PLAIN" );
134 case EnumAuthenticationType::CRAM_MD5:
135 return QLatin1String( "CRAM-MD5" );
136 case EnumAuthenticationType::DIGEST_MD5:
137 return QLatin1String( "DIGEST-MD5" );
138 case EnumAuthenticationType::NTLM:
139 return QLatin1String( "NTLM" );
140 case EnumAuthenticationType::GSSAPI:
141 return QLatin1String( "GSSAPI" );
142 case EnumAuthenticationType::CLEAR:
143 return i18nc( "Authentication method", "Clear text" );
144 case EnumAuthenticationType::APOP:
145 return QLatin1String( "APOP" );
146 case EnumAuthenticationType::ANONYMOUS:
147 return i18nc( "Authentication method", "Anonymous" );
148 }
149 Q_ASSERT( false );
150 return QString();
151}
152
153void Transport::usrReadConfig()
154{
155 TransportBase::usrReadConfig();
156
157 setHost( host().trimmed() );
158
159 if ( d->oldName.isEmpty() ) {
160 d->oldName = name();
161 }
162
163 // Set TransportType.
164 {
165 using namespace Akonadi;
166 d->transportType = TransportType();
167 d->transportType.d->mType = type();
168 kDebug() << "type" << type();
169 if ( type() == EnumType::Akonadi ) {
170 const AgentInstance instance = AgentManager::self()->instance( host() );
171 if ( !instance.isValid() ) {
172 kWarning() << "Akonadi transport with invalid resource instance.";
173 }
174 d->transportType.d->mAgentType = instance.type();
175 kDebug() << "agent type" << instance.type().name() << "id" << instance.type().identifier();
176 }
177 // Now we have the type and possibly agentType. Get the name, description
178 // etc. from TransportManager.
179 const TransportType::List &types = TransportManager::self()->types();
180 int index = types.indexOf( d->transportType );
181 if ( index != -1 ) {
182 d->transportType = types[ index ];
183 } else {
184 kWarning() << "Type unknown to manager.";
185 d->transportType.d->mName = i18nc( "An unknown transport type", "Unknown" );
186 }
187 }
188
189 // we have everything we need
190 if ( !storePassword() ) {
191 return;
192 }
193
194 if ( d->passwordLoaded ) {
195 if ( d->passwordNeedsUpdateFromWallet ) {
196 d->passwordNeedsUpdateFromWallet = false;
197 // read password if wallet is open, defer otherwise
198 if ( Wallet::isOpen( Wallet::NetworkWallet() ) ) {
199 // Don't read the password right away because this can lead
200 // to reentrancy problems in KDBusServiceStarter when an application
201 // run in Kontact creates the transports (due to a QEventLoop in the
202 // synchronous KWallet openWallet call).
203 QTimer::singleShot( 0, this, SLOT(readPassword()) );
204 } else {
205 d->passwordLoaded = false;
206 }
207 }
208
209 return;
210 }
211
212 // try to find a password in the config file otherwise
213 KConfigGroup group( config(), currentGroup() );
214 if ( group.hasKey( "password" ) ) {
215 d->password = KStringHandler::obscure( group.readEntry( "password" ) );
216 } else if ( group.hasKey( "password-kmail" ) ) {
217 d->password = Legacy::decryptKMail( group.readEntry( "password-kmail" ) );
218 } else if ( group.hasKey( "password-knode" ) ) {
219 d->password = Legacy::decryptKNode( group.readEntry( "password-knode" ) );
220 }
221
222 if ( !d->password.isEmpty() ) {
223 d->passwordLoaded = true;
224 if ( Wallet::isEnabled() ) {
225 d->needsWalletMigration = true;
226 } else {
227 d->storePasswordInFile = true;
228 }
229 }
230}
231
232void Transport::usrWriteConfig()
233{
234 if ( requiresAuthentication() && storePassword() && d->passwordDirty ) {
235 const QString storePassword = d->password;
236 Wallet *wallet = TransportManager::self()->wallet();
237 if ( !wallet || wallet->writePassword( QString::number( id() ), d->password ) != 0 ) {
238 // wallet saving failed, ask if we should store in the config file instead
239 if ( d->storePasswordInFile || KMessageBox::warningYesNo(
240 0,
241 i18n( "KWallet is not available. It is strongly recommended to use "
242 "KWallet for managing your passwords.\n"
243 "However, the password can be stored in the configuration "
244 "file instead. The password is stored in an obfuscated format, "
245 "but should not be considered secure from decryption efforts "
246 "if access to the configuration file is obtained.\n"
247 "Do you want to store the password for server '%1' in the "
248 "configuration file?", name() ),
249 i18n( "KWallet Not Available" ),
250 KGuiItem( i18n( "Store Password" ) ),
251 KGuiItem( i18n( "Do Not Store Password" ) ) ) == KMessageBox::Yes ) {
252 // write to config file
253 KConfigGroup group( config(), currentGroup() );
254 group.writeEntry( "password", KStringHandler::obscure( storePassword ) );
255 d->storePasswordInFile = true;
256 }
257 }
258 d->passwordDirty = false;
259 }
260
261 TransportBase::usrWriteConfig();
262 TransportManager::self()->emitChangesCommitted();
263 if ( name() != d->oldName ) {
264 emit TransportManager::self()->transportRenamed( id(), d->oldName, name() );
265 d->oldName = name();
266 }
267}
268
269void Transport::readPassword()
270{
271 // no need to load a password if the account doesn't require auth
272 if ( !requiresAuthentication() ) {
273 return;
274 }
275 d->passwordLoaded = true;
276
277 // check whether there is a chance to find our password at all
278 if ( Wallet::folderDoesNotExist( Wallet::NetworkWallet(), WALLET_FOLDER ) ||
279 Wallet::keyDoesNotExist( Wallet::NetworkWallet(), WALLET_FOLDER,
280 QString::number( id() ) ) ) {
281 // try migrating password from kmail
282 if ( Wallet::folderDoesNotExist( Wallet::NetworkWallet(), KMAIL_WALLET_FOLDER ) ||
283 Wallet::keyDoesNotExist( Wallet::NetworkWallet(), KMAIL_WALLET_FOLDER,
284 QString::fromLatin1( "transport-%1" ).arg( id() ) ) ) {
285 return;
286 }
287 kDebug() << "migrating password from kmail wallet";
288 KWallet::Wallet *wallet = TransportManager::self()->wallet();
289 if ( wallet ) {
290 QString pwd;
291 wallet->setFolder( KMAIL_WALLET_FOLDER );
292 if ( wallet->readPassword( QString::fromLatin1( "transport-%1" ).arg( id() ), pwd ) == 0 ) {
293 setPassword( pwd );
294 writeConfig();
295 } else {
296 d->password.clear();
297 d->passwordLoaded = false;
298 }
299 wallet->removeEntry( QString::fromLatin1( "transport-%1" ).arg( id() ) );
300 wallet->setFolder( WALLET_FOLDER );
301 }
302 return;
303 }
304
305 // finally try to open the wallet and read the password
306 KWallet::Wallet *wallet = TransportManager::self()->wallet();
307 if ( wallet ) {
308 QString pwd;
309 if ( wallet->readPassword( QString::number( id() ), pwd ) == 0 ) {
310 setPassword( pwd );
311 } else {
312 d->password.clear();
313 d->passwordLoaded = false;
314 }
315 }
316}
317
318bool Transport::needsWalletMigration() const
319{
320 return d->needsWalletMigration;
321}
322
323void Transport::migrateToWallet()
324{
325 kDebug() << "migrating" << id() << "to wallet";
326 d->needsWalletMigration = false;
327 KConfigGroup group( config(), currentGroup() );
328 group.deleteEntry( "password" );
329 group.deleteEntry( "password-kmail" );
330 group.deleteEntry( "password-knode" );
331 d->passwordDirty = true;
332 d->storePasswordInFile = false;
333 writeConfig();
334}
335
336Transport *Transport::clone() const
337{
338 QString id = currentGroup().mid( 10 );
339 return new Transport( id );
340}
341
342TransportType Transport::transportType() const
343{
344 if ( !d->transportType.isValid() ) {
345 kWarning() << "Invalid transport type.";
346 }
347 return d->transportType;
348}
349
350void Transport::setTransportType( const TransportType &type )
351{
352 Q_ASSERT( type.isValid() );
353 d->transportType = type;
354 setType( type.type() );
355}
356
MailTransport::Legacy::decryptKNode
static QString decryptKNode(const QString &data)
Read data encrypted using KNode's legacy encryption.
Definition legacydecrypt.cpp:34
MailTransport::Legacy::decryptKMail
static QString decryptKMail(const QString &data)
Read data encrypted using KMail's legacy encryption.
Definition legacydecrypt.cpp:29
MailTransport::TransportManager::transportById
Transport * transportById(int id, bool def=true) const
Returns the Transport object with the given id.
Definition transportmanager.cpp:171
MailTransport::TransportManager::types
TransportType::List types() const
Returns a list of all available transport types.
Definition transportmanager.cpp:203
MailTransport::TransportManager::self
static TransportManager * self()
Returns the TransportManager instance.
Definition transportmanager.cpp:162
MailTransport::TransportManager::wallet
KWallet::Wallet * wallet()
Returns a pointer to an open wallet if available, 0 otherwise.
Definition transportmanager.cpp:574
MailTransport::TransportManager::transportRenamed
void transportRenamed(int id, const QString &oldName, const QString &newName)
Emitted when a transport has been renamed.
MailTransport::TransportType
A representation of a transport type.
Definition transporttype.h:52
MailTransport::TransportType::type
TransportBase::EnumType::type type() const
Definition transporttype.cpp:71
MailTransport::TransportType::isValid
bool isValid() const
Returns whether the transport type is valid.
Definition transporttype.cpp:59
MailTransport::TransportType::List
QList< TransportType > List
Describes a list of transport types.
Definition transporttype.h:62
MailTransport::Transport
Represents the settings of a specific mail transport.
Definition transport.h:51
MailTransport::Transport::migrateToWallet
void migrateToWallet()
Try to migrate the password from the config file to the wallet.
Definition transport.cpp:323
MailTransport::Transport::forceUniqueName
void forceUniqueName()
Makes sure the transport has a unique name.
Definition transport.cpp:83
MailTransport::Transport::needsWalletMigration
bool needsWalletMigration() const
Returns true if the password was not stored in the wallet.
Definition transport.cpp:318
MailTransport::Transport::setPassword
void setPassword(const QString &passwd)
Sets the password of this transport.
Definition transport.cpp:73
MailTransport::Transport::authenticationTypeString
QString authenticationTypeString() const
Returns a string representation of the authentication type.
Definition transport.cpp:122
MailTransport::Transport::password
QString password()
Returns the password of this transport.
Definition transport.cpp:64
MailTransport::Transport::isComplete
bool isComplete() const
Returns true if all settings have been loaded.
Definition transport.cpp:117
MailTransport::Transport::setTransportType
void setTransportType(const TransportType &type)
Sets the type of this transport.
Definition transport.cpp:350
MailTransport::Transport::~Transport
virtual ~Transport()
Destructor.
Definition transport.cpp:54
MailTransport::Transport::clone
Transport * clone() const
Returns a deep copy of this Transport object which will no longer be automatically updated.
Definition transport.cpp:336
MailTransport::Transport::updatePasswordState
void updatePasswordState()
This function synchronizes the password of this transport with the password of the transport with the...
Definition transport.cpp:101
MailTransport::Transport::isValid
bool isValid() const
Returns true if this transport is valid, ie.
Definition transport.cpp:59
MailTransport::Transport::transportType
TransportType transportType() const
Returns the type of this transport.
Definition transport.cpp:342
MailTransport::Transport::Transport
Transport(const QString &cfgGroup)
Creates a Transport object.
Definition transport.cpp:42
TransportPrivate
Private class that helps to provide binary compatibility between releases.
Definition transport_p.h:30
mailtransport_defs.h
Internal file containing constant definitions etc.
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Wed Jan 24 2024 00:00:00 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

mailtransport

Skip menu "mailtransport"
  • Main Page
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • Related Pages

kdepimlibs-4.14.10 API Reference

Skip menu "kdepimlibs-4.14.10 API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal