2 d188f690 2022-02-04 op * Copyright (c) 2022 Omar Polo <op@omarpolo.com>
4 d188f690 2022-02-04 op * Permission to use, copy, modify, and distribute this software for any
5 d188f690 2022-02-04 op * purpose with or without fee is hereby granted, provided that the above
6 d188f690 2022-02-04 op * copyright notice and this permission notice appear in all copies.
8 d188f690 2022-02-04 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 d188f690 2022-02-04 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 d188f690 2022-02-04 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 d188f690 2022-02-04 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 d188f690 2022-02-04 op * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 d188f690 2022-02-04 op * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 d188f690 2022-02-04 op * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 d188f690 2022-02-04 op #include "compat.h"
19 d188f690 2022-02-04 op #include <sys/types.h>
20 d188f690 2022-02-04 op #include <sys/socket.h>
22 d188f690 2022-02-04 op #include <netdb.h>
24 d188f690 2022-02-04 op #include <errno.h>
25 d188f690 2022-02-04 op #include <signal.h>
26 d188f690 2022-02-04 op #include <stdio.h>
27 d188f690 2022-02-04 op #include <stdlib.h>
28 d188f690 2022-02-04 op #include <string.h>
29 d188f690 2022-02-04 op #include <syslog.h>
30 d188f690 2022-02-04 op #include <tls.h>
31 d188f690 2022-02-04 op #include <unistd.h>
33 d188f690 2022-02-04 op #include "log.h"
35 d188f690 2022-02-04 op #define MIN(a, b) ((a) < (b) ? (a) : (b))
39 d188f690 2022-02-04 op const char *tohost;
40 d188f690 2022-02-04 op const char *fromhost;
42 d188f690 2022-02-04 op uint8_t *cert;
43 d188f690 2022-02-04 op size_t certlen;
45 d188f690 2022-02-04 op size_t keylen;
47 d188f690 2022-02-04 op #define MAXSOCK 32
48 d188f690 2022-02-04 op struct event sockev[MAXSOCK];
49 d188f690 2022-02-04 op int socks[MAXSOCK];
52 d188f690 2022-02-04 op char kamihost[64];
53 d188f690 2022-02-04 op char kamiport[8];
56 d188f690 2022-02-04 op struct tls *ctx;
57 d188f690 2022-02-04 op struct bufferevent *server;
59 d188f690 2022-02-04 op struct bufferevent *client;
63 d188f690 2022-02-04 op #ifndef __OpenBSD__
64 d188f690 2022-02-04 op # define pledge(a, b) (0)
67 d188f690 2022-02-04 op static const char *
68 d188f690 2022-02-04 op copysec(const char *s, char *d, size_t len)
70 d188f690 2022-02-04 op const char *c;
72 d188f690 2022-02-04 op if ((c = strchr(s, ':')) == NULL)
74 d188f690 2022-02-04 op if ((size_t)(c-s) >= len-1)
76 d188f690 2022-02-04 op memset(d, 0, len);
77 d188f690 2022-02-04 op memcpy(d, s, c - s);
82 d188f690 2022-02-04 op parse_tohost(void)
84 d188f690 2022-02-04 op const char *c;
86 d188f690 2022-02-04 op if ((c = strchr(tohost, ':')) == NULL) {
87 d188f690 2022-02-04 op strlcpy(kamihost, tohost, sizeof(kamihost));
88 d188f690 2022-02-04 op strlcpy(kamiport, "1337", sizeof(kamiport));
92 d188f690 2022-02-04 op if ((c = copysec(tohost, kamihost, sizeof(kamihost))) == NULL)
93 d188f690 2022-02-04 op fatalx("hostname too long: %s", tohost);
95 d188f690 2022-02-04 op strlcpy(kamiport, c+1, sizeof(kamiport));
99 d188f690 2022-02-04 op tls_readcb(int fd, short event, void *d)
101 d188f690 2022-02-04 op struct bufferevent *bufev = d;
102 d188f690 2022-02-04 op struct conn *conn = bufev->cbarg;
103 d188f690 2022-02-04 op char buf[IBUF_READ_SIZE];
104 d188f690 2022-02-04 op int what = EVBUFFER_READ;
105 d188f690 2022-02-04 op int howmuch = IBUF_READ_SIZE;
109 d188f690 2022-02-04 op if (event == EV_TIMEOUT) {
110 d188f690 2022-02-04 op what |= EVBUFFER_TIMEOUT;
114 d188f690 2022-02-04 op if (bufev->wm_read.high != 0)
115 d188f690 2022-02-04 op howmuch = MIN(sizeof(buf), bufev->wm_read.high);
117 d188f690 2022-02-04 op switch (ret = tls_read(conn->ctx, buf, howmuch)) {
118 d188f690 2022-02-04 op case TLS_WANT_POLLIN:
119 d188f690 2022-02-04 op case TLS_WANT_POLLOUT:
122 d188f690 2022-02-04 op what |= EVBUFFER_ERROR;
127 d188f690 2022-02-04 op if (len == 0) {
128 d188f690 2022-02-04 op what |= EVBUFFER_EOF;
132 d188f690 2022-02-04 op if (evbuffer_add(bufev->input, buf, len) == -1) {
133 d188f690 2022-02-04 op what |= EVBUFFER_ERROR;
137 d188f690 2022-02-04 op event_add(&bufev->ev_read, NULL);
139 d188f690 2022-02-04 op len = EVBUFFER_LENGTH(bufev->input);
140 d188f690 2022-02-04 op if (bufev->wm_read.low != 0 && len < bufev->wm_read.low)
142 d188f690 2022-02-04 op if (bufev->wm_read.high != 0 && len > bufev->wm_read.high) {
144 d188f690 2022-02-04 op * here we could implement some read pressure
149 d188f690 2022-02-04 op if (bufev->readcb != NULL)
150 d188f690 2022-02-04 op (*bufev->readcb)(bufev, bufev->cbarg);
155 d188f690 2022-02-04 op event_add(&bufev->ev_read, NULL);
159 d188f690 2022-02-04 op (*bufev->errorcb)(bufev, what, bufev->cbarg);
163 d188f690 2022-02-04 op tls_writecb(int fd, short event, void *d)
165 d188f690 2022-02-04 op struct bufferevent *bufev = d;
166 d188f690 2022-02-04 op struct conn *conn = bufev->cbarg;
169 d188f690 2022-02-04 op short what = EVBUFFER_WRITE;
171 d188f690 2022-02-04 op if (event == EV_TIMEOUT) {
172 d188f690 2022-02-04 op what |= EVBUFFER_TIMEOUT;
176 d188f690 2022-02-04 op if (EVBUFFER_LENGTH(bufev->output) != 0) {
177 d188f690 2022-02-04 op ret = tls_write(conn->ctx,
178 d188f690 2022-02-04 op EVBUFFER_DATA(bufev->output),
179 d188f690 2022-02-04 op EVBUFFER_LENGTH(bufev->output));
180 d188f690 2022-02-04 op switch (ret) {
181 d188f690 2022-02-04 op case TLS_WANT_POLLIN:
182 d188f690 2022-02-04 op case TLS_WANT_POLLOUT:
185 d188f690 2022-02-04 op what |= EVBUFFER_ERROR;
189 d188f690 2022-02-04 op evbuffer_drain(bufev->output, len);
192 d188f690 2022-02-04 op if (EVBUFFER_LENGTH(bufev->output) != 0)
193 d188f690 2022-02-04 op event_add(&bufev->ev_write, NULL);
195 d188f690 2022-02-04 op if (bufev->writecb != NULL &&
196 d188f690 2022-02-04 op EVBUFFER_LENGTH(bufev->output) <= bufev->wm_write.low)
197 d188f690 2022-02-04 op (*bufev->writecb)(bufev, bufev->cbarg);
201 d188f690 2022-02-04 op event_add(&bufev->ev_write, NULL);
205 d188f690 2022-02-04 op (*bufev->errorcb)(bufev, what, bufev->cbarg);
211 d188f690 2022-02-04 op struct addrinfo hints, *res, *res0;
212 d188f690 2022-02-04 op int v, r, saved_errno;
213 d188f690 2022-02-04 op char host[64];
214 d188f690 2022-02-04 op const char *c, *h, *port, *cause;
216 d188f690 2022-02-04 op if ((c = strchr(fromhost, ':')) == NULL) {
218 d188f690 2022-02-04 op port = fromhost;
220 d188f690 2022-02-04 op if ((c = copysec(fromhost, host, sizeof(host))) == NULL)
221 d188f690 2022-02-04 op fatalx("hostname too long: %s", fromhost);
226 d188f690 2022-02-04 op memset(&hints, 0, sizeof(hints));
227 d188f690 2022-02-04 op hints.ai_family = AF_UNSPEC;
228 d188f690 2022-02-04 op hints.ai_socktype = SOCK_STREAM;
229 d188f690 2022-02-04 op hints.ai_flags = AI_PASSIVE;
231 d188f690 2022-02-04 op r = getaddrinfo(h, port, &hints, &res0);
233 d188f690 2022-02-04 op fatalx("getaddrinfo(%s): %s", fromhost,
234 d188f690 2022-02-04 op gai_strerror(r));
236 d188f690 2022-02-04 op for (res = res0; res && nsock < MAXSOCK; res = res->ai_next) {
237 d188f690 2022-02-04 op socks[nsock] = socket(res->ai_family, res->ai_socktype,
238 d188f690 2022-02-04 op res->ai_protocol);
239 d188f690 2022-02-04 op if (socks[nsock] == -1) {
240 d188f690 2022-02-04 op cause = "socket";
244 d188f690 2022-02-04 op if (bind(socks[nsock], res->ai_addr, res->ai_addrlen) == -1) {
245 d188f690 2022-02-04 op cause = "bind";
246 d188f690 2022-02-04 op saved_errno = errno;
247 d188f690 2022-02-04 op close(socks[nsock]);
248 d188f690 2022-02-04 op errno = saved_errno;
253 d188f690 2022-02-04 op if (setsockopt(socks[nsock], SOL_SOCKET, SO_REUSEADDR, &v,
254 d188f690 2022-02-04 op sizeof(v)) == -1)
255 d188f690 2022-02-04 op err(1, "setsockopt(SO_REUSEADDR)");
258 d188f690 2022-02-04 op if (setsockopt(socks[nsock], SOL_SOCKET, SO_REUSEPORT, &v,
259 d188f690 2022-02-04 op sizeof(v)) == -1)
260 d188f690 2022-02-04 op err(1, "setsockopt(SO_REUSEPORT)");
262 d188f690 2022-02-04 op listen(socks[nsock], 5);
266 d188f690 2022-02-04 op if (nsock == 0)
267 d188f690 2022-02-04 op fatal("%s", cause);
269 d188f690 2022-02-04 op freeaddrinfo(res0);
273 d188f690 2022-02-04 op servconnect(void)
275 d188f690 2022-02-04 op struct addrinfo hints, *res, *res0;
276 d188f690 2022-02-04 op int r, saved_errno, sock;
277 d188f690 2022-02-04 op const char *cause;
279 d188f690 2022-02-04 op memset(&hints, 0, sizeof(hints));
280 d188f690 2022-02-04 op hints.ai_family = AF_UNSPEC;
281 d188f690 2022-02-04 op hints.ai_socktype = SOCK_STREAM;
283 d188f690 2022-02-04 op r = getaddrinfo(kamihost, kamiport, &hints, &res0);
284 d188f690 2022-02-04 op if (r != 0) {
285 d188f690 2022-02-04 op log_warnx("getaddrinfo(%s, %s): %s", kamihost, kamiport,
286 d188f690 2022-02-04 op gai_strerror(r));
290 d188f690 2022-02-04 op for (res = res0; res != NULL; res = res->ai_next) {
291 d188f690 2022-02-04 op sock = socket(res->ai_family, res->ai_socktype,
292 d188f690 2022-02-04 op res->ai_protocol);
293 d188f690 2022-02-04 op if (sock == -1) {
294 d188f690 2022-02-04 op cause = "socket";
298 d188f690 2022-02-04 op if (connect(sock, res->ai_addr, res->ai_addrlen) == -1) {
299 d188f690 2022-02-04 op cause = "connect";
300 d188f690 2022-02-04 op saved_errno = errno;
302 d188f690 2022-02-04 op errno = saved_errno;
307 d188f690 2022-02-04 op /* found one */
311 d188f690 2022-02-04 op if (sock == -1)
312 d188f690 2022-02-04 op log_warn("%s", cause);
314 d188f690 2022-02-04 op freeaddrinfo(res0);
319 d188f690 2022-02-04 op copy_to_server(struct bufferevent *bev, void *d)
321 d188f690 2022-02-04 op struct conn *c = d;
323 d188f690 2022-02-04 op bufferevent_write_buffer(c->server, EVBUFFER_INPUT(bev));
327 d188f690 2022-02-04 op copy_to_client(struct bufferevent *bev, void *d)
329 d188f690 2022-02-04 op struct conn *c = d;
331 d188f690 2022-02-04 op bufferevent_write_buffer(c->client, EVBUFFER_INPUT(bev));
335 d188f690 2022-02-04 op nopcb(struct bufferevent *bev, void *d)
341 d188f690 2022-02-04 op errcb(struct bufferevent *bev, short ev, void *d)
343 d188f690 2022-02-04 op struct conn *c = d;
345 d188f690 2022-02-04 op log_debug("closing connection (event=%x / side=%s)", ev,
346 d188f690 2022-02-04 op bev == c->server ? "server" : "client");
348 d188f690 2022-02-04 op bufferevent_free(c->server);
349 d188f690 2022-02-04 op bufferevent_free(c->client);
351 d188f690 2022-02-04 op tls_close(c->ctx);
352 d188f690 2022-02-04 op tls_free(c->ctx);
354 d188f690 2022-02-04 op close(c->lfd);
355 d188f690 2022-02-04 op close(c->kfd);
361 d188f690 2022-02-04 op doaccept(int fd, short ev, void *data)
363 d188f690 2022-02-04 op struct tls_config *conf;
364 d188f690 2022-02-04 op struct conn *c;
367 d188f690 2022-02-04 op if ((c = calloc(1, sizeof(*c))) == NULL)
368 d188f690 2022-02-04 op fatal("calloc");
370 d188f690 2022-02-04 op if ((c->lfd = accept(fd, NULL, 0)) == -1) {
371 d188f690 2022-02-04 op log_warn("accept");
376 d188f690 2022-02-04 op if ((c->kfd = servconnect()) == -1) {
377 d188f690 2022-02-04 op close(c->lfd);
382 d188f690 2022-02-04 op if ((c->ctx = tls_client()) == NULL)
383 d188f690 2022-02-04 op fatal("tls_client");
385 d188f690 2022-02-04 op if ((conf = tls_config_new()) == NULL)
386 d188f690 2022-02-04 op fatal("tls_config_new");
388 d188f690 2022-02-04 op if (tls_config_set_cert_mem(conf, cert, certlen) == -1 ||
389 d188f690 2022-02-04 op tls_config_set_key_mem(conf, key, keylen) == -1)
390 d188f690 2022-02-04 op fatalx("tls_config_set_{cert,key}: %s", tls_config_error(conf));
391 d188f690 2022-02-04 op tls_config_insecure_noverifycert(conf);
393 d188f690 2022-02-04 op if (tls_configure(c->ctx, conf) == -1)
394 d188f690 2022-02-04 op fatalx("tls_configure");
396 d188f690 2022-02-04 op tls_config_free(conf);
398 d188f690 2022-02-04 op if (tls_connect_socket(c->ctx, c->kfd, kamihost) == -1)
399 d188f690 2022-02-04 op fatal("tls_connect_socket");
401 d188f690 2022-02-04 op again: switch (r = tls_handshake(c->ctx)) {
403 d188f690 2022-02-04 op log_warnx("tls_handshake: %s", tls_error(c->ctx));
404 d188f690 2022-02-04 op tls_close(c->ctx);
405 d188f690 2022-02-04 op tls_free(c->ctx);
406 d188f690 2022-02-04 op close(c->lfd);
407 d188f690 2022-02-04 op close(c->kfd);
410 d188f690 2022-02-04 op case TLS_WANT_POLLIN:
411 d188f690 2022-02-04 op case TLS_WANT_POLLOUT:
415 d188f690 2022-02-04 op c->server = bufferevent_new(c->kfd, copy_to_client, nopcb, errcb, c);
416 d188f690 2022-02-04 op if (c->server == NULL)
417 d188f690 2022-02-04 op fatal("bufferevent_new");
419 d188f690 2022-02-04 op event_set(&c->server->ev_read, c->kfd, EV_READ, tls_readcb,
421 d188f690 2022-02-04 op event_set(&c->server->ev_write, c->kfd, EV_WRITE, tls_writecb,
424 d188f690 2022-02-04 op #if HAVE_EVENT2
425 d188f690 2022-02-04 op evbuffer_unfreeze(c->server->input, 0);
426 d188f690 2022-02-04 op evbuffer_unfreeze(c->server->output, 1);
429 d188f690 2022-02-04 op c->client = bufferevent_new(c->lfd, copy_to_server, nopcb, errcb, c);
430 d188f690 2022-02-04 op if (c->client == NULL)
431 d188f690 2022-02-04 op fatal("bufferevent_new");
433 d188f690 2022-02-04 op bufferevent_enable(c->server, EV_READ|EV_WRITE);
434 d188f690 2022-02-04 op bufferevent_enable(c->client, EV_READ|EV_WRITE);
437 d188f690 2022-02-04 op __dead static void
440 d188f690 2022-02-04 op fprintf(stderr,
441 d188f690 2022-02-04 op "usage: %s [-dv] -c host[:port] -l [host:]port -C cert [-K key]\n",
442 d188f690 2022-02-04 op getprogname());
447 d188f690 2022-02-04 op main(int argc, char **argv)
450 d188f690 2022-02-04 op const char *certf = NULL, *keyf = NULL;
452 d188f690 2022-02-04 op log_init(1, LOG_DAEMON);
453 d188f690 2022-02-04 op log_setverbose(1);
455 d188f690 2022-02-04 op while ((ch = getopt(argc, argv, "C:c:dK:l:v")) != -1) {
456 d188f690 2022-02-04 op switch (ch) {
458 d188f690 2022-02-04 op certf = optarg;
461 d188f690 2022-02-04 op tohost = optarg;
467 d188f690 2022-02-04 op keyf = optarg;
470 d188f690 2022-02-04 op fromhost = optarg;
479 d188f690 2022-02-04 op argc -= optind;
480 d188f690 2022-02-04 op argv += optind;
482 d188f690 2022-02-04 op if (argc != 0)
484 d188f690 2022-02-04 op if (certf == NULL || tohost == NULL || fromhost == NULL)
486 d188f690 2022-02-04 op if (keyf == NULL)
487 d188f690 2022-02-04 op keyf = certf;
489 d188f690 2022-02-04 op parse_tohost();
491 d188f690 2022-02-04 op if ((cert = tls_load_file(certf, &certlen, NULL)) == NULL)
492 d188f690 2022-02-04 op fatal("can't load %s", certf);
493 d188f690 2022-02-04 op if ((key = tls_load_file(keyf, &keylen, NULL)) == NULL)
494 d188f690 2022-02-04 op fatal("can't load %s", keyf);
496 d188f690 2022-02-04 op log_init(debug, LOG_DAEMON);
497 d188f690 2022-02-04 op log_setverbose(verbose);
500 d188f690 2022-02-04 op daemon(1, 0);
502 d188f690 2022-02-04 op signal(SIGPIPE, SIG_IGN);
504 d188f690 2022-02-04 op event_init();
507 d188f690 2022-02-04 op for (i = 0; i < nsock; ++i) {
508 d188f690 2022-02-04 op event_set(&sockev[i], socks[i], EV_READ|EV_PERSIST,
509 d188f690 2022-02-04 op doaccept, NULL);
510 d188f690 2022-02-04 op event_add(&sockev[i], NULL);
513 d188f690 2022-02-04 op if (pledge("stdio dns inet", NULL) == -1)
514 d188f690 2022-02-04 op err(1, "pledge");
516 d188f690 2022-02-04 op log_info("starting");
517 d188f690 2022-02-04 op event_dispatch();