1 /*-
2 * Copyright (c) 2006 Verdens Gang AS
3 * Copyright (c) 2006-2015 Varnish Software AS
4 * All rights reserved.
5 *
6 * Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
7 *
8 * SPDX-License-Identifier: BSD-2-Clause
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
31 * Acceptor socket management
32 */
33
34 #include "config.h"
35
36 #include <sys/types.h>
37 #include <sys/socket.h>
38 #include <sys/un.h>
39 #include <sys/stat.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <unistd.h>
44 #include <pwd.h>
45 #include <grp.h>
46
47 #include "mgt/mgt.h"
48 #include "common/heritage.h"
49
50 #include "vav.h"
51 #include "vcli_serve.h"
52 #include "vsa.h"
53 #include "vss.h"
54 #include "vtcp.h"
55 #include "vus.h"
56
57 struct listen_arg {
58 unsigned magic;
59 #define LISTEN_ARG_MAGIC 0xbb2fc333
60 VTAILQ_ENTRY(listen_arg) list;
61 const char *endpoint;
62 const char *name;
63 VTAILQ_HEAD(,listen_sock) socks;
64 const struct transport *transport;
65 const struct uds_perms *perms;
66 };
67
68 struct uds_perms {
69 unsigned magic;
70 #define UDS_PERMS_MAGIC 0x84fb5635
71 mode_t mode;
72 uid_t uid;
73 gid_t gid;
74 };
75
76 static VTAILQ_HEAD(,listen_arg) listen_args =
77 VTAILQ_HEAD_INITIALIZER(listen_args);
78
79 static int
mac_opensocket(struct listen_sock * ls)80 mac_opensocket(struct listen_sock *ls)
81 {
82 int fail;
83 struct sockaddr_un uds;
84
85 CHECK_OBJ_NOTNULL(ls, LISTEN_SOCK_MAGIC);
86 if (ls->sock > 0) {
87 MCH_Fd_Inherit(ls->sock, NULL);
88 closefd(&ls->sock);
89 }
90 if (!ls->uds)
91 ls->sock = VTCP_bind(ls->addr, NULL);
92 else {
93 uds.sun_family = PF_UNIX;
94 bprintf(uds.sun_path, "%s", ls->endpoint);
95 ls->sock = VUS_bind(&uds, NULL);
96 }
97 fail = errno;
98 if (ls->sock < 0) {
99 AN(fail);
100 return (fail);
101 }
102 if (ls->perms != NULL) {
103 CHECK_OBJ(ls->perms, UDS_PERMS_MAGIC);
104 assert(ls->uds);
105 errno = 0;
106 if (ls->perms->mode != 0 &&
107 chmod(ls->endpoint, ls->perms->mode) != 0)
108 return (errno);
109 if (chown(ls->endpoint, ls->perms->uid, ls->perms->gid) != 0)
110 return (errno);
111 }
112 MCH_Fd_Inherit(ls->sock, "sock");
113 return (0);
114 }
115
116 /*=====================================================================
117 * Reopen the accept sockets to get rid of listen status.
118 * returns the highest errno encountered, 0 for success
119 */
120
121 int
MAC_reopen_sockets(void)122 MAC_reopen_sockets(void)
123 {
124 struct listen_sock *ls;
125 int err, fail = 0;
126
127 VTAILQ_FOREACH(ls, &heritage.socks, list) {
128 VJ_master(JAIL_MASTER_PRIVPORT);
129 err = mac_opensocket(ls);
130 VJ_master(JAIL_MASTER_LOW);
131 if (err == 0)
132 continue;
133 if (err > fail)
134 fail = err;
135 MGT_Complain(C_ERR,
136 "Could not reopen listen socket %s: %s",
137 ls->endpoint, vstrerror(err));
138 }
139 return (fail);
140 }
141
142 /*--------------------------------------------------------------------*/
143
144 static struct listen_sock *
mk_listen_sock(const struct listen_arg * la,const struct suckaddr * sa)145 mk_listen_sock(const struct listen_arg *la, const struct suckaddr *sa)
146 {
147 struct listen_sock *ls;
148 int fail;
149
150 ALLOC_OBJ(ls, LISTEN_SOCK_MAGIC);
151 AN(ls);
152 ls->sock = -1;
153 ls->addr = VSA_Clone(sa);
154 AN(ls->addr);
155 ls->endpoint = strdup(la->endpoint);
156 AN(ls->endpoint);
157 ls->name = la->name;
158 ls->transport = la->transport;
159 ls->perms = la->perms;
160 if (*la->endpoint == '/')
161 ls->uds = 1;
162 VJ_master(JAIL_MASTER_PRIVPORT);
163 fail = mac_opensocket(ls);
164 VJ_master(JAIL_MASTER_LOW);
165 if (fail) {
166 free(ls->addr);
167 free(ls->endpoint);
168 FREE_OBJ(ls);
169 if (fail != EAFNOSUPPORT)
170 ARGV_ERR("Could not get socket %s: %s\n",
171 la->endpoint, vstrerror(fail));
172 return (NULL);
173 }
174 return (ls);
175 }
176
v_matchproto_(vss_resolved_f)177 static int v_matchproto_(vss_resolved_f)
178 mac_tcp(void *priv, const struct suckaddr *sa)
179 {
180 struct listen_arg *la;
181 struct listen_sock *ls;
182 char abuf[VTCP_ADDRBUFSIZE], pbuf[VTCP_PORTBUFSIZE];
183 char nbuf[VTCP_ADDRBUFSIZE+VTCP_PORTBUFSIZE+2];
184
185 CAST_OBJ_NOTNULL(la, priv, LISTEN_ARG_MAGIC);
186
187 VTAILQ_FOREACH(ls, &heritage.socks, list) {
188 if (!ls->uds && !VSA_Compare(sa, ls->addr))
189 ARGV_ERR("-a arguments %s and %s have same address\n",
190 ls->endpoint, la->endpoint);
191 }
192 ls = mk_listen_sock(la, sa);
193 if (ls == NULL)
194 return (0);
195 AZ(ls->uds);
196 if (VSA_Port(ls->addr) == 0) {
197 /*
198 * If the argv port number is zero, we adopt whatever
199 * port number this VTCP_bind() found us, as if
200 * it was specified by the argv.
201 */
202 free(ls->addr);
203 ls->addr = VTCP_my_suckaddr(ls->sock);
204 VTCP_myname(ls->sock, abuf, sizeof abuf,
205 pbuf, sizeof pbuf);
206 bprintf(nbuf, "%s:%s", abuf, pbuf);
207 REPLACE(ls->endpoint, nbuf);
208 }
209 VTAILQ_INSERT_TAIL(&la->socks, ls, arglist);
210 VTAILQ_INSERT_TAIL(&heritage.socks, ls, list);
211 return (0);
212 }
213
v_matchproto_(vus_resolved_f)214 static int v_matchproto_(vus_resolved_f)
215 mac_uds(void *priv, const struct sockaddr_un *uds)
216 {
217 struct listen_arg *la;
218 struct listen_sock *ls;
219
220 CAST_OBJ_NOTNULL(la, priv, LISTEN_ARG_MAGIC);
221
222 VTAILQ_FOREACH(ls, &heritage.socks, list) {
223 if (ls->uds && strcmp(uds->sun_path, ls->endpoint) == 0)
224 ARGV_ERR("-a arguments %s and %s have same address\n",
225 ls->endpoint, la->endpoint);
226 }
227 ls = mk_listen_sock(la, bogo_ip);
228 if (ls == NULL)
229 return (0);
230 AN(ls->uds);
231 VTAILQ_INSERT_TAIL(&la->socks, ls, arglist);
232 VTAILQ_INSERT_TAIL(&heritage.socks, ls, list);
233 return (0);
234 }
235
236 void
MAC_Arg(const char * spec)237 MAC_Arg(const char *spec)
238 {
239 char **av;
240 struct listen_arg *la;
241 const char *err;
242 int error;
243 const struct transport *xp = NULL;
244 const char *name;
245 char name_buf[8];
246 static unsigned seq = 0;
247 struct passwd *pwd = NULL;
248 struct group *grp = NULL;
249 mode_t mode = 0;
250 struct uds_perms *perms;
251
252 av = MGT_NamedArg(spec, &name, "-a");
253 AN(av);
254
255 ALLOC_OBJ(la, LISTEN_ARG_MAGIC);
256 AN(la);
257 VTAILQ_INIT(&la->socks);
258 VTAILQ_INSERT_TAIL(&listen_args, la, list);
259 la->endpoint = av[1];
260
261 if (name == NULL) {
262 bprintf(name_buf, "a%u", seq++);
263 name = strdup(name_buf);
264 AN(name);
265 }
266 la->name = name;
267
268 if (*la->endpoint != '/' && strchr(la->endpoint, '/') != NULL)
269 ARGV_ERR("Unix domain socket addresses must be"
270 " absolute paths in -a (%s)\n", la->endpoint);
271
272 if (*la->endpoint == '/' && heritage.min_vcl_version < 41)
273 heritage.min_vcl_version = 41;
274
275 for (int i = 2; av[i] != NULL; i++) {
276 char *eq, *val;
277 int len;
278
279 if ((eq = strchr(av[i], '=')) == NULL) {
280 if (xp != NULL)
281 ARGV_ERR("Too many protocol sub-args"
282 " in -a (%s)\n", av[i]);
283 xp = XPORT_Find(av[i]);
284 if (xp == NULL)
285 ARGV_ERR("Unknown protocol '%s'\n", av[i]);
286 continue;
287 }
288 if (la->endpoint[0] != '/')
289 ARGV_ERR("Invalid sub-arg %s for IP addresses"
290 " in -a\n", av[i]);
291
292 val = eq + 1;
293 len = eq - av[i];
294 assert(len >= 0);
295 if (len == 0)
296 ARGV_ERR("Invalid sub-arg %s in -a\n", av[i]);
297
298 if (strncmp(av[i], "user", len) == 0) {
299 if (pwd != NULL)
300 ARGV_ERR("Too many user sub-args in -a (%s)\n",
301 av[i]);
302 pwd = getpwnam(val);
303 if (pwd == NULL)
304 ARGV_ERR("Unknown user %s in -a\n", val);
305 continue;
306 }
307
308 if (strncmp(av[i], "group", len) == 0) {
309 if (grp != NULL)
310 ARGV_ERR("Too many group sub-args in -a (%s)\n",
311 av[i]);
312 grp = getgrnam(val);
313 if (grp == NULL)
314 ARGV_ERR("Unknown group %s in -a\n", val);
315 continue;
316 }
317
318 if (strncmp(av[i], "mode", len) == 0) {
319 long m;
320 char *p;
321
322 if (mode != 0)
323 ARGV_ERR("Too many mode sub-args in -a (%s)\n",
324 av[i]);
325 if (*val == '\0')
326 ARGV_ERR("Empty mode sub-arg in -a\n");
327 errno = 0;
328 m = strtol(val, &p, 8);
329 if (*p != '\0')
330 ARGV_ERR("Invalid mode sub-arg %s in -a\n",
331 val);
332 if (errno)
333 ARGV_ERR("Cannot parse mode sub-arg %s in -a: "
334 "%s\n", val, vstrerror(errno));
335 if (m <= 0 || m > 0777)
336 ARGV_ERR("Mode sub-arg %s out of range in -a\n",
337 val);
338 mode = (mode_t) m;
339 continue;
340 }
341
342 ARGV_ERR("Invalid sub-arg %s in -a\n", av[i]);
343 }
344
345 if (xp == NULL)
346 xp = XPORT_Find("http");
347 AN(xp);
348 la->transport = xp;
349
350 if (pwd != NULL || grp != NULL || mode != 0) {
351 ALLOC_OBJ(perms, UDS_PERMS_MAGIC);
352 AN(perms);
353 if (pwd != NULL)
354 perms->uid = pwd->pw_uid;
355 else
356 perms->uid = (uid_t) -1;
357 if (grp != NULL)
358 perms->gid = grp->gr_gid;
359 else
360 perms->gid = (gid_t) -1;
361 perms->mode = mode;
362 la->perms = perms;
363 }
364 else
365 AZ(la->perms);
366
367 if (*la->endpoint != '/')
368 error = VSS_resolver(av[1], "80", mac_tcp, la, &err);
369 else
370 error = VUS_resolver(av[1], mac_uds, la, &err);
371
372 if (VTAILQ_EMPTY(&la->socks) || error)
373 ARGV_ERR("Got no socket(s) for %s\n", av[1]);
374 VAV_Free(av);
375 }
376