X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?p=sim%2Fo1-interface.git;a=blobdiff_plain;f=ntsimulator%2Fntsim-ng%2Ffeatures%2Fnetconf_call_home%2Fnetconf_call_home.c;h=59b2e58b10ed2cb651545156c081fab7c5441aba;hp=a56e45b42467a62249735b6672624e8de59b6c51;hb=fd9a6164f9cff51682fcebe77f53d99b8d882bc7;hpb=22cd30649dfac2fcfdf233765aa7feeea7141d96 diff --git a/ntsimulator/ntsim-ng/features/netconf_call_home/netconf_call_home.c b/ntsimulator/ntsim-ng/features/netconf_call_home/netconf_call_home.c index a56e45b..59b2e58 100644 --- a/ntsimulator/ntsim-ng/features/netconf_call_home/netconf_call_home.c +++ b/ntsimulator/ntsim-ng/features/netconf_call_home/netconf_call_home.c @@ -30,11 +30,14 @@ #include "core/framework.h" #include "core/xpath.h" -#define NETCONF_CALLHOME_CURL_SEND_PAYLOAD_FORMAT "{\"odl-netconf-callhome-server:device\":[{\"odl-netconf-callhome-server:unique-id\":\"%s\",\"odl-netconf-callhome-server:ssh-host-key\":\"%s\",\"odl-netconf-callhome-server:credentials\":{\"odl-netconf-callhome-server:username\":\"netconf\",\"odl-netconf-callhome-server:passwords\":[\"netconf!\"]}}]}" +#define NETCONF_SSH_CALLHOME_CURL_SEND_PAYLOAD_FORMAT "{\"odl-netconf-callhome-server:device\":[{\"odl-netconf-callhome-server:unique-id\":\"%s\", \"odl-netconf-callhome-server:ssh-client-params\": {\"odl-netconf-callhome-server:host-key\":\"%s\",\"odl-netconf-callhome-server:credentials\":{\"odl-netconf-callhome-server:username\":\"netconf\",\"odl-netconf-callhome-server:passwords\":[\"netconf!\"]}}}]}" +#define NETCONF_TLS_CALLHOME_CURL_SEND_PAYLOAD_FORMAT "{\"odl-netconf-callhome-server:device\":[{\"odl-netconf-callhome-server:unique-id\":\"%s\", \"odl-netconf-callhome-server:tls-client-params\": {\"odl-netconf-callhome-server:certificate-id\":\"%s\",\"odl-netconf-callhome-server:key-id\":\"%s\"}}]}" +#define NETCONF_TRUSTED_CERTIFICATE_CURL_SEND_PAYLOAD_FORMAT "{\"input\":{\"trusted-certificate\":[{\"name\":\"%s\",\"certificate\":\"%s\"}]}}" static int create_ssh_callhome_endpoint(sr_session_ctx_t *current_session, struct lyd_node *netconf_node); static int create_tls_callhome_endpoint(sr_session_ctx_t *current_session, struct lyd_node *netconf_node); -static int send_odl_callhome_configuration(sr_session_ctx_t *current_session); +static int send_odl_add_trusted_certificate(sr_session_ctx_t *current_session); +static int send_odl_callhome_configuration(sr_session_ctx_t *current_session, bool is_tls); static int netconf_call_home_status = 0; @@ -73,17 +76,31 @@ int netconf_call_home_feature_start(sr_session_ctx_t *current_session) { return NTS_ERR_FAILED; } - rc = create_ssh_callhome_endpoint(current_session, netconf_node); - if(rc != NTS_ERR_OK) { - log_error("could not create SSH CallHome endpoint on the NETCONF Server\n"); + controller_details_t *controller = controller_details_get(current_session); + if(controller == 0) { + log_error("controller_details_get failed\n"); return NTS_ERR_FAILED; } - rc = create_tls_callhome_endpoint(current_session, netconf_node); - if(rc != NTS_ERR_OK) { - log_error("could not create TLS CallHome endpoint on the NETCONF Server\n"); - return NTS_ERR_FAILED; + if (controller->nc_callhome_port == 4335) { + // port is CallHome via TLS + rc = create_tls_callhome_endpoint(current_session, netconf_node); + if(rc != NTS_ERR_OK) { + log_error("could not create TLS CallHome endpoint on the NETCONF Server\n"); + controller_details_free(controller); + return NTS_ERR_FAILED; + } + } + else { + // port is CallHome via SSH + rc = create_ssh_callhome_endpoint(current_session, netconf_node); + if(rc != NTS_ERR_OK) { + log_error("could not create SSH CallHome endpoint on the NETCONF Server\n"); + controller_details_free(controller); + return NTS_ERR_FAILED; + } } + controller_details_free(controller); rc = sr_edit_batch(current_session, netconf_node, "merge"); if(rc != SR_ERR_OK) { @@ -129,7 +146,6 @@ static int create_ssh_callhome_endpoint(sr_session_ctx_t *current_session, struc return NTS_ERR_FAILED; } - struct lyd_node *rcl = lyd_new_path(netconf_node, 0, IETF_NETCONF_SERVER_CH_SSH_TCP_CLIENT_SCHEMA_XPATH"/keepalives/idle-time", "1", 0, LYD_PATH_OPT_NOPARENTRET); if(rcl == 0) { log_error("could not created yang path\n"); @@ -202,7 +218,7 @@ static int create_ssh_callhome_endpoint(sr_session_ctx_t *current_session, struc return NTS_ERR_FAILED; } - int rc = send_odl_callhome_configuration(current_session); + int rc = send_odl_callhome_configuration(current_session, false); if(rc != NTS_ERR_OK) { log_add_verbose(2, "could not send ODL Call Home configuration.\n"); } @@ -214,30 +230,194 @@ static int create_tls_callhome_endpoint(sr_session_ctx_t *current_session, struc assert(current_session); assert(netconf_node); - // checkAS future usage, TLS endpoint yet supported in ODL + controller_details_t *controller = controller_details_get(current_session); + if(controller == 0) { + log_error("controller_details_get failed\n"); + return NTS_ERR_FAILED; + } + + char *controller_ip = strdup(controller->ip); + uint16_t controller_callhome_port = controller->nc_callhome_port; + controller_details_free(controller); + + if(controller_ip == 0) { + log_error("strdup failed\n"); + return NTS_ERR_FAILED; + } + struct lyd_node *rcl = lyd_new_path(netconf_node, 0, IETF_NETCONF_SERVER_CH_TLS_TCP_CLIENT_SCHEMA_XPATH"/keepalives/idle-time", "1", 0, LYD_PATH_OPT_NOPARENTRET); + if(rcl == 0) { + log_error("could not created yang path\n"); + free(controller_ip); + return NTS_ERR_FAILED; + } + + rcl = lyd_new_path(netconf_node, 0, IETF_NETCONF_SERVER_CH_TLS_TCP_CLIENT_SCHEMA_XPATH"/keepalives/max-probes", "10", 0, LYD_PATH_OPT_NOPARENTRET); + if(rcl == 0) { + log_error("could not created yang path\n"); + free(controller_ip); + return NTS_ERR_FAILED; + } + + rcl = lyd_new_path(netconf_node, 0, IETF_NETCONF_SERVER_CH_TLS_TCP_CLIENT_SCHEMA_XPATH"/keepalives/probe-interval", "5", 0, LYD_PATH_OPT_NOPARENTRET); + if(rcl == 0) { + log_error("could not created yang path\n"); + free(controller_ip); + return NTS_ERR_FAILED; + } + + rcl = lyd_new_path(netconf_node, 0, IETF_NETCONF_SERVER_CH_TLS_TCP_CLIENT_SCHEMA_XPATH"/remote-address", controller_ip, 0, LYD_PATH_OPT_NOPARENTRET); + if(rcl == 0) { + log_error("could not created yang path\n"); + free(controller_ip); + return NTS_ERR_FAILED; + } + free(controller_ip); + + char port[20]; + sprintf(port, "%d", controller_callhome_port); + rcl = lyd_new_path(netconf_node, 0, IETF_NETCONF_SERVER_CH_TLS_TCP_CLIENT_SCHEMA_XPATH"/remote-port", port, 0, LYD_PATH_OPT_NOPARENTRET); + if(rcl == 0) { + log_error("could not created yang path\n"); + return NTS_ERR_FAILED; + } + + rcl = lyd_new_path(netconf_node, 0, IETF_NETCONF_SERVER_CH_TLS_SERVER_PARAMS_SCEHMA_XPATH"/server-identity/keystore-reference/asymmetric-key", KS_KEY_NAME, 0, LYD_PATH_OPT_NOPARENTRET); + if(rcl == 0) { + log_error("could not created yang path\n"); + return NTS_ERR_FAILED; + } + + rcl = lyd_new_path(netconf_node, 0, IETF_NETCONF_SERVER_CH_TLS_SERVER_PARAMS_SCEHMA_XPATH"/server-identity/keystore-reference/certificate", KS_CERT_NAME, 0, LYD_PATH_OPT_NOPARENTRET); + if(rcl == 0) { + log_error("could not created yang path\n"); + return NTS_ERR_FAILED; + } + + rcl = lyd_new_path(netconf_node, 0, IETF_NETCONF_SERVER_CH_TLS_SERVER_PARAMS_SCEHMA_XPATH"/client-authentication/required", "", 0, LYD_PATH_OPT_NOPARENTRET); + if(rcl == 0) { + log_error("could not created yang path\n"); + return NTS_ERR_FAILED; + } + + rcl = lyd_new_path(netconf_node, 0, IETF_NETCONF_SERVER_CH_TLS_SERVER_PARAMS_SCEHMA_XPATH"/client-authentication/ca-certs", "cacerts", 0, LYD_PATH_OPT_NOPARENTRET); + if(rcl == 0) { + log_error("could not created yang path\n"); + return NTS_ERR_FAILED; + } + + rcl = lyd_new_path(netconf_node, 0, IETF_NETCONF_SERVER_CH_TLS_SERVER_PARAMS_SCEHMA_XPATH"/client-authentication/client-certs", "clientcerts", 0, LYD_PATH_OPT_NOPARENTRET); + if(rcl == 0) { + log_error("could not created yang path\n"); + return NTS_ERR_FAILED; + } + + rcl = lyd_new_path(netconf_node, 0, IETF_NETCONF_SERVER_CH_TLS_SERVER_PARAMS_SCEHMA_XPATH"/client-authentication/cert-maps/cert-to-name[id='1']/fingerprint", "02:E9:38:1F:F6:8B:62:DE:0A:0B:C5:03:81:A8:03:49:A0:00:7F:8B:F3", 0, LYD_PATH_OPT_NOPARENTRET); + if(rcl == 0) { + log_error("could not created yang path\n"); + return NTS_ERR_FAILED; + } + + rcl = lyd_new_path(netconf_node, session_context, IETF_NETCONF_SERVER_CH_TLS_SERVER_PARAMS_SCEHMA_XPATH"/client-authentication/cert-maps/cert-to-name[id='1']/map-type", "ietf-x509-cert-to-name:specified", 0, LYD_PATH_OPT_NOPARENTRET); + if(rcl == 0) { + log_error("could not created yang path\n"); + return NTS_ERR_FAILED; + } + + rcl = lyd_new_path(netconf_node, 0, IETF_NETCONF_SERVER_CH_TLS_SERVER_PARAMS_SCEHMA_XPATH"/client-authentication/cert-maps/cert-to-name[id='1']/name", "netconf", 0, LYD_PATH_OPT_NOPARENTRET); + if(rcl == 0) { + log_error("could not created yang path\n"); + return NTS_ERR_FAILED; + } + + rcl = lyd_new_path(netconf_node, 0, IETF_NETCONF_SERVER_CH_CONN_PERSISTENT_SCHEMA_XPATH, "", 0, LYD_PATH_OPT_NOPARENTRET); + if(rcl == 0) { + log_error("could not created yang path\n"); + return NTS_ERR_FAILED; + } + + int rc = send_odl_callhome_configuration(current_session, true); + if(rc != NTS_ERR_OK) { + log_add_verbose(2, "could not send ODL Call Home configuration.\n"); + } + return NTS_ERR_OK; } -static int send_odl_callhome_configuration(sr_session_ctx_t *current_session) { +static int send_odl_add_trusted_certificate(sr_session_ctx_t *current_session) { assert(current_session); - char *public_ssh_key = read_key(SERVER_PUBLIC_SSH_KEY_PATH); - if(public_ssh_key == 0) { - log_error("could not read the public ssh key from file %s\n", SERVER_PUBLIC_SSH_KEY_PATH); + char *server_cert = read_key(SERVER_CERT_PATH); + if(server_cert == 0) { + log_error("could not read the serevr certificate from file %s\n", SERVER_CERT_PATH); return NTS_ERR_FAILED; } - char *ssh_key_string; - ssh_key_string = strtok(public_ssh_key, " "); - ssh_key_string = strtok(NULL, " "); - ssh_key_string[strlen(ssh_key_string) - 1] = 0; // trim the newline character + char *odl_trusted_certificate_payload = 0; + asprintf(&odl_trusted_certificate_payload, NETCONF_TRUSTED_CERTIFICATE_CURL_SEND_PAYLOAD_FORMAT, framework_environment.settings.hostname, server_cert); + if(odl_trusted_certificate_payload == 0) { + log_error("bad asprintf\n"); + return NTS_ERR_FAILED; + } + free(server_cert); + + controller_details_t *controller = controller_details_get(current_session); + if(controller == 0) { + log_error("controller_details_get failed\n"); + return NTS_ERR_FAILED; + } + + char *url = 0; + asprintf(&url, "%s/rests/operations/netconf-keystore:add-trusted-certificate", controller->base_url); + if(url == 0) { + log_error("bad asprintf\n"); + controller_details_free(controller); + return NTS_ERR_FAILED; + } + + int rc = http_request(url, controller->username, controller->password, "POST", odl_trusted_certificate_payload, 0, 0); + if(rc != NTS_ERR_OK) { + log_error("http_request failed\n"); + } + + free(url); + controller_details_free(controller); + free(odl_trusted_certificate_payload); + + return rc; +} + +static int send_odl_callhome_configuration(sr_session_ctx_t *current_session, bool is_tls) { + assert(current_session); - // checkAS we have hardcoded here the username and password of the NETCONF Server char *odl_callhome_payload = 0; - asprintf(&odl_callhome_payload, NETCONF_CALLHOME_CURL_SEND_PAYLOAD_FORMAT, framework_environment.settings.hostname, ssh_key_string); - free(public_ssh_key); + if (!is_tls) { + char *public_ssh_key = read_key(SERVER_PUBLIC_SSH_KEY_PATH); + if(public_ssh_key == 0) { + log_error("could not read the public ssh key from file %s\n", SERVER_PUBLIC_SSH_KEY_PATH); + return NTS_ERR_FAILED; + } + + char *ssh_key_string; + ssh_key_string = strtok(public_ssh_key, " "); + ssh_key_string = strtok(NULL, " "); + ssh_key_string[strlen(ssh_key_string) - 1] = 0; // trim the newline character + + // checkAS we have hardcoded here the username and password of the NETCONF Server + asprintf(&odl_callhome_payload, NETCONF_SSH_CALLHOME_CURL_SEND_PAYLOAD_FORMAT, framework_environment.settings.hostname, ssh_key_string); + free(public_ssh_key); + } + else { + int ret = send_odl_add_trusted_certificate(current_session); + if (ret != NTS_ERR_OK) { + log_error("Could not send trusted certificate to ODL."); + return NTS_ERR_FAILED; + } + // checkAS we have hardcoded here the private key of ODL + asprintf(&odl_callhome_payload, NETCONF_TLS_CALLHOME_CURL_SEND_PAYLOAD_FORMAT, framework_environment.settings.hostname, framework_environment.settings.hostname, "ODL_private_key_0"); + } + if(odl_callhome_payload == 0) { log_error("bad asprintf\n"); return NTS_ERR_FAILED;