Skip to content
This repository has been archived by the owner on Jun 24, 2021. It is now read-only.

Add SNI support #305

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions include/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,8 @@ struct LocalUser
unsigned int sasl_messages;
unsigned int sasl_failures;
time_t sasl_next_retry;

char *sni;
};

#define AUTHC_F_DEFERRED 0x01
Expand Down
24 changes: 24 additions & 0 deletions ircd/sslproc.c
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,27 @@ ssl_process_certfp(ssl_ctl_t * ctl, ssl_ctl_buf_t * ctl_buf)
client_p->certfp = certfp_string;
}


static void
ssl_process_sni(ssl_ctl_t * ctl, ssl_ctl_buf_t * ctl_buf)
{
struct Client *client_p;
int32_t fd;
char *sni_string;

if(ctl_buf->buflen > 5 + RB_SSL_SNI_LEN)
return;

fd = buf_to_uint32(&ctl_buf->buf[1]);
client_p = find_cli_connid_hash(fd);
if(client_p == NULL)
return;
rb_free(client_p->localClient->sni);
sni_string = rb_malloc(ctl_buf->buflen - 4);
rb_strlcpy(sni_string, &ctl_buf->buf[5], ctl_buf->buflen - 0);
client_p->localClient->sni = sni_string;
}

static void
ssl_process_cmd_recv(ssl_ctl_t * ctl)
{
Expand Down Expand Up @@ -590,6 +611,9 @@ ssl_process_cmd_recv(ssl_ctl_t * ctl)
case 'z':
ircd_zlib_ok = 0;
break;
case 'n':
ssl_process_sni(ctl, ctl_buf);
break;
default:
ilog(L_MAIN, "Received invalid command from ssld: %s", ctl_buf->buf);
sendto_realops_snomask(SNO_GENERAL, L_ALL, "Received invalid command from ssld");
Expand Down
3 changes: 3 additions & 0 deletions librb/include/rb_commio.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ void rb_note(rb_fde_t *, const char *);
#define RB_SSL_CERTFP_LEN_SHA256 32
#define RB_SSL_CERTFP_LEN_SHA512 64

#define RB_SSL_SNI_LEN 250

int rb_set_nb(rb_fde_t *);
int rb_set_buffers(rb_fde_t *, int);

Expand Down Expand Up @@ -165,6 +167,7 @@ rb_platform_fd_t rb_get_fd(rb_fde_t *F);
const char *rb_get_ssl_strerror(rb_fde_t *F);
int rb_get_ssl_certfp(rb_fde_t *F, uint8_t certfp[RB_SSL_CERTFP_LEN], int method);
int rb_get_ssl_certfp_file(const char *filename, uint8_t certfp[RB_SSL_CERTFP_LEN], int method);
int rb_get_ssl_sni(rb_fde_t *F, uint8_t sni[static RB_SSL_SNI_LEN]);

rb_fde_t *rb_get_fde(rb_platform_fd_t fd);

Expand Down
1 change: 1 addition & 0 deletions librb/src/export-syms.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ rb_get_random
rb_get_sockerr
rb_get_ssl_certfp
rb_get_ssl_certfp_file
rb_get_ssl_sni
rb_get_ssl_strerror
rb_get_type
rb_getmaxconnect
Expand Down
21 changes: 21 additions & 0 deletions librb/src/openssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,27 @@ rb_get_ssl_strerror(rb_fde_t *const F)
return rb_ssl_strerror(F->ssl_errno);
}

int
rb_get_ssl_sni(rb_fde_t *F, uint8_t sni[static RB_SSL_SNI_LEN])
{
const char *openssl_sni;
size_t n;

if (F == NULL || F->ssl == NULL)
return 0;

openssl_sni = SSL_get_servername(F->ssl, TLSEXT_NAMETYPE_host_name);
if (openssl_sni == NULL)
return 0;

n = snprintf((char *)sni, RB_SSL_SNI_LEN, "%s", openssl_sni);

if (n == 0 || n > RB_SSL_SNI_LEN || n > INT_MAX)
return 0;

return (int)n;
}

int
rb_get_ssl_certfp(rb_fde_t *const F, uint8_t certfp[const RB_SSL_CERTFP_LEN], const int method)
{
Expand Down
7 changes: 7 additions & 0 deletions modules/m_whois.c
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,13 @@ single_whois(struct Client *source_p, struct Client *target_p, int operspy)
sendto_one_numeric(source_p, RPL_WHOISCERTFP,
form_str(RPL_WHOISCERTFP),
target_p->name, target_p->certfp);

if((source_p == target_p || IsOper(source_p)) &&
target_p->localClient != NULL &&
target_p->localClient->sni != NULL)
sendto_one_numeric(source_p, RPL_WHOISCERTFP,
"%s %s :Connected to hostname",
target_p->name, target_p->localClient->sni);
}

if(MyClient(target_p))
Expand Down
16 changes: 16 additions & 0 deletions ssld/ssld.c
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,21 @@ ssl_send_certfp(conn_t *conn)
mod_cmd_write_queue(conn->ctl, buf, 13 + len);
}

static void
ssl_send_sni(conn_t *conn)
{
uint8_t buf[5 + RB_SSL_SNI_LEN];

int len = rb_get_ssl_sni(conn->mod_fd, &buf[5]);
if (len == 0)
return;

lrb_assert(len <= RB_SSL_SNI_LEN);
buf[0] = 'n';
uint32_to_buf(&buf[1], conn->id);
mod_cmd_write_queue(conn->ctl, buf, 5 + len);
}

static void
ssl_send_open(conn_t *conn)
{
Expand All @@ -714,6 +729,7 @@ ssl_process_accept_cb(rb_fde_t *F, int status, struct sockaddr *addr, rb_socklen
{
ssl_send_cipher(conn);
ssl_send_certfp(conn);
ssl_send_sni(conn);
ssl_send_open(conn);
conn_mod_read_cb(conn->mod_fd, conn);
conn_plain_read_cb(conn->plain_fd, conn);
Expand Down