]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/shared/socket-util.c
core: Fix assertion with empty Exec*= paths
[thirdparty/systemd.git] / src / shared / socket-util.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <string.h>
23 #include <unistd.h>
24 #include <errno.h>
25 #include <arpa/inet.h>
26 #include <stdio.h>
27 #include <net/if.h>
28 #include <sys/types.h>
29 #include <stddef.h>
30 #include <netdb.h>
31
32 #include "macro.h"
33 #include "path-util.h"
34 #include "util.h"
35 #include "socket-util.h"
36 #include "missing.h"
37 #include "fileio.h"
38 #include "formats-util.h"
39
40 int socket_address_parse(SocketAddress *a, const char *s) {
41 char *e, *n;
42 unsigned u;
43 int r;
44
45 assert(a);
46 assert(s);
47
48 zero(*a);
49 a->type = SOCK_STREAM;
50
51 if (*s == '[') {
52 /* IPv6 in [x:.....:z]:p notation */
53
54 if (!socket_ipv6_is_supported()) {
55 log_warning("Binding to IPv6 address not available since kernel does not support IPv6.");
56 return -EAFNOSUPPORT;
57 }
58
59 e = strchr(s+1, ']');
60 if (!e)
61 return -EINVAL;
62
63 n = strndupa(s+1, e-s-1);
64
65 errno = 0;
66 if (inet_pton(AF_INET6, n, &a->sockaddr.in6.sin6_addr) <= 0)
67 return errno > 0 ? -errno : -EINVAL;
68
69 e++;
70 if (*e != ':')
71 return -EINVAL;
72
73 e++;
74 r = safe_atou(e, &u);
75 if (r < 0)
76 return r;
77
78 if (u <= 0 || u > 0xFFFF)
79 return -EINVAL;
80
81 a->sockaddr.in6.sin6_family = AF_INET6;
82 a->sockaddr.in6.sin6_port = htons((uint16_t) u);
83 a->size = sizeof(struct sockaddr_in6);
84
85 } else if (*s == '/') {
86 /* AF_UNIX socket */
87
88 size_t l;
89
90 l = strlen(s);
91 if (l >= sizeof(a->sockaddr.un.sun_path))
92 return -EINVAL;
93
94 a->sockaddr.un.sun_family = AF_UNIX;
95 memcpy(a->sockaddr.un.sun_path, s, l);
96 a->size = offsetof(struct sockaddr_un, sun_path) + l + 1;
97
98 } else if (*s == '@') {
99 /* Abstract AF_UNIX socket */
100 size_t l;
101
102 l = strlen(s+1);
103 if (l >= sizeof(a->sockaddr.un.sun_path) - 1)
104 return -EINVAL;
105
106 a->sockaddr.un.sun_family = AF_UNIX;
107 memcpy(a->sockaddr.un.sun_path+1, s+1, l);
108 a->size = offsetof(struct sockaddr_un, sun_path) + 1 + l;
109
110 } else {
111 e = strchr(s, ':');
112 if (e) {
113 r = safe_atou(e+1, &u);
114 if (r < 0)
115 return r;
116
117 if (u <= 0 || u > 0xFFFF)
118 return -EINVAL;
119
120 n = strndupa(s, e-s);
121
122 /* IPv4 in w.x.y.z:p notation? */
123 r = inet_pton(AF_INET, n, &a->sockaddr.in.sin_addr);
124 if (r < 0)
125 return -errno;
126
127 if (r > 0) {
128 /* Gotcha, it's a traditional IPv4 address */
129 a->sockaddr.in.sin_family = AF_INET;
130 a->sockaddr.in.sin_port = htons((uint16_t) u);
131 a->size = sizeof(struct sockaddr_in);
132 } else {
133 unsigned idx;
134
135 if (strlen(n) > IF_NAMESIZE-1)
136 return -EINVAL;
137
138 /* Uh, our last resort, an interface name */
139 idx = if_nametoindex(n);
140 if (idx == 0)
141 return -EINVAL;
142
143 if (!socket_ipv6_is_supported()) {
144 log_warning("Binding to interface is not available since kernel does not support IPv6.");
145 return -EAFNOSUPPORT;
146 }
147
148 a->sockaddr.in6.sin6_family = AF_INET6;
149 a->sockaddr.in6.sin6_port = htons((uint16_t) u);
150 a->sockaddr.in6.sin6_scope_id = idx;
151 a->sockaddr.in6.sin6_addr = in6addr_any;
152 a->size = sizeof(struct sockaddr_in6);
153 }
154 } else {
155
156 /* Just a port */
157 r = safe_atou(s, &u);
158 if (r < 0)
159 return r;
160
161 if (u <= 0 || u > 0xFFFF)
162 return -EINVAL;
163
164 if (socket_ipv6_is_supported()) {
165 a->sockaddr.in6.sin6_family = AF_INET6;
166 a->sockaddr.in6.sin6_port = htons((uint16_t) u);
167 a->sockaddr.in6.sin6_addr = in6addr_any;
168 a->size = sizeof(struct sockaddr_in6);
169 } else {
170 a->sockaddr.in.sin_family = AF_INET;
171 a->sockaddr.in.sin_port = htons((uint16_t) u);
172 a->sockaddr.in.sin_addr.s_addr = INADDR_ANY;
173 a->size = sizeof(struct sockaddr_in);
174 }
175 }
176 }
177
178 return 0;
179 }
180
181 int socket_address_parse_netlink(SocketAddress *a, const char *s) {
182 int family;
183 unsigned group = 0;
184 _cleanup_free_ char *sfamily = NULL;
185 assert(a);
186 assert(s);
187
188 zero(*a);
189 a->type = SOCK_RAW;
190
191 errno = 0;
192 if (sscanf(s, "%ms %u", &sfamily, &group) < 1)
193 return errno > 0 ? -errno : -EINVAL;
194
195 family = netlink_family_from_string(sfamily);
196 if (family < 0)
197 return -EINVAL;
198
199 a->sockaddr.nl.nl_family = AF_NETLINK;
200 a->sockaddr.nl.nl_groups = group;
201
202 a->type = SOCK_RAW;
203 a->size = sizeof(struct sockaddr_nl);
204 a->protocol = family;
205
206 return 0;
207 }
208
209 int socket_address_verify(const SocketAddress *a) {
210 assert(a);
211
212 switch (socket_address_family(a)) {
213
214 case AF_INET:
215 if (a->size != sizeof(struct sockaddr_in))
216 return -EINVAL;
217
218 if (a->sockaddr.in.sin_port == 0)
219 return -EINVAL;
220
221 if (a->type != SOCK_STREAM && a->type != SOCK_DGRAM)
222 return -EINVAL;
223
224 return 0;
225
226 case AF_INET6:
227 if (a->size != sizeof(struct sockaddr_in6))
228 return -EINVAL;
229
230 if (a->sockaddr.in6.sin6_port == 0)
231 return -EINVAL;
232
233 if (a->type != SOCK_STREAM && a->type != SOCK_DGRAM)
234 return -EINVAL;
235
236 return 0;
237
238 case AF_UNIX:
239 if (a->size < offsetof(struct sockaddr_un, sun_path))
240 return -EINVAL;
241
242 if (a->size > offsetof(struct sockaddr_un, sun_path)) {
243
244 if (a->sockaddr.un.sun_path[0] != 0) {
245 char *e;
246
247 /* path */
248 e = memchr(a->sockaddr.un.sun_path, 0, sizeof(a->sockaddr.un.sun_path));
249 if (!e)
250 return -EINVAL;
251
252 if (a->size != offsetof(struct sockaddr_un, sun_path) + (e - a->sockaddr.un.sun_path) + 1)
253 return -EINVAL;
254 }
255 }
256
257 if (a->type != SOCK_STREAM && a->type != SOCK_DGRAM && a->type != SOCK_SEQPACKET)
258 return -EINVAL;
259
260 return 0;
261
262 case AF_NETLINK:
263
264 if (a->size != sizeof(struct sockaddr_nl))
265 return -EINVAL;
266
267 if (a->type != SOCK_RAW && a->type != SOCK_DGRAM)
268 return -EINVAL;
269
270 return 0;
271
272 default:
273 return -EAFNOSUPPORT;
274 }
275 }
276
277 int socket_address_print(const SocketAddress *a, char **ret) {
278 int r;
279
280 assert(a);
281 assert(ret);
282
283 r = socket_address_verify(a);
284 if (r < 0)
285 return r;
286
287 if (socket_address_family(a) == AF_NETLINK) {
288 _cleanup_free_ char *sfamily = NULL;
289
290 r = netlink_family_to_string_alloc(a->protocol, &sfamily);
291 if (r < 0)
292 return r;
293
294 r = asprintf(ret, "%s %u", sfamily, a->sockaddr.nl.nl_groups);
295 if (r < 0)
296 return -ENOMEM;
297
298 return 0;
299 }
300
301 return sockaddr_pretty(&a->sockaddr.sa, a->size, false, true, ret);
302 }
303
304 bool socket_address_can_accept(const SocketAddress *a) {
305 assert(a);
306
307 return
308 a->type == SOCK_STREAM ||
309 a->type == SOCK_SEQPACKET;
310 }
311
312 bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) {
313 assert(a);
314 assert(b);
315
316 /* Invalid addresses are unequal to all */
317 if (socket_address_verify(a) < 0 ||
318 socket_address_verify(b) < 0)
319 return false;
320
321 if (a->type != b->type)
322 return false;
323
324 if (socket_address_family(a) != socket_address_family(b))
325 return false;
326
327 switch (socket_address_family(a)) {
328
329 case AF_INET:
330 if (a->sockaddr.in.sin_addr.s_addr != b->sockaddr.in.sin_addr.s_addr)
331 return false;
332
333 if (a->sockaddr.in.sin_port != b->sockaddr.in.sin_port)
334 return false;
335
336 break;
337
338 case AF_INET6:
339 if (memcmp(&a->sockaddr.in6.sin6_addr, &b->sockaddr.in6.sin6_addr, sizeof(a->sockaddr.in6.sin6_addr)) != 0)
340 return false;
341
342 if (a->sockaddr.in6.sin6_port != b->sockaddr.in6.sin6_port)
343 return false;
344
345 break;
346
347 case AF_UNIX:
348 if (a->size <= offsetof(struct sockaddr_un, sun_path) ||
349 b->size <= offsetof(struct sockaddr_un, sun_path))
350 return false;
351
352 if ((a->sockaddr.un.sun_path[0] == 0) != (b->sockaddr.un.sun_path[0] == 0))
353 return false;
354
355 if (a->sockaddr.un.sun_path[0]) {
356 if (!path_equal_or_files_same(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path))
357 return false;
358 } else {
359 if (a->size != b->size)
360 return false;
361
362 if (memcmp(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path, a->size) != 0)
363 return false;
364 }
365
366 break;
367
368 case AF_NETLINK:
369 if (a->protocol != b->protocol)
370 return false;
371
372 if (a->sockaddr.nl.nl_groups != b->sockaddr.nl.nl_groups)
373 return false;
374
375 break;
376
377 default:
378 /* Cannot compare, so we assume the addresses are different */
379 return false;
380 }
381
382 return true;
383 }
384
385 bool socket_address_is(const SocketAddress *a, const char *s, int type) {
386 struct SocketAddress b;
387
388 assert(a);
389 assert(s);
390
391 if (socket_address_parse(&b, s) < 0)
392 return false;
393
394 b.type = type;
395
396 return socket_address_equal(a, &b);
397 }
398
399 bool socket_address_is_netlink(const SocketAddress *a, const char *s) {
400 struct SocketAddress b;
401
402 assert(a);
403 assert(s);
404
405 if (socket_address_parse_netlink(&b, s) < 0)
406 return false;
407
408 return socket_address_equal(a, &b);
409 }
410
411 const char* socket_address_get_path(const SocketAddress *a) {
412 assert(a);
413
414 if (socket_address_family(a) != AF_UNIX)
415 return NULL;
416
417 if (a->sockaddr.un.sun_path[0] == 0)
418 return NULL;
419
420 return a->sockaddr.un.sun_path;
421 }
422
423 bool socket_ipv6_is_supported(void) {
424 _cleanup_free_ char *l = NULL;
425
426 if (access("/sys/module/ipv6", F_OK) != 0)
427 return false;
428
429 /* If we can't check "disable" parameter, assume enabled */
430 if (read_one_line_file("/sys/module/ipv6/parameters/disable", &l) < 0)
431 return true;
432
433 /* If module was loaded with disable=1 no IPv6 available */
434 return l[0] == '0';
435 }
436
437 bool socket_address_matches_fd(const SocketAddress *a, int fd) {
438 SocketAddress b;
439 socklen_t solen;
440
441 assert(a);
442 assert(fd >= 0);
443
444 b.size = sizeof(b.sockaddr);
445 if (getsockname(fd, &b.sockaddr.sa, &b.size) < 0)
446 return false;
447
448 if (b.sockaddr.sa.sa_family != a->sockaddr.sa.sa_family)
449 return false;
450
451 solen = sizeof(b.type);
452 if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &b.type, &solen) < 0)
453 return false;
454
455 if (b.type != a->type)
456 return false;
457
458 if (a->protocol != 0) {
459 solen = sizeof(b.protocol);
460 if (getsockopt(fd, SOL_SOCKET, SO_PROTOCOL, &b.protocol, &solen) < 0)
461 return false;
462
463 if (b.protocol != a->protocol)
464 return false;
465 }
466
467 return socket_address_equal(a, &b);
468 }
469
470 int sockaddr_port(const struct sockaddr *_sa) {
471 union sockaddr_union *sa = (union sockaddr_union*) _sa;
472
473 assert(sa);
474
475 if (!IN_SET(sa->sa.sa_family, AF_INET, AF_INET6))
476 return -EAFNOSUPPORT;
477
478 return ntohs(sa->sa.sa_family == AF_INET6 ?
479 sa->in6.sin6_port :
480 sa->in.sin_port);
481 }
482
483 int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ipv6, bool include_port, char **ret) {
484 union sockaddr_union *sa = (union sockaddr_union*) _sa;
485 char *p;
486 int r;
487
488 assert(sa);
489 assert(salen >= sizeof(sa->sa.sa_family));
490
491 switch (sa->sa.sa_family) {
492
493 case AF_INET: {
494 uint32_t a;
495
496 a = ntohl(sa->in.sin_addr.s_addr);
497
498 if (include_port)
499 r = asprintf(&p,
500 "%u.%u.%u.%u:%u",
501 a >> 24, (a >> 16) & 0xFF, (a >> 8) & 0xFF, a & 0xFF,
502 ntohs(sa->in.sin_port));
503 else
504 r = asprintf(&p,
505 "%u.%u.%u.%u",
506 a >> 24, (a >> 16) & 0xFF, (a >> 8) & 0xFF, a & 0xFF);
507 if (r < 0)
508 return -ENOMEM;
509 break;
510 }
511
512 case AF_INET6: {
513 static const unsigned char ipv4_prefix[] = {
514 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF
515 };
516
517 if (translate_ipv6 &&
518 memcmp(&sa->in6.sin6_addr, ipv4_prefix, sizeof(ipv4_prefix)) == 0) {
519 const uint8_t *a = sa->in6.sin6_addr.s6_addr+12;
520 if (include_port)
521 r = asprintf(&p,
522 "%u.%u.%u.%u:%u",
523 a[0], a[1], a[2], a[3],
524 ntohs(sa->in6.sin6_port));
525 else
526 r = asprintf(&p,
527 "%u.%u.%u.%u",
528 a[0], a[1], a[2], a[3]);
529 if (r < 0)
530 return -ENOMEM;
531 } else {
532 char a[INET6_ADDRSTRLEN];
533
534 inet_ntop(AF_INET6, &sa->in6.sin6_addr, a, sizeof(a));
535
536 if (include_port) {
537 r = asprintf(&p,
538 "[%s]:%u",
539 a,
540 ntohs(sa->in6.sin6_port));
541 if (r < 0)
542 return -ENOMEM;
543 } else {
544 p = strdup(a);
545 if (!p)
546 return -ENOMEM;
547 }
548 }
549
550 break;
551 }
552
553 case AF_UNIX:
554 if (salen <= offsetof(struct sockaddr_un, sun_path)) {
555 p = strdup("<unnamed>");
556 if (!p)
557 return -ENOMEM;
558
559 } else if (sa->un.sun_path[0] == 0) {
560 /* abstract */
561
562 /* FIXME: We assume we can print the
563 * socket path here and that it hasn't
564 * more than one NUL byte. That is
565 * actually an invalid assumption */
566
567 p = new(char, sizeof(sa->un.sun_path)+1);
568 if (!p)
569 return -ENOMEM;
570
571 p[0] = '@';
572 memcpy(p+1, sa->un.sun_path+1, sizeof(sa->un.sun_path)-1);
573 p[sizeof(sa->un.sun_path)] = 0;
574
575 } else {
576 p = strndup(sa->un.sun_path, sizeof(sa->un.sun_path));
577 if (!ret)
578 return -ENOMEM;
579 }
580
581 break;
582
583 default:
584 return -EOPNOTSUPP;
585 }
586
587
588 *ret = p;
589 return 0;
590 }
591
592 int getpeername_pretty(int fd, char **ret) {
593 union sockaddr_union sa;
594 socklen_t salen = sizeof(sa);
595 int r;
596
597 assert(fd >= 0);
598 assert(ret);
599
600 if (getpeername(fd, &sa.sa, &salen) < 0)
601 return -errno;
602
603 if (sa.sa.sa_family == AF_UNIX) {
604 struct ucred ucred = {};
605
606 /* UNIX connection sockets are anonymous, so let's use
607 * PID/UID as pretty credentials instead */
608
609 r = getpeercred(fd, &ucred);
610 if (r < 0)
611 return r;
612
613 if (asprintf(ret, "PID "PID_FMT"/UID "UID_FMT, ucred.pid, ucred.uid) < 0)
614 return -ENOMEM;
615
616 return 0;
617 }
618
619 /* For remote sockets we translate IPv6 addresses back to IPv4
620 * if applicable, since that's nicer. */
621
622 return sockaddr_pretty(&sa.sa, salen, true, true, ret);
623 }
624
625 int getsockname_pretty(int fd, char **ret) {
626 union sockaddr_union sa;
627 socklen_t salen = sizeof(sa);
628
629 assert(fd >= 0);
630 assert(ret);
631
632 if (getsockname(fd, &sa.sa, &salen) < 0)
633 return -errno;
634
635 /* For local sockets we do not translate IPv6 addresses back
636 * to IPv6 if applicable, since this is usually used for
637 * listening sockets where the difference between IPv4 and
638 * IPv6 matters. */
639
640 return sockaddr_pretty(&sa.sa, salen, false, true, ret);
641 }
642
643 int socknameinfo_pretty(union sockaddr_union *sa, socklen_t salen, char **_ret) {
644 int r;
645 char host[NI_MAXHOST], *ret;
646
647 assert(_ret);
648
649 r = getnameinfo(&sa->sa, salen, host, sizeof(host), NULL, 0,
650 NI_IDN|NI_IDN_USE_STD3_ASCII_RULES);
651 if (r != 0) {
652 int saved_errno = errno;
653
654 r = sockaddr_pretty(&sa->sa, salen, true, true, &ret);
655 if (r < 0)
656 return log_error_errno(r, "sockadd_pretty() failed: %m");
657
658 log_debug_errno(saved_errno, "getnameinfo(%s) failed: %m", ret);
659 } else {
660 ret = strdup(host);
661 if (!ret)
662 return log_oom();
663 }
664
665 *_ret = ret;
666 return 0;
667 }
668
669 int getnameinfo_pretty(int fd, char **ret) {
670 union sockaddr_union sa;
671 socklen_t salen = sizeof(sa);
672
673 assert(fd >= 0);
674 assert(ret);
675
676 if (getsockname(fd, &sa.sa, &salen) < 0)
677 return log_error_errno(errno, "getsockname(%d) failed: %m", fd);
678
679 return socknameinfo_pretty(&sa, salen, ret);
680 }
681
682 int socket_address_unlink(SocketAddress *a) {
683 assert(a);
684
685 if (socket_address_family(a) != AF_UNIX)
686 return 0;
687
688 if (a->sockaddr.un.sun_path[0] == 0)
689 return 0;
690
691 if (unlink(a->sockaddr.un.sun_path) < 0)
692 return -errno;
693
694 return 1;
695 }
696
697 static const char* const netlink_family_table[] = {
698 [NETLINK_ROUTE] = "route",
699 [NETLINK_FIREWALL] = "firewall",
700 [NETLINK_INET_DIAG] = "inet-diag",
701 [NETLINK_NFLOG] = "nflog",
702 [NETLINK_XFRM] = "xfrm",
703 [NETLINK_SELINUX] = "selinux",
704 [NETLINK_ISCSI] = "iscsi",
705 [NETLINK_AUDIT] = "audit",
706 [NETLINK_FIB_LOOKUP] = "fib-lookup",
707 [NETLINK_CONNECTOR] = "connector",
708 [NETLINK_NETFILTER] = "netfilter",
709 [NETLINK_IP6_FW] = "ip6-fw",
710 [NETLINK_DNRTMSG] = "dnrtmsg",
711 [NETLINK_KOBJECT_UEVENT] = "kobject-uevent",
712 [NETLINK_GENERIC] = "generic",
713 [NETLINK_SCSITRANSPORT] = "scsitransport",
714 [NETLINK_ECRYPTFS] = "ecryptfs"
715 };
716
717 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(netlink_family, int, INT_MAX);
718
719 static const char* const socket_address_bind_ipv6_only_table[_SOCKET_ADDRESS_BIND_IPV6_ONLY_MAX] = {
720 [SOCKET_ADDRESS_DEFAULT] = "default",
721 [SOCKET_ADDRESS_BOTH] = "both",
722 [SOCKET_ADDRESS_IPV6_ONLY] = "ipv6-only"
723 };
724
725 DEFINE_STRING_TABLE_LOOKUP(socket_address_bind_ipv6_only, SocketAddressBindIPv6Only);
726
727 bool sockaddr_equal(const union sockaddr_union *a, const union sockaddr_union *b) {
728 assert(a);
729 assert(b);
730
731 if (a->sa.sa_family != b->sa.sa_family)
732 return false;
733
734 if (a->sa.sa_family == AF_INET)
735 return a->in.sin_addr.s_addr == b->in.sin_addr.s_addr;
736
737 if (a->sa.sa_family == AF_INET6)
738 return memcmp(&a->in6.sin6_addr, &b->in6.sin6_addr, sizeof(a->in6.sin6_addr)) == 0;
739
740 return false;
741 }
742
743 char* ether_addr_to_string(const struct ether_addr *addr, char buffer[ETHER_ADDR_TO_STRING_MAX]) {
744 assert(addr);
745 assert(buffer);
746
747 /* Like ether_ntoa() but uses %02x instead of %x to print
748 * ethernet addresses, which makes them look less funny. Also,
749 * doesn't use a static buffer. */
750
751 sprintf(buffer, "%02x:%02x:%02x:%02x:%02x:%02x",
752 addr->ether_addr_octet[0],
753 addr->ether_addr_octet[1],
754 addr->ether_addr_octet[2],
755 addr->ether_addr_octet[3],
756 addr->ether_addr_octet[4],
757 addr->ether_addr_octet[5]);
758
759 return buffer;
760 }