mailtransport
transport.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "transport.h"
00021 #include "transportmanager.h"
00022 #include "mailtransport_defs.h"
00023 #include "legacydecrypt.h"
00024
00025 #include <kdebug.h>
00026 #include <klocale.h>
00027 #include <kmessagebox.h>
00028 #include <kstringhandler.h>
00029 #include <kwallet.h>
00030 #include <kconfiggroup.h>
00031
00032 using namespace MailTransport;
00033 using namespace KWallet;
00034
00039 class TransportPrivate {
00040 public:
00041 QString password;
00042 bool passwordLoaded;
00043 bool passwordDirty;
00044 bool storePasswordInFile;
00045 bool needsWalletMigration;
00046 QString oldName;
00047 };
00048
00049 Transport::Transport( const QString &cfgGroup ) :
00050 TransportBase( cfgGroup ), d( new TransportPrivate )
00051 {
00052 kDebug(5324) << cfgGroup;
00053 d->passwordLoaded = false;
00054 d->passwordDirty = false;
00055 d->storePasswordInFile = false;
00056 d->needsWalletMigration = false;
00057 readConfig();
00058 }
00059
00060 Transport::~Transport()
00061 {
00062 delete d;
00063 }
00064
00065 bool Transport::isValid() const
00066 {
00067 return ( id() > 0 ) && !host().isEmpty() && port() <= 65536;
00068 }
00069
00070 QString Transport::password()
00071 {
00072 if ( !d->passwordLoaded && requiresAuthentication() && storePassword() &&
00073 d->password.isEmpty() )
00074 TransportManager::self()->loadPasswords();
00075 return d->password;
00076 }
00077
00078 void Transport::setPassword(const QString & passwd)
00079 {
00080 d->passwordLoaded = true;
00081 if ( d->password == passwd )
00082 return;
00083 d->passwordDirty = true;
00084 d->password = passwd;
00085 }
00086
00087 bool Transport::isComplete() const
00088 {
00089 return !requiresAuthentication() || !storePassword() || d->passwordLoaded;
00090 }
00091
00092 QString Transport::authenticationTypeString() const
00093 {
00094 switch ( authenticationType() ) {
00095 case EnumAuthenticationType::LOGIN: return QLatin1String( "LOGIN" );
00096 case EnumAuthenticationType::PLAIN: return QLatin1String( "PLAIN" );
00097 case EnumAuthenticationType::CRAM_MD5: return QLatin1String( "CRAM-MD5" );
00098 case EnumAuthenticationType::DIGEST_MD5: return QLatin1String( "DIGEST-MD5" );
00099 case EnumAuthenticationType::NTLM: return QLatin1String( "NTLM" );
00100 case EnumAuthenticationType::GSSAPI: return QLatin1String( "GSSAPI" );
00101 }
00102 Q_ASSERT( false );
00103 return QString();
00104 }
00105
00106 void Transport::usrReadConfig()
00107 {
00108 TransportBase::usrReadConfig();
00109 if ( d->oldName.isEmpty() )
00110 d->oldName = name();
00111
00112
00113 if ( !storePassword() || d->passwordLoaded )
00114 return;
00115
00116
00117 KConfigGroup group( config(), currentGroup() );
00118 if ( group.hasKey( "password" ) )
00119 d->password = KStringHandler::obscure( group.readEntry( "password" ) );
00120 else if ( group.hasKey( "password-kmail" ) )
00121 d->password = Legacy::decryptKMail( group.readEntry( "password-kmail" ) );
00122 else if ( group.hasKey( "password-knode" ) )
00123 d->password = Legacy::decryptKNode( group.readEntry( "password-knode" ) );
00124
00125 if ( !d->password.isEmpty() ) {
00126 d->passwordLoaded = true;
00127 if ( Wallet::isEnabled() ) {
00128 d->needsWalletMigration = true;
00129 } else {
00130 d->storePasswordInFile = true;
00131 }
00132 } else {
00133
00134 if ( Wallet::isOpen( Wallet::NetworkWallet() ) )
00135 readPassword();
00136 }
00137 }
00138
00139 void Transport::usrWriteConfig()
00140 {
00141 if ( requiresAuthentication() && storePassword() && d->passwordDirty ) {
00142 Wallet *wallet = TransportManager::self()->wallet();
00143 if ( !wallet || wallet->writePassword(QString::number(id()), d->password) != 0 ) {
00144
00145 if ( d->storePasswordInFile || KMessageBox::warningYesNo( 0,
00146 i18n("KWallet is not available. It is strongly recommended to use "
00147 "KWallet for managing your passwords.\n"
00148 "However, the password can be stored in the configuration "
00149 "file instead. The password is stored in an obfuscated format, "
00150 "but should not be considered secure from decryption efforts "
00151 "if access to the configuration file is obtained.\n"
00152 "Do you want to store the password for server '%1' in the "
00153 "configuration file?", name() ),
00154 i18n("KWallet Not Available"),
00155 KGuiItem( i18n("Store Password") ),
00156 KGuiItem( i18n("Do Not Store Password") ) )
00157 == KMessageBox::Yes ) {
00158
00159 KConfigGroup group( config(), currentGroup() );
00160 group.writeEntry( "password", KStringHandler::obscure( d->password ) );
00161 d->storePasswordInFile = true;
00162 }
00163 }
00164 d->passwordDirty = false;
00165 }
00166
00167 TransportBase::usrWriteConfig();
00168 TransportManager::self()->emitChangesCommitted();
00169 if ( name() != d->oldName ) {
00170 emit TransportManager::self()->transportRenamed( id(), d->oldName, name() );
00171 d->oldName = name();
00172 }
00173 }
00174
00175 void Transport::readPassword()
00176 {
00177
00178 if ( !requiresAuthentication() )
00179 return;
00180 d->passwordLoaded = true;
00181
00182
00183 if ( Wallet::folderDoesNotExist(Wallet::NetworkWallet(), WALLET_FOLDER) ||
00184 Wallet::keyDoesNotExist(Wallet::NetworkWallet(), WALLET_FOLDER,
00185 QString::number(id())) )
00186 {
00187
00188 if ( Wallet::folderDoesNotExist(Wallet::NetworkWallet(), KMAIL_WALLET_FOLDER ) ||
00189 Wallet::keyDoesNotExist(Wallet::NetworkWallet(), KMAIL_WALLET_FOLDER,
00190 QString::fromLatin1("transport-%1").arg( id() ) ) )
00191 return;
00192 kDebug(5324) << "migrating password from kmail wallet";
00193 KWallet::Wallet *wallet = TransportManager::self()->wallet();
00194 if ( wallet ) {
00195 wallet->setFolder( KMAIL_WALLET_FOLDER );
00196 wallet->readPassword( QString::fromLatin1("transport-%1").arg( id() ),
00197 d->password );
00198 wallet->removeEntry( QString::fromLatin1("transport-%1").arg( id() ) );
00199 wallet->setFolder( WALLET_FOLDER );
00200 d->passwordDirty = true;
00201 writeConfig();
00202 }
00203 return;
00204 }
00205
00206
00207 KWallet::Wallet *wallet = TransportManager::self()->wallet();
00208 if ( wallet )
00209 wallet->readPassword( QString::number(id()), d->password );
00210 }
00211
00212 bool Transport::needsWalletMigration() const
00213 {
00214 return d->needsWalletMigration;
00215 }
00216
00217 void Transport::migrateToWallet()
00218 {
00219 kDebug(5324) << "migrating" << id() << "to wallet";
00220 d->needsWalletMigration = false;
00221 KConfigGroup group( config(), currentGroup() );
00222 group.deleteEntry( "password" );
00223 d->passwordDirty = true;
00224 d->storePasswordInFile = false;
00225 writeConfig();
00226 }
00227
00228 Transport* Transport::clone() const
00229 {
00230 QString id = currentGroup().mid( 10 );
00231 return new Transport( id );
00232 }