2 f224a3fe 2021-08-24 xhr * Copyright (c) 2021 Matthias Schmidt <xhr@giessen.ccc.de>
4 f224a3fe 2021-08-24 xhr * Permission to use, copy, modify, and distribute this software for any
5 f224a3fe 2021-08-24 xhr * purpose with or without fee is hereby granted, provided that the above
6 f224a3fe 2021-08-24 xhr * copyright notice and this permission notice appear in all copies.
8 f224a3fe 2021-08-24 xhr * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 f224a3fe 2021-08-24 xhr * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 f224a3fe 2021-08-24 xhr * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 f224a3fe 2021-08-24 xhr * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 f224a3fe 2021-08-24 xhr * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 f224a3fe 2021-08-24 xhr * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 f224a3fe 2021-08-24 xhr * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 f224a3fe 2021-08-24 xhr #define _GNU_SOURCE
19 f224a3fe 2021-08-24 xhr #include <sys/file.h>
20 f224a3fe 2021-08-24 xhr #include <sys/queue.h>
21 f224a3fe 2021-08-24 xhr #include <sys/socket.h>
22 f224a3fe 2021-08-24 xhr #include <sys/syslog.h>
23 f224a3fe 2021-08-24 xhr #include <sys/types.h>
24 f224a3fe 2021-08-24 xhr #include <sys/wait.h>
26 f224a3fe 2021-08-24 xhr #include <arpa/inet.h>
28 f224a3fe 2021-08-24 xhr #include <net/if.h>
29 f224a3fe 2021-08-24 xhr #include <netinet/in.h>
31 f224a3fe 2021-08-24 xhr #include <openssl/err.h>
32 f224a3fe 2021-08-24 xhr #include <openssl/ssl.h>
34 f224a3fe 2021-08-24 xhr #include <errno.h>
35 f224a3fe 2021-08-24 xhr #include <fcntl.h>
36 f224a3fe 2021-08-24 xhr #include <limits.h>
37 f224a3fe 2021-08-24 xhr #include <netdb.h>
38 f224a3fe 2021-08-24 xhr #include <pthread.h>
39 f224a3fe 2021-08-24 xhr #include <pwd.h>
40 f224a3fe 2021-08-24 xhr #include <signal.h>
41 f224a3fe 2021-08-24 xhr #include <syslog.h>
42 f224a3fe 2021-08-24 xhr #include <stdarg.h>
43 f224a3fe 2021-08-24 xhr #include <stdio.h>
44 f224a3fe 2021-08-24 xhr #include <stdlib.h>
45 f224a3fe 2021-08-24 xhr #include <string.h>
46 f224a3fe 2021-08-24 xhr #include <unistd.h>
48 f224a3fe 2021-08-24 xhr #if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) &&\
49 f224a3fe 2021-08-24 xhr !defined(__DragonFly__)
50 f224a3fe 2021-08-24 xhr #include <grp.h>
51 f224a3fe 2021-08-24 xhr #endif /* __BSD__ */
53 f224a3fe 2021-08-24 xhr #include "log.h"
54 f224a3fe 2021-08-24 xhr #include "twind.h"
56 f224a3fe 2021-08-24 xhr #define PID_BUF_SIZE 100
57 f224a3fe 2021-08-24 xhr #define TWIND_USER "_twind"
58 f224a3fe 2021-08-24 xhr #define _PATH_TWIND_CHROOT "/var/twind"
59 f224a3fe 2021-08-24 xhr #define _PATH_TWIND_LOGS "/var/twind/logs"
60 f224a3fe 2021-08-24 xhr #define _PATH_TWIND_CERT "/etc/twind/twind.cert.pem"
61 f224a3fe 2021-08-24 xhr #define _PATH_TWIND_KEY "/etc/twind/twind.key.pem"
62 f224a3fe 2021-08-24 xhr #define _PATH_TWIND_PID_CHROOT "/var/twind/twind.pid"
63 f224a3fe 2021-08-24 xhr #define _PATH_TWIND_PID "twind.pid"
65 f224a3fe 2021-08-24 xhr static void organize_termination(void);
66 f224a3fe 2021-08-24 xhr static void open_sockets(int[2], int);
67 f224a3fe 2021-08-24 xhr void *get_in_addr(struct sockaddr *);
68 f224a3fe 2021-08-24 xhr void* main_request_handler(void*);
69 f224a3fe 2021-08-24 xhr int receive_gemini_request(SSL*, char *);
70 f224a3fe 2021-08-24 xhr int handle_incoming_connections(int, int, SSL_CTX *);
71 f224a3fe 2021-08-24 xhr void fork_main_process(int[2], SSL_CTX *);
72 f224a3fe 2021-08-24 xhr SSL_CTX* initialize_tls_context(void);
73 f224a3fe 2021-08-24 xhr int open_pid_file(void);
74 f224a3fe 2021-08-24 xhr static void drop_root(void);
76 f224a3fe 2021-08-24 xhr #if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) &&\
77 f224a3fe 2021-08-24 xhr !defined(__DragonFly__)
78 f224a3fe 2021-08-24 xhr void setproctitle(const char *, ...);
79 f224a3fe 2021-08-24 xhr void setproctitle(const char *fmt, ...) {}
80 f224a3fe 2021-08-24 xhr #endif /* __BSD__ */
85 f224a3fe 2021-08-24 xhr extern char *__progname;
87 f224a3fe 2021-08-24 xhr fprintf(stderr, "usage: %s [-dfv] [-p port]\n", __progname);
92 f224a3fe 2021-08-24 xhr signal_handler(int signal)
94 f224a3fe 2021-08-24 xhr switch (signal) {
96 75e29feb 2021-08-26 xhr reload_log_files = 1;
99 f224a3fe 2021-08-24 xhr case SIGTERM:
100 f224a3fe 2021-08-24 xhr organize_termination();
103 f224a3fe 2021-08-24 xhr fatalx("Unknown signal");
108 f224a3fe 2021-08-24 xhr main(int argc, char *argv[])
110 f224a3fe 2021-08-24 xhr SSL_CTX *sslctx = NULL;
111 f224a3fe 2021-08-24 xhr int ch, fg_flag = 0, debug_flag = 0, verbose_flag = 0;
112 f224a3fe 2021-08-24 xhr int tcpsock[2] = { -1, -1 }, port = 1965;
114 f224a3fe 2021-08-24 xhr log_init(1, LOG_DAEMON); /* Log to stderr until daemonized. */
115 f224a3fe 2021-08-24 xhr log_setverbose(1);
117 f224a3fe 2021-08-24 xhr while ((ch = getopt(argc, argv, "dfp:vV")) != -1) {
118 f224a3fe 2021-08-24 xhr switch(ch) {
120 f224a3fe 2021-08-24 xhr debug_flag = 1;
123 f224a3fe 2021-08-24 xhr fg_flag = 1;
126 f224a3fe 2021-08-24 xhr port = atoi(optarg);
129 f224a3fe 2021-08-24 xhr verbose_flag = 1;
132 f224a3fe 2021-08-24 xhr fprintf(stderr, "Version %s\n", VERSION);
140 f224a3fe 2021-08-24 xhr argc -= optind;
141 f224a3fe 2021-08-24 xhr argv += optind;
143 f224a3fe 2021-08-24 xhr if (geteuid())
144 f224a3fe 2021-08-24 xhr fatalx("need root privileges");
146 f224a3fe 2021-08-24 xhr open_pid_file();
148 f224a3fe 2021-08-24 xhr if (signal(SIGINT, signal_handler) == SIG_ERR)
149 f224a3fe 2021-08-24 xhr fatalx("signal");
150 f224a3fe 2021-08-24 xhr if (signal(SIGTERM, signal_handler) == SIG_ERR)
151 f224a3fe 2021-08-24 xhr fatalx("signal");
152 75e29feb 2021-08-26 xhr if (signal(SIGHUP, signal_handler) == SIG_ERR)
153 75e29feb 2021-08-26 xhr fatalx("signal");
155 f224a3fe 2021-08-24 xhr open_sockets(tcpsock, port);
157 f224a3fe 2021-08-24 xhr sslctx = initialize_tls_context();
159 f224a3fe 2021-08-24 xhr drop_root();
161 f224a3fe 2021-08-24 xhr log_init(debug_flag, LOG_DAEMON);
162 f224a3fe 2021-08-24 xhr log_setverbose(verbose_flag);
165 f224a3fe 2021-08-24 xhr #ifdef __OpenBSD__
166 9e328210 2021-08-26 xhr if (pledge("stdio inet dns proc rpath wpath cpath", NULL) == -1)
167 f224a3fe 2021-08-24 xhr fatalx("pledge");
168 f224a3fe 2021-08-24 xhr #endif /* __OpenBSD__ */
170 f224a3fe 2021-08-24 xhr if (!fg_flag)
171 f224a3fe 2021-08-24 xhr if (daemon(0, 0) == -1)
172 f224a3fe 2021-08-24 xhr fatalx("daemonizing failed");
174 9e328210 2021-08-26 xhr open_twind_logs();
176 ee3ef24f 2021-08-26 xhr fork_main_process(tcpsock, sslctx);
178 f224a3fe 2021-08-24 xhr organize_termination();
184 f224a3fe 2021-08-24 xhr organize_termination(void)
186 f224a3fe 2021-08-24 xhr pid_t sub_pid;
188 9e328210 2021-08-26 xhr close_twind_logs();
190 7b16d7ca 2021-08-26 xhr #ifdef __OpenBSD__
191 7b16d7ca 2021-08-26 xhr if (pledge("stdio", NULL) == -1)
192 7b16d7ca 2021-08-26 xhr fatalx("pledge");
193 7b16d7ca 2021-08-26 xhr #endif /* __OpenBSD__ */
195 f224a3fe 2021-08-24 xhr log_debug("waiting for sub processes to terminate");
197 f224a3fe 2021-08-24 xhr sub_pid = wait(NULL);
198 f224a3fe 2021-08-24 xhr if (sub_pid == -1) {
199 f224a3fe 2021-08-24 xhr if (errno == ECHILD) {
200 f224a3fe 2021-08-24 xhr /* All sub processes are terminated */
201 f224a3fe 2021-08-24 xhr close_twind_logs();
202 f224a3fe 2021-08-24 xhr log_debug("twind turns to dust");
205 f224a3fe 2021-08-24 xhr fatalx("wait");
209 aae0748e 2021-08-26 xhr log_debug("Child %d terminated", sub_pid);
214 f224a3fe 2021-08-24 xhr initialize_tls_context(void)
216 f224a3fe 2021-08-24 xhr SSL_CTX *sslctx;
218 f224a3fe 2021-08-24 xhr SSL_load_error_strings();
219 f224a3fe 2021-08-24 xhr OpenSSL_add_all_algorithms();
221 f224a3fe 2021-08-24 xhr sslctx = SSL_CTX_new(TLS_method());
222 f224a3fe 2021-08-24 xhr if (sslctx == NULL)
223 f224a3fe 2021-08-24 xhr fatalx("Cannot initialize TLS CTX structure");
225 f224a3fe 2021-08-24 xhr SSL_CTX_set_ecdh_auto(sslctx, 1);
227 f224a3fe 2021-08-24 xhr /* Gemini requires TLSv1.2 minimum */
228 f224a3fe 2021-08-24 xhr if (SSL_CTX_set_min_proto_version(sslctx, TLS1_2_VERSION) != 1)
229 f224a3fe 2021-08-24 xhr fatalx("Cannot set minimum TLS version");
231 f224a3fe 2021-08-24 xhr if (SSL_CTX_use_certificate_file(sslctx, _PATH_TWIND_CERT, SSL_FILETYPE_PEM)
233 f224a3fe 2021-08-24 xhr fatalx("Cannot load TLS certificate %s", _PATH_TWIND_CERT);
235 f224a3fe 2021-08-24 xhr if (SSL_CTX_use_PrivateKey_file(sslctx, _PATH_TWIND_KEY, SSL_FILETYPE_PEM)
237 f224a3fe 2021-08-24 xhr fatalx("Cannot load TLS private key %s", _PATH_TWIND_KEY);
239 f224a3fe 2021-08-24 xhr return sslctx;
243 f224a3fe 2021-08-24 xhr get_in_addr(struct sockaddr *sa)
245 f224a3fe 2021-08-24 xhr if (sa->sa_family == AF_INET)
246 f224a3fe 2021-08-24 xhr return &(((struct sockaddr_in*)sa)->sin_addr);
248 f224a3fe 2021-08-24 xhr return &(((struct sockaddr_in6*)sa)->sin6_addr);
252 f224a3fe 2021-08-24 xhr handle_incoming_connections(int counter, int tcpsock, SSL_CTX *sslctx)
254 f224a3fe 2021-08-24 xhr struct sockaddr_storage addr;
255 f224a3fe 2021-08-24 xhr struct client_connection *cc;
256 f224a3fe 2021-08-24 xhr char str[INET6_ADDRSTRLEN];
257 f224a3fe 2021-08-24 xhr pthread_t thread_id;
258 f224a3fe 2021-08-24 xhr socklen_t len = sizeof(addr);
259 f224a3fe 2021-08-24 xhr int ret, ssl_err;
261 f224a3fe 2021-08-24 xhr #ifdef __OpenBSD__
262 f224a3fe 2021-08-24 xhr /* We can get rid of proc pledge here */
263 9e328210 2021-08-26 xhr if (pledge("stdio inet dns rpath wpath cpath", NULL) == -1)
264 f224a3fe 2021-08-24 xhr fatalx("pledge");
265 f224a3fe 2021-08-24 xhr #endif /* __OpenBSD__ */
267 f224a3fe 2021-08-24 xhr memset(str, 0, sizeof(str));
270 75e29feb 2021-08-26 xhr if (reload_log_files == 1) {
271 75e29feb 2021-08-26 xhr reload_log_files = 0;
272 75e29feb 2021-08-26 xhr log_debug("Re-open log files");
273 75e29feb 2021-08-26 xhr close_twind_logs();
274 75e29feb 2021-08-26 xhr open_twind_logs();
277 f224a3fe 2021-08-24 xhr ret = accept(tcpsock, (struct sockaddr *)&addr, &len);
278 f224a3fe 2021-08-24 xhr if (ret < 0)
279 f224a3fe 2021-08-24 xhr fatalx("Error when accepting connection");
281 f224a3fe 2021-08-24 xhr cc = xmalloc(sizeof(struct client_connection));
283 f224a3fe 2021-08-24 xhr inet_ntop(addr.ss_family, get_in_addr((struct sockaddr *)&addr), str, sizeof(str));
284 f224a3fe 2021-08-24 xhr strlcpy(cc->client_addr, str, INET6_ADDRSTRLEN);
285 c750ce60 2021-08-25 xhr log_info("Connection from %s", cc->client_addr);
287 f224a3fe 2021-08-24 xhr if ((cc->ssl_peer = SSL_new(sslctx)) == NULL) {
288 f224a3fe 2021-08-24 xhr log_warn("Creating new TLS structure failed");
294 f224a3fe 2021-08-24 xhr if (SSL_set_fd(cc->ssl_peer, ret) == 0) {
295 f224a3fe 2021-08-24 xhr log_warn("TLS cannot set file descriptor");
296 f224a3fe 2021-08-24 xhr SSL_free(cc->ssl_peer);
302 f224a3fe 2021-08-24 xhr ssl_err = SSL_accept(cc->ssl_peer);
303 f224a3fe 2021-08-24 xhr if (ssl_err < 0) {
304 f224a3fe 2021-08-24 xhr ERR_print_errors_fp(stderr);
305 f224a3fe 2021-08-24 xhr log_warn("Fatal TLS error. Cannot accept TLS connection");
306 f224a3fe 2021-08-24 xhr SSL_shutdown(cc->ssl_peer);
307 f224a3fe 2021-08-24 xhr SSL_free(cc->ssl_peer);
311 f224a3fe 2021-08-24 xhr } else if (ssl_err == 0) {
312 f224a3fe 2021-08-24 xhr log_warn("TLS handshake not successful");
313 f224a3fe 2021-08-24 xhr SSL_shutdown(cc->ssl_peer);
314 f224a3fe 2021-08-24 xhr SSL_free(cc->ssl_peer);
320 f224a3fe 2021-08-24 xhr log_debug("SSL connection using %s", SSL_get_cipher(cc->ssl_peer));
322 f224a3fe 2021-08-24 xhr if (pthread_create(&thread_id, NULL, main_request_handler, ((void*)cc))
324 f224a3fe 2021-08-24 xhr log_warn("Cannot create handling thread");
325 f224a3fe 2021-08-24 xhr SSL_shutdown(cc->ssl_peer);
326 f224a3fe 2021-08-24 xhr SSL_free(cc->ssl_peer);
332 f224a3fe 2021-08-24 xhr if (pthread_join(thread_id, NULL) != 0) {
333 f224a3fe 2021-08-24 xhr log_warn("Error while joining thread");
334 f224a3fe 2021-08-24 xhr SSL_shutdown(cc->ssl_peer);
335 f224a3fe 2021-08-24 xhr SSL_free(cc->ssl_peer);
341 f224a3fe 2021-08-24 xhr SSL_shutdown(cc->ssl_peer);
342 f224a3fe 2021-08-24 xhr SSL_free(cc->ssl_peer);
351 f224a3fe 2021-08-24 xhr fork_main_process(int tcpsock[2], SSL_CTX *sslctx)
356 9ebb8b99 2021-08-26 xhr setproctitle("main");
358 f224a3fe 2021-08-24 xhr /* Fork two main handler processes, one for IPv4, one for IPv6 */
359 f224a3fe 2021-08-24 xhr for (i=0; i < 2; i++) {
360 f224a3fe 2021-08-24 xhr if (tcpsock[i] == -1)
362 f224a3fe 2021-08-24 xhr switch (pid = fork()) {
364 f224a3fe 2021-08-24 xhr fatalx("Cannot fork() main IPv%d handler process", i == 0 ? 4 : 6);
366 f224a3fe 2021-08-24 xhr log_debug("Main IPv%d handling process started: %d", i == 0 ? 4 : 6,
368 f224a3fe 2021-08-24 xhr setproctitle("v%d %s", i == 0 ? 4 : 6, "handler");
369 f224a3fe 2021-08-24 xhr handle_incoming_connections(i, tcpsock[i], sslctx);
376 f224a3fe 2021-08-24 xhr main_request_handler(void *argp)
378 f224a3fe 2021-08-24 xhr struct client_connection *cc = (struct client_connection *)argp;
379 f224a3fe 2021-08-24 xhr char finalpath[MAXREQLEN];
380 f224a3fe 2021-08-24 xhr char temp[MAXREQLEN];
381 f224a3fe 2021-08-24 xhr char request[MAXREQLEN];
382 f224a3fe 2021-08-24 xhr char *ext = NULL;
383 f224a3fe 2021-08-24 xhr char *mime = NULL;
386 f224a3fe 2021-08-24 xhr memset(finalpath, 0, sizeof(finalpath));
387 f224a3fe 2021-08-24 xhr memset(request, 0, sizeof(request));
388 f224a3fe 2021-08-24 xhr memset(temp, 0, sizeof(temp));
390 f224a3fe 2021-08-24 xhr if (receive_gemini_request(cc->ssl_peer, request) < 0) {
391 f224a3fe 2021-08-24 xhr log_warn("Receiving initial request failed");
392 f224a3fe 2021-08-24 xhr return NULL;
395 f224a3fe 2021-08-24 xhr ret = get_path_from_request(request, finalpath);
396 f224a3fe 2021-08-24 xhr if (ret == -1) { /* Malformed request */
397 f224a3fe 2021-08-24 xhr log_error(cc, "Malformed request");
398 f224a3fe 2021-08-24 xhr send_non_success_response(cc->ssl_peer, STATUS_BAD_REQUEST);
399 f224a3fe 2021-08-24 xhr return NULL;
400 f224a3fe 2021-08-24 xhr } else if (ret == -2) { /* 404 */
401 f224a3fe 2021-08-24 xhr log_error(cc, "Request file not found");
402 f224a3fe 2021-08-24 xhr send_non_success_response(cc->ssl_peer, STATUS_NOT_FOUND);
403 f224a3fe 2021-08-24 xhr return NULL;
406 f224a3fe 2021-08-24 xhr if ((ext = get_file_extension(finalpath)) == NULL) {
407 f224a3fe 2021-08-24 xhr log_debug("Cannot get file extension from %s", finalpath);
409 f224a3fe 2021-08-24 xhr if ((mime = get_mime_type(ext)) == NULL)
410 f224a3fe 2021-08-24 xhr log_debug("Cannot get MIME type for %s", ext);
413 f224a3fe 2021-08-24 xhr log_access(cc, finalpath);
415 f224a3fe 2021-08-24 xhr if (send_response(cc->ssl_peer, STATUS_SUCCESS, finalpath, mime) < 0) {
416 f224a3fe 2021-08-24 xhr log_warn("Sending response to client failed");
417 f224a3fe 2021-08-24 xhr return NULL;
423 f224a3fe 2021-08-24 xhr return NULL;
427 f224a3fe 2021-08-24 xhr * Gemini requests are a single CRLF-terminated line with the following structure:
429 f224a3fe 2021-08-24 xhr * <URL><CR><LF>
431 f224a3fe 2021-08-24 xhr * <URL> is a UTF-8 encoded absolute URL, including a scheme, of maximum length
432 f224a3fe 2021-08-24 xhr * 1024 bytes.
435 f224a3fe 2021-08-24 xhr receive_gemini_request(SSL *ssl_peer, char* request_buf)
437 f224a3fe 2021-08-24 xhr if (SSL_read(ssl_peer, request_buf, MAXREQLEN) <= 0)
444 f224a3fe 2021-08-24 xhr open_sockets(int tcpsock[2], int port)
446 f224a3fe 2021-08-24 xhr struct sockaddr_in addr4;
447 f224a3fe 2021-08-24 xhr struct sockaddr_in6 addr6;
448 f224a3fe 2021-08-24 xhr struct sockaddr *addr;
449 f224a3fe 2021-08-24 xhr socklen_t len;
450 f224a3fe 2021-08-24 xhr int opt = 1;
452 f224a3fe 2021-08-24 xhr memset(&addr4, 0, sizeof(addr4));
453 f224a3fe 2021-08-24 xhr addr4.sin_family = AF_INET;
454 f224a3fe 2021-08-24 xhr addr4.sin_port = htons(port);
455 f224a3fe 2021-08-24 xhr addr4.sin_addr.s_addr = INADDR_ANY;
456 f224a3fe 2021-08-24 xhr addr = (struct sockaddr*)&addr4;
457 f224a3fe 2021-08-24 xhr len = sizeof(addr4);
459 f224a3fe 2021-08-24 xhr if ((tcpsock[0] = socket(AF_INET, SOCK_STREAM, 0)) != -1) {
460 f224a3fe 2021-08-24 xhr if (setsockopt(tcpsock[0], SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))
462 f224a3fe 2021-08-24 xhr log_warn("setting SO_REUSEADDR on socket");
463 f224a3fe 2021-08-24 xhr if (bind(tcpsock[0], addr, len) == -1) {
464 f224a3fe 2021-08-24 xhr close(tcpsock[0]);
465 f224a3fe 2021-08-24 xhr tcpsock[0] = -1;
467 f224a3fe 2021-08-24 xhr if (listen(tcpsock[0], 5) == -1) {
468 f224a3fe 2021-08-24 xhr close(tcpsock[0]);
469 f224a3fe 2021-08-24 xhr tcpsock[0] = -1;
473 f224a3fe 2021-08-24 xhr memset(&addr6, 0, sizeof(addr6));
474 f224a3fe 2021-08-24 xhr addr6.sin6_family = AF_INET6;
475 f224a3fe 2021-08-24 xhr addr6.sin6_port = htons(port);
476 f224a3fe 2021-08-24 xhr addr6.sin6_addr = in6addr_any;
477 f224a3fe 2021-08-24 xhr addr = (struct sockaddr*)&addr6;
478 f224a3fe 2021-08-24 xhr len = sizeof(addr6);
480 f224a3fe 2021-08-24 xhr if ((tcpsock[1] = socket(AF_INET6, SOCK_STREAM, 0)) != -1) {
481 f224a3fe 2021-08-24 xhr if (setsockopt(tcpsock[1], SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))
483 f224a3fe 2021-08-24 xhr log_warn("setting SO_REUSEADDR on socket");
484 f224a3fe 2021-08-24 xhr if (bind(tcpsock[1], addr, len) == -1) {
485 f224a3fe 2021-08-24 xhr close(tcpsock[1]);
486 f224a3fe 2021-08-24 xhr tcpsock[1] = -1;
488 f224a3fe 2021-08-24 xhr if (listen(tcpsock[1], 5) == -1) {
489 f224a3fe 2021-08-24 xhr close(tcpsock[1]);
490 f224a3fe 2021-08-24 xhr tcpsock[1] = -1;
494 f224a3fe 2021-08-24 xhr if (tcpsock[0] == -1 && tcpsock[1] == -1) {
495 f224a3fe 2021-08-24 xhr fatalx("Cannot bind to 0.0.0.0 or :: on Port 1965");
500 f224a3fe 2021-08-24 xhr open_pid_file(void)
502 f224a3fe 2021-08-24 xhr char buf[PID_BUF_SIZE];
503 f224a3fe 2021-08-24 xhr char pid_path[MAXREQLEN];
506 f224a3fe 2021-08-24 xhr snprintf(pid_path, MAXREQLEN, "%s/%s",
507 f224a3fe 2021-08-24 xhr _PATH_TWIND_CHROOT, _PATH_TWIND_PID);
508 f224a3fe 2021-08-24 xhr if ((fd = open(pid_path, O_CREAT|O_RDWR, 0600)) == -1)
509 f224a3fe 2021-08-24 xhr fatalx("Cannot open PID file");
511 f224a3fe 2021-08-24 xhr if (flock(fd, LOCK_EX|LOCK_NB) == -1)
512 f224a3fe 2021-08-24 xhr fatalx("Cannot get lock on PID file. Another instance running?");
515 f224a3fe 2021-08-24 xhr * We need to truncate the file since the new PID could be shorter than
516 f224a3fe 2021-08-24 xhr * an old one in the file.
518 f224a3fe 2021-08-24 xhr if (ftruncate(fd, 0) == -1)
519 f224a3fe 2021-08-24 xhr fatalx("Cannot truncate PID file");
521 f224a3fe 2021-08-24 xhr snprintf(buf, PID_BUF_SIZE, "%ld\n", (long) getpid());
522 f224a3fe 2021-08-24 xhr if (write(fd, buf, strlen(buf)) != (ssize_t)strlen(buf))
523 f224a3fe 2021-08-24 xhr fatalx("Cannot write PID file");
529 f224a3fe 2021-08-24 xhr drop_root(void)
531 f224a3fe 2021-08-24 xhr struct passwd *pw;
533 f224a3fe 2021-08-24 xhr if (!(pw = getpwnam(TWIND_USER)))
534 f224a3fe 2021-08-24 xhr fatalx("Cannot find user entry for %s", TWIND_USER);
536 f224a3fe 2021-08-24 xhr if (!pw->pw_uid)
537 f224a3fe 2021-08-24 xhr fatalx("Cannot get UID entry for %s", TWIND_USER);
539 f224a3fe 2021-08-24 xhr #ifdef __OpenBSD__
540 f224a3fe 2021-08-24 xhr if (unveil(_PATH_TWIND_CERT, "r") == -1)
541 f224a3fe 2021-08-24 xhr fatalx("unveil");
542 f224a3fe 2021-08-24 xhr if (unveil(_PATH_TWIND_KEY, "r") == -1)
543 f224a3fe 2021-08-24 xhr fatalx("unveil");
544 f224a3fe 2021-08-24 xhr if (unveil(_PATH_TWIND_CHROOT, "r") == -1)
545 f224a3fe 2021-08-24 xhr fatalx("unveil");
546 f224a3fe 2021-08-24 xhr if (unveil(_PATH_TWIND_PID_CHROOT, "r") == -1)
547 f224a3fe 2021-08-24 xhr fatalx("unveil");
548 f224a3fe 2021-08-24 xhr if (unveil(_PATH_TWIND_LOGS, "cw") == -1)
549 f224a3fe 2021-08-24 xhr log_warn("unveil");
550 f224a3fe 2021-08-24 xhr if (unveil(NULL, NULL) == -1)
551 f224a3fe 2021-08-24 xhr fatalx("unveil");
552 f224a3fe 2021-08-24 xhr #endif /* __OpenBSD__ */
554 f224a3fe 2021-08-24 xhr if (chroot(_PATH_TWIND_CHROOT) == -1)
555 f224a3fe 2021-08-24 xhr fatalx("chroot() to %s failed", _PATH_TWIND_CHROOT);
556 f224a3fe 2021-08-24 xhr if (chdir("/") == -1)
557 f224a3fe 2021-08-24 xhr fatalx("chdir() failed");
559 f224a3fe 2021-08-24 xhr if (setgroups(1, &pw->pw_gid) == -1)
560 f224a3fe 2021-08-24 xhr fatalx("Cannot set group access list");
561 f224a3fe 2021-08-24 xhr if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) == -1)
562 f224a3fe 2021-08-24 xhr fatalx("Cannot set GUID to %d", pw->pw_gid);
563 f224a3fe 2021-08-24 xhr if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) == -1)
564 f224a3fe 2021-08-24 xhr fatalx("Cannot set UID to %d", pw->pw_uid);