From cb633a78d6d0a992cb042aec9db5dacc183ff57b Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Sun, 2 Nov 2025 21:02:06 +0100 Subject: [PATCH] confd: minor coding style fixes and refactoring Collapse, simplify, and break up ietf_keystore_change() into multiple functions. Signed-off-by: Joachim Wiberg --- src/confd/src/core.c | 21 ++-- src/confd/src/core.h | 1 - src/confd/src/ietf-keystore.c | 219 ++++++++++++++++++---------------- 3 files changed, 132 insertions(+), 109 deletions(-) diff --git a/src/confd/src/core.c b/src/confd/src/core.c index 415114d0..9b29b488 100644 --- a/src/confd/src/core.c +++ b/src/confd/src/core.c @@ -8,8 +8,8 @@ struct confd confd; -int core_startup_save(sr_session_ctx_t *session, uint32_t sub_id, const char *module, - const char *xpath, sr_event_t event, unsigned request_id, void *priv) +static int core_startup_save(sr_session_ctx_t *session, uint32_t sub_id, const char *module, + const char *xpath, sr_event_t event, unsigned request_id, void *priv) { sr_event_t last_event = -1; static unsigned int last_request = -1; @@ -260,16 +260,21 @@ static int change_cb(sr_session_ctx_t *session, uint32_t sub_id, const char *mod AUDIT("The new configuration has been applied."); } + free_diff: - lyd_free_tree(diff); - return rc; + lyd_free_tree(diff); + return rc; } -static inline int subscribe_module(char *model, struct confd *confd, int flags) { - return sr_module_change_subscribe(confd->session, model, "//.", change_cb, confd, - CB_PRIO_PRIMARY, SR_SUBSCR_CHANGE_ALL_MODULES | SR_SUBSCR_DEFAULT | flags, &confd->sub) && +static inline int subscribe_module(char *model, struct confd *confd, int flags) +{ + ERROR("core: subscribing to models"); + return sr_module_change_subscribe(confd->session, model, "//.", change_cb, confd, + CB_PRIO_PRIMARY, SR_SUBSCR_CHANGE_ALL_MODULES | + SR_SUBSCR_DEFAULT | flags, &confd->sub) && sr_module_change_subscribe(confd->startup, model, "//.", core_startup_save, NULL, - CB_PRIO_PASSIVE, SR_SUBSCR_PASSIVE | SR_SUBSCR_CHANGE_ALL_MODULES, &confd->sub); + CB_PRIO_PASSIVE, SR_SUBSCR_CHANGE_ALL_MODULES | + SR_SUBSCR_PASSIVE, &confd->sub); } int sr_plugin_init_cb(sr_session_ctx_t *session, void **priv) diff --git a/src/confd/src/core.h b/src/confd/src/core.h index 0317f83e..d7c2f2e0 100644 --- a/src/confd/src/core.h +++ b/src/confd/src/core.h @@ -135,7 +135,6 @@ struct confd { struct dagger netdag; }; -int core_startup_save (sr_session_ctx_t *, uint32_t, const char *, const char *, sr_event_t, unsigned, void *); static inline int register_change(sr_session_ctx_t *session, const char *module, const char *xpath, int flags, sr_module_change_cb cb, void *arg, sr_subscription_ctx_t **sub) diff --git a/src/confd/src/ietf-keystore.c b/src/confd/src/ietf-keystore.c index a87303ee..fa1d786f 100644 --- a/src/confd/src/ietf-keystore.c +++ b/src/confd/src/ietf-keystore.c @@ -51,89 +51,122 @@ static char *filerd(const char *fn, size_t len) return buf; } -int ietf_keystore_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd) +static int gen_hostkey(const char *name, struct lyd_node *change) +{ + const char *private_key, *public_key; + int rc = SR_ERR_OK; + + private_key = lydx_get_cattr(change, "cleartext-private-key"); + public_key = lydx_get_cattr(change, "public-key"); + + if (mkdir(SSH_HOSTKEYS_NEXT, 0600) && (errno != EEXIST)) { + ERRNO("Failed creating %s", SSH_HOSTKEYS_NEXT); + rc = SR_ERR_INTERNAL; + } + + if (systemf("/usr/libexec/infix/mksshkey %s %s %s %s", name, SSH_HOSTKEYS_NEXT, public_key, private_key)) + rc = SR_ERR_INTERNAL; + + return rc; +} + +static int keystore_update(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff) +{ + const char *xpath = "/ietf-keystore:keystore/asymmetric-keys/asymmetric-key"; + sr_val_t *list = NULL; + size_t count = 0; + int rc; + + rc = sr_get_items(session, xpath, 0, 0, &list, &count); + if (rc != SR_ERR_OK) { + ERROR("Cannot find any asymmetric keys in configuration"); + return 0; + } + + for (size_t i = 0; i < count; i++) { + char *name = srx_get_str(session, "%s/name", list[i].xpath); + char *public_key_format, *private_key_format; + char *pub_key = NULL, *priv_key = NULL; + sr_val_t *entry = &list[i]; + + if (srx_isset(session, "%s/cleartext-private-key", entry->xpath) || + srx_isset(session, "%s/public-key", entry->xpath)) + continue; + + public_key_format = srx_get_str(session, "%s/public-key-format", entry->xpath); + if (!public_key_format) + continue; + + private_key_format = srx_get_str(session, "%s/private-key-format", entry->xpath); + if (!private_key_format) { + free(public_key_format); + continue; + } + + if (strcmp(private_key_format, "infix-crypto-types:rsa-private-key-format") || + strcmp(public_key_format, "infix-crypto-types:ssh-public-key-format")) + continue; + + NOTE("SSH key (%s) does not exist, generating...", name); + if (systemf("/usr/libexec/infix/mkkeys %s %s", SSH_PRIVATE_KEY, SSH_PUBLIC_KEY)) { + ERROR("Failed generating SSH keys for %s", name); + goto next; + } + + priv_key = filerd(SSH_PRIVATE_KEY, filesz(SSH_PRIVATE_KEY)); + if (!priv_key) + goto next; + + pub_key = filerd(SSH_PUBLIC_KEY, filesz(SSH_PUBLIC_KEY)); + if (!pub_key) + goto next; + + rc = srx_set_str(session, priv_key, 0, "%s/cleartext-private-key", entry->xpath); + if (rc) { + ERROR("Failed setting private key for %s... rc: %d", name, rc); + goto next; + } + + rc = srx_set_str(session, pub_key, 0, "%s/public-key", entry->xpath); + if (rc != SR_ERR_OK) { + ERROR("Failed setting public key for %s... rc: %d", name, rc); + goto next; + } + next: + if (erase(SSH_PRIVATE_KEY)) + ERRNO("Failed removing SSH server private key"); + if (erase(SSH_PUBLIC_KEY)) + ERRNO("Failed removing SSH server public key"); + + if (priv_key) + free(priv_key); + + if (pub_key) + free(pub_key); + + free(name); + free(public_key_format); + free(private_key_format); + } + + if (list) + sr_free_values(list, count); + + return 0; +} + +int ietf_keystore_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, + sr_event_t event, struct confd *confd) { struct lyd_node *changes, *change; - sr_val_t *list = NULL; int rc = SR_ERR_OK; - size_t count = 0; + if (diff && !lydx_find_xpathf(diff, XPATH_KEYSTORE_)) return SR_ERR_OK; switch (event) { case SR_EV_UPDATE: - rc = sr_get_items(session, "/ietf-keystore:keystore/asymmetric-keys/asymmetric-key", 0, 0, &list, &count); - if (rc != SR_ERR_OK) { - ERROR("Cannot find any asymmetric keys in configuration"); - return 0; - } - - - for (size_t i = 0; i < count; ++i) { - sr_val_t *entry = &list[i]; - - if (!srx_isset(session, "%s/cleartext-private-key", entry->xpath) && !srx_isset(session, "%s/public-key", entry->xpath)) { - char *private_key_format, *public_key_format; - - public_key_format = srx_get_str(session, "%s/public-key-format", entry->xpath); - if (!public_key_format) - continue; - private_key_format = srx_get_str(session, "%s/private-key-format", entry->xpath); - if (!private_key_format) { - free(public_key_format); - continue; - } - - if (!strcmp(private_key_format, "infix-crypto-types:rsa-private-key-format") && - !strcmp(public_key_format, "infix-crypto-types:ssh-public-key-format")) { - char *pub_key = NULL, *priv_key = NULL, *name; - - name = srx_get_str(session, "%s/name", entry->xpath); - NOTE("SSH key (%s) does not exist, generating...", name); - if (systemf("/usr/libexec/infix/mkkeys %s %s", SSH_PRIVATE_KEY, SSH_PUBLIC_KEY)) { - ERROR("Failed to generate SSH keys for %s", name); - goto next; - } - - priv_key = filerd(SSH_PRIVATE_KEY, filesz(SSH_PRIVATE_KEY)); - if (!priv_key) - goto next; - - pub_key = filerd(SSH_PUBLIC_KEY, filesz(SSH_PUBLIC_KEY)); - if (!pub_key) - goto next; - - rc = srx_set_str(session, priv_key, 0, "%s/cleartext-private-key", entry->xpath); - if (rc) { - ERROR("Failed setting private key for %s... rc: %d", name, rc); - goto next; - } - rc = srx_set_str(session, pub_key, 0, "%s/public-key", entry->xpath); - if (rc != SR_ERR_OK) { - ERROR("Failed setting public key for %s... rc: %d", name, rc); - goto next; - } - next: - if (erase(SSH_PRIVATE_KEY)) - ERRNO("Failed removing SSH server private key"); - if (erase(SSH_PUBLIC_KEY)) - ERRNO("Failed removing SSH server public key"); - - if (priv_key) - free(priv_key); - - if (pub_key) - free(pub_key); - - free(name); - } - free(public_key_format); - free(private_key_format); - } - } - if (list) - sr_free_values(list, count); - + rc = keystore_update(session, config, diff); break; case SR_EV_CHANGE: case SR_EV_ENABLED: @@ -142,49 +175,35 @@ int ietf_keystore_change(sr_session_ctx_t *session, struct lyd_node *config, str rmrf(SSH_HOSTKEYS_NEXT); return SR_ERR_OK; case SR_EV_DONE: - if(fexist(SSH_HOSTKEYS_NEXT)) { - if(rmrf(SSH_HOSTKEYS)) { + if (fexist(SSH_HOSTKEYS_NEXT)) { + if (rmrf(SSH_HOSTKEYS)) ERRNO("Failed to remove old SSH hostkeys: %d", errno); - } - if (rename(SSH_HOSTKEYS_NEXT, SSH_HOSTKEYS)) ERRNO("Failed switching to new %s", SSH_HOSTKEYS); } return SR_ERR_OK; - default: return SR_ERR_OK; } changes = lydx_get_descendant(config, "keystore", "asymmetric-keys", "asymmetric-key", NULL); - LYX_LIST_FOR_EACH(changes, change, "asymmetric-key") { - const char *name, *private_key_type, *public_key_type; - const char *private_key, *public_key; + const char *name = lydx_get_cattr(change, "name"); + const char *type; - name = lydx_get_cattr(change, "name"); - private_key_type = lydx_get_cattr(change, "private-key-format"); - public_key_type = lydx_get_cattr(change, "public-key-format"); - - if (strcmp(private_key_type, "infix-crypto-types:rsa-private-key-format")) { - INFO("Private key %s is not of SSH type", name); + type = lydx_get_cattr(change, "private-key-format"); + if (strcmp(type, "infix-crypto-types:rsa-private-key-format")) { + INFO("Private key %s is not of SSH type (%s)", name, type); continue; } - if (strcmp(public_key_type, "infix-crypto-types:ssh-public-key-format")) { - INFO("Public key %s is not of SSH type", name); + type = lydx_get_cattr(change, "public-key-format"); + if (strcmp(type, "infix-crypto-types:ssh-public-key-format")) { + INFO("Public key %s is not of SSH type (%s)", name, type); continue; } - private_key = lydx_get_cattr(change, "cleartext-private-key"); - public_key = lydx_get_cattr(change, "public-key"); - if (mkdir(SSH_HOSTKEYS_NEXT, 0600) && (errno != EEXIST)) { - ERRNO("Failed creating %s", SSH_HOSTKEYS_NEXT); - rc = SR_ERR_INTERNAL; - } - - if(systemf("/usr/libexec/infix/mksshkey %s %s %s %s", name, SSH_HOSTKEYS_NEXT, public_key, private_key)) - rc = SR_ERR_INTERNAL; + gen_hostkey(name, change); } return rc;