Blame


1 f224a3fe 2021-08-24 xhr /*
2 f224a3fe 2021-08-24 xhr * Copyright (c) 2021 Matthias Schmidt <xhr@giessen.ccc.de>
3 f224a3fe 2021-08-24 xhr *
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.
7 f224a3fe 2021-08-24 xhr *
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.
15 f224a3fe 2021-08-24 xhr */
16 f224a3fe 2021-08-24 xhr
17 f224a3fe 2021-08-24 xhr #define _GNU_SOURCE
18 f224a3fe 2021-08-24 xhr
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>
25 f224a3fe 2021-08-24 xhr
26 f224a3fe 2021-08-24 xhr #include <arpa/inet.h>
27 f224a3fe 2021-08-24 xhr
28 f224a3fe 2021-08-24 xhr #include <net/if.h>
29 f224a3fe 2021-08-24 xhr #include <netinet/in.h>
30 f224a3fe 2021-08-24 xhr
31 f224a3fe 2021-08-24 xhr #include <openssl/err.h>
32 f224a3fe 2021-08-24 xhr #include <openssl/ssl.h>
33 f224a3fe 2021-08-24 xhr
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>
47 f224a3fe 2021-08-24 xhr
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__ */
52 f224a3fe 2021-08-24 xhr
53 f224a3fe 2021-08-24 xhr #include "log.h"
54 f224a3fe 2021-08-24 xhr #include "twind.h"
55 f224a3fe 2021-08-24 xhr
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"
64 f224a3fe 2021-08-24 xhr
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);
75 f224a3fe 2021-08-24 xhr
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__ */
81 f224a3fe 2021-08-24 xhr
82 f224a3fe 2021-08-24 xhr static void
83 f224a3fe 2021-08-24 xhr usage(void)
84 f224a3fe 2021-08-24 xhr {
85 f224a3fe 2021-08-24 xhr extern char *__progname;
86 f224a3fe 2021-08-24 xhr
87 f224a3fe 2021-08-24 xhr fprintf(stderr, "usage: %s [-dfv] [-p port]\n", __progname);
88 f224a3fe 2021-08-24 xhr exit(-1);
89 f224a3fe 2021-08-24 xhr }
90 f224a3fe 2021-08-24 xhr
91 f224a3fe 2021-08-24 xhr static void
92 f224a3fe 2021-08-24 xhr signal_handler(int signal)
93 f224a3fe 2021-08-24 xhr {
94 f224a3fe 2021-08-24 xhr switch (signal) {
95 75e29feb 2021-08-26 xhr case SIGHUP:
96 75e29feb 2021-08-26 xhr reload_log_files = 1;
97 75e29feb 2021-08-26 xhr break;
98 f224a3fe 2021-08-24 xhr case SIGINT:
99 f224a3fe 2021-08-24 xhr case SIGTERM:
100 f224a3fe 2021-08-24 xhr organize_termination();
101 f224a3fe 2021-08-24 xhr break;
102 f224a3fe 2021-08-24 xhr default:
103 f224a3fe 2021-08-24 xhr fatalx("Unknown signal");
104 f224a3fe 2021-08-24 xhr }
105 f224a3fe 2021-08-24 xhr }
106 f224a3fe 2021-08-24 xhr
107 f224a3fe 2021-08-24 xhr int
108 f224a3fe 2021-08-24 xhr main(int argc, char *argv[])
109 f224a3fe 2021-08-24 xhr {
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;
113 f224a3fe 2021-08-24 xhr
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);
116 f224a3fe 2021-08-24 xhr
117 f224a3fe 2021-08-24 xhr while ((ch = getopt(argc, argv, "dfp:vV")) != -1) {
118 f224a3fe 2021-08-24 xhr switch(ch) {
119 f224a3fe 2021-08-24 xhr case 'd':
120 f224a3fe 2021-08-24 xhr debug_flag = 1;
121 f224a3fe 2021-08-24 xhr break;
122 f224a3fe 2021-08-24 xhr case 'f':
123 f224a3fe 2021-08-24 xhr fg_flag = 1;
124 f224a3fe 2021-08-24 xhr break;
125 f224a3fe 2021-08-24 xhr case 'p':
126 f224a3fe 2021-08-24 xhr port = atoi(optarg);
127 f224a3fe 2021-08-24 xhr break;
128 f224a3fe 2021-08-24 xhr case 'v':
129 f224a3fe 2021-08-24 xhr verbose_flag = 1;
130 f224a3fe 2021-08-24 xhr break;
131 f224a3fe 2021-08-24 xhr case 'V':
132 f224a3fe 2021-08-24 xhr fprintf(stderr, "Version %s\n", VERSION);
133 f224a3fe 2021-08-24 xhr exit(-1);
134 f224a3fe 2021-08-24 xhr default:
135 f224a3fe 2021-08-24 xhr usage();
136 f224a3fe 2021-08-24 xhr break;
137 f224a3fe 2021-08-24 xhr }
138 f224a3fe 2021-08-24 xhr }
139 f224a3fe 2021-08-24 xhr
140 f224a3fe 2021-08-24 xhr argc -= optind;
141 f224a3fe 2021-08-24 xhr argv += optind;
142 f224a3fe 2021-08-24 xhr
143 f224a3fe 2021-08-24 xhr if (geteuid())
144 f224a3fe 2021-08-24 xhr fatalx("need root privileges");
145 f224a3fe 2021-08-24 xhr
146 f224a3fe 2021-08-24 xhr open_pid_file();
147 f224a3fe 2021-08-24 xhr
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");
154 f224a3fe 2021-08-24 xhr
155 f224a3fe 2021-08-24 xhr open_sockets(tcpsock, port);
156 f224a3fe 2021-08-24 xhr
157 f224a3fe 2021-08-24 xhr sslctx = initialize_tls_context();
158 f224a3fe 2021-08-24 xhr
159 f224a3fe 2021-08-24 xhr drop_root();
160 f224a3fe 2021-08-24 xhr
161 f224a3fe 2021-08-24 xhr log_init(debug_flag, LOG_DAEMON);
162 f224a3fe 2021-08-24 xhr log_setverbose(verbose_flag);
163 f224a3fe 2021-08-24 xhr
164 f224a3fe 2021-08-24 xhr
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__ */
169 f224a3fe 2021-08-24 xhr
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");
173 9e328210 2021-08-26 xhr
174 9e328210 2021-08-26 xhr open_twind_logs();
175 f224a3fe 2021-08-24 xhr
176 ee3ef24f 2021-08-26 xhr fork_main_process(tcpsock, sslctx);
177 ee3ef24f 2021-08-26 xhr
178 f224a3fe 2021-08-24 xhr organize_termination();
179 f224a3fe 2021-08-24 xhr
180 f224a3fe 2021-08-24 xhr return 0;
181 f224a3fe 2021-08-24 xhr }
182 f224a3fe 2021-08-24 xhr
183 f224a3fe 2021-08-24 xhr static void
184 f224a3fe 2021-08-24 xhr organize_termination(void)
185 f224a3fe 2021-08-24 xhr {
186 f224a3fe 2021-08-24 xhr pid_t sub_pid;
187 9e328210 2021-08-26 xhr
188 9e328210 2021-08-26 xhr close_twind_logs();
189 f224a3fe 2021-08-24 xhr
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__ */
194 7b16d7ca 2021-08-26 xhr
195 f224a3fe 2021-08-24 xhr log_debug("waiting for sub processes to terminate");
196 f224a3fe 2021-08-24 xhr for (;;) {
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");
203 f224a3fe 2021-08-24 xhr exit(0);
204 f224a3fe 2021-08-24 xhr } else {
205 f224a3fe 2021-08-24 xhr fatalx("wait");
206 f224a3fe 2021-08-24 xhr }
207 f224a3fe 2021-08-24 xhr }
208 aae0748e 2021-08-26 xhr
209 aae0748e 2021-08-26 xhr log_debug("Child %d terminated", sub_pid);
210 f224a3fe 2021-08-24 xhr }
211 f224a3fe 2021-08-24 xhr }
212 f224a3fe 2021-08-24 xhr
213 f224a3fe 2021-08-24 xhr SSL_CTX*
214 f224a3fe 2021-08-24 xhr initialize_tls_context(void)
215 f224a3fe 2021-08-24 xhr {
216 f224a3fe 2021-08-24 xhr SSL_CTX *sslctx;
217 f224a3fe 2021-08-24 xhr
218 f224a3fe 2021-08-24 xhr SSL_load_error_strings();
219 f224a3fe 2021-08-24 xhr OpenSSL_add_all_algorithms();
220 f224a3fe 2021-08-24 xhr
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");
224 f224a3fe 2021-08-24 xhr
225 f224a3fe 2021-08-24 xhr SSL_CTX_set_ecdh_auto(sslctx, 1);
226 f224a3fe 2021-08-24 xhr
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");
230 f224a3fe 2021-08-24 xhr
231 f224a3fe 2021-08-24 xhr if (SSL_CTX_use_certificate_file(sslctx, _PATH_TWIND_CERT, SSL_FILETYPE_PEM)
232 f224a3fe 2021-08-24 xhr != 1)
233 f224a3fe 2021-08-24 xhr fatalx("Cannot load TLS certificate %s", _PATH_TWIND_CERT);
234 f224a3fe 2021-08-24 xhr
235 f224a3fe 2021-08-24 xhr if (SSL_CTX_use_PrivateKey_file(sslctx, _PATH_TWIND_KEY, SSL_FILETYPE_PEM)
236 f224a3fe 2021-08-24 xhr != 1)
237 f224a3fe 2021-08-24 xhr fatalx("Cannot load TLS private key %s", _PATH_TWIND_KEY);
238 f224a3fe 2021-08-24 xhr
239 f224a3fe 2021-08-24 xhr return sslctx;
240 f224a3fe 2021-08-24 xhr }
241 f224a3fe 2021-08-24 xhr
242 f224a3fe 2021-08-24 xhr void *
243 f224a3fe 2021-08-24 xhr get_in_addr(struct sockaddr *sa)
244 f224a3fe 2021-08-24 xhr {
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);
247 f224a3fe 2021-08-24 xhr
248 f224a3fe 2021-08-24 xhr return &(((struct sockaddr_in6*)sa)->sin6_addr);
249 f224a3fe 2021-08-24 xhr }
250 f224a3fe 2021-08-24 xhr
251 f224a3fe 2021-08-24 xhr int
252 f224a3fe 2021-08-24 xhr handle_incoming_connections(int counter, int tcpsock, SSL_CTX *sslctx)
253 f224a3fe 2021-08-24 xhr {
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;
260 f224a3fe 2021-08-24 xhr
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__ */
266 f224a3fe 2021-08-24 xhr
267 f224a3fe 2021-08-24 xhr memset(str, 0, sizeof(str));
268 f224a3fe 2021-08-24 xhr
269 f224a3fe 2021-08-24 xhr while (1) {
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();
275 75e29feb 2021-08-26 xhr }
276 75e29feb 2021-08-26 xhr
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");
280 f224a3fe 2021-08-24 xhr
281 f224a3fe 2021-08-24 xhr cc = xmalloc(sizeof(struct client_connection));
282 f224a3fe 2021-08-24 xhr
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);
286 f224a3fe 2021-08-24 xhr
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");
289 f224a3fe 2021-08-24 xhr free(cc);
290 f224a3fe 2021-08-24 xhr close(ret);
291 f224a3fe 2021-08-24 xhr continue;
292 f224a3fe 2021-08-24 xhr }
293 f224a3fe 2021-08-24 xhr
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);
297 f224a3fe 2021-08-24 xhr free(cc);
298 f224a3fe 2021-08-24 xhr close(ret);
299 f224a3fe 2021-08-24 xhr continue;
300 f224a3fe 2021-08-24 xhr }
301 f224a3fe 2021-08-24 xhr
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);
308 f224a3fe 2021-08-24 xhr free(cc);
309 f224a3fe 2021-08-24 xhr close(ret);
310 f224a3fe 2021-08-24 xhr continue;
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);
315 f224a3fe 2021-08-24 xhr free(cc);
316 f224a3fe 2021-08-24 xhr close(ret);
317 f224a3fe 2021-08-24 xhr continue;
318 f224a3fe 2021-08-24 xhr }
319 f224a3fe 2021-08-24 xhr
320 f224a3fe 2021-08-24 xhr log_debug("SSL connection using %s", SSL_get_cipher(cc->ssl_peer));
321 f224a3fe 2021-08-24 xhr
322 f224a3fe 2021-08-24 xhr if (pthread_create(&thread_id, NULL, main_request_handler, ((void*)cc))
323 f224a3fe 2021-08-24 xhr != 0) {
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);
327 f224a3fe 2021-08-24 xhr free(cc);
328 f224a3fe 2021-08-24 xhr close(ret);
329 f224a3fe 2021-08-24 xhr continue;
330 f224a3fe 2021-08-24 xhr }
331 f224a3fe 2021-08-24 xhr
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);
336 f224a3fe 2021-08-24 xhr free(cc);
337 f224a3fe 2021-08-24 xhr close(ret);
338 f224a3fe 2021-08-24 xhr continue;
339 f224a3fe 2021-08-24 xhr }
340 f224a3fe 2021-08-24 xhr
341 f224a3fe 2021-08-24 xhr SSL_shutdown(cc->ssl_peer);
342 f224a3fe 2021-08-24 xhr SSL_free(cc->ssl_peer);
343 f224a3fe 2021-08-24 xhr free(cc);
344 f224a3fe 2021-08-24 xhr close(ret);
345 f224a3fe 2021-08-24 xhr }
346 f224a3fe 2021-08-24 xhr
347 f224a3fe 2021-08-24 xhr return 0;
348 f224a3fe 2021-08-24 xhr }
349 f224a3fe 2021-08-24 xhr
350 f224a3fe 2021-08-24 xhr void
351 f224a3fe 2021-08-24 xhr fork_main_process(int tcpsock[2], SSL_CTX *sslctx)
352 f224a3fe 2021-08-24 xhr {
353 f224a3fe 2021-08-24 xhr pid_t pid;
354 f224a3fe 2021-08-24 xhr int i;
355 9ebb8b99 2021-08-26 xhr
356 9ebb8b99 2021-08-26 xhr setproctitle("main");
357 f224a3fe 2021-08-24 xhr
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)
361 f224a3fe 2021-08-24 xhr continue;
362 f224a3fe 2021-08-24 xhr switch (pid = fork()) {
363 f224a3fe 2021-08-24 xhr case -1:
364 f224a3fe 2021-08-24 xhr fatalx("Cannot fork() main IPv%d handler process", i == 0 ? 4 : 6);
365 f224a3fe 2021-08-24 xhr case 0:
366 f224a3fe 2021-08-24 xhr log_debug("Main IPv%d handling process started: %d", i == 0 ? 4 : 6,
367 f224a3fe 2021-08-24 xhr getpid());
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);
370 f224a3fe 2021-08-24 xhr exit(0);
371 f224a3fe 2021-08-24 xhr }
372 f224a3fe 2021-08-24 xhr }
373 f224a3fe 2021-08-24 xhr }
374 f224a3fe 2021-08-24 xhr
375 f224a3fe 2021-08-24 xhr void *
376 f224a3fe 2021-08-24 xhr main_request_handler(void *argp)
377 f224a3fe 2021-08-24 xhr {
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;
384 f224a3fe 2021-08-24 xhr int ret;
385 f224a3fe 2021-08-24 xhr
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));
389 f224a3fe 2021-08-24 xhr
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;
393 f224a3fe 2021-08-24 xhr }
394 f224a3fe 2021-08-24 xhr
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;
404 f224a3fe 2021-08-24 xhr }
405 f224a3fe 2021-08-24 xhr
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);
408 f224a3fe 2021-08-24 xhr } else {
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);
411 f224a3fe 2021-08-24 xhr }
412 f224a3fe 2021-08-24 xhr
413 f224a3fe 2021-08-24 xhr log_access(cc, finalpath);
414 f224a3fe 2021-08-24 xhr
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;
418 f224a3fe 2021-08-24 xhr }
419 f224a3fe 2021-08-24 xhr
420 f224a3fe 2021-08-24 xhr free(ext);
421 f224a3fe 2021-08-24 xhr free(mime);
422 f224a3fe 2021-08-24 xhr
423 f224a3fe 2021-08-24 xhr return NULL;
424 f224a3fe 2021-08-24 xhr }
425 f224a3fe 2021-08-24 xhr
426 f224a3fe 2021-08-24 xhr /*
427 f224a3fe 2021-08-24 xhr * Gemini requests are a single CRLF-terminated line with the following structure:
428 f224a3fe 2021-08-24 xhr *
429 f224a3fe 2021-08-24 xhr * <URL><CR><LF>
430 f224a3fe 2021-08-24 xhr *
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.
433 f224a3fe 2021-08-24 xhr */
434 f224a3fe 2021-08-24 xhr int
435 f224a3fe 2021-08-24 xhr receive_gemini_request(SSL *ssl_peer, char* request_buf)
436 f224a3fe 2021-08-24 xhr {
437 f224a3fe 2021-08-24 xhr if (SSL_read(ssl_peer, request_buf, MAXREQLEN) <= 0)
438 f224a3fe 2021-08-24 xhr return -1;
439 f224a3fe 2021-08-24 xhr
440 f224a3fe 2021-08-24 xhr return 0;
441 f224a3fe 2021-08-24 xhr }
442 f224a3fe 2021-08-24 xhr
443 f224a3fe 2021-08-24 xhr static void
444 f224a3fe 2021-08-24 xhr open_sockets(int tcpsock[2], int port)
445 f224a3fe 2021-08-24 xhr {
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;
451 f224a3fe 2021-08-24 xhr
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);
458 f224a3fe 2021-08-24 xhr
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))
461 f224a3fe 2021-08-24 xhr == -1)
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;
466 f224a3fe 2021-08-24 xhr }
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;
470 f224a3fe 2021-08-24 xhr }
471 f224a3fe 2021-08-24 xhr }
472 f224a3fe 2021-08-24 xhr
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);
479 f224a3fe 2021-08-24 xhr
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))
482 f224a3fe 2021-08-24 xhr == -1)
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;
487 f224a3fe 2021-08-24 xhr }
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;
491 f224a3fe 2021-08-24 xhr }
492 f224a3fe 2021-08-24 xhr }
493 f224a3fe 2021-08-24 xhr
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");
496 f224a3fe 2021-08-24 xhr }
497 f224a3fe 2021-08-24 xhr }
498 f224a3fe 2021-08-24 xhr
499 f224a3fe 2021-08-24 xhr int
500 f224a3fe 2021-08-24 xhr open_pid_file(void)
501 f224a3fe 2021-08-24 xhr {
502 f224a3fe 2021-08-24 xhr char buf[PID_BUF_SIZE];
503 f224a3fe 2021-08-24 xhr char pid_path[MAXREQLEN];
504 f224a3fe 2021-08-24 xhr int fd;
505 f224a3fe 2021-08-24 xhr
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");
510 f224a3fe 2021-08-24 xhr
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?");
513 f224a3fe 2021-08-24 xhr
514 f224a3fe 2021-08-24 xhr /*
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.
517 f224a3fe 2021-08-24 xhr */
518 f224a3fe 2021-08-24 xhr if (ftruncate(fd, 0) == -1)
519 f224a3fe 2021-08-24 xhr fatalx("Cannot truncate PID file");
520 f224a3fe 2021-08-24 xhr
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");
524 f224a3fe 2021-08-24 xhr
525 f224a3fe 2021-08-24 xhr return fd;
526 f224a3fe 2021-08-24 xhr }
527 f224a3fe 2021-08-24 xhr
528 f224a3fe 2021-08-24 xhr static void
529 f224a3fe 2021-08-24 xhr drop_root(void)
530 f224a3fe 2021-08-24 xhr {
531 f224a3fe 2021-08-24 xhr struct passwd *pw;
532 f224a3fe 2021-08-24 xhr
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);
535 f224a3fe 2021-08-24 xhr
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);
538 f224a3fe 2021-08-24 xhr
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__ */
553 f224a3fe 2021-08-24 xhr
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");
558 f224a3fe 2021-08-24 xhr
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);
565 f224a3fe 2021-08-24 xhr
566 f224a3fe 2021-08-24 xhr }
567 f224a3fe 2021-08-24 xhr