Blame


1 b0a6bcf7 2022-09-13 op /*
2 b0a6bcf7 2022-09-13 op * Copyright (c) 2022 Omar Polo <op@omarpolo.com>
3 b0a6bcf7 2022-09-13 op * Copyright (c) 2011 - 2015 Reyk Floeter <reyk@openbsd.org>
4 b0a6bcf7 2022-09-13 op *
5 b0a6bcf7 2022-09-13 op * Permission to use, copy, modify, and distribute this software for any
6 b0a6bcf7 2022-09-13 op * purpose with or without fee is hereby granted, provided that the above
7 b0a6bcf7 2022-09-13 op * copyright notice and this permission notice appear in all copies.
8 b0a6bcf7 2022-09-13 op *
9 b0a6bcf7 2022-09-13 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 b0a6bcf7 2022-09-13 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 b0a6bcf7 2022-09-13 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 b0a6bcf7 2022-09-13 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 b0a6bcf7 2022-09-13 op * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 b0a6bcf7 2022-09-13 op * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 b0a6bcf7 2022-09-13 op * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 b0a6bcf7 2022-09-13 op */
17 b0a6bcf7 2022-09-13 op
18 b0a6bcf7 2022-09-13 op #include <sys/types.h>
19 b0a6bcf7 2022-09-13 op #include <sys/queue.h>
20 b0a6bcf7 2022-09-13 op #include <sys/socket.h>
21 b0a6bcf7 2022-09-13 op #include <sys/un.h>
22 b0a6bcf7 2022-09-13 op #include <sys/tree.h>
23 b0a6bcf7 2022-09-13 op #include <sys/time.h>
24 b0a6bcf7 2022-09-13 op #include <sys/uio.h>
25 b0a6bcf7 2022-09-13 op
26 b0a6bcf7 2022-09-13 op #include <sys/stat.h> /* umask */
27 b0a6bcf7 2022-09-13 op #include <sys/un.h> /* sockaddr_un */
28 b0a6bcf7 2022-09-13 op
29 b0a6bcf7 2022-09-13 op #include <errno.h>
30 b0a6bcf7 2022-09-13 op #include <event.h>
31 b0a6bcf7 2022-09-13 op #include <limits.h>
32 b0a6bcf7 2022-09-13 op #include <pwd.h>
33 b0a6bcf7 2022-09-13 op #include <unistd.h>
34 b0a6bcf7 2022-09-13 op #include <stdlib.h>
35 b0a6bcf7 2022-09-13 op #include <stdio.h>
36 b0a6bcf7 2022-09-13 op #include <string.h>
37 b0a6bcf7 2022-09-13 op #include <imsg.h>
38 b0a6bcf7 2022-09-13 op
39 b0a6bcf7 2022-09-13 op #include "proc.h"
40 b0a6bcf7 2022-09-13 op #include "log.h"
41 b0a6bcf7 2022-09-13 op #include "xmalloc.h"
42 b0a6bcf7 2022-09-13 op
43 b0a6bcf7 2022-09-13 op #include "galileo.h"
44 b0a6bcf7 2022-09-13 op
45 b0a6bcf7 2022-09-13 op int
46 b0a6bcf7 2022-09-13 op config_init(struct galileo *env)
47 b0a6bcf7 2022-09-13 op {
48 b0a6bcf7 2022-09-13 op /* Global configuration */
49 b0a6bcf7 2022-09-13 op if (privsep_process == PROC_PARENT)
50 b0a6bcf7 2022-09-13 op env->sc_prefork = PROXY_NUMPROC;
51 b0a6bcf7 2022-09-13 op
52 b0a6bcf7 2022-09-13 op /* Other configuration. */
53 afb86b2c 2022-09-23 op TAILQ_INIT(&env->sc_proxies);
54 b0a6bcf7 2022-09-13 op
55 b0a6bcf7 2022-09-13 op env->sc_sock_fd = -1;
56 b0a6bcf7 2022-09-13 op
57 c9e6d547 2022-09-23 op return (0);
58 b0a6bcf7 2022-09-13 op }
59 b0a6bcf7 2022-09-13 op
60 b0a6bcf7 2022-09-13 op void
61 b0a6bcf7 2022-09-13 op config_purge(struct galileo *env)
62 b0a6bcf7 2022-09-13 op {
63 afb86b2c 2022-09-23 op struct proxy *p;
64 40f762b2 2022-09-23 op struct fcgi *fcgi;
65 40f762b2 2022-09-23 op struct client *clt;
66 b0a6bcf7 2022-09-13 op
67 40f762b2 2022-09-23 op while ((fcgi = SPLAY_MIN(fcgi_tree, &env->sc_fcgi_socks))) {
68 40f762b2 2022-09-23 op while ((clt = SPLAY_MIN(client_tree, &fcgi->fcg_clients))) {
69 40f762b2 2022-09-23 op if (fcgi_abort_request(clt) == -1) {
70 40f762b2 2022-09-23 op fcgi = NULL;
71 40f762b2 2022-09-23 op break;
72 40f762b2 2022-09-23 op }
73 40f762b2 2022-09-23 op }
74 40f762b2 2022-09-23 op
75 40f762b2 2022-09-23 op if (fcgi == NULL)
76 a12e95aa 2022-09-30 op continue;
77 40f762b2 2022-09-23 op
78 40f762b2 2022-09-23 op SPLAY_REMOVE(fcgi_tree, &env->sc_fcgi_socks, fcgi);
79 40f762b2 2022-09-23 op fcgi_free(fcgi);
80 40f762b2 2022-09-23 op }
81 40f762b2 2022-09-23 op
82 246017d4 2022-09-30 op if (env->sc_sock_fd != -1) {
83 246017d4 2022-09-30 op event_del(&env->sc_evsock);
84 246017d4 2022-09-30 op event_del(&env->sc_evpause);
85 246017d4 2022-09-30 op close(env->sc_sock_fd);
86 246017d4 2022-09-30 op env->sc_sock_fd = -1;
87 246017d4 2022-09-30 op }
88 40f762b2 2022-09-23 op
89 afb86b2c 2022-09-23 op while ((p = TAILQ_FIRST(&env->sc_proxies)) != NULL) {
90 afb86b2c 2022-09-23 op TAILQ_REMOVE(&env->sc_proxies, p, pr_entry);
91 afb86b2c 2022-09-23 op proxy_purge(p);
92 b0a6bcf7 2022-09-13 op }
93 b0a6bcf7 2022-09-13 op }
94 b0a6bcf7 2022-09-13 op
95 b0a6bcf7 2022-09-13 op int
96 afb86b2c 2022-09-23 op config_setproxy(struct galileo *env, struct proxy *p)
97 b0a6bcf7 2022-09-13 op {
98 b0a6bcf7 2022-09-13 op struct privsep *ps = env->sc_ps;
99 b0a6bcf7 2022-09-13 op
100 afb86b2c 2022-09-23 op if (proc_compose(ps, PROC_PROXY, IMSG_CFG_SRV, p, sizeof(*p)) == -1)
101 b0a6bcf7 2022-09-13 op fatal("proc_compose");
102 c9e6d547 2022-09-23 op return (0);
103 b0a6bcf7 2022-09-13 op }
104 b0a6bcf7 2022-09-13 op
105 b0a6bcf7 2022-09-13 op int
106 afb86b2c 2022-09-23 op config_getproxy(struct galileo *env, struct imsg *imsg)
107 b0a6bcf7 2022-09-13 op {
108 afb86b2c 2022-09-23 op struct proxy *proxy;
109 b0a6bcf7 2022-09-13 op
110 afb86b2c 2022-09-23 op proxy = xcalloc(1, sizeof(*proxy));
111 afb86b2c 2022-09-23 op if (IMSG_DATA_SIZE(imsg) != sizeof(*proxy))
112 b0a6bcf7 2022-09-13 op fatalx("%s: bad imsg size", __func__);
113 b0a6bcf7 2022-09-13 op
114 afb86b2c 2022-09-23 op memcpy(proxy, imsg->data, sizeof(*proxy));
115 b0a6bcf7 2022-09-13 op
116 26cd3e9d 2022-09-23 op log_debug("%s: proxy=%s -> %s:%s (%s)", __func__,
117 afb86b2c 2022-09-23 op proxy->pr_conf.host, proxy->pr_conf.proxy_addr,
118 afb86b2c 2022-09-23 op proxy->pr_conf.proxy_port, proxy->pr_conf.proxy_name);
119 b0a6bcf7 2022-09-13 op
120 afb86b2c 2022-09-23 op TAILQ_INSERT_TAIL(&env->sc_proxies, proxy, pr_entry);
121 b0a6bcf7 2022-09-13 op
122 c9e6d547 2022-09-23 op return (0);
123 b0a6bcf7 2022-09-13 op }
124 b0a6bcf7 2022-09-13 op
125 b0a6bcf7 2022-09-13 op int
126 b0a6bcf7 2022-09-13 op config_setsock(struct galileo *env)
127 b0a6bcf7 2022-09-13 op {
128 b0a6bcf7 2022-09-13 op struct privsep *ps = env->sc_ps;
129 b0a6bcf7 2022-09-13 op struct passwd *pw = ps->ps_pw;
130 b0a6bcf7 2022-09-13 op struct sockaddr_un sun;
131 b0a6bcf7 2022-09-13 op const char *path = GALILEO_SOCK;
132 b0a6bcf7 2022-09-13 op int id, fd, old_umask;
133 b0a6bcf7 2022-09-13 op
134 b0a6bcf7 2022-09-13 op /*
135 b0a6bcf7 2022-09-13 op * open listening socket.
136 b0a6bcf7 2022-09-13 op *
137 b0a6bcf7 2022-09-13 op * XXX: move to server.c as server_privinit like httpd once we
138 b0a6bcf7 2022-09-13 op * support more than one listening socket.
139 b0a6bcf7 2022-09-13 op */
140 b0a6bcf7 2022-09-13 op if ((fd = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0)) == -1) {
141 b0a6bcf7 2022-09-13 op log_warn("%s: socket", __func__);
142 b0a6bcf7 2022-09-13 op return (-1);
143 b0a6bcf7 2022-09-13 op }
144 b0a6bcf7 2022-09-13 op
145 b0a6bcf7 2022-09-13 op memset(&sun, 0, sizeof(sun));
146 b0a6bcf7 2022-09-13 op sun.sun_family = AF_UNIX;
147 b0a6bcf7 2022-09-13 op strlcpy(sun.sun_path, path, sizeof(sun.sun_path));
148 b0a6bcf7 2022-09-13 op
149 b0a6bcf7 2022-09-13 op if (unlink(path) == -1)
150 b0a6bcf7 2022-09-13 op if (errno != ENOENT) {
151 b0a6bcf7 2022-09-13 op log_warn("%s: unlink %s", __func__, path);
152 b0a6bcf7 2022-09-13 op close(fd);
153 b0a6bcf7 2022-09-13 op return (-1);
154 b0a6bcf7 2022-09-13 op }
155 b0a6bcf7 2022-09-13 op
156 b0a6bcf7 2022-09-13 op old_umask = umask(S_IXUSR|S_IXGRP|S_IWOTH|S_IROTH|S_IXOTH);
157 b0a6bcf7 2022-09-13 op if (bind(fd, (struct sockaddr *)&sun, sizeof(sun)) == -1) {
158 b0a6bcf7 2022-09-13 op log_warn("%s: bind: %s (%d)", __func__, path, geteuid());
159 b0a6bcf7 2022-09-13 op close(fd);
160 b0a6bcf7 2022-09-13 op umask(old_umask);
161 b0a6bcf7 2022-09-13 op return (-1);
162 b0a6bcf7 2022-09-13 op }
163 b0a6bcf7 2022-09-13 op umask(old_umask);
164 b0a6bcf7 2022-09-13 op
165 b0a6bcf7 2022-09-13 op if (chmod(path, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) == -1) {
166 b0a6bcf7 2022-09-13 op log_warn("%s: chmod", __func__);
167 b0a6bcf7 2022-09-13 op close(fd);
168 b0a6bcf7 2022-09-13 op (void)unlink(path);
169 b0a6bcf7 2022-09-13 op return (-1);
170 b0a6bcf7 2022-09-13 op }
171 b0a6bcf7 2022-09-13 op
172 b0a6bcf7 2022-09-13 op if (chown(path, pw->pw_uid, pw->pw_gid) == -1) {
173 b0a6bcf7 2022-09-13 op log_warn("%s: chown", __func__);
174 b0a6bcf7 2022-09-13 op close(fd);
175 b0a6bcf7 2022-09-13 op (void)unlink(path);
176 b0a6bcf7 2022-09-13 op return (-1);
177 b0a6bcf7 2022-09-13 op }
178 b0a6bcf7 2022-09-13 op
179 b0a6bcf7 2022-09-13 op if (listen(fd, 5) == -1) {
180 b0a6bcf7 2022-09-13 op log_warn("%s: listen", __func__);
181 b0a6bcf7 2022-09-13 op close(fd);
182 b0a6bcf7 2022-09-13 op (void)unlink(path);
183 b0a6bcf7 2022-09-13 op return (-1);
184 b0a6bcf7 2022-09-13 op }
185 b0a6bcf7 2022-09-13 op
186 b0a6bcf7 2022-09-13 op for (id = 0; id < PROC_MAX; ++id) {
187 b0a6bcf7 2022-09-13 op int n, m;
188 b0a6bcf7 2022-09-13 op
189 b0a6bcf7 2022-09-13 op if (id == privsep_process || id != PROC_PROXY)
190 b0a6bcf7 2022-09-13 op continue;
191 b0a6bcf7 2022-09-13 op
192 b0a6bcf7 2022-09-13 op n = -1;
193 b0a6bcf7 2022-09-13 op proc_range(ps, id, &n, &m);
194 b0a6bcf7 2022-09-13 op for (n = 0; n < m; ++n) {
195 b0a6bcf7 2022-09-13 op int d;
196 b0a6bcf7 2022-09-13 op
197 b0a6bcf7 2022-09-13 op if ((d = dup(fd)) == -1) {
198 b0a6bcf7 2022-09-13 op log_warn("%s: dup", __func__);
199 b0a6bcf7 2022-09-13 op close(fd);
200 b0a6bcf7 2022-09-13 op return (-1);
201 b0a6bcf7 2022-09-13 op }
202 b0a6bcf7 2022-09-13 op
203 b0a6bcf7 2022-09-13 op if (proc_compose_imsg(ps, id, n, IMSG_CFG_SOCK,
204 b0a6bcf7 2022-09-13 op -1, d, NULL, 0) == -1) {
205 b0a6bcf7 2022-09-13 op log_warn("%s: failed to compose "
206 b0a6bcf7 2022-09-13 op "IMSG_CFG_SOCK", __func__);
207 b0a6bcf7 2022-09-13 op close(fd);
208 b0a6bcf7 2022-09-13 op return (-1);
209 b0a6bcf7 2022-09-13 op }
210 b0a6bcf7 2022-09-13 op if (proc_flush_imsg(ps, id, n) == -1) {
211 b0a6bcf7 2022-09-13 op log_warn("%s: failed to flush", __func__);
212 b0a6bcf7 2022-09-13 op close(fd);
213 b0a6bcf7 2022-09-13 op return (-1);
214 b0a6bcf7 2022-09-13 op }
215 b0a6bcf7 2022-09-13 op }
216 b0a6bcf7 2022-09-13 op }
217 b0a6bcf7 2022-09-13 op
218 cbd105ce 2022-09-23 op close(fd);
219 b0a6bcf7 2022-09-13 op return (0);
220 b0a6bcf7 2022-09-13 op }
221 b0a6bcf7 2022-09-13 op
222 b0a6bcf7 2022-09-13 op int
223 b0a6bcf7 2022-09-13 op config_getsock(struct galileo *env, struct imsg *imsg)
224 b0a6bcf7 2022-09-13 op {
225 b0a6bcf7 2022-09-13 op /* XXX: make it more like httpd/gotwebd' one */
226 c9e6d547 2022-09-23 op return (imsg->fd);
227 b0a6bcf7 2022-09-13 op }
228 b0a6bcf7 2022-09-13 op
229 b0a6bcf7 2022-09-13 op int
230 b0a6bcf7 2022-09-13 op config_setreset(struct galileo *env)
231 b0a6bcf7 2022-09-13 op {
232 b0a6bcf7 2022-09-13 op struct privsep *ps = env->sc_ps;
233 b0a6bcf7 2022-09-13 op int id;
234 b0a6bcf7 2022-09-13 op
235 b0a6bcf7 2022-09-13 op for (id = 0; id < PROC_MAX; ++id)
236 40f762b2 2022-09-23 op if (id != PROC_PARENT)
237 40f762b2 2022-09-23 op proc_compose(ps, id, IMSG_CTL_RESET, NULL, 0);
238 b0a6bcf7 2022-09-13 op
239 b0a6bcf7 2022-09-13 op return (0);
240 b0a6bcf7 2022-09-13 op }
241 b0a6bcf7 2022-09-13 op
242 b0a6bcf7 2022-09-13 op int
243 b0a6bcf7 2022-09-13 op config_getreset(struct galileo *env, struct imsg *imsg)
244 b0a6bcf7 2022-09-13 op {
245 b0a6bcf7 2022-09-13 op config_purge(env);
246 b0a6bcf7 2022-09-13 op
247 b0a6bcf7 2022-09-13 op return (0);
248 b0a6bcf7 2022-09-13 op }
249 40f762b2 2022-09-23 op
250 40f762b2 2022-09-23 op int
251 40f762b2 2022-09-23 op config_getcfg(struct galileo *env, struct imsg *imsg)
252 40f762b2 2022-09-23 op {
253 40f762b2 2022-09-23 op if (privsep_process != PROC_PARENT)
254 40f762b2 2022-09-23 op proc_compose(env->sc_ps, PROC_PARENT,
255 40f762b2 2022-09-23 op IMSG_CFG_DONE, NULL, 0);
256 40f762b2 2022-09-23 op
257 40f762b2 2022-09-23 op return (0);
258 40f762b2 2022-09-23 op }