auth_request_timeout, request);
hash_table_insert(handler->requests, POINTER_CAST(id), request);
+ /* If the provided certificate is not valid (untrusted CA signature),
+ we allow continuing only if there are fingerprints for the certificate
+ too. If there are no certificate fingerprints, we can already fail
+ here.
+
+ Actual validity is re-checked after authentication, so that
+ certificate fingeprints can be checked too.
+ */
if (request->set->ssl_require_client_cert &&
- !request->fields.valid_client_cert) {
+ !request->fields.valid_client_cert &&
+ (request->fields.ssl_client_cert_fp == NULL ||
+ *request->fields.ssl_client_cert_fp == '\0') &&
+ (request->fields.ssl_client_cert_pubkey_fp == NULL ||
+ *request->fields.ssl_client_cert_pubkey_fp == '\0')) {
/* we fail without valid certificate */
auth_request_handler_auth_fail(handler, request,
"Client didn't present valid SSL certificate");
enum passdb_result result)
{
i_assert(array_count(&request->authdb_event) > 0);
+
+ /* If client certificates are required, ensure that something
+ checked the certificate, either it was valid due to CA checks
+ or certificate fingerprint checks. */
+ if (result == PASSDB_RESULT_OK &&
+ request->set->ssl_require_client_cert &&
+ !request->fields.valid_client_cert) {
+ const char *reply = "Client didn't present valid SSL certificate";
+ request->failed = TRUE;
+ auth_request_set_field(request, "reason", reply, STATIC_PASS_SCHEME);
+ result = PASSDB_RESULT_PASSWORD_MISMATCH;
+ }
+
struct event *event = authdb_event(request);
struct event_passthrough *e =
event_create_passthrough(event)->