diff --git a/ircd/s_serv.c b/ircd/s_serv.c index 4b449323b..6335c5767 100644 --- a/ircd/s_serv.c +++ b/ircd/s_serv.c @@ -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) { diff --git a/modules/core/m_server.c b/modules/core/m_server.c index f4e922bbe..213d7f511 100644 --- a/modules/core/m_server.c +++ b/modules/core/m_server.c @@ -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",