Retry cleartext connection in case TLS failed - sacc - sacc(omys), simple console gopher client
git clone git://bitreich.org/sacc/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/sacc/
Log
Files
Refs
Tags
LICENSE
---
commit 7e0793d8395184b5b21ecdd0b13bccb524d1e414
parent 4aa1ecfaf6c97cb02c7e34c88cc67c070b600b67
Author: Quentin Rameau 
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 
 #include 
 #include 
 #include 
@@ -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;