diff --git a/src/ldapconnection.cpp b/src/ldapconnection.cpp --- a/src/ldapconnection.cpp +++ b/src/ldapconnection.cpp @@ -297,7 +297,45 @@ //FIXME: accessing to certificate handling would be good qCDebug(LDAP_LOG) << "setting security to:" << d->mServer.security(); if (d->mServer.security() == LdapServer::TLS) { + bool initContext = false; + if (d->mServer.tlsCACertFile().isEmpty() == false) { + if(setOption(LDAP_OPT_X_TLS_CACERTFILE, d->mServer.tlsCACertFile().toUtf8().data()) != LDAP_OPT_SUCCESS) { + d->mConnectionError = i18n("Could not set CA certificate file."); + return -1; + } + initContext = true; + } + + if (d->mServer.tlsRequireCertificate() != LdapServer::TLSReqCertDefault) { + int reqcert; + switch (d->mServer.tlsRequireCertificate()) { + case LdapServer::TLSReqCertAllow: reqcert = LDAP_OPT_X_TLS_ALLOW; break; + case LdapServer::TLSReqCertDemand: reqcert = LDAP_OPT_X_TLS_DEMAND; break; + case LdapServer::TLSReqCertHard: reqcert = LDAP_OPT_X_TLS_HARD; break; + case LdapServer::TLSReqCertNever: reqcert = LDAP_OPT_X_TLS_NEVER; break; + case LdapServer::TLSReqCertTry: reqcert = LDAP_OPT_X_TLS_TRY; break; + default: + d->mConnectionError = i18n("Invalid TLS require certificate mode."); + return -1; + } + + if (setOption(LDAP_OPT_X_TLS_REQUIRE_CERT, &reqcert) != LDAP_OPT_SUCCESS) { + d->mConnectionError = i18n("Could not set TLS require certificate mode."); + return -1; + } + initContext = true; + } + + if (initContext) { + int isServer = 0; + if (setOption(LDAP_OPT_X_TLS_NEWCTX, &isServer) != LDAP_OPT_SUCCESS) { + d->mConnectionError = i18n("Could not initialize new TLS context."); + return -1; + } + } + qCDebug(LDAP_LOG) << "start TLS"; + #ifdef HAVE_LDAP_START_TLS_S if ((ret = ldap_start_tls_s(d->mLDAP, nullptr, nullptr)) != LDAP_SUCCESS) { d->mConnectionError = ldapErrorString(); diff --git a/src/ldapserver.h b/src/ldapserver.h --- a/src/ldapserver.h +++ b/src/ldapserver.h @@ -89,6 +89,19 @@ SASL ///< Azthenticate with the SASL framework. } Auth; + /** + * Describes the certificate request and check behaviour + * for TLS/SSL connections. + */ + typedef enum { + TLSReqCertDefault, ///< Use system defaults + TLSReqCertNever, ///< Do not require any certificates. + TLSReqCertDemand, ///< Use LDAP_OPT_X_TLS_DEMAND. + TLSReqCertAllow, ///< Use LDAP_OPT_X_TLS_ALLOW. + TLSReqCertTry, ///< Use LDAP_OPT_X_TLS_TRY. + TLSReqCertHard, ///< Use LDAP_OPT_X_TLS_HARD. + } TLSRequireCertificate; + /** * Clears all server settings. */ @@ -202,6 +215,26 @@ */ Auth auth() const; + /** + * Sets the certificate require mode for TLS/SSL connections + */ + void setTLSRequireCertificate(TLSRequireCertificate reqCert); + + /** + * Returns the certificate require mode for TLS/SSL connections + */ + TLSRequireCertificate tlsRequireCertificate() const; + + /** + * Sets the CA certificate file for TLS/SSL connections + */ + void setTLSCACertFile(const QString &caCertFile); + + /** + * Returns the CA certificate file used for TLS/SSL connections. + */ + QString tlsCACertFile() const; + /** * Sets the @p mech of the LDAP connection. */ diff --git a/src/ldapserver.cpp b/src/ldapserver.cpp --- a/src/ldapserver.cpp +++ b/src/ldapserver.cpp @@ -43,6 +43,8 @@ int mTimeout; Security mSecurity; Auth mAuth; + QString mTLSCACertFile; + TLSRequireCertificate mTLSRequireCertificate; LdapUrl::Scope mScope; int mCompletionWeight = -1; }; @@ -93,6 +95,8 @@ d->mPassword.clear(); d->mSecurity = None; d->mAuth = Anonymous; + d->mTLSRequireCertificate = TLSReqCertDefault; + d->mTLSCACertFile.clear(); d->mVersion = 3; d->mTimeout = 0; d->mSizeLimit = d->mTimeLimit = d->mPageSize = 0; @@ -174,6 +178,16 @@ return d->mAuth; } +LdapServer::TLSRequireCertificate LdapServer::tlsRequireCertificate() const +{ + return d->mTLSRequireCertificate; +} + +QString LdapServer::tlsCACertFile() const +{ + return d->mTLSCACertFile; +} + QString LdapServer::mech() const { return d->mMech; @@ -259,6 +273,16 @@ d->mAuth = auth; } +void LdapServer::setTLSRequireCertificate(LdapServer::TLSRequireCertificate reqCert) +{ + d->mTLSRequireCertificate = reqCert; +} + +void LdapServer::setTLSCACertFile(const QString &caCertFile) +{ + d->mTLSCACertFile = caCertFile; +} + void LdapServer::setMech(const QString &mech) { d->mMech = mech;