From c9c9ffd06f4751e9ffd714d80ab492316000c3ce Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 5 Jun 2016 14:43:34 +0100 Subject: Add initial support for client certificate fingerprints Networks such as Freenode and OFTC use client certificates to identify users and servers, not only for services, but also for server operator status and auth blocks. This allows us to use stronger certificates for authentication rather than passwords. --- src/conf_parser.y | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) (limited to 'src/conf_parser.y') diff --git a/src/conf_parser.y b/src/conf_parser.y index 0a71741..e91f79d 100644 --- a/src/conf_parser.y +++ b/src/conf_parser.y @@ -1693,6 +1693,8 @@ auth_entry: IRCD_AUTH conf->passwd = xstrdup(block_state.rpass.buf); if (block_state.name.buf[0]) conf->name = xstrdup(block_state.name.buf); + if (block_state.cert.buf[0]) + conf->certfp = xstrdup(block_state.cert.buf); conf->flags = block_state.flags.value; conf->port = block_state.port.value; @@ -1705,6 +1707,7 @@ auth_entry: IRCD_AUTH auth_items: auth_items auth_item | auth_item; auth_item: auth_user | auth_passwd | auth_class | auth_flags | auth_spoof | auth_redir_serv | auth_redir_port | + auth_ssl_certificate_fingerprint | auth_encrypted | error ';' ; auth_user: USER '=' QSTRING ';' @@ -1719,6 +1722,12 @@ auth_passwd: PASSWORD '=' QSTRING ';' strlcpy(block_state.rpass.buf, yylval.string, sizeof(block_state.rpass.buf)); }; +auth_ssl_certificate_fingerprint: SSL_CERTIFICATE_FINGERPRINT '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + strlcpy(block_state.cert.buf, yylval.string, sizeof(block_state.cert.buf)); +} + auth_class: CLASS '=' QSTRING ';' { if (conf_parser_ctx.pass == 2) @@ -2089,8 +2098,9 @@ connect_entry: CONNECT !block_state.host.buf[0]) break; - if (!block_state.rpass.buf[0] || - !block_state.spass.buf[0]) + if ((!block_state.rpass.buf[0] || + !block_state.spass.buf[0]) && + !block_state.cert.buf[0]) break; if (has_wildcards(block_state.name.buf) || @@ -2104,7 +2114,10 @@ connect_entry: CONNECT conf->host = xstrdup(block_state.host.buf); conf->name = xstrdup(block_state.name.buf); conf->passwd = xstrdup(block_state.rpass.buf); - conf->spasswd = xstrdup(block_state.spass.buf); + if (!block_state.spass.buf[0]) + conf->spasswd = xstrdup("certificate_auth"); + else + conf->spasswd = xstrdup(block_state.spass.buf); if (block_state.cert.buf[0]) conf->certfp = xstrdup(block_state.cert.buf); @@ -2383,7 +2396,7 @@ deny_reason: REASON '=' QSTRING ';' exempt_entry: EXEMPT '{' exempt_items '}' ';'; exempt_items: exempt_items exempt_item | exempt_item; -exempt_item: exempt_ip | error; +exempt_item: exempt_ip | exempt_ssl_certificate_fingerprint | error; exempt_ip: IP '=' QSTRING ';' { @@ -2399,6 +2412,18 @@ exempt_ip: IP '=' QSTRING ';' } }; +exempt_ssl_certificate_fingerprint: SSL_CERTIFICATE_FINGERPRINT '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + struct MaskItem *conf = conf_make(CONF_EXEMPT); + + conf->certfp = xstrdup(yylval.string); + conf->host = xstrdup(yylval.string); + add_conf_by_address(CONF_EXEMPT, conf); + } +} + /*************************************************************************** * section gecos ***************************************************************************/ -- cgit