Skip to content

Commit

Permalink
Fix failing tls upgrade of plain-to-plain botlink. Fixes #580
Browse files Browse the repository at this point in the history
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 e6f2fa1
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/dcc.c
Expand Up @@ -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);
}
Expand Down
4 changes: 4 additions & 0 deletions src/eggdrop.h
Expand Up @@ -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
*/
Expand Down
6 changes: 6 additions & 0 deletions src/net.c
Expand Up @@ -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);
}
Expand Down
3 changes: 3 additions & 0 deletions src/tls.c
Expand Up @@ -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.");
Expand Down

0 comments on commit e6f2fa1

Please sign in to comment.