Introduction
Introduction Statistics Contact Development Disclaimer Help
Add TLS support - sacc - sacc - sacc(omys), simple console gopher client (confi…
git clone git://git.codemadness.org/sacc
Log
Files
Refs
LICENSE
---
commit 92394502830c460c78633f56a69da4ce5f01d5fa
parent a58414c67ddf05ff48b8a86fb2d3cf5e58cea4b9
Author: Quentin Rameau <[email protected]>
Date: Fri, 9 Apr 2021 23:58:34 +0200
Add TLS support
TLS will be used when a gophers:// URL is requested.
Diffstat:
M Makefile | 4 ++--
M config.mk | 4 ++++
M sacc.c | 124 ++++++++++++++++++++++++++---…
3 files changed, 110 insertions(+), 22 deletions(-)
---
diff --git a/Makefile b/Makefile
@@ -14,7 +14,7 @@ config.h:
cp config.def.h config.h
$(BIN): $(OBJ)
- $(CC) $(OBJ) $(LDFLAGS) $(LIBS) -o $@
+ $(CC) $(OBJ) $(LDFLAGS) $(LIBS) $(TLSLIBS) -o $@
$(OBJ): config.h config.mk common.h
@@ -33,7 +33,7 @@ uninstall:
# Stock FLAGS
SACCCFLAGS = -D_DEFAULT_SOURCE -D_XOPEN_SOURCE=700 -D_BSD_SOURCE -D_GNU_SOURCE…
- $(CFLAGS)
+ $(TLSCFLAGS) $(CFLAGS)
.c.o:
$(CC) $(SACCCFLAGS) -c $<
diff --git a/config.mk b/config.mk
@@ -12,3 +12,7 @@ LIBS=-lcurses
# Define NEED_ASPRINTF and/or NEED_STRCASESTR in your cflags if your system do…
# not provide asprintf() or strcasestr(), respectively.
#CFLAGS = -DNEED_ASPRINTF -DNEED_STRCASESTR
+
+# gophers (gopher over TLS) support
+TLSCFLAGS = -DUSE_TLS
+TLSLIBS = -ltls
diff --git a/sacc.c b/sacc.c
@@ -18,14 +18,26 @@
#include <sys/types.h>
#include <sys/wait.h>
+#ifdef USE_TLS
+#include <tls.h>
+#endif
+
#include "common.h"
#include "config.h"
+struct cnx {
+#ifdef USE_TLS
+ struct tls *tls;
+#endif
+ int sock;
+};
+
static char *mainurl;
static Item *mainentry;
static int devnullfd;
static int parent = 1;
static int interactive;
+static int tls;
static void (*diag)(char *fmt, ...);
@@ -417,7 +429,7 @@ molddiritem(char *raw)
}
static char *
-getrawitem(int sock)
+getrawitem(struct cnx *cnx)
{
char *raw, *buf;
size_t bn, bs;
@@ -445,7 +457,18 @@ getrawitem(int sock)
buf = raw + (bn-1) * BUFSIZ;
bs = BUFSIZ;
}
- } while ((n = read(sock, buf, bs)) > 0);
+
+#ifdef USE_TLS
+ if (tls) {
+ do {
+ n = tls_read(cnx->tls, buf, bs);
+ } while (n == TLS_WANT_POLLIN || n == TLS_WANT_POLLOUT…
+ } else
+#endif
+ {
+ n = read(cnx->sock, buf, bs);
+ }
+ } while (n > 0);
*buf = '\0';
@@ -458,7 +481,7 @@ getrawitem(int sock)
}
static int
-sendselector(int sock, const char *selector)
+sendselector(struct cnx *cnx, const char *selector)
{
char *msg, *p;
size_t ln;
@@ -468,10 +491,21 @@ sendselector(int sock, const char *selector)
msg = p = xmalloc(ln);
snprintf(msg, ln--, "%s\r\n", selector);
- while ((n = write(sock, p, ln)) > 0) {
+ do {
+#ifdef USE_TLS
+ if (tls) {
+ do {
+ n = tls_write(cnx->tls, p, ln);
+ } while (n == TLS_WANT_POLLIN || n == TLS_WANT_POLLOUT…
+ } else
+#endif
+ {
+ n = write(cnx->sock, p, ln);
+ }
+
ln -= n;
p += n;
- }
+ } while (n > 0);
free(msg);
if (n == -1)
@@ -480,8 +514,20 @@ sendselector(int sock, const char *selector)
return n;
}
+static void
+closecnx(struct cnx *cnx)
+{
+#ifdef USE_TLS
+ if (tls) {
+ tls_close(cnx->tls);
+ tls_free(cnx->tls);
+ }
+#endif
+ close(cnx->sock);
+}
+
static int
-connectto(const char *host, const char *port)
+connectto(const char *host, const char *port, struct cnx *cnx)
{
sigset_t set, oset;
static const struct addrinfo hints = {
@@ -506,10 +552,23 @@ connectto(const char *host, const char *port)
if ((sock = socket(addr->ai_family, addr->ai_socktype,
addr->ai_protocol)) < 0)
continue;
- if ((r = connect(sock, addr->ai_addr, addr->ai_addrlen)) < 0) {
+
+ r = connect(sock, addr->ai_addr, addr->ai_addrlen);
+ if (r == -1) {
close(sock);
continue;
}
+#ifdef USE_TLS
+ if (tls) {
+ if ((cnx->tls = tls_client()) == NULL) {
+ diag("Can't establish TLS with \"%s\": %s",
+ host, tls_error(cnx->tls));
+ close(sock);
+ continue;
+ }
+ r = tls_connect_socket(cnx->tls, sock, host);
+ }
+#endif
break;
}
@@ -526,8 +585,10 @@ connectto(const char *host, const char *port)
}
sigprocmask(SIG_SETMASK, &oset, NULL);
- return sock;
+ cnx->sock = sock;
+
+ return 0;
err:
sigprocmask(SIG_SETMASK, &oset, NULL);
return -1;
@@ -537,13 +598,15 @@ static int
download(Item *item, int dest)
{
char buf[BUFSIZ];
+ struct cnx cnx;
ssize_t r, w;
int src;
if (!item->tag) {
- if ((src = connectto(item->host, item->port)) < 0 ||
- sendselector(src, item->selector) < 0)
+ if (connectto(item->host, item->port, &cnx) < 0 ||
+ sendselector(&cnx, item->selector) < 0)
return 0;
+ src = cnx.sock;
} else if ((src = open(item->tag, O_RDONLY)) < 0) {
printf("Can't open source file %s: %s",
item->tag, strerror(errno));
@@ -551,8 +614,20 @@ download(Item *item, int dest)
return 0;
}
- w = 0;
- while ((r = read(src, buf, BUFSIZ)) > 0) {
+ for (w = 0; w != -1;) {
+#ifdef USE_TLS
+ if (tls) {
+ do {
+ r = tls_read(cnx.tls, buf, sizeof(buf));
+ } while (r == TLS_WANT_POLLIN || r == TLS_WANT_POLLOUT…
+ } else
+#endif
+ {
+ r = read(src, buf, sizeof(buf));
+ }
+ if (r <= 0)
+ break;
+
while ((w = write(dest, buf, r)) > 0)
r -= w;
}
@@ -563,7 +638,7 @@ download(Item *item, int dest)
errno = 0;
}
- close(src);
+ closecnx(&cnx);
return (r == 0 && w == 0);
}
@@ -618,14 +693,15 @@ cleanup:
static int
fetchitem(Item *item)
{
- char *raw, *r;
- int sock;
+ struct cnx cnx;
+ char *raw;
- if ((sock = connectto(item->host, item->port)) < 0 ||
- sendselector(sock, item->selector) < 0)
+ if (connectto(item->host, item->port, &cnx) < 0 ||
+ sendselector(&cnx, item->selector) < 0)
return 0;
- raw = getrawitem(sock);
- close(sock);
+
+ raw = getrawitem(&cnx);
+ closecnx(&cnx);
if (raw == NULL || !*raw) {
diag("Empty response from server");
@@ -910,8 +986,16 @@ moldentry(char *url)
int parsed, ipv6;
if (p = strstr(url, "://")) {
- if (strncmp(url, "gopher", p - url))
+ if (strncmp(url, "gopher", p - url) == 0) {
+ if (tls) {
+ diag("Switching from gophers to gopher");
+ tls = 0;
+ }
+ } else if (strncmp(url, "gophers", p - url) == 0) {
+ tls = 1;
+ } else {
die("Protocol not supported: %.*s", p - url, url);
+ }
host = p + 3;
}
You are viewing proxied material from codemadness.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.