zygo

ncurses gopher client
Log | Files | Refs

commit 8e4578dce73dedf5c13de024b82966de78411ede
parent 1a1744a294a88e1b916c9e771272a8c0be61ea53
Author: hhvn <dev@hhvn.uk>
Date:   Tue, 18 Jan 2022 20:05:21 +0000

Automatic TLS (off by default)

Diffstat:
Mconfig.def.h | 2++
Mplain.c | 8+++++---
Mtls.c | 23+++++++++++++++--------
Mzygo.1 | 10+++++++++-
Mzygo.c | 41++++++++++++++++++++++++-----------------
Mzygo.h | 4++--
6 files changed, 57 insertions(+), 31 deletions(-)

diff --git a/config.def.h b/config.def.h @@ -2,6 +2,8 @@ static char *plumber = "xdg-open"; static int parallelplumb = 0; static int stimeout = 5; static int regexflags = REG_ICASE|REG_EXTENDED; +static int autotls = 0; /* automatically try to + establish TLS connections? */ static short bar_pair[2] = {-1, 0}; static short uri_pair[2] = {0, 7}; diff --git a/plain.c b/plain.c @@ -8,18 +8,20 @@ static int fd; if (ai) freeaddrinfo(ai) int -net_connect(Elem *e) { +net_connect(Elem *e, int silent) { struct addrinfo *ai = NULL; int ret; if ((ret = getaddrinfo(e->server, e->port, NULL, &ai)) != 0 || ai == NULL) { - error("could not lookup %s:%s", e->server, e->port); + if (!silent) + error("could not lookup %s:%s", e->server, e->port); goto fail; } if ((fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)) == -1 || connect(fd, ai->ai_addr, ai->ai_addrlen) == -1) { - error("could not connect to %s:%s", e->server, e->port); + if (!silent) + error("could not connect to %s:%s", e->server, e->port); goto fail; } diff --git a/tls.c b/tls.c @@ -9,7 +9,7 @@ int fd; int tls; int -net_connect(Elem *e) { +net_connect(Elem *e, int silent) { struct addrinfo *ai = NULL; int ret; @@ -22,7 +22,8 @@ net_connect(Elem *e) { tls_free(ctx); if ((conf = tls_config_new()) == NULL) { - error("tls_config_new(): %s", tls_config_error(conf)); + if (!silent) + error("tls_config_new(): %s", tls_config_error(conf)); goto fail; } @@ -32,35 +33,41 @@ net_connect(Elem *e) { } if ((ctx = tls_client()) == NULL) { - error("tls_client(): %s", tls_error(ctx)); + if (!silent) + error("tls_client(): %s", tls_error(ctx)); goto fail; } if (tls_configure(ctx, conf) == -1) { - error("tls_configure(): %s", tls_error(ctx)); + if (!silent) + error("tls_configure(): %s", tls_error(ctx)); goto fail; } } if ((ret = getaddrinfo(e->server, e->port, NULL, &ai)) != 0 || ai == NULL) { - error("could not lookup %s:%s", e->server, e->port); + if (!silent) + error("could not lookup %s:%s", e->server, e->port); goto fail; } if ((fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)) == -1 || connect(fd, ai->ai_addr, ai->ai_addrlen) == -1) { - error("could not connect to %s:%s", e->server, e->port); + if (!silent) + error("could not connect to %s:%s", e->server, e->port); goto fail; } if (tls) { if (tls_connect_socket(ctx, fd, e->server) == -1) { - error("could not tls-ify connection to %s:%s", e->server, e->port); + if (!silent) + error("could not tls-ify connection to %s:%s", e->server, e->port); goto fail; } if (tls_handshake(ctx) == -1) { - error("could not perform tls handshake with %s:%s", e->server, e->port); + if (!silent) + error("could not perform tls handshake with %s:%s", e->server, e->port); goto fail; } } diff --git a/zygo.1 b/zygo.1 @@ -34,7 +34,15 @@ and has pager functionality using ncurses. .Nm supports gopher over TLS using the gophers:// uri schema. If a gopher menu is accessed over TLS, -any links with the same server and port will be accessed over TLS. +any links to the same server and port will be accessed over TLS. + +.Nm +will also attempt to upgrade connections to TLS when it encounters a new server +if the +.Ar autotls +variable is set in +.Ar config.h "." +(Off by default). .Ss Name .Nm is taken from the first four letters of the gopher genus Zygogeomys. diff --git a/zygo.c b/zygo.c @@ -433,7 +433,7 @@ readline(char *buf, size_t count) { } int -go(Elem *e, int mhist) { +go(Elem *e, int mhist, int notls) { char line[BUFLEN]; char *sh, *arg, *uri; char *search; @@ -471,7 +471,7 @@ go(Elem *e, int mhist) { waitpid(pid, NULL, 0); fprintf(stderr, "Press enter..."); fread(&line, sizeof(char), 1, stdin); - initscr(); + initscr(); } return -1; } @@ -490,11 +490,17 @@ go(Elem *e, int mhist) { move(LINES - 1, 0); clrtoeol(); - printw("Connecting to %s:%s", dup->server, dup->port); + if (!dup->tls && autotls && !notls && + (!current || strcmp(current->server, dup->server) != 0)) { + dup->tls = 1; + printw("Attempting a TLS connection with %s:%s", dup->server, dup->port); + } else { + printw("Connecting to %s:%s", dup->server, dup->port); + } refresh(); - if ((ret = net_connect(e)) == -1) { - if (dup->tls) { + if ((ret = net_connect(dup, e->tls != dup->tls)) == -1) { + if (dup->tls && dup->tls == e->tls) { attron(A_BOLD | COLOR_PAIR(PAIR_CMD)); printw(" Try again in cleartext? "); curs_set(1); @@ -502,14 +508,15 @@ go(Elem *e, int mhist) { refresh(); timeout(stimeout * 1000); if (tolower(getch()) == 'y') { - elem = elem_dup(e); - elem->tls = 0; - ret = go(elem, mhist); - elem_free(elem); + dup->tls = 0; + ret = go(dup, mhist, 1); } + timeout(-1); + } else if (dup->tls) { + dup->tls = 0; + ret = go(dup, mhist, 1); } - timeout(-1); elem_free(dup); return ret; } @@ -836,7 +843,7 @@ run(void) { switch (ui.cmd) { case ':': e = uritoelem(ui.arg); - go(e, 1); + go(e, 1, 0); elem_free(e); break; case '+': @@ -873,7 +880,7 @@ run(void) { e->selector = erealloc(e->selector, strlen(e->selector) + strlen(ui.arg) + 1); /* should be safe.. I think */ strcat(e->selector, ui.arg); - go(e, 1); + go(e, 1, 0); elem_free(e); break; } @@ -951,7 +958,7 @@ run(void) { case '<': if (history) { e = list_pop(&history); - go(e, 0); + go(e, 0, 0); free(e); draw_page(); draw_bar(); @@ -961,7 +968,7 @@ run(void) { break; case '*': checkcurrent(); - go(current, 0); + go(current, 0, 0); draw_page(); draw_bar(); break; @@ -984,7 +991,7 @@ run(void) { e = elem_dup(current); free(e->selector); e->selector = strdup(""); - go(e, 1); + go(e, 1, 0); elem_free(e); draw_page(); draw_bar(); @@ -1034,7 +1041,7 @@ gonum: if (atoi(ui.arg) > page->lastid || atoi(ui.arg) < 1) error("no such link: %d", atoi(ui.arg)); else - go(list_idget(&page, atoi(ui.arg)), 1); + go(list_idget(&page, atoi(ui.arg)), 1, 0); ui.wantinput = 0; draw_page(); draw_bar(); @@ -1112,7 +1119,7 @@ main(int argc, char *argv[]) { } } else { target = uritoelem(argv[argc-1]); - go(target, 1); + go(target, 1, 0); } } diff --git a/zygo.h b/zygo.h @@ -88,7 +88,7 @@ size_t list_len(List **l); /* Network functions * only works with one fd/ctx at * a time, reset at net_connect */ -int net_connect(Elem *e); +int net_connect(Elem *e, int silent); int net_read(void *buf, size_t count); int net_write(void *buf, size_t count); int net_close(void); @@ -108,7 +108,7 @@ void run(void); /* Misc */ int readline(char *buf, size_t count); -int go(Elem *e, int mhist); +int go(Elem *e, int mhist, int notls); void sighandler(int signal); #ifdef ZYGO_STRLCAT #undef strlcat