Open SCAP Library
Loading...
Searching...
No Matches
systemdshared.h
1
7/*
8 * Copyright 2014 Red Hat Inc., Durham, North Carolina.
9 * All Rights Reserved.
10 *
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
15 *
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 *
25 * Authors:
26 *
27 */
28
29#pragma once
30
31#ifndef OPENSCAP_OVAL_PROBES_SYSTEMDSHARED_H_
32#define OPENSCAP_OVAL_PROBES_SYSTEMDSHARED_H_
33
34#ifdef HAVE_CONFIG_H
35#include <config.h>
36#endif
37
38#include <limits.h>
39#include <stdio.h>
40#include <dbus/dbus.h>
41#include "common/debug_priv.h"
42#include "oscap_helpers.h"
43
44// Old versions of libdbus API don't have DBusBasicValue and DBus8ByteStruct
45// as a public typedefs.
46// These two typedefs were copied from libdbus 1.8 branch, see
47// http://cgit.freedesktop.org/dbus/dbus/tree/dbus/dbus-types.h?h=dbus-1.8#n137
48typedef struct
49{
50 dbus_uint32_t first32;
51 dbus_uint32_t second32;
53
54typedef union
55{
56 unsigned char bytes[8];
57 dbus_int16_t i16;
58 dbus_uint16_t u16;
59 dbus_int32_t i32;
60 dbus_uint32_t u32;
61 dbus_bool_t bool_val;
62#ifdef DBUS_HAVE_INT64
63 dbus_int64_t i64;
64 dbus_uint64_t u64;
65#endif
67 double dbl;
68 unsigned char byt;
69 char *str;
70 int fd;
72
73static char *get_path_by_unit(DBusConnection *conn, const char *unit)
74{
75 DBusMessage *msg = NULL;
76 DBusPendingCall *pending = NULL;
77 _DBusBasicValue path;
78 char *ret = NULL;
79
80 msg = dbus_message_new_method_call(
81 "org.freedesktop.systemd1",
82 "/org/freedesktop/systemd1",
83 "org.freedesktop.systemd1.Manager",
84 // LoadUnit is similar to GetUnit except it will load the unit file
85 // if it hasn't been loaded yet.
86 "LoadUnit"
87 );
88 if (msg == NULL) {
89 dD("Failed to create dbus_message via dbus_message_new_method_call!");
90 goto cleanup;
91 }
92
93 DBusMessageIter args;
94
95 dbus_message_iter_init_append(msg, &args);
96 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &unit)) {
97 dD("Failed to append unit '%s' string parameter to dbus message!", unit);
98 goto cleanup;
99 }
100
101 if (!dbus_connection_send_with_reply(conn, msg, &pending, -1)) {
102 dD("Failed to send message via dbus!");
103 goto cleanup;
104 }
105 if (pending == NULL) {
106 dD("Invalid dbus pending call!");
107 goto cleanup;
108 }
109
110 dbus_connection_flush(conn);
111 dbus_message_unref(msg); msg = NULL;
112
113 dbus_pending_call_block(pending);
114 msg = dbus_pending_call_steal_reply(pending);
115 if (msg == NULL) {
116 dD("Failed to steal dbus pending call reply.");
117 goto cleanup;
118 }
119 dbus_pending_call_unref(pending); pending = NULL;
120
121 if (!dbus_message_iter_init(msg, &args)) {
122 dD("Failed to initialize iterator over received dbus message.");
123 goto cleanup;
124 }
125
126 if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_OBJECT_PATH) {
127 dD("Expected string argument in reply. Instead received: %s.", dbus_message_type_to_string(dbus_message_iter_get_arg_type(&args)));
128 goto cleanup;
129 }
130
131 dbus_message_iter_get_basic(&args, &path);
132 ret = oscap_strdup(path.str);
133 dbus_message_unref(msg); msg = NULL;
134
135cleanup:
136 if (pending != NULL)
137 dbus_pending_call_unref(pending);
138
139 if (msg != NULL)
140 dbus_message_unref(msg);
141
142 return ret;
143}
144
145static int get_all_systemd_units(DBusConnection* conn, int(*callback)(const char *, void *), void *cbarg)
146{
147 DBusMessage *msg = NULL;
148 DBusPendingCall *pending = NULL;
149 char ret = 1;
150
151 msg = dbus_message_new_method_call(
152 "org.freedesktop.systemd1",
153 "/org/freedesktop/systemd1",
154 "org.freedesktop.systemd1.Manager",
155 "ListUnits"
156 );
157 if (msg == NULL) {
158 dD("Failed to create dbus_message via dbus_message_new_method_call!");
159 goto cleanup;
160 }
161
162 DBusMessageIter args, unit_iter;
163
164 // the args should be empty for this call
165 dbus_message_iter_init_append(msg, &args);
166
167 if (!dbus_connection_send_with_reply(conn, msg, &pending, -1)) {
168 dD("Failed to send message via dbus!");
169 goto cleanup;
170 }
171 if (pending == NULL) {
172 dD("Invalid dbus pending call!");
173 goto cleanup;
174 }
175
176 dbus_connection_flush(conn);
177 dbus_message_unref(msg); msg = NULL;
178
179 dbus_pending_call_block(pending);
180 msg = dbus_pending_call_steal_reply(pending);
181 if (msg == NULL) {
182 dD("Failed to steal dbus pending call reply.");
183 goto cleanup;
184 }
185 dbus_pending_call_unref(pending); pending = NULL;
186
187 if (!dbus_message_iter_init(msg, &args)) {
188 dD("Failed to initialize iterator over received dbus message.");
189 goto cleanup;
190 }
191
192 if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_ARRAY) {
193 dD("Expected array of structs in reply. Instead received: %s.", dbus_message_type_to_string(dbus_message_iter_get_arg_type(&args)));
194 goto cleanup;
195 }
196
197 dbus_message_iter_recurse(&args, &unit_iter);
198 do {
199 if (dbus_message_iter_get_arg_type(&unit_iter) != DBUS_TYPE_STRUCT) {
200 dD("Expected unit struct as elements in returned array. Instead received: %s.", dbus_message_type_to_string(dbus_message_iter_get_arg_type(&unit_iter)));
201 goto cleanup;
202 }
203
204 DBusMessageIter unit_name;
205 dbus_message_iter_recurse(&unit_iter, &unit_name);
206
207 if (dbus_message_iter_get_arg_type(&unit_name) != DBUS_TYPE_STRING) {
208 dD("Expected string as the first element in the unit struct. Instead received: %s.", dbus_message_type_to_string(dbus_message_iter_get_arg_type(&unit_name)));
209 goto cleanup;
210 }
211
212 _DBusBasicValue value;
213 dbus_message_iter_get_basic(&unit_name, &value);
214 char *unit_name_s = oscap_strdup(value.str);
215 int cbret = callback(unit_name_s, cbarg);
216 free(unit_name_s);
217 if (cbret != 0) {
218 goto cleanup;
219 }
220 }
221 while (dbus_message_iter_next(&unit_iter));
222
223 dbus_message_unref(msg); msg = NULL;
224
225 ret = 0;
226
227cleanup:
228 if (pending != NULL)
229 dbus_pending_call_unref(pending);
230
231 if (msg != NULL)
232 dbus_message_unref(msg);
233
234 return ret;
235}
236
237static char *dbus_value_to_string(DBusMessageIter *iter)
238{
239 const int arg_type = dbus_message_iter_get_arg_type(iter);
240 if (dbus_type_is_basic(arg_type)) {
241 _DBusBasicValue value;
242 dbus_message_iter_get_basic(iter, &value);
243
244 switch (arg_type)
245 {
246 case DBUS_TYPE_BYTE:
247 return oscap_sprintf("%c", value.byt);
248
249 case DBUS_TYPE_BOOLEAN:
250 return oscap_strdup(value.bool_val ? "true" : "false");
251
252 case DBUS_TYPE_INT16:
253 return oscap_sprintf("%i", value.i16);
254
255 case DBUS_TYPE_UINT16:
256 return oscap_sprintf("%u", value.u16);
257
258 case DBUS_TYPE_INT32:
259 return oscap_sprintf("%i", value.i32);
260
261 case DBUS_TYPE_UINT32:
262 return oscap_sprintf("%u", value.u32);
263
264#ifdef DBUS_HAVE_INT64
265 case DBUS_TYPE_INT64:
266 return oscap_sprintf("%li", value.i64);
267
268 case DBUS_TYPE_UINT64:
269 return oscap_sprintf("%lu", value.u64);
270#endif
271
272 case DBUS_TYPE_DOUBLE:
273 return oscap_sprintf("%g", value.dbl);
274
275 case DBUS_TYPE_STRING:
276 case DBUS_TYPE_OBJECT_PATH:
277 case DBUS_TYPE_SIGNATURE:
278 return oscap_strdup(value.str);
279
280 // non-basic types
281 //case DBUS_TYPE_ARRAY:
282 //case DBUS_TYPE_STRUCT:
283 //case DBUS_TYPE_DICT_ENTRY:
284 //case DBUS_TYPE_VARIANT:
285
286 //case DBUS_TYPE_UNIX_FD:
287 // return oscap_sprintf("%i", value.fd);
288
289 default:
290 dD("Encountered unknown dbus basic type!");
291 return oscap_strdup("error, unknown basic type!");
292 }
293 }
294 else if (arg_type == DBUS_TYPE_ARRAY) {
295 DBusMessageIter array;
296 dbus_message_iter_recurse(iter, &array);
297
298 char *ret = NULL;
299 do {
300 char *element = dbus_value_to_string(&array);
301
302 if (element == NULL)
303 continue;
304
305 char *old_ret = ret;
306 if (old_ret == NULL)
307 ret = oscap_sprintf("%s", element);
308 else
309 ret = oscap_sprintf("%s, %s", old_ret, element);
310
311 free(old_ret);
312 free(element);
313 }
314 while (dbus_message_iter_next(&array));
315
316 return ret;
317 }/*
318 else if (arg_type == DBUS_TYPE_VARIANT) {
319 DBusMessageIter inner;
320 dbus_message_iter_recurse(iter, &inner);
321 return dbus_value_to_string(&inner);
322 }*/
323
324 return NULL;
325}
326
327static DBusConnection *connect_dbus()
328{
329 DBusConnection *conn = NULL;
330
331 DBusError err;
332 dbus_error_init(&err);
333
334 const char *prefix = getenv("OSCAP_PROBE_ROOT");
335 if (prefix != NULL) {
336 char dbus_address[PATH_MAX] = {0};
337 snprintf(dbus_address, PATH_MAX, "unix:path=%s/run/dbus/system_bus_socket", prefix);
338 setenv("DBUS_SYSTEM_BUS_ADDRESS", dbus_address, 0);
339 /* We won't overwrite DBUS_SYSTEM_BUS_ADDRESS so that
340 * user could have a way to define some non-standard system bus socket location */
341 }
342
343 conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
344 if (dbus_error_is_set(&err)) {
345 dD("Failed to get DBUS_BUS_SYSTEM connection - %s", err.message);
346 goto cleanup;
347 }
348 if (conn == NULL) {
349 dD("DBusConnection == NULL!");
350 goto cleanup;
351 }
352
353 dbus_bus_register(conn, &err);
354 if (dbus_error_is_set(&err)) {
355 dD("Failed to register on dbus - %s", err.message);
356 goto cleanup;
357 }
358
359cleanup:
360 dbus_error_free(&err);
361
362 return conn;
363}
364
365static void disconnect_dbus(DBusConnection *conn)
366{
367 // NOOP
368
369 // Connections retrieved via dbus_bus_get shall not be destroyed,
370 // these connections are shared.
371}
372
373#endif
oscap debug helpers private header
Definition: systemdshared.h:49
Definition: systemdshared.h:55
dbus_uint16_t u16
as int16
Definition: systemdshared.h:58
dbus_int16_t i16
as int16
Definition: systemdshared.h:57
double dbl
as double
Definition: systemdshared.h:67
_DBus8ByteStruct eight
as 8-byte struct
Definition: systemdshared.h:66
char * str
as char* (string, object path or signature)
Definition: systemdshared.h:69
int fd
as Unix file descriptor
Definition: systemdshared.h:70
dbus_uint32_t u32
as int32
Definition: systemdshared.h:60
dbus_bool_t bool_val
as boolean
Definition: systemdshared.h:61
unsigned char byt
as byte
Definition: systemdshared.h:68
dbus_int32_t i32
as int32
Definition: systemdshared.h:59