2 aac8053c 2021-08-12 xhr * Copyright (c) 2021 Matthias Schmidt <xhr@giessen.ccc.de>
4 aac8053c 2021-08-12 xhr * Permission to use, copy, modify, and distribute this software for any
5 aac8053c 2021-08-12 xhr * purpose with or without fee is hereby granted, provided that the above
6 aac8053c 2021-08-12 xhr * copyright notice and this permission notice appear in all copies.
8 aac8053c 2021-08-12 xhr * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 aac8053c 2021-08-12 xhr * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 aac8053c 2021-08-12 xhr * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 aac8053c 2021-08-12 xhr * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 aac8053c 2021-08-12 xhr * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 aac8053c 2021-08-12 xhr * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 aac8053c 2021-08-12 xhr * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 003004f9 2021-08-08 xhr #define _GNU_SOURCE
19 e68a87d3 2021-08-09 xhr #include <sys/file.h>
20 edc334c2 2021-08-05 xhr #include <sys/queue.h>
21 edc334c2 2021-08-05 xhr #include <sys/socket.h>
22 edc334c2 2021-08-05 xhr #include <sys/syslog.h>
23 edc334c2 2021-08-05 xhr #include <sys/types.h>
24 a366f6dc 2021-08-07 xhr #include <sys/wait.h>
26 a366f6dc 2021-08-07 xhr #include <arpa/inet.h>
28 edc334c2 2021-08-05 xhr #include <net/if.h>
29 095cf201 2021-08-08 xhr #include <netinet/in.h>
31 4b2a8511 2021-08-07 xhr #include <openssl/err.h>
32 4b2a8511 2021-08-07 xhr #include <openssl/ssl.h>
34 a366f6dc 2021-08-07 xhr #include <errno.h>
35 401450e1 2021-08-08 xhr #include <fcntl.h>
36 8748d027 2021-08-08 xhr #include <limits.h>
37 edc334c2 2021-08-05 xhr #include <netdb.h>
38 1685bafb 2021-08-11 xhr #include <pthread.h>
39 dd70858b 2021-08-08 xhr #include <pwd.h>
40 171c60e7 2021-08-09 xhr #include <signal.h>
41 edc334c2 2021-08-05 xhr #include <syslog.h>
42 edc334c2 2021-08-05 xhr #include <stdarg.h>
43 edc334c2 2021-08-05 xhr #include <stdio.h>
44 edc334c2 2021-08-05 xhr #include <stdlib.h>
45 edc334c2 2021-08-05 xhr #include <string.h>
46 edc334c2 2021-08-05 xhr #include <unistd.h>
48 0f5f93fa 2021-08-12 xhr #if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) &&\
49 0f5f93fa 2021-08-12 xhr !defined(__DragonFly__)
50 5af2ed18 2021-08-08 xhr #include <grp.h>
51 5af2ed18 2021-08-08 xhr #endif /* __BSD__ */
53 edc334c2 2021-08-05 xhr #include "log.h"
54 a8bc9bf1 2021-08-06 xhr #include "twind.h"
56 e68a87d3 2021-08-09 xhr #define PID_BUF_SIZE 100
57 dd70858b 2021-08-08 xhr #define TWIND_USER "_twind"
58 243b8b13 2021-08-12 xhr #define _PATH_TWIND_CHROOT "/var/twind"
59 243b8b13 2021-08-12 xhr #define _PATH_TWIND_CERT "/etc/twind/twind.cert.pem"
60 243b8b13 2021-08-12 xhr #define _PATH_TWIND_KEY "/etc/twind/twind.key.pem"
61 243b8b13 2021-08-12 xhr #define _PATH_TWIND_PID_CHROOT "/var/twind/twind.pid"
62 7e4cf0c1 2021-08-09 xhr #define _PATH_TWIND_PID "twind.pid"
64 7e4cf0c1 2021-08-09 xhr static void organize_termination(void);
65 004fd51a 2021-08-12 xhr static void open_sockets(int[2], int);
66 1685bafb 2021-08-11 xhr void* main_request_handler(void*);
67 84033a53 2021-08-08 xhr void receive_gemini_request(SSL*, char *);
68 6b4246f1 2021-08-10 xhr int handle_incoming_connections(int, int, SSL_CTX *);
69 6b4246f1 2021-08-10 xhr void fork_main_process(int[2], SSL_CTX *);
70 1d446d16 2021-08-07 xhr SSL_CTX* initialize_tls_context(void);
71 e68a87d3 2021-08-09 xhr int open_pid_file(void);
72 87876c15 2021-08-09 xhr static void drop_root(void);
74 0f5f93fa 2021-08-12 xhr #if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) &&\
75 0f5f93fa 2021-08-12 xhr !defined(__DragonFly__)
76 003004f9 2021-08-08 xhr void setproctitle(const char *, ...);
77 003004f9 2021-08-08 xhr void setproctitle(const char *fmt, ...) {}
78 5af2ed18 2021-08-08 xhr #endif /* __BSD__ */
83 edc334c2 2021-08-05 xhr extern char *__progname;
85 004fd51a 2021-08-12 xhr fprintf(stderr, "usage: %s [-dfv] [-p port]\n", __progname);
90 7e4cf0c1 2021-08-09 xhr signal_handler(int signal)
92 7e4cf0c1 2021-08-09 xhr switch (signal) {
94 7e4cf0c1 2021-08-09 xhr case SIGTERM:
95 7e4cf0c1 2021-08-09 xhr organize_termination();
98 7e4cf0c1 2021-08-09 xhr fatalx("Unknown signal");
103 edc334c2 2021-08-05 xhr main(int argc, char *argv[])
105 4b2a8511 2021-08-07 xhr SSL_CTX *sslctx = NULL;
106 c83eee1a 2021-08-08 xhr int ch, fg_flag = 0, debug_flag = 0, verbose_flag = 0;
107 004fd51a 2021-08-12 xhr int tcpsock[2] = { -1, -1 }, port = 1965;
109 c83eee1a 2021-08-08 xhr log_init(1, LOG_DAEMON); /* Log to stderr until daemonized. */
110 c83eee1a 2021-08-08 xhr log_setverbose(1);
112 004fd51a 2021-08-12 xhr while ((ch = getopt(argc, argv, "dfp:vV")) != -1) {
113 edc334c2 2021-08-05 xhr switch(ch) {
115 c83eee1a 2021-08-08 xhr debug_flag = 1;
118 edc334c2 2021-08-05 xhr fg_flag = 1;
121 004fd51a 2021-08-12 xhr port = atoi(optarg);
124 c83eee1a 2021-08-08 xhr verbose_flag = 1;
127 b67b4591 2021-08-12 xhr fprintf(stderr, "Version %s\n", VERSION);
135 edc334c2 2021-08-05 xhr argc -= optind;
136 edc334c2 2021-08-05 xhr argv += optind;
138 86bf65be 2021-08-08 xhr if (geteuid())
139 86bf65be 2021-08-08 xhr fatalx("need root privileges");
141 6b4246f1 2021-08-10 xhr open_pid_file();
143 7e4cf0c1 2021-08-09 xhr if (signal(SIGINT, signal_handler) == SIG_ERR)
144 7e4cf0c1 2021-08-09 xhr fatalx("signal");
145 7e4cf0c1 2021-08-09 xhr if (signal(SIGTERM, signal_handler) == SIG_ERR)
146 7e4cf0c1 2021-08-09 xhr fatalx("signal");
148 004fd51a 2021-08-12 xhr open_sockets(tcpsock, port);
150 1d446d16 2021-08-07 xhr sslctx = initialize_tls_context();
152 dd70858b 2021-08-08 xhr drop_root();
154 c83eee1a 2021-08-08 xhr log_init(debug_flag, LOG_DAEMON);
155 c83eee1a 2021-08-08 xhr log_setverbose(verbose_flag);
157 a77b63fc 2021-08-08 xhr #ifdef __OpenBSD__
158 a77b63fc 2021-08-08 xhr if (pledge("stdio inet dns proc rpath", NULL) == -1)
159 a77b63fc 2021-08-08 xhr fatalx("pledge");
160 015e6064 2021-08-08 xhr #endif /* __OpenBSD__ */
162 6b4246f1 2021-08-10 xhr fork_main_process(tcpsock, sslctx);
164 a366f6dc 2021-08-07 xhr if (!fg_flag)
165 698f8cca 2021-08-13 xhr if (daemon(0, 0) == -1)
166 698f8cca 2021-08-13 xhr fatalx("daemonizing failed");
168 7e4cf0c1 2021-08-09 xhr organize_termination();
174 7e4cf0c1 2021-08-09 xhr organize_termination(void)
176 e68a87d3 2021-08-09 xhr pid_t sub_pid;
178 3f509e2b 2021-08-08 xhr log_debug("waiting for sub processes to terminate");
180 6fe8945f 2021-08-08 xhr sub_pid = wait(NULL);
181 6fe8945f 2021-08-08 xhr if (sub_pid == -1) {
182 3f509e2b 2021-08-08 xhr if (errno == ECHILD) {
183 3f509e2b 2021-08-08 xhr /* All sub processes are terminated */
184 3f509e2b 2021-08-08 xhr log_debug("twind turns to dust");
187 3f509e2b 2021-08-08 xhr fatalx("wait");
194 1d446d16 2021-08-07 xhr initialize_tls_context(void)
196 4b2a8511 2021-08-07 xhr SSL_CTX *sslctx;
198 4b2a8511 2021-08-07 xhr SSL_load_error_strings();
199 4b2a8511 2021-08-07 xhr OpenSSL_add_all_algorithms();
201 4b2a8511 2021-08-07 xhr sslctx = SSL_CTX_new(TLS_method());
202 4b2a8511 2021-08-07 xhr if (sslctx == NULL)
203 4b2a8511 2021-08-07 xhr fatalx("Cannot initialize TLS CTX structure");
205 982d4e86 2021-08-07 xhr SSL_CTX_set_ecdh_auto(sslctx, 1);
207 4b2a8511 2021-08-07 xhr /* Gemini requires TLSv1.2 minimum */
208 4b2a8511 2021-08-07 xhr if (SSL_CTX_set_min_proto_version(sslctx, TLS1_2_VERSION) != 1)
209 4b2a8511 2021-08-07 xhr fatalx("Cannot set minimum TLS version");
211 0f5f93fa 2021-08-12 xhr if (SSL_CTX_use_certificate_file(sslctx, _PATH_TWIND_CERT, SSL_FILETYPE_PEM)
213 243b8b13 2021-08-12 xhr fatalx("Cannot load TLS certificate %s", _PATH_TWIND_CERT);
215 0f5f93fa 2021-08-12 xhr if (SSL_CTX_use_PrivateKey_file(sslctx, _PATH_TWIND_KEY, SSL_FILETYPE_PEM)
217 243b8b13 2021-08-12 xhr fatalx("Cannot load TLS private key %s", _PATH_TWIND_KEY);
219 4b2a8511 2021-08-07 xhr return sslctx;
223 6b4246f1 2021-08-10 xhr handle_incoming_connections(int counter, int tcpsock, SSL_CTX *sslctx)
225 357f6918 2021-08-07 xhr struct sockaddr_storage addr;
226 357f6918 2021-08-07 xhr struct sockaddr_in clientaddr;
227 fa201375 2021-08-07 xhr struct sockaddr_in6 clientaddr6;
228 357f6918 2021-08-07 xhr char str[INET6_ADDRSTRLEN];
229 1685bafb 2021-08-11 xhr pthread_t thread_id;
230 1e186154 2021-08-20 xhr SSL *ssl_peer;
231 c4e27397 2021-08-12 xhr socklen_t len = sizeof(addr);
232 20a3d818 2021-08-11 xhr int ret, ssl_err;
234 1d030f6b 2021-08-12 xhr #ifdef __OpenBSD__
235 1d030f6b 2021-08-12 xhr /* We can get rid of proc pledge here */
236 1d030f6b 2021-08-12 xhr if (pledge("stdio inet dns rpath", NULL) == -1)
237 1d030f6b 2021-08-12 xhr fatalx("pledge");
238 1d030f6b 2021-08-12 xhr #endif /* __OpenBSD__ */
241 357f6918 2021-08-07 xhr ret = accept(tcpsock, (struct sockaddr *)&addr, &len);
242 357f6918 2021-08-07 xhr if (ret < 0)
243 357f6918 2021-08-07 xhr fatalx("Error when accepting connection");
245 357f6918 2021-08-07 xhr getpeername(ret, (struct sockaddr *)&clientaddr, &len);
246 357f6918 2021-08-07 xhr if (clientaddr.sin_family == AF_INET) {
247 1e186154 2021-08-20 xhr if (inet_ntop(AF_INET, &clientaddr.sin_addr, str, sizeof(str)))
248 0f5f93fa 2021-08-12 xhr log_info("Connection from %s on Port %d",
249 1e186154 2021-08-20 xhr str, ntohs(clientaddr.sin_port));
250 357f6918 2021-08-07 xhr } else if (clientaddr.sin_family == AF_INET6) {
251 fa201375 2021-08-07 xhr getpeername(ret, (struct sockaddr *)&clientaddr6, &len);
252 1e186154 2021-08-20 xhr if (inet_ntop(AF_INET6, &clientaddr6.sin6_addr, str, sizeof(str)))
253 0f5f93fa 2021-08-12 xhr log_info("Connection from %s on Port %d",
254 1e186154 2021-08-20 xhr str, ntohs(clientaddr6.sin6_port));
257 1e186154 2021-08-20 xhr if ((ssl_peer = SSL_new(sslctx)) == NULL) {
258 4b2a8511 2021-08-07 xhr log_warn("Creating new TLS structure failed");
263 1e186154 2021-08-20 xhr if (SSL_set_fd(ssl_peer, ret) == 0) {
264 4b2a8511 2021-08-07 xhr log_warn("TLS cannot set file descriptor");
265 1e186154 2021-08-20 xhr SSL_free(ssl_peer);
270 1e186154 2021-08-20 xhr ssl_err = SSL_accept(ssl_peer);
271 4b2a8511 2021-08-07 xhr if (ssl_err < 0) {
272 982d4e86 2021-08-07 xhr ERR_print_errors_fp(stderr);
273 4b2a8511 2021-08-07 xhr log_warn("Fatal TLS error. Cannot accept TLS connection");
274 1e186154 2021-08-20 xhr SSL_shutdown(ssl_peer);
275 1e186154 2021-08-20 xhr SSL_free(ssl_peer);
278 4b2a8511 2021-08-07 xhr } else if (ssl_err == 0) {
279 4b2a8511 2021-08-07 xhr log_warn("TLS handshake not successful");
280 1e186154 2021-08-20 xhr SSL_shutdown(ssl_peer);
281 1e186154 2021-08-20 xhr SSL_free(ssl_peer);
286 1e186154 2021-08-20 xhr log_debug("SSL connection using %s\n", SSL_get_cipher (ssl_peer));
288 1e186154 2021-08-20 xhr if (pthread_create(&thread_id, NULL, main_request_handler, ((void*)ssl_peer))
290 1685bafb 2021-08-11 xhr log_warn("Cannot create handling thread");
294 1685bafb 2021-08-11 xhr pthread_join(thread_id, NULL);
296 1e186154 2021-08-20 xhr SSL_shutdown(ssl_peer);
297 1e186154 2021-08-20 xhr SSL_free(ssl_peer);
305 6b4246f1 2021-08-10 xhr fork_main_process(int tcpsock[2], SSL_CTX *sslctx)
310 c466f347 2021-08-10 xhr /* Fork two main handler processes, one for IPv4, one for IPv6 */
311 c466f347 2021-08-10 xhr for (i=0; i < 2; i++) {
312 6b4246f1 2021-08-10 xhr if (tcpsock[i] == -1)
314 c466f347 2021-08-10 xhr switch (pid = fork()) {
316 c466f347 2021-08-10 xhr fatalx("Cannot fork() main IPv%d handler process", i == 0 ? 4 : 6);
318 0f5f93fa 2021-08-12 xhr log_debug("Main IPv%d handling process started: %d", i == 0 ? 4 : 6,
320 c466f347 2021-08-10 xhr setproctitle("v%d %s", i == 0 ? 4 : 6, "handler");
321 6b4246f1 2021-08-10 xhr handle_incoming_connections(i, tcpsock[i], sslctx);
328 1685bafb 2021-08-11 xhr main_request_handler(void *argp)
330 1e186154 2021-08-20 xhr SSL *ssl_peer = (SSL*)argp;
331 be8b7633 2021-08-13 xhr char finalpath[MAXREQLEN];
332 be8b7633 2021-08-13 xhr char temp[MAXREQLEN];
333 a8bc9bf1 2021-08-06 xhr char request[MAXREQLEN];
334 5bbe30c9 2021-08-11 xhr char *ext = NULL;
335 5bbe30c9 2021-08-11 xhr char *mime = NULL;
338 fce15385 2021-08-10 xhr memset(finalpath, 0, sizeof(finalpath));
339 fce15385 2021-08-10 xhr memset(request, 0, sizeof(request));
340 4166cdd7 2021-08-12 xhr memset(temp, 0, sizeof(temp));
342 1e186154 2021-08-20 xhr receive_gemini_request(ssl_peer, request);
344 06fbded9 2021-08-12 xhr ret = get_path_from_request(request, finalpath);
345 06fbded9 2021-08-12 xhr if (ret == -1) { /* Malformed request */
346 1e186154 2021-08-20 xhr send_non_success_response(ssl_peer, STATUS_BAD_REQUEST);
347 06fbded9 2021-08-12 xhr return NULL;
348 06fbded9 2021-08-12 xhr } else if (ret == -2) { /* 404 */
349 1e186154 2021-08-20 xhr send_non_success_response(ssl_peer, STATUS_NOT_FOUND);
350 06fbded9 2021-08-12 xhr return NULL;
353 5bbe30c9 2021-08-11 xhr if ((ext = get_file_extension(finalpath)) == NULL) {
354 8c443bed 2021-08-10 xhr log_debug("Cannot get file extension from %s", finalpath);
356 5bbe30c9 2021-08-11 xhr if ((mime = get_mime_type(ext)) == NULL)
357 5bbe30c9 2021-08-11 xhr log_debug("Cannot get MIME type for %s", ext);
360 1e186154 2021-08-20 xhr if (send_response(ssl_peer, STATUS_SUCCESS, finalpath, mime) < 0) {
361 fce15385 2021-08-10 xhr log_warn("Sending response to client failed");
362 b0efd6e3 2021-08-14 xhr return NULL;
368 1685bafb 2021-08-11 xhr return NULL;
372 a8bc9bf1 2021-08-06 xhr * Gemini requests are a single CRLF-terminated line with the following structure:
374 a8bc9bf1 2021-08-06 xhr * <URL><CR><LF>
376 0f5f93fa 2021-08-12 xhr * <URL> is a UTF-8 encoded absolute URL, including a scheme, of maximum length
377 0f5f93fa 2021-08-12 xhr * 1024 bytes.
380 84033a53 2021-08-08 xhr receive_gemini_request(SSL *ssl_peer, char* request_buf)
382 84033a53 2021-08-08 xhr if (SSL_read(ssl_peer, request_buf, MAXREQLEN) <= 0) {
383 84033a53 2021-08-08 xhr log_warn("initial recv failed");
390 004fd51a 2021-08-12 xhr open_sockets(int tcpsock[2], int port)
392 c15168fe 2021-08-12 xhr struct sockaddr_in addr4;
393 c15168fe 2021-08-12 xhr struct sockaddr_in6 addr6;
394 c15168fe 2021-08-12 xhr struct sockaddr *addr;
395 c15168fe 2021-08-12 xhr socklen_t len;
396 c15168fe 2021-08-12 xhr int opt = 1;
398 c15168fe 2021-08-12 xhr memset(&addr4, 0, sizeof(addr4));
399 c15168fe 2021-08-12 xhr addr4.sin_family = AF_INET;
400 004fd51a 2021-08-12 xhr addr4.sin_port = htons(port);
401 c15168fe 2021-08-12 xhr addr4.sin_addr.s_addr = INADDR_ANY;
402 c15168fe 2021-08-12 xhr addr = (struct sockaddr*)&addr4;
403 c15168fe 2021-08-12 xhr len = sizeof(addr4);
405 c15168fe 2021-08-12 xhr if ((tcpsock[0] = socket(AF_INET, SOCK_STREAM, 0)) != -1) {
406 0f5f93fa 2021-08-12 xhr if (setsockopt(tcpsock[0], SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))
408 c15168fe 2021-08-12 xhr log_warn("setting SO_REUSEADDR on socket");
409 c15168fe 2021-08-12 xhr if (bind(tcpsock[0], addr, len) == -1) {
410 c15168fe 2021-08-12 xhr close(tcpsock[0]);
411 c15168fe 2021-08-12 xhr tcpsock[0] = -1;
413 c15168fe 2021-08-12 xhr if (listen(tcpsock[0], 5) == -1) {
414 c15168fe 2021-08-12 xhr close(tcpsock[0]);
415 c15168fe 2021-08-12 xhr tcpsock[0] = -1;
419 c15168fe 2021-08-12 xhr memset(&addr6, 0, sizeof(addr6));
420 c15168fe 2021-08-12 xhr addr6.sin6_family = AF_INET6;
421 004fd51a 2021-08-12 xhr addr6.sin6_port = htons(port);
422 c15168fe 2021-08-12 xhr addr6.sin6_addr = in6addr_any;
423 c15168fe 2021-08-12 xhr addr = (struct sockaddr*)&addr6;
424 c15168fe 2021-08-12 xhr len = sizeof(addr6);
426 c15168fe 2021-08-12 xhr if ((tcpsock[1] = socket(AF_INET6, SOCK_STREAM, 0)) != -1) {
427 0f5f93fa 2021-08-12 xhr if (setsockopt(tcpsock[1], SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))
429 c15168fe 2021-08-12 xhr log_warn("setting SO_REUSEADDR on socket");
430 c15168fe 2021-08-12 xhr if (bind(tcpsock[1], addr, len) == -1) {
431 c15168fe 2021-08-12 xhr close(tcpsock[1]);
432 c15168fe 2021-08-12 xhr tcpsock[1] = -1;
434 c15168fe 2021-08-12 xhr if (listen(tcpsock[1], 5) == -1) {
435 c15168fe 2021-08-12 xhr close(tcpsock[1]);
436 c15168fe 2021-08-12 xhr tcpsock[1] = -1;
440 994b0764 2021-08-10 xhr if (tcpsock[0] == -1 && tcpsock[1] == -1) {
441 efd3a30e 2021-08-06 xhr fatalx("Cannot bind to 0.0.0.0 or :: on Port 1965");
446 e68a87d3 2021-08-09 xhr open_pid_file(void)
448 e68a87d3 2021-08-09 xhr char buf[PID_BUF_SIZE];
449 be8b7633 2021-08-13 xhr char pid_path[MAXREQLEN];
452 be8b7633 2021-08-13 xhr snprintf(pid_path, MAXREQLEN, "%s/%s",
453 0f5f93fa 2021-08-12 xhr _PATH_TWIND_CHROOT, _PATH_TWIND_PID);
454 7e4cf0c1 2021-08-09 xhr if ((fd = open(pid_path, O_CREAT|O_RDWR, 0600)) == -1)
455 e68a87d3 2021-08-09 xhr fatalx("Cannot open PID file");
457 e68a87d3 2021-08-09 xhr if (flock(fd, LOCK_EX|LOCK_NB) == -1)
458 e68a87d3 2021-08-09 xhr fatalx("Cannot get lock on PID file. Another instance running?");
461 e68a87d3 2021-08-09 xhr * We need to truncate the file since the new PID could be shorter than
462 e68a87d3 2021-08-09 xhr * an old one in the file.
464 e68a87d3 2021-08-09 xhr if (ftruncate(fd, 0) == -1)
465 e68a87d3 2021-08-09 xhr fatalx("Cannot truncate PID file");
467 e68a87d3 2021-08-09 xhr snprintf(buf, PID_BUF_SIZE, "%ld\n", (long) getpid());
468 e68a87d3 2021-08-09 xhr if (write(fd, buf, strlen(buf)) != (ssize_t)strlen(buf))
469 e68a87d3 2021-08-09 xhr fatalx("Cannot write PID file");
475 87876c15 2021-08-09 xhr drop_root(void)
477 87876c15 2021-08-09 xhr struct passwd *pw;
479 87876c15 2021-08-09 xhr if (!(pw = getpwnam(TWIND_USER)))
480 87876c15 2021-08-09 xhr fatalx("Cannot find user entry for %s", TWIND_USER);
482 87876c15 2021-08-09 xhr if (!pw->pw_uid)
483 87876c15 2021-08-09 xhr fatalx("Cannot get UID entry for %s", TWIND_USER);
485 d42126da 2021-08-12 xhr #ifdef __OpenBSD__
486 d42126da 2021-08-12 xhr if (unveil(_PATH_TWIND_CERT, "r") == -1)
487 d42126da 2021-08-12 xhr fatalx("unveil");
488 d42126da 2021-08-12 xhr if (unveil(_PATH_TWIND_KEY, "r") == -1)
489 d42126da 2021-08-12 xhr fatalx("unveil");
490 d42126da 2021-08-12 xhr if (unveil(_PATH_TWIND_CHROOT, "r") == -1)
491 d42126da 2021-08-12 xhr fatalx("unveil");
492 d42126da 2021-08-12 xhr if (unveil(_PATH_TWIND_PID_CHROOT, "r") == -1)
493 d42126da 2021-08-12 xhr fatalx("unveil");
494 d42126da 2021-08-12 xhr if (unveil(NULL, NULL) == -1)
495 d42126da 2021-08-12 xhr fatalx("unveil");
496 d42126da 2021-08-12 xhr #endif /* __OpenBSD__ */
498 243b8b13 2021-08-12 xhr if (chroot(_PATH_TWIND_CHROOT) == -1)
499 243b8b13 2021-08-12 xhr fatalx("chroot() to %s failed", _PATH_TWIND_CHROOT);
500 87876c15 2021-08-09 xhr if (chdir("/") == -1)
501 7d2dd1b9 2021-08-12 xhr fatalx("chdir() failed");
503 87876c15 2021-08-09 xhr if (setgroups(1, &pw->pw_gid) == -1)
504 87876c15 2021-08-09 xhr fatalx("Cannot set group access list");
505 87876c15 2021-08-09 xhr if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) == -1)
506 87876c15 2021-08-09 xhr fatalx("Cannot set GUID to %d", pw->pw_gid);
507 87876c15 2021-08-09 xhr if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) == -1)
508 87876c15 2021-08-09 xhr fatalx("Cannot set UID to %d", pw->pw_uid);