diff --git a/src/main.c b/src/main.c index dc354f7e..78d3aabd 100644 --- a/src/main.c +++ b/src/main.c @@ -505,6 +505,98 @@ np2srv_sm_oper_cb(sr_session_ctx_t *session, uint32_t UNUSED(sub_id), const char return rc; } +#ifdef NC_ENABLED_SSH_TLS + +/** + * @brief Callback for sending certificate expiration notifications generated by libnetconf2. + */ +static void +np2srv_cert_exp_notif_cb(const char *expiration_time, const char *xpath, void *user_data) +{ + sr_session_ctx_t *sr_sess = user_data; + const struct ly_ctx *ly_ctx = NULL; + int rc, stop_thread = 0; + struct lyd_node *ntf = NULL; + + ly_ctx = sr_acquire_context(np2srv.sr_conn); + if (!ly_ctx) { + ERR("Failed to acquire sysrepo context."); + stop_thread = 1; + goto cleanup; + } + + rc = lyd_new_path(NULL, ly_ctx, xpath, expiration_time, 0, &ntf); + if (rc) { + ERR("Failed to create certificate expiration notification data."); + stop_thread = 1; + goto cleanup; + } + + rc = sr_notif_send_tree(sr_sess, ntf, 0, 0); + if (rc) { + ERR("Failed to send certificate expiration notification."); + stop_thread = 1; + goto cleanup; + } + +cleanup: + lyd_free_tree(ntf); + if (ly_ctx) { + sr_release_context(np2srv.sr_conn); + } + if (stop_thread) { + nc_server_notif_cert_expiration_thread_stop(1); + } +} + +/** + * @brief Start the certificate expiration notification thread. + * + * The thread is started only if the 'certificate-expiration-notification' feature is enabled. + * + * @return 0 if the thread is successfully started or if the feature is disabled, -1 on error. + */ +static int +np2srv_start_cert_exp_notif_thread(void) +{ + int r, ret = 0; + const struct ly_ctx *ly_ctx; + const struct lys_module *mod; + + ly_ctx = sr_acquire_context(np2srv.sr_conn); + if (!ly_ctx) { + ERR("Failed to acquire SR connection context."); + return -1; + } + + mod = ly_ctx_get_module_implemented(ly_ctx, "ietf-crypto-types"); + if (!mod) { + ERR("Module \"ietf-crypto-types\" not implemented in sysrepo."); + ret = -1; + goto cleanup; + } + + /* check if the feature is enabled and if so, then start the thread */ + r = lys_feature_value(mod, "certificate-expiration-notification"); + if (r == LY_SUCCESS) { + if (nc_server_notif_cert_expiration_thread_start(np2srv_cert_exp_notif_cb, np2srv.sr_sess, NULL)) { + ERR("Failed to start certificate expiration notification thread."); + ret = -1; + goto cleanup; + } + } else if (r == LY_ENOTFOUND) { + ERR("Feature \"certificate-expiration-notification\" not found in module \"ietf-crypto-types\"."); + ret = -1; + goto cleanup; + } + +cleanup: + sr_release_context(np2srv.sr_conn); + return ret; +} + +#endif /* NC_ENABLED_SSH_TLS */ + /** * @brief Initialize the server, * @@ -562,6 +654,12 @@ server_init(void) ERR("Setting authorized_keys path format failed."); goto error; } + + /* start certificate expiration notification thread if the certificate-expiration-notification feature is enabled */ + if (np2srv_start_cert_exp_notif_thread()) { + ERR("Starting certificate expiration notification thread failed."); + goto error; + } #endif /* NC_ENABLED_SSH_TLS */ /* set capabilities for the NETCONF Notifications */