Blame


1 aac8053c 2021-08-12 xhr /*
2 aac8053c 2021-08-12 xhr * Copyright (c) 2021 Matthias Schmidt <xhr@giessen.ccc.de>
3 aac8053c 2021-08-12 xhr *
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.
7 aac8053c 2021-08-12 xhr *
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.
15 aac8053c 2021-08-12 xhr */
16 aac8053c 2021-08-12 xhr
17 003004f9 2021-08-08 xhr #define _GNU_SOURCE
18 003004f9 2021-08-08 xhr
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>
25 edc334c2 2021-08-05 xhr
26 a366f6dc 2021-08-07 xhr #include <arpa/inet.h>
27 a366f6dc 2021-08-07 xhr
28 edc334c2 2021-08-05 xhr #include <net/if.h>
29 095cf201 2021-08-08 xhr #include <netinet/in.h>
30 edc334c2 2021-08-05 xhr
31 4b2a8511 2021-08-07 xhr #include <openssl/err.h>
32 4b2a8511 2021-08-07 xhr #include <openssl/ssl.h>
33 4b2a8511 2021-08-07 xhr
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>
47 5af2ed18 2021-08-08 xhr
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__ */
52 edc334c2 2021-08-05 xhr
53 edc334c2 2021-08-05 xhr #include "log.h"
54 a8bc9bf1 2021-08-06 xhr #include "twind.h"
55 edc334c2 2021-08-05 xhr
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"
63 a8bc9bf1 2021-08-06 xhr
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);
73 003004f9 2021-08-08 xhr
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__ */
79 edc334c2 2021-08-05 xhr
80 edc334c2 2021-08-05 xhr static void
81 edc334c2 2021-08-05 xhr usage(void)
82 edc334c2 2021-08-05 xhr {
83 edc334c2 2021-08-05 xhr extern char *__progname;
84 edc334c2 2021-08-05 xhr
85 004fd51a 2021-08-12 xhr fprintf(stderr, "usage: %s [-dfv] [-p port]\n", __progname);
86 be0cc427 2021-08-08 xhr exit(-1);
87 dd70858b 2021-08-08 xhr }
88 dd70858b 2021-08-08 xhr
89 7e4cf0c1 2021-08-09 xhr static void
90 7e4cf0c1 2021-08-09 xhr signal_handler(int signal)
91 7e4cf0c1 2021-08-09 xhr {
92 7e4cf0c1 2021-08-09 xhr switch (signal) {
93 7e4cf0c1 2021-08-09 xhr case SIGINT:
94 7e4cf0c1 2021-08-09 xhr case SIGTERM:
95 7e4cf0c1 2021-08-09 xhr organize_termination();
96 7e4cf0c1 2021-08-09 xhr break;
97 7e4cf0c1 2021-08-09 xhr default:
98 7e4cf0c1 2021-08-09 xhr fatalx("Unknown signal");
99 7e4cf0c1 2021-08-09 xhr }
100 7e4cf0c1 2021-08-09 xhr }
101 e68a87d3 2021-08-09 xhr
102 edc334c2 2021-08-05 xhr int
103 edc334c2 2021-08-05 xhr main(int argc, char *argv[])
104 edc334c2 2021-08-05 xhr {
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;
108 edc334c2 2021-08-05 xhr
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);
111 c83eee1a 2021-08-08 xhr
112 004fd51a 2021-08-12 xhr while ((ch = getopt(argc, argv, "dfp:vV")) != -1) {
113 edc334c2 2021-08-05 xhr switch(ch) {
114 edc334c2 2021-08-05 xhr case 'd':
115 c83eee1a 2021-08-08 xhr debug_flag = 1;
116 edc334c2 2021-08-05 xhr break;
117 edc334c2 2021-08-05 xhr case 'f':
118 edc334c2 2021-08-05 xhr fg_flag = 1;
119 edc334c2 2021-08-05 xhr break;
120 004fd51a 2021-08-12 xhr case 'p':
121 004fd51a 2021-08-12 xhr port = atoi(optarg);
122 004fd51a 2021-08-12 xhr break;
123 c83eee1a 2021-08-08 xhr case 'v':
124 c83eee1a 2021-08-08 xhr verbose_flag = 1;
125 c83eee1a 2021-08-08 xhr break;
126 b67b4591 2021-08-12 xhr case 'V':
127 b67b4591 2021-08-12 xhr fprintf(stderr, "Version %s\n", VERSION);
128 b67b4591 2021-08-12 xhr exit(-1);
129 edc334c2 2021-08-05 xhr default:
130 edc334c2 2021-08-05 xhr usage();
131 edc334c2 2021-08-05 xhr break;
132 edc334c2 2021-08-05 xhr }
133 edc334c2 2021-08-05 xhr }
134 edc334c2 2021-08-05 xhr
135 edc334c2 2021-08-05 xhr argc -= optind;
136 edc334c2 2021-08-05 xhr argv += optind;
137 edc334c2 2021-08-05 xhr
138 86bf65be 2021-08-08 xhr if (geteuid())
139 86bf65be 2021-08-08 xhr fatalx("need root privileges");
140 dd70858b 2021-08-08 xhr
141 6b4246f1 2021-08-10 xhr open_pid_file();
142 e68a87d3 2021-08-09 xhr
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");
147 7e4cf0c1 2021-08-09 xhr
148 004fd51a 2021-08-12 xhr open_sockets(tcpsock, port);
149 243b8b13 2021-08-12 xhr
150 1d446d16 2021-08-07 xhr sslctx = initialize_tls_context();
151 4b2a8511 2021-08-07 xhr
152 dd70858b 2021-08-08 xhr drop_root();
153 c83eee1a 2021-08-08 xhr
154 c83eee1a 2021-08-08 xhr log_init(debug_flag, LOG_DAEMON);
155 c83eee1a 2021-08-08 xhr log_setverbose(verbose_flag);
156 dd70858b 2021-08-08 xhr
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__ */
161 a77b63fc 2021-08-08 xhr
162 6b4246f1 2021-08-10 xhr fork_main_process(tcpsock, sslctx);
163 edc334c2 2021-08-05 xhr
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");
167 e68a87d3 2021-08-09 xhr
168 7e4cf0c1 2021-08-09 xhr organize_termination();
169 e68a87d3 2021-08-09 xhr
170 e68a87d3 2021-08-09 xhr return 0;
171 e68a87d3 2021-08-09 xhr }
172 e68a87d3 2021-08-09 xhr
173 e68a87d3 2021-08-09 xhr static void
174 7e4cf0c1 2021-08-09 xhr organize_termination(void)
175 e68a87d3 2021-08-09 xhr {
176 e68a87d3 2021-08-09 xhr pid_t sub_pid;
177 a366f6dc 2021-08-07 xhr
178 3f509e2b 2021-08-08 xhr log_debug("waiting for sub processes to terminate");
179 3f509e2b 2021-08-08 xhr for (;;) {
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");
185 3f509e2b 2021-08-08 xhr exit(0);
186 3f509e2b 2021-08-08 xhr } else {
187 3f509e2b 2021-08-08 xhr fatalx("wait");
188 3f509e2b 2021-08-08 xhr }
189 3f509e2b 2021-08-08 xhr }
190 3f509e2b 2021-08-08 xhr }
191 c8b6c180 2021-08-15 xhr }
192 4b2a8511 2021-08-07 xhr
193 4b2a8511 2021-08-07 xhr SSL_CTX*
194 1d446d16 2021-08-07 xhr initialize_tls_context(void)
195 4b2a8511 2021-08-07 xhr {
196 4b2a8511 2021-08-07 xhr SSL_CTX *sslctx;
197 8748d027 2021-08-08 xhr
198 4b2a8511 2021-08-07 xhr SSL_load_error_strings();
199 4b2a8511 2021-08-07 xhr OpenSSL_add_all_algorithms();
200 4b2a8511 2021-08-07 xhr
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");
204 4b2a8511 2021-08-07 xhr
205 982d4e86 2021-08-07 xhr SSL_CTX_set_ecdh_auto(sslctx, 1);
206 982d4e86 2021-08-07 xhr
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");
210 4b2a8511 2021-08-07 xhr
211 0f5f93fa 2021-08-12 xhr if (SSL_CTX_use_certificate_file(sslctx, _PATH_TWIND_CERT, SSL_FILETYPE_PEM)
212 0f5f93fa 2021-08-12 xhr != 1)
213 243b8b13 2021-08-12 xhr fatalx("Cannot load TLS certificate %s", _PATH_TWIND_CERT);
214 4b2a8511 2021-08-07 xhr
215 0f5f93fa 2021-08-12 xhr if (SSL_CTX_use_PrivateKey_file(sslctx, _PATH_TWIND_KEY, SSL_FILETYPE_PEM)
216 0f5f93fa 2021-08-12 xhr != 1)
217 243b8b13 2021-08-12 xhr fatalx("Cannot load TLS private key %s", _PATH_TWIND_KEY);
218 4b2a8511 2021-08-07 xhr
219 4b2a8511 2021-08-07 xhr return sslctx;
220 edc334c2 2021-08-05 xhr }
221 edc334c2 2021-08-05 xhr
222 357f6918 2021-08-07 xhr int
223 6b4246f1 2021-08-10 xhr handle_incoming_connections(int counter, int tcpsock, SSL_CTX *sslctx)
224 357f6918 2021-08-07 xhr {
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;
233 1d030f6b 2021-08-12 xhr
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__ */
239 c466f347 2021-08-10 xhr
240 357f6918 2021-08-07 xhr while (1) {
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");
244 357f6918 2021-08-07 xhr
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));
255 357f6918 2021-08-07 xhr }
256 357f6918 2021-08-07 xhr
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");
259 982d4e86 2021-08-07 xhr close(ret);
260 4b2a8511 2021-08-07 xhr continue;
261 4b2a8511 2021-08-07 xhr }
262 4b2a8511 2021-08-07 xhr
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);
266 982d4e86 2021-08-07 xhr close(ret);
267 4b2a8511 2021-08-07 xhr continue;
268 4b2a8511 2021-08-07 xhr }
269 4b2a8511 2021-08-07 xhr
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);
276 982d4e86 2021-08-07 xhr close(ret);
277 4b2a8511 2021-08-07 xhr continue;
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);
282 982d4e86 2021-08-07 xhr close(ret);
283 4b2a8511 2021-08-07 xhr continue;
284 4b2a8511 2021-08-07 xhr }
285 4b2a8511 2021-08-07 xhr
286 1e186154 2021-08-20 xhr log_debug("SSL connection using %s\n", SSL_get_cipher (ssl_peer));
287 4b2a8511 2021-08-07 xhr
288 1e186154 2021-08-20 xhr if (pthread_create(&thread_id, NULL, main_request_handler, ((void*)ssl_peer))
289 0f5f93fa 2021-08-12 xhr != 0) {
290 1685bafb 2021-08-11 xhr log_warn("Cannot create handling thread");
291 1685bafb 2021-08-11 xhr return -1;
292 357f6918 2021-08-07 xhr }
293 357f6918 2021-08-07 xhr
294 1685bafb 2021-08-11 xhr pthread_join(thread_id, NULL);
295 357f6918 2021-08-07 xhr
296 1e186154 2021-08-20 xhr SSL_shutdown(ssl_peer);
297 1e186154 2021-08-20 xhr SSL_free(ssl_peer);
298 357f6918 2021-08-07 xhr close(ret);
299 357f6918 2021-08-07 xhr }
300 357f6918 2021-08-07 xhr
301 357f6918 2021-08-07 xhr return 0;
302 357f6918 2021-08-07 xhr }
303 357f6918 2021-08-07 xhr
304 357f6918 2021-08-07 xhr void
305 6b4246f1 2021-08-10 xhr fork_main_process(int tcpsock[2], SSL_CTX *sslctx)
306 357f6918 2021-08-07 xhr {
307 c466f347 2021-08-10 xhr pid_t pid;
308 c466f347 2021-08-10 xhr int i;
309 357f6918 2021-08-07 xhr
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)
313 6b4246f1 2021-08-10 xhr continue;
314 c466f347 2021-08-10 xhr switch (pid = fork()) {
315 c466f347 2021-08-10 xhr case -1:
316 c466f347 2021-08-10 xhr fatalx("Cannot fork() main IPv%d handler process", i == 0 ? 4 : 6);
317 c466f347 2021-08-10 xhr case 0:
318 0f5f93fa 2021-08-12 xhr log_debug("Main IPv%d handling process started: %d", i == 0 ? 4 : 6,
319 0f5f93fa 2021-08-12 xhr getpid());
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);
322 c466f347 2021-08-10 xhr exit(0);
323 c466f347 2021-08-10 xhr }
324 357f6918 2021-08-07 xhr }
325 357f6918 2021-08-07 xhr }
326 357f6918 2021-08-07 xhr
327 1685bafb 2021-08-11 xhr void *
328 1685bafb 2021-08-11 xhr main_request_handler(void *argp)
329 edc334c2 2021-08-05 xhr {
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;
336 5bbe30c9 2021-08-11 xhr int ret;
337 fce15385 2021-08-10 xhr
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));
341 fce15385 2021-08-10 xhr
342 1e186154 2021-08-20 xhr receive_gemini_request(ssl_peer, request);
343 fce15385 2021-08-10 xhr
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;
351 06fbded9 2021-08-12 xhr }
352 8c443bed 2021-08-10 xhr
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);
355 5bbe30c9 2021-08-11 xhr } else {
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);
358 fce15385 2021-08-10 xhr }
359 fce15385 2021-08-10 xhr
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;
363 4b60621e 2021-08-09 xhr }
364 8c443bed 2021-08-10 xhr
365 8c443bed 2021-08-10 xhr free(ext);
366 8c443bed 2021-08-10 xhr free(mime);
367 1685bafb 2021-08-11 xhr
368 1685bafb 2021-08-11 xhr return NULL;
369 a8bc9bf1 2021-08-06 xhr }
370 a8bc9bf1 2021-08-06 xhr
371 a8bc9bf1 2021-08-06 xhr /*
372 a8bc9bf1 2021-08-06 xhr * Gemini requests are a single CRLF-terminated line with the following structure:
373 a8bc9bf1 2021-08-06 xhr *
374 a8bc9bf1 2021-08-06 xhr * <URL><CR><LF>
375 a8bc9bf1 2021-08-06 xhr *
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.
378 a8bc9bf1 2021-08-06 xhr */
379 a8bc9bf1 2021-08-06 xhr void
380 84033a53 2021-08-08 xhr receive_gemini_request(SSL *ssl_peer, char* request_buf)
381 a8bc9bf1 2021-08-06 xhr {
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");
384 84033a53 2021-08-08 xhr }
385 84033a53 2021-08-08 xhr
386 edc334c2 2021-08-05 xhr return;
387 edc334c2 2021-08-05 xhr }
388 edc334c2 2021-08-05 xhr
389 edc334c2 2021-08-05 xhr static void
390 004fd51a 2021-08-12 xhr open_sockets(int tcpsock[2], int port)
391 c15168fe 2021-08-12 xhr {
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;
397 edc334c2 2021-08-05 xhr
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);
404 edc334c2 2021-08-05 xhr
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))
407 0f5f93fa 2021-08-12 xhr == -1)
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;
412 edc334c2 2021-08-05 xhr }
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;
416 c15168fe 2021-08-12 xhr }
417 edc334c2 2021-08-05 xhr }
418 edc334c2 2021-08-05 xhr
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);
425 edc334c2 2021-08-05 xhr
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))
428 0f5f93fa 2021-08-12 xhr == -1)
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;
433 efd3a30e 2021-08-06 xhr }
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;
437 c15168fe 2021-08-12 xhr }
438 edc334c2 2021-08-05 xhr }
439 edc334c2 2021-08-05 xhr
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");
442 efd3a30e 2021-08-06 xhr }
443 edc334c2 2021-08-05 xhr }
444 e68a87d3 2021-08-09 xhr
445 e68a87d3 2021-08-09 xhr int
446 e68a87d3 2021-08-09 xhr open_pid_file(void)
447 e68a87d3 2021-08-09 xhr {
448 e68a87d3 2021-08-09 xhr char buf[PID_BUF_SIZE];
449 be8b7633 2021-08-13 xhr char pid_path[MAXREQLEN];
450 e68a87d3 2021-08-09 xhr int fd;
451 e68a87d3 2021-08-09 xhr
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");
456 e68a87d3 2021-08-09 xhr
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?");
459 e68a87d3 2021-08-09 xhr
460 e68a87d3 2021-08-09 xhr /*
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.
463 e68a87d3 2021-08-09 xhr */
464 e68a87d3 2021-08-09 xhr if (ftruncate(fd, 0) == -1)
465 e68a87d3 2021-08-09 xhr fatalx("Cannot truncate PID file");
466 e68a87d3 2021-08-09 xhr
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");
470 e68a87d3 2021-08-09 xhr
471 e68a87d3 2021-08-09 xhr return fd;
472 e68a87d3 2021-08-09 xhr }
473 87876c15 2021-08-09 xhr
474 87876c15 2021-08-09 xhr static void
475 87876c15 2021-08-09 xhr drop_root(void)
476 87876c15 2021-08-09 xhr {
477 87876c15 2021-08-09 xhr struct passwd *pw;
478 87876c15 2021-08-09 xhr
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);
481 e68a87d3 2021-08-09 xhr
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);
484 d42126da 2021-08-12 xhr
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__ */
497 87876c15 2021-08-09 xhr
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");
502 87876c15 2021-08-09 xhr
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);
509 87876c15 2021-08-09 xhr
510 87876c15 2021-08-09 xhr }
511 87876c15 2021-08-09 xhr