]> jfr.im git - solanum.git/commitdiff
mr_server: Report certificate fingerprint mismatches
authorSimon Arlott <sa.me.uk>
Sat, 23 Apr 2016 16:32:24 +0000 (17:32 +0100)
committerSimon Arlott <sa.me.uk>
Sat, 23 Apr 2016 16:37:05 +0000 (17:37 +0100)
Log the received certificate fingerprint when it causes a server to be
rejected.

ircd/s_serv.c
modules/core/m_server.c

index 4b449323bcf8a85e71e589b19fa44d63a2001390..6335c5767a66249c34c39e4d142741c435102bce 100644 (file)
@@ -347,6 +347,9 @@ check_server(const char *name, struct Client *client_p)
        rb_dlink_node *ptr;
        int error = -1;
        const char *encr;
+       bool name_matched = false;
+       bool host_matched = false;
+       bool certfp_failed = false;
 
        s_assert(NULL != client_p);
        if(client_p == NULL)
@@ -368,14 +371,14 @@ check_server(const char *name, struct Client *client_p)
                if(!match(tmp_p->name, name))
                        continue;
 
-               error = -3;
+               name_matched = true;
 
                /* XXX: Fix me for IPv6 */
                /* XXX sockhost is the IPv4 ip as a string */
                if(match(tmp_p->host, client_p->host) ||
                   match(tmp_p->host, client_p->sockhost))
                {
-                       error = -2;
+                       host_matched = true;
 
                        if(tmp_p->passwd)
                        {
@@ -397,8 +400,10 @@ check_server(const char *name, struct Client *client_p)
 
                        if(tmp_p->certfp)
                        {
-                               if(!client_p->certfp || rb_strcasecmp(tmp_p->certfp, client_p->certfp) != 0)
+                               if(!client_p->certfp || rb_strcasecmp(tmp_p->certfp, client_p->certfp) != 0) {
+                                       certfp_failed = true;
                                        continue;
+                               }
                        }
 
                        server_p = tmp_p;
@@ -407,7 +412,17 @@ check_server(const char *name, struct Client *client_p)
        }
 
        if(server_p == NULL)
+       {
+               /* return the most specific error */
+               if(certfp_failed)
+                       error = -6;
+               else if(host_matched)
+                       error = -2;
+               else if(name_matched)
+                       error = -3;
+
                return error;
+       }
 
        if(ServerConfSSL(server_p) && client_p->localClient->ssl_ctl == NULL)
        {
index f4e922bbeed131cbc36a321a3ce5d37d1d4de2f6..213d7f511f433a271c0d784340624a51d3e912d9 100644 (file)
@@ -188,6 +188,15 @@ mr_server(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sourc
 
                exit_client(client_p, client_p, client_p, "Access denied, requires SSL/TLS but is plaintext");
                return;
+       case -6:
+               sendto_realops_snomask(SNO_GENERAL, L_ALL,
+                    "Connection from servername %s has invalid certificate fingerprint %s",
+                    name, client_p->certfp);
+               ilog(L_SERVER, "Access denied, invalid certificate fingerprint %s from %s",
+                    client_p->certfp, log_client_name(client_p, SHOW_IP));
+
+               exit_client(client_p, client_p, client_p, "Invalid fingerprint.");
+               return;
        default:
                sendto_realops_snomask(SNO_GENERAL, L_ALL,
                     "Connection from servername %s rejected, unknown error %d",