summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Mack <daniel@zonque.org>2016-11-03 17:30:06 +0100
committerLennart Poettering <lennart@poettering.net>2017-09-22 15:24:54 +0200
commitb36672e072e32060d6c25acfb51e409bc617b754 (patch)
tree03ed77f636deca027db5417c6da88bd804d92817
parentAdd abstraction model for BPF programs (diff)
downloadsystemd-b36672e072e32060d6c25acfb51e409bc617b754.tar.xz
systemd-b36672e072e32060d6c25acfb51e409bc617b754.zip
Add IP address address ACL representation and parser
Add a config directive parser that takes multiple space separated IPv4 or IPv6 addresses with optional netmasks in CIDR notation rvalue and puts a parsed version of it to linked list of IPAddressAccessItem objects. The code actually using this will be added later.
-rw-r--r--src/core/ip-address-access.c165
-rw-r--r--src/core/ip-address-access.h36
-rw-r--r--src/core/meson.build176
3 files changed, 290 insertions, 87 deletions
diff --git a/src/core/ip-address-access.c b/src/core/ip-address-access.c
new file mode 100644
index 0000000000..6a89bb23c1
--- /dev/null
+++ b/src/core/ip-address-access.c
@@ -0,0 +1,165 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2016 Daniel Mack
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "alloc-util.h"
+#include "extract-word.h"
+#include "hostname-util.h"
+#include "ip-address-access.h"
+#include "parse-util.h"
+#include "string-util.h"
+
+int config_parse_ip_address_access(
+ const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+
+ IPAddressAccessItem **list = data;
+ const char *p;
+ int r;
+
+ assert(list);
+
+ if (isempty(rvalue)) {
+ *list = ip_address_access_free_all(*list);
+ return 0;
+ }
+
+ p = rvalue;
+
+ for (;;) {
+ _cleanup_free_ IPAddressAccessItem *a = NULL;
+ _cleanup_free_ char *word = NULL;
+
+ r = extract_first_word(&p, &word, NULL, 0);
+ if (r == 0)
+ break;
+ if (r == -ENOMEM)
+ return log_oom();
+ if (r < 0) {
+ log_syntax(unit, LOG_WARNING, filename, line, r, "Invalid syntax, ignoring: %s", rvalue);
+ break;
+ }
+
+ a = new0(IPAddressAccessItem, 1);
+ if (!a)
+ return log_oom();
+
+ if (streq(word, "any")) {
+ /* "any" is a shortcut for 0.0.0.0/0 and ::/0 */
+
+ a->family = AF_INET;
+ LIST_APPEND(items, *list, a);
+
+ a = new0(IPAddressAccessItem, 1);
+ if (!a)
+ return log_oom();
+
+ a->family = AF_INET6;
+
+ } else if (is_localhost(word)) {
+ /* "localhost" is a shortcut for 127.0.0.0/8 and ::1/128 */
+
+ a->family = AF_INET;
+ a->address.in.s_addr = htobe32(0x7f000000);
+ a->prefixlen = 8;
+ LIST_APPEND(items, *list, a);
+
+ a = new0(IPAddressAccessItem, 1);
+ if (!a)
+ return log_oom();
+
+ a->family = AF_INET6;
+ a->address.in6 = (struct in6_addr) IN6ADDR_LOOPBACK_INIT;
+ a->prefixlen = 128;
+
+ } else if (streq(word, "link-local")) {
+
+ /* "link-local" is a shortcut for 169.254.0.0/16 and fe80::/64 */
+
+ a->family = AF_INET;
+ a->address.in.s_addr = htobe32((UINT32_C(169) << 24 | UINT32_C(254) << 16));
+ a->prefixlen = 16;
+ LIST_APPEND(items, *list, a);
+
+ a = new0(IPAddressAccessItem, 1);
+ if (!a)
+ return log_oom();
+
+ a->family = AF_INET6;
+ a->address.in6 = (struct in6_addr) {
+ .__in6_u.__u6_addr32[0] = htobe32(0xfe800000)
+ };
+ a->prefixlen = 64;
+
+ } else if (streq(word, "multicast")) {
+
+ /* "multicast" is a shortcut for 224.0.0.0/4 and ff00::/8 */
+
+ a->family = AF_INET;
+ a->address.in.s_addr = htobe32((UINT32_C(224) << 24));
+ a->prefixlen = 4;
+ LIST_APPEND(items, *list, a);
+
+ a = new0(IPAddressAccessItem, 1);
+ if (!a)
+ return log_oom();
+
+ a->family = AF_INET6;
+ a->address.in6 = (struct in6_addr) {
+ .__in6_u.__u6_addr32[0] = htobe32(0xff000000)
+ };
+ a->prefixlen = 8;
+
+ } else {
+ r = in_addr_prefix_from_string_auto(word, &a->family, &a->address, &a->prefixlen);
+ if (r < 0) {
+ log_syntax(unit, LOG_WARNING, filename, line, r, "Address prefix is invalid, ignoring assignment: %s", word);
+ return 0;
+ }
+ }
+
+ LIST_APPEND(items, *list, a);
+ a = NULL;
+ }
+
+ return 0;
+}
+
+IPAddressAccessItem* ip_address_access_free_all(IPAddressAccessItem *first) {
+ IPAddressAccessItem *next, *p = first;
+
+ while (p) {
+ next = p->items_next;
+ free(p);
+
+ p = next;
+ }
+
+ return NULL;
+}
diff --git a/src/core/ip-address-access.h b/src/core/ip-address-access.h
new file mode 100644
index 0000000000..eea20b4848
--- /dev/null
+++ b/src/core/ip-address-access.h
@@ -0,0 +1,36 @@
+#pragma once
+
+/***
+ This file is part of systemd.
+
+ Copyright 2016 Daniel Mack
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "in-addr-util.h"
+#include "list.h"
+
+typedef struct IPAddressAccessItem IPAddressAccessItem;
+
+struct IPAddressAccessItem {
+ int family;
+ unsigned char prefixlen;
+ union in_addr_union address;
+ LIST_FIELDS(IPAddressAccessItem, items);
+};
+
+int config_parse_ip_address_access(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+
+IPAddressAccessItem* ip_address_access_free_all(IPAddressAccessItem *first);
diff --git a/src/core/meson.build b/src/core/meson.build
index 569eed9cad..bea0d3528d 100644
--- a/src/core/meson.build
+++ b/src/core/meson.build
@@ -1,114 +1,116 @@
libcore_la_sources = '''
- unit.c
- unit.h
- unit-printf.c
- unit-printf.h
- job.c
- job.h
- manager.c
- manager.h
- transaction.c
- transaction.h
- load-fragment.c
- load-fragment.h
- service.c
- service.h
- socket.c
- socket.h
- target.c
- target.h
- device.c
- device.h
- mount.c
- mount.h
+ audit-fd.c
+ audit-fd.h
automount.c
automount.h
- swap.c
- swap.h
- timer.c
- timer.h
- path.c
- path.h
- slice.c
- slice.h
- scope.c
- scope.h
- load-dropin.c
- load-dropin.h
- execute.c
- execute.h
- dynamic-user.c
- dynamic-user.h
- kill.c
- kill.h
- dbus.c
- dbus.h
- dbus-manager.c
- dbus-manager.h
- dbus-unit.c
- dbus-unit.h
+ cgroup.c
+ cgroup.h
+ dbus-automount.c
+ dbus-automount.h
+ dbus-cgroup.c
+ dbus-cgroup.h
+ dbus-device.c
+ dbus-device.h
+ dbus-execute.c
+ dbus-execute.h
dbus-job.c
dbus-job.h
+ dbus-kill.c
+ dbus-kill.h
+ dbus-manager.c
+ dbus-manager.h
+ dbus-mount.c
+ dbus-mount.h
+ dbus-path.c
+ dbus-path.h
+ dbus-scope.c
+ dbus-scope.h
dbus-service.c
dbus-service.h
+ dbus-slice.c
+ dbus-slice.h
dbus-socket.c
dbus-socket.h
- dbus-target.c
- dbus-target.h
- dbus-device.c
- dbus-device.h
- dbus-mount.c
- dbus-mount.h
- dbus-automount.c
- dbus-automount.h
dbus-swap.c
dbus-swap.h
+ dbus-target.c
+ dbus-target.h
dbus-timer.c
dbus-timer.h
- dbus-path.c
- dbus-path.h
- dbus-slice.c
- dbus-slice.h
- dbus-scope.c
- dbus-scope.h
- dbus-execute.c
- dbus-execute.h
- dbus-kill.c
- dbus-kill.h
- dbus-cgroup.c
- dbus-cgroup.h
- cgroup.c
- cgroup.h
- selinux-access.c
- selinux-access.h
- selinux-setup.c
- selinux-setup.h
- smack-setup.c
- smack-setup.h
+ dbus-unit.c
+ dbus-unit.h
+ dbus.c
+ dbus.h
+ device.c
+ device.h
+ dynamic-user.c
+ dynamic-user.h
+ emergency-action.c
+ emergency-action.h
+ execute.c
+ execute.h
+ hostname-setup.c
+ hostname-setup.h
ima-setup.c
ima-setup.h
- locale-setup.h
+ ip-address-access.c
+ ip-address-access.h
+ job.c
+ job.h
+ kill.c
+ kill.h
+ killall.c
+ killall.h
+ kmod-setup.c
+ kmod-setup.h
+ load-dropin.c
+ load-dropin.h
+ load-fragment.c
+ load-fragment.h
locale-setup.c
- hostname-setup.c
- hostname-setup.h
+ locale-setup.h
+ loopback-setup.c
+ loopback-setup.h
machine-id-setup.c
machine-id-setup.h
+ manager.c
+ manager.h
mount-setup.c
mount-setup.h
- kmod-setup.c
- kmod-setup.h
- loopback-setup.h
- loopback-setup.c
+ mount.c
+ mount.h
namespace.c
namespace.h
- killall.h
- killall.c
- audit-fd.c
- audit-fd.h
+ path.c
+ path.h
+ scope.c
+ scope.h
+ selinux-access.c
+ selinux-access.h
+ selinux-setup.c
+ selinux-setup.h
+ service.c
+ service.h
show-status.c
show-status.h
- emergency-action.c
- emergency-action.h
+ slice.c
+ slice.h
+ smack-setup.c
+ smack-setup.h
+ socket.c
+ socket.h
+ swap.c
+ swap.h
+ target.c
+ target.h
+ timer.c
+ timer.h
+ transaction.c
+ transaction.h
+ unit-printf.c
+ unit-printf.h
+ unit.c
+ unit.h
'''.split()
load_fragment_gperf_gperf = custom_target(