summaryrefslogtreecommitdiffstats
path: root/kmail/kmtransport.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kmail/kmtransport.cpp')
-rw-r--r--kmail/kmtransport.cpp807
1 files changed, 807 insertions, 0 deletions
diff --git a/kmail/kmtransport.cpp b/kmail/kmtransport.cpp
new file mode 100644
index 000000000..60e56d190
--- /dev/null
+++ b/kmail/kmtransport.cpp
@@ -0,0 +1,807 @@
+/**
+ * kmtransport.cpp
+ *
+ * Copyright (c) 2001-2002 Michael Haeckel <haeckel@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <config.h>
+#include <assert.h>
+
+#include "kmtransport.h"
+
+#include <qbuttongroup.h>
+#include <qcheckbox.h>
+#include <qlayout.h>
+#include <klineedit.h>
+#include <qradiobutton.h>
+#include <qtabwidget.h>
+#include <qvalidator.h>
+#include <qlabel.h>
+#include <qpushbutton.h>
+#include <qwhatsthis.h>
+
+#include <kfiledialog.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kseparator.h>
+#include <kdebug.h>
+#include <kwallet.h>
+using KWallet::Wallet;
+#include <kprotocolinfo.h>
+
+#include "kmkernel.h"
+#include "kmservertest.h"
+#include "kmaccount.h"
+#include "protocols.h"
+#include "transportmanager.h"
+using namespace KMail;
+
+KMTransportInfo::KMTransportInfo() : mPasswdDirty( false ),
+ mStorePasswd( false ), mStorePasswdInConfig( false ), mId( 0 )
+{
+ name = i18n("Unnamed");
+ port = "25";
+ auth = false;
+ specifyHostname = false;
+}
+
+
+KMTransportInfo::~KMTransportInfo()
+{
+}
+
+
+void KMTransportInfo::readConfig(int id)
+{
+ KConfig *config = KMKernel::config();
+ KConfigGroupSaver saver(config, "Transport " + QString::number(id));
+ mId = config->readUnsignedNumEntry( "id", 0 );
+ type = config->readEntry("type", "smtp");
+ name = config->readEntry("name", i18n("Unnamed"));
+ host = config->readEntry("host", "localhost");
+ port = config->readEntry("port", "25");
+ user = config->readEntry("user");
+ mPasswd = KMAccount::decryptStr(config->readEntry("pass"));
+ precommand = config->readPathEntry("precommand");
+ encryption = config->readEntry("encryption");
+ authType = config->readEntry("authtype");
+ auth = config->readBoolEntry("auth");
+ mStorePasswd = config->readBoolEntry("storepass");
+ specifyHostname = config->readBoolEntry("specifyHostname", false);
+ localHostname = config->readEntry("localHostname");
+
+ if ( !storePasswd() )
+ return;
+
+ if ( !mPasswd.isEmpty() ) {
+ // migration to kwallet if available
+ if ( Wallet::isEnabled() ) {
+ config->deleteEntry( "pass" );
+ mPasswdDirty = true;
+ mStorePasswdInConfig = false;
+ writeConfig( id );
+ } else
+ mStorePasswdInConfig = true;
+ } else {
+ // read password if wallet is open, defer otherwise
+ if ( Wallet::isOpen( Wallet::NetworkWallet() ) )
+ readPassword();
+ }
+}
+
+
+void KMTransportInfo::writeConfig(int id)
+{
+ KConfig *config = KMKernel::config();
+ KConfigGroupSaver saver(config, "Transport " + QString::number(id));
+ if (!mId)
+ mId = TransportManager::createId();
+ config->writeEntry("id", mId);
+ config->writeEntry("type", type);
+ config->writeEntry("name", name);
+ config->writeEntry("host", host);
+ config->writeEntry("port", port);
+ config->writeEntry("user", user);
+ config->writePathEntry("precommand", precommand);
+ config->writeEntry("encryption", encryption);
+ config->writeEntry("authtype", authType);
+ config->writeEntry("auth", auth);
+ config->writeEntry("storepass", storePasswd());
+ config->writeEntry("specifyHostname", specifyHostname);
+ config->writeEntry("localHostname", localHostname);
+
+ if ( storePasswd() ) {
+ // write password into the wallet if possible and necessary
+ bool passwdStored = false;
+ Wallet *wallet = kmkernel->wallet();
+ if ( mPasswdDirty ) {
+ if ( wallet && wallet->writePassword( "transport-" + QString::number(mId), passwd() ) == 0 ) {
+ passwdStored = true;
+ mPasswdDirty = false;
+ mStorePasswdInConfig = false;
+ }
+ } else {
+ passwdStored = wallet ? !mStorePasswdInConfig /*already in the wallet*/ : config->hasKey("pass");
+ }
+ // wallet not available, ask the user if we should use the config file instead
+ if ( !passwdStored && ( mStorePasswdInConfig || KMessageBox::warningYesNo( 0,
+ i18n("KWallet is not available. It is strongly recommended to use "
+ "KWallet for managing your passwords.\n"
+ "However, KMail can store the password in its 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 account '%1' in the "
+ "configuration file?").arg( name ),
+ i18n("KWallet Not Available"),
+ KGuiItem( i18n("Store Password") ),
+ KGuiItem( i18n("Do Not Store Password") ) )
+ == KMessageBox::Yes ) ) {
+ config->writeEntry( "pass", KMAccount::encryptStr( passwd() ) );
+ mStorePasswdInConfig = true;
+ }
+ }
+
+ // delete already stored password if password storage is disabled
+ if ( !storePasswd() ) {
+ if ( !Wallet::keyDoesNotExist(
+ Wallet::NetworkWallet(), "kmail", "transport-" + QString::number(mId) ) ) {
+ Wallet *wallet = kmkernel->wallet();
+ if ( wallet )
+ wallet->removeEntry( "transport-" + QString::number(mId) );
+ }
+ config->deleteEntry( "pass" );
+ }
+}
+
+
+int KMTransportInfo::findTransport(const QString &name)
+{
+ KConfig *config = KMKernel::config();
+ KConfigGroupSaver saver(config, "General");
+ int numTransports = config->readNumEntry("transports", 0);
+ for (int i = 1; i <= numTransports; i++)
+ {
+ KConfigGroupSaver saver(config, "Transport " + QString::number(i));
+ if (config->readEntry("name") == name) return i;
+ }
+ return 0;
+}
+
+
+QStringList KMTransportInfo::availableTransports()
+{
+ QStringList result;
+ KConfig *config = KMKernel::config();
+ KConfigGroupSaver saver(config, "General");
+ int numTransports = config->readNumEntry("transports", 0);
+ for (int i = 1; i <= numTransports; i++)
+ {
+ KConfigGroupSaver saver(config, "Transport " + QString::number(i));
+ result.append(config->readEntry("name"));
+ }
+ return result;
+}
+
+
+QString KMTransportInfo::passwd() const
+{
+ if ( auth && storePasswd() && mPasswd.isEmpty() )
+ readPassword();
+ return mPasswd;
+}
+
+
+void KMTransportInfo::setPasswd( const QString &passwd )
+{
+ if ( passwd != mPasswd ) {
+ mPasswd = passwd;
+ mPasswdDirty = true;
+ }
+}
+
+
+void KMTransportInfo::setStorePasswd( bool store )
+{
+ if ( mStorePasswd != store && store )
+ mPasswdDirty = true;
+ mStorePasswd = store;
+}
+
+
+void KMTransportInfo::readPassword() const
+{
+ if ( !storePasswd() || !auth )
+ return;
+
+ // ### workaround for broken Wallet::keyDoesNotExist() which returns wrong
+ // results for new entries without closing and reopening the wallet
+ if ( Wallet::isOpen( Wallet::NetworkWallet() ) ) {
+ Wallet* wallet = kmkernel->wallet();
+ if ( !wallet || !wallet->hasEntry( "transport-" + QString::number(mId) ) )
+ return;
+ } else {
+ if ( Wallet::keyDoesNotExist( Wallet::NetworkWallet(), "kmail", "transport-" + QString::number(mId) ) )
+ return;
+ }
+
+ if ( kmkernel->wallet() )
+ kmkernel->wallet()->readPassword( "transport-" + QString::number(mId), mPasswd );
+}
+
+
+KMTransportSelDlg::KMTransportSelDlg( QWidget *parent, const char *name,
+ bool modal )
+ : KDialogBase( parent, name, modal, i18n("Add Transport"), Ok|Cancel, Ok )
+{
+ QFrame *page = makeMainWidget();
+ QVBoxLayout *topLayout = new QVBoxLayout( page, 0, spacingHint() );
+
+ QButtonGroup *group = new QButtonGroup( i18n("Transport"), page );
+ connect(group, SIGNAL(clicked(int)), SLOT(buttonClicked(int)) );
+
+ topLayout->addWidget( group, 10 );
+ QVBoxLayout *vlay = new QVBoxLayout( group, spacingHint()*2, spacingHint() );
+ vlay->addSpacing( fontMetrics().lineSpacing() );
+
+ QRadioButton *radioButton1 = new QRadioButton( i18n("SM&TP"), group );
+ vlay->addWidget( radioButton1 );
+ QRadioButton *radioButton2 = new QRadioButton( i18n("&Sendmail"), group );
+ vlay->addWidget( radioButton2 );
+
+ vlay->addStretch( 10 );
+
+ radioButton1->setChecked(true); // Pop is most common ?
+ buttonClicked(0);
+}
+
+void KMTransportSelDlg::buttonClicked( int id )
+{
+ mSelectedButton = id;
+}
+
+
+int KMTransportSelDlg::selected( void ) const
+{
+ return mSelectedButton;
+}
+
+
+KMTransportDialog::KMTransportDialog( const QString & caption,
+ KMTransportInfo *transportInfo,
+ QWidget *parent, const char *name,
+ bool modal )
+ : KDialogBase( parent, name, modal, caption, Ok|Cancel, Ok, true ),
+ mServerTest( 0 ),
+ mTransportInfo( transportInfo ),
+ mAuthNone( AllAuth ), mAuthSSL( AllAuth ), mAuthTLS( AllAuth )
+{
+ assert(transportInfo != 0);
+
+ if( transportInfo->type == QString::fromLatin1("sendmail") )
+ {
+ makeSendmailPage();
+ } else {
+ makeSmtpPage();
+ }
+
+ setupSettings();
+}
+
+
+KMTransportDialog::~KMTransportDialog()
+{
+}
+
+
+void KMTransportDialog::makeSendmailPage()
+{
+ QFrame *page = makeMainWidget();
+ QVBoxLayout *topLayout = new QVBoxLayout( page, 0, spacingHint() );
+
+ mSendmail.titleLabel = new QLabel( page );
+ mSendmail.titleLabel->setText( i18n("Transport: Sendmail") );
+ QFont titleFont( mSendmail.titleLabel->font() );
+ titleFont.setBold( true );
+ mSendmail.titleLabel->setFont( titleFont );
+ topLayout->addWidget( mSendmail.titleLabel );
+ KSeparator *hline = new KSeparator( KSeparator::HLine, page);
+ topLayout->addWidget( hline );
+
+ QGridLayout *grid = new QGridLayout( topLayout, 3, 3, spacingHint() );
+ grid->addColSpacing( 1, fontMetrics().maxWidth()*15 );
+ grid->setRowStretch( 2, 10 );
+ grid->setColStretch( 1, 10 );
+
+ QLabel *label = new QLabel( i18n("&Name:"), page );
+ grid->addWidget( label, 0, 0 );
+ mSendmail.nameEdit = new KLineEdit( page );
+ label->setBuddy( mSendmail.nameEdit );
+ grid->addWidget( mSendmail.nameEdit, 0, 1 );
+
+ label = new QLabel( i18n("&Location:"), page );
+ grid->addWidget( label, 1, 0 );
+ mSendmail.locationEdit = new KLineEdit( page );
+ label->setBuddy(mSendmail.locationEdit);
+ grid->addWidget( mSendmail.locationEdit, 1, 1 );
+ mSendmail.chooseButton =
+ new QPushButton( i18n("Choos&e..."), page );
+ connect( mSendmail.chooseButton, SIGNAL(clicked()),
+ this, SLOT(slotSendmailChooser()) );
+
+ connect( mSendmail.locationEdit, SIGNAL(textChanged ( const QString & )),
+ this, SLOT(slotSendmailEditPath(const QString &)) );
+
+ mSendmail.chooseButton->setAutoDefault( false );
+ grid->addWidget( mSendmail.chooseButton, 1, 2 );
+ slotSendmailEditPath(mSendmail.locationEdit->text());
+}
+
+void KMTransportDialog::slotSendmailEditPath(const QString & _text)
+{
+ enableButtonOK( !_text.isEmpty() );
+}
+
+void KMTransportDialog::makeSmtpPage()
+{
+ QFrame *page = makeMainWidget();
+ QVBoxLayout *topLayout = new QVBoxLayout( page, 0, spacingHint() );
+
+ mSmtp.titleLabel = new QLabel( page );
+ mSmtp.titleLabel->setText( i18n("Transport: SMTP") );
+ QFont titleFont( mSmtp.titleLabel->font() );
+ titleFont.setBold( true );
+ mSmtp.titleLabel->setFont( titleFont );
+ topLayout->addWidget( mSmtp.titleLabel );
+ KSeparator *hline = new KSeparator( KSeparator::HLine, page);
+ topLayout->addWidget( hline );
+
+ QTabWidget *tabWidget = new QTabWidget(page);
+ topLayout->addWidget( tabWidget );
+
+ QWidget *page1 = new QWidget( tabWidget );
+ tabWidget->addTab( page1, i18n("&General") );
+
+ QGridLayout *grid = new QGridLayout( page1, 14, 2, spacingHint() );
+ grid->addColSpacing( 1, fontMetrics().maxWidth()*15 );
+ grid->setRowStretch( 13, 10 );
+ grid->setColStretch( 1, 10 );
+
+ QLabel *label = new QLabel( i18n("&Name:"), page1 );
+ grid->addWidget( label, 0, 0 );
+ mSmtp.nameEdit = new KLineEdit( page1 );
+ QWhatsThis::add(mSmtp.nameEdit,
+ i18n("The name that KMail will use when "
+ "referring to this server."));
+ label->setBuddy( mSmtp.nameEdit );
+ grid->addWidget( mSmtp.nameEdit, 0, 1 );
+
+ label = new QLabel( i18n("&Host:"), page1 );
+ grid->addWidget( label, 3, 0 );
+ mSmtp.hostEdit = new KLineEdit( page1 );
+ QWhatsThis::add(mSmtp.hostEdit,
+ i18n("The domain name or numerical address "
+ "of the SMTP server."));
+ label->setBuddy( mSmtp.hostEdit );
+ grid->addWidget( mSmtp.hostEdit, 3, 1 );
+
+ label = new QLabel( i18n("&Port:"), page1 );
+ grid->addWidget( label, 4, 0 );
+ mSmtp.portEdit = new KLineEdit( page1 );
+ mSmtp.portEdit->setValidator( new QIntValidator(this) );
+ QWhatsThis::add(mSmtp.portEdit,
+ i18n("The port number that the SMTP server "
+ "is listening on. The default port is 25."));
+ label->setBuddy( mSmtp.portEdit );
+ grid->addWidget( mSmtp.portEdit, 4, 1 );
+
+ label = new QLabel( i18n("Preco&mmand:"), page1 );
+ grid->addWidget( label, 5, 0 );
+ mSmtp.precommand = new KLineEdit( page1 );
+ QWhatsThis::add(mSmtp.precommand,
+ i18n("A command to run locally, prior "
+ "to sending email. This can be used "
+ "to set up ssh tunnels, for example. "
+ "Leave it empty if no command should be run."));
+ label->setBuddy(mSmtp.precommand);
+ grid->addWidget( mSmtp.precommand, 5, 1 );
+
+ QFrame* line = new QFrame( page1 );
+ line->setFrameStyle( QFrame::HLine | QFrame::Plain );
+ grid->addMultiCellWidget( line, 6, 6, 0, 1 );
+
+ mSmtp.authCheck =
+ new QCheckBox( i18n("Server &requires authentication"), page1 );
+ QWhatsThis::add(mSmtp.authCheck,
+ i18n("Check this option if your SMTP server "
+ "requires authentication before accepting "
+ "mail. This is known as "
+ "'Authenticated SMTP' or simply ASMTP."));
+ connect(mSmtp.authCheck, SIGNAL(clicked()),
+ SLOT(slotRequiresAuthClicked()));
+ grid->addMultiCellWidget( mSmtp.authCheck, 7, 7, 0, 1 );
+
+ mSmtp.loginLabel = new QLabel( i18n("&Login:"), page1 );
+ grid->addWidget( mSmtp.loginLabel, 8, 0 );
+ mSmtp.loginEdit = new KLineEdit( page1 );
+ mSmtp.loginLabel->setBuddy( mSmtp.loginEdit );
+ QWhatsThis::add(mSmtp.loginEdit,
+ i18n("The user name to send to the server "
+ "for authorization"));
+ grid->addWidget( mSmtp.loginEdit, 8, 1 );
+
+ mSmtp.passwordLabel = new QLabel( i18n("P&assword:"), page1 );
+ grid->addWidget( mSmtp.passwordLabel, 9, 0 );
+ mSmtp.passwordEdit = new KLineEdit( page1 );
+ mSmtp.passwordEdit->setEchoMode( QLineEdit::Password );
+ mSmtp.passwordLabel->setBuddy( mSmtp.passwordEdit );
+ QWhatsThis::add(mSmtp.passwordEdit,
+ i18n("The password to send to the server "
+ "for authorization"));
+ grid->addWidget( mSmtp.passwordEdit, 9, 1 );
+
+ mSmtp.storePasswordCheck =
+ new QCheckBox( i18n("&Store SMTP password"), page1 );
+ QWhatsThis::add(mSmtp.storePasswordCheck,
+ i18n("Check this option to have KMail store "
+ "the password.\nIf KWallet is available "
+ "the password will be stored there which is considered "
+ "safe.\nHowever, if KWallet is not available, "
+ "the password will be stored in KMail's configuration "
+ "file. 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."));
+ grid->addMultiCellWidget( mSmtp.storePasswordCheck, 10, 10, 0, 1 );
+
+ line = new QFrame( page1 );
+ line->setFrameStyle( QFrame::HLine | QFrame::Plain );
+ grid->addMultiCellWidget( line, 11, 11, 0, 1 );
+
+ mSmtp.specifyHostnameCheck =
+ new QCheckBox( i18n("Sen&d custom hostname to server"), page1 );
+ grid->addMultiCellWidget( mSmtp.specifyHostnameCheck, 12, 12, 0, 1 );
+ QWhatsThis::add(mSmtp.specifyHostnameCheck,
+ i18n("Check this option to have KMail use "
+ "a custom hostname when identifying itself "
+ "to the mail server."
+ "<p>This is useful when your system's hostname "
+ "may not be set correctly or to mask your "
+ "system's true hostname."));
+
+ mSmtp.localHostnameLabel = new QLabel( i18n("Hos&tname:"), page1 );
+ grid->addWidget( mSmtp.localHostnameLabel, 13, 0);
+ mSmtp.localHostnameEdit = new KLineEdit( page1 );
+ QWhatsThis::add(mSmtp.localHostnameEdit,
+ i18n("Enter the hostname KMail should use when "
+ "identifying itself to the server."));
+ mSmtp.localHostnameLabel->setBuddy( mSmtp.localHostnameEdit );
+ grid->addWidget( mSmtp.localHostnameEdit, 13, 1 );
+ connect( mSmtp.specifyHostnameCheck, SIGNAL(toggled(bool)),
+ mSmtp.localHostnameEdit, SLOT(setEnabled(bool)));
+ connect( mSmtp.specifyHostnameCheck, SIGNAL(toggled(bool)),
+ mSmtp.localHostnameLabel, SLOT(setEnabled(bool)));
+
+ QWidget *page2 = new QWidget( tabWidget );
+ tabWidget->addTab( page2, i18n("S&ecurity") );
+ QVBoxLayout *vlay = new QVBoxLayout( page2, spacingHint() );
+ mSmtp.encryptionGroup = new QButtonGroup( 1, Qt::Horizontal,
+ i18n("Encryption"), page2 );
+ mSmtp.encryptionNone =
+ new QRadioButton( i18n("&None"), mSmtp.encryptionGroup );
+ mSmtp.encryptionSSL =
+ new QRadioButton( i18n("&SSL"), mSmtp.encryptionGroup );
+ mSmtp.encryptionTLS =
+ new QRadioButton( i18n("&TLS"), mSmtp.encryptionGroup );
+ connect(mSmtp.encryptionGroup, SIGNAL(clicked(int)),
+ SLOT(slotSmtpEncryptionChanged(int)));
+ vlay->addWidget( mSmtp.encryptionGroup );
+
+ mSmtp.authGroup = new QButtonGroup( 1, Qt::Horizontal,
+ i18n("Authentication Method"), page2 );
+ mSmtp.authLogin = new QRadioButton( i18n("Please translate this "
+ "authentication method only if you have a good reason", "&LOGIN"),
+ mSmtp.authGroup );
+ mSmtp.authPlain = new QRadioButton( i18n("Please translate this "
+ "authentication method only if you have a good reason", "&PLAIN"),
+ mSmtp.authGroup );
+ mSmtp.authCramMd5 = new QRadioButton( i18n("CRAM-MD&5"), mSmtp.authGroup );
+ mSmtp.authDigestMd5 = new QRadioButton( i18n("&DIGEST-MD5"), mSmtp.authGroup );
+ mSmtp.authNTLM = new QRadioButton( i18n("&NTLM"), mSmtp.authGroup );
+ mSmtp.authGSSAPI = new QRadioButton( i18n("&GSSAPI"), mSmtp.authGroup );
+ if ( KProtocolInfo::capabilities("smtp").contains("SASL") == 0 ) {
+ mSmtp.authNTLM->hide();
+ mSmtp.authGSSAPI->hide();
+ }
+ vlay->addWidget( mSmtp.authGroup );
+
+ vlay->addStretch();
+
+ QHBoxLayout *buttonLay = new QHBoxLayout( vlay );
+ mSmtp.checkCapabilities =
+ new QPushButton( i18n("Check &What the Server Supports"), page2 );
+ connect(mSmtp.checkCapabilities, SIGNAL(clicked()),
+ SLOT(slotCheckSmtpCapabilities()));
+ buttonLay->addStretch();
+ buttonLay->addWidget( mSmtp.checkCapabilities );
+}
+
+
+void KMTransportDialog::setupSettings()
+{
+ if (mTransportInfo->type == "sendmail")
+ {
+ mSendmail.nameEdit->setText(mTransportInfo->name);
+ mSendmail.locationEdit->setText(mTransportInfo->host);
+ } else {
+ mSmtp.nameEdit->setText(mTransportInfo->name);
+ mSmtp.hostEdit->setText(mTransportInfo->host);
+ mSmtp.portEdit->setText(mTransportInfo->port);
+ mSmtp.authCheck->setChecked(mTransportInfo->auth);
+ mSmtp.loginEdit->setText(mTransportInfo->user);
+ mSmtp.passwordEdit->setText(mTransportInfo->passwd());
+ mSmtp.storePasswordCheck->setChecked(mTransportInfo->storePasswd());
+ mSmtp.precommand->setText(mTransportInfo->precommand);
+ mSmtp.specifyHostnameCheck->setChecked(mTransportInfo->specifyHostname);
+ mSmtp.localHostnameEdit->setText(mTransportInfo->localHostname);
+
+ if (mTransportInfo->encryption == "TLS")
+ mSmtp.encryptionTLS->setChecked(true);
+ else if (mTransportInfo->encryption == "SSL")
+ mSmtp.encryptionSSL->setChecked(true);
+ else mSmtp.encryptionNone->setChecked(true);
+
+ if (mTransportInfo->authType == "LOGIN")
+ mSmtp.authLogin->setChecked(true);
+ else if (mTransportInfo->authType == "CRAM-MD5")
+ mSmtp.authCramMd5->setChecked(true);
+ else if (mTransportInfo->authType == "DIGEST-MD5")
+ mSmtp.authDigestMd5->setChecked(true);
+ else if (mTransportInfo->authType == "NTLM")
+ mSmtp.authNTLM->setChecked(true);
+ else if (mTransportInfo->authType == "GSSAPI")
+ mSmtp.authGSSAPI->setChecked(true);
+ else mSmtp.authPlain->setChecked(true);
+
+ slotRequiresAuthClicked();
+ mSmtp.localHostnameEdit->setEnabled(mTransportInfo->specifyHostname);
+ mSmtp.localHostnameLabel->setEnabled(mTransportInfo->specifyHostname);
+ }
+}
+
+
+void KMTransportDialog::saveSettings()
+{
+ if (mTransportInfo->type == "sendmail")
+ {
+ mTransportInfo->name = mSendmail.nameEdit->text().stripWhiteSpace();
+ mTransportInfo->host = mSendmail.locationEdit->text().stripWhiteSpace();
+ } else {
+ mTransportInfo->name = mSmtp.nameEdit->text();
+ mTransportInfo->host = mSmtp.hostEdit->text().stripWhiteSpace();
+ mTransportInfo->port = mSmtp.portEdit->text().stripWhiteSpace();
+ mTransportInfo->auth = mSmtp.authCheck->isChecked();
+ mTransportInfo->user = mSmtp.loginEdit->text().stripWhiteSpace();
+ mTransportInfo->setPasswd( mSmtp.passwordEdit->text() );
+ mTransportInfo->setStorePasswd( mSmtp.storePasswordCheck->isChecked() );
+ mTransportInfo->precommand = mSmtp.precommand->text().stripWhiteSpace();
+ mTransportInfo->specifyHostname = mSmtp.specifyHostnameCheck->isChecked();
+ mTransportInfo->localHostname = mSmtp.localHostnameEdit->text().stripWhiteSpace();
+
+ mTransportInfo->encryption = (mSmtp.encryptionTLS->isChecked()) ? "TLS" :
+ (mSmtp.encryptionSSL->isChecked()) ? "SSL" : "NONE";
+
+ mTransportInfo->authType = (mSmtp.authLogin->isChecked()) ? "LOGIN" :
+ (mSmtp.authCramMd5->isChecked()) ? "CRAM-MD5" :
+ (mSmtp.authDigestMd5->isChecked()) ? "DIGEST-MD5" :
+ (mSmtp.authNTLM->isChecked()) ? "NTLM" :
+ (mSmtp.authGSSAPI->isChecked()) ? "GSSAPI" : "PLAIN";
+ }
+}
+
+
+void KMTransportDialog::slotSendmailChooser()
+{
+ KFileDialog dialog("/", QString::null, this, 0, true );
+ dialog.setCaption(i18n("Choose sendmail Location") );
+
+ if( dialog.exec() == QDialog::Accepted )
+ {
+ KURL url = dialog.selectedURL();
+ if( url.isEmpty() == true )
+ {
+ return;
+ }
+
+ if( url.isLocalFile() == false )
+ {
+ KMessageBox::sorry( 0, i18n( "Only local files allowed." ) );
+ return;
+ }
+
+ mSendmail.locationEdit->setText( url.path() );
+ }
+}
+
+
+void KMTransportDialog::slotRequiresAuthClicked()
+{
+ bool b = mSmtp.authCheck->isChecked();
+ mSmtp.loginLabel->setEnabled(b);
+ mSmtp.loginEdit->setEnabled(b);
+ mSmtp.passwordLabel->setEnabled(b);
+ mSmtp.passwordEdit->setEnabled(b);
+ mSmtp.storePasswordCheck->setEnabled(b);
+ mSmtp.authGroup->setEnabled(b);
+}
+
+
+void KMTransportDialog::slotSmtpEncryptionChanged(int id)
+{
+ kdDebug(5006) << "KMTransportDialog::slotSmtpEncryptionChanged( " << id << " )" << endl;
+ // adjust SSL port:
+ if (id == SSL || mSmtp.portEdit->text() == "465")
+ mSmtp.portEdit->setText((id == SSL) ? "465" : "25");
+
+ // switch supported auth methods:
+ QButton * old = mSmtp.authGroup->selected();
+ int authMethods = id == TLS ? mAuthTLS : id == SSL ? mAuthSSL : mAuthNone ;
+ enableAuthMethods( authMethods );
+ if ( !old->isEnabled() )
+ checkHighest( mSmtp.authGroup );
+}
+
+void KMTransportDialog::enableAuthMethods( unsigned int auth ) {
+ kdDebug(5006) << "KMTransportDialog::enableAuthMethods( " << auth << " )" << endl;
+ mSmtp.authPlain->setEnabled( auth & PLAIN );
+ // LOGIN doesn't offer anything over PLAIN, requires more server
+ // roundtrips and is not an official SASL mechanism, but a MS-ism,
+ // so only enable it if PLAIN isn't available:
+ mSmtp.authLogin->setEnabled( auth & LOGIN && !(auth & PLAIN));
+ mSmtp.authCramMd5->setEnabled( auth & CRAM_MD5 );
+ mSmtp.authDigestMd5->setEnabled( auth & DIGEST_MD5 );
+ mSmtp.authNTLM->setEnabled( auth & NTLM );
+ mSmtp.authGSSAPI->setEnabled( auth & GSSAPI );
+}
+
+unsigned int KMTransportDialog::authMethodsFromString( const QString & s ) {
+ unsigned int result = 0;
+ QStringList sl = QStringList::split( '\n', s.upper() );
+ for ( QStringList::const_iterator it = sl.begin() ; it != sl.end() ; ++it )
+ if ( *it == "SASL/LOGIN" )
+ result |= LOGIN;
+ else if ( *it == "SASL/PLAIN" )
+ result |= PLAIN;
+ else if ( *it == "SASL/CRAM-MD5" )
+ result |= CRAM_MD5;
+ else if ( *it == "SASL/DIGEST-MD5" )
+ result |= DIGEST_MD5;
+ else if ( *it == "SASL/NTLM" )
+ result |= NTLM;
+ else if ( *it == "SASL/GSSAPI" )
+ result |= GSSAPI;
+ return result;
+}
+
+unsigned int KMTransportDialog::authMethodsFromStringList( const QStringList & sl ) {
+ unsigned int result = 0;
+ for ( QStringList::const_iterator it = sl.begin() ; it != sl.end() ; ++it )
+ if ( *it == "LOGIN" )
+ result |= LOGIN;
+ else if ( *it == "PLAIN" )
+ result |= PLAIN;
+ else if ( *it == "CRAM-MD5" )
+ result |= CRAM_MD5;
+ else if ( *it == "DIGEST-MD5" )
+ result |= DIGEST_MD5;
+ else if ( *it == "NTLM" )
+ result |= NTLM;
+ else if ( *it == "GSSAPI" )
+ result |= GSSAPI;
+ return result;
+}
+
+void KMTransportDialog::slotCheckSmtpCapabilities()
+{
+ delete mServerTest;
+ mServerTest = new KMServerTest(SMTP_PROTOCOL, mSmtp.hostEdit->text(),
+ mSmtp.portEdit->text().toInt());
+ connect( mServerTest,
+ SIGNAL( capabilities( const QStringList &, const QStringList &,
+ const QString &, const QString &,
+ const QString & )),
+ this,
+ SLOT( slotSmtpCapabilities( const QStringList &,
+ const QStringList &, const QString &,
+ const QString &, const QString & ) ) );
+ mSmtp.checkCapabilities->setEnabled(false);
+}
+
+
+void KMTransportDialog::checkHighest(QButtonGroup *btnGroup)
+{
+ for ( int i = btnGroup->count() - 1; i >= 0 ; --i )
+ {
+ QButton * btn = btnGroup->find(i);
+ if (btn && btn->isEnabled())
+ {
+ btn->animateClick();
+ return;
+ }
+ }
+}
+
+
+void KMTransportDialog::slotSmtpCapabilities( const QStringList & capaNormal,
+ const QStringList & capaSSL,
+ const QString & authNone,
+ const QString & authSSL,
+ const QString & authTLS )
+{
+ mSmtp.checkCapabilities->setEnabled( true );
+ kdDebug(5006) << "KMTransportDialog::slotSmtpCapabilities( ..., "
+ << authNone << ", " << authSSL << ", " << authTLS << " )" << endl;
+ mSmtp.encryptionNone->setEnabled( !capaNormal.isEmpty() );
+ mSmtp.encryptionSSL->setEnabled( !capaSSL.isEmpty() );
+ mSmtp.encryptionTLS->setEnabled( capaNormal.findIndex("STARTTLS") != -1 );
+ if ( authNone.isEmpty() && authSSL.isEmpty() && authTLS.isEmpty() ) {
+ // slave doesn't seem to support "* AUTH METHODS" metadata (or server can't do AUTH)
+ mAuthNone = authMethodsFromStringList( capaNormal );
+ if ( mSmtp.encryptionTLS->isEnabled() )
+ mAuthTLS = mAuthNone;
+ else
+ mAuthTLS = 0;
+ mAuthSSL = authMethodsFromStringList( capaSSL );
+ }
+ else {
+ mAuthNone = authMethodsFromString( authNone );
+ mAuthSSL = authMethodsFromString( authSSL );
+ mAuthTLS = authMethodsFromString( authTLS );
+ }
+ kdDebug(5006) << "mAuthNone = " << mAuthNone
+ << "; mAuthSSL = " << mAuthSSL
+ << "; mAuthTLS = " << mAuthTLS << endl;
+ checkHighest( mSmtp.encryptionGroup );
+ delete mServerTest;
+ mServerTest = 0;
+}
+bool KMTransportDialog::sanityCheckSmtpInput()
+{
+ // FIXME: add additional checks for all fields that needs it
+ // this is only the beginning
+ if ( mSmtp.hostEdit->text().isEmpty() ) {
+ QString errorMsg = i18n("The Host field cannot be empty. Please "
+ "enter the name or the IP address of the SMTP server.");
+ KMessageBox::sorry( this, errorMsg, i18n("Invalid Hostname or Address") );
+ return false;
+ }
+ return true;
+}
+
+void KMTransportDialog::slotOk()
+{
+ if (mTransportInfo->type != "sendmail") {
+ if( !sanityCheckSmtpInput() ) {
+ return;
+ }
+ }
+
+ saveSettings();
+ accept();
+}
+
+
+#include "kmtransport.moc"