diff --git a/doc/libnetconf.doc b/doc/libnetconf.doc index b58f96fc..20be760f 100644 --- a/doc/libnetconf.doc +++ b/doc/libnetconf.doc @@ -18,7 +18,7 @@ * - Creating, sending, receiving, and replying to RPCs ([RFC 4741](https://tools.ietf.org/html/rfc4741), * [RFC 6241](https://tools.ietf.org/html/rfc6241)). * - Creating, sending and receiving NETCONF Event Notifications ([RFC 5277](https://tools.ietf.org/html/rfc5277)). - * - Configuring the NETCONF server based on the [ietf-netconf-server](https://datatracker.ietf.org/doc/html/draft-ietf-netconf-netconf-client-server-29) YANG module. + * - Configuring the NETCONF server based on the [ietf-netconf-server](https://datatracker.ietf.org/doc/html/draft-ietf-netconf-netconf-client-server-29) YANG module * * @section about-license License * @@ -219,7 +219,7 @@ * If you authenticated the connection using some tunneling software, you * can pass its file descriptors to _libnetconf2_ using ::nc_connect_inout(), * which will continue to establish a full NETCONF session. To connect locally - * on a UNIX socket avoiding all cryptography use ::nc_connect_unix(). + * on a UNIX socket avoiding all cryptography use ::nc_connect_unix(). * * Funtions List * ------------- @@ -327,28 +327,24 @@ * data - *YANG data* and *YANG diff*. * * YANG data - * --------- - * + * == * Configuring the server using YANG data simplifies the management of network services. * With YANG data, you build a structured configuration tree and apply it as a whole. * This approach is user-friendly, allowing you to modify the configuration by adding or deleting nodes, * and then deploying the updated configuration tree in its entirety, providing a way to manage your server's settings. * The *libnetconf2* library exports API functions that can help you with creation or deletion of the *YANG* data. - * Using this approach requires you to have access to the current configuration whenever you want to make any changes. * * YANG diff - * --------- - * + * == * YANG diff, enriched with operation attributes, offers advanced configuration control. * It empowers the user to make precise changes within the configuration tree, * enabling operations like specific node deletions, additions, and modifications. * On the other hand, unlike YANG data, YANG diff represents only a subtree of the * changes expecting the whole configuration to be managed externally. - * For example this approach is used by the tool [sysrepo](https://www.sysrepo.org/). + * For example this is done by the tool [sysrepo](https://www.sysrepo.org/). * * Usage - * ----- - * + * == * To be able to configure the server, the required models first need to be implemented. * To do this, see ::nc_server_config_load_modules(). * Not all of the *ietf-netconf-server* (and all of its associated modules) features are enabled. @@ -378,7 +374,6 @@ * - ::nc_server_config_add_address_port() * - ::nc_server_config_add_unix_socket() * - ::nc_server_config_del_endpt() - * * - ::nc_server_config_add_keystore_asym_key() * - ::nc_server_config_del_keystore_asym_key() * - ::nc_server_config_add_keystore_cert() @@ -399,8 +394,7 @@ * Another option for authorized clients is to reference another endpoint's clients, however be careful not to create a cyclic reference * (see ::nc_server_config_add_ssh_endpoint_client_ref()). An authorized client MUST authenticate to all of it's configured authentication methods. * - * There are also some other optional settings. Like setting the authentication attempts and timeout of an authorized client, or - * setting the encryption/key exchange/mac/public key algorithms, etc. + * There are also some other optional settings. * * Functions List * -------------- @@ -409,6 +403,8 @@ * * - ::nc_server_config_add_ssh_hostkey() * - ::nc_server_config_del_ssh_hostkey() + * - ::nc_server_config_add_ssh_keystore_ref() + * - ::nc_server_config_del_ssh_keystore_ref() * - ::nc_server_config_add_ssh_auth_attempts() * - ::nc_server_config_add_ssh_auth_timeout() * @@ -416,12 +412,26 @@ * - ::nc_server_config_del_ssh_user_pubkey() * - ::nc_server_config_add_ssh_user_password() * - ::nc_server_config_del_ssh_user_password() + * - ::nc_server_config_add_ssh_user_none() + * - ::nc_server_config_del_ssh_user_none() * - ::nc_server_config_add_ssh_user_interactive() * - ::nc_server_config_del_ssh_user_interactive() * - ::nc_server_config_del_ssh_user() + * - ::nc_server_config_add_ssh_truststore_ref() + * - ::nc_server_config_del_ssh_truststore_ref() * - ::nc_server_config_add_ssh_endpoint_client_ref() * - ::nc_server_config_del_ssh_endpoint_client_ref() * + * - ::nc_server_config_add_ssh_host_key_algs() + * - ::nc_server_config_del_ssh_host_key_alg() + * - ::nc_server_config_add_ssh_key_exchange_algs() + * - ::nc_server_config_del_ssh_key_exchange_alg() + * - ::nc_server_config_add_ssh_encryption_algs() + * - ::nc_server_config_del_ssh_encryption_alg() + * - ::nc_server_config_add_ssh_mac_algs() + * - ::nc_server_config_del_ssh_mac_alg() + * + * * TLS * === * @@ -430,7 +440,7 @@ * options that TLS uses to derive usernames from client certificates. * * If you wish to listen on a TLS endpoint, you need to configure the endpoint's - * server certificate (see ::nc_server_config_add_tls_server_cert()). + * server certificate (see ::nc_server_config_add_tls_server_certificate()). * * To accept client certificates, they must first be considered trusted. * For each TLS endpoint you may configure two types of client certificates. @@ -446,25 +456,44 @@ * _cert-to-name_ entry. * * There are some further options. For example you can configure the TLS - * version and ciphers to be used or you can even use a Certificate Revocation List. + * version and ciphers to be used. You may also choose to use a Certificate + * Revoke List. There are three options, ::nc_server_config_add_tls_crl_path() + * attempts to get the list of revoked certificates from a file. ::nc_server_config_add_tls_crl_url() + * attempts to download the list from the given URL. Lastly, ::nc_server_config_add_tls_crl_cert_ext() + * attempts to download the CRLs from URLs specified in the extension fields of the configured certificates. * * Functions List * -------------- * * Available in __nc_server.h__. * - * - ::nc_server_config_add_tls_server_cert() - * - ::nc_server_config_del_tls_server_cert() - * - * - ::nc_server_config_add_tls_client_cert() - * - ::nc_server_config_del_tls_client_cert() - * - ::nc_server_config_add_tls_ca_cert() - * - ::nc_server_config_del_tls_ca_cert() + * - ::nc_server_config_add_tls_server_certificate() + * - ::nc_server_config_del_tls_server_certificate() + * - ::nc_server_config_add_tls_keystore_ref() + * - ::nc_server_config_del_tls_keystore_ref() + * + * - ::nc_server_config_add_tls_client_certificate() + * - ::nc_server_config_del_tls_client_certificate() + * - ::nc_server_config_add_tls_client_cert_truststore_ref() + * - ::nc_server_config_del_tls_client_cert_truststore_ref() + * - ::nc_server_config_add_tls_client_ca() + * - ::nc_server_config_del_tls_client_ca() + * - ::nc_server_config_add_tls_client_ca_truststore_ref() + * - ::nc_server_config_del_tls_client_ca_truststore_ref() * - ::nc_server_config_add_tls_endpoint_client_ref() * - ::nc_server_config_del_tls_endpoint_client_ref() * - ::nc_server_config_add_tls_ctn() * - ::nc_server_config_del_tls_ctn() * + * - ::nc_server_config_add_tls_version() + * - ::nc_server_config_del_tls_version() + * - ::nc_server_config_add_tls_ciphers() + * - ::nc_server_config_del_tls_cipher() + * - ::nc_server_config_add_tls_crl_path() + * - ::nc_server_config_add_tls_crl_url() + * - ::nc_server_config_add_tls_crl_cert_ext() + * - ::nc_server_config_del_tls_crl() + * * FD * == * @@ -513,24 +542,53 @@ * * - ::nc_server_config_add_ch_ssh_hostkey() * - ::nc_server_config_del_ch_ssh_hostkey() + * - ::nc_server_config_add_ch_ssh_keystore_ref() + * - ::nc_server_config_del_ch_ssh_keystore_ref() * - ::nc_server_config_add_ch_ssh_auth_attempts() * - ::nc_server_config_add_ch_ssh_auth_timeout() * - ::nc_server_config_add_ch_ssh_user_pubkey() * - ::nc_server_config_del_ch_ssh_user_pubkey() * - ::nc_server_config_add_ch_ssh_user_password() * - ::nc_server_config_del_ch_ssh_user_password() + * - ::nc_server_config_add_ch_ssh_user_none() + * - ::nc_server_config_del_ch_ssh_user_none() * - ::nc_server_config_add_ch_ssh_user_interactive() * - ::nc_server_config_del_ch_ssh_user_interactive() * - ::nc_server_config_del_ch_ssh_user() - * - * - ::nc_server_config_add_ch_tls_server_cert() - * - ::nc_server_config_del_ch_tls_server_cert() - * - ::nc_server_config_add_ch_tls_client_cert() - * - ::nc_server_config_del_ch_tls_client_cert() - * - ::nc_server_config_add_ch_tls_ca_cert() - * - ::nc_server_config_del_ch_tls_ca_cert() + * - ::nc_server_config_add_ch_ssh_truststore_ref() + * - ::nc_server_config_del_ch_ssh_truststore_ref() + * - ::nc_server_config_add_ch_ssh_host_key_algs() + * - ::nc_server_config_del_ch_ssh_host_key_alg() + * - ::nc_server_config_add_ch_ssh_key_exchange_algs() + * - ::nc_server_config_del_ch_ssh_key_exchange_alg() + * - ::nc_server_config_add_ch_ssh_encryption_algs() + * - ::nc_server_config_del_ch_ssh_encryption_alg() + * - ::nc_server_config_add_ch_ssh_mac_algs() + * - ::nc_server_config_del_ch_ssh_mac_alg() + * + * - ::nc_server_config_add_ch_tls_server_certificate() + * - ::nc_server_config_del_ch_tls_server_certificate() + * - ::nc_server_config_add_ch_tls_keystore_ref() + * - ::nc_server_config_del_ch_tls_keystore_ref() + * - ::nc_server_config_add_ch_tls_client_certificate() + * - ::nc_server_config_del_ch_tls_client_certificate() + * - ::nc_server_config_add_ch_tls_client_cert_truststore_ref() + * - ::nc_server_config_del_ch_tls_client_cert_truststore_ref() + * - ::nc_server_config_add_ch_tls_client_ca() + * - ::nc_server_config_del_ch_tls_client_ca() + * - ::nc_server_config_add_ch_tls_client_ca_truststore_ref() + * - ::nc_server_config_del_ch_tls_client_ca_truststore_ref() * - ::nc_server_config_add_ch_tls_ctn() * - ::nc_server_config_del_ch_tls_ctn() + * - ::nc_server_config_add_ch_tls_version() + * - ::nc_server_config_del_ch_tls_version() + * - ::nc_server_config_add_ch_tls_ciphers() + * - ::nc_server_config_del_ch_tls_cipher() + * - ::nc_server_config_add_ch_tls_crl_path() + * - ::nc_server_config_add_ch_tls_crl_url() + * - ::nc_server_config_add_ch_tls_crl_cert_ext() + * - ::nc_server_config_del_ch_tls_crl() + * * * Connecting And Cleanup * ====================== @@ -654,7 +712,7 @@ * To free up some resources, it is possible to adjust the maximum idle period * of a session before it is disconnected. In _Call Home_, for both a persistent * and periodic connection can this idle timeout be specified separately for each - * client by configuring the server. Unlike other timeouts, the idle timeout + * client using corresponding functions. Unlike other timeouts, the idle timeout * can only be set via applying configuration data. * * Lastly, SSH user authentication timeout can be also modified. It is the time diff --git a/src/server_config.h b/src/server_config.h index e38c086c..d1480760 100644 --- a/src/server_config.h +++ b/src/server_config.h @@ -20,6 +20,7 @@ extern "C" { #endif +#include #include #include @@ -212,7 +213,6 @@ int nc_server_config_del_keystore_cert(const char *asym_key_name, const char *ce * @brief Creates new YANG data nodes for a public key in the truststore. * * @param[in] ctx libyang context. - * @param[in] ti Transport for which this key will be used, to be generated correctly. * @param[in] pub_bag_name Arbitrary identifier of the public key bag. * This name is used to reference the public keys in the bag. * If a public key bag with this name already exists, its contents will be changed. @@ -223,8 +223,8 @@ int nc_server_config_del_keystore_cert(const char *asym_key_name, const char *ce * Otherwise the new YANG data will be added to the previous data and may override it. * @return 0 on success, non-zero otherwise. */ -int nc_server_config_add_truststore_pubkey(const struct ly_ctx *ctx, NC_TRANSPORT_IMPL ti, - const char *pub_bag_name, const char *pubkey_name, const char *pubkey_path, struct lyd_node **config); +int nc_server_config_add_truststore_pubkey(const struct ly_ctx *ctx, const char *pub_bag_name, const char *pubkey_name, + const char *pubkey_path, struct lyd_node **config); /** * @brief Deletes a truststore's public key from the YANG data. @@ -310,6 +310,35 @@ int nc_server_config_add_ssh_hostkey(const struct ly_ctx *ctx, const char *endpt int nc_server_config_del_ssh_hostkey(const struct ly_ctx *ctx, const char *endpt_name, const char *hostkey_name, struct lyd_node **config); +/** + * @brief Creates new YANG data nodes for a reference to an asymmetric key located in the keystore. + * + * This asymmetric key pair will be used as the SSH hostkey. + * + * @param[in] ctx libyang context. + * @param[in] endpt_name Arbitrary identifier of an endpoint. + * If an endpoint with this identifier already exists, its contents will be changed. + * @param[in] hostkey_name Arbitrary identifier of the endpoint's hostkey. + * If an endpoint's hostkey with this identifier already exists, its contents will be changed. + * @param[in] keystore_reference Name of the asymmetric key pair to be referenced and used as a hostkey. + * @param[in,out] config Configuration YANG data tree. If *config is NULL, it will be created. + * Otherwise the new YANG data will be added to the previous data and may override it. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_add_ssh_keystore_ref(const struct ly_ctx *ctx, const char *endpt_name, const char *hostkey_name, + const char *keystore_reference, struct lyd_node **config); + +/** + * @brief Deletes a keystore reference from the YANG data. + * + * @param[in] endpt_name Identifier of an existing endpoint. + * @param[in] hostkey_name Identifier of an existing hostkey on the given endpoint. + * @param[in,out] config Configuration YANG data tree. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_del_ssh_keystore_ref(const char *endpt_name, const char *hostkey_name, + struct lyd_node **config); + /** * @brief Creates new YANG configuration data nodes for the maximum amount of failed SSH authentication attempts. * @@ -398,6 +427,32 @@ int nc_server_config_add_ssh_user_password(const struct ly_ctx *ctx, const char int nc_server_config_del_ssh_user_password(const char *endpt_name, const char *user_name, struct lyd_node **config); +/** + * @brief Creates new YANG configuration data nodes for an SSH user's none authentication method. + * + * @param[in] ctx libyang context. + * @param[in] endpt_name Arbitrary identifier of the endpoint. + * If an endpoint with this identifier already exists, its user might be changed. + * @param[in] user_name Arbitrary identifier of the user. + * If an user with this identifier already exists, its contents will be changed. + * @param[in,out] config Configuration YANG data tree. If *config is NULL, it will be created. + * Otherwise the new YANG data will be added to the previous data and may override it. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_add_ssh_user_none(const struct ly_ctx *ctx, const char *endpt_name, + const char *user_name, struct lyd_node **config); + +/** + * @brief Deletes an SSH user's none authentication method from the YANG data. + * + * @param[in] endpt_name Identifier of an existing endpoint. + * @param[in] user_name Identifier of an existing user on the given endpoint. + * @param[in,out] config Modified configuration YANG data tree. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_del_ssh_user_none(const char *endpt_name, const char *user_name, + struct lyd_node **config); + /** * @brief Creates new YANG configuration data nodes for an SSH user's keyboard interactive authentication method. * @@ -440,6 +495,35 @@ int nc_server_config_del_ssh_user_interactive(const char *endpt_name, const char int nc_server_config_del_ssh_user(const char *endpt_name, const char *user_name, struct lyd_node **config); +/** + * @brief Creates new YANG data nodes for a reference to a public key bag located in the truststore. + * + * The public key's located in the bag will be used for client authentication. + * + * @param[in] ctx libyang context. + * @param[in] endpt_name Arbitrary identifier of an endpoint. + * If an endpoint with this identifier already exists, its contents will be changed. + * @param[in] user_name Arbitrary identifier of the endpoint's user. + * If an endpoint's user with this identifier already exists, its contents will be changed. + * @param[in] truststore_reference Name of the public key bag to be referenced and used for authentication. + * @param[in,out] config Configuration YANG data tree. If *config is NULL, it will be created. + * Otherwise the new YANG data will be added to the previous data and may override it. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_add_ssh_truststore_ref(const struct ly_ctx *ctx, const char *endpt_name, const char *user_name, + const char *truststore_reference, struct lyd_node **config); + +/** + * @brief Deletes a truststore reference from the YANG data. + * + * @param[in] endpt_name Identifier of an existing endpoint. + * @param[in] user_name Identifier of an user on the given endpoint whose truststore reference will be deleted. + * @param[in,out] config Modified configuration YANG data tree. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_del_ssh_truststore_ref(const char *endpt_name, const char *user_name, + struct lyd_node **config); + /** * @brief Creates new YANG configuration data nodes, which will be a reference to another SSH endpoint's users. * @@ -467,6 +551,122 @@ int nc_server_config_add_ssh_endpoint_client_ref(const struct ly_ctx *ctx, const */ int nc_server_config_del_ssh_endpoint_client_ref(const char *endpt_name, struct lyd_node **config); +/** + * @brief Creates new YANG configuration data nodes for host-key algorithms replacing any previous ones. + * + * Supported algorithms are: ssh-ed25519, ecdsa-sha2-nistp256, ecdsa-sha2-nistp384, ecdsa-sha2-nistp521, + * rsa-sha2-512, rsa-sha2-256, ssh-rsa and ssh-dss. + * + * @param[in] ctx libyang context + * @param[in] endpt_name Arbitrary identifier of the endpoint. + * If an endpoint with this identifier already exists, its host-key algorithms will be replaced. + * @param[in,out] config Configuration YANG data tree. If *config is NULL, it will be created. + * Otherwise the new YANG data will be added to the previous data and may override it. + * @param[in] alg_count Number of following algorithms. + * @param[in] ... String literals of host-key algorithms in a decreasing order of preference. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_add_ssh_host_key_algs(const struct ly_ctx *ctx, const char *endpt_name, + struct lyd_node **config, int alg_count, ...); + +/** + * @brief Deletes a hostkey algorithm from the YANG data. + * + * @param[in] endpt_name Identifier of an existing endpoint. + * @param[in] alg Optional algorithm to be deleted. + * If NULL, all of the hostkey algorithms on this endpoint will be deleted. + * @param[in,out] config Modified configuration YANG data tree. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_del_ssh_host_key_alg(const char *endpt_name, const char *alg, struct lyd_node **config); + +/** + * @brief Creates new YANG configuration data nodes for key exchange algorithms replacing any previous ones. + * + * Supported algorithms are: diffie-hellman-group-exchange-sha1, curve25519-sha256, ecdh-sha2-nistp256, + * ecdh-sha2-nistp384, ecdh-sha2-nistp521, diffie-hellman-group18-sha512, diffie-hellman-group16-sha512, + * diffie-hellman-group-exchange-sha256 and diffie-hellman-group14-sha256. + * + * @param[in] ctx libyang context + * @param[in] endpt_name Arbitrary identifier of the endpoint. + * If an endpoint with this identifier already exists, its key exchange algorithms will be replaced. + * @param[in,out] config Configuration YANG data tree. If *config is NULL, it will be created. + * Otherwise the new YANG data will be added to the previous data and may override it. + * @param[in] alg_count Number of following algorithms. + * @param[in] ... String literals of key exchange algorithms in a decreasing order of preference. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_add_ssh_key_exchange_algs(const struct ly_ctx *ctx, const char *endpt_name, struct lyd_node **config, + int alg_count, ...); + +/** + * @brief Deletes a key exchange algorithm from the YANG data. + * + * @param[in] endpt_name Identifier of an existing endpoint. + * @param[in] alg Optional algorithm to be deleted. + * If NULL, all of the key exchange algorithms on this endpoint will be deleted. + * @param[in,out] config Modified configuration YANG data tree. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_del_ssh_key_exchange_alg(const char *endpt_name, const char *alg, struct lyd_node **config); + +/** + * @brief Creates new YANG configuration data nodes for encryption algorithms replacing any previous ones. + * + * Supported algorithms are: aes256-ctr, aes192-ctr, aes128-ctr, aes256-cbc, aes192-cbc, aes128-cbc, blowfish-cbc + * triple-des-cbc and none. + * + * @param[in] ctx libyang context + * @param[in] endpt_name Arbitrary identifier of the endpoint. + * If an endpoint with this identifier already exists, its encryption algorithms will be replaced. + * @param[in,out] config Configuration YANG data tree. If *config is NULL, it will be created. + * Otherwise the new YANG data will be added to the previous data and may override it. + * @param[in] alg_count Number of following algorithms. + * @param[in] ... String literals of encryption algorithms in a decreasing order of preference. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_add_ssh_encryption_algs(const struct ly_ctx *ctx, const char *endpt_name, struct lyd_node **config, + int alg_count, ...); + +/** + * @brief Deletes an encryption algorithm from the YANG data. + * + * @param[in] endpt_name Identifier of an existing endpoint. + * @param[in] alg Optional algorithm to be deleted. + * If NULL, all of the encryption algorithms on this endpoint will be deleted. + * @param[in,out] config Modified configuration YANG data tree. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_del_ssh_encryption_alg(const char *endpt_name, const char *alg, struct lyd_node **config); + +/** + * @brief Creates new YANG configuration data nodes for mac algorithms replacing any previous ones. + * + * Supported algorithms are: hmac-sha2-256, hmac-sha2-512 and hmac-sha1. + * + * @param[in] ctx libyang context + * @param[in] endpt_name Arbitrary identifier of the endpoint. + * If an endpoint with this identifier already exists, its mac algorithms will be replaced. + * @param[in,out] config Configuration YANG data tree. If *config is NULL, it will be created. + * Otherwise the new YANG data will be added to the previous data and may override it. + * @param[in] alg_count Number of following algorithms. + * @param[in] ... String literals of mac algorithms in a decreasing order of preference. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_add_ssh_mac_algs(const struct ly_ctx *ctx, const char *endpt_name, struct lyd_node **config, + int alg_count, ...); + +/** + * @brief Deletes a mac algorithm from the YANG data. + * + * @param[in] endpt_name Identifier of an existing endpoint. + * @param[in] alg Optional algorithm to be deleted. + * If NULL, all of the mac algorithms on this endpoint will be deleted. + * @param[in,out] config Modified configuration YANG data tree. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_del_ssh_mac_alg(const char *endpt_name, const char *alg, struct lyd_node **config); + /** * @} SSH Server Configuration */ @@ -493,7 +693,7 @@ int nc_server_config_del_ssh_endpoint_client_ref(const char *endpt_name, struct * Otherwise the new YANG data will be added to the previous data and may override it. * @return 0 on success, non-zero otherwise. */ -int nc_server_config_add_tls_server_cert(const struct ly_ctx *ctx, const char *endpt_name, const char *privkey_path, +int nc_server_config_add_tls_server_certificate(const struct ly_ctx *ctx, const char *endpt_name, const char *privkey_path, const char *pubkey_path, const char *certificate_path, struct lyd_node **config); /** @@ -503,7 +703,31 @@ int nc_server_config_add_tls_server_cert(const struct ly_ctx *ctx, const char *e * @param[in,out] config Modified configuration YANG data tree. * @return 0 on success, non-zero otherwise. */ -int nc_server_config_del_tls_server_cert(const char *endpt_name, struct lyd_node **config); +int nc_server_config_del_tls_server_certificate(const char *endpt_name, struct lyd_node **config); + +/** + * @brief Creates new YANG configuration data nodes for a keystore reference to the TLS server's certificate. + * + * @param[in] ctx libyang context. + * @param[in] endpt_name Arbitrary identifier of the endpoint. + * If an endpoint with this identifier already exists, its contents will be changed. + * @param[in] asym_key_ref Name of the asymmetric key pair in the keystore to be referenced. + * @param[in] cert_ref Name of the certificate, which must belong to the given asymmetric key pair, to be referenced. + * @param[in,out] config Configuration YANG data tree. If *config is NULL, it will be created. + * Otherwise the new YANG data will be added to the previous data and may override it. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_add_tls_keystore_ref(const struct ly_ctx *ctx, const char *endpt_name, const char *asym_key_ref, + const char *cert_ref, struct lyd_node **config); + +/** + * @brief Deletes a TLS server certificate keystore reference from the YANG data. + * + * @param[in] endpt_name Identifier of an existing endpoint. + * @param[in,out] config Modified configuration YANG data tree. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_del_tls_keystore_ref(const char *endpt_name, struct lyd_node **config); /** * @brief Creates new YANG configuration data nodes for a client's (end-entity) certificate. @@ -518,7 +742,7 @@ int nc_server_config_del_tls_server_cert(const char *endpt_name, struct lyd_node * Otherwise the new YANG data will be added to the previous data and may override it. * @return 0 on success, non-zero otherwise. */ -int nc_server_config_add_tls_client_cert(const struct ly_ctx *ctx, const char *endpt_name, const char *cert_name, +int nc_server_config_add_tls_client_certificate(const struct ly_ctx *ctx, const char *endpt_name, const char *cert_name, const char *cert_path, struct lyd_node **config); /** @@ -530,7 +754,30 @@ int nc_server_config_add_tls_client_cert(const struct ly_ctx *ctx, const char *e * @param[in,out] config Modified configuration YANG data tree. * @return 0 on success, non-zero otherwise. */ -int nc_server_config_del_tls_client_cert(const char *endpt_name, const char *cert_name, struct lyd_node **config); +int nc_server_config_del_tls_client_certificate(const char *endpt_name, const char *cert_name, struct lyd_node **config); + +/** + * @brief Creates new YANG configuration data nodes for a truststore reference to a set of client (end-entity) certificates. + * + * @param[in] ctx libyang context. + * @param[in] endpt_name Arbitrary identifier of the endpoint. + * If an endpoint with this identifier already exists, its contents will be changed. + * @param[in] cert_bag_ref Identifier of the certificate bag in the truststore to be referenced. + * @param[in,out] config Configuration YANG data tree. If *config is NULL, it will be created. + * Otherwise the new YANG data will be added to the previous data and may override it. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_add_tls_client_cert_truststore_ref(const struct ly_ctx *ctx, const char *endpt_name, + const char *cert_bag_ref, struct lyd_node **config); + +/** + * @brief Deletes a client (end-entity) certificates truststore reference from the YANG data. + * + * @param[in] endpt_name Identifier of an existing endpoint. + * @param[in,out] config Modified configuration YANG data tree. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_del_tls_client_cert_truststore_ref(const char *endpt_name, struct lyd_node **config); /** * @brief Creates new YANG configuration data nodes for a client certificate authority (trust-anchor) certificate. @@ -545,7 +792,7 @@ int nc_server_config_del_tls_client_cert(const char *endpt_name, const char *cer * Otherwise the new YANG data will be added to the previous data and may override it. * @return 0 on success, non-zero otherwise. */ -int nc_server_config_add_tls_ca_cert(const struct ly_ctx *ctx, const char *endpt_name, const char *cert_name, +int nc_server_config_add_tls_client_ca(const struct ly_ctx *ctx, const char *endpt_name, const char *cert_name, const char *cert_path, struct lyd_node **config); /** @@ -557,7 +804,30 @@ int nc_server_config_add_tls_ca_cert(const struct ly_ctx *ctx, const char *endpt * @param[in,out] config Modified configuration YANG data tree. * @return 0 on success, non-zero otherwise. */ -int nc_server_config_del_tls_ca_cert(const char *endpt_name, const char *cert_name, struct lyd_node **config); +int nc_server_config_del_tls_client_ca(const char *endpt_name, const char *cert_name, struct lyd_node **config); + +/** + * @brief Creates new YANG configuration data nodes for a truststore reference to a set of client certificate authority (trust-anchor) certificates. + * + * @param[in] ctx libyang context. + * @param[in] endpt_name Arbitrary identifier of the endpoint. + * If an endpoint with this identifier already exists, its contents will be changed. + * @param[in] cert_bag_ref Identifier of the certificate bag in the truststore to be referenced. + * @param[in,out] config Configuration YANG data tree. If *config is NULL, it will be created. + * Otherwise the new YANG data will be added to the previous data and may override it. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_add_tls_client_ca_truststore_ref(const struct ly_ctx *ctx, const char *endpt_name, + const char *cert_bag_ref, struct lyd_node **config); + +/** + * @brief Deletes a client certificate authority (trust-anchor) certificates truststore reference from the YANG data. + * + * @param[in] endpt_name Identifier of an existing endpoint. + * @param[in,out] config Modified configuration YANG data tree. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_del_tls_client_ca_truststore_ref(const char *endpt_name, struct lyd_node **config); /** * @brief Creates new YANG configuration data nodes, which will be a reference to another TLS endpoint's certificates. @@ -615,6 +885,122 @@ int nc_server_config_add_tls_ctn(const struct ly_ctx *ctx, const char *endpt_nam */ int nc_server_config_del_tls_ctn(const char *endpt_name, uint32_t id, struct lyd_node **config); +/** + * @brief Creates new YANG configuration data nodes for a TLS version. + * + * @param[in] ctx libyang context. + * @param[in] endpt_name Arbitrary identifier of the endpoint. + * If an endpoint with this identifier already exists, its contents will be changed. + * @param[in] tls_version TLS version to be used. Call this multiple times to set + * the accepted versions of the TLS protocol and let the client and server negotiate + * the given version. + * @param[in,out] config Configuration YANG data tree. If *config is NULL, it will be created. + * Otherwise the new YANG data will be added to the previous data and may override it. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_add_tls_version(const struct ly_ctx *ctx, const char *endpt_name, + NC_TLS_VERSION tls_version, struct lyd_node **config); + +/** + * @brief Deletes a TLS version from the YANG data. + * + * @param[in] endpt_name Identifier of an existing endpoint. + * @param[in] tls_version TLS version to be deleted. + * @param[in,out] config Modified configuration YANG data tree. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_del_tls_version(const char *endpt_name, NC_TLS_VERSION tls_version, struct lyd_node **config); + +/** + * @brief Creates new YANG configuration data nodes for a TLS cipher. + * + * @param[in] ctx libyang context. + * @param[in] endpt_name Arbitrary identifier of the endpoint. + * If an endpoint with this identifier already exists, its contents will be changed. + * @param[in,out] config Configuration YANG data tree. If *config is NULL, it will be created. + * Otherwise the new YANG data will be added to the previous data and may override it. + * @param[in] cipher_count Number of following ciphers. + * @param[in] ... TLS ciphers. These ciphers MUST be in the format as listed in the + * iana-tls-cipher-suite-algs YANG model (lowercase and separated by dashes). Regardless + * of the TLS protocol version used, all of these ciphers will be tried and some of them + * might not be set (TLS handshake might fail then). For the list of supported ciphers see + * the OpenSSL documentation. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_add_tls_ciphers(const struct ly_ctx *ctx, const char *endpt_name, struct lyd_node **config, + int cipher_count, ...); + +/** + * @brief Deletes a TLS cipher from the YANG data. + * + * @param[in] endpt_name Identifier of an existing endpoint. + * @param[in] cipher TLS cipher to be deleted. + * @param[in,out] config Modified configuration YANG data tree. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_del_tls_cipher(const char *endpt_name, const char *cipher, struct lyd_node **config); + +/** + * @brief Creates new YANG configuration data nodes for a Certificate Revocation List via a local file. + * + * Beware that you can choose up to one function between the three CRL alternatives on a given endpoint and calling + * this function will remove any CRL YANG nodes created by the other two functions. + * + * @param[in] ctx libyang context. + * @param[in] endpt_name Arbitrary identifier of the endpoint. + * If an endpoint with this identifier already exists, its contents will be changed. + * @param[in] crl_path Path to a DER/PEM encoded CRL file. + * @param[in,out] config Configuration YANG data tree. If *config is NULL, it will be created. + * Otherwise the new YANG data will be added to the previous data and may override it. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_add_tls_crl_path(const struct ly_ctx *ctx, const char *endpt_name, + const char *crl_path, struct lyd_node **config); + +/** + * @brief Creates new YANG configuration data nodes for a Certificate Revocation List via an URL. + * + * Beware that you can choose up to one function between the three CRL alternatives on a given endpoint and calling + * this function will remove any CRL YANG nodes created by the other two functions. + * + * @param[in] ctx libyang context. + * @param[in] endpt_name Arbitrary identifier of the endpoint. + * If an endpoint with this identifier already exists, its contents will be changed. + * @param[in] crl_url URL from which the CRL file will be downloaded. The file has to be in the DER or PEM format. + * The allowed protocols are all the protocols supported by CURL. + * @param[in,out] config Configuration YANG data tree. If *config is NULL, it will be created. + * Otherwise the new YANG data will be added to the previous data and may override it. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_add_tls_crl_url(const struct ly_ctx *ctx, const char *endpt_name, const char *crl_url, struct lyd_node **config); + +/** + * @brief Creates new YANG configuration data nodes for a Certificate Revocation List via certificate extensions. + * + * The chain of configured Certificate Authorities will be examined. For each certificate in this chain all the + * CRLs from the URLs specified in their extension fields CRL Distribution Points will be downloaded and used. + * + * Beware that you can choose up to one function between the three CRL alternatives on a given endpoint and calling + * this function will remove any CRL YANG nodes created by the other two functions. + * + * @param[in] ctx libyang context. + * @param[in] endpt_name Arbitrary identifier of the endpoint. + * If an endpoint with this identifier already exists, its contents will be changed. + * @param[in,out] config Configuration YANG data tree. If *config is NULL, it will be created. + * Otherwise the new YANG data will be added to the previous data and may override it. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_add_tls_crl_cert_ext(const struct ly_ctx *ctx, const char *endpt_name, struct lyd_node **config); + +/** + * @brief Deletes all the CRL nodes from the YANG data. + * + * @param[in] endpt_name Identifier of an existing endpoint. + * @param[in,out] config Modified configuration YANG data tree. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_del_tls_crl(const char *endpt_name, struct lyd_node **config); + /** * @} TLS Server Configuration */ @@ -849,7 +1235,39 @@ int nc_server_config_del_ch_ssh_hostkey(const char *client_name, const char *end const char *hostkey_name, struct lyd_node **config); /** - * @brief Creates new YANG configuration data nodes for the maximum amount of failed Call Home SSH authentication attempts. + * @brief Creates new YANG data nodes for a reference to an asymmetric key located in the keystore. + * + * This asymmetric key pair will be used as the Call Home SSH hostkey. + * + * @param[in] ctx libyang context. + * @param[in] client_name Arbitrary identifier of the Call Home client. + * If a Call Home client with this identifier already exists, its contents will be changed. + * @param[in] endpt_name Arbitrary identifier of the client's endpoint. + * If the client's endpoint with this identifier already exists, its contents will be changed. + * @param[in] hostkey_name Arbitrary identifier of the endpoint's hostkey. + * If the endpoint's hostkey with this identifier already exists, its contents will be changed. + * @param[in] keystore_reference Name of the asymmetric key pair to be referenced and used as a hostkey. + * @param[in,out] config Configuration YANG data tree. If *config is NULL, it will be created. + * Otherwise the new YANG data will be added to the previous data and may override it. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_add_ch_ssh_keystore_ref(const struct ly_ctx *ctx, const char *client_name, + const char *endpt_name, const char *hostkey_name, const char *keystore_reference, struct lyd_node **config); + +/** + * @brief Deletes a Call Home keystore reference from the YANG data. + * + * @param[in] client_name Identifier of an existing Call Home client. + * @param[in] endpt_name Identifier of an existing endpoint that belongs to the given CH client. + * @param[in] hostkey_name Identifier of an existing hostkey that belongs to the given CH endpoint. + * @param[in,out] config Modified configuration YANG data tree. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_del_ch_ssh_keystore_ref(const char *client_name, const char *endpt_name, + const char *hostkey_name, struct lyd_node **config); + +/** + * @brief Creates new YANG configuration data nodes for the maximum amount of failed Call Home SSH authentication attempts. * * @param[in] ctx libyang context. * @param[in] client_name Arbitrary identifier of the Call Home client. @@ -946,6 +1364,35 @@ int nc_server_config_add_ch_ssh_user_password(const struct ly_ctx *ctx, const ch int nc_server_config_del_ch_ssh_user_password(const char *client_name, const char *endpt_name, const char *user_name, struct lyd_node **config); +/** + * @brief Creates new YANG configuration data nodes for a Call Home SSH user's none authentication method. + * + * @param[in] ctx libyang context. + * @param[in] client_name Arbitrary identifier of the Call Home client. + * If a Call Home client with this identifier already exists, its contents will be changed. + * @param[in] endpt_name Arbitrary identifier of the client's endpoint. + * If the client's endpoint with this identifier already exists, its contents will be changed. + * @param[in] user_name Arbitrary identifier of the endpoint's user. + * If the endpoint's user with this identifier already exists, its contents will be changed. + * @param[in,out] config Configuration YANG data tree. If *config is NULL, it will be created. + * Otherwise the new YANG data will be added to the previous data and may override it. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_add_ch_ssh_user_none(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name, + const char *user_name, struct lyd_node **config); + +/** + * @brief Deletes a Call Home SSH user's none authentication method from the YANG data. + * + * @param[in] client_name Identifier of an existing Call Home client. + * @param[in] endpt_name Identifier of an existing endpoint that belongs to the given CH client. + * @param[in] user_name Identifier of an existing SSH user that belongs to the given CH endpoint. + * @param[in,out] config Modified configuration YANG data tree. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_del_ch_ssh_user_none(const char *client_name, const char *endpt_name, + const char *user_name, struct lyd_node **config); + /** * @brief Creates new YANG configuration data nodes for a Call Home SSH user's keyboard interactive authentication method. * @@ -991,6 +1438,170 @@ int nc_server_config_del_ch_ssh_user_interactive(const char *client_name, const int nc_server_config_del_ch_ssh_user(const char *client_name, const char *endpt_name, const char *user_name, struct lyd_node **config); +/** + * @brief Creates new YANG data nodes for a reference to a public key bag located in the truststore. + * + * The public key's located in the bag will be used for Call Home SSH client authentication. + * + * @param[in] ctx libyang context. + * @param[in] client_name Arbitrary identifier of the Call Home client. + * If a Call Home client with this identifier already exists, its contents will be changed. + * @param[in] endpt_name Arbitrary identifier of the client's endpoint. + * If the client's endpoint with this identifier already exists, its contents will be changed. + * @param[in] user_name Arbitrary identifier of the endpoint's user. + * If the endpoint's user with this identifier already exists, its contents will be changed. + * @param[in] truststore_reference Name of the public key bag to be referenced and used for authentication. + * @param[in,out] config Configuration YANG data tree. If *config is NULL, it will be created. + * Otherwise the new YANG data will be added to the previous data and may override it. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_add_ch_ssh_truststore_ref(const struct ly_ctx *ctx, const char *client_name, + const char *endpt_name, const char *user_name, const char *truststore_reference, struct lyd_node **config); + +/** + * @brief Deletes a Call Home SSH truststore reference from the YANG data. + * + * @param[in] client_name Identifier of an existing Call Home client. + * @param[in] endpt_name Identifier of an existing endpoint that belongs to the given CH client. + * @param[in] user_name Identifier of an existing SSH user that belongs to the given CH endpoint. + * @param[in,out] config Modified configuration YANG data tree. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_del_ch_ssh_truststore_ref(const char *client_name, const char *endpt_name, + const char *user_name, struct lyd_node **config); + +/** + * @brief Creates new YANG configuration data nodes for Call Home host-key algorithms replacing any previous ones. + * + * Supported algorithms are: ssh-ed25519, ecdsa-sha2-nistp256, ecdsa-sha2-nistp384, ecdsa-sha2-nistp521, + * rsa-sha2-512, rsa-sha2-256, ssh-rsa and ssh-dss. + * + * @param[in] ctx libyang context. + * @param[in] client_name Arbitrary identifier of the Call Home client. + * If a Call Home client with this identifier already exists, its contents will be changed. + * @param[in] endpt_name Arbitrary identifier of the client's endpoint. + * If the client's endpoint with this identifier already exists, its contents will be changed. + * @param[in,out] config Configuration YANG data tree. If *config is NULL, it will be created. + * Otherwise the new YANG data will be added to the previous data and may override it. + * @param[in] alg_count Number of following algorithms. + * @param[in] ... String literals of host-key algorithms in a decreasing order of preference. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_add_ch_ssh_host_key_algs(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name, + struct lyd_node **config, int alg_count, ...); + +/** + * @brief Deletes a Call Home hostkey algorithm from the YANG data. + * + * @param[in] client_name Identifier of an existing Call Home client. + * @param[in] endpt_name Identifier of an existing endpoint that belongs to the given CH client. + * @param[in] alg Optional algorithm to be deleted. + * If NULL, all of the hostkey algorithms on this endpoint will be deleted. + * @param[in,out] config Modified configuration YANG data tree. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_del_ch_ssh_host_key_alg(const char *client_name, const char *endpt_name, + const char *alg, struct lyd_node **config); + +/** + * @brief Creates new YANG configuration data nodes for Call Home key exchange algorithms replacing any previous ones. + * + * Supported algorithms are: diffie-hellman-group-exchange-sha1, curve25519-sha256, ecdh-sha2-nistp256, + * ecdh-sha2-nistp384, ecdh-sha2-nistp521, diffie-hellman-group18-sha512, diffie-hellman-group16-sha512, + * diffie-hellman-group-exchange-sha256 and diffie-hellman-group14-sha256. + * + * @param[in] ctx libyang context. + * @param[in] client_name Arbitrary identifier of the Call Home client. + * If a Call Home client with this identifier already exists, its contents will be changed. + * @param[in] endpt_name Arbitrary identifier of the client's endpoint. + * If the client's endpoint with this identifier already exists, its contents will be changed. + * @param[in,out] config Configuration YANG data tree. If *config is NULL, it will be created. + * Otherwise the new YANG data will be added to the previous data and may override it. + * @param[in] alg_count Number of following algorithms. + * @param[in] ... String literals of key exchange algorithms in a decreasing order of preference. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_add_ch_ssh_key_exchange_algs(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name, + struct lyd_node **config, int alg_count, ...); + +/** + * @brief Deletes a Call Home key exchange algorithm from the YANG data. + * + * @param[in] client_name Identifier of an existing Call Home client. + * @param[in] endpt_name Identifier of an existing endpoint that belongs to the given CH client. + * @param[in] alg Optional algorithm to be deleted. + * If NULL, all of the key exchange algorithms on this endpoint will be deleted. + * @param[in,out] config Modified configuration YANG data tree. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_del_ch_ssh_key_exchange_alg(const char *client_name, const char *endpt_name, + const char *alg, struct lyd_node **config); + +/** + * @brief Creates new YANG configuration data nodes for Call Home encryption algorithms replacing any previous ones. + * + * Supported algorithms are: aes256-ctr, aes192-ctr, aes128-ctr, aes256-cbc, aes192-cbc, aes128-cbc, blowfish-cbc + * triple-des-cbc and none. + * + * @param[in] ctx libyang context. + * @param[in] client_name Arbitrary identifier of the Call Home client. + * If a Call Home client with this identifier already exists, its contents will be changed. + * @param[in] endpt_name Arbitrary identifier of the client's endpoint. + * If the client's endpoint with this identifier already exists, its contents will be changed. + * @param[in,out] config Configuration YANG data tree. If *config is NULL, it will be created. + * Otherwise the new YANG data will be added to the previous data and may override it. + * @param[in] alg_count Number of following algorithms. + * @param[in] ... String literals of encryption algorithms in a decreasing order of preference. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_add_ch_ssh_encryption_algs(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name, + struct lyd_node **config, int alg_count, ...); + +/** + * @brief Deletes a Call Home encryption algorithm from the YANG data. + * + * @param[in] client_name Identifier of an existing Call Home client. + * @param[in] endpt_name Identifier of an existing endpoint that belongs to the given CH client. + * @param[in] alg Optional algorithm to be deleted. + * If NULL, all of the encryption algorithms on this endpoint will be deleted. + * @param[in,out] config Modified configuration YANG data tree. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_del_ch_ssh_encryption_alg(const char *client_name, const char *endpt_name, + const char *alg, struct lyd_node **config); + +/** + * @brief Creates new YANG configuration data nodes for Call Home mac algorithms replacing any previous ones. + * + * Supported algorithms are: hmac-sha2-256, hmac-sha2-512 and hmac-sha1. + * + * @param[in] ctx libyang context. + * @param[in] client_name Arbitrary identifier of the Call Home client. + * If a Call Home client with this identifier already exists, its contents will be changed. + * @param[in] endpt_name Arbitrary identifier of the client's endpoint. + * If the client's endpoint with this identifier already exists, its contents will be changed. + * @param[in,out] config Configuration YANG data tree. If *config is NULL, it will be created. + * Otherwise the new YANG data will be added to the previous data and may override it. + * @param[in] alg_count Number of following algorithms. + * @param[in] ... String literals of mac algorithms in a decreasing order of preference. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_add_ch_ssh_mac_algs(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name, + struct lyd_node **config, int alg_count, ...); + +/** + * @brief Deletes a Call Home mac algorithm from the YANG data. + * + * @param[in] client_name Identifier of an existing Call Home client. + * @param[in] endpt_name Identifier of an existing endpoint that belongs to the given CH client. + * @param[in] alg Optional algorithm to be deleted. + * If NULL, all of the mac algorithms on this endpoint will be deleted. + * @param[in,out] config Modified configuration YANG data tree. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_del_ch_ssh_mac_alg(const char *client_name, const char *endpt_name, + const char *alg, struct lyd_node **config); + /** * @} SSH Call Home Server Configuration */ @@ -1019,7 +1630,7 @@ int nc_server_config_del_ch_ssh_user(const char *client_name, const char *endpt_ * Otherwise the new YANG data will be added to the previous data and may override it. * @return 0 on success, non-zero otherwise. */ -int nc_server_config_add_ch_tls_server_cert(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name, +int nc_server_config_add_ch_tls_server_certificate(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name, const char *privkey_path, const char *pubkey_path, const char *certificate_path, struct lyd_node **config); /** @@ -1030,7 +1641,35 @@ int nc_server_config_add_ch_tls_server_cert(const struct ly_ctx *ctx, const char * @param[in,out] config Modified configuration YANG data tree. * @return 0 on success, non-zero otherwise. */ -int nc_server_config_del_ch_tls_server_cert(const char *client_name, const char *endpt_name, +int nc_server_config_del_ch_tls_server_certificate(const char *client_name, const char *endpt_name, + struct lyd_node **config); + +/** + * @brief Creates new YANG configuration data nodes for a keystore reference to the Call Home TLS server's certificate. + * + * @param[in] ctx libyang context. + * @param[in] client_name Arbitrary identifier of the Call Home client. + * If a Call Home client with this identifier already exists, its contents will be changed. + * @param[in] endpt_name Arbitrary identifier of the Call Home client's endpoint. + * If a Call Home client's endpoint with this identifier already exists, its contents will be changed. + * @param[in] asym_key_ref Name of the asymmetric key pair in the keystore to be referenced. + * @param[in] cert_ref Name of the certificate, which must belong to the given asymmetric key pair, to be referenced. + * @param[in,out] config Configuration YANG data tree. If *config is NULL, it will be created. + * Otherwise the new YANG data will be added to the previous data and may override it. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_add_ch_tls_keystore_ref(const struct ly_ctx *ctx, const char *client_name, + const char *endpt_name, const char *asym_key_ref, const char *cert_ref, struct lyd_node **config); + +/** + * @brief Deletes a TLS server certificate keystore reference from the YANG data. + * + * @param[in] client_name Identifier of an existing Call Home client. + * @param[in] endpt_name Identifier of an existing Call Home endpoint that belongs to the given client. + * @param[in,out] config Modified configuration YANG data tree. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_del_ch_tls_keystore_ref(const char *client_name, const char *endpt_name, struct lyd_node **config); /** @@ -1048,7 +1687,7 @@ int nc_server_config_del_ch_tls_server_cert(const char *client_name, const char * Otherwise the new YANG data will be added to the previous data and may override it. * @return 0 on success, non-zero otherwise. */ -int nc_server_config_add_ch_tls_client_cert(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name, +int nc_server_config_add_ch_tls_client_certificate(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name, const char *cert_name, const char *cert_path, struct lyd_node **config); /** @@ -1061,9 +1700,36 @@ int nc_server_config_add_ch_tls_client_cert(const struct ly_ctx *ctx, const char * @param[in,out] config Modified configuration YANG data tree. * @return 0 on success, non-zero otherwise. */ -int nc_server_config_del_ch_tls_client_cert(const char *client_name, const char *endpt_name, +int nc_server_config_del_ch_tls_client_certificate(const char *client_name, const char *endpt_name, const char *cert_name, struct lyd_node **config); +/** + * @brief Creates new YANG configuration data nodes for a Call Home truststore reference to a set of client (end-entity) certificates. + * + * @param[in] ctx libyang context. + * @param[in] client_name Arbitrary identifier of the Call Home client. + * If a Call Home client with this identifier already exists, its contents will be changed. + * @param[in] endpt_name Arbitrary identifier of the Call Home client's endpoint. + * If a Call Home client's endpoint with this identifier already exists, its contents will be changed. + * @param[in] cert_bag_ref Identifier of the certificate bag in the truststore to be referenced. + * @param[in,out] config Configuration YANG data tree. If *config is NULL, it will be created. + * Otherwise the new YANG data will be added to the previous data and may override it. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_add_ch_tls_client_cert_truststore_ref(const struct ly_ctx *ctx, const char *client_name, + const char *endpt_name, const char *cert_bag_ref, struct lyd_node **config); + +/** + * @brief Deletes a Call Home client (end-entity) certificates truststore reference from the YANG data. + * + * @param[in] client_name Identifier of an existing Call Home client. + * @param[in] endpt_name Identifier of an existing Call Home endpoint that belongs to the given client. + * @param[in,out] config Modified configuration YANG data tree. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_del_ch_tls_client_cert_truststore_ref(const char *client_name, const char *endpt_name, + struct lyd_node **config); + /** * @brief Creates new YANG configuration data nodes for a client certificate authority (trust-anchor) certificate. * @@ -1079,7 +1745,7 @@ int nc_server_config_del_ch_tls_client_cert(const char *client_name, const char * Otherwise the new YANG data will be added to the previous data and may override it. * @return 0 on success, non-zero otherwise. */ -int nc_server_config_add_ch_tls_ca_cert(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name, +int nc_server_config_add_ch_tls_client_ca(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name, const char *cert_name, const char *cert_path, struct lyd_node **config); /** @@ -1092,9 +1758,36 @@ int nc_server_config_add_ch_tls_ca_cert(const struct ly_ctx *ctx, const char *cl * @param[in,out] config Modified configuration YANG data tree. * @return 0 on success, non-zero otherwise. */ -int nc_server_config_del_ch_tls_ca_cert(const char *client_name, const char *endpt_name, +int nc_server_config_del_ch_tls_client_ca(const char *client_name, const char *endpt_name, const char *cert_name, struct lyd_node **config); +/** + * @brief Creates new YANG configuration data nodes for a Call Home truststore reference to a set of client certificate authority (trust-anchor) certificates. + * + * @param[in] ctx libyang context. + * @param[in] client_name Arbitrary identifier of the Call Home client. + * If a Call Home client with this identifier already exists, its contents will be changed. + * @param[in] endpt_name Arbitrary identifier of the Call Home client's endpoint. + * If a Call Home client's endpoint with this identifier already exists, its contents will be changed. + * @param[in] cert_bag_ref Identifier of the certificate bag in the truststore to be referenced. + * @param[in,out] config Configuration YANG data tree. If *config is NULL, it will be created. + * Otherwise the new YANG data will be added to the previous data and may override it. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_add_ch_tls_client_ca_truststore_ref(const struct ly_ctx *ctx, const char *client_name, + const char *endpt_name, const char *cert_bag_ref, struct lyd_node **config); + +/** + * @brief Deletes a Call Home client certificate authority (trust-anchor) certificates truststore reference from the YANG data. + * + * @param[in] client_name Identifier of an existing Call Home client. + * @param[in] endpt_name Identifier of an existing Call Home endpoint that belongs to the given client. + * @param[in,out] config Modified configuration YANG data tree. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_del_ch_tls_client_ca_truststore_ref(const char *client_name, const char *endpt_name, + struct lyd_node **config); + /** * @brief Creates new YANG configuration data nodes for a Call Home cert-to-name entry. * @@ -1128,6 +1821,138 @@ int nc_server_config_add_ch_tls_ctn(const struct ly_ctx *ctx, const char *client int nc_server_config_del_ch_tls_ctn(const char *client_name, const char *endpt_name, uint32_t id, struct lyd_node **config); +/** + * @brief Creates new YANG configuration data nodes for a Call Home TLS version. + * + * @param[in] ctx libyang context. + * @param[in] client_name Arbitrary identifier of the Call Home client. + * If a Call Home client with this identifier already exists, its contents will be changed. + * @param[in] endpt_name Arbitrary identifier of the Call Home client's endpoint. + * If a Call Home client's endpoint with this identifier already exists, its contents will be changed. + * @param[in] tls_version TLS version to be used. Call this multiple times to set the accepted versions + * of the TLS protocol and let the client and server negotiate the given version. + * @param[in,out] config Configuration YANG data tree. If *config is NULL, it will be created. + * Otherwise the new YANG data will be added to the previous data and may override it. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_add_ch_tls_version(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name, + NC_TLS_VERSION tls_version, struct lyd_node **config); + +/** + * @brief Deletes a TLS version from the YANG data. + * + * @param[in] client_name Identifier of an existing Call Home client. + * @param[in] endpt_name Identifier of an existing Call Home endpoint that belongs to the given client. + * @param[in] tls_version TLS version to be deleted. + * @param[in,out] config Modified configuration YANG data tree. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_del_ch_tls_version(const char *client_name, const char *endpt_name, + NC_TLS_VERSION tls_version, struct lyd_node **config); + +/** + * @brief Creates new YANG configuration data nodes for a Call Home TLS cipher. + * + * @param[in] ctx libyang context. + * @param[in] client_name Arbitrary identifier of the Call Home client. + * If a Call Home client with this identifier already exists, its contents will be changed. + * @param[in] endpt_name Arbitrary identifier of the Call Home client's endpoint. + * If a Call Home client's endpoint with this identifier already exists, its contents will be changed. + * @param[in,out] config Configuration YANG data tree. If *config is NULL, it will be created. + * Otherwise the new YANG data will be added to the previous data and may override it. + * @param[in] cipher_count Number of following ciphers. + * @param[in] ... TLS ciphers. These ciphers MUST be in the format as listed in the + * iana-tls-cipher-suite-algs YANG model (lowercase and separated by dashes). Regardless + * of the TLS protocol version used, all of these ciphers will be tried and some of them + * might not be set (TLS handshake might fail then). For the list of supported ciphers see + * the OpenSSL documentation. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_add_ch_tls_ciphers(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name, + struct lyd_node **config, int cipher_count, ...); + +/** + * @brief Deletes a Call Home TLS cipher from the YANG data. + * + * @param[in] client_name Identifier of an existing Call Home client. + * @param[in] endpt_name Identifier of an existing Call Home endpoint that belongs to the given client. + * @param[in] cipher TLS cipher to be deleted. + * @param[in,out] config Modified configuration YANG data tree. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_del_ch_tls_cipher(const char *client_name, const char *endpt_name, + const char *cipher, struct lyd_node **config); + +/** + * @brief Creates new YANG configuration data nodes for a Call Home Certificate Revocation List via a local file. + * + * Beware that you can choose up to one function between the three CRL alternatives on a given endpoint and calling + * this function will remove any CRL YANG nodes created by the other two functions. + * + * @param[in] ctx libyang context. + * @param[in] client_name Arbitrary identifier of the Call Home client. + * If a Call Home client with this identifier already exists, its contents will be changed. + * @param[in] endpt_name Arbitrary identifier of the Call Home client's endpoint. + * If a Call Home client's endpoint with this identifier already exists, its contents will be changed. + * @param[in] crl_path Path to a DER/PEM encoded CRL file. + * @param[in,out] config Configuration YANG data tree. If *config is NULL, it will be created. + * Otherwise the new YANG data will be added to the previous data and may override it. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_add_ch_tls_crl_path(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name, + const char *crl_path, struct lyd_node **config); + +/** + * @brief Creates new YANG configuration data nodes for a Call Home Certificate Revocation List via an URL. + * + * Beware that you can choose up to one function between the three CRL alternatives on a given endpoint and calling + * this function will remove any CRL YANG nodes created by the other two functions. + * + * @param[in] ctx libyang context. + * @param[in] client_name Arbitrary identifier of the Call Home client. + * If a Call Home client with this identifier already exists, its contents will be changed. + * @param[in] endpt_name Arbitrary identifier of the Call Home client's endpoint. + * If a Call Home client's endpoint with this identifier already exists, its contents will be changed. + * @param[in] crl_url URL from which the CRL file will be downloaded. The file has to be in the DER or PEM format. + * The allowed protocols are all the protocols supported by CURL. + * @param[in,out] config Configuration YANG data tree. If *config is NULL, it will be created. + * Otherwise the new YANG data will be added to the previous data and may override it. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_add_ch_tls_crl_url(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name, + const char *crl_url, struct lyd_node **config); + +/** + * @brief Creates new YANG configuration data nodes for a Call Home Certificate Revocation List via certificate extensions. + * + * The chain of configured Certificate Authorities will be examined. For each certificate in this chain all the + * CRLs from the URLs specified in their extension fields CRL Distribution Points will be downloaded and used. + * + * Beware that you can choose up to one function between the three CRL alternatives on a given endpoint and calling + * this function will remove any CRL YANG nodes created by the other two functions. + * + * @param[in] ctx libyang context. + * @param[in] client_name Arbitrary identifier of the Call Home client. + * If a Call Home client with this identifier already exists, its contents will be changed. + * @param[in] endpt_name Arbitrary identifier of the Call Home client's endpoint. + * If a Call Home client's endpoint with this identifier already exists, its contents will be changed. + * @param[in,out] config Configuration YANG data tree. If *config is NULL, it will be created. + * Otherwise the new YANG data will be added to the previous data and may override it. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_add_ch_tls_crl_cert_ext(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name, + struct lyd_node **config); + +/** + * @brief Deletes all the CRL nodes from the YANG data. + * + * @param[in] client_name Identifier of an existing Call Home client. + * @param[in] endpt_name Identifier of an existing Call Home endpoint that belongs to the given client. + * @param[in,out] config Modified configuration YANG data tree. + * @return 0 on success, non-zero otherwise. + */ +int nc_server_config_del_ch_tls_crl(const char *client_name, const char *endpt_name, struct lyd_node **config); + /** * @} TLS Call Home Server Configuration */ diff --git a/src/server_config_util.c b/src/server_config_util.c index cf19e012..2e8aed14 100644 --- a/src/server_config_util.c +++ b/src/server_config_util.c @@ -32,7 +32,6 @@ #include "compat.h" #include "log_p.h" -#include "server_config.h" #include "session.h" #include "session_p.h" @@ -1317,8 +1316,8 @@ nc_server_config_del_keystore_cert(const char *asym_key_name, const char *cert_n } API int -nc_server_config_add_truststore_pubkey(const struct ly_ctx *ctx, NC_TRANSPORT_IMPL ti, const char *pub_bag_name, - const char *pubkey_name, const char *pubkey_path, struct lyd_node **config) +nc_server_config_add_truststore_pubkey(const struct ly_ctx *ctx, const char *pub_bag_name, const char *pubkey_name, + const char *pubkey_path, struct lyd_node **config) { int ret = 0; char *pubkey = NULL; @@ -1326,15 +1325,7 @@ nc_server_config_add_truststore_pubkey(const struct ly_ctx *ctx, NC_TRANSPORT_IM NC_CHECK_ARG_RET(NULL, ctx, pub_bag_name, pubkey_name, pubkey_path, config, 1); - if (ti == NC_TI_LIBSSH) { - ret = nc_server_config_util_get_ssh_pubkey_file(pubkey_path, &pubkey); - } else if (ti == NC_TI_OPENSSL) { - ret = nc_server_config_util_get_spki_pubkey_file(pubkey_path, &pubkey); - } else { - ERR(NULL, "Public key in the truststore can only be created for SSH or TLS transports."); - ret = 1; - goto cleanup; - } + ret = nc_server_config_util_get_ssh_pubkey_file(pubkey_path, &pubkey); if (ret) { goto cleanup; } diff --git a/src/server_config_util_ssh.c b/src/server_config_util_ssh.c index 64b56abc..bcd9bd6d 100644 --- a/src/server_config_util_ssh.c +++ b/src/server_config_util_ssh.c @@ -182,6 +182,82 @@ nc_server_config_del_ch_ssh_hostkey(const char *client_name, const char *endpt_n } } +API int +nc_server_config_add_ssh_keystore_ref(const struct ly_ctx *ctx, const char *endpt_name, const char *hostkey_name, + const char *keystore_reference, struct lyd_node **config) +{ + int ret = 0; + + NC_CHECK_ARG_RET(NULL, ctx, endpt_name, hostkey_name, keystore_reference, config, 1); + + ret = nc_server_config_create(ctx, config, keystore_reference, "/ietf-netconf-server:netconf-server/listen/" + "endpoint[name='%s']/ssh/ssh-server-parameters/server-identity/host-key[name='%s']/public-key/" + "keystore-reference", endpt_name, hostkey_name); + if (ret) { + goto cleanup; + } + + /* delete inline definition nodes if present */ + ret = nc_server_config_check_delete(config, "/ietf-netconf-server:netconf-server/listen/" + "endpoint[name='%s']/ssh/ssh-server-parameters/server-identity/host-key[name='%s']/public-key/" + "inline-definition", endpt_name, hostkey_name); + if (ret) { + goto cleanup; + } + +cleanup: + return ret; +} + +API int +nc_server_config_add_ch_ssh_keystore_ref(const struct ly_ctx *ctx, const char *client_name, + const char *endpt_name, const char *hostkey_name, const char *keystore_reference, struct lyd_node **config) +{ + int ret = 0; + + NC_CHECK_ARG_RET(NULL, ctx, client_name, endpt_name, hostkey_name, keystore_reference, config, 1); + + ret = nc_server_config_create(ctx, config, keystore_reference, "/ietf-netconf-server:netconf-server/call-home/" + "netconf-client[name='%s']/endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/server-identity/" + "host-key[name='%s']/public-key/keystore-reference", client_name, endpt_name, hostkey_name); + if (ret) { + goto cleanup; + } + + /* delete inline definition nodes if present */ + ret = nc_server_config_check_delete(config, "/ietf-netconf-server:netconf-server/call-home/" + "netconf-client[name='%s']/endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/server-identity/" + "host-key[name='%s']/public-key/inline-definition", client_name, endpt_name, hostkey_name); + if (ret) { + goto cleanup; + } + +cleanup: + return ret; +} + +API int +nc_server_config_del_ssh_keystore_ref(const char *endpt_name, const char *hostkey_name, + struct lyd_node **config) +{ + NC_CHECK_ARG_RET(NULL, endpt_name, config, 1); + + return nc_server_config_delete(config, "/ietf-netconf-server:netconf-server/listen/" + "endpoint[name='%s']/ssh/ssh-server-parameters/server-identity/host-key[name='%s']/public-key/" + "keystore-reference", endpt_name, hostkey_name); +} + +API int +nc_server_config_del_ch_ssh_keystore_ref(const char *client_name, const char *endpt_name, + const char *hostkey_name, struct lyd_node **config) +{ + NC_CHECK_ARG_RET(NULL, client_name, endpt_name, hostkey_name, config, 1); + + return nc_server_config_delete(config, "/ietf-netconf-server:netconf-server/call-home/" + "netconf-client[name='%s']/endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/server-identity/" + "host-key[name='%s']/public-key/keystore-reference", client_name, endpt_name, hostkey_name); +} + API int nc_server_config_add_ssh_auth_attempts(const struct ly_ctx *ctx, const char *endpt_name, uint16_t auth_attempts, struct lyd_node **config) @@ -539,6 +615,47 @@ nc_server_config_del_ch_ssh_user_password(const char *client_name, const char *e "users/user[name='%s']/password", client_name, endpt_name, user_name); } +API int +nc_server_config_add_ssh_user_none(const struct ly_ctx *ctx, const char *endpt_name, + const char *user_name, struct lyd_node **config) +{ + NC_CHECK_ARG_RET(NULL, ctx, endpt_name, user_name, config, 1); + + return nc_server_config_create(ctx, config, NULL, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/" + "users/user[name='%s']/none", endpt_name, user_name); +} + +API int +nc_server_config_add_ch_ssh_user_none(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name, + const char *user_name, struct lyd_node **config) +{ + NC_CHECK_ARG_RET(NULL, ctx, client_name, endpt_name, user_name, config, 1); + + return nc_server_config_create(ctx, config, NULL, "/ietf-netconf-server:netconf-server/call-home/" + "netconf-client[name='%s']/endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/" + "users/user[name='%s']/none", client_name, endpt_name, user_name); +} + +API int +nc_server_config_del_ssh_user_none(const char *endpt_name, const char *user_name, struct lyd_node **config) +{ + NC_CHECK_ARG_RET(NULL, endpt_name, user_name, config, 1); + + return nc_server_config_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/" + "ssh-server-parameters/client-authentication/users/user[name='%s']/none", endpt_name, user_name); +} + +API int +nc_server_config_del_ch_ssh_user_none(const char *client_name, const char *endpt_name, + const char *user_name, struct lyd_node **config) +{ + NC_CHECK_ARG_RET(NULL, client_name, endpt_name, user_name, config, 1); + + return nc_server_config_delete(config, "/ietf-netconf-server:netconf-server/call-home/" + "netconf-client[name='%s']/endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/" + "users/user[name='%s']/none", client_name, endpt_name, user_name); +} + static int _nc_server_config_add_ssh_user_interactive(const struct ly_ctx *ctx, const char *tree_path, const char *pam_config_name, const char *pam_config_dir, struct lyd_node **config) @@ -689,3 +806,530 @@ nc_server_config_del_ssh_endpoint_client_ref(const char *endpt_name, struct lyd_ return nc_server_config_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/ssh-server-parameters/" "client-authentication/libnetconf2-netconf-server:endpoint-client-auth", endpt_name); } + +API int +nc_server_config_add_ssh_truststore_ref(const struct ly_ctx *ctx, const char *endpt_name, const char *user_name, + const char *truststore_reference, struct lyd_node **config) +{ + int ret = 0; + + NC_CHECK_ARG_RET(NULL, ctx, endpt_name, user_name, truststore_reference, config, 1); + + ret = nc_server_config_create(ctx, config, truststore_reference, "/ietf-netconf-server:netconf-server/listen/" + "endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/users/user[name='%s']/public-keys/" + "truststore-reference", endpt_name, user_name); + if (ret) { + goto cleanup; + } + + /* delete inline definition nodes if present */ + ret = nc_server_config_check_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/" + "ssh-server-parameters/client-authentication/users/user[name='%s']/public-keys/inline-definition", + endpt_name, user_name); + if (ret) { + goto cleanup; + } + +cleanup: + return ret; +} + +API int +nc_server_config_add_ch_ssh_truststore_ref(const struct ly_ctx *ctx, const char *client_name, + const char *endpt_name, const char *user_name, const char *truststore_reference, struct lyd_node **config) +{ + int ret = 0; + + NC_CHECK_ARG_RET(NULL, ctx, client_name, endpt_name, user_name, truststore_reference, config, 1); + + ret = nc_server_config_create(ctx, config, truststore_reference, "/ietf-netconf-server:netconf-server/call-home/" + "netconf-client[name='%s']/endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/" + "users/user[name='%s']/public-keys/truststore-reference", client_name, endpt_name, user_name); + if (ret) { + goto cleanup; + } + + /* delete inline definition nodes if present */ + ret = nc_server_config_check_delete(config, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/" + "endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/users/user[name='%s']/" + "public-keys/inline-definition", client_name, endpt_name, user_name); + if (ret) { + goto cleanup; + } + +cleanup: + return ret; +} + +API int +nc_server_config_del_ssh_truststore_ref(const char *endpt_name, const char *user_name, + struct lyd_node **config) +{ + NC_CHECK_ARG_RET(NULL, endpt_name, user_name, config, 1); + + return nc_server_config_delete(config, "/ietf-netconf-server:netconf-server/listen/" + "endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/users/user[name='%s']/public-keys/" + "truststore-reference", endpt_name, user_name); +} + +API int +nc_server_config_del_ch_ssh_truststore_ref(const char *client_name, const char *endpt_name, + const char *user_name, struct lyd_node **config) +{ + NC_CHECK_ARG_RET(NULL, client_name, endpt_name, user_name, config, 1); + + return nc_server_config_delete(config, "/ietf-netconf-server:netconf-server/call-home/" + "netconf-client[name='%s']/endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/" + "users/user[name='%s']/public-keys/truststore-reference", client_name, endpt_name, user_name); +} + +static int +nc_server_config_ssh_transport_params_prep(const struct ly_ctx *ctx, const char *client_name, + const char *endpt_name, struct lyd_node *config, struct lyd_node **new_tree, struct lyd_node **alg_tree) +{ + int ret = 0; + char *tree_path = NULL; + + NC_CHECK_ARG_RET(NULL, ctx, endpt_name, config, new_tree, alg_tree, 1); + + /* prepare path */ + if (client_name) { + /* ch */ + ret = asprintf(&tree_path, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/endpoints/" + "endpoint[name='%s']/ssh/ssh-server-parameters/transport-params", client_name, endpt_name); + } else { + /* listen */ + ret = asprintf(&tree_path, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/" + "ssh/ssh-server-parameters/transport-params", endpt_name); + } + if (ret == -1) { + ERRMEM; + tree_path = NULL; + ret = 1; + goto cleanup; + } + + /* create all the nodes in the path */ + ret = lyd_new_path2(config, ctx, tree_path, NULL, 0, 0, LYD_NEW_PATH_UPDATE, new_tree, alg_tree); + if (ret) { + ERR(NULL, "Creating new path to transport-params failed."); + goto cleanup; + } + + if (!*alg_tree) { + /* no new nodes added, set the path correctly for adding child nodes later */ + ret = lyd_find_path(config, tree_path, 0, alg_tree); + if (ret) { + goto cleanup; + } + } + +cleanup: + free(tree_path); + return ret; +} + +static int +nc_server_config_ssh_transport_params_create(const struct ly_ctx *ctx, NC_ALG_TYPE alg_type, int alg_count, va_list ap, + struct lyd_node *tree) +{ + int i, ret = 0; + char *alg, *alg_ident; + const char *module, *alg_path, *old_path; + struct lyd_node *old = NULL; + + NC_CHECK_ARG_RET(NULL, ctx, tree, 1); + + /* get the correct module with the indentity base and the path in the ietf-netconf-server module */ + switch (alg_type) { + case NC_ALG_HOSTKEY: + module = "iana-ssh-public-key-algs"; + alg_path = "host-key/host-key-alg"; + old_path = "host-key"; + break; + case NC_ALG_KEY_EXCHANGE: + module = "iana-ssh-key-exchange-algs"; + alg_path = "key-exchange/key-exchange-alg"; + old_path = "key-exchange"; + break; + case NC_ALG_ENCRYPTION: + module = "iana-ssh-encryption-algs"; + alg_path = "encryption/encryption-alg"; + old_path = "encryption"; + break; + case NC_ALG_MAC: + module = "iana-ssh-mac-algs"; + alg_path = "mac/mac-alg"; + old_path = "mac"; + break; + default: + ret = 1; + ERR(NULL, "Unknown algorithm type."); + goto cleanup; + } + + /* delete all older algorithms (if any) se they can be replaced by the new ones */ + lyd_find_path(tree, old_path, 0, &old); + if (old) { + lyd_free_tree(old); + } + + for (i = 0; i < alg_count; i++) { + alg = va_arg(ap, char *); + + if (asprintf(&alg_ident, "%s:%s", module, alg) == -1) { + ERRMEM; + ret = 1; + goto cleanup; + } + + /* create the leaf list */ + ret = lyd_new_path(tree, ctx, alg_path, alg_ident, 0, NULL); + if (ret) { + ERR(NULL, "Creating new algorithm leaf-list failed."); + free(alg_ident); + goto cleanup; + } + + free(alg_ident); + alg_ident = NULL; + } + +cleanup: + return ret; +} + +static int +nc_server_config_ssh_transport_params(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name, + NC_ALG_TYPE alg_type, int alg_count, va_list ap, struct lyd_node **config) +{ + int ret = 0; + struct lyd_node *new_tree, *alg_tree; + + NC_CHECK_ARG_RET(NULL, ctx, endpt_name, config, 1); + + /* prepare the tree for appending child nodes (the params) */ + ret = nc_server_config_ssh_transport_params_prep(ctx, client_name, endpt_name, *config, &new_tree, &alg_tree); + if (ret) { + goto cleanup; + } + + if (!*config) { + *config = new_tree; + } + + /* create the child nodes */ + ret = nc_server_config_ssh_transport_params_create(ctx, alg_type, alg_count, ap, alg_tree); + if (ret) { + goto cleanup; + } + + /* add all default nodes */ + ret = lyd_new_implicit_tree(*config, LYD_IMPLICIT_NO_STATE, NULL); + if (ret) { + goto cleanup; + } + +cleanup: + return ret; +} + +API int +nc_server_config_add_ssh_host_key_algs(const struct ly_ctx *ctx, const char *endpt_name, struct lyd_node **config, + int alg_count, ...) +{ + int ret = 0; + va_list ap; + + NC_CHECK_ARG_RET(NULL, ctx, endpt_name, config, alg_count, 1); + + va_start(ap, alg_count); + + ret = nc_server_config_ssh_transport_params(ctx, NULL, endpt_name, NC_ALG_HOSTKEY, alg_count, ap, config); + if (ret) { + ERR(NULL, "Creating new hostkey algorithms failed."); + goto cleanup; + } + +cleanup: + va_end(ap); + return ret; +} + +API int +nc_server_config_add_ch_ssh_host_key_algs(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name, + struct lyd_node **config, int alg_count, ...) +{ + int ret = 0; + va_list ap; + + NC_CHECK_ARG_RET(NULL, ctx, client_name, endpt_name, config, alg_count, 1); + + va_start(ap, alg_count); + + ret = nc_server_config_ssh_transport_params(ctx, client_name, endpt_name, NC_ALG_HOSTKEY, alg_count, ap, config); + if (ret) { + ERR(NULL, "Creating new hostkey algorithms failed."); + goto cleanup; + } + +cleanup: + va_end(ap); + return ret; +} + +API int +nc_server_config_del_ssh_host_key_alg(const char *endpt_name, const char *alg, struct lyd_node **config) +{ + NC_CHECK_ARG_RET(NULL, endpt_name, config, 1); + + if (alg) { + return nc_server_config_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/" + "ssh/ssh-server-parameters/transport-params/host-key/" + "host-key-alg[.='iana-ssh-public-key-algs:%s']", endpt_name, alg); + } else { + return nc_server_config_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/" + "ssh/ssh-server-parameters/transport-params/host-key", endpt_name); + } +} + +API int +nc_server_config_del_ch_ssh_host_key_alg(const char *client_name, const char *endpt_name, + const char *alg, struct lyd_node **config) +{ + NC_CHECK_ARG_RET(NULL, client_name, endpt_name, config, 1); + + if (alg) { + return nc_server_config_delete(config, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/" + "endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/transport-params/host-key/" + "host-key-alg[.='iana-ssh-public-key-algs:%s']", client_name, endpt_name, alg); + } else { + return nc_server_config_delete(config, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/" + "endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/transport-params/host-key", client_name, endpt_name); + } +} + +API int +nc_server_config_add_ssh_key_exchange_algs(const struct ly_ctx *ctx, const char *endpt_name, struct lyd_node **config, + int alg_count, ...) +{ + int ret = 0; + va_list ap; + + NC_CHECK_ARG_RET(NULL, ctx, endpt_name, config, alg_count, 1); + + va_start(ap, alg_count); + + ret = nc_server_config_ssh_transport_params(ctx, NULL, endpt_name, NC_ALG_KEY_EXCHANGE, alg_count, ap, config); + if (ret) { + ERR(NULL, "Creating new key exchange algorithms failed."); + goto cleanup; + } + +cleanup: + va_end(ap); + return ret; +} + +API int +nc_server_config_add_ch_ssh_key_exchange_algs(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name, + struct lyd_node **config, int alg_count, ...) +{ + int ret = 0; + va_list ap; + + NC_CHECK_ARG_RET(NULL, ctx, client_name, endpt_name, config, alg_count, 1); + + va_start(ap, alg_count); + + ret = nc_server_config_ssh_transport_params(ctx, client_name, endpt_name, NC_ALG_KEY_EXCHANGE, alg_count, ap, config); + if (ret) { + ERR(NULL, "Creating new key exchange algorithms failed."); + goto cleanup; + } + +cleanup: + va_end(ap); + return ret; +} + +API int +nc_server_config_del_ssh_key_exchange_alg(const char *endpt_name, const char *alg, struct lyd_node **config) +{ + NC_CHECK_ARG_RET(NULL, endpt_name, config, 1); + + if (alg) { + return nc_server_config_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/" + "ssh/ssh-server-parameters/transport-params/key-exchange/" + "key-exchange-alg[.='iana-ssh-key-exchange-algs:%s']", endpt_name, alg); + } else { + return nc_server_config_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/" + "ssh/ssh-server-parameters/transport-params/key-exchange", endpt_name); + } +} + +API int +nc_server_config_del_ch_ssh_key_exchange_alg(const char *client_name, const char *endpt_name, + const char *alg, struct lyd_node **config) +{ + NC_CHECK_ARG_RET(NULL, client_name, endpt_name, config, 1); + + if (alg) { + return nc_server_config_delete(config, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/" + "endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/transport-params/key-exchange/" + "key-exchange-alg[.='iana-ssh-key-exchange-algs:%s']", client_name, endpt_name, alg); + } else { + return nc_server_config_delete(config, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/" + "endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/transport-params/key-exchange", client_name, endpt_name); + } +} + +API int +nc_server_config_add_ssh_encryption_algs(const struct ly_ctx *ctx, const char *endpt_name, struct lyd_node **config, + int alg_count, ...) +{ + int ret = 0; + va_list ap; + + NC_CHECK_ARG_RET(NULL, ctx, endpt_name, config, alg_count, 1); + + va_start(ap, alg_count); + + ret = nc_server_config_ssh_transport_params(ctx, NULL, endpt_name, NC_ALG_ENCRYPTION, alg_count, ap, config); + if (ret) { + ERR(NULL, "Creating new encryption algorithms failed."); + goto cleanup; + } + +cleanup: + va_end(ap); + return ret; +} + +API int +nc_server_config_add_ch_ssh_encryption_algs(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name, + struct lyd_node **config, int alg_count, ...) +{ + int ret = 0; + va_list ap; + + NC_CHECK_ARG_RET(NULL, ctx, client_name, endpt_name, config, alg_count, 1); + + va_start(ap, alg_count); + + ret = nc_server_config_ssh_transport_params(ctx, client_name, endpt_name, NC_ALG_ENCRYPTION, alg_count, ap, config); + if (ret) { + ERR(NULL, "Creating new encryption algorithms failed."); + goto cleanup; + } + +cleanup: + va_end(ap); + return ret; +} + +API int +nc_server_config_del_ssh_encryption_alg(const char *endpt_name, const char *alg, struct lyd_node **config) +{ + NC_CHECK_ARG_RET(NULL, endpt_name, config, 1); + + if (alg) { + return nc_server_config_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/" + "ssh/ssh-server-parameters/transport-params/encryption/" + "encryption-alg[.='iana-ssh-encryption-algs:%s']", endpt_name, alg); + } else { + return nc_server_config_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/" + "ssh/ssh-server-parameters/transport-params/encryption", endpt_name); + } +} + +API int +nc_server_config_del_ch_ssh_encryption_alg(const char *client_name, const char *endpt_name, + const char *alg, struct lyd_node **config) +{ + NC_CHECK_ARG_RET(NULL, client_name, endpt_name, config, 1); + + if (alg) { + return nc_server_config_delete(config, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/" + "endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/transport-params/encryption/" + "encryption-alg[.='iana-ssh-encryption-algs:%s']", client_name, endpt_name, alg); + } else { + return nc_server_config_delete(config, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/" + "endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/transport-params/encryption", client_name, endpt_name); + } +} + +API int +nc_server_config_add_ssh_mac_algs(const struct ly_ctx *ctx, const char *endpt_name, struct lyd_node **config, + int alg_count, ...) +{ + int ret = 0; + va_list ap; + + NC_CHECK_ARG_RET(NULL, ctx, endpt_name, config, alg_count, 1); + + va_start(ap, alg_count); + + ret = nc_server_config_ssh_transport_params(ctx, NULL, endpt_name, NC_ALG_MAC, alg_count, ap, config); + if (ret) { + ERR(NULL, "Creating new mac algorithms failed."); + goto cleanup; + } + +cleanup: + va_end(ap); + return ret; +} + +API int +nc_server_config_add_ch_ssh_mac_algs(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name, + struct lyd_node **config, int alg_count, ...) +{ + int ret = 0; + va_list ap; + + NC_CHECK_ARG_RET(NULL, ctx, client_name, endpt_name, config, alg_count, 1); + + va_start(ap, alg_count); + + ret = nc_server_config_ssh_transport_params(ctx, client_name, endpt_name, NC_ALG_MAC, alg_count, ap, config); + if (ret) { + ERR(NULL, "Creating new mac algorithms failed."); + goto cleanup; + } + +cleanup: + va_end(ap); + return ret; +} + +API int +nc_server_config_del_ssh_mac_alg(const char *endpt_name, const char *alg, struct lyd_node **config) +{ + NC_CHECK_ARG_RET(NULL, endpt_name, config, 1); + + if (alg) { + return nc_server_config_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/" + "ssh/ssh-server-parameters/transport-params/mac/" + "mac-alg[.='iana-ssh-mac-algs:%s']", endpt_name, alg); + } else { + return nc_server_config_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/" + "ssh/ssh-server-parameters/transport-params/mac", endpt_name); + } +} + +API int +nc_server_config_del_ch_ssh_mac_alg(const char *client_name, const char *endpt_name, + const char *alg, struct lyd_node **config) +{ + NC_CHECK_ARG_RET(NULL, client_name, endpt_name, config, 1); + + if (alg) { + return nc_server_config_delete(config, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/" + "endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/transport-params/mac/" + "mac-alg[.='iana-ssh-mac-algs:%s']", client_name, endpt_name, alg); + } else { + return nc_server_config_delete(config, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/" + "endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/transport-params/mac", client_name, endpt_name); + } +} diff --git a/src/server_config_util_tls.c b/src/server_config_util_tls.c index 0d628f60..20837c24 100644 --- a/src/server_config_util_tls.c +++ b/src/server_config_util_tls.c @@ -33,7 +33,7 @@ #include "session_p.h" static int -_nc_server_config_add_tls_server_cert(const struct ly_ctx *ctx, const char *tree_path, const char *privkey_path, +_nc_server_config_add_tls_server_certificate(const struct ly_ctx *ctx, const char *tree_path, const char *privkey_path, const char *pubkey_path, const char *certificate_path, struct lyd_node **config) { int ret = 0; @@ -103,7 +103,7 @@ _nc_server_config_add_tls_server_cert(const struct ly_ctx *ctx, const char *tree } API int -nc_server_config_add_tls_server_cert(const struct ly_ctx *ctx, const char *endpt_name, const char *privkey_path, +nc_server_config_add_tls_server_certificate(const struct ly_ctx *ctx, const char *endpt_name, const char *privkey_path, const char *pubkey_path, const char *certificate_path, struct lyd_node **config) { int ret = 0; @@ -119,7 +119,7 @@ nc_server_config_add_tls_server_cert(const struct ly_ctx *ctx, const char *endpt goto cleanup; } - ret = _nc_server_config_add_tls_server_cert(ctx, path, privkey_path, pubkey_path, + ret = _nc_server_config_add_tls_server_certificate(ctx, path, privkey_path, pubkey_path, certificate_path, config); if (ret) { ERR(NULL, "Creating new TLS server certificate YANG data failed."); @@ -132,7 +132,7 @@ nc_server_config_add_tls_server_cert(const struct ly_ctx *ctx, const char *endpt } API int -nc_server_config_del_tls_server_cert(const char *endpt_name, struct lyd_node **config) +nc_server_config_del_tls_server_certificate(const char *endpt_name, struct lyd_node **config) { NC_CHECK_ARG_RET(NULL, endpt_name, config, 1); @@ -141,7 +141,7 @@ nc_server_config_del_tls_server_cert(const char *endpt_name, struct lyd_node **c } API int -nc_server_config_add_ch_tls_server_cert(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name, +nc_server_config_add_ch_tls_server_certificate(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name, const char *privkey_path, const char *pubkey_path, const char *certificate_path, struct lyd_node **config) { int ret = 0; @@ -158,7 +158,7 @@ nc_server_config_add_ch_tls_server_cert(const struct ly_ctx *ctx, const char *cl goto cleanup; } - ret = _nc_server_config_add_tls_server_cert(ctx, path, privkey_path, pubkey_path, + ret = _nc_server_config_add_tls_server_certificate(ctx, path, privkey_path, pubkey_path, certificate_path, config); if (ret) { ERR(NULL, "Creating new CH TLS server certificate YANG data failed."); @@ -171,7 +171,7 @@ nc_server_config_add_ch_tls_server_cert(const struct ly_ctx *ctx, const char *cl } API int -nc_server_config_del_ch_tls_server_cert(const char *client_name, const char *endpt_name, +nc_server_config_del_ch_tls_server_certificate(const char *client_name, const char *endpt_name, struct lyd_node **config) { NC_CHECK_ARG_RET(NULL, client_name, endpt_name, config, 1); @@ -182,7 +182,109 @@ nc_server_config_del_ch_tls_server_cert(const char *client_name, const char *end } static int -_nc_server_config_add_tls_client_cert(const struct ly_ctx *ctx, const char *tree_path, +_nc_server_config_add_tls_keystore_ref(const struct ly_ctx *ctx, const char *tree_path, const char *asym_key_ref, + const char *cert_ref, struct lyd_node **config) +{ + int ret = 0; + + /* create asymmetric key pair reference */ + ret = nc_server_config_append(ctx, tree_path, "keystore-reference/asymmetric-key", asym_key_ref, config); + if (ret) { + goto cleanup; + } + + /* create cert reference, this cert has to belong to the asym key */ + ret = nc_server_config_append(ctx, tree_path, "keystore-reference/certificate", cert_ref, config); + if (ret) { + goto cleanup; + } + + /* delete inline definition if present */ + ret = nc_server_config_check_delete(config, "%s/inline-definition", tree_path); + if (ret) { + goto cleanup; + } + +cleanup: + return ret; +} + +API int +nc_server_config_add_tls_keystore_ref(const struct ly_ctx *ctx, const char *endpt_name, const char *asym_key_ref, + const char *cert_ref, struct lyd_node **config) +{ + int ret = 0; + char *path = NULL; + + NC_CHECK_ARG_RET(NULL, ctx, endpt_name, asym_key_ref, cert_ref, config, 1); + + if (asprintf(&path, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/" + "tls/tls-server-parameters/server-identity/certificate", endpt_name) == -1) { + ERRMEM; + path = NULL; + ret = 1; + goto cleanup; + } + + ret = _nc_server_config_add_tls_keystore_ref(ctx, path, asym_key_ref, cert_ref, config); + if (ret) { + goto cleanup; + } + +cleanup: + free(path); + return ret; +} + +API int +nc_server_config_del_tls_keystore_ref(const char *endpt_name, struct lyd_node **config) +{ + NC_CHECK_ARG_RET(NULL, endpt_name, config, 1); + + return nc_server_config_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/" + "tls/tls-server-parameters/server-identity/certificate/keystore-reference", endpt_name); +} + +API int +nc_server_config_add_ch_tls_keystore_ref(const struct ly_ctx *ctx, const char *client_name, + const char *endpt_name, const char *asym_key_ref, const char *cert_ref, struct lyd_node **config) +{ + int ret = 0; + char *path = NULL; + + NC_CHECK_ARG_RET(NULL, ctx, client_name, endpt_name, asym_key_ref, cert_ref, config, 1); + + if (asprintf(&path, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/endpoints/" + "endpoint[name='%s']/tls/tls-server-parameters/server-identity/certificate", client_name, endpt_name) == -1) { + ERRMEM; + path = NULL; + ret = 1; + goto cleanup; + } + + ret = _nc_server_config_add_tls_keystore_ref(ctx, path, asym_key_ref, cert_ref, config); + if (ret) { + goto cleanup; + } + +cleanup: + free(path); + return ret; +} + +API int +nc_server_config_del_ch_tls_keystore_ref(const char *client_name, const char *endpt_name, + struct lyd_node **config) +{ + NC_CHECK_ARG_RET(NULL, client_name, endpt_name, config, 1); + + return nc_server_config_delete(config, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/" + "endpoints/endpoint[name='%s']/tls/tls-server-parameters/server-identity/certificate/" + "keystore-reference", client_name, endpt_name); +} + +static int +_nc_server_config_add_tls_client_certificate(const struct ly_ctx *ctx, const char *tree_path, const char *cert_path, struct lyd_node **config) { int ret = 0; @@ -207,7 +309,7 @@ _nc_server_config_add_tls_client_cert(const struct ly_ctx *ctx, const char *tree } API int -nc_server_config_add_tls_client_cert(const struct ly_ctx *ctx, const char *endpt_name, const char *cert_name, +nc_server_config_add_tls_client_certificate(const struct ly_ctx *ctx, const char *endpt_name, const char *cert_name, const char *cert_path, struct lyd_node **config) { int ret = 0; @@ -223,7 +325,7 @@ nc_server_config_add_tls_client_cert(const struct ly_ctx *ctx, const char *endpt goto cleanup; } - ret = _nc_server_config_add_tls_client_cert(ctx, path, cert_path, config); + ret = _nc_server_config_add_tls_client_certificate(ctx, path, cert_path, config); if (ret) { ERR(NULL, "Creating new TLS client certificate YANG data failed."); goto cleanup; @@ -242,7 +344,7 @@ nc_server_config_add_tls_client_cert(const struct ly_ctx *ctx, const char *endpt } API int -nc_server_config_del_tls_client_cert(const char *endpt_name, const char *cert_name, struct lyd_node **config) +nc_server_config_del_tls_client_certificate(const char *endpt_name, const char *cert_name, struct lyd_node **config) { NC_CHECK_ARG_RET(NULL, endpt_name, config, 1); @@ -258,7 +360,7 @@ nc_server_config_del_tls_client_cert(const char *endpt_name, const char *cert_na } API int -nc_server_config_add_ch_tls_client_cert(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name, +nc_server_config_add_ch_tls_client_certificate(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name, const char *cert_name, const char *cert_path, struct lyd_node **config) { int ret = 0; @@ -275,7 +377,7 @@ nc_server_config_add_ch_tls_client_cert(const struct ly_ctx *ctx, const char *cl goto cleanup; } - ret = _nc_server_config_add_tls_client_cert(ctx, path, cert_path, config); + ret = _nc_server_config_add_tls_client_certificate(ctx, path, cert_path, config); if (ret) { ERR(NULL, "Creating new CH TLS client certificate YANG data failed."); goto cleanup; @@ -295,7 +397,7 @@ nc_server_config_add_ch_tls_client_cert(const struct ly_ctx *ctx, const char *cl } API int -nc_server_config_del_ch_tls_client_cert(const char *client_name, const char *endpt_name, +nc_server_config_del_ch_tls_client_certificate(const char *client_name, const char *endpt_name, const char *cert_name, struct lyd_node **config) { NC_CHECK_ARG_RET(NULL, client_name, endpt_name, config, 1); @@ -312,7 +414,79 @@ nc_server_config_del_ch_tls_client_cert(const char *client_name, const char *end } API int -nc_server_config_add_tls_ca_cert(const struct ly_ctx *ctx, const char *endpt_name, const char *cert_name, +nc_server_config_add_tls_client_cert_truststore_ref(const struct ly_ctx *ctx, const char *endpt_name, + const char *cert_bag_ref, struct lyd_node **config) +{ + int ret = 0; + + NC_CHECK_ARG_RET(NULL, ctx, endpt_name, cert_bag_ref, config, 1); + + ret = nc_server_config_create(ctx, config, cert_bag_ref, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/tls/" + "tls-server-parameters/client-authentication/ee-certs/truststore-reference", endpt_name); + if (ret) { + goto cleanup; + } + + /* delete inline definition if present */ + ret = nc_server_config_check_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/tls/" + "tls-server-parameters/client-authentication/ee-certs/inline-definition", endpt_name); + if (ret) { + goto cleanup; + } + +cleanup: + return ret; +} + +API int +nc_server_config_del_tls_client_cert_truststore_ref(const char *endpt_name, struct lyd_node **config) +{ + NC_CHECK_ARG_RET(NULL, endpt_name, config, 1); + + return nc_server_config_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/tls/" + "tls-server-parameters/client-authentication/ee-certs/truststore-reference", endpt_name); +} + +API int +nc_server_config_add_ch_tls_client_cert_truststore_ref(const struct ly_ctx *ctx, const char *client_name, + const char *endpt_name, const char *cert_bag_ref, struct lyd_node **config) +{ + int ret = 0; + + NC_CHECK_ARG_RET(NULL, ctx, client_name, endpt_name, cert_bag_ref, config, 1); + + ret = nc_server_config_create(ctx, config, cert_bag_ref, "/ietf-netconf-server:netconf-server/call-home/" + "netconf-client[name='%s']/endpoints/endpoint[name='%s']/tls/tls-server-parameters/" + "client-authentication/ee-certs/truststore-reference", client_name, endpt_name); + if (ret) { + goto cleanup; + } + + /* delete inline definition if present */ + ret = nc_server_config_check_delete(config, "/ietf-netconf-server:netconf-server/call-home/" + "netconf-client[name='%s']/endpoints/endpoint[name='%s']/tls/" + "tls-server-parameters/client-authentication/ee-certs/inline-definition", client_name, endpt_name); + if (ret) { + goto cleanup; + } + +cleanup: + return ret; +} + +API int +nc_server_config_del_ch_tls_client_cert_truststore_ref(const char *client_name, const char *endpt_name, + struct lyd_node **config) +{ + NC_CHECK_ARG_RET(NULL, client_name, endpt_name, config, 1); + + return nc_server_config_delete(config, "/ietf-netconf-server:netconf-server/call-home/" + "netconf-client[name='%s']/endpoints/endpoint[name='%s']/tls/tls-server-parameters/" + "client-authentication/ee-certs/truststore-reference", client_name, endpt_name); +} + +API int +nc_server_config_add_tls_client_ca(const struct ly_ctx *ctx, const char *endpt_name, const char *cert_name, const char *cert_path, struct lyd_node **config) { int ret = 0; @@ -328,7 +502,7 @@ nc_server_config_add_tls_ca_cert(const struct ly_ctx *ctx, const char *endpt_nam goto cleanup; } - ret = _nc_server_config_add_tls_client_cert(ctx, path, cert_path, config); + ret = _nc_server_config_add_tls_client_certificate(ctx, path, cert_path, config); if (ret) { ERR(NULL, "Creating new TLS client certificate authority YANG data failed."); goto cleanup; @@ -347,7 +521,7 @@ nc_server_config_add_tls_ca_cert(const struct ly_ctx *ctx, const char *endpt_nam } API int -nc_server_config_del_tls_ca_cert(const char *endpt_name, const char *cert_name, struct lyd_node **config) +nc_server_config_del_tls_client_ca(const char *endpt_name, const char *cert_name, struct lyd_node **config) { NC_CHECK_ARG_RET(NULL, endpt_name, config, 1); @@ -363,7 +537,7 @@ nc_server_config_del_tls_ca_cert(const char *endpt_name, const char *cert_name, } API int -nc_server_config_add_ch_tls_ca_cert(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name, +nc_server_config_add_ch_tls_client_ca(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name, const char *cert_name, const char *cert_path, struct lyd_node **config) { int ret = 0; @@ -380,7 +554,7 @@ nc_server_config_add_ch_tls_ca_cert(const struct ly_ctx *ctx, const char *client goto cleanup; } - ret = _nc_server_config_add_tls_client_cert(ctx, path, cert_path, config); + ret = _nc_server_config_add_tls_client_certificate(ctx, path, cert_path, config); if (ret) { ERR(NULL, "Creating new CH TLS client certificate authority YANG data failed."); goto cleanup; @@ -400,7 +574,7 @@ nc_server_config_add_ch_tls_ca_cert(const struct ly_ctx *ctx, const char *client } API int -nc_server_config_del_ch_tls_ca_cert(const char *client_name, const char *endpt_name, +nc_server_config_del_ch_tls_client_ca(const char *client_name, const char *endpt_name, const char *cert_name, struct lyd_node **config) { NC_CHECK_ARG_RET(NULL, client_name, endpt_name, config, 1); @@ -416,6 +590,78 @@ nc_server_config_del_ch_tls_ca_cert(const char *client_name, const char *endpt_n } } +API int +nc_server_config_add_tls_client_ca_truststore_ref(const struct ly_ctx *ctx, const char *endpt_name, + const char *cert_bag_ref, struct lyd_node **config) +{ + int ret = 0; + + NC_CHECK_ARG_RET(NULL, ctx, endpt_name, cert_bag_ref, config, 1); + + ret = nc_server_config_create(ctx, config, cert_bag_ref, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/tls/" + "tls-server-parameters/client-authentication/ca-certs/truststore-reference", endpt_name); + if (ret) { + goto cleanup; + } + + /* delete inline definition if present */ + ret = nc_server_config_check_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/tls/" + "tls-server-parameters/client-authentication/ca-certs/inline-definition", endpt_name); + if (ret) { + goto cleanup; + } + +cleanup: + return ret; +} + +API int +nc_server_config_del_tls_client_ca_truststore_ref(const char *endpt_name, struct lyd_node **config) +{ + NC_CHECK_ARG_RET(NULL, endpt_name, config, 1); + + return nc_server_config_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/tls/" + "tls-server-parameters/client-authentication/ca-certs/truststore-reference", endpt_name); +} + +API int +nc_server_config_add_ch_tls_client_ca_truststore_ref(const struct ly_ctx *ctx, const char *client_name, + const char *endpt_name, const char *cert_bag_ref, struct lyd_node **config) +{ + int ret = 0; + + NC_CHECK_ARG_RET(NULL, ctx, client_name, endpt_name, cert_bag_ref, config, 1); + + ret = nc_server_config_create(ctx, config, cert_bag_ref, "/ietf-netconf-server:netconf-server/call-home/" + "netconf-client[name='%s']/endpoints/endpoint[name='%s']/tls/tls-server-parameters/" + "client-authentication/ca-certs/truststore-reference", client_name, endpt_name); + if (ret) { + goto cleanup; + } + + /* delete inline definition if present */ + ret = nc_server_config_check_delete(config, "/ietf-netconf-server:netconf-server/call-home/" + "netconf-client[name='%s']/endpoints/endpoint[name='%s']/tls/tls-server-parameters/" + "client-authentication/ca-certs/inline-definition", client_name, endpt_name); + if (ret) { + goto cleanup; + } + +cleanup: + return ret; +} + +API int +nc_server_config_del_ch_tls_client_ca_truststore_ref(const char *client_name, const char *endpt_name, + struct lyd_node **config) +{ + NC_CHECK_ARG_RET(NULL, client_name, endpt_name, config, 1); + + return nc_server_config_delete(config, "/ietf-netconf-server:netconf-server/call-home/" + "netconf-client[name='%s']/endpoints/endpoint[name='%s']/tls/tls-server-parameters/" + "client-authentication/ca-certs/truststore-reference", client_name, endpt_name); +} + static const char * nc_server_config_tls_maptype2str(NC_TLS_CTN_MAPTYPE map_type) { @@ -565,6 +811,562 @@ nc_server_config_del_ch_tls_ctn(const char *client_name, const char *endpt_name, } } +static const char * +nc_server_config_tlsversion2str(NC_TLS_VERSION version) +{ + switch (version) { + case NC_TLS_VERSION_10: + return "ietf-tls-common:tls10"; + case NC_TLS_VERSION_11: + return "ietf-tls-common:tls11"; + case NC_TLS_VERSION_12: + return "ietf-tls-common:tls12"; + case NC_TLS_VERSION_13: + return "ietf-tls-common:tls13"; + default: + ERR(NULL, "Unknown TLS version."); + return NULL; + } +} + +API int +nc_server_config_add_tls_version(const struct ly_ctx *ctx, const char *endpt_name, + NC_TLS_VERSION tls_version, struct lyd_node **config) +{ + int ret = 0; + const char *version; + + NC_CHECK_ARG_RET(NULL, ctx, endpt_name, config, 1); + + /* version to str */ + version = nc_server_config_tlsversion2str(tls_version); + if (!version) { + ret = 1; + goto cleanup; + } + + ret = nc_server_config_create(ctx, config, version, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/tls/tls-server-parameters/" + "hello-params/tls-versions/tls-version", endpt_name); + if (ret) { + ERR(NULL, "Creating new YANG data nodes for TLS version failed."); + goto cleanup; + } + +cleanup: + return ret; +} + +API int +nc_server_config_add_ch_tls_version(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name, + NC_TLS_VERSION tls_version, struct lyd_node **config) +{ + int ret = 0; + const char *version; + + NC_CHECK_ARG_RET(NULL, ctx, client_name, endpt_name, config, 1); + + /* version to str */ + version = nc_server_config_tlsversion2str(tls_version); + if (!version) { + ret = 1; + goto cleanup; + } + + ret = nc_server_config_create(ctx, config, version, "/ietf-netconf-server:netconf-server/call-home/" + "netconf-client[name='%s']/endpoints/endpoint[name='%s']/tls/tls-server-parameters/" + "hello-params/tls-versions/tls-version", client_name, endpt_name); + if (ret) { + ERR(NULL, "Creating new YANG data nodes for CH TLS version failed."); + goto cleanup; + } + +cleanup: + return ret; +} + +API int +nc_server_config_del_tls_version(const char *endpt_name, NC_TLS_VERSION tls_version, struct lyd_node **config) +{ + int ret = 0; + const char *version; + + NC_CHECK_ARG_RET(NULL, endpt_name, config, 1); + + /* version to str */ + version = nc_server_config_tlsversion2str(tls_version); + if (!version) { + ret = 1; + goto cleanup; + } + + ret = nc_server_config_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/tls/" + "tls-server-parameters/hello-params/tls-versions/tls-version[.='%s']", endpt_name, version); + +cleanup: + return ret; +} + +API int +nc_server_config_del_ch_tls_version(const char *client_name, const char *endpt_name, + NC_TLS_VERSION tls_version, struct lyd_node **config) +{ + int ret = 0; + const char *version; + + NC_CHECK_ARG_RET(NULL, client_name, endpt_name, config, 1); + + /* version to str */ + version = nc_server_config_tlsversion2str(tls_version); + if (!version) { + ret = 1; + goto cleanup; + } + + ret = nc_server_config_delete(config, "/ietf-netconf-server:netconf-server/call-home/" + "netconf-client[name='%s']/endpoints/endpoint[name='%s']/tls/" + "tls-server-parameters/hello-params/tls-versions/tls-version[.='%s']", client_name, endpt_name, version); + +cleanup: + return ret; +} + +static int +_nc_server_config_add_tls_ciphers(const struct ly_ctx *ctx, const char *tree_path, + int cipher_count, va_list ap, struct lyd_node **config) +{ + int ret = 0, i; + struct lyd_node *old = NULL; + char *cipher = NULL, *cipher_ident = NULL; + + NC_CHECK_ARG_RET(NULL, ctx, tree_path, config, 1); + + /* delete all older algorithms (if any) se they can be replaced by the new ones */ + lyd_find_path(*config, tree_path, 0, &old); + if (old) { + lyd_free_tree(old); + } + + for (i = 0; i < cipher_count; i++) { + cipher = va_arg(ap, char *); + + if (asprintf(&cipher_ident, "iana-tls-cipher-suite-algs:%s", cipher) == -1) { + ERRMEM; + ret = 1; + goto cleanup; + } + + ret = nc_server_config_append(ctx, tree_path, "cipher-suite", cipher_ident, config); + if (ret) { + free(cipher_ident); + goto cleanup; + } + + free(cipher_ident); + cipher_ident = NULL; + } + +cleanup: + return ret; +} + +API int +nc_server_config_add_tls_ciphers(const struct ly_ctx *ctx, const char *endpt_name, struct lyd_node **config, + int cipher_count, ...) +{ + int ret = 0; + va_list ap; + char *path = NULL; + + NC_CHECK_ARG_RET(NULL, ctx, endpt_name, cipher_count, config, 1); + + va_start(ap, cipher_count); + + if (asprintf(&path, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/tls/" + "tls-server-parameters/hello-params/cipher-suites", endpt_name) == -1) { + ERRMEM; + path = NULL; + ret = 1; + goto cleanup; + } + + ret = _nc_server_config_add_tls_ciphers(ctx, path, cipher_count, ap, config); + if (ret) { + ERR(NULL, "Creating new TLS cipher YANG data nodes failed."); + goto cleanup; + } + +cleanup: + va_end(ap); + free(path); + return ret; +} + +API int +nc_server_config_add_ch_tls_ciphers(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name, + struct lyd_node **config, int cipher_count, ...) +{ + int ret = 0; + va_list ap; + char *path = NULL; + + NC_CHECK_ARG_RET(NULL, ctx, client_name, endpt_name, cipher_count, config, 1); + + va_start(ap, cipher_count); + + if (asprintf(&path, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/endpoints/" + "endpoint[name='%s']/tls/tls-server-parameters/hello-params/cipher-suites", client_name, endpt_name) == -1) { + ERRMEM; + path = NULL; + ret = 1; + goto cleanup; + } + + ret = _nc_server_config_add_tls_ciphers(ctx, path, cipher_count, ap, config); + if (ret) { + ERR(NULL, "Creating new Call-Home TLS cipher YANG data nodes failed."); + goto cleanup; + } + +cleanup: + va_end(ap); + free(path); + return ret; +} + +API int +nc_server_config_del_tls_cipher(const char *endpt_name, const char *cipher, struct lyd_node **config) +{ + NC_CHECK_ARG_RET(NULL, endpt_name, cipher, config, 1); + + return nc_server_config_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/" + "tls/tls-server-parameters/hello-params/cipher-suites/" + "cipher-suite[.='iana-tls-cipher-suite-algs:%s']", endpt_name, cipher); +} + +API int +nc_server_config_del_ch_tls_cipher(const char *client_name, const char *endpt_name, + const char *cipher, struct lyd_node **config) +{ + NC_CHECK_ARG_RET(NULL, client_name, endpt_name, cipher, config, 1); + + return nc_server_config_delete(config, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/" + "endpoints/endpoint[name='%s']/tls/tls-server-parameters/hello-params/cipher-suites/" + "cipher-suite[.='iana-tls-cipher-suite-algs:%s']", client_name, endpt_name, cipher); +} + +static int +_nc_server_config_add_tls_crl_path(const struct ly_ctx *ctx, const char *tree_path, + const char *crl_path, struct lyd_node **config) +{ + int ret = 0; + + NC_CHECK_ARG_RET(NULL, ctx, tree_path, crl_path, config, 1); + + /* create the crl path node */ + ret = nc_server_config_append(ctx, tree_path, "libnetconf2-netconf-server:crl-path", crl_path, config); + if (ret) { + goto cleanup; + } + + /* delete other choice nodes if they are present */ + ret = nc_server_config_check_delete(config, "%s/libnetconf2-netconf-server:crl-url", tree_path); + if (ret) { + goto cleanup; + } + ret = nc_server_config_check_delete(config, "%s/libnetconf2-netconf-server:crl-cert-ext", tree_path); + if (ret) { + goto cleanup; + } + +cleanup: + return ret; +} + +API int +nc_server_config_add_tls_crl_path(const struct ly_ctx *ctx, const char *endpt_name, + const char *crl_path, struct lyd_node **config) +{ + int ret = 0; + char *path = NULL; + + NC_CHECK_ARG_RET(NULL, ctx, endpt_name, crl_path, config, 1); + + if (asprintf(&path, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/tls/tls-server-parameters/" + "client-authentication", endpt_name) == -1) { + ERRMEM; + path = NULL; + ret = 1; + goto cleanup; + } + + ret = _nc_server_config_add_tls_crl_path(ctx, path, crl_path, config); + if (ret) { + ERR(NULL, "Creating new CRL YANG data nodes failed."); + goto cleanup; + } + +cleanup: + free(path); + return ret; +} + +API int +nc_server_config_add_ch_tls_crl_path(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name, + const char *crl_path, struct lyd_node **config) +{ + int ret = 0; + char *path = NULL; + + NC_CHECK_ARG_RET(NULL, ctx, client_name, endpt_name, crl_path, config, 1); + + if (asprintf(&path, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/" + "endpoints/endpoint[name='%s']/tls/tls-server-parameters/" + "client-authentication", client_name, endpt_name) == -1) { + ERRMEM; + path = NULL; + ret = 1; + goto cleanup; + } + + ret = _nc_server_config_add_tls_crl_path(ctx, path, crl_path, config); + if (ret) { + ERR(NULL, "Creating new CH CRL YANG data nodes failed."); + goto cleanup; + } + +cleanup: + free(path); + return ret; +} + +static int +_nc_server_config_add_tls_crl_url(const struct ly_ctx *ctx, const char *tree_path, + const char *crl_url, struct lyd_node **config) +{ + int ret = 0; + + NC_CHECK_ARG_RET(NULL, ctx, tree_path, crl_url, config, 1); + + /* create the crl path node */ + ret = nc_server_config_append(ctx, tree_path, "libnetconf2-netconf-server:crl-url", crl_url, config); + if (ret) { + goto cleanup; + } + + /* delete other choice nodes if they are present */ + ret = nc_server_config_check_delete(config, "%s/libnetconf2-netconf-server:crl-path", tree_path); + if (ret) { + goto cleanup; + } + ret = nc_server_config_check_delete(config, "%s/libnetconf2-netconf-server:crl-cert-ext", tree_path); + if (ret) { + goto cleanup; + } + +cleanup: + return ret; +} + +API int +nc_server_config_add_tls_crl_url(const struct ly_ctx *ctx, const char *endpt_name, const char *crl_url, struct lyd_node **config) +{ + int ret = 0; + char *path = NULL; + + NC_CHECK_ARG_RET(NULL, ctx, endpt_name, crl_url, config, 1); + + if (asprintf(&path, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/tls/tls-server-parameters/" + "client-authentication", endpt_name) == -1) { + ERRMEM; + path = NULL; + ret = 1; + goto cleanup; + } + + ret = _nc_server_config_add_tls_crl_url(ctx, path, crl_url, config); + if (ret) { + ERR(NULL, "Creating new CRL YANG data nodes failed."); + goto cleanup; + } + +cleanup: + free(path); + return ret; +} + +API int +nc_server_config_add_ch_tls_crl_url(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name, + const char *crl_url, struct lyd_node **config) +{ + int ret = 0; + char *path = NULL; + + NC_CHECK_ARG_RET(NULL, ctx, client_name, endpt_name, crl_url, config, 1); + + if (asprintf(&path, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/" + "endpoints/endpoint[name='%s']/tls/tls-server-parameters/" + "client-authentication", client_name, endpt_name) == -1) { + ERRMEM; + path = NULL; + ret = 1; + goto cleanup; + } + + ret = _nc_server_config_add_tls_crl_url(ctx, path, crl_url, config); + if (ret) { + ERR(NULL, "Creating new CH CRL YANG data nodes failed."); + goto cleanup; + } + +cleanup: + free(path); + return ret; +} + +static int +_nc_server_config_add_tls_crl_cert_ext(const struct ly_ctx *ctx, const char *tree_path, struct lyd_node **config) +{ + int ret = 0; + + NC_CHECK_ARG_RET(NULL, ctx, tree_path, config, 1); + + /* create the crl path node */ + ret = nc_server_config_append(ctx, tree_path, "libnetconf2-netconf-server:crl-cert-ext", NULL, config); + if (ret) { + goto cleanup; + } + + /* delete other choice nodes if they are present */ + ret = nc_server_config_check_delete(config, "%s/libnetconf2-netconf-server:crl-path", tree_path); + if (ret) { + goto cleanup; + } + ret = nc_server_config_check_delete(config, "%s/libnetconf2-netconf-server:crl-url", tree_path); + if (ret) { + goto cleanup; + } + +cleanup: + return ret; +} + +API int +nc_server_config_add_tls_crl_cert_ext(const struct ly_ctx *ctx, const char *endpt_name, struct lyd_node **config) +{ + int ret = 0; + char *path = NULL; + + NC_CHECK_ARG_RET(NULL, ctx, endpt_name, config, 1); + + if (asprintf(&path, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/tls/tls-server-parameters/" + "client-authentication", endpt_name) == -1) { + ERRMEM; + path = NULL; + ret = 1; + goto cleanup; + } + + ret = _nc_server_config_add_tls_crl_cert_ext(ctx, path, config); + if (ret) { + ERR(NULL, "Creating new CRL YANG data nodes failed."); + goto cleanup; + } + +cleanup: + free(path); + return ret; +} + +API int +nc_server_config_add_ch_tls_crl_cert_ext(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name, + struct lyd_node **config) +{ + int ret = 0; + char *path = NULL; + + NC_CHECK_ARG_RET(NULL, ctx, client_name, endpt_name, config, 1); + + if (asprintf(&path, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/" + "endpoints/endpoint[name='%s']/tls/tls-server-parameters/" + "client-authentication", client_name, endpt_name) == -1) { + ERRMEM; + path = NULL; + ret = 1; + goto cleanup; + } + + ret = _nc_server_config_add_tls_crl_cert_ext(ctx, path, config); + if (ret) { + ERR(NULL, "Creating new CH CRL YANG data nodes failed."); + goto cleanup; + } + +cleanup: + free(path); + return ret; +} + +API int +nc_server_config_del_tls_crl(const char *endpt_name, struct lyd_node **config) +{ + int ret = 0; + + NC_CHECK_ARG_RET(NULL, endpt_name, config, 1); + + ret = nc_server_config_check_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/tls/tls-server-parameters/" + "client-authentication/libnetconf2-netconf-server:crl-path", endpt_name); + if (ret) { + goto cleanup; + } + + ret = nc_server_config_check_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/tls/tls-server-parameters/" + "client-authentication/libnetconf2-netconf-server:crl-url", endpt_name); + if (ret) { + goto cleanup; + } + + ret = nc_server_config_check_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/tls/tls-server-parameters/" + "client-authentication/libnetconf2-netconf-server:crl-cert-ext", endpt_name); + if (ret) { + goto cleanup; + } + +cleanup: + return ret; +} + +API int +nc_server_config_del_ch_tls_crl(const char *client_name, const char *endpt_name, struct lyd_node **config) +{ + int ret = 0; + + NC_CHECK_ARG_RET(NULL, client_name, endpt_name, config, 1); + + ret = nc_server_config_check_delete(config, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/" + "endpoints/endpoint[name='%s']/tls/tls-server-parameters/" + "client-authentication/libnetconf2-netconf-server:crl-path", client_name, endpt_name); + if (ret) { + goto cleanup; + } + + ret = nc_server_config_check_delete(config, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/" + "endpoints/endpoint[name='%s']/tls/tls-server-parameters/" + "client-authentication/libnetconf2-netconf-server:crl-url", client_name, endpt_name); + if (ret) { + goto cleanup; + } + + ret = nc_server_config_check_delete(config, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/" + "endpoints/endpoint[name='%s']/tls/tls-server-parameters/" + "client-authentication/libnetconf2-netconf-server:crl-cert-ext", client_name, endpt_name); + if (ret) { + goto cleanup; + } + +cleanup: + return ret; +} + API int nc_server_config_add_tls_endpoint_client_ref(const struct ly_ctx *ctx, const char *endpt_name, const char *referenced_endpt, struct lyd_node **config) { diff --git a/tests/test_auth.c b/tests/test_auth.c index 631a84a5..a7021800 100644 --- a/tests/test_auth.c +++ b/tests/test_auth.c @@ -1,7 +1,7 @@ /** * @file test_auth.c * @author Roman Janota - * @brief libnetconf2 SSH authentication methods test + * @brief libnetconf2 Linux PAM keyboard-interactive authentication test * * @copyright * Copyright (c) 2022 CESNET, z.s.p.o. @@ -330,8 +330,7 @@ setup_f(void **state) ret = nc_server_config_add_ssh_user_password(ctx, "endpt", "test_pw", "testpw", &tree); assert_int_equal(ret, 0); - ret = lyd_new_path(tree, ctx, "/ietf-netconf-server:netconf-server/listen/endpoint[name='endpt']/ssh/ssh-server-parameters/" - "client-authentication/users/user[name='test_none']/none", NULL, 0, NULL); + ret = nc_server_config_add_ssh_user_none(ctx, "endpt", "test_none", &tree); assert_int_equal(ret, 0); /* configure the server based on the data */ diff --git a/tests/test_ch.c b/tests/test_ch.c index 558e29a2..a4d5f14d 100644 --- a/tests/test_ch.c +++ b/tests/test_ch.c @@ -404,15 +404,15 @@ setup_tls(void **state) assert_int_equal(ret, 0); /* set call-home server certificate */ - ret = nc_server_config_add_ch_tls_server_cert(ctx, "ch_tls", "endpt", TESTS_DIR "/data/server.key", NULL, TESTS_DIR "/data/server.crt", &test_state->tls_tree); + ret = nc_server_config_add_ch_tls_server_certificate(ctx, "ch_tls", "endpt", TESTS_DIR "/data/server.key", NULL, TESTS_DIR "/data/server.crt", &test_state->tls_tree); assert_int_equal(ret, 0); /* set call-home client end entity certificate */ - ret = nc_server_config_add_ch_tls_client_cert(ctx, "ch_tls", "endpt", "ee-cert", TESTS_DIR "/data/client.crt", &test_state->tls_tree); + ret = nc_server_config_add_ch_tls_client_certificate(ctx, "ch_tls", "endpt", "ee-cert", TESTS_DIR "/data/client.crt", &test_state->tls_tree); assert_int_equal(ret, 0); /* set call-home client certificate authority certificate */ - ret = nc_server_config_add_ch_tls_ca_cert(ctx, "ch_tls", "endpt", "ca-cert", TESTS_DIR "/data/serverca.pem", &test_state->tls_tree); + ret = nc_server_config_add_ch_tls_client_ca(ctx, "ch_tls", "endpt", "ca-cert", TESTS_DIR "/data/serverca.pem", &test_state->tls_tree); assert_int_equal(ret, 0); /* set call-home CTN */ diff --git a/tests/test_config_new.c b/tests/test_config_new.c new file mode 100644 index 00000000..03ebb0bd --- /dev/null +++ b/tests/test_config_new.c @@ -0,0 +1,213 @@ +/** + * @file test_keystore.c + * @author Roman Janota + * @brief libnetconf2 Linux PAM keyboard-interactive authentication test + * + * @copyright + * Copyright (c) 2022 CESNET, z.s.p.o. + * + * This source code is licensed under BSD 3-Clause License (the "License"). + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + */ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include + +#include + +#include "tests/config.h" + +#define NC_ACCEPT_TIMEOUT 2000 +#define NC_PS_POLL_TIMEOUT 2000 + +struct ly_ctx *ctx; + +struct test_state { + pthread_barrier_t barrier; +}; + +static void * +server_thread(void *arg) +{ + int ret; + NC_MSG_TYPE msgtype; + struct nc_session *session; + struct nc_pollsession *ps; + struct test_state *state = arg; + + ps = nc_ps_new(); + assert_non_null(ps); + + /* accept a session and add it to the poll session structure */ + pthread_barrier_wait(&state->barrier); + msgtype = nc_accept(NC_ACCEPT_TIMEOUT, ctx, &session); + assert_int_equal(msgtype, NC_MSG_HELLO); + + ret = nc_ps_add_session(ps, session); + assert_int_equal(ret, 0); + + do { + ret = nc_ps_poll(ps, NC_PS_POLL_TIMEOUT, NULL); + assert_int_equal(ret & NC_PSPOLL_RPC, NC_PSPOLL_RPC); + } while (!(ret & NC_PSPOLL_SESSION_TERM)); + + nc_ps_clear(ps, 1, NULL); + nc_ps_free(ps); + return NULL; +} + +static char * +auth_password(const char *username, const char *hostname, void *priv) +{ + (void) username; + (void) hostname; + (void) priv; + + /* set the reply to password authentication */ + return strdup("testpassword123"); +} + +static void * +client_thread(void *arg) +{ + int ret; + struct nc_session *session = NULL; + struct test_state *state = arg; + + /* skip all hostkey and known_hosts checks */ + nc_client_ssh_set_knownhosts_mode(NC_SSH_KNOWNHOSTS_SKIP); + + ret = nc_client_set_schema_searchpath(MODULES_DIR); + assert_int_equal(ret, 0); + + ret = nc_client_ssh_set_username("client"); + assert_int_equal(ret, 0); + + nc_client_ssh_set_auth_password_clb(auth_password, NULL); + + pthread_barrier_wait(&state->barrier); + session = nc_connect_ssh("127.0.0.1", 10005, NULL); + assert_non_null(session); + + nc_session_free(session, NULL); + return NULL; +} + +static void +test_nc_config_new(void **state) +{ + int ret, i; + pthread_t tids[2]; + + assert_non_null(state); + + ret = pthread_create(&tids[0], NULL, client_thread, *state); + assert_int_equal(ret, 0); + ret = pthread_create(&tids[1], NULL, server_thread, *state); + assert_int_equal(ret, 0); + + for (i = 0; i < 2; i++) { + pthread_join(tids[i], NULL); + } +} + +static int +setup_f(void **state) +{ + int ret; + struct lyd_node *tree = NULL; + struct test_state *test_state; + + nc_verbosity(NC_VERB_VERBOSE); + + /* init barrier */ + test_state = malloc(sizeof *test_state); + assert_non_null(test_state); + + ret = pthread_barrier_init(&test_state->barrier, NULL, 2); + assert_int_equal(ret, 0); + + *state = test_state; + + /* new context */ + ret = ly_ctx_new(MODULES_DIR, 0, &ctx); + assert_int_equal(ret, 0); + + /* initialize the context by loading default modules */ + ret = nc_server_init_ctx(&ctx); + assert_int_equal(ret, 0); + + /* load ietf-netconf-server module and it's imports */ + ret = nc_server_config_load_modules(&ctx); + assert_int_equal(ret, 0); + + /* create new hostkey data */ + ret = nc_server_config_add_ssh_hostkey(ctx, "endpt", "hostkey", TESTS_DIR "/data/server.key", NULL, &tree); + assert_int_equal(ret, 0); + + /* create new address and port data */ + ret = nc_server_config_add_address_port(ctx, "endpt", NC_TI_LIBSSH, "127.0.0.1", 10005, &tree); + assert_int_equal(ret, 0); + + /* create the host-key algorithms data */ + ret = nc_server_config_add_ssh_host_key_algs(ctx, "endpt", &tree, 1, "rsa-sha2-512"); + assert_int_equal(ret, 0); + + /* create the client authentication data, password only */ + ret = nc_server_config_add_ssh_user_password(ctx, "endpt", "client", "testpassword123", &tree); + assert_int_equal(ret, 0); + + /* configure the server based on the data */ + ret = nc_server_config_setup_data(tree); + assert_int_equal(ret, 0); + + ret = nc_server_init(); + assert_int_equal(ret, 0); + + /* initialize client */ + ret = nc_client_init(); + assert_int_equal(ret, 0); + + lyd_free_all(tree); + + return 0; +} + +static int +teardown_f(void **state) +{ + int ret = 0; + struct test_state *test_state; + + assert_non_null(state); + test_state = *state; + + ret = pthread_barrier_destroy(&test_state->barrier); + assert_int_equal(ret, 0); + + free(*state); + nc_client_destroy(); + nc_server_destroy(); + ly_ctx_destroy(ctx); + + return 0; +} + +int +main(void) +{ + const struct CMUnitTest tests[] = { + cmocka_unit_test_setup_teardown(test_nc_config_new, setup_f, teardown_f), + }; + + setenv("CMOCKA_TEST_ABORT", "1", 1); + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/tests/test_crl.c b/tests/test_crl.c index 6cd6dc77..9b951edd 100644 --- a/tests/test_crl.c +++ b/tests/test_crl.c @@ -148,15 +148,15 @@ setup_f(void **state) assert_int_equal(ret, 0); /* create new server certificate data */ - ret = nc_server_config_add_tls_server_cert(ctx, "endpt", TESTS_DIR "/data/server.key", NULL, TESTS_DIR "/data/server.crt", &tree); + ret = nc_server_config_add_tls_server_certificate(ctx, "endpt", TESTS_DIR "/data/server.key", NULL, TESTS_DIR "/data/server.crt", &tree); assert_int_equal(ret, 0); /* create new end entity client cert data */ - ret = nc_server_config_add_tls_client_cert(ctx, "endpt", "client_cert", TESTS_DIR "/data/client.crt", &tree); + ret = nc_server_config_add_tls_client_certificate(ctx, "endpt", "client_cert", TESTS_DIR "/data/client.crt", &tree); assert_int_equal(ret, 0); /* create new client ca data */ - ret = nc_server_config_add_tls_ca_cert(ctx, "endpt", "client_ca", TESTS_DIR "/data/serverca.pem", &tree); + ret = nc_server_config_add_tls_client_ca(ctx, "endpt", "client_ca", TESTS_DIR "/data/serverca.pem", &tree); assert_int_equal(ret, 0); /* create new cert-to-name */ @@ -165,11 +165,27 @@ setup_f(void **state) NC_TLS_CTN_SPECIFIED, "client", &tree); assert_int_equal(ret, 0); + /* limit TLS version to 1.3 */ + ret = nc_server_config_add_tls_version(ctx, "endpt", NC_TLS_VERSION_13, &tree); + assert_int_equal(ret, 0); + + /* set the TLS cipher */ + ret = nc_server_config_add_tls_ciphers(ctx, "endpt", &tree, 3, "tls-aes-128-ccm-sha256", "tls-aes-128-gcm-sha256", "tls-chacha20-poly1305-sha256"); + assert_int_equal(ret, 0); + + /* set this node, but it should be deleted by the next call, bcs only one choice node can be present */ + ret = nc_server_config_add_tls_crl_url(ctx, "endpt", "abc", &tree); + assert_int_equal(ret, 0); + /* set path to a CRL file */ - ret = lyd_new_path(tree, ctx, "/ietf-netconf-server:netconf-server/listen/endpoint[name='endpt']/tls/tls-server-parameters/" - "client-authentication/libnetconf2-netconf-server:crl-path", TESTS_DIR "/data/crl.pem", 0, NULL); + ret = nc_server_config_add_tls_crl_path(ctx, "endpt", TESTS_DIR "/data/crl.pem", &tree); assert_int_equal(ret, 0); + /* check if the choice node was removed */ + ret = lyd_find_path(tree, "/ietf-netconf-server:netconf-server/listen/endpoint[name='endpt']/tls/tls-server-parameters/" + "client-authentication/libnetconf2-netconf-server:crl-url", 0, NULL); + assert_int_not_equal(ret, 0); + /* configure the server based on the data */ ret = nc_server_config_setup_data(tree); assert_int_equal(ret, 0); diff --git a/tests/test_endpt_share_clients.c b/tests/test_endpt_share_clients.c index 7099d77e..7966de1a 100644 --- a/tests/test_endpt_share_clients.c +++ b/tests/test_endpt_share_clients.c @@ -260,16 +260,16 @@ setup_tls(void **state) assert_int_equal(ret, 0); /* create the first TLS endpoint with a single end entity client cert and a CTN entry */ - ret = nc_server_config_add_tls_server_cert(ctx, "TLS_endpt_1", TESTS_DIR "/data/server.key", NULL, TESTS_DIR "/data/server.crt", &tree); + ret = nc_server_config_add_tls_server_certificate(ctx, "TLS_endpt_1", TESTS_DIR "/data/server.key", NULL, TESTS_DIR "/data/server.crt", &tree); assert_int_equal(ret, 0); ret = nc_server_config_add_address_port(ctx, "TLS_endpt_1", NC_TI_OPENSSL, "127.0.0.1", 10007, &tree); assert_int_equal(ret, 0); - ret = nc_server_config_add_tls_client_cert(ctx, "TLS_endpt_1", "cert_client", TESTS_DIR "/data/client.crt", &tree); + ret = nc_server_config_add_tls_client_certificate(ctx, "TLS_endpt_1", "cert_client", TESTS_DIR "/data/client.crt", &tree); assert_int_equal(ret, 0); - ret = nc_server_config_add_tls_ca_cert(ctx, "TLS_endpt_1", "cert_ca", TESTS_DIR "/data/serverca.pem", &tree); + ret = nc_server_config_add_tls_client_ca(ctx, "TLS_endpt_1", "cert_ca", TESTS_DIR "/data/serverca.pem", &tree); assert_int_equal(ret, 0); ret = nc_server_config_add_tls_ctn(ctx, "TLS_endpt_1", 1, @@ -278,7 +278,7 @@ setup_tls(void **state) assert_int_equal(ret, 0); /* create the second TLS endpoint with a reference to the first endpoint */ - ret = nc_server_config_add_tls_server_cert(ctx, "TLS_endpt_2", + ret = nc_server_config_add_tls_server_certificate(ctx, "TLS_endpt_2", TESTS_DIR "/data/server.key", NULL, TESTS_DIR "/data/server.crt", &tree); assert_int_equal(ret, 0); diff --git a/tests/test_ks_ts.c b/tests/test_ks_ts.c index 5440b7e6..1e08a7ce 100644 --- a/tests/test_ks_ts.c +++ b/tests/test_ks_ts.c @@ -141,20 +141,16 @@ setup_ssh(void **state) ret = nc_server_config_add_address_port(ctx, "endpt", NC_TI_LIBSSH, "127.0.0.1", 10005, &tree); assert_int_equal(ret, 0); - ret = lyd_new_path(tree, ctx, "/ietf-netconf-server:netconf-server/listen/" - "endpoint[name='endpt']/ssh/ssh-server-parameters/server-identity/host-key[name='hostkey']/public-key/" - "keystore-reference", "test_keystore", 0, NULL); + ret = nc_server_config_add_ssh_keystore_ref(ctx, "endpt", "hostkey", "test_keystore", &tree); assert_int_equal(ret, 0); - ret = lyd_new_path(tree, ctx, "/ietf-netconf-server:netconf-server/listen/" - "endpoint[name='endpt']/ssh/ssh-server-parameters/client-authentication/users/user[name='client']/public-keys/" - "truststore-reference", "test_truststore", 0, NULL); + ret = nc_server_config_add_ssh_truststore_ref(ctx, "endpt", "client", "test_truststore", &tree); assert_int_equal(ret, 0); ret = nc_server_config_add_keystore_asym_key(ctx, NC_TI_LIBSSH, "test_keystore", TESTS_DIR "/data/key_rsa", NULL, &tree); assert_int_equal(ret, 0); - ret = nc_server_config_add_truststore_pubkey(ctx, NC_TI_LIBSSH, "test_truststore", "pubkey", TESTS_DIR "/data/id_ed25519.pub", &tree); + ret = nc_server_config_add_truststore_pubkey(ctx, "test_truststore", "pubkey", TESTS_DIR "/data/id_ed25519.pub", &tree); assert_int_equal(ret, 0); /* configure the server based on the data */ @@ -268,21 +264,15 @@ setup_tls(void **state) assert_int_equal(ret, 0); /* new keystore ref for the TLS server cert */ - ret = lyd_new_path(tree, ctx, "/ietf-netconf-server:netconf-server/listen/endpoint[name='endpt']/" - "tls/tls-server-parameters/server-identity/certificate/keystore-reference/asymmetric-key", "server_key", 0, NULL); - assert_int_equal(ret, 0); - ret = lyd_new_path(tree, ctx, "/ietf-netconf-server:netconf-server/listen/endpoint[name='endpt']/" - "tls/tls-server-parameters/server-identity/certificate/keystore-reference/certificate", "server_cert", 0, NULL); + ret = nc_server_config_add_tls_keystore_ref(ctx, "endpt", "server_key", "server_cert", &tree); assert_int_equal(ret, 0); /* new truststore ref for the client cert */ - ret = lyd_new_path(tree, ctx, "/ietf-netconf-server:netconf-server/listen/endpoint[name='endpt']/tls/" - "tls-server-parameters/client-authentication/ee-certs/truststore-reference", "ee_cert_bag", 0, NULL); + ret = nc_server_config_add_tls_client_cert_truststore_ref(ctx, "endpt", "ee_cert_bag", &tree); assert_int_equal(ret, 0); /* new truststore ref for the client CA cert */ - ret = lyd_new_path(tree, ctx, "/ietf-netconf-server:netconf-server/listen/endpoint[name='endpt']/tls/" - "tls-server-parameters/client-authentication/ca-certs/truststore-reference", "ca_cert_bag", 0, NULL); + ret = nc_server_config_add_tls_client_ca_truststore_ref(ctx, "endpt", "ca_cert_bag", &tree); assert_int_equal(ret, 0); /* new cert-to-name */ diff --git a/tests/test_runtime_changes.c b/tests/test_runtime_changes.c index 284d3606..7c389ee4 100644 --- a/tests/test_runtime_changes.c +++ b/tests/test_runtime_changes.c @@ -240,11 +240,11 @@ test_nc_change_tls_srv_crt(void **state) test_state = *state; init_test_create_threads_tls(tids, state); - ret = nc_server_config_add_tls_server_cert(ctx, "endpt_tls", TESTS_DIR "/data/client.key", NULL, TESTS_DIR "/data/client.crt", &test_state->tree); + ret = nc_server_config_add_tls_server_certificate(ctx, "endpt_tls", TESTS_DIR "/data/client.key", NULL, TESTS_DIR "/data/client.crt", &test_state->tree); assert_int_equal(ret, 0); configure(test_state, NC_TEST_EXPECT_FAIL, NC_TEST_STATE_RUN); - ret = nc_server_config_add_tls_server_cert(ctx, "endpt_tls", TESTS_DIR "/data/server.key", NULL, TESTS_DIR "/data/server.crt", &test_state->tree); + ret = nc_server_config_add_tls_server_certificate(ctx, "endpt_tls", TESTS_DIR "/data/server.key", NULL, TESTS_DIR "/data/server.crt", &test_state->tree); assert_int_equal(ret, 0); configure(test_state, NC_TEST_EXPECT_OK, NC_TEST_STATE_END); @@ -264,11 +264,11 @@ test_nc_change_tls_client_crt(void **state) test_state = *state; init_test_create_threads_tls(tids, state); - ret = nc_server_config_add_tls_client_cert(ctx, "endpt_tls", "client_cert", TESTS_DIR "/data/server.crt", &test_state->tree); + ret = nc_server_config_add_tls_client_certificate(ctx, "endpt_tls", "client_cert", TESTS_DIR "/data/server.crt", &test_state->tree); assert_int_equal(ret, 0); configure(test_state, NC_TEST_EXPECT_FAIL, NC_TEST_STATE_RUN); - ret = nc_server_config_add_tls_client_cert(ctx, "endpt_tls", "client_cert", TESTS_DIR "/data/client.crt", &test_state->tree); + ret = nc_server_config_add_tls_client_certificate(ctx, "endpt_tls", "client_cert", TESTS_DIR "/data/client.crt", &test_state->tree); assert_int_equal(ret, 0); configure(test_state, NC_TEST_EXPECT_OK, NC_TEST_STATE_END); @@ -305,13 +305,60 @@ test_nc_change_tls_ctn(void **state) } } +static void +test_nc_change_tls_version(void **state) +{ + int ret, i; + pthread_t tids[2]; + struct test_state *test_state; + + assert_non_null(state); + test_state = *state; + init_test_create_threads_tls(tids, state); + + ret = nc_server_config_add_tls_version(ctx, "endpt_tls", NC_TLS_VERSION_11, &test_state->tree); + assert_int_equal(ret, 0); + configure(test_state, NC_TEST_EXPECT_FAIL, NC_TEST_STATE_RUN); + + ret = nc_server_config_add_tls_version(ctx, "endpt_tls", NC_TLS_VERSION_13, &test_state->tree); + assert_int_equal(ret, 0); + configure(test_state, NC_TEST_EXPECT_OK, NC_TEST_STATE_END); + + for (i = 0; i < 2; i++) { + pthread_join(tids[i], NULL); + } +} + +static void +test_nc_change_tls_ciphers(void **state) +{ + int ret, i; + pthread_t tids[2]; + struct test_state *test_state; + + assert_non_null(state); + test_state = *state; + init_test_create_threads_tls(tids, state); + + ret = nc_server_config_add_tls_ciphers(ctx, "endpt_tls", &test_state->tree, 1, "tls-rsa-with-null-sha"); + assert_int_equal(ret, 0); + configure(test_state, NC_TEST_EXPECT_FAIL, NC_TEST_STATE_RUN); + + ret = nc_server_config_add_tls_ciphers(ctx, "endpt_tls", &test_state->tree, 3, "tls-aes-128-ccm-sha256", "tls-aes-128-gcm-sha256", "tls-chacha20-poly1305-sha256"); + assert_int_equal(ret, 0); + configure(test_state, NC_TEST_EXPECT_OK, NC_TEST_STATE_END); + + for (i = 0; i < 2; i++) { + pthread_join(tids[i], NULL); + } +} + static void test_nc_change_ssh_hostkey(void **state) { int ret, i; pthread_t tids[2]; struct test_state *test_state; - struct lyd_node *hostkey = NULL; assert_non_null(state); test_state = *state; @@ -321,18 +368,9 @@ test_nc_change_ssh_hostkey(void **state) assert_int_equal(ret, 0); configure(test_state, NC_TEST_EXPECT_OK, NC_TEST_STATE_RUN); - /* delete the locally defined hostkey */ - ret = lyd_find_path(test_state->tree, "/ietf-netconf-server:netconf-server/listen/" - "endpoint[name='endpt_ssh']/ssh/ssh-server-parameters/server-identity/host-key[name='hostkey']/public-key", 0, &hostkey); - assert_non_null(hostkey); - lyd_free_tree(hostkey); - - /* add the keystore entry and set it as hostkey */ ret = nc_server_config_add_keystore_asym_key(ctx, NC_TI_LIBSSH, "keystore_hostkey", TESTS_DIR "/data/key_rsa", TESTS_DIR "/data/key_rsa.pub", &test_state->tree); assert_int_equal(ret, 0); - ret = lyd_new_path(test_state->tree, ctx, "/ietf-netconf-server:netconf-server/listen/" - "endpoint[name='endpt_ssh']/ssh/ssh-server-parameters/server-identity/host-key[name='hostkey']/public-key/" - "keystore-reference", "keystore_hostkey", 0, NULL); + ret = nc_server_config_add_ssh_keystore_ref(ctx, "endpt_ssh", "hostkey", "keystore_hostkey", &test_state->tree); assert_int_equal(ret, 0); configure(test_state, NC_TEST_EXPECT_OK, NC_TEST_STATE_END); @@ -365,6 +403,30 @@ test_nc_change_ssh_usr_pubkey(void **state) } } +static void +test_nc_change_ssh_hostkey_algs(void **state) +{ + int ret, i; + pthread_t tids[2]; + struct test_state *test_state; + + assert_non_null(state); + test_state = *state; + init_test_create_threads_ssh(tids, state); + + ret = nc_server_config_add_ssh_host_key_algs(ctx, "endpt_ssh", &test_state->tree, 1, "ssh-dss"); + assert_int_equal(ret, 0); + configure(test_state, NC_TEST_EXPECT_FAIL, NC_TEST_STATE_RUN); + + ret = nc_server_config_add_ssh_host_key_algs(ctx, "endpt_ssh", &test_state->tree, 1, "rsa-sha2-256"); + assert_int_equal(ret, 0); + configure(test_state, NC_TEST_EXPECT_OK, NC_TEST_STATE_END); + + for (i = 0; i < 2; i++) { + pthread_join(tids[i], NULL); + } +} + static int setup_f(void **state) { @@ -399,11 +461,11 @@ setup_f(void **state) assert_int_equal(ret, 0); /* create new server certificate data */ - ret = nc_server_config_add_tls_server_cert(ctx, "endpt_tls", TESTS_DIR "/data/server.key", NULL, TESTS_DIR "/data/server.crt", &test_state->tree); + ret = nc_server_config_add_tls_server_certificate(ctx, "endpt_tls", TESTS_DIR "/data/server.key", NULL, TESTS_DIR "/data/server.crt", &test_state->tree); assert_int_equal(ret, 0); /* create new end entity client cert data */ - ret = nc_server_config_add_tls_client_cert(ctx, "endpt_tls", "client_cert", TESTS_DIR "/data/client.crt", &test_state->tree); + ret = nc_server_config_add_tls_client_certificate(ctx, "endpt_tls", "client_cert", TESTS_DIR "/data/client.crt", &test_state->tree); assert_int_equal(ret, 0); /* create new cert-to-name */ @@ -464,8 +526,11 @@ main(void) cmocka_unit_test_setup_teardown(test_nc_change_tls_srv_crt, setup_f, teardown_f), cmocka_unit_test_setup_teardown(test_nc_change_tls_client_crt, setup_f, teardown_f), cmocka_unit_test_setup_teardown(test_nc_change_tls_ctn, setup_f, teardown_f), + cmocka_unit_test_setup_teardown(test_nc_change_tls_version, setup_f, teardown_f), + cmocka_unit_test_setup_teardown(test_nc_change_tls_ciphers, setup_f, teardown_f), cmocka_unit_test_setup_teardown(test_nc_change_ssh_hostkey, setup_f, teardown_f), - cmocka_unit_test_setup_teardown(test_nc_change_ssh_usr_pubkey, setup_f, teardown_f) + cmocka_unit_test_setup_teardown(test_nc_change_ssh_usr_pubkey, setup_f, teardown_f), + cmocka_unit_test_setup_teardown(test_nc_change_ssh_hostkey_algs, setup_f, teardown_f), }; setenv("CMOCKA_TEST_ABORT", "1", 1); diff --git a/tests/test_tls.c b/tests/test_tls.c index 542f7bdb..7d84184d 100644 --- a/tests/test_tls.c +++ b/tests/test_tls.c @@ -142,15 +142,15 @@ setup_f(void **state) assert_int_equal(ret, 0); /* create new server certificate data */ - ret = nc_server_config_add_tls_server_cert(ctx, "endpt", TESTS_DIR "/data/server.key", NULL, TESTS_DIR "/data/server.crt", &tree); + ret = nc_server_config_add_tls_server_certificate(ctx, "endpt", TESTS_DIR "/data/server.key", NULL, TESTS_DIR "/data/server.crt", &tree); assert_int_equal(ret, 0); /* create new end entity client cert data */ - ret = nc_server_config_add_tls_client_cert(ctx, "endpt", "client_cert", TESTS_DIR "/data/client.crt", &tree); + ret = nc_server_config_add_tls_client_certificate(ctx, "endpt", "client_cert", TESTS_DIR "/data/client.crt", &tree); assert_int_equal(ret, 0); /* create new client ca data */ - ret = nc_server_config_add_tls_ca_cert(ctx, "endpt", "client_ca", TESTS_DIR "/data/serverca.pem", &tree); + ret = nc_server_config_add_tls_client_ca(ctx, "endpt", "client_ca", TESTS_DIR "/data/serverca.pem", &tree); assert_int_equal(ret, 0); /* create new cert-to-name */ @@ -159,6 +159,14 @@ setup_f(void **state) NC_TLS_CTN_SPECIFIED, "client", &tree); assert_int_equal(ret, 0); + /* limit TLS version to 1.3 */ + ret = nc_server_config_add_tls_version(ctx, "endpt", NC_TLS_VERSION_13, &tree); + assert_int_equal(ret, 0); + + /* set the TLS cipher */ + ret = nc_server_config_add_tls_ciphers(ctx, "endpt", &tree, 3, "tls-aes-128-ccm-sha256", "tls-aes-128-gcm-sha256", "tls-chacha20-poly1305-sha256"); + assert_int_equal(ret, 0); + /* configure the server based on the data */ ret = nc_server_config_setup_data(tree); assert_int_equal(ret, 0);