Retry cleartext connection in case TLS failed - sacc - sacc(omys), simple console gopher client (HTM) git clone git://bitreich.org/sacc/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/sacc/ (DIR) Log (DIR) Files (DIR) Refs (DIR) Tags (DIR) LICENSE --- (DIR) commit 7e0793d8395184b5b21ecdd0b13bccb524d1e414 (DIR) parent 4aa1ecfaf6c97cb02c7e34c88cc67c070b600b67 (HTM) Author: Quentin Rameau <quinq@fifth.space> Date: Sun, 11 Apr 2021 17:12:00 +0200 Retry cleartext connection in case TLS failed Diffstat: M io_tls.c | 33 ++++++++++++++++++++++++++----- M sacc.c | 32 ++++++++++++++++--------------- 2 files changed, 45 insertions(+), 20 deletions(-) --- (DIR) diff --git a/io_tls.c b/io_tls.c @@ -1,3 +1,4 @@ +#include <stdlib.h> #include <string.h> #include <unistd.h> #include <netdb.h> @@ -32,6 +33,7 @@ static int connect_tls(struct cnx *c, struct addrinfo *ai, const char *host) { struct tls *t; + char *r; int s; c->tls = NULL; @@ -43,13 +45,34 @@ connect_tls(struct cnx *c, struct addrinfo *ai, const char *host) if (tls) { if ((t = tls_client()) == NULL) return -1; - if (tls_connect_socket(t, s, host) == -1) - return -1; - - c->tls = t; + if (tls_connect_socket(t, s, host) == 0) { + do { + s = tls_handshake(t); + } while (s == TLS_WANT_POLLIN || s == TLS_WANT_POLLOUT); + if (s == 0) { + c->tls = t; + } else { + diag("Can't establish TLS with \"%s\": %s", + host, tls_error(t)); + r = uiprompt("Retry on cleartext? [Yn]: "); + switch (*r) { + case 'Y': + case 'y': + case '\0': + tls = 0; + s = -2; + break; + default: + s = -3; + } + free(r); + } + } else { + s = -1; + } } - return 0; + return s; } static void (DIR) diff --git a/sacc.c b/sacc.c @@ -491,8 +491,8 @@ connectto(const char *host, const char *port, struct cnx *c) .ai_socktype = SOCK_STREAM, .ai_protocol = IPPROTO_TCP, }; - struct addrinfo *addrs, *addr; - int r, err; + struct addrinfo *addrs, *ai; + int r, err, conn; sigemptyset(&set); sigaddset(&set, SIGWINCH); @@ -505,18 +505,20 @@ connectto(const char *host, const char *port, struct cnx *c) } r = -1; - for (addr = addrs; addr; addr = addr->ai_next) { - if ((c->sock = socket(addr->ai_family, addr->ai_socktype, - addr->ai_protocol)) == -1) { - err = errno; - continue; - } - - if ((r = ioconnect(c, addr, host)) == 0) - break; + for (ai = addrs; ai && r == -1; ai = ai->ai_next) { + do { + if ((c->sock = socket(ai->ai_family, ai->ai_socktype, + ai->ai_protocol)) == -1) { + err = errno; + break; + } - err = errno; - close(c->sock); + if ((r = ioconnect(c, ai, host)) < 0) { + err = errno; + ioclose(c); + } + /* retry on cleartext */ + } while (r == -2); } freeaddrinfo(addrs); @@ -537,7 +539,7 @@ download(Item *item, int dest) ssize_t r, w; if (item->tag == NULL) { - if (connectto(item->host, item->port, &c) == -1 || + if (connectto(item->host, item->port, &c) < 0 || sendselector(&c, item->selector) == -1) return 0; } else { @@ -621,7 +623,7 @@ fetchitem(Item *item) struct cnx c; char *raw; - if (connectto(item->host, item->port, &c) == -1 || + if (connectto(item->host, item->port, &c) < 0 || sendselector(&c, item->selector) == -1) return 0;