mirror of
https://github.com/systemd/systemd.git
synced 2024-12-22 17:35:35 +03:00
sd-varlink: add sd_varlink_server_set_info
Fixes https://github.com/systemd/systemd/issues/35508. As reported in the bug, the values were hardcoded for the systemd project. https://varlink.org/Service lists vendor, product, version, url, and interfaces as the mandatory parameters, so add an interface to set the first four. The last field is set automatically based on the registered interfaces as before. If the values are not filled in, we return empty strings. With NULL, 'varlinkctl info' would say: (string):1:25: Object field 'vendor' has wrong type null, expected string.
This commit is contained in:
parent
fbee22c237
commit
29f63c67b0
@ -102,6 +102,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||
/* Test one: write the data as method call to a server */
|
||||
assert_se(socketpair(AF_UNIX, SOCK_STREAM, 0, server_pair) >= 0);
|
||||
assert_se(sd_varlink_server_new(&s, 0) >= 0);
|
||||
assert_se(sd_varlink_server_set_info(s, "Vendor", "Product", "Version", "URL") >= 0);
|
||||
assert_se(sd_varlink_server_set_description(s, "myserver") >= 0);
|
||||
assert_se(sd_varlink_server_attach_event(s, e, 0) >= 0);
|
||||
assert_se(sd_varlink_server_add_connection(s, server_pair[0], NULL) >= 0);
|
||||
|
@ -1037,6 +1037,7 @@ global:
|
||||
sd_varlink_server_set_connections_max;
|
||||
sd_varlink_server_set_connections_per_uid_max;
|
||||
sd_varlink_server_set_description;
|
||||
sd_varlink_server_set_info;
|
||||
sd_varlink_server_set_exit_on_idle;
|
||||
sd_varlink_server_set_userdata;
|
||||
sd_varlink_server_shutdown;
|
||||
|
@ -31,7 +31,6 @@
|
||||
#include "varlink-internal.h"
|
||||
#include "varlink-io.systemd.h"
|
||||
#include "varlink-org.varlink.service.h"
|
||||
#include "version.h"
|
||||
|
||||
#define VARLINK_DEFAULT_CONNECTIONS_MAX 4096U
|
||||
#define VARLINK_DEFAULT_CONNECTIONS_PER_UID_MAX 1024U
|
||||
@ -1193,20 +1192,16 @@ static int generic_method_get_info(
|
||||
void *userdata) {
|
||||
|
||||
_cleanup_strv_free_ char **interfaces = NULL;
|
||||
_cleanup_free_ char *product = NULL;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->server);
|
||||
|
||||
if (sd_json_variant_elements(parameters) != 0)
|
||||
return sd_varlink_error_invalid_parameter(link, parameters);
|
||||
|
||||
product = strjoin("systemd (", program_invocation_short_name, ")");
|
||||
if (!product)
|
||||
return -ENOMEM;
|
||||
|
||||
sd_varlink_interface *interface;
|
||||
HASHMAP_FOREACH(interface, ASSERT_PTR(link->server)->interfaces) {
|
||||
HASHMAP_FOREACH(interface, link->server->interfaces) {
|
||||
r = strv_extend(&interfaces, interface->name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -1216,10 +1211,10 @@ static int generic_method_get_info(
|
||||
|
||||
return sd_varlink_replybo(
|
||||
link,
|
||||
SD_JSON_BUILD_PAIR_STRING("vendor", "The systemd Project"),
|
||||
SD_JSON_BUILD_PAIR_STRING("product", product),
|
||||
SD_JSON_BUILD_PAIR_STRING("version", PROJECT_VERSION_FULL " (" GIT_VERSION ")"),
|
||||
SD_JSON_BUILD_PAIR_STRING("url", "https://systemd.io/"),
|
||||
SD_JSON_BUILD_PAIR_STRING("vendor", strempty(link->server->vendor)),
|
||||
SD_JSON_BUILD_PAIR_STRING("product", strempty(link->server->product)),
|
||||
SD_JSON_BUILD_PAIR_STRING("version", strempty(link->server->version)),
|
||||
SD_JSON_BUILD_PAIR_STRING("url", strempty(link->server->url)),
|
||||
SD_JSON_BUILD_PAIR_STRV("interfaces", interfaces));
|
||||
}
|
||||
|
||||
@ -3262,12 +3257,41 @@ static sd_varlink_server* varlink_server_destroy(sd_varlink_server *s) {
|
||||
sd_event_unref(s->event);
|
||||
|
||||
free(s->description);
|
||||
free(s->vendor);
|
||||
free(s->product);
|
||||
free(s->version);
|
||||
free(s->url);
|
||||
|
||||
return mfree(s);
|
||||
}
|
||||
|
||||
DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(sd_varlink_server, sd_varlink_server, varlink_server_destroy);
|
||||
|
||||
_public_ int sd_varlink_server_set_info(
|
||||
sd_varlink_server *s,
|
||||
const char *vendor,
|
||||
const char *product,
|
||||
const char *version,
|
||||
const char *url) {
|
||||
|
||||
assert_return(s, -EINVAL);
|
||||
|
||||
_cleanup_free_ char
|
||||
*a = vendor ? strdup(vendor) : NULL,
|
||||
*b = product ? strdup(product) : NULL,
|
||||
*c = version ? strdup(version) : NULL,
|
||||
*d = url ? strdup(url) : NULL;
|
||||
if ((vendor && !a) || (product && !b) || (version && !c) || (url && !d))
|
||||
return log_oom_debug();
|
||||
|
||||
free_and_replace(s->vendor, a);
|
||||
free_and_replace(s->product, b);
|
||||
free_and_replace(s->version, c);
|
||||
free_and_replace(s->url, d);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int validate_connection(sd_varlink_server *server, const struct ucred *ucred) {
|
||||
int allowed = -1;
|
||||
|
||||
|
@ -222,7 +222,12 @@ struct sd_varlink_server {
|
||||
Hashmap *by_uid; /* UID_TO_PTR(uid) → UINT_TO_PTR(n_connections) */
|
||||
|
||||
void *userdata;
|
||||
|
||||
char *description;
|
||||
char *vendor;
|
||||
char *product;
|
||||
char *version;
|
||||
char *url;
|
||||
|
||||
unsigned connections_max;
|
||||
unsigned connections_per_uid_max;
|
||||
|
@ -219,6 +219,13 @@ int sd_varlink_server_new(sd_varlink_server **ret, sd_varlink_server_flags_t fla
|
||||
sd_varlink_server* sd_varlink_server_ref(sd_varlink_server *s);
|
||||
sd_varlink_server* sd_varlink_server_unref(sd_varlink_server *s);
|
||||
|
||||
int sd_varlink_server_set_info(
|
||||
sd_varlink_server *s,
|
||||
const char *vendor,
|
||||
const char *product,
|
||||
const char *version,
|
||||
const char *url);
|
||||
|
||||
/* Add addresses or fds to listen on */
|
||||
int sd_varlink_server_listen_address(sd_varlink_server *s, const char *address, mode_t mode);
|
||||
int sd_varlink_server_listen_fd(sd_varlink_server *s, int fd);
|
||||
|
Loading…
Reference in New Issue
Block a user