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