Blame


1 8a35f56c 2022-07-16 thomas /*
2 8a35f56c 2022-07-16 thomas * Copyright (c) 2020-2021 Tracey Emery <tracey@traceyemery.net>
3 8a35f56c 2022-07-16 thomas * Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
4 8a35f56c 2022-07-16 thomas *
5 8a35f56c 2022-07-16 thomas * Permission to use, copy, modify, and distribute this software for any
6 8a35f56c 2022-07-16 thomas * purpose with or without fee is hereby granted, provided that the above
7 8a35f56c 2022-07-16 thomas * copyright notice and this permission notice appear in all copies.
8 8a35f56c 2022-07-16 thomas *
9 8a35f56c 2022-07-16 thomas * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 8a35f56c 2022-07-16 thomas * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 8a35f56c 2022-07-16 thomas * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 8a35f56c 2022-07-16 thomas * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 8a35f56c 2022-07-16 thomas * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 8a35f56c 2022-07-16 thomas * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 8a35f56c 2022-07-16 thomas * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 8a35f56c 2022-07-16 thomas */
17 8a35f56c 2022-07-16 thomas
18 5f50119f 2023-11-25 thomas #include "got_compat.h"
19 5f50119f 2023-11-25 thomas
20 8a35f56c 2022-07-16 thomas #include <sys/types.h>
21 8b925c6c 2022-07-16 thomas #include <sys/queue.h>
22 8a35f56c 2022-07-16 thomas #include <sys/time.h>
23 8a35f56c 2022-07-16 thomas #include <sys/uio.h>
24 8a35f56c 2022-07-16 thomas #include <sys/socket.h>
25 8a35f56c 2022-07-16 thomas
26 8a35f56c 2022-07-16 thomas #include <net/if.h>
27 8a35f56c 2022-07-16 thomas #include <netinet/in.h>
28 8a35f56c 2022-07-16 thomas
29 8a35f56c 2022-07-16 thomas #include <stdio.h>
30 8a35f56c 2022-07-16 thomas #include <stdlib.h>
31 8a35f56c 2022-07-16 thomas #include <termios.h>
32 8a35f56c 2022-07-16 thomas #include <unistd.h>
33 8a35f56c 2022-07-16 thomas #include <limits.h>
34 8a35f56c 2022-07-16 thomas #include <string.h>
35 8a35f56c 2022-07-16 thomas #include <event.h>
36 8a35f56c 2022-07-16 thomas #include <fcntl.h>
37 8a35f56c 2022-07-16 thomas #include <errno.h>
38 8a35f56c 2022-07-16 thomas
39 8a35f56c 2022-07-16 thomas #include "got_opentemp.h"
40 161663e7 2023-03-11 thomas #include "got_reference.h"
41 8a35f56c 2022-07-16 thomas
42 8a35f56c 2022-07-16 thomas #include "gotwebd.h"
43 8a35f56c 2022-07-16 thomas
44 8a35f56c 2022-07-16 thomas int
45 8a35f56c 2022-07-16 thomas config_init(struct gotwebd *env)
46 8a35f56c 2022-07-16 thomas {
47 0b16f49b 2023-06-22 thomas strlcpy(env->httpd_chroot, D_HTTPD_CHROOT, sizeof(env->httpd_chroot));
48 8a35f56c 2022-07-16 thomas
49 f85c939f 2023-11-22 thomas env->prefork_gotwebd = GOTWEBD_NUMPROC;
50 f85c939f 2023-11-22 thomas env->server_cnt = 0;
51 f85c939f 2023-11-22 thomas TAILQ_INIT(&env->servers);
52 f85c939f 2023-11-22 thomas TAILQ_INIT(&env->sockets);
53 8a35f56c 2022-07-16 thomas
54 2a18388f 2023-05-17 thomas return 0;
55 8a35f56c 2022-07-16 thomas }
56 8a35f56c 2022-07-16 thomas
57 8a35f56c 2022-07-16 thomas int
58 8a35f56c 2022-07-16 thomas config_getcfg(struct gotwebd *env, struct imsg *imsg)
59 8a35f56c 2022-07-16 thomas {
60 8a35f56c 2022-07-16 thomas /* nothing to do but tell gotwebd configuration is done */
61 f85c939f 2023-11-22 thomas if (sockets_compose_main(env, IMSG_CFG_DONE, NULL, 0) == -1)
62 f85c939f 2023-11-22 thomas fatal("sockets_compose_main IMSG_CFG_DONE");
63 2a18388f 2023-05-17 thomas return 0;
64 8a35f56c 2022-07-16 thomas }
65 8a35f56c 2022-07-16 thomas
66 8a35f56c 2022-07-16 thomas int
67 8a35f56c 2022-07-16 thomas config_setserver(struct gotwebd *env, struct server *srv)
68 8a35f56c 2022-07-16 thomas {
69 f85c939f 2023-11-22 thomas if (main_compose_sockets(env, IMSG_CFG_SRV, -1, srv, sizeof(*srv))
70 a004b24a 2022-09-06 thomas == -1)
71 f85c939f 2023-11-22 thomas fatal("main_compose_sockets IMSG_CFG_SRV");
72 2a18388f 2023-05-17 thomas return 0;
73 8a35f56c 2022-07-16 thomas }
74 8a35f56c 2022-07-16 thomas
75 8a35f56c 2022-07-16 thomas int
76 8a35f56c 2022-07-16 thomas config_getserver(struct gotwebd *env, struct imsg *imsg)
77 8a35f56c 2022-07-16 thomas {
78 8a35f56c 2022-07-16 thomas struct server *srv;
79 8a35f56c 2022-07-16 thomas uint8_t *p = imsg->data;
80 8a35f56c 2022-07-16 thomas
81 8a35f56c 2022-07-16 thomas srv = calloc(1, sizeof(*srv));
82 8a35f56c 2022-07-16 thomas if (srv == NULL)
83 8a35f56c 2022-07-16 thomas fatalx("%s: calloc", __func__);
84 8a35f56c 2022-07-16 thomas
85 d1d263ea 2023-11-22 thomas if (IMSG_DATA_SIZE(imsg) != sizeof(*srv))
86 d1d263ea 2023-11-22 thomas fatalx("%s: wrong size", __func__);
87 a004b24a 2022-09-06 thomas
88 a004b24a 2022-09-06 thomas memcpy(srv, p, sizeof(*srv));
89 8a35f56c 2022-07-16 thomas
90 8a35f56c 2022-07-16 thomas /* log server info */
91 8a35f56c 2022-07-16 thomas log_debug("%s: server=%s fcgi_socket=%s unix_socket=%s", __func__,
92 8a35f56c 2022-07-16 thomas srv->name, srv->fcgi_socket ? "yes" : "no", srv->unix_socket ?
93 8a35f56c 2022-07-16 thomas "yes" : "no");
94 8a35f56c 2022-07-16 thomas
95 90d63d47 2022-08-16 thomas TAILQ_INSERT_TAIL(&env->servers, srv, entry);
96 8a35f56c 2022-07-16 thomas
97 2a18388f 2023-05-17 thomas return 0;
98 8a35f56c 2022-07-16 thomas }
99 8a35f56c 2022-07-16 thomas
100 8a35f56c 2022-07-16 thomas int
101 8a35f56c 2022-07-16 thomas config_setsock(struct gotwebd *env, struct socket *sock)
102 8a35f56c 2022-07-16 thomas {
103 8a35f56c 2022-07-16 thomas /* open listening sockets */
104 8a35f56c 2022-07-16 thomas if (sockets_privinit(env, sock) == -1)
105 8a35f56c 2022-07-16 thomas return -1;
106 8a35f56c 2022-07-16 thomas
107 f85c939f 2023-11-22 thomas if (main_compose_sockets(env, IMSG_CFG_SOCK, sock->fd,
108 f85c939f 2023-11-22 thomas &sock->conf, sizeof(sock->conf)) == -1)
109 f85c939f 2023-11-22 thomas fatal("main_compose_sockets IMSG_CFG_SOCK");
110 8a35f56c 2022-07-16 thomas
111 f85c939f 2023-11-22 thomas sock->fd = -1;
112 2a18388f 2023-05-17 thomas return 0;
113 8a35f56c 2022-07-16 thomas }
114 8a35f56c 2022-07-16 thomas
115 8a35f56c 2022-07-16 thomas int
116 8a35f56c 2022-07-16 thomas config_getsock(struct gotwebd *env, struct imsg *imsg)
117 8a35f56c 2022-07-16 thomas {
118 8a35f56c 2022-07-16 thomas struct socket *sock = NULL;
119 8a35f56c 2022-07-16 thomas struct socket_conf sock_conf;
120 8a35f56c 2022-07-16 thomas uint8_t *p = imsg->data;
121 8a35f56c 2022-07-16 thomas int i;
122 8a35f56c 2022-07-16 thomas
123 d1d263ea 2023-11-22 thomas if (IMSG_DATA_SIZE(imsg) != sizeof(sock_conf))
124 d1d263ea 2023-11-22 thomas fatalx("%s: wrong size", __func__);
125 d1d263ea 2023-11-22 thomas
126 8a35f56c 2022-07-16 thomas memcpy(&sock_conf, p, sizeof(sock_conf));
127 8a35f56c 2022-07-16 thomas
128 8a35f56c 2022-07-16 thomas if (IMSG_DATA_SIZE(imsg) != sizeof(sock_conf)) {
129 8a35f56c 2022-07-16 thomas log_debug("%s: imsg size error", __func__);
130 8a35f56c 2022-07-16 thomas return 1;
131 8a35f56c 2022-07-16 thomas }
132 8a35f56c 2022-07-16 thomas
133 8a35f56c 2022-07-16 thomas /* create a new socket */
134 8a35f56c 2022-07-16 thomas if ((sock = calloc(1, sizeof(*sock))) == NULL) {
135 8a35f56c 2022-07-16 thomas return 1;
136 8a35f56c 2022-07-16 thomas }
137 8a35f56c 2022-07-16 thomas
138 8a35f56c 2022-07-16 thomas memcpy(&sock->conf, &sock_conf, sizeof(sock->conf));
139 3d97effa 2024-01-31 thomas sock->fd = imsg_get_fd(imsg);
140 8a35f56c 2022-07-16 thomas
141 90d63d47 2022-08-16 thomas TAILQ_INSERT_TAIL(&env->sockets, sock, entry);
142 8a35f56c 2022-07-16 thomas
143 8a35f56c 2022-07-16 thomas for (i = 0; i < PRIV_FDS__MAX; i++)
144 8a35f56c 2022-07-16 thomas sock->priv_fd[i] = -1;
145 8a35f56c 2022-07-16 thomas
146 e80b37ed 2022-07-22 thomas for (i = 0; i < GOTWEB_PACK_NUM_TEMPFILES; i++)
147 8a35f56c 2022-07-16 thomas sock->pack_fds[i] = -1;
148 8a35f56c 2022-07-16 thomas
149 8a35f56c 2022-07-16 thomas /* log new socket info */
150 720c2b05 2022-08-16 thomas log_debug("%s: name=%s id=%d server=%s af_type=%s socket_path=%s",
151 8a35f56c 2022-07-16 thomas __func__, sock->conf.name, sock->conf.id, sock->conf.srv_name,
152 720c2b05 2022-08-16 thomas sock->conf.af_type == AF_UNIX ? "unix" :
153 720c2b05 2022-08-16 thomas (sock->conf.af_type == AF_INET ? "inet" :
154 720c2b05 2022-08-16 thomas (sock->conf.af_type == AF_INET6 ? "inet6" : "unknown")),
155 102d840d 2023-06-22 thomas *sock->conf.unix_socket_name != '\0' ?
156 8a35f56c 2022-07-16 thomas sock->conf.unix_socket_name : "none");
157 8a35f56c 2022-07-16 thomas
158 2a18388f 2023-05-17 thomas return 0;
159 8a35f56c 2022-07-16 thomas }
160 8a35f56c 2022-07-16 thomas
161 8a35f56c 2022-07-16 thomas int
162 8a35f56c 2022-07-16 thomas config_setfd(struct gotwebd *env, struct socket *sock)
163 8a35f56c 2022-07-16 thomas {
164 25ebe470 2023-11-22 thomas int i, j, ret, fd;
165 8a35f56c 2022-07-16 thomas
166 8a35f56c 2022-07-16 thomas log_debug("%s: Allocating %d file descriptors",
167 e80b37ed 2022-07-22 thomas __func__, PRIV_FDS__MAX + GOTWEB_PACK_NUM_TEMPFILES);
168 8a35f56c 2022-07-16 thomas
169 f85c939f 2023-11-22 thomas for (i = 0; i < PRIV_FDS__MAX + GOTWEB_PACK_NUM_TEMPFILES; i++) {
170 25ebe470 2023-11-22 thomas for (j = 0; j < env->nserver; ++j) {
171 25ebe470 2023-11-22 thomas fd = got_opentempfd();
172 25ebe470 2023-11-22 thomas if (fd == -1)
173 25ebe470 2023-11-22 thomas fatal("got_opentemp");
174 25ebe470 2023-11-22 thomas if (imsg_compose_event(&env->iev_server[j],
175 25ebe470 2023-11-22 thomas IMSG_CFG_FD, 0, -1, fd, &sock->conf.id,
176 25ebe470 2023-11-22 thomas sizeof(sock->conf.id)) == -1)
177 25ebe470 2023-11-22 thomas fatal("imsg_compose_event IMSG_CFG_FD");
178 25ebe470 2023-11-22 thomas
179 25ebe470 2023-11-22 thomas do {
180 25ebe470 2023-11-22 thomas ret = imsg_flush(&env->iev_server[j].ibuf);
181 25ebe470 2023-11-22 thomas } while (ret == -1 && errno == EAGAIN);
182 25ebe470 2023-11-22 thomas if (ret == -1)
183 25ebe470 2023-11-22 thomas fatal("imsg_flush");
184 25ebe470 2023-11-22 thomas imsg_event_add(&env->iev_server[j]);
185 25ebe470 2023-11-22 thomas }
186 8a35f56c 2022-07-16 thomas }
187 f85c939f 2023-11-22 thomas
188 8a35f56c 2022-07-16 thomas return 0;
189 8a35f56c 2022-07-16 thomas }
190 8a35f56c 2022-07-16 thomas
191 8a35f56c 2022-07-16 thomas int
192 8a35f56c 2022-07-16 thomas config_getfd(struct gotwebd *env, struct imsg *imsg)
193 8a35f56c 2022-07-16 thomas {
194 8a35f56c 2022-07-16 thomas struct socket *sock;
195 8a35f56c 2022-07-16 thomas uint8_t *p = imsg->data;
196 3d97effa 2024-01-31 thomas int sock_id, match = 0, i, j;
197 8a35f56c 2022-07-16 thomas
198 d1d263ea 2023-11-22 thomas if (IMSG_DATA_SIZE(imsg) != sizeof(sock_id))
199 d1d263ea 2023-11-22 thomas fatalx("%s: wrong size", __func__);
200 d1d263ea 2023-11-22 thomas
201 8a35f56c 2022-07-16 thomas memcpy(&sock_id, p, sizeof(sock_id));
202 8a35f56c 2022-07-16 thomas
203 90d63d47 2022-08-16 thomas TAILQ_FOREACH(sock, &env->sockets, entry) {
204 e80b37ed 2022-07-22 thomas const int nfds = (GOTWEB_PACK_NUM_TEMPFILES + PRIV_FDS__MAX);
205 e80b37ed 2022-07-22 thomas for (i = 0; i < nfds; i++) {
206 8a35f56c 2022-07-16 thomas if (i < PRIV_FDS__MAX && sock->priv_fd[i] == -1) {
207 3d97effa 2024-01-31 thomas sock->priv_fd[i] = imsg_get_fd(imsg);
208 8a35f56c 2022-07-16 thomas log_debug("%s: assigning socket %d priv_fd %d",
209 3d97effa 2024-01-31 thomas __func__, sock_id, sock->priv_fd[i]);
210 8a35f56c 2022-07-16 thomas match = 1;
211 8a35f56c 2022-07-16 thomas break;
212 8a35f56c 2022-07-16 thomas }
213 3d97effa 2024-01-31 thomas
214 3d97effa 2024-01-31 thomas j = i - PRIV_FDS__MAX;
215 3d97effa 2024-01-31 thomas if (sock->pack_fds[j] == -1) {
216 3d97effa 2024-01-31 thomas sock->pack_fds[j] = imsg_get_fd(imsg);
217 8a35f56c 2022-07-16 thomas log_debug("%s: assigning socket %d pack_fd %d",
218 3d97effa 2024-01-31 thomas __func__, sock_id, sock->pack_fds[j]);
219 8a35f56c 2022-07-16 thomas match = 1;
220 8a35f56c 2022-07-16 thomas break;
221 8a35f56c 2022-07-16 thomas }
222 8a35f56c 2022-07-16 thomas }
223 8a35f56c 2022-07-16 thomas }
224 8a35f56c 2022-07-16 thomas
225 8a35f56c 2022-07-16 thomas if (match)
226 2a18388f 2023-05-17 thomas return 0;
227 8a35f56c 2022-07-16 thomas else
228 8a35f56c 2022-07-16 thomas return 1;
229 8a35f56c 2022-07-16 thomas }