Commit 89669520 authored by Krzysztof Nowicki's avatar Krzysztof Nowicki
Browse files

Enable configuration of public key authentication

parent 7bd1befa
......@@ -52,6 +52,8 @@ static const QVector<StringPair> userAgents = {
{QStringLiteral("Mozilla Thunderbird 38 for Mac (with ExQuilla)"), QStringLiteral("Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:38.0) Gecko/20100101 Thunderbird/38.2.0")}
};
static const QString pkeyPasswordMapKey = QStringLiteral("pkey-password");
static bool execJob(KJob *job)
{
QEventLoop loop;
......@@ -127,10 +129,21 @@ EwsConfigDialog::EwsConfigDialog(EwsResource *parentResource, EwsClient &client,
mUi->authUsernameRadioButton->setChecked(true);
} else if (authMode == QStringLiteral("oauth2")) {
mUi->authOAuth2RadioButton->setChecked(true);
mUi->pkeyAuthGroupBox->setEnabled(true);
}
#else
mUi->authUsernameRadioButton->setChecked(true);
#endif
#ifdef HAVE_QCA
mUi->pkeyAuthCert->setText(mSettings->pKeyCert());
mUi->pkeyAuthKey->setText(mSettings->pKeyKey());
connect(mSettings.data(), &EwsSettings::mapRequestFinished, this, [&](const QMap<QString, QString> &map) {
if (map.contains(pkeyPasswordMapKey)) {
mUi->pkeyAuthPassword->setPassword(map[pkeyPasswordMapKey]);
}
});
mSettings->requestMap();
#endif
int selectedIndex = -1;
int i = 0;
......@@ -158,6 +171,9 @@ EwsConfigDialog::EwsConfigDialog(EwsResource *parentResource, EwsClient &client,
mUi->aboutLicenseLabel->setText(i18nc("@info", "Distributed under the GNU Library General Public License version 2.0 or later."));
mUi->aboutUrlLabel->setText(QStringLiteral("<a href=\"https://github.com/KrissN/akonadi-ews\">https://github.com/KrissN/akonadi-ews</a>"));
mUi->pkeyAuthCert->setMode(KFile::File | KFile::ExistingOnly | KFile::LocalOnly);
mUi->pkeyAuthKey->setMode(KFile::File | KFile::ExistingOnly | KFile::LocalOnly);
connect(okButton, &QPushButton::clicked, this, &EwsConfigDialog::save);
connect(mUi->autodiscoverButton, &QPushButton::clicked, this, &EwsConfigDialog::performAutoDiscovery);
connect(mUi->kcfg_Username, &KLineEdit::textChanged, this, &EwsConfigDialog::setAutoDiscoveryNeeded);
......@@ -165,6 +181,8 @@ EwsConfigDialog::EwsConfigDialog(EwsResource *parentResource, EwsClient &client,
connect(mUi->kcfg_Domain, &KLineEdit::textChanged, this, &EwsConfigDialog::setAutoDiscoveryNeeded);
connect(mUi->kcfg_HasDomain, &QCheckBox::toggled, this, &EwsConfigDialog::setAutoDiscoveryNeeded);
connect(mUi->kcfg_Email, &KLineEdit::textChanged, this, &EwsConfigDialog::setAutoDiscoveryNeeded);
connect(mUi->authUsernameRadioButton, &QRadioButton::toggled, this, &EwsConfigDialog::setAutoDiscoveryNeeded);
connect(mUi->authOAuth2RadioButton, &QRadioButton::toggled, this, &EwsConfigDialog::setAutoDiscoveryNeeded);
connect(mUi->kcfg_BaseUrl, &KLineEdit::textChanged, this, &EwsConfigDialog::enableTryConnect);
connect(mUi->tryConnectButton, &QPushButton::clicked, this, &EwsConfigDialog::tryConnect);
connect(mUi->userAgentCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &EwsConfigDialog::userAgentChanged);
......@@ -216,6 +234,16 @@ void EwsConfigDialog::save()
mSettings->setAuthMode(QStringLiteral("oauth2"));
}
#endif
#ifdef HAVE_QCA
if (mUi->pkeyAuthGroupBox->isEnabled() &&
!mUi->pkeyAuthCert->text().isEmpty() && !mUi->pkeyAuthKey->text().isEmpty()) {
mSettings->setPKeyCert(mUi->pkeyAuthCert->text());
mSettings->setPKeyKey(mUi->pkeyAuthKey->text());
const QMap<QString, QString> map = {{pkeyPasswordMapKey, mUi->pkeyAuthPassword->password()}};
mSettings->setMap(map);
}
#endif
if (!mAuthMap.isEmpty()) {
mSettings->setMap(mAuthMap);
}
......@@ -299,6 +327,8 @@ void EwsConfigDialog::setAutoDiscoveryNeeded()
okEnabled = false;
}
mButtonBox->button(QDialogButtonBox::Ok)->setEnabled(okEnabled);
mUi->pkeyAuthGroupBox->setEnabled(mUi->authOAuth2RadioButton->isChecked());
}
QString EwsConfigDialog::fullUsername() const
......@@ -435,6 +465,14 @@ EwsAbstractAuth *EwsConfigDialog::prepareAuth()
}
auth->setAuthParentWidget(this);
#ifdef HAVE_QCA
if (mUi->pkeyAuthGroupBox->isEnabled() &&
!mUi->pkeyAuthCert->text().isEmpty() && !mUi->pkeyAuthKey->text().isEmpty()) {
auth->setPKeyAuthCertificateFiles(mUi->pkeyAuthCert->text(), mUi->pkeyAuthKey->text());
mAuthMap[pkeyPasswordMapKey] = mUi->pkeyAuthPassword->password();
}
#endif
connect(auth, &EwsAbstractAuth::requestWalletPassword, this, [&](bool) {
auth->walletPasswordRequestFinished(mUi->passwordEdit->password());
});
......
......@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>602</width>
<height>551</height>
<height>665</height>
</rect>
</property>
<property name="windowTitle">
......@@ -172,7 +172,7 @@
</widget>
</item>
<item row="2" column="1">
<widget class="KPasswordLineEdit" name="passwordEdit">
<widget class="KPasswordLineEdit" name="passwordEdit" native="true">
<property name="whatsThis">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The password used to login to the Exchange server.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Note:&lt;/span&gt; This can be left empty when using Kerberos authentication.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
......@@ -306,6 +306,68 @@
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="pkeyAuthGroupBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="whatsThis">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Private Key (PKey) Authentication is used as an additional authentication step to OAuth2-based authentication. It uses an X.509 certificate and private key that identifies a trusted device, which was joined to the Azure Directory using a Workplace Join.&lt;/p&gt;&lt;p&gt;Some administrators may mandate use of PKey authentication when connecting to Office 365 from outside of corporate network. In other cases, when multi-factor authentication is set-up, using the PKey authentication can satisfy requirements for strong authentication, in which case entering the MFA code is not required.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="title">
<string>Private Key (PKey) Authentication (Office 365)</string>
</property>
<layout class="QFormLayout" name="pkeyAuthGroupBoxLayout">
<item row="0" column="0">
<widget class="QLabel" name="pkeyAuthCertLabel">
<property name="minimumSize">
<size>
<width>95</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Certificate:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="KUrlRequester" name="pkeyAuthCert" native="true">
<property name="filter" stdset="0">
<string notr="true">*.pem</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="pkeyAuthKeyLabel">
<property name="text">
<string>Private key:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="KUrlRequester" name="pkeyAuthKey" native="true">
<property name="filter" stdset="0">
<string notr="true">*.pem</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="pkeyAuthPasswordLabel">
<property name="text">
<string>Key password:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="KPasswordLineEdit" name="pkeyAuthPassword" native="true"/>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="generalTabSpacer">
<property name="orientation">
......@@ -699,6 +761,11 @@
<extends>QWidget</extends>
<header>kpasswordlineedit.h</header>
</customwidget>
<customwidget>
<class>KUrlRequester</class>
<extends>QWidget</extends>
<header>kurlrequester.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>tabWidget</tabstop>
......@@ -714,6 +781,9 @@
<tabstop>autodiscoverButton</tabstop>
<tabstop>tryConnectButton</tabstop>
<tabstop>kcfg_BaseUrl</tabstop>
<tabstop>pkeyAuthCert</tabstop>
<tabstop>pkeyAuthKey</tabstop>
<tabstop>pkeyAuthPassword</tabstop>
<tabstop>pollRadioButton</tabstop>
<tabstop>kcfg_PollInterval</tabstop>
<tabstop>streamingRadioButton</tabstop>
......
......@@ -68,6 +68,12 @@
<label>OAuth2 return URI</label>
<default>urn:ietf:wg:oauth:2.0:oob</default>
</entry>
<entry name="PKeyCert" type="String">
<label>Path to PKey authentication PEM certificate</label>
</entry>
<entry name="PKeyKey" type="String">
<label>Path to PKey authentication PEM private key</label>
</entry>
<entry name="SyncState" type="String" />
<entry name="FolderSyncState" type="String" />
<entry name="EventSubscriptionId" type="String" />
......
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