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