20 #include "transport.h"
21 #include "transport_p.h"
22 #include "legacydecrypt.h"
24 #include "transportmanager.h"
25 #include "transporttype_p.h"
29 #include <KConfigGroup>
31 #include <KLocalizedString>
32 #include <KMessageBox>
33 #include <KStringHandler>
34 #include <KWallet/Wallet>
36 #include <akonadi/agentinstance.h>
37 #include <akonadi/agentmanager.h>
39 using namespace MailTransport;
40 using namespace KWallet;
46 d->passwordLoaded =
false;
47 d->passwordDirty =
false;
48 d->storePasswordInFile =
false;
49 d->needsWalletMigration =
false;
50 d->passwordNeedsUpdateFromWallet =
false;
61 return (
id() > 0 ) && !host().isEmpty() && port() <= 65536;
66 if ( !d->passwordLoaded && requiresAuthentication() && storePassword() &&
67 d->password.isEmpty() ) {
75 d->passwordLoaded =
true;
76 if ( d->password == passwd ) {
79 d->passwordDirty =
true;
85 QStringList existingNames;
87 if ( t->id() != id() ) {
88 existingNames << t->name();
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 ) );
104 if ( original ==
this ) {
105 kWarning() <<
"Tried to update password state of non-cloned transport.";
109 d->password = original->d->password;
110 d->passwordLoaded = original->d->passwordLoaded;
111 d->passwordDirty = original->d->passwordDirty;
113 kWarning() <<
"Transport with this ID not managed by transport manager.";
119 return !requiresAuthentication() || !storePassword() || d->passwordLoaded;
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" );
153 void Transport::usrReadConfig()
155 TransportBase::usrReadConfig();
157 setHost( host().trimmed() );
159 if ( d->oldName.isEmpty() ) {
165 using namespace Akonadi;
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.";
174 d->transportType.d->mAgentType = instance.type();
175 kDebug() <<
"agent type" << instance.type().name() <<
"id" << instance.type().identifier();
180 int index = types.indexOf( d->transportType );
182 d->transportType = types[ index ];
184 kWarning() <<
"Type unknown to manager.";
185 d->transportType.d->mName = i18nc(
"An unknown transport type",
"Unknown" );
190 if ( !storePassword() ) {
194 if ( d->passwordLoaded ) {
195 if ( d->passwordNeedsUpdateFromWallet ) {
196 d->passwordNeedsUpdateFromWallet =
false;
198 if ( Wallet::isOpen( Wallet::NetworkWallet() ) ) {
203 QTimer::singleShot( 0,
this, SLOT(readPassword()) );
205 d->passwordLoaded =
false;
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" ) ) {
218 }
else if ( group.hasKey(
"password-knode" ) ) {
222 if ( !d->password.isEmpty() ) {
223 d->passwordLoaded =
true;
224 if ( Wallet::isEnabled() ) {
225 d->needsWalletMigration =
true;
227 d->storePasswordInFile =
true;
232 void Transport::usrWriteConfig()
234 if ( requiresAuthentication() && storePassword() && d->passwordDirty ) {
236 if ( !wallet || wallet->writePassword( QString::number(
id() ), d->password ) != 0 ) {
238 if ( d->storePasswordInFile || KMessageBox::warningYesNo(
240 i18n(
"KWallet is not available. It is strongly recommended to use "
241 "KWallet for managing your passwords.\n"
242 "However, the password can be stored in the configuration "
243 "file instead. The password is stored in an obfuscated format, "
244 "but should not be considered secure from decryption efforts "
245 "if access to the configuration file is obtained.\n"
246 "Do you want to store the password for server '%1' in the "
247 "configuration file?", name() ),
248 i18n(
"KWallet Not Available" ),
249 KGuiItem( i18n(
"Store Password" ) ),
250 KGuiItem( i18n(
"Do Not Store Password" ) ) ) == KMessageBox::Yes ) {
252 KConfigGroup group( config(), currentGroup() );
253 group.writeEntry(
"password", KStringHandler::obscure( d->password ) );
254 d->storePasswordInFile =
true;
257 d->passwordDirty =
false;
260 TransportBase::usrWriteConfig();
262 if ( name() != d->oldName ) {
268 void Transport::readPassword()
271 if ( !requiresAuthentication() ) {
274 d->passwordLoaded =
true;
277 if ( Wallet::folderDoesNotExist( Wallet::NetworkWallet(), WALLET_FOLDER ) ||
278 Wallet::keyDoesNotExist( Wallet::NetworkWallet(), WALLET_FOLDER,
279 QString::number(
id() ) ) ) {
281 if ( Wallet::folderDoesNotExist( Wallet::NetworkWallet(), KMAIL_WALLET_FOLDER ) ||
282 Wallet::keyDoesNotExist( Wallet::NetworkWallet(), KMAIL_WALLET_FOLDER,
283 QString::fromLatin1(
"transport-%1" ).arg(
id() ) ) ) {
286 kDebug() <<
"migrating password from kmail wallet";
290 wallet->setFolder( KMAIL_WALLET_FOLDER );
291 if ( wallet->readPassword( QString::fromLatin1(
"transport-%1" ).arg(
id() ), pwd ) == 0 ) {
296 d->passwordLoaded =
false;
298 wallet->removeEntry( QString::fromLatin1(
"transport-%1" ).arg(
id() ) );
299 wallet->setFolder( WALLET_FOLDER );
308 if ( wallet->readPassword( QString::number(
id() ), pwd ) == 0 ) {
312 d->passwordLoaded =
false;
319 return d->needsWalletMigration;
324 kDebug() <<
"migrating" << id() <<
"to wallet";
325 d->needsWalletMigration =
false;
326 KConfigGroup group( config(), currentGroup() );
327 group.deleteEntry(
"password" );
328 group.deleteEntry(
"password-kmail" );
329 group.deleteEntry(
"password-knode" );
330 d->passwordDirty =
true;
331 d->storePasswordInFile =
false;
337 QString
id = currentGroup().mid( 10 );
343 if ( !d->transportType.
isValid() ) {
344 kWarning() <<
"Invalid transport type.";
346 return d->transportType;
352 d->transportType = type;
353 setType( type.
type() );
A representation of a transport type.
void migrateToWallet()
Try to migrate the password from the config file to the wallet.
bool isComplete() const
Returns true if all settings have been loaded.
static TransportManager * self()
Returns the TransportManager instance.
void setPassword(const QString &passwd)
Sets the password of this transport.
KWallet::Wallet * wallet()
Returns a pointer to an open wallet if available, 0 otherwise.
bool isValid() const
Returns whether the transport type is valid.
QString password()
Returns the password of this transport.
void setTransportType(const TransportType &type)
Sets the type of this transport.
Private class that helps to provide binary compatibility between releases.
QString authenticationTypeString() const
Returns a string representation of the authentication type.
bool needsWalletMigration() const
Returns true if the password was not stored in the wallet.
bool isValid() const
Returns true if this transport is valid, ie.
static QString decryptKMail(const QString &data)
Read data encrypted using KMail's legacy encryption.
void transportRenamed(int id, const QString &oldName, const QString &newName)
Emitted when a transport has been renamed.
Transport * clone() const
Returns a deep copy of this Transport object which will no longer be automatically updated...
void forceUniqueName()
Makes sure the transport has a unique name.
Internal file containing constant definitions etc.
QList< TransportType > List
Describes a list of transport types.
static QString decryptKNode(const QString &data)
Read data encrypted using KNode's legacy encryption.
void updatePasswordState()
This function synchronizes the password of this transport with the password of the transport with the...
TransportBase::EnumType::type type() const
Transport(const QString &cfgGroup)
Creates a Transport object.
Represents the settings of a specific mail transport.
Transport * transportById(int id, bool def=true) const
Returns the Transport object with the given id.
virtual ~Transport()
Destructor.
TransportType::List types() const
Returns a list of all available transport types.
TransportType transportType() const
Returns the type of this transport.