Permalink
Browse files

Fix failing tls upgrade of plain-to-plain botlink. Fixes #580

Found by: maimizuno, Cizzle
Patch by: Cizzle
Fixes: #580 

Upgrading a starting botlink to use TLS when both hub and leaf used non-TLS ports (no +prefix) occasionally timed out for no apparent reason.

The failure happened due to the Client Hello of the TLS handshake arriving too soon and together with the "startls -" botlinkmessage at the hub causing that Client Hello to be missed by the TLS handshake.

The fix consists of two parts, one for the hub and one for the leaf. This way the fix is backward compatible for hubs having to deal with unpatched leafs and leafs having to deal with unpatched hubs.
  • Loading branch information...
Cizzle authored and vanosg committed Nov 18, 2018
1 parent ee03769 commit e6f2fa19bbc4ef9d0962464baefa259e2beda8e4
Showing with 18 additions and 0 deletions.
  1. +5 −0 src/dcc.c
  2. +4 −0 src/eggdrop.h
  3. +6 −0 src/net.c
  4. +3 −0 src/tls.c
@@ -1782,6 +1782,11 @@ static void dcc_telnet_pass(int idx, int atr)
* will simply ignore the request and everything will go on as usual.
*/
if (!dcc[idx].ssl) {
/* find number in socklist */
int i = findsock(dcc[idx].sock);
struct threaddata *td = threaddata();
/* mark socket to read next incoming at reduced len */
td->socklist[i].flags |= SOCK_SENTTLS;
dprintf(idx, "starttls\n");
putlog(LOG_BOTS, "*", "Sent STARTTLS to %s...", dcc[idx].nick);
}
@@ -652,6 +652,10 @@ typedef struct {
#define SOCK_VIRTUAL 0x0200 /* not-connected socket (dont read it!) */
#define SOCK_BUFFER 0x0400 /* buffer data; don't notify dcc funcs */
#define SOCK_TCL 0x0800 /* tcl socket, don't do anything on it */
#ifdef TLS
# define SOCK_SENTTLS 0x1000 /* Socket that awaits a starttls in the
* next read */
#endif
/* Flags to sock_has_data
*/
@@ -919,6 +919,12 @@ int sockread(char *s, int *len, sock_list *slist, int slistmax, int tclonly)
ERR_error_string(ERR_get_error(), 0), err);
x = -1;
}
} else if (slist[i].flags & SOCK_SENTTLS) {
/* We are awaiting a reply on our "starttls", only read
* strlen("starttls -\n") bytes so we don't accidently
* read the Client Hello from the ssl handshake */
x = read(slist[i].sock, s, strlen("starttls -\n"));
slist[i].flags &= ~SOCK_SENTTLS;
} else
x = read(slist[i].sock, s, grab);
}
@@ -780,7 +780,10 @@ int ssl_handshake(int sock, int flags, int verify, int loglevel, char *host,
SSL_set_mode(td->socklist[i].ssl, SSL_MODE_ENABLE_PARTIAL_WRITE |
SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
if (data->flags & TLS_CONNECT) {
struct timespec req = { 0, 1000000L };
SSL_set_verify(td->socklist[i].ssl, SSL_VERIFY_PEER, ssl_verify);
/* Introduce 1ms lag so an unpatched hub has time to setup the ssl handshake */
nanosleep(&req, NULL);
ret = SSL_connect(td->socklist[i].ssl);
if (!ret)
debug0("TLS: connect handshake failed.");

0 comments on commit e6f2fa1

Please sign in to comment.