diff --git a/mailtransport/transport.cpp b/mailtransport/transport.cpp index 351f932ce..4c4066910 100644 --- a/mailtransport/transport.cpp +++ b/mailtransport/transport.cpp @@ -1,266 +1,266 @@ /* Copyright (c) 2006 - 2007 Volker Krause This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "transport.h" #include "transportmanager.h" #include "mailtransport_defs.h" #include "legacydecrypt.h" #include #include #include #include #include #include using namespace MailTransport; using namespace KWallet; /** * Private class that helps to provide binary compatibility between releases. * @internal */ class TransportPrivate { public: QString password; bool passwordLoaded; bool passwordDirty; bool storePasswordInFile; bool needsWalletMigration; QString oldName; }; Transport::Transport( const QString &cfgGroup ) : TransportBase( cfgGroup ), d( new TransportPrivate ) { kDebug() << cfgGroup; d->passwordLoaded = false; d->passwordDirty = false; d->storePasswordInFile = false; d->needsWalletMigration = false; readConfig(); } Transport::~Transport() { delete d; } bool Transport::isValid() const { return ( id() > 0 ) && !host().isEmpty() && port() <= 65536; } QString Transport::password() { if ( !d->passwordLoaded && requiresAuthentication() && storePassword() && d->password.isEmpty() ) { TransportManager::self()->loadPasswords(); d->password = TransportManager::self()->transportById( id(), false )->password(); } return d->password; } void Transport::setPassword( const QString &passwd ) { d->passwordLoaded = true; if ( d->password == passwd ) { return; } d->passwordDirty = true; d->password = passwd; } void Transport::updatePasswordState() { Transport *original = TransportManager::self()->transportById( id(), false ); if ( original == this ) { kWarning() << "Tried to update password state of non-cloned transport."; return; } if ( original ) { d->password = original->d->password; d->passwordLoaded = original->d->passwordLoaded; d->passwordDirty = original->d->passwordDirty; - } - else + } else { kWarning() << "Transport with this ID not managed by transport manager."; + } } bool Transport::isComplete() const { return !requiresAuthentication() || !storePassword() || d->passwordLoaded; } QString Transport::authenticationTypeString() const { switch ( authenticationType() ) { case EnumAuthenticationType::LOGIN: return QLatin1String( "LOGIN" ); case EnumAuthenticationType::PLAIN: return QLatin1String( "PLAIN" ); case EnumAuthenticationType::CRAM_MD5: return QLatin1String( "CRAM-MD5" ); case EnumAuthenticationType::DIGEST_MD5: return QLatin1String( "DIGEST-MD5" ); case EnumAuthenticationType::NTLM: return QLatin1String( "NTLM" ); case EnumAuthenticationType::GSSAPI: return QLatin1String( "GSSAPI" ); } Q_ASSERT( false ); return QString(); } void Transport::usrReadConfig() { TransportBase::usrReadConfig(); setHost( host().trimmed() ); if ( d->oldName.isEmpty() ) { d->oldName = name(); } // we have everything we need if ( !storePassword() || d->passwordLoaded ) { return; } // try to find a password in the config file otherwise KConfigGroup group( config(), currentGroup() ); if ( group.hasKey( "password" ) ) { d->password = KStringHandler::obscure( group.readEntry( "password" ) ); } else if ( group.hasKey( "password-kmail" ) ) { d->password = Legacy::decryptKMail( group.readEntry( "password-kmail" ) ); } else if ( group.hasKey( "password-knode" ) ) { d->password = Legacy::decryptKNode( group.readEntry( "password-knode" ) ); } if ( !d->password.isEmpty() ) { d->passwordLoaded = true; if ( Wallet::isEnabled() ) { d->needsWalletMigration = true; } else { d->storePasswordInFile = true; } } else { // read password if wallet is open, defer otherwise if ( Wallet::isOpen( Wallet::NetworkWallet() ) ) { readPassword(); } } } void Transport::usrWriteConfig() { if ( requiresAuthentication() && storePassword() && d->passwordDirty ) { Wallet *wallet = TransportManager::self()->wallet(); if ( !wallet || wallet->writePassword( QString::number( id() ), d->password ) != 0 ) { // wallet saving failed, ask if we should store in the config file instead if ( d->storePasswordInFile || KMessageBox::warningYesNo( 0, i18n( "KWallet is not available. It is strongly recommended to use " "KWallet for managing your passwords.\n" "However, the password can be stored in the configuration " "file instead. The password is stored in an obfuscated format, " "but should not be considered secure from decryption efforts " "if access to the configuration file is obtained.\n" "Do you want to store the password for server '%1' in the " "configuration file?", name() ), i18n( "KWallet Not Available" ), KGuiItem( i18n( "Store Password" ) ), KGuiItem( i18n( "Do Not Store Password" ) ) ) == KMessageBox::Yes ) { // write to config file KConfigGroup group( config(), currentGroup() ); group.writeEntry( "password", KStringHandler::obscure( d->password ) ); d->storePasswordInFile = true; } } d->passwordDirty = false; } TransportBase::usrWriteConfig(); TransportManager::self()->emitChangesCommitted(); if ( name() != d->oldName ) { emit TransportManager::self()->transportRenamed( id(), d->oldName, name() ); d->oldName = name(); } } void Transport::readPassword() { // no need to load a password if the account doesn't require auth if ( !requiresAuthentication() ) { return; } d->passwordLoaded = true; // check whether there is a chance to find our password at all if ( Wallet::folderDoesNotExist( Wallet::NetworkWallet(), WALLET_FOLDER ) || Wallet::keyDoesNotExist( Wallet::NetworkWallet(), WALLET_FOLDER, QString::number( id() ) ) ) { // try migrating password from kmail if ( Wallet::folderDoesNotExist( Wallet::NetworkWallet(), KMAIL_WALLET_FOLDER ) || Wallet::keyDoesNotExist( Wallet::NetworkWallet(), KMAIL_WALLET_FOLDER, QString::fromLatin1( "transport-%1" ).arg( id() ) ) ) { return; } kDebug() << "migrating password from kmail wallet"; KWallet::Wallet *wallet = TransportManager::self()->wallet(); if ( wallet ) { wallet->setFolder( KMAIL_WALLET_FOLDER ); wallet->readPassword( QString::fromLatin1( "transport-%1" ).arg( id() ), d->password ); wallet->removeEntry( QString::fromLatin1( "transport-%1" ).arg( id() ) ); wallet->setFolder( WALLET_FOLDER ); d->passwordDirty = true; writeConfig(); } return; } // finally try to open the wallet and read the password KWallet::Wallet *wallet = TransportManager::self()->wallet(); if ( wallet ) { wallet->readPassword( QString::number( id() ), d->password ); } } bool Transport::needsWalletMigration() const { return d->needsWalletMigration; } void Transport::migrateToWallet() { kDebug() << "migrating" << id() << "to wallet"; d->needsWalletMigration = false; KConfigGroup group( config(), currentGroup() ); group.deleteEntry( "password" ); d->passwordDirty = true; d->storePasswordInFile = false; writeConfig(); } Transport *Transport::clone() const { QString id = currentGroup().mid( 10 ); return new Transport( id ); } diff --git a/mailtransport/transport.h b/mailtransport/transport.h index 8a44146b0..4e2f17bed 100644 --- a/mailtransport/transport.h +++ b/mailtransport/transport.h @@ -1,126 +1,126 @@ /* Copyright (c) 2006 - 2007 Volker Krause This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef MAILTRANSPORT_TRANSPORT_H #define MAILTRANSPORT_TRANSPORT_H #include #include class TransportPrivate; namespace MailTransport { /** Represents the settings of a specific mail transport. To create a new empty Transport object, use TransportManager::createTransport(). */ class MAILTRANSPORT_EXPORT Transport : public TransportBase { friend class TransportManager; public: /** Destructor */ virtual ~Transport(); typedef QList List; /** Returns true if this transport is valid, ie. has all necessary data set. */ bool isValid() const; /** Returns the password of this transport. */ QString password(); /** Sets the password of this transport. @param passwd The new password. */ void setPassword( const QString &passwd ); /** - This function syncronizes the password of this transport with the password of the - transport with the same ID that is managed by the transport manager. - This is only useful for cloned transports, since their passwords don't automatically - get updated when calling TransportManager::loadPasswordsAsync() or - TransportManager::loadPasswords(). + This function synchronizes the password of this transport with the + password of the transport with the same ID that is managed by the + transport manager. This is only useful for cloned transports, since + their passwords don't automatically get updated when calling + TransportManager::loadPasswordsAsync() or TransportManager::loadPasswords(). @sa clone() @since 4.2 */ void updatePasswordState(); /** Returns true if all settings have been loaded. This is the way to find out if the password has already been loaded from the wallet. */ bool isComplete() const; /** Returns a string representation of the authentication type. */ QString authenticationTypeString() const; /** Returns a deep copy of this Transport object which will no longer be automatically updated. Use this if you need to store a Transport object over a longer time. However it is recommended to store transport identifiers instead if possible. @sa updatePasswordState() */ Transport *clone() const; protected: /** Creates a Transport object. Should only be used by TransportManager. @param cfgGroup The KConfig group to read its data from. */ Transport( const QString &cfgGroup ); virtual void usrReadConfig(); virtual void usrWriteConfig(); /** Returns true if the password was not stored in the wallet. */ bool needsWalletMigration() const; /** Try to migrate the password from the config file to the wallet. */ void migrateToWallet(); private: void readPassword(); private: TransportPrivate *const d; }; } #endif diff --git a/mailtransport/transportmanagementwidget.cpp b/mailtransport/transportmanagementwidget.cpp index bcb8839d9..b5e18a702 100644 --- a/mailtransport/transportmanagementwidget.cpp +++ b/mailtransport/transportmanagementwidget.cpp @@ -1,183 +1,183 @@ /* Copyright (c) 2006 - 2007 Volker Krause Based on KMail code by: Copyright (C) 2001-2003 Marc Mutz This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "transportmanagementwidget.h" #include "ui_transportmanagementwidget.h" #include "transportmanager.h" #include "transport.h" #include "transportconfigdialog.h" using namespace MailTransport; class TransportManagementWidget::Private { public: Ui::TransportManagementWidget ui; }; TransportManagementWidget::TransportManagementWidget( QWidget *parent ) : QWidget( parent ), d( new Private ) { - KGlobal::locale()->insertCatalog(QString::fromLatin1("libmailtransport")); + KGlobal::locale()->insertCatalog( QString::fromLatin1( "libmailtransport" ) ); d->ui.setupUi( this ); d->ui.transportList->setHeaderLabels( QStringList() << i18nc( "@title:column email transport name", "Name" ) << i18nc( "@title:column email transport type", "Type" ) ); d->ui.transportList->sortItems( 0, Qt::AscendingOrder ); connect( d->ui.transportList, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), SLOT(updateButtonState()) ); connect( d->ui.transportList, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), SLOT(editClicked()) ); connect( d->ui.addButton, SIGNAL(clicked()), SLOT(addClicked()) ); connect( d->ui.editButton, SIGNAL(clicked()), SLOT(editClicked()) ); connect( d->ui.removeButton, SIGNAL(clicked()), SLOT(removeClicked()) ); connect( d->ui.defaultButton, SIGNAL(clicked()), SLOT(defaultClicked()) ); fillTransportList(); connect( TransportManager::self(), SIGNAL(transportsChanged()), SLOT(fillTransportList()) ); } TransportManagementWidget::~TransportManagementWidget() { delete d; } void TransportManagementWidget::fillTransportList() { // try to preserve the selection int selected = -1; if ( d->ui.transportList->currentItem() ) { selected = d->ui.transportList->currentItem()->data( 0, Qt::UserRole ).toInt(); } d->ui.transportList->clear(); foreach ( Transport *t, TransportManager::self()->transports() ) { QTreeWidgetItem *item = new QTreeWidgetItem( d->ui.transportList ); item->setData( 0, Qt::UserRole, t->id() ); item->setText( 0, t->name() ); QString type; switch ( t->type() ) { case Transport::EnumType::SMTP: type = i18nc( "@option SMTP transport", "SMTP" ); break; case Transport::EnumType::Sendmail: type = i18nc( "@option sendmail transport", "Sendmail" ); break; } if ( TransportManager::self()->defaultTransportId() == t->id() ) { type += i18nc( "@label the default mail transport", " (Default)" ); } item->setText( 1, type ); if ( t->id() == selected ) { d->ui.transportList->setCurrentItem( item ); } } updateButtonState(); } void TransportManagementWidget::updateButtonState() { if ( !d->ui.transportList->currentItem() ) { d->ui.editButton->setEnabled( false ); d->ui.removeButton->setEnabled( false ); d->ui.defaultButton->setEnabled( false ); } else { d->ui.editButton->setEnabled( true ); d->ui.removeButton->setEnabled( true ); if ( d->ui.transportList->currentItem()->data( 0, Qt::UserRole ) == TransportManager::self()->defaultTransportId() ) { d->ui.defaultButton->setEnabled( false ); } else { d->ui.defaultButton->setEnabled( true ); } } } void TransportManagementWidget::addClicked() { // initialize transport Transport *t = TransportManager::self()->createTransport(); t->setType( Transport::EnumType::SMTP ); // configure transporr TransportConfigDialog *tcd = new TransportConfigDialog( t, this ); connect( tcd, SIGNAL(sendmailClicked()), SLOT(slotSendmail()) ); tcd->setCaption( i18nc( "@title:window", "Add Transport" ) ); if ( tcd->exec() == KDialog::Accepted ) { TransportManager::self()->addTransport( t ); } else { delete t; } } void TransportManagementWidget::slotSendmail() { // initialize transport Transport *t = TransportManager::self()->createTransport(); t->setType( Transport::EnumType::Sendmail ); t->setHost( QLatin1String( "/usr/sbin/sendmail" ) ); TransportConfigDialog tcd( t, this ); tcd.setCaption( i18nc( "@title:window", "Add Transport" ) ); if ( tcd.exec() == KDialog::Accepted ) { TransportManager::self()->addTransport( t ); } else { delete t; } } void TransportManagementWidget::editClicked() { Q_ASSERT( d->ui.transportList->currentItem() ); int currentId = d->ui.transportList->currentItem()->data( 0, Qt::UserRole ).toInt(); Transport *transport = TransportManager::self()->transportById( currentId ); if ( !transport ) { return; } transport = transport->clone(); TransportConfigDialog t( transport, this ); t.setCaption( i18nc( "@title:window", "Modify Transport" ) ); t.exec(); delete transport; } void TransportManagementWidget::removeClicked() { Q_ASSERT( d->ui.transportList->currentItem() ); TransportManager::self()->removeTransport( d->ui.transportList->currentItem()->data( 0, Qt::UserRole ).toInt() ); } void TransportManagementWidget::defaultClicked() { Q_ASSERT( d->ui.transportList->currentItem() ); TransportManager::self()->setDefaultTransport( d->ui.transportList->currentItem()->data( 0, Qt::UserRole ).toInt() ); } #include "transportmanagementwidget.moc"