mirror of
https://github.com/nextcloud/desktop.git
synced 2024-11-27 09:30:13 +03:00
Also store the CACertificates of the client side certificate
Else authentication will still fail in setups that have a chain of certificates supplied. Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>
This commit is contained in:
parent
dbde585049
commit
d584bedcb6
5 changed files with 79 additions and 12 deletions
|
@ -29,6 +29,7 @@ namespace {
|
|||
const char userC[] = "user";
|
||||
const char clientCertificatePEMC[] = "_clientCertificatePEM";
|
||||
const char clientKeyPEMC[] = "_clientKeyPEM";
|
||||
const char clientCaCertificatesPEMC[] = "_clientCaCertificatesPEM";
|
||||
} // ns
|
||||
|
||||
class WebFlowCredentialsAccessManager : public AccessManager
|
||||
|
@ -56,6 +57,12 @@ protected:
|
|||
QSslConfiguration sslConfiguration = req.sslConfiguration();
|
||||
sslConfiguration.setLocalCertificate(_cred->_clientSslCertificate);
|
||||
sslConfiguration.setPrivateKey(_cred->_clientSslKey);
|
||||
|
||||
// Merge client side CA with system CA
|
||||
auto ca = sslConfiguration.systemCaCertificates();
|
||||
ca.append(_cred->_clientSslCaCertificates);
|
||||
sslConfiguration.setCaCertificates(ca);
|
||||
|
||||
req.setSslConfiguration(sslConfiguration);
|
||||
}
|
||||
|
||||
|
@ -70,7 +77,7 @@ private:
|
|||
|
||||
static void addSettingsToJob(Account *account, QKeychain::Job *job)
|
||||
{
|
||||
Q_UNUSED(account);
|
||||
Q_UNUSED(account)
|
||||
auto settings = ConfigFile::settingsWithGroup(Theme::instance()->appName());
|
||||
settings->setParent(job); // make the job parent to make setting deleted properly
|
||||
job->setSettings(settings.release());
|
||||
|
@ -85,11 +92,12 @@ WebFlowCredentials::WebFlowCredentials()
|
|||
|
||||
}
|
||||
|
||||
WebFlowCredentials::WebFlowCredentials(const QString &user, const QString &password, const QSslCertificate &certificate, const QSslKey &key)
|
||||
WebFlowCredentials::WebFlowCredentials(const QString &user, const QString &password, const QSslCertificate &certificate, const QSslKey &key, const QList<QSslCertificate> &caCertificates)
|
||||
: _user(user)
|
||||
, _password(password)
|
||||
, _clientSslKey(key)
|
||||
, _clientSslCertificate(certificate)
|
||||
, _clientSslCaCertificates(caCertificates)
|
||||
, _ready(true)
|
||||
, _credentialsValid(true)
|
||||
, _keychainMigration(false)
|
||||
|
@ -163,7 +171,7 @@ void WebFlowCredentials::askFromUser() {
|
|||
}
|
||||
|
||||
void WebFlowCredentials::slotAskFromUserCredentialsProvided(const QString &user, const QString &pass, const QString &host) {
|
||||
Q_UNUSED(host);
|
||||
Q_UNUSED(host)
|
||||
|
||||
if (_user != user) {
|
||||
qCInfo(lcWebFlowCredentials()) << "Authed with the wrong user!";
|
||||
|
@ -246,6 +254,28 @@ void WebFlowCredentials::slotWriteClientCertPEMJobDone()
|
|||
}
|
||||
|
||||
void WebFlowCredentials::slotWriteClientKeyPEMJobDone()
|
||||
{
|
||||
// write ca certs if there are any
|
||||
if (!_clientSslCaCertificates.isEmpty()) {
|
||||
WritePasswordJob *job = new WritePasswordJob(Theme::instance()->appName());
|
||||
addSettingsToJob(_account, job);
|
||||
job->setInsecureFallback(false);
|
||||
connect(job, &Job::finished, this, &WebFlowCredentials::slotWriteClientCaCertsPEMJobDone);
|
||||
job->setKey(keychainKey(_account->url().toString(), _user + clientCaCertificatesPEMC, _account->id()));
|
||||
|
||||
QByteArray certs;
|
||||
for(auto cert:_clientSslCaCertificates) {
|
||||
certs += cert.toPem();
|
||||
}
|
||||
|
||||
job->setBinaryData(certs);
|
||||
job->start();
|
||||
} else {
|
||||
slotWriteClientCaCertsPEMJobDone();
|
||||
}
|
||||
}
|
||||
|
||||
void WebFlowCredentials::slotWriteClientCaCertsPEMJobDone()
|
||||
{
|
||||
WritePasswordJob *job = new WritePasswordJob(Theme::instance()->appName());
|
||||
addSettingsToJob(_account, job);
|
||||
|
@ -314,7 +344,7 @@ QString WebFlowCredentials::fetchUser() {
|
|||
}
|
||||
|
||||
void WebFlowCredentials::slotAuthentication(QNetworkReply *reply, QAuthenticator *authenticator) {
|
||||
Q_UNUSED(reply);
|
||||
Q_UNUSED(reply)
|
||||
|
||||
if (!_ready) {
|
||||
return;
|
||||
|
@ -415,6 +445,31 @@ void WebFlowCredentials::slotReadClientKeyPEMJobDone(QKeychain::Job *incomingJob
|
|||
}
|
||||
}
|
||||
|
||||
// Now fetch the actual server password
|
||||
const QString kck = keychainKey(
|
||||
_account->url().toString(),
|
||||
_user + clientCaCertificatesPEMC,
|
||||
_keychainMigration ? QString() : _account->id());
|
||||
|
||||
ReadPasswordJob *job = new ReadPasswordJob(Theme::instance()->appName());
|
||||
addSettingsToJob(_account, job);
|
||||
job->setInsecureFallback(false);
|
||||
job->setKey(kck);
|
||||
connect(job, &Job::finished, this, &WebFlowCredentials::slotReadClientCaCertsPEMJobDone);
|
||||
job->start();
|
||||
}
|
||||
|
||||
void WebFlowCredentials::slotReadClientCaCertsPEMJobDone(QKeychain::Job *incomingJob) {
|
||||
// Store key in memory
|
||||
ReadPasswordJob *readJob = static_cast<ReadPasswordJob *>(incomingJob);
|
||||
|
||||
if (readJob->error() == NoError && readJob->binaryData().length() > 0) {
|
||||
QList<QSslCertificate> sslCertificateList = QSslCertificate::fromData(readJob->binaryData(), QSsl::Pem);
|
||||
if (sslCertificateList.length() >= 1) {
|
||||
_clientSslCaCertificates = sslCertificateList;
|
||||
}
|
||||
}
|
||||
|
||||
// Now fetch the actual server password
|
||||
const QString kck = keychainKey(
|
||||
_account->url().toString(),
|
||||
|
|
|
@ -30,7 +30,12 @@ public:
|
|||
static constexpr QNetworkRequest::Attribute DontAddCredentialsAttribute = QNetworkRequest::User;
|
||||
|
||||
explicit WebFlowCredentials();
|
||||
WebFlowCredentials(const QString &user, const QString &password, const QSslCertificate &certificate = QSslCertificate(), const QSslKey &key = QSslKey());
|
||||
WebFlowCredentials(
|
||||
const QString &user,
|
||||
const QString &password,
|
||||
const QSslCertificate &certificate = QSslCertificate(),
|
||||
const QSslKey &key = QSslKey(),
|
||||
const QList<QSslCertificate> &caCertificates = QList<QSslCertificate>());
|
||||
|
||||
QString authType() const override;
|
||||
QString user() const override;
|
||||
|
@ -58,10 +63,12 @@ private slots:
|
|||
|
||||
void slotReadClientCertPEMJobDone(QKeychain::Job *incomingJob);
|
||||
void slotReadClientKeyPEMJobDone(QKeychain::Job *incomingJob);
|
||||
void slotReadClientCaCertsPEMJobDone(QKeychain::Job *incommingJob);
|
||||
void slotReadPasswordJobDone(QKeychain::Job *incomingJob);
|
||||
|
||||
void slotWriteClientCertPEMJobDone();
|
||||
void slotWriteClientKeyPEMJobDone();
|
||||
void slotWriteClientCaCertsPEMJobDone();
|
||||
void slotWriteJobDone(QKeychain::Job *);
|
||||
|
||||
protected:
|
||||
|
@ -69,7 +76,8 @@ protected:
|
|||
*
|
||||
* Goes through
|
||||
* slotReadClientCertPEMJobDone to
|
||||
* slotReadClientCertPEMJobDone to
|
||||
* slotReadClientKeyPEMJobDone to
|
||||
* slotReadClientCaCertsPEMJobDone to
|
||||
* slotReadJobDone
|
||||
*/
|
||||
void fetchFromKeychainHelper();
|
||||
|
@ -83,6 +91,7 @@ protected:
|
|||
QString _password;
|
||||
QSslKey _clientSslKey;
|
||||
QSslCertificate _clientSslCertificate;
|
||||
QList<QSslCertificate> _clientSslCaCertificates;
|
||||
|
||||
bool _ready;
|
||||
bool _credentialsValid;
|
||||
|
|
|
@ -136,7 +136,8 @@ AbstractCredentials *Flow2AuthCredsPage::getCredentials() const
|
|||
_user,
|
||||
_appPassword,
|
||||
ocWizard->_clientSslCertificate,
|
||||
ocWizard->_clientSslKey
|
||||
ocWizard->_clientSslKey,
|
||||
ocWizard->_clientSslCaCertificates
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -377,12 +377,13 @@ QString subjectInfoHelper(const QSslCertificate &cert, const QByteArray &qa)
|
|||
//called during the validation of the client certificate.
|
||||
void OwncloudSetupPage::slotCertificateAccepted()
|
||||
{
|
||||
QList<QSslCertificate> clientCaCertificates;
|
||||
QFile certFile(addCertDial->getCertificatePath());
|
||||
certFile.open(QFile::ReadOnly);
|
||||
if (QSslCertificate::importPkcs12(&certFile,
|
||||
&_ocWizard->_clientSslKey, &_ocWizard->_clientSslCertificate,
|
||||
&clientCaCertificates,
|
||||
if (QSslCertificate::importPkcs12(
|
||||
&certFile,
|
||||
&_ocWizard->_clientSslKey,
|
||||
&_ocWizard->_clientSslCertificate,
|
||||
&_ocWizard->_clientSslCaCertificates,
|
||||
addCertDial->getCertificatePasswd().toLocal8Bit())) {
|
||||
AccountPtr acc = _ocWizard->account();
|
||||
|
||||
|
@ -397,7 +398,7 @@ void OwncloudSetupPage::slotCertificateAccepted()
|
|||
|
||||
// Be sure to merge the CAs
|
||||
auto ca = sslConfiguration.systemCaCertificates();
|
||||
ca.append(clientCaCertificates);
|
||||
ca.append(_ocWizard->_clientSslCaCertificates);
|
||||
sslConfiguration.setCaCertificates(ca);
|
||||
|
||||
acc->setSslConfiguration(sslConfiguration);
|
||||
|
|
|
@ -78,6 +78,7 @@ public:
|
|||
// Set from the OwncloudSetupPage, later used from OwncloudHttpCredsPage
|
||||
QSslKey _clientSslKey;
|
||||
QSslCertificate _clientSslCertificate;
|
||||
QList<QSslCertificate> _clientSslCaCertificates;
|
||||
|
||||
public slots:
|
||||
void setAuthType(DetermineAuthTypeJob::AuthType type);
|
||||
|
|
Loading…
Reference in a new issue