Commit 664d6a65 authored by Volker Krause's avatar Volker Krause
Browse files

Now that kio_smtp works again, add SMTP encryption and authentication

auto-detection.

svn path=/trunk/KDE/kdepim/mailtransport/; revision=615023
parent 38f21c4d
......@@ -29,8 +29,9 @@ TransportComboBox
TransportConfigDialog
---------------------
- enforce unique name
- SMTP auth method discovery (kio_smtp needs to fixed first)
- Sanity checks as in kmtransport
- adjust port and available auth methods on encryption change
- reset enc/auth selection when host changes
Transport
---------
......
......@@ -93,6 +93,7 @@
<choice name="NTLM"/>
<choice name="GSSAPI"/>
</choices>
<default>PLAIN</default>
</entry>
<entry name="specifyHostname" type="Bool">
<label><!-- TODO --></label>
......
......@@ -226,7 +226,20 @@
<property name="spacing" >
<number>6</number>
</property>
<item row="3" column="0" >
<item row="2" column="0" >
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>181</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="1" >
<spacer>
<property name="orientation" >
<enum>Qt::Vertical</enum>
......@@ -239,17 +252,20 @@
</property>
</spacer>
</item>
<item row="2" column="0" >
<item row="2" column="1" >
<widget class="KPushButton" name="checkCapabilities" >
<property name="text" >
<string>Check &amp;What the Server Supports</string>
</property>
</widget>
</item>
<item row="0" column="0" >
<widget class="KButtonGroup" name="kcfg_encryption" >
<item row="1" column="0" colspan="2" >
<widget class="KButtonGroup" name="kcfg_authenticationType" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="title" >
<string>Encryption</string>
<string>Authentication Method</string>
</property>
<layout class="QVBoxLayout" >
<property name="margin" >
......@@ -259,80 +275,80 @@
<number>6</number>
</property>
<item>
<widget class="QRadioButton" name="none" >
<widget class="QRadioButton" name="login" >
<property name="text" >
<string>&amp;None</string>
<string>&amp;LOGIN</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="ssl" >
<widget class="QRadioButton" name="plain" >
<property name="text" >
<string>&amp;SSL</string>
<string>&amp;PLAIN</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="tls" >
<widget class="QRadioButton" name="crammd5" >
<property name="text" >
<string>&amp;TLS</string>
<string>CRAM-MD&amp;5</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0" >
<widget class="KButtonGroup" name="kcfg_authenticationType" >
<property name="title" >
<string>Authentication Method</string>
</property>
<layout class="QVBoxLayout" >
<property name="margin" >
<number>9</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<item>
<widget class="QRadioButton" name="login" >
<widget class="QRadioButton" name="digestmd5" >
<property name="text" >
<string>&amp;LOGIN</string>
<string>&amp;DIGEST-MD5</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="plain" >
<widget class="QRadioButton" name="ntlm" >
<property name="text" >
<string>&amp;PLAIN</string>
<string>&amp;NTLM</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="crammd5" >
<widget class="QRadioButton" name="gssapi" >
<property name="text" >
<string>CRAM-MD&amp;5</string>
<string>&amp;GSSAPI</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="0" colspan="2" >
<widget class="KButtonGroup" name="kcfg_encryption" >
<property name="title" >
<string>Encryption</string>
</property>
<layout class="QVBoxLayout" >
<property name="margin" >
<number>9</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<item>
<widget class="QRadioButton" name="digestmd5" >
<widget class="QRadioButton" name="none" >
<property name="text" >
<string>&amp;DIGEST-MD5</string>
<string>&amp;None</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="ntlm" >
<widget class="QRadioButton" name="ssl" >
<property name="text" >
<string>&amp;NTLM</string>
<string>&amp;SSL</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="gssapi" >
<widget class="QRadioButton" name="tls" >
<property name="text" >
<string>&amp;GSSAPI</string>
<string>&amp;TLS</string>
</property>
</widget>
</item>
......@@ -348,26 +364,26 @@
<layoutfunction spacing="KDialog::spacingHint()" margin="KDialog::marginHint()" />
<customwidgets>
<customwidget>
<class>KSeparator</class>
<extends>QFrame</extends>
<header>kseparator.h</header>
<class>KButtonGroup</class>
<extends>QGroupBox</extends>
<header>kbuttongroup.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>KPushButton</class>
<extends>QPushButton</extends>
<header>kpushbutton.h</header>
</customwidget>
<customwidget>
<class>KSeparator</class>
<extends>QFrame</extends>
<header>kseparator.h</header>
</customwidget>
<customwidget>
<class>KLineEdit</class>
<extends>QLineEdit</extends>
<header>klineedit.h</header>
</customwidget>
<customwidget>
<class>KButtonGroup</class>
<extends>QGroupBox</extends>
<header>kbuttongroup.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>tabWidget</tabstop>
......@@ -401,12 +417,12 @@
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel" >
<x>130</x>
<y>233</y>
<x>141</x>
<y>215</y>
</hint>
<hint type="destinationlabel" >
<x>156</x>
<y>289</y>
<x>162</x>
<y>242</y>
</hint>
</hints>
</connection>
......@@ -417,12 +433,12 @@
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel" >
<x>217</x>
<y>256</y>
<x>228</x>
<y>215</y>
</hint>
<hint type="destinationlabel" >
<x>223</x>
<y>324</y>
<x>229</x>
<y>271</y>
</hint>
</hints>
</connection>
......@@ -433,12 +449,12 @@
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel" >
<x>57</x>
<y>232</y>
<x>68</x>
<y>215</y>
</hint>
<hint type="destinationlabel" >
<x>68</x>
<y>291</y>
<x>78</x>
<y>244</y>
</hint>
</hints>
</connection>
......@@ -449,12 +465,12 @@
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel" >
<x>107</x>
<y>256</y>
<x>118</x>
<y>215</y>
</hint>
<hint type="destinationlabel" >
<x>91</x>
<y>326</y>
<x>78</x>
<y>273</y>
</hint>
</hints>
</connection>
......@@ -465,12 +481,12 @@
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel" >
<x>189</x>
<y>399</y>
<x>200</x>
<y>334</y>
</hint>
<hint type="destinationlabel" >
<x>187</x>
<y>432</y>
<x>193</x>
<y>361</y>
</hint>
</hints>
</connection>
......@@ -481,12 +497,12 @@
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel" >
<x>109</x>
<y>399</y>
<x>120</x>
<y>334</y>
</hint>
<hint type="destinationlabel" >
<x>108</x>
<y>434</y>
<x>78</x>
<y>363</y>
</hint>
</hints>
</connection>
......@@ -497,12 +513,28 @@
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel" >
<x>39</x>
<y>242</y>
<x>50</x>
<y>215</y>
</hint>
<hint type="destinationlabel" >
<x>58</x>
<y>299</y>
</hint>
</hints>
</connection>
<connection>
<sender>kcfg_requiresAuthentication</sender>
<signal>toggled(bool)</signal>
<receiver>kcfg_authenticationType</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel" >
<x>215</x>
<y>205</y>
</hint>
<hint type="destinationlabel" >
<x>47</x>
<y>344</y>
<x>215</x>
<y>285</y>
</hint>
</hints>
</connection>
......
......@@ -32,6 +32,8 @@
#include <kmessagebox.h>
#include <kprotocolinfo.h>
#include <QButtonGroup>
using namespace KPIM;
class KPIM::TransportConfigDialog::Private
......@@ -45,6 +47,44 @@ class KPIM::TransportConfigDialog::Private
KConfigDialogManager* manager;
KLineEdit* passwordEdit;
ServerTest* serverTest;
QButtonGroup* encryptionGroup;
QButtonGroup* authGroup;
// detected authentication capabilities
QList<int> noEncCapa, sslCapa, tlsCapa;
void resetAuthCapabilities()
{
noEncCapa.clear();
noEncCapa << Transport::EnumAuthenticationType::LOGIN
<< Transport::EnumAuthenticationType::PLAIN
<< Transport::EnumAuthenticationType::CRAM_MD5
<< Transport::EnumAuthenticationType::DIGEST_MD5
<< Transport::EnumAuthenticationType::NTLM
<< Transport::EnumAuthenticationType::GSSAPI;
sslCapa = tlsCapa = noEncCapa;
if ( authGroup )
updateAuthCapbilities();
}
void updateAuthCapbilities()
{
Q_ASSERT( transport->type() == Transport::EnumType::SMTP );
QList<int> capa = noEncCapa;
if ( smtp.ssl->isChecked() )
capa = sslCapa;
else if ( smtp.tls->isChecked() )
capa = tlsCapa;
for ( int i = 0; i < authGroup->buttons().count(); ++i )
authGroup->buttons().at( i )->setEnabled( capa.contains( i ) );
// 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:
if ( capa.contains( Transport::EnumAuthenticationType::PLAIN ) )
smtp.login->setEnabled( false );
}
};
TransportConfigDialog::TransportConfigDialog( Transport* transport, QWidget * parent) :
......@@ -56,6 +96,8 @@ TransportConfigDialog::TransportConfigDialog( Transport* transport, QWidget * pa
d->transport = transport;
d->passwordEdit = 0;
d->serverTest = 0;
d->authGroup = 0;
d->resetAuthCapabilities();
setButtons( Ok|Cancel );
connect( this, SIGNAL(okClicked()), SLOT(save()) );
......@@ -67,6 +109,19 @@ TransportConfigDialog::TransportConfigDialog( Transport* transport, QWidget * pa
d->smtp.setupUi( mainWidget() );
d->passwordEdit = d->smtp.password;
d->encryptionGroup = new QButtonGroup( this );
d->encryptionGroup->addButton( d->smtp.none );
d->encryptionGroup->addButton( d->smtp.ssl );
d->encryptionGroup->addButton( d->smtp.tls );
d->authGroup = new QButtonGroup( this );
d->authGroup->addButton( d->smtp.login );
d->authGroup->addButton( d->smtp.plain );
d->authGroup->addButton( d->smtp.crammd5 );
d->authGroup->addButton( d->smtp.digestmd5 );
d->authGroup->addButton( d->smtp.ntlm );
d->authGroup->addButton( d->smtp.gssapi );
if ( KProtocolInfo::capabilities("smtp").contains("SASL") == 0 ) {
d->smtp.ntlm->hide();
d->smtp.gssapi->hide();
......@@ -148,12 +203,78 @@ void TransportConfigDialog::passwordsLoaded()
d->passwordEdit->setText( d->transport->password() );
}
static QList<int> authMethodsFromStringList( const QStringList &list )
{
QList<int> result;
for ( QStringList::ConstIterator it = list.begin() ; it != list.end() ; ++it ) {
if ( *it == "LOGIN" )
result << Transport::EnumAuthenticationType::LOGIN;
else if ( *it == "PLAIN" )
result << Transport::EnumAuthenticationType::PLAIN;
else if ( *it == "CRAM-MD5" )
result << Transport::EnumAuthenticationType::CRAM_MD5;
else if ( *it == "DIGEST-MD5" )
result << Transport::EnumAuthenticationType::DIGEST_MD5;
else if ( *it == "NTLM" )
result << Transport::EnumAuthenticationType::NTLM;
else if ( *it == "GSSAPI" )
result << Transport::EnumAuthenticationType::GSSAPI;
}
return result;
}
static QList<int> authMethodsFromString( const QString &s )
{
QStringList list;
foreach ( QString tmp, s.toUpper().split( '\n', QString::SkipEmptyParts ) )
list << tmp.remove( "SASL/" );
return authMethodsFromStringList( list );
}
static void checkHighestEnabledButton( QButtonGroup *group )
{
Q_ASSERT( group );
for ( int i = group->buttons().count() - 1; i >= 0 ; --i ) {
QAbstractButton *b = group->buttons().at( i );
if ( b && b->isEnabled() ) {
b->animateClick();
return;
}
}
}
void TransportConfigDialog::smtpCapabilities( const QStringList &capaNormal, const QStringList &capaSSL,
const QString &authNone, const QString &authSSL, const QString &authTLS )
{
kDebug() << k_funcinfo << capaNormal << capaSSL << authNone << authSSL << authTLS << endl;
d->smtp.checkCapabilities->setEnabled( true );
// TODO: need to fix kio_smtp first
// encryption method
d->smtp.none->setEnabled( !capaNormal.isEmpty() );
d->smtp.ssl->setEnabled( !capaSSL.isEmpty() );
d->smtp.tls->setEnabled( capaNormal.indexOf("STARTTLS") != -1 );
checkHighestEnabledButton( d->encryptionGroup );
// authentication methods
if ( authNone.isEmpty() && authSSL.isEmpty() && authTLS.isEmpty() ) {
// slave doesn't seem to support "* AUTH METHODS" metadata (or server can't do AUTH)
d->noEncCapa = authMethodsFromStringList( capaNormal );
if ( d->smtp.tls->isEnabled() )
d->tlsCapa = d->noEncCapa;
else
d->tlsCapa.clear();
d->sslCapa = authMethodsFromStringList( capaSSL );
} else {
d->noEncCapa = authMethodsFromString( authNone );
d->sslCapa = authMethodsFromString( authSSL );
d->tlsCapa = authMethodsFromString( authTLS );
}
d->updateAuthCapbilities();
checkHighestEnabledButton( d->authGroup );
delete d->serverTest;
d->serverTest = 0;
}
#include "transportconfigdialog.moc"
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment