kmail

kmtransport.cpp

Go to the documentation of this file.
00001 
00020 #include <config.h>
00021 #include <assert.h>
00022 
00023 #include "kmtransport.h"
00024 
00025 #include <qbuttongroup.h>
00026 #include <qcheckbox.h>
00027 #include <qlayout.h>
00028 #include <klineedit.h>
00029 #include <qradiobutton.h>
00030 #include <qtabwidget.h>
00031 #include <qvalidator.h>
00032 #include <qlabel.h>
00033 #include <qpushbutton.h>
00034 #include <qwhatsthis.h>
00035 
00036 #include <kfiledialog.h>
00037 #include <klocale.h>
00038 #include <kmessagebox.h>
00039 #include <kseparator.h>
00040 #include <kdebug.h>
00041 #include <kwallet.h>
00042 using KWallet::Wallet;
00043 #include <kprotocolinfo.h>
00044 
00045 #include "kmkernel.h"
00046 #include "kmservertest.h"
00047 #include "kmaccount.h"
00048 #include "protocols.h"
00049 #include "transportmanager.h"
00050 using namespace KMail;
00051 
00052 KMTransportInfo::KMTransportInfo() : mPasswdDirty( false ),
00053   mStorePasswd( false ), mStorePasswdInConfig( false ), mId( 0 )
00054 {
00055   name = i18n("Unnamed");
00056   port = "25";
00057   auth = false;
00058   specifyHostname = false;
00059 }
00060 
00061 
00062 KMTransportInfo::~KMTransportInfo()
00063 {
00064 }
00065 
00066 
00067 void KMTransportInfo::readConfig(int id)
00068 {
00069   KConfig *config = KMKernel::config();
00070   KConfigGroupSaver saver(config, "Transport " + QString::number(id));
00071   mId = config->readUnsignedNumEntry( "id", 0 );
00072   type = config->readEntry("type", "smtp");
00073   name = config->readEntry("name", i18n("Unnamed"));
00074   host = config->readEntry("host", "localhost");
00075   port = config->readEntry("port", "25");
00076   user = config->readEntry("user");
00077   mPasswd = KMAccount::decryptStr(config->readEntry("pass"));
00078   precommand = config->readPathEntry("precommand");
00079   encryption = config->readEntry("encryption");
00080   authType = config->readEntry("authtype");
00081   auth = config->readBoolEntry("auth");
00082   mStorePasswd = config->readBoolEntry("storepass");
00083   specifyHostname = config->readBoolEntry("specifyHostname", false);
00084   localHostname = config->readEntry("localHostname");
00085 
00086   if ( !storePasswd() )
00087     return;
00088 
00089   if ( !mPasswd.isEmpty() ) {
00090     // migration to kwallet if available
00091     if ( Wallet::isEnabled() ) {
00092       config->deleteEntry( "pass" );
00093       mPasswdDirty = true;
00094       mStorePasswdInConfig = false;
00095       writeConfig( id );
00096     } else
00097       mStorePasswdInConfig = true;
00098   } else {
00099     // read password if wallet is open, defer otherwise
00100     if ( Wallet::isOpen( Wallet::NetworkWallet() ) )
00101       readPassword();
00102   }
00103 }
00104 
00105 
00106 void KMTransportInfo::writeConfig(int id)
00107 {
00108   KConfig *config = KMKernel::config();
00109   KConfigGroupSaver saver(config, "Transport " + QString::number(id));
00110   if (!mId)
00111     mId = TransportManager::createId();
00112   config->writeEntry("id", mId);
00113   config->writeEntry("type", type);
00114   config->writeEntry("name", name);
00115   config->writeEntry("host", host);
00116   config->writeEntry("port", port);
00117   config->writeEntry("user", user);
00118   config->writePathEntry("precommand", precommand);
00119   config->writeEntry("encryption", encryption);
00120   config->writeEntry("authtype", authType);
00121   config->writeEntry("auth", auth);
00122   config->writeEntry("storepass", storePasswd());
00123   config->writeEntry("specifyHostname", specifyHostname);
00124   config->writeEntry("localHostname", localHostname);
00125 
00126   if ( storePasswd() ) {
00127     // write password into the wallet if possible and necessary
00128     bool passwdStored = false;
00129     Wallet *wallet = kmkernel->wallet();
00130     if ( mPasswdDirty ) {
00131       if ( wallet && wallet->writePassword( "transport-" + QString::number(mId), passwd() ) == 0 ) {
00132         passwdStored = true;
00133         mPasswdDirty = false;
00134         mStorePasswdInConfig = false;
00135       }
00136     } else {
00137       passwdStored = wallet ? !mStorePasswdInConfig /*already in the wallet*/ : config->hasKey("pass");
00138     }
00139     // wallet not available, ask the user if we should use the config file instead
00140     if ( !passwdStored && ( mStorePasswdInConfig ||  KMessageBox::warningYesNo( 0,
00141          i18n("KWallet is not available. It is strongly recommended to use "
00142               "KWallet for managing your passwords.\n"
00143               "However, KMail can store the password in its configuration "
00144               "file instead. The password is stored in an obfuscated format, "
00145               "but should not be considered secure from decryption efforts "
00146               "if access to the configuration file is obtained.\n"
00147               "Do you want to store the password for account '%1' in the "
00148               "configuration file?").arg( name ),
00149          i18n("KWallet Not Available"),
00150          KGuiItem( i18n("Store Password") ),
00151          KGuiItem( i18n("Do Not Store Password") ) )
00152          == KMessageBox::Yes ) ) {
00153       config->writeEntry( "pass", KMAccount::encryptStr( passwd() ) );
00154       mStorePasswdInConfig = true;
00155     }
00156   }
00157 
00158   // delete already stored password if password storage is disabled
00159   if ( !storePasswd() ) {
00160     if ( !Wallet::keyDoesNotExist(
00161           Wallet::NetworkWallet(), "kmail", "transport-" + QString::number(mId) ) ) {
00162       Wallet *wallet = kmkernel->wallet();
00163       if ( wallet )
00164         wallet->removeEntry( "transport-" + QString::number(mId) );
00165     }
00166     config->deleteEntry( "pass" );
00167   }
00168 }
00169 
00170 
00171 int KMTransportInfo::findTransport(const QString &name)
00172 {
00173   KConfig *config = KMKernel::config();
00174   KConfigGroupSaver saver(config, "General");
00175   int numTransports = config->readNumEntry("transports", 0);
00176   for (int i = 1; i <= numTransports; i++)
00177   {
00178     KConfigGroupSaver saver(config, "Transport " + QString::number(i));
00179     if (config->readEntry("name") == name) return i;
00180   }
00181   return 0;
00182 }
00183 
00184 
00185 QStringList KMTransportInfo::availableTransports()
00186 {
00187   QStringList result;
00188   KConfig *config = KMKernel::config();
00189   KConfigGroupSaver saver(config, "General");
00190   int numTransports = config->readNumEntry("transports", 0);
00191   for (int i = 1; i <= numTransports; i++)
00192   {
00193     KConfigGroupSaver saver(config, "Transport " + QString::number(i));
00194     result.append(config->readEntry("name"));
00195   }
00196   return result;
00197 }
00198 
00199 
00200 QString KMTransportInfo::passwd() const
00201 {
00202   if ( auth && storePasswd() && mPasswd.isEmpty() )
00203     readPassword();
00204   return mPasswd;
00205 }
00206 
00207 
00208 void KMTransportInfo::setPasswd( const QString &passwd )
00209 {
00210   if ( passwd != mPasswd ) {
00211     mPasswd = passwd;
00212     mPasswdDirty = true;
00213   }
00214 }
00215 
00216 
00217 void KMTransportInfo::setStorePasswd( bool store )
00218 {
00219   if ( mStorePasswd != store && store )
00220     mPasswdDirty = true;
00221   mStorePasswd = store;
00222 }
00223 
00224 
00225 void KMTransportInfo::readPassword() const
00226 {
00227   if ( !storePasswd() || !auth )
00228     return;
00229 
00230   // ### workaround for broken Wallet::keyDoesNotExist() which returns wrong
00231   // results for new entries without closing and reopening the wallet
00232   if ( Wallet::isOpen( Wallet::NetworkWallet() ) ) {
00233     Wallet* wallet = kmkernel->wallet();
00234     if ( !wallet || !wallet->hasEntry( "transport-" + QString::number(mId) ) )
00235       return;
00236   } else {
00237     if ( Wallet::keyDoesNotExist( Wallet::NetworkWallet(), "kmail", "transport-" + QString::number(mId) ) )
00238       return;
00239   }
00240 
00241   if ( kmkernel->wallet() )
00242     kmkernel->wallet()->readPassword( "transport-" + QString::number(mId), mPasswd );
00243 }
00244 
00245 
00246 KMTransportSelDlg::KMTransportSelDlg( QWidget *parent, const char *name,
00247   bool modal )
00248   : KDialogBase( parent, name, modal, i18n("Add Transport"), Ok|Cancel, Ok )
00249 {
00250   QFrame *page = makeMainWidget();
00251   QVBoxLayout *topLayout = new QVBoxLayout( page, 0, spacingHint() );
00252 
00253   QButtonGroup *group = new QButtonGroup( i18n("Transport"), page );
00254   connect(group, SIGNAL(clicked(int)), SLOT(buttonClicked(int)) );
00255 
00256   topLayout->addWidget( group, 10 );
00257   QVBoxLayout *vlay = new QVBoxLayout( group, spacingHint()*2, spacingHint() );
00258   vlay->addSpacing( fontMetrics().lineSpacing() );
00259 
00260   QRadioButton *radioButton1 = new QRadioButton( i18n("SM&TP"), group );
00261   vlay->addWidget( radioButton1 );
00262   QRadioButton *radioButton2 = new QRadioButton( i18n("&Sendmail"), group );
00263   vlay->addWidget( radioButton2 );
00264 
00265   vlay->addStretch( 10 );
00266 
00267   radioButton1->setChecked(true); // Pop is most common ?
00268   buttonClicked(0);
00269 }
00270 
00271 void KMTransportSelDlg::buttonClicked( int id )
00272 {
00273   mSelectedButton = id;
00274 }
00275 
00276 
00277 int KMTransportSelDlg::selected( void ) const
00278 {
00279   return mSelectedButton;
00280 }
00281 
00282 
00283 KMTransportDialog::KMTransportDialog( const QString & caption,
00284                       KMTransportInfo *transportInfo,
00285                       QWidget *parent, const char *name,
00286                       bool modal )
00287   : KDialogBase( parent, name, modal, caption, Ok|Cancel, Ok, true ),
00288     mServerTest( 0 ),
00289     mTransportInfo( transportInfo ),
00290     mAuthNone( AllAuth ), mAuthSSL( AllAuth ), mAuthTLS( AllAuth )
00291 {
00292   assert(transportInfo != 0);
00293 
00294   if( transportInfo->type == QString::fromLatin1("sendmail") )
00295   {
00296     makeSendmailPage();
00297   } else {
00298     makeSmtpPage();
00299   }
00300 
00301   setupSettings();
00302 }
00303 
00304 
00305 KMTransportDialog::~KMTransportDialog()
00306 {
00307 }
00308 
00309 
00310 void KMTransportDialog::makeSendmailPage()
00311 {
00312   QFrame *page = makeMainWidget();
00313   QVBoxLayout *topLayout = new QVBoxLayout( page, 0, spacingHint() );
00314 
00315   mSendmail.titleLabel = new QLabel( page );
00316   mSendmail.titleLabel->setText( i18n("Transport: Sendmail") );
00317   QFont titleFont( mSendmail.titleLabel->font() );
00318   titleFont.setBold( true );
00319   mSendmail.titleLabel->setFont( titleFont );
00320   topLayout->addWidget( mSendmail.titleLabel );
00321   KSeparator *hline = new KSeparator( KSeparator::HLine, page);
00322   topLayout->addWidget( hline );
00323 
00324   QGridLayout *grid = new QGridLayout( topLayout, 3, 3, spacingHint() );
00325   grid->addColSpacing( 1, fontMetrics().maxWidth()*15 );
00326   grid->setRowStretch( 2, 10 );
00327   grid->setColStretch( 1, 10 );
00328 
00329   QLabel *label = new QLabel( i18n("&Name:"), page );
00330   grid->addWidget( label, 0, 0 );
00331   mSendmail.nameEdit = new KLineEdit( page );
00332   label->setBuddy( mSendmail.nameEdit );
00333   grid->addWidget( mSendmail.nameEdit, 0, 1 );
00334 
00335   label = new QLabel( i18n("&Location:"), page );
00336   grid->addWidget( label, 1, 0 );
00337   mSendmail.locationEdit = new KLineEdit( page );
00338   label->setBuddy(mSendmail.locationEdit);
00339   grid->addWidget( mSendmail.locationEdit, 1, 1 );
00340   mSendmail.chooseButton =
00341     new QPushButton( i18n("Choos&e..."), page );
00342   connect( mSendmail.chooseButton, SIGNAL(clicked()),
00343            this, SLOT(slotSendmailChooser()) );
00344 
00345   connect( mSendmail.locationEdit, SIGNAL(textChanged ( const QString & )),
00346            this, SLOT(slotSendmailEditPath(const QString &)) );
00347 
00348   mSendmail.chooseButton->setAutoDefault( false );
00349   grid->addWidget( mSendmail.chooseButton, 1, 2 );
00350   slotSendmailEditPath(mSendmail.locationEdit->text());
00351 }
00352 
00353 void KMTransportDialog::slotSendmailEditPath(const QString & _text)
00354 {
00355   enableButtonOK( !_text.isEmpty() );
00356 }
00357 
00358 void KMTransportDialog::makeSmtpPage()
00359 {
00360   QFrame *page = makeMainWidget();
00361   QVBoxLayout *topLayout = new QVBoxLayout( page, 0, spacingHint() );
00362 
00363   mSmtp.titleLabel = new QLabel( page );
00364   mSmtp.titleLabel->setText( i18n("Transport: SMTP") );
00365   QFont titleFont( mSmtp.titleLabel->font() );
00366   titleFont.setBold( true );
00367   mSmtp.titleLabel->setFont( titleFont );
00368   topLayout->addWidget( mSmtp.titleLabel );
00369   KSeparator *hline = new KSeparator( KSeparator::HLine, page);
00370   topLayout->addWidget( hline );
00371 
00372   QTabWidget *tabWidget = new QTabWidget(page);
00373   topLayout->addWidget( tabWidget );
00374 
00375   QWidget *page1 = new QWidget( tabWidget );
00376   tabWidget->addTab( page1, i18n("&General") );
00377 
00378   QGridLayout *grid = new QGridLayout( page1, 14, 2, spacingHint() );
00379   grid->addColSpacing( 1, fontMetrics().maxWidth()*15 );
00380   grid->setRowStretch( 13, 10 );
00381   grid->setColStretch( 1, 10 );
00382 
00383   QLabel *label = new QLabel( i18n("&Name:"), page1 );
00384   grid->addWidget( label, 0, 0 );
00385   mSmtp.nameEdit = new KLineEdit( page1 );
00386   QWhatsThis::add(mSmtp.nameEdit,
00387                   i18n("The name that KMail will use when "
00388                        "referring to this server."));
00389   label->setBuddy( mSmtp.nameEdit );
00390   grid->addWidget( mSmtp.nameEdit, 0, 1 );
00391 
00392   label = new QLabel( i18n("&Host:"), page1 );
00393   grid->addWidget( label, 3, 0 );
00394   mSmtp.hostEdit = new KLineEdit( page1 );
00395   QWhatsThis::add(mSmtp.hostEdit,
00396                   i18n("The domain name or numerical address "
00397                        "of the SMTP server."));
00398   label->setBuddy( mSmtp.hostEdit );
00399   grid->addWidget( mSmtp.hostEdit, 3, 1 );
00400 
00401   label = new QLabel( i18n("&Port:"), page1 );
00402   grid->addWidget( label, 4, 0 );
00403   mSmtp.portEdit = new KLineEdit( page1 );
00404   mSmtp.portEdit->setValidator( new QIntValidator(this) );
00405   QWhatsThis::add(mSmtp.portEdit,
00406                   i18n("The port number that the SMTP server "
00407                        "is listening on. The default port is 25."));
00408   label->setBuddy( mSmtp.portEdit );
00409   grid->addWidget( mSmtp.portEdit, 4, 1 );
00410 
00411   label = new QLabel( i18n("Preco&mmand:"), page1 );
00412   grid->addWidget( label, 5, 0 );
00413   mSmtp.precommand = new KLineEdit( page1 );
00414   QWhatsThis::add(mSmtp.precommand,
00415                   i18n("A command to run locally, prior "
00416                        "to sending email. This can be used "
00417                        "to set up ssh tunnels, for example. "
00418                        "Leave it empty if no command should be run."));
00419   label->setBuddy(mSmtp.precommand);
00420   grid->addWidget( mSmtp.precommand, 5, 1 );
00421 
00422   QFrame* line = new QFrame( page1 );
00423   line->setFrameStyle( QFrame::HLine | QFrame::Plain );
00424   grid->addMultiCellWidget( line, 6, 6, 0, 1 );
00425 
00426   mSmtp.authCheck =
00427     new QCheckBox( i18n("Server &requires authentication"), page1 );
00428   QWhatsThis::add(mSmtp.authCheck,
00429                   i18n("Check this option if your SMTP server "
00430                        "requires authentication before accepting "
00431                        "mail. This is known as "
00432                        "'Authenticated SMTP' or simply ASMTP."));
00433   connect(mSmtp.authCheck, SIGNAL(clicked()),
00434           SLOT(slotRequiresAuthClicked()));
00435   grid->addMultiCellWidget( mSmtp.authCheck, 7, 7, 0, 1 );
00436 
00437   mSmtp.loginLabel = new QLabel( i18n("&Login:"), page1 );
00438   grid->addWidget( mSmtp.loginLabel, 8, 0 );
00439   mSmtp.loginEdit = new KLineEdit( page1 );
00440   mSmtp.loginLabel->setBuddy( mSmtp.loginEdit );
00441   QWhatsThis::add(mSmtp.loginEdit,
00442                   i18n("The user name to send to the server "
00443                        "for authorization"));
00444   grid->addWidget( mSmtp.loginEdit, 8, 1 );
00445 
00446   mSmtp.passwordLabel = new QLabel( i18n("P&assword:"), page1 );
00447   grid->addWidget( mSmtp.passwordLabel, 9, 0 );
00448   mSmtp.passwordEdit = new KLineEdit( page1 );
00449   mSmtp.passwordEdit->setEchoMode( QLineEdit::Password );
00450   mSmtp.passwordLabel->setBuddy( mSmtp.passwordEdit );
00451   QWhatsThis::add(mSmtp.passwordEdit,
00452                   i18n("The password to send to the server "
00453                        "for authorization"));
00454   grid->addWidget( mSmtp.passwordEdit, 9, 1 );
00455 
00456   mSmtp.storePasswordCheck =
00457     new QCheckBox( i18n("&Store SMTP password"), page1 );
00458   QWhatsThis::add(mSmtp.storePasswordCheck,
00459                   i18n("Check this option to have KMail store "
00460                   "the password.\nIf KWallet is available "
00461                   "the password will be stored there which is considered "
00462                   "safe.\nHowever, if KWallet is not available, "
00463                   "the password will be stored in KMail's configuration "
00464                   "file. The password is stored in an "
00465                   "obfuscated format, but should not be "
00466                   "considered secure from decryption efforts "
00467                   "if access to the configuration file is obtained."));
00468   grid->addMultiCellWidget( mSmtp.storePasswordCheck, 10, 10, 0, 1 );
00469 
00470   line = new QFrame( page1 );
00471   line->setFrameStyle( QFrame::HLine | QFrame::Plain );
00472   grid->addMultiCellWidget( line, 11, 11, 0, 1 );
00473 
00474   mSmtp.specifyHostnameCheck =
00475     new QCheckBox( i18n("Sen&d custom hostname to server"), page1 );
00476   grid->addMultiCellWidget( mSmtp.specifyHostnameCheck, 12, 12, 0, 1 );
00477   QWhatsThis::add(mSmtp.specifyHostnameCheck,
00478                   i18n("Check this option to have KMail use "
00479                        "a custom hostname when identifying itself "
00480                        "to the mail server."
00481                        "<p>This is useful when your system's hostname "
00482                        "may not be set correctly or to mask your "
00483                        "system's true hostname."));
00484 
00485   mSmtp.localHostnameLabel = new QLabel( i18n("Hos&tname:"), page1 );
00486   grid->addWidget( mSmtp.localHostnameLabel, 13, 0);
00487   mSmtp.localHostnameEdit = new KLineEdit( page1 );
00488   QWhatsThis::add(mSmtp.localHostnameEdit,
00489                   i18n("Enter the hostname KMail should use when "
00490                        "identifying itself to the server."));
00491   mSmtp.localHostnameLabel->setBuddy( mSmtp.localHostnameEdit );
00492   grid->addWidget( mSmtp.localHostnameEdit, 13, 1 );
00493   connect( mSmtp.specifyHostnameCheck, SIGNAL(toggled(bool)),
00494            mSmtp.localHostnameEdit, SLOT(setEnabled(bool)));
00495   connect( mSmtp.specifyHostnameCheck, SIGNAL(toggled(bool)),
00496            mSmtp.localHostnameLabel, SLOT(setEnabled(bool)));
00497 
00498   QWidget *page2 = new QWidget( tabWidget );
00499   tabWidget->addTab( page2, i18n("S&ecurity") );
00500   QVBoxLayout *vlay = new QVBoxLayout( page2, spacingHint() );
00501   mSmtp.encryptionGroup = new QButtonGroup( 1, Qt::Horizontal,
00502     i18n("Encryption"), page2 );
00503   mSmtp.encryptionNone =
00504     new QRadioButton( i18n("&None"), mSmtp.encryptionGroup );
00505   mSmtp.encryptionSSL =
00506     new QRadioButton( i18n("&SSL"), mSmtp.encryptionGroup );
00507   mSmtp.encryptionTLS =
00508     new QRadioButton( i18n("&TLS"), mSmtp.encryptionGroup );
00509   connect(mSmtp.encryptionGroup, SIGNAL(clicked(int)),
00510     SLOT(slotSmtpEncryptionChanged(int)));
00511   vlay->addWidget( mSmtp.encryptionGroup );
00512 
00513   mSmtp.authGroup = new QButtonGroup( 1, Qt::Horizontal,
00514     i18n("Authentication Method"), page2 );
00515   mSmtp.authLogin = new QRadioButton( i18n("Please translate this "
00516     "authentication method only if you have a good reason", "&LOGIN"),
00517     mSmtp.authGroup );
00518   mSmtp.authPlain = new QRadioButton( i18n("Please translate this "
00519     "authentication method only if you have a good reason", "&PLAIN"),
00520     mSmtp.authGroup  );
00521   mSmtp.authCramMd5 = new QRadioButton( i18n("CRAM-MD&5"), mSmtp.authGroup );
00522   mSmtp.authDigestMd5 = new QRadioButton( i18n("&DIGEST-MD5"), mSmtp.authGroup );
00523   mSmtp.authNTLM = new QRadioButton( i18n("&NTLM"), mSmtp.authGroup );
00524   mSmtp.authGSSAPI = new QRadioButton( i18n("&GSSAPI"), mSmtp.authGroup );
00525   if ( KProtocolInfo::capabilities("smtp").contains("SASL") == 0 ) {
00526     mSmtp.authNTLM->hide();
00527     mSmtp.authGSSAPI->hide();
00528   }
00529   vlay->addWidget( mSmtp.authGroup );
00530 
00531   vlay->addStretch();
00532 
00533   QHBoxLayout *buttonLay = new QHBoxLayout( vlay );
00534   mSmtp.checkCapabilities =
00535     new QPushButton( i18n("Check &What the Server Supports"), page2 );
00536   connect(mSmtp.checkCapabilities, SIGNAL(clicked()),
00537     SLOT(slotCheckSmtpCapabilities()));
00538   buttonLay->addStretch();
00539   buttonLay->addWidget( mSmtp.checkCapabilities );
00540 }
00541 
00542 
00543 void KMTransportDialog::setupSettings()
00544 {
00545   if (mTransportInfo->type == "sendmail")
00546   {
00547     mSendmail.nameEdit->setText(mTransportInfo->name);
00548     mSendmail.locationEdit->setText(mTransportInfo->host);
00549   } else {
00550     mSmtp.nameEdit->setText(mTransportInfo->name);
00551     mSmtp.hostEdit->setText(mTransportInfo->host);
00552     mSmtp.portEdit->setText(mTransportInfo->port);
00553     mSmtp.authCheck->setChecked(mTransportInfo->auth);
00554     mSmtp.loginEdit->setText(mTransportInfo->user);
00555     mSmtp.passwordEdit->setText(mTransportInfo->passwd());
00556     mSmtp.storePasswordCheck->setChecked(mTransportInfo->storePasswd());
00557     mSmtp.precommand->setText(mTransportInfo->precommand);
00558     mSmtp.specifyHostnameCheck->setChecked(mTransportInfo->specifyHostname);
00559     mSmtp.localHostnameEdit->setText(mTransportInfo->localHostname);
00560 
00561     if (mTransportInfo->encryption == "TLS")
00562       mSmtp.encryptionTLS->setChecked(true);
00563     else if (mTransportInfo->encryption == "SSL")
00564       mSmtp.encryptionSSL->setChecked(true);
00565     else mSmtp.encryptionNone->setChecked(true);
00566 
00567     if (mTransportInfo->authType == "LOGIN")
00568       mSmtp.authLogin->setChecked(true);
00569     else if (mTransportInfo->authType == "CRAM-MD5")
00570       mSmtp.authCramMd5->setChecked(true);
00571     else if (mTransportInfo->authType == "DIGEST-MD5")
00572       mSmtp.authDigestMd5->setChecked(true);
00573     else if (mTransportInfo->authType == "NTLM")
00574       mSmtp.authNTLM->setChecked(true);
00575     else if (mTransportInfo->authType == "GSSAPI")
00576       mSmtp.authGSSAPI->setChecked(true);
00577     else mSmtp.authPlain->setChecked(true);
00578 
00579     slotRequiresAuthClicked();
00580     mSmtp.localHostnameEdit->setEnabled(mTransportInfo->specifyHostname);
00581     mSmtp.localHostnameLabel->setEnabled(mTransportInfo->specifyHostname);
00582   }
00583 }
00584 
00585 
00586 void KMTransportDialog::saveSettings()
00587 {
00588   if (mTransportInfo->type == "sendmail")
00589   {
00590     mTransportInfo->name = mSendmail.nameEdit->text().stripWhiteSpace();
00591     mTransportInfo->host = mSendmail.locationEdit->text().stripWhiteSpace();
00592   } else {
00593     mTransportInfo->name = mSmtp.nameEdit->text();
00594     mTransportInfo->host = mSmtp.hostEdit->text().stripWhiteSpace();
00595     mTransportInfo->port = mSmtp.portEdit->text().stripWhiteSpace();
00596     mTransportInfo->auth = mSmtp.authCheck->isChecked();
00597     mTransportInfo->user = mSmtp.loginEdit->text().stripWhiteSpace();
00598     mTransportInfo->setPasswd( mSmtp.passwordEdit->text() );
00599     mTransportInfo->setStorePasswd( mSmtp.storePasswordCheck->isChecked() );
00600     mTransportInfo->precommand = mSmtp.precommand->text().stripWhiteSpace();
00601     mTransportInfo->specifyHostname = mSmtp.specifyHostnameCheck->isChecked();
00602     mTransportInfo->localHostname = mSmtp.localHostnameEdit->text().stripWhiteSpace();
00603 
00604     mTransportInfo->encryption = (mSmtp.encryptionTLS->isChecked()) ? "TLS" :
00605     (mSmtp.encryptionSSL->isChecked()) ? "SSL" : "NONE";
00606 
00607     mTransportInfo->authType = (mSmtp.authLogin->isChecked()) ? "LOGIN" :
00608     (mSmtp.authCramMd5->isChecked()) ? "CRAM-MD5" :
00609     (mSmtp.authDigestMd5->isChecked()) ? "DIGEST-MD5" :
00610     (mSmtp.authNTLM->isChecked()) ? "NTLM" :
00611     (mSmtp.authGSSAPI->isChecked()) ? "GSSAPI" : "PLAIN";
00612   }
00613 }
00614 
00615 
00616 void KMTransportDialog::slotSendmailChooser()
00617 {
00618   KFileDialog dialog("/", QString::null, this, 0, true );
00619   dialog.setCaption(i18n("Choose sendmail Location") );
00620 
00621   if( dialog.exec() == QDialog::Accepted )
00622   {
00623     KURL url = dialog.selectedURL();
00624     if( url.isEmpty() == true )
00625     {
00626       return;
00627     }
00628 
00629     if( url.isLocalFile() == false )
00630     {
00631       KMessageBox::sorry( 0, i18n( "Only local files allowed." ) );
00632       return;
00633     }
00634 
00635     mSendmail.locationEdit->setText( url.path() );
00636   }
00637 }
00638 
00639 
00640 void KMTransportDialog::slotRequiresAuthClicked()
00641 {
00642   bool b = mSmtp.authCheck->isChecked();
00643   mSmtp.loginLabel->setEnabled(b);
00644   mSmtp.loginEdit->setEnabled(b);
00645   mSmtp.passwordLabel->setEnabled(b);
00646   mSmtp.passwordEdit->setEnabled(b);
00647   mSmtp.storePasswordCheck->setEnabled(b);
00648   mSmtp.authGroup->setEnabled(b);
00649 }
00650 
00651 
00652 void KMTransportDialog::slotSmtpEncryptionChanged(int id)
00653 {
00654   kdDebug(5006) << "KMTransportDialog::slotSmtpEncryptionChanged( " << id << " )" << endl;
00655   // adjust SSL port:
00656   if (id == SSL || mSmtp.portEdit->text() == "465")
00657     mSmtp.portEdit->setText((id == SSL) ? "465" : "25");
00658 
00659   // switch supported auth methods:
00660   QButton * old = mSmtp.authGroup->selected();
00661   int authMethods = id == TLS ? mAuthTLS : id == SSL ? mAuthSSL : mAuthNone ;
00662   enableAuthMethods( authMethods );
00663   if ( !old->isEnabled() )
00664     checkHighest( mSmtp.authGroup );
00665 }
00666 
00667 void KMTransportDialog::enableAuthMethods( unsigned int auth ) {
00668   kdDebug(5006) << "KMTransportDialog::enableAuthMethods( " << auth << " )" << endl;
00669   mSmtp.authPlain->setEnabled( auth & PLAIN );
00670   // LOGIN doesn't offer anything over PLAIN, requires more server
00671   // roundtrips and is not an official SASL mechanism, but a MS-ism,
00672   // so only enable it if PLAIN isn't available:
00673   mSmtp.authLogin->setEnabled( auth & LOGIN && !(auth & PLAIN));
00674   mSmtp.authCramMd5->setEnabled( auth & CRAM_MD5 );
00675   mSmtp.authDigestMd5->setEnabled( auth & DIGEST_MD5 );
00676   mSmtp.authNTLM->setEnabled( auth & NTLM );
00677   mSmtp.authGSSAPI->setEnabled( auth & GSSAPI );
00678 }
00679 
00680 unsigned int KMTransportDialog::authMethodsFromString( const QString & s ) {
00681   unsigned int result = 0;
00682   QStringList sl = QStringList::split( '\n', s.upper() );
00683   for ( QStringList::const_iterator it = sl.begin() ; it != sl.end() ; ++it )
00684     if (  *it == "SASL/LOGIN" )
00685       result |= LOGIN;
00686     else if ( *it == "SASL/PLAIN" )
00687       result |= PLAIN;
00688     else if ( *it == "SASL/CRAM-MD5" )
00689       result |= CRAM_MD5;
00690     else if ( *it == "SASL/DIGEST-MD5" )
00691       result |= DIGEST_MD5;
00692     else if ( *it == "SASL/NTLM" )
00693       result |= NTLM;
00694     else if ( *it == "SASL/GSSAPI" )
00695       result |= GSSAPI;
00696   return result;
00697 }
00698 
00699 unsigned int KMTransportDialog::authMethodsFromStringList( const QStringList & sl ) {
00700   unsigned int result = 0;
00701   for ( QStringList::const_iterator it = sl.begin() ; it != sl.end() ; ++it )
00702     if ( *it == "LOGIN" )
00703       result |= LOGIN;
00704     else if ( *it == "PLAIN" )
00705       result |= PLAIN;
00706     else if ( *it == "CRAM-MD5" )
00707       result |= CRAM_MD5;
00708     else if ( *it == "DIGEST-MD5" )
00709       result |= DIGEST_MD5;
00710     else if ( *it == "NTLM" )
00711       result |= NTLM;
00712     else if ( *it == "GSSAPI" )
00713       result |= GSSAPI;
00714   return result;
00715 }
00716 
00717 void KMTransportDialog::slotCheckSmtpCapabilities()
00718 {
00719   delete mServerTest;
00720   mServerTest = new KMServerTest(SMTP_PROTOCOL, mSmtp.hostEdit->text(),
00721     mSmtp.portEdit->text().toInt());
00722   connect( mServerTest,
00723            SIGNAL( capabilities( const QStringList &, const QStringList &,
00724                                  const QString &, const QString &,
00725                                  const QString & )),
00726            this,
00727            SLOT( slotSmtpCapabilities( const QStringList &,
00728                                        const QStringList &, const QString &,
00729                                        const QString &, const QString & ) ) );
00730   mSmtp.checkCapabilities->setEnabled(false);
00731 }
00732 
00733 
00734 void KMTransportDialog::checkHighest(QButtonGroup *btnGroup)
00735 {
00736   for ( int i = btnGroup->count() - 1; i >= 0 ; --i )
00737   {
00738     QButton * btn = btnGroup->find(i);
00739     if (btn && btn->isEnabled())
00740     {
00741       btn->animateClick();
00742       return;
00743     }
00744   }
00745 }
00746 
00747 
00748 void KMTransportDialog::slotSmtpCapabilities( const QStringList & capaNormal,
00749                                               const QStringList & capaSSL,
00750                                               const QString & authNone,
00751                                               const QString & authSSL,
00752                                               const QString & authTLS )
00753 {
00754   mSmtp.checkCapabilities->setEnabled( true );
00755   kdDebug(5006) << "KMTransportDialog::slotSmtpCapabilities( ..., "
00756         << authNone << ", " << authSSL << ", " << authTLS << " )" << endl;
00757   mSmtp.encryptionNone->setEnabled( !capaNormal.isEmpty() );
00758   mSmtp.encryptionSSL->setEnabled( !capaSSL.isEmpty() );
00759   mSmtp.encryptionTLS->setEnabled( capaNormal.findIndex("STARTTLS") != -1 );
00760   if ( authNone.isEmpty() && authSSL.isEmpty() && authTLS.isEmpty() ) {
00761     // slave doesn't seem to support "* AUTH METHODS" metadata (or server can't do AUTH)
00762     mAuthNone = authMethodsFromStringList( capaNormal );
00763     if ( mSmtp.encryptionTLS->isEnabled() )
00764       mAuthTLS = mAuthNone;
00765     else
00766       mAuthTLS = 0;
00767     mAuthSSL = authMethodsFromStringList( capaSSL );
00768   }
00769   else {
00770     mAuthNone = authMethodsFromString( authNone );
00771     mAuthSSL = authMethodsFromString( authSSL );
00772     mAuthTLS = authMethodsFromString( authTLS );
00773   }
00774   kdDebug(5006) << "mAuthNone = " << mAuthNone
00775                 << "; mAuthSSL = " << mAuthSSL
00776                 << "; mAuthTLS = " << mAuthTLS << endl;
00777   checkHighest( mSmtp.encryptionGroup );
00778   delete mServerTest;
00779   mServerTest = 0;
00780 }
00781 bool KMTransportDialog::sanityCheckSmtpInput()
00782 {
00783   // FIXME: add additional checks for all fields that needs it
00784   // this is only the beginning
00785   if ( mSmtp.hostEdit->text().isEmpty() ) {
00786     QString errorMsg = i18n("The Host field cannot be empty. Please  "
00787                             "enter the name or the IP address of the SMTP server.");
00788     KMessageBox::sorry( this, errorMsg, i18n("Invalid Hostname or Address") );
00789     return false;
00790   }
00791   return true;
00792 }
00793 
00794 void KMTransportDialog::slotOk()
00795 {
00796   if (mTransportInfo->type != "sendmail") {
00797     if( !sanityCheckSmtpInput() ) {
00798       return;
00799     }
00800   }
00801 
00802   saveSettings();
00803   accept();
00804 }
00805 
00806 
00807 #include "kmtransport.moc"