diff options
| author | Alexander Barton <alex@barton.de> | 2024-01-02 21:10:17 +0100 |
|---|---|---|
| committer | Alexander Barton <alex@barton.de> | 2024-03-23 20:19:01 +0100 |
| commit | 679505aab9fea21b27a3d4bbf99cf2a16cf3d3d5 (patch) | |
| tree | 215a0a85e6b2397daacf27b7d66fda486713b2e2 /src | |
| parent | 08647ab1e7cf0d034f2d8987a3cac3201af84e02 (diff) | |
| download | ngircd-679505aab9fea21b27a3d4bbf99cf2a16cf3d3d5.tar.gz ngircd-679505aab9fea21b27a3d4bbf99cf2a16cf3d3d5.zip | |
S2S-TLS/OpenSSL: Fix handling of certificate information for incoming connections
Show proper certificate information for incoming connections, too, and not "peer did not present a certificate", regardless if the client sent a certificate or not. And free the client certificate structure "peer_cert" on incoming connections as well!
Diffstat (limited to 'src')
| -rw-r--r-- | src/ngircd/conn-ssl.c | 46 |
1 files changed, 30 insertions, 16 deletions
diff --git a/src/ngircd/conn-ssl.c b/src/ngircd/conn-ssl.c index a51f46b2..d89c11fe 100644 --- a/src/ngircd/conn-ssl.c +++ b/src/ngircd/conn-ssl.c @@ -935,22 +935,36 @@ ConnSSL_LogCertInfo( CONNECTION * c, bool connect) Log(LOG_INFO, "Connection %d: initialized %s using cipher %s, %s.", c->sock, SSL_get_version(ssl), SSL_get_cipher(ssl), comp_alg); peer_cert = SSL_get_peer_certificate(ssl); - if (peer_cert && connect) { + if (peer_cert) { cert_seen = true; - /* Client: Check server certificate */ - int err = SSL_get_verify_result(ssl); - if (err == X509_V_OK) { - const char *peername = SSL_get0_peername(ssl); - if (peername != NULL) - cert_ok = true; - LogDebug("X509_V_OK, peername = '%s'", peername); - } else - Log(LOG_ERR, "Certificate validation failed: %s", - X509_verify_cert_error_string(err)); - snprintf(msg, sizeof(msg), "%svalid peer certificate", - cert_ok ? "" : "in"); - LogOpenSSL_CertInfo(cert_ok ? LOG_DEBUG : LOG_ERR, peer_cert, - msg); + + if (connect) { + /* Outgoing connection. Verify the remote server! */ + int err = SSL_get_verify_result(ssl); + if (err == X509_V_OK) { + const char *peername = SSL_get0_peername(ssl); + if (peername != NULL) + cert_ok = true; + LogDebug("X509_V_OK, peername = '%s'", peername); + } else + Log(LOG_WARNING, "Certificate validation failed: %s!", + X509_verify_cert_error_string(err)); + + snprintf(msg, sizeof(msg), "Got %svalid server certificate", + cert_ok ? "" : "in"); + LogOpenSSL_CertInfo(LOG_INFO, peer_cert, msg); + } else { + /* Incoming connection. + * Accept all certificates, don't depend on their + * validity: for example, we don't know the hostname + * to check, because we not yet even know if this is a + * server connection at all and if so, which one, so we + * don't know a host name to look for. On the other + * hand we want client certificates, for example for + * "CertFP" authentication with services ... */ + LogOpenSSL_CertInfo(LOG_INFO, peer_cert, + "Got unchecked client certificate"); + } X509_free(peer_cert); } @@ -1038,7 +1052,7 @@ done_cn_validation: if (cert_ok) Conn_OPTION_ADD(c, CONN_SSL_PEERCERT_OK); if (!cert_seen) - Log(LOG_INFO, "Peer did not present a certificate"); + Log(LOG_INFO, "Peer did not present a certificate."); } |