iAdd tls support to geomyidae. - geomyidae - A small C-based gopherd. Err bitreich.org 70 hgit clone git://bitreich.org/geomyidae/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/geomyidae/ URL:git://bitreich.org/geomyidae/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/geomyidae/ bitreich.org 70 1Log /scm/geomyidae/log.gph bitreich.org 70 1Files /scm/geomyidae/files.gph bitreich.org 70 1Refs /scm/geomyidae/refs.gph bitreich.org 70 1Tags /scm/geomyidae/tag bitreich.org 70 1README /scm/geomyidae/file/README.gph bitreich.org 70 1LICENSE /scm/geomyidae/file/LICENSE.gph bitreich.org 70 i--- Err bitreich.org 70 1commit 07240d76fd8e1d0a67c49bf7e123bb508613e691 /scm/geomyidae/commit/07240d76fd8e1d0a67c49bf7e123bb508613e691.gph bitreich.org 70 1parent 4500d3596d7b166ad1e832adeefc6be3da685b09 /scm/geomyidae/commit/4500d3596d7b166ad1e832adeefc6be3da685b09.gph bitreich.org 70 hAuthor: Christoph Lohmann <20h@r-36.net> URL:mailto:20h@r-36.net bitreich.org 70 iDate: Sun, 7 Jun 2020 18:49:28 +0200 Err bitreich.org 70 i Err bitreich.org 70 iAdd tls support to geomyidae. Err bitreich.org 70 i Err bitreich.org 70 iDiffstat: Err bitreich.org 70 i M Makefile | 2 +- Err bitreich.org 70 i M handlr.c | 11 +++++++---- Err bitreich.org 70 i M main.c | 168 ++++++++++++++++++++++++++----- Err bitreich.org 70 i Err bitreich.org 70 i3 files changed, 149 insertions(+), 32 deletions(-) Err bitreich.org 70 i--- Err bitreich.org 70 1diff --git a/Makefile b/Makefile /scm/geomyidae/file/Makefile.gph bitreich.org 70 i@@ -11,7 +11,7 @@ MANDIR = ${PREFIX}/share/man/man8 Err bitreich.org 70 i Err bitreich.org 70 i CFLAGS = -O2 -Wall Err bitreich.org 70 i GEOM_CFLAGS = -D_DEFAULT_SOURCE -I. -I/usr/include ${CFLAGS} Err bitreich.org 70 i-GEOM_LDFLAGS = -L/usr/lib -L. ${LDFLAGS} Err bitreich.org 70 i+GEOM_LDFLAGS = -L/usr/lib -L. -ltls ${LDFLAGS} Err bitreich.org 70 i Err bitreich.org 70 i SRC = main.c ind.c handlr.c Err bitreich.org 70 i OBJ = ${SRC:.c=.o} Err bitreich.org 70 1diff --git a/handlr.c b/handlr.c /scm/geomyidae/file/handlr.c.gph bitreich.org 70 i@@ -16,6 +16,8 @@ Err bitreich.org 70 i #include Err bitreich.org 70 i #include Err bitreich.org 70 i #include Err bitreich.org 70 i+#include Err bitreich.org 70 i+ Err bitreich.org 70 i #include "ind.h" Err bitreich.org 70 i #include "arg.h" Err bitreich.org 70 i Err bitreich.org 70 i@@ -205,11 +207,11 @@ handledcgi(int sock, char *file, char *port, char *base, char *args, Err bitreich.org 70 i if (args == NULL) Err bitreich.org 70 i args = ""; Err bitreich.org 70 i Err bitreich.org 70 i- dup2(sock, 0); Err bitreich.org 70 i- dup2(sock, 2); Err bitreich.org 70 i+ while (dup2(sock, 0) < 0 && errno == EINTR); Err bitreich.org 70 i+ while (dup2(sock, 2) < 0 && errno == EINTR); Err bitreich.org 70 i switch (fork()) { Err bitreich.org 70 i case 0: Err bitreich.org 70 i- dup2(outpipe[1], 1); Err bitreich.org 70 i+ while(dup2(outpipe[1], 1) < 0 && errno == EINTR); Err bitreich.org 70 i close(outpipe[0]); Err bitreich.org 70 i if (path != NULL) { Err bitreich.org 70 i if (chdir(path) < 0) Err bitreich.org 70 i@@ -223,11 +225,12 @@ handledcgi(int sock, char *file, char *port, char *base, char *args, Err bitreich.org 70 i perror("execl"); Err bitreich.org 70 i _exit(1); Err bitreich.org 70 i } Err bitreich.org 70 i+ break; Err bitreich.org 70 i case -1: Err bitreich.org 70 i perror("fork"); Err bitreich.org 70 i break; Err bitreich.org 70 i default: Err bitreich.org 70 i- dup2(sock, 1); Err bitreich.org 70 i+ while(dup2(sock, 1) < 0 && errno == EINTR); Err bitreich.org 70 i close(outpipe[1]); Err bitreich.org 70 i Err bitreich.org 70 i if (!(fp = fdopen(outpipe[0], "r"))) { Err bitreich.org 70 1diff --git a/main.c b/main.c /scm/geomyidae/file/main.c.gph bitreich.org 70 i@@ -25,6 +25,7 @@ Err bitreich.org 70 i #include Err bitreich.org 70 i #include Err bitreich.org 70 i #include Err bitreich.org 70 i+#include Err bitreich.org 70 i Err bitreich.org 70 i #include "ind.h" Err bitreich.org 70 i #include "handlr.h" Err bitreich.org 70 i@@ -116,34 +117,22 @@ logentry(char *host, char *port, char *qry, char *status) Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i void Err bitreich.org 70 i-handlerequest(int sock, char *base, char *ohost, char *port, char *clienth, Err bitreich.org 70 i- char *clientp, int nocgi) Err bitreich.org 70 i+handlerequest(int sock, char *req, int rlen, char *base, char *ohost, Err bitreich.org 70 i+ char *port, char *clienth, char *clientp, int nocgi) Err bitreich.org 70 i { Err bitreich.org 70 i struct stat dir; Err bitreich.org 70 i char recvc[1025], recvb[1025], path[1025], *args = NULL, *sear, *c; Err bitreich.org 70 i- int len = 0, fd, i, retl, maxrecv; Err bitreich.org 70 i+ int len = 0, fd, i, maxrecv; Err bitreich.org 70 i filetype *type; Err bitreich.org 70 i Err bitreich.org 70 i memset(&dir, 0, sizeof(dir)); Err bitreich.org 70 i memset(recvb, 0, sizeof(recvb)); Err bitreich.org 70 i memset(recvc, 0, sizeof(recvc)); Err bitreich.org 70 i Err bitreich.org 70 i- maxrecv = sizeof(recvb); Err bitreich.org 70 i- /* Err bitreich.org 70 i- * Force at least one byte per packet. Limit, so the server Err bitreich.org 70 i- * cannot be put into DoS via zero-length packets. Err bitreich.org 70 i- */ Err bitreich.org 70 i- do { Err bitreich.org 70 i- retl = recv(sock, recvb+len, sizeof(recvb)-1-len, 0); Err bitreich.org 70 i- if (retl <= 0) { Err bitreich.org 70 i- if (retl < 0) Err bitreich.org 70 i- perror("recv"); Err bitreich.org 70 i- break; Err bitreich.org 70 i- } Err bitreich.org 70 i- len += retl; Err bitreich.org 70 i- } while (recvb[len-1] != '\n' && --maxrecv > 0); Err bitreich.org 70 i- if (len <= 0) Err bitreich.org 70 i+ maxrecv = sizeof(recvb) - 1; Err bitreich.org 70 i+ if (rlen > maxrecv || rlen < 0) Err bitreich.org 70 i return; Err bitreich.org 70 i+ memcpy(recvb, req, rlen); Err bitreich.org 70 i Err bitreich.org 70 i c = strchr(recvb, '\r'); Err bitreich.org 70 i if (c) Err bitreich.org 70 i@@ -174,7 +163,7 @@ handlerequest(int sock, char *base, char *ohost, char *port, char *clienth, Err bitreich.org 70 i } Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i- memmove(recvc, recvb, len+1); Err bitreich.org 70 i+ memmove(recvc, recvb, rlen+1); Err bitreich.org 70 i Err bitreich.org 70 i if (!strncmp(recvb, "URL:", 4)) { Err bitreich.org 70 i len = snprintf(path, sizeof(path), htredir, Err bitreich.org 70 i@@ -409,6 +398,7 @@ void Err bitreich.org 70 i usage(void) Err bitreich.org 70 i { Err bitreich.org 70 i dprintf(2, "usage: %s [-46cden] [-l logfile] " Err bitreich.org 70 i+ "[-t keyfile certfile] " Err bitreich.org 70 i "[-v loglvl] [-b base] [-p port] [-o sport] " Err bitreich.org 70 i "[-u user] [-g group] [-h host] [-i interface ...]\n", Err bitreich.org 70 i argv0); Err bitreich.org 70 i@@ -423,13 +413,18 @@ main(int argc, char *argv[]) Err bitreich.org 70 i socklen_t cltlen; Err bitreich.org 70 i int sock, dofork = 1, inetf = AF_UNSPEC, usechroot = 0, Err bitreich.org 70 i nocgi = 0, errno_save, nbindips = 0, i, j, Err bitreich.org 70 i- nlfdret, *lfdret, listfd, maxlfd; Err bitreich.org 70 i+ nlfdret, *lfdret, listfd, maxlfd, dotls = 0, istls = 0, Err bitreich.org 70 i+ shuflen, wlen, shufpos, tlspipe[2], maxrecv, retl, Err bitreich.org 70 i+ rlen = 0; Err bitreich.org 70 i fd_set rfd; Err bitreich.org 70 i char *port, *base, clienth[NI_MAXHOST], clientp[NI_MAXSERV], Err bitreich.org 70 i *user = NULL, *group = NULL, **bindips = NULL, Err bitreich.org 70 i- *ohost = NULL, *sport = NULL, *p; Err bitreich.org 70 i+ *ohost = NULL, *sport = NULL, *p, *certfile = NULL, Err bitreich.org 70 i+ *keyfile = NULL, shufbuf[1025], byte0, recvb[1025]; Err bitreich.org 70 i struct passwd *us = NULL; Err bitreich.org 70 i struct group *gr = NULL; Err bitreich.org 70 i+ struct tls_config *tlsconfig = NULL; Err bitreich.org 70 i+ struct tls *tlsctx = NULL, *tlsclientctx; Err bitreich.org 70 i Err bitreich.org 70 i base = stdbase; Err bitreich.org 70 i port = stdport; Err bitreich.org 70 i@@ -483,6 +478,11 @@ main(int argc, char *argv[]) Err bitreich.org 70 i case 'n': Err bitreich.org 70 i revlookup = 0; Err bitreich.org 70 i break; Err bitreich.org 70 i+ case 't': Err bitreich.org 70 i+ dotls = 1; Err bitreich.org 70 i+ keyfile = EARGF(usage()); Err bitreich.org 70 i+ certfile = EARGF(usage()); Err bitreich.org 70 i+ break; Err bitreich.org 70 i default: Err bitreich.org 70 i usage(); Err bitreich.org 70 i } ARGEND; Err bitreich.org 70 i@@ -493,6 +493,33 @@ main(int argc, char *argv[]) Err bitreich.org 70 i if (argc != 0) Err bitreich.org 70 i usage(); Err bitreich.org 70 i Err bitreich.org 70 i+ if (dotls) { Err bitreich.org 70 i+ if (tls_init() < 0) { Err bitreich.org 70 i+ perror("tls_init"); Err bitreich.org 70 i+ return 1; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ if ((tlsconfig = tls_config_new()) == NULL) { Err bitreich.org 70 i+ perror("tls_config_new"); Err bitreich.org 70 i+ return 1; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ if ((tlsctx = tls_server()) == NULL) { Err bitreich.org 70 i+ perror("tls_server"); Err bitreich.org 70 i+ return 1; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ if (tls_config_set_key_file(tlsconfig, keyfile) < 0) { Err bitreich.org 70 i+ perror("tls_config_set_key_file"); Err bitreich.org 70 i+ return 1; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ if (tls_config_set_cert_file(tlsconfig, certfile) < 0) { Err bitreich.org 70 i+ perror("tls_config_set_cert_file"); Err bitreich.org 70 i+ return 1; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ if (tls_configure(tlsctx, tlsconfig) < 0) { Err bitreich.org 70 i+ perror("tls_configure"); Err bitreich.org 70 i+ return 1; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i if (ohost == NULL) { Err bitreich.org 70 i /* Do not use HOST_NAME_MAX, it is not defined on NetBSD. */ Err bitreich.org 70 i ohost = xcalloc(1, 256+1); Err bitreich.org 70 i@@ -716,16 +743,97 @@ main(int argc, char *argv[]) Err bitreich.org 70 i } Err bitreich.org 70 i #endif /* __OpenBSD__ */ Err bitreich.org 70 i Err bitreich.org 70 i- handlerequest(sock, base, ohost, sport, clienth, Err bitreich.org 70 i- clientp, nocgi); Err bitreich.org 70 i+ if (recv(sock, &byte0, 1, MSG_PEEK) < 1) Err bitreich.org 70 i+ return 1; Err bitreich.org 70 i+ Err bitreich.org 70 i+ /* Err bitreich.org 70 i+ * First byte is 0x16 == 22, which is the TLS Err bitreich.org 70 i+ * Handshake first byte. Err bitreich.org 70 i+ */ Err bitreich.org 70 i+ istls = 0; Err bitreich.org 70 i+ if (byte0 == 0x16 && dotls) { Err bitreich.org 70 i+ istls = 1; Err bitreich.org 70 i+ if (tls_accept_socket(tlsctx, &tlsclientctx, sock) < 0) Err bitreich.org 70 i+ return 1; Err bitreich.org 70 i+ if (tls_handshake(tlsclientctx) < 0) Err bitreich.org 70 i+ return 1; Err bitreich.org 70 i+ } Err bitreich.org 70 i Err bitreich.org 70 i- waitforpendingbytes(sock); Err bitreich.org 70 i+ maxrecv = sizeof(recvb) - 1; Err bitreich.org 70 i+ do { Err bitreich.org 70 i+ if (istls) { Err bitreich.org 70 i+ retl = tls_read(tlsclientctx, Err bitreich.org 70 i+ recvb+rlen, sizeof(recvb)-1-rlen); Err bitreich.org 70 i+ } else { Err bitreich.org 70 i+ retl = read(sock, recvb+rlen, Err bitreich.org 70 i+ sizeof(recvb)-1-rlen); Err bitreich.org 70 i+ } Err bitreich.org 70 i+ if (retl <= 0) { Err bitreich.org 70 i+ if (retl < 0) Err bitreich.org 70 i+ perror("recv"); Err bitreich.org 70 i+ break; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ rlen += retl; Err bitreich.org 70 i+ } while (recvb[rlen-1] != '\n' Err bitreich.org 70 i+ && --maxrecv > 0); Err bitreich.org 70 i+ if (rlen <= 0) Err bitreich.org 70 i+ return 1; Err bitreich.org 70 i Err bitreich.org 70 i- shutdown(sock, SHUT_RDWR); Err bitreich.org 70 i+ if (istls) { Err bitreich.org 70 i+ if (pipe(tlspipe) < 0) { Err bitreich.org 70 i+ perror("tls_pipe"); Err bitreich.org 70 i+ return 1; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i+ switch(fork()) { Err bitreich.org 70 i+ case 0: Err bitreich.org 70 i+ sock = tlspipe[1]; Err bitreich.org 70 i+ close(tlspipe[0]); Err bitreich.org 70 i+ break; Err bitreich.org 70 i+ case -1: Err bitreich.org 70 i+ perror("fork"); Err bitreich.org 70 i+ return 1; Err bitreich.org 70 i+ default: Err bitreich.org 70 i+ close(tlspipe[1]); Err bitreich.org 70 i+ do { Err bitreich.org 70 i+ shuflen = read(tlspipe[0], shufbuf, sizeof(shufbuf)-1); Err bitreich.org 70 i+ if (shuflen == EINTR) Err bitreich.org 70 i+ continue; Err bitreich.org 70 i+ for (shufpos = 0; shufpos < shuflen; shufpos += wlen) { Err bitreich.org 70 i+ wlen = tls_write(tlsclientctx, shufbuf+shufpos, shuflen-shufpos); Err bitreich.org 70 i+ if (wlen < 0) { Err bitreich.org 70 i+ printf("tls_write failed: %s\n", tls_error(tlsclientctx)); Err bitreich.org 70 i+ return 1; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ } Err bitreich.org 70 i+ } while(shuflen > 0); Err bitreich.org 70 i+ Err bitreich.org 70 i+ tls_close(tlsclientctx); Err bitreich.org 70 i+ tls_free(tlsclientctx); Err bitreich.org 70 i+ close(tlspipe[0]); Err bitreich.org 70 i+ Err bitreich.org 70 i+ waitforpendingbytes(sock); Err bitreich.org 70 i+ shutdown(sock, SHUT_RDWR); Err bitreich.org 70 i+ close(sock); Err bitreich.org 70 i+ return 0; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i+ handlerequest(sock, recvb, rlen, base, Err bitreich.org 70 i+ ohost, sport, clienth, Err bitreich.org 70 i+ clientp, nocgi); Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (!istls) { Err bitreich.org 70 i+ waitforpendingbytes(sock); Err bitreich.org 70 i+ shutdown(sock, SHUT_RDWR); Err bitreich.org 70 i+ close(sock); Err bitreich.org 70 i+ } Err bitreich.org 70 i close(sock); Err bitreich.org 70 i Err bitreich.org 70 i- if (loglvl & CONN) Err bitreich.org 70 i- logentry(clienth, clientp, "-", "disconnected"); Err bitreich.org 70 i+ if (loglvl & CONN) { Err bitreich.org 70 i+ logentry(clienth, clientp, "-", Err bitreich.org 70 i+ "disconnected"); Err bitreich.org 70 i+ } Err bitreich.org 70 i Err bitreich.org 70 i return 0; Err bitreich.org 70 i default: Err bitreich.org 70 i@@ -746,6 +854,12 @@ main(int argc, char *argv[]) Err bitreich.org 70 i } Err bitreich.org 70 i free(listfds); Err bitreich.org 70 i Err bitreich.org 70 i+ if (dotls) { Err bitreich.org 70 i+ tls_close(tlsctx); Err bitreich.org 70 i+ tls_free(tlsctx); Err bitreich.org 70 i+ tls_config_free(tlsconfig); Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i return 0; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 .