1 /*#############################################################################
3 # IPFire.org - A linux based firewall #
4 # Copyright (C) 2023 IPFire Network Development Team #
6 # This program is free software: you can redistribute it and/or modify #
7 # it under the terms of the GNU General Public License as published by #
8 # the Free Software Foundation, either version 3 of the License, or #
9 # (at your option) any later version. #
11 # This program is distributed in the hope that it will be useful, #
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
14 # GNU General Public License for more details. #
16 # You should have received a copy of the GNU General Public License #
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
19 #############################################################################*/
24 #include <systemd/sd-bus.h>
25 #include <systemd/sd-event.h>
31 static int nw_bus_daemon_reload(sd_bus_message
* m
, void* data
, sd_bus_error
* error
) {
32 struct nw_daemon
* daemon
= (struct nw_daemon
*)data
;
35 nw_daemon_reload(daemon
);
37 // Respond with an empty message
38 return sd_bus_reply_method_return(m
, NULL
);
41 static const sd_bus_vtable daemon_vtable
[] = {
42 SD_BUS_VTABLE_START(0),
43 SD_BUS_METHOD("Reload", SD_BUS_NO_ARGS
, SD_BUS_NO_RESULT
,
44 nw_bus_daemon_reload
, SD_BUS_VTABLE_UNPRIVILEGED
),
48 const struct nw_bus_implementation daemon_implementation
= {
49 .path
= "/org/ipfire/network1",
50 .interface
= "org.ipfire.network1",
51 .vtables
= BUS_VTABLES(daemon_vtable
),
54 static int nw_bus_on_connect(sd_bus_message
* m
, void* data
, sd_bus_error
* error
) {
55 struct nw_daemon
* daemon
= (struct nw_daemon
*)data
;
57 DEBUG("Connected to D-Bus\n");
62 int nw_bus_connect(sd_bus
* bus
, sd_event
* loop
) {
65 // Create a bus object
68 ERROR("Could not allocate a bus object: %s\n", strerror(-r
));
73 r
= sd_bus_set_description(bus
, NETWORKD_BUS_DESCRIPTION
);
75 ERROR("Could not set bus description: %s\n", strerror(-r
));
79 const char* address
= secure_getenv("DBUS_SYSTEM_BUS_ADDRESS");
81 address
= DEFAULT_SYSTEM_BUS_ADDRESS
;
84 r
= sd_bus_set_address(bus
, address
);
86 ERROR("Could not set bus address: %s\n", strerror(-r
));
91 r
= sd_bus_set_bus_client(bus
, 1);
93 ERROR("Could not set bus client: %s\n", strerror(-r
));
97 // Request some credentials for all messages
98 r
= sd_bus_negotiate_creds(bus
, 1,
99 SD_BUS_CREDS_UID
|SD_BUS_CREDS_EUID
|SD_BUS_CREDS_EFFECTIVE_CAPS
);
101 ERROR("Could not negotiate creds: %s\n", strerror(-r
));
105 // Automatically bind when the socket is available
106 r
= sd_bus_set_watch_bind(bus
, 1);
108 ERROR("Could not watch socket: %s\n", strerror(-r
));
112 // Emit a connected signal when we are connected
113 r
= sd_bus_set_connected_signal(bus
, 1);
115 ERROR("Could not enable sending a connect signal: %s\n", strerror(-r
));
119 // Connect to the bus
120 r
= sd_bus_start(bus
);
122 ERROR("Could not connect to bus: %s\n", strerror(-r
));
126 // Register the implementation
127 r
= nw_bus_register_implementation(bus
, &daemon_implementation
, NULL
);
131 // Request interface name
132 r
= sd_bus_request_name_async(bus
, NULL
, "org.ipfire.network1", 0, NULL
, NULL
);
134 ERROR("Could not request bus name: %s\n", strerror(-r
));
138 // Attach the event loop
139 r
= sd_bus_attach_event(bus
, loop
, 0);
141 ERROR("Could not attach bus to event loop: %s\n", strerror(-r
));
145 // Request receiving a connect signal
146 r
= sd_bus_match_signal_async(bus
, NULL
, "org.freedesktop.DBus.Local",
147 NULL
, "org.freedesktop.DBus.Local", "Connected", nw_bus_on_connect
, NULL
, NULL
);
149 ERROR("Could not request match on Connected signal: %s\n", strerror(-r
));
156 int nw_bus_register_implementation(sd_bus
* bus
,
157 const struct nw_bus_implementation
* impl
, void* data
) {
160 DEBUG("Registering bus object implementation for path=%s iface=%s\n",
161 impl
->path
, impl
->interface
);
163 for (const sd_bus_vtable
** vtable
= impl
->vtables
; vtable
&& *vtable
; vtable
++) {
164 r
= sd_bus_add_object_vtable(bus
, NULL
, impl
->path
, impl
->interface
, *vtable
, data
);
166 ERROR("Could not register bus path %s with interface %s: %m\n",
167 impl
->path
, impl
->interface
);