ssld: add a callback when the connection is opened
This allows us to wait until we have the fingerprint information before continuing with a server connect process.
This commit is contained in:
parent
fbbc6aeb00
commit
4fbb736202
5 changed files with 71 additions and 8 deletions
|
@ -275,6 +275,8 @@ struct LocalUser
|
||||||
struct _ssl_ctl *ssl_ctl; /* which ssl daemon we're associate with */
|
struct _ssl_ctl *ssl_ctl; /* which ssl daemon we're associate with */
|
||||||
struct _ssl_ctl *z_ctl; /* second ctl for ssl+zlib */
|
struct _ssl_ctl *z_ctl; /* second ctl for ssl+zlib */
|
||||||
struct ws_ctl *ws_ctl; /* ctl for wsockd */
|
struct ws_ctl *ws_ctl; /* ctl for wsockd */
|
||||||
|
CNCB *ssl_callback; /* ssl connection is now open */
|
||||||
|
void *ssl_data; /* data for callback */
|
||||||
uint32_t localflags;
|
uint32_t localflags;
|
||||||
struct ZipStats *zipstats; /* zipstats */
|
struct ZipStats *zipstats; /* zipstats */
|
||||||
uint16_t cork_count; /* used for corking/uncorking connections */
|
uint16_t cork_count; /* used for corking/uncorking connections */
|
||||||
|
|
|
@ -1166,6 +1166,8 @@ serv_connect_ssl_callback(rb_fde_t *F, int status, void *data)
|
||||||
|
|
||||||
}
|
}
|
||||||
client_p->localClient->F = xF[0];
|
client_p->localClient->F = xF[0];
|
||||||
|
client_p->localClient->ssl_callback = serv_connect_callback;
|
||||||
|
client_p->localClient->ssl_data = data;
|
||||||
|
|
||||||
client_p->localClient->ssl_ctl = start_ssld_connect(F, xF[1], connid_get(client_p));
|
client_p->localClient->ssl_ctl = start_ssld_connect(F, xF[1], connid_get(client_p));
|
||||||
if(!client_p->localClient->ssl_ctl)
|
if(!client_p->localClient->ssl_ctl)
|
||||||
|
@ -1174,7 +1176,6 @@ serv_connect_ssl_callback(rb_fde_t *F, int status, void *data)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SetSSL(client_p);
|
SetSSL(client_p);
|
||||||
serv_connect_callback(client_p->localClient->F, RB_OK, client_p);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1218,7 +1219,7 @@ serv_connect_callback(rb_fde_t *F, int status, void *data)
|
||||||
/* COMM_ERR_TIMEOUT wont have an errno associated with it,
|
/* COMM_ERR_TIMEOUT wont have an errno associated with it,
|
||||||
* the others will.. --fl
|
* the others will.. --fl
|
||||||
*/
|
*/
|
||||||
if(status == RB_ERR_TIMEOUT)
|
if(status == RB_ERR_TIMEOUT || status == RB_ERROR_SSL)
|
||||||
{
|
{
|
||||||
sendto_realops_snomask(SNO_GENERAL, is_remote_connect(client_p) ? L_NETWIDE : L_ALL,
|
sendto_realops_snomask(SNO_GENERAL, is_remote_connect(client_p) ? L_NETWIDE : L_ALL,
|
||||||
"Error connecting to %s[%s]: %s",
|
"Error connecting to %s[%s]: %s",
|
||||||
|
|
|
@ -387,6 +387,32 @@ ssl_process_zipstats(ssl_ctl_t * ctl, ssl_ctl_buf_t * ctl_buf)
|
||||||
zips->out_ratio = 0;
|
zips->out_ratio = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ssl_process_open_fd(ssl_ctl_t * ctl, ssl_ctl_buf_t * ctl_buf)
|
||||||
|
{
|
||||||
|
struct Client *client_p;
|
||||||
|
uint32_t fd;
|
||||||
|
|
||||||
|
if(ctl_buf->buflen < 5)
|
||||||
|
return; /* bogus message..drop it.. XXX should warn here */
|
||||||
|
|
||||||
|
fd = buf_to_uint32(&ctl_buf->buf[1]);
|
||||||
|
client_p = find_cli_connid_hash(fd);
|
||||||
|
if(client_p == NULL || client_p->localClient == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(client_p->localClient->ssl_callback)
|
||||||
|
{
|
||||||
|
CNCB *hdl = client_p->localClient->ssl_callback;
|
||||||
|
void *data = client_p->localClient->ssl_data;
|
||||||
|
|
||||||
|
client_p->localClient->ssl_callback = NULL;
|
||||||
|
client_p->localClient->ssl_data = NULL;
|
||||||
|
|
||||||
|
hdl(client_p->localClient->F, RB_OK, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ssl_process_dead_fd(ssl_ctl_t * ctl, ssl_ctl_buf_t * ctl_buf)
|
ssl_process_dead_fd(ssl_ctl_t * ctl, ssl_ctl_buf_t * ctl_buf)
|
||||||
{
|
{
|
||||||
|
@ -400,8 +426,30 @@ ssl_process_dead_fd(ssl_ctl_t * ctl, ssl_ctl_buf_t * ctl_buf)
|
||||||
fd = buf_to_uint32(&ctl_buf->buf[1]);
|
fd = buf_to_uint32(&ctl_buf->buf[1]);
|
||||||
rb_strlcpy(reason, &ctl_buf->buf[5], sizeof(reason));
|
rb_strlcpy(reason, &ctl_buf->buf[5], sizeof(reason));
|
||||||
client_p = find_cli_connid_hash(fd);
|
client_p = find_cli_connid_hash(fd);
|
||||||
if(client_p == NULL)
|
if(client_p == NULL || client_p->localClient == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if(IsAnyServer(client_p))
|
||||||
|
{
|
||||||
|
sendto_realops_snomask(SNO_GENERAL, is_remote_connect(client_p) && !IsServer(client_p) ? L_NETWIDE : L_ALL, "ssld error for %s: %s", client_p->name, reason);
|
||||||
|
ilog(L_SERVER, "ssld error for %s: %s", log_client_name(client_p, SHOW_IP), reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if there is still a pending callback, call it now */
|
||||||
|
if(client_p->localClient->ssl_callback)
|
||||||
|
{
|
||||||
|
CNCB *hdl = client_p->localClient->ssl_callback;
|
||||||
|
void *data = client_p->localClient->ssl_data;
|
||||||
|
|
||||||
|
client_p->localClient->ssl_callback = NULL;
|
||||||
|
client_p->localClient->ssl_data = NULL;
|
||||||
|
|
||||||
|
hdl(client_p->localClient->F, RB_ERROR_SSL, data);
|
||||||
|
|
||||||
|
/* the callback should have exited the client */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(IsAnyServer(client_p) || IsRegistered(client_p))
|
if(IsAnyServer(client_p) || IsRegistered(client_p))
|
||||||
{
|
{
|
||||||
/* read any last moment ERROR, QUIT or the like -- jilles */
|
/* read any last moment ERROR, QUIT or the like -- jilles */
|
||||||
|
@ -410,11 +458,6 @@ ssl_process_dead_fd(ssl_ctl_t * ctl, ssl_ctl_buf_t * ctl_buf)
|
||||||
if (IsAnyDead(client_p))
|
if (IsAnyDead(client_p))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(IsAnyServer(client_p))
|
|
||||||
{
|
|
||||||
sendto_realops_snomask(SNO_GENERAL, is_remote_connect(client_p) && !IsServer(client_p) ? L_NETWIDE : L_ALL, "ssld error for %s: %s", client_p->name, reason);
|
|
||||||
ilog(L_SERVER, "ssld error for %s: %s", log_client_name(client_p, SHOW_IP), reason);
|
|
||||||
}
|
|
||||||
exit_client(client_p, client_p, &me, reason);
|
exit_client(client_p, client_p, &me, reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -490,6 +533,9 @@ ssl_process_cmd_recv(ssl_ctl_t * ctl)
|
||||||
case 'N':
|
case 'N':
|
||||||
ircd_ssl_ok = false; /* ssld says it can't do ssl/tls */
|
ircd_ssl_ok = false; /* ssld says it can't do ssl/tls */
|
||||||
break;
|
break;
|
||||||
|
case 'O':
|
||||||
|
ssl_process_open_fd(ctl, ctl_buf);
|
||||||
|
break;
|
||||||
case 'D':
|
case 'D':
|
||||||
ssl_process_dead_fd(ctl, ctl_buf);
|
ssl_process_dead_fd(ctl, ctl_buf);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -95,6 +95,8 @@ mr_starttls(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sou
|
||||||
sendto_one_numeric(client_p, RPL_STARTTLS, form_str(RPL_STARTTLS));
|
sendto_one_numeric(client_p, RPL_STARTTLS, form_str(RPL_STARTTLS));
|
||||||
send_queued(client_p);
|
send_queued(client_p);
|
||||||
|
|
||||||
|
/* TODO: set localClient->ssl_callback and handle success/failure */
|
||||||
|
|
||||||
ctl = start_ssld_accept(client_p->localClient->F, F[1], connid_get(client_p));
|
ctl = start_ssld_accept(client_p->localClient->F, F[1], connid_get(client_p));
|
||||||
if (ctl != NULL)
|
if (ctl != NULL)
|
||||||
{
|
{
|
||||||
|
|
12
ssld/ssld.c
12
ssld/ssld.c
|
@ -699,6 +699,16 @@ ssl_send_certfp(conn_t *conn)
|
||||||
mod_cmd_write_queue(conn->ctl, buf, 9 + len);
|
mod_cmd_write_queue(conn->ctl, buf, 9 + len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ssl_send_open(conn_t *conn)
|
||||||
|
{
|
||||||
|
uint8_t buf[5];
|
||||||
|
|
||||||
|
buf[0] = 'O';
|
||||||
|
uint32_to_buf(&buf[1], conn->id);
|
||||||
|
mod_cmd_write_queue(conn->ctl, buf, 5);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ssl_process_accept_cb(rb_fde_t *F, int status, struct sockaddr *addr, rb_socklen_t len, void *data)
|
ssl_process_accept_cb(rb_fde_t *F, int status, struct sockaddr *addr, rb_socklen_t len, void *data)
|
||||||
{
|
{
|
||||||
|
@ -708,6 +718,7 @@ ssl_process_accept_cb(rb_fde_t *F, int status, struct sockaddr *addr, rb_socklen
|
||||||
{
|
{
|
||||||
ssl_send_cipher(conn);
|
ssl_send_cipher(conn);
|
||||||
ssl_send_certfp(conn);
|
ssl_send_certfp(conn);
|
||||||
|
ssl_send_open(conn);
|
||||||
conn_mod_read_cb(conn->mod_fd, conn);
|
conn_mod_read_cb(conn->mod_fd, conn);
|
||||||
conn_plain_read_cb(conn->plain_fd, conn);
|
conn_plain_read_cb(conn->plain_fd, conn);
|
||||||
return;
|
return;
|
||||||
|
@ -726,6 +737,7 @@ ssl_process_connect_cb(rb_fde_t *F, int status, void *data)
|
||||||
{
|
{
|
||||||
ssl_send_cipher(conn);
|
ssl_send_cipher(conn);
|
||||||
ssl_send_certfp(conn);
|
ssl_send_certfp(conn);
|
||||||
|
ssl_send_open(conn);
|
||||||
conn_mod_read_cb(conn->mod_fd, conn);
|
conn_mod_read_cb(conn->mod_fd, conn);
|
||||||
conn_plain_read_cb(conn->plain_fd, conn);
|
conn_plain_read_cb(conn->plain_fd, conn);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue