• Skip to content
  • Skip to link menu
KDE 4.3 API Reference
  • KDE API Reference
  • KDE-PIM Libraries
  • Sitemap
  • Contact Us
 

mailtransport

transport.cpp

00001 /*
00002     Copyright (c) 2006 - 2007 Volker Krause <vkrause@kde.org>
00003 
00004     This library is free software; you can redistribute it and/or modify it
00005     under the terms of the GNU Library General Public License as published by
00006     the Free Software Foundation; either version 2 of the License, or (at your
00007     option) any later version.
00008 
00009     This library is distributed in the hope that it will be useful, but WITHOUT
00010     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00011     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00012     License for more details.
00013 
00014     You should have received a copy of the GNU Library General Public License
00015     along with this library; see the file COPYING.LIB.  If not, write to the
00016     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00017     02110-1301, USA.
00018 */
00019 
00020 #include "transport.h"
00021 #include "transportmanager.h"
00022 #include "mailtransport_defs.h"
00023 #include "legacydecrypt.h"
00024 
00025 #include <QTimer>
00026 #include <kdebug.h>
00027 #include <klocale.h>
00028 #include <kmessagebox.h>
00029 #include <kstringhandler.h>
00030 #include <kwallet.h>
00031 #include <kconfiggroup.h>
00032 
00033 using namespace MailTransport;
00034 using namespace KWallet;
00035 
00040 class TransportPrivate
00041 {
00042   public:
00043     QString password;
00044     bool passwordLoaded;
00045     bool passwordDirty;
00046     bool storePasswordInFile;
00047     bool needsWalletMigration;
00048     QString oldName;
00049 };
00050 
00051 Transport::Transport( const QString &cfgGroup ) :
00052     TransportBase( cfgGroup ), d( new TransportPrivate )
00053 {
00054   kDebug() << cfgGroup;
00055   d->passwordLoaded = false;
00056   d->passwordDirty = false;
00057   d->storePasswordInFile = false;
00058   d->needsWalletMigration = false;
00059   readConfig();
00060 }
00061 
00062 Transport::~Transport()
00063 {
00064   delete d;
00065 }
00066 
00067 bool Transport::isValid() const
00068 {
00069   return ( id() > 0 ) && !host().isEmpty() && port() <= 65536;
00070 }
00071 
00072 QString Transport::password()
00073 {
00074   if ( !d->passwordLoaded && requiresAuthentication() && storePassword() &&
00075        d->password.isEmpty() ) {
00076     TransportManager::self()->loadPasswords();
00077     d->password = TransportManager::self()->transportById( id(), false )->password();
00078   }
00079   return d->password;
00080 }
00081 
00082 void Transport::setPassword( const QString &passwd )
00083 {
00084   d->passwordLoaded = true;
00085   if ( d->password == passwd ) {
00086     return;
00087   }
00088   d->passwordDirty = true;
00089   d->password = passwd;
00090 }
00091 
00092 void Transport::updatePasswordState()
00093 {
00094   Transport *original = TransportManager::self()->transportById( id(), false );
00095   if ( original == this ) {
00096     kWarning() << "Tried to update password state of non-cloned transport.";
00097     return;
00098   }
00099   if ( original ) {
00100     d->password = original->d->password;
00101     d->passwordLoaded = original->d->passwordLoaded;
00102     d->passwordDirty = original->d->passwordDirty;
00103   } else {
00104     kWarning() << "Transport with this ID not managed by transport manager.";
00105   }
00106 }
00107 
00108 bool Transport::isComplete() const
00109 {
00110   return !requiresAuthentication() || !storePassword() || d->passwordLoaded;
00111 }
00112 
00113 QString Transport::authenticationTypeString() const
00114 {
00115   switch ( authenticationType() ) {
00116   case EnumAuthenticationType::LOGIN:
00117     return QLatin1String( "LOGIN" );
00118   case EnumAuthenticationType::PLAIN:
00119     return QLatin1String( "PLAIN" );
00120   case EnumAuthenticationType::CRAM_MD5:
00121     return QLatin1String( "CRAM-MD5" );
00122   case EnumAuthenticationType::DIGEST_MD5:
00123     return QLatin1String( "DIGEST-MD5" );
00124   case EnumAuthenticationType::NTLM:
00125     return QLatin1String( "NTLM" );
00126   case EnumAuthenticationType::GSSAPI:
00127     return QLatin1String( "GSSAPI" );
00128   }
00129   Q_ASSERT( false );
00130   return QString();
00131 }
00132 
00133 void Transport::usrReadConfig()
00134 {
00135   TransportBase::usrReadConfig();
00136 
00137   setHost( host().trimmed() );
00138 
00139   if ( d->oldName.isEmpty() ) {
00140     d->oldName = name();
00141   }
00142 
00143   // we have everything we need
00144   if ( !storePassword() || d->passwordLoaded ) {
00145     return;
00146   }
00147 
00148   // try to find a password in the config file otherwise
00149   KConfigGroup group( config(), currentGroup() );
00150   if ( group.hasKey( "password" ) ) {
00151     d->password = KStringHandler::obscure( group.readEntry( "password" ) );
00152   } else if ( group.hasKey( "password-kmail" ) ) {
00153     d->password = Legacy::decryptKMail( group.readEntry( "password-kmail" ) );
00154   } else if ( group.hasKey( "password-knode" ) ) {
00155     d->password = Legacy::decryptKNode( group.readEntry( "password-knode" ) );
00156   }
00157 
00158   if ( !d->password.isEmpty() ) {
00159     d->passwordLoaded = true;
00160     if ( Wallet::isEnabled() ) {
00161       d->needsWalletMigration = true;
00162     } else {
00163       d->storePasswordInFile = true;
00164     }
00165   } else {
00166     // read password if wallet is open, defer otherwise
00167     if ( Wallet::isOpen( Wallet::NetworkWallet() ) ) {
00168       // Don't read the password right away because this can lead
00169       // to reentrancy problems in KDBusServiceStarter when an application
00170       // run in Kontact creates the transports (due to a QEventLoop in the
00171       // synchronous KWallet openWallet call).
00172       QTimer::singleShot( 0, this, SLOT(readPassword()) );
00173     }
00174   }
00175 }
00176 
00177 void Transport::usrWriteConfig()
00178 {
00179   if ( requiresAuthentication() && storePassword() && d->passwordDirty ) {
00180     Wallet *wallet = TransportManager::self()->wallet();
00181     if ( !wallet || wallet->writePassword( QString::number( id() ), d->password ) != 0 ) {
00182       // wallet saving failed, ask if we should store in the config file instead
00183       if ( d->storePasswordInFile || KMessageBox::warningYesNo(
00184              0,
00185              i18n( "KWallet is not available. It is strongly recommended to use "
00186                    "KWallet for managing your passwords.\n"
00187                    "However, the password can be stored in the configuration "
00188                    "file instead. The password is stored in an obfuscated format, "
00189                    "but should not be considered secure from decryption efforts "
00190                    "if access to the configuration file is obtained.\n"
00191                    "Do you want to store the password for server '%1' in the "
00192                    "configuration file?", name() ),
00193              i18n( "KWallet Not Available" ),
00194              KGuiItem( i18n( "Store Password" ) ),
00195              KGuiItem( i18n( "Do Not Store Password" ) ) ) == KMessageBox::Yes ) {
00196         // write to config file
00197         KConfigGroup group( config(), currentGroup() );
00198         group.writeEntry( "password", KStringHandler::obscure( d->password ) );
00199         d->storePasswordInFile = true;
00200       }
00201     }
00202     d->passwordDirty = false;
00203   }
00204 
00205   TransportBase::usrWriteConfig();
00206   TransportManager::self()->emitChangesCommitted();
00207   if ( name() != d->oldName ) {
00208     emit TransportManager::self()->transportRenamed( id(), d->oldName, name() );
00209     d->oldName = name();
00210   }
00211 }
00212 
00213 void Transport::readPassword()
00214 {
00215   // no need to load a password if the account doesn't require auth
00216   if ( !requiresAuthentication() ) {
00217     return;
00218   }
00219   d->passwordLoaded = true;
00220 
00221   // check whether there is a chance to find our password at all
00222   if ( Wallet::folderDoesNotExist( Wallet::NetworkWallet(), WALLET_FOLDER ) ||
00223        Wallet::keyDoesNotExist( Wallet::NetworkWallet(), WALLET_FOLDER,
00224                                 QString::number( id() ) ) ) {
00225     // try migrating password from kmail
00226     if ( Wallet::folderDoesNotExist( Wallet::NetworkWallet(), KMAIL_WALLET_FOLDER ) ||
00227          Wallet::keyDoesNotExist( Wallet::NetworkWallet(), KMAIL_WALLET_FOLDER,
00228                                   QString::fromLatin1( "transport-%1" ).arg( id() ) ) ) {
00229       return;
00230     }
00231     kDebug() << "migrating password from kmail wallet";
00232     KWallet::Wallet *wallet = TransportManager::self()->wallet();
00233     if ( wallet ) {
00234       wallet->setFolder( KMAIL_WALLET_FOLDER );
00235       wallet->readPassword( QString::fromLatin1( "transport-%1" ).arg( id() ), d->password );
00236       wallet->removeEntry( QString::fromLatin1( "transport-%1" ).arg( id() ) );
00237       wallet->setFolder( WALLET_FOLDER );
00238       d->passwordDirty = true;
00239       writeConfig();
00240     }
00241     return;
00242   }
00243 
00244   // finally try to open the wallet and read the password
00245   KWallet::Wallet *wallet = TransportManager::self()->wallet();
00246   if ( wallet ) {
00247     wallet->readPassword( QString::number( id() ), d->password );
00248   }
00249 }
00250 
00251 bool Transport::needsWalletMigration() const
00252 {
00253   return d->needsWalletMigration;
00254 }
00255 
00256 void Transport::migrateToWallet()
00257 {
00258   kDebug() << "migrating" << id() << "to wallet";
00259   d->needsWalletMigration = false;
00260   KConfigGroup group( config(), currentGroup() );
00261   group.deleteEntry( "password" );
00262   d->passwordDirty = true;
00263   d->storePasswordInFile = false;
00264   writeConfig();
00265 }
00266 
00267 Transport *Transport::clone() const
00268 {
00269   QString id = currentGroup().mid( 10 );
00270   return new Transport( id );
00271 }
00272 
00273 #include "transport.moc"

mailtransport

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

KDE-PIM Libraries

Skip menu "KDE-PIM Libraries"
  • akonadi
  • kabc
  • kblog
  • kcal
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  • kldap
  • kmime
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Generated for KDE-PIM Libraries by doxygen 1.5.9
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal