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