const char userC[] = "user";
const char clientCertificatePEMC[] = "_clientCertificatePEM";
const char clientKeyPEMC[] = "_clientKeyPEM";
+ const char clientCaCertificatesPEMC[] = "_clientCaCertificatesPEM";
} // ns
class WebFlowCredentialsAccessManager : public AccessManager
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);
}
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());
}
-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)
}
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!";
}
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);
}
void WebFlowCredentials::slotAuthentication(QNetworkReply *reply, QAuthenticator *authenticator) {
- Q_UNUSED(reply);
+ Q_UNUSED(reply)
if (!_ready) {
return;
}
}
+ // 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(),
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;
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:
*
* Goes through
* slotReadClientCertPEMJobDone to
- * slotReadClientCertPEMJobDone to
+ * slotReadClientKeyPEMJobDone to
+ * slotReadClientCaCertsPEMJobDone to
* slotReadJobDone
*/
void fetchFromKeychainHelper();
QString _password;
QSslKey _clientSslKey;
QSslCertificate _clientSslCertificate;
+ QList<QSslCertificate> _clientSslCaCertificates;
bool _ready;
bool _credentialsValid;
//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();
// Be sure to merge the CAs
auto ca = sslConfiguration.systemCaCertificates();
- ca.append(clientCaCertificates);
+ ca.append(_ocWizard->_clientSslCaCertificates);
sslConfiguration.setCaCertificates(ca);
acc->setSslConfiguration(sslConfiguration);