commit 7e0793d8395184b5b21ecdd0b13bccb524d1e414
parent 4aa1ecfaf6c97cb02c7e34c88cc67c070b600b67
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(-)
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
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;