1 /*************************************************************************
3 * Copyright 2020 highstreet technologies GmbH and others
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 ***************************************************************************/
20 #include "nc_config.h"
21 #include "utils/log_utils.h"
22 #include "utils/sys_utils.h"
23 #include "utils/http_client.h"
30 #include <libyang/libyang.h>
31 #include "core/session.h"
32 #include "core/xpath.h"
33 #include "core/framework.h"
35 #define GEN_KEY_SCRIPT "/home/netconf/.ssh/generate-ssh-keys.sh"
36 #define KS_CERT_NAME "melacon_server_cert"
37 #define SERVER_PRIVATE_KEY_PATH "/home/netconf/.ssh/melacon.server.key"
38 #define SERVER_PUBLIC_KEY_PATH "/home/netconf/.ssh/melacon.server.key.pub.pem"
39 #define SERVER_CERT_PATH "/home/netconf/.ssh/melacon.server.crt"
40 #define CA_CERT_PATH "/home/netconf/.ssh/ca.pem"
42 static int nc_config_netconf_port = STANDARD_NETCONF_PORT;
44 static int load_ssh_keys(sr_session_ctx_t *session);
45 static int load_trusted_certificates(sr_session_ctx_t *session);
46 static int configure_nacm(sr_session_ctx_t *session);
47 static int create_ssh_listen_endpoints(struct lyd_node *netconf_node, int ssh_connections);
48 static int create_tls_listen_endpoints(struct lyd_node *netconf_node, int tls_connections);
49 static int configure_endpoints_connections(sr_session_ctx_t *session);
51 int netconf_configure(void) {
54 nc_config_netconf_port = STANDARD_NETCONF_PORT;
56 //check if was already ran
58 rc = sr_get_item(session_running, IETF_KEYSTORE_SCHEMA_XPATH, 0, &val);
60 log_error("sr_get_item failed\n");
61 return NTS_ERR_FAILED;
64 bool already_done = (val->dflt == false);
68 log_add_verbose(2, "netconf_configure() already ran, skipping...\n");
72 // generate and load private keys
73 log_add_verbose(1, "ietf-keystore startup datastore configuration...");
74 rc = load_ssh_keys(session_running);
76 log_error("could not load SSH keys\n");
77 return NTS_ERR_FAILED;
79 log_add(1, LOG_COLOR_BOLD_GREEN"done\n"LOG_COLOR_RESET);
81 // load trusted certificates
82 log_add_verbose(1, "ietf-truststore startup datastore configuration...");
83 rc = load_trusted_certificates(session_running);
85 log_error("could not load trusted certificates\n");
86 return NTS_ERR_FAILED;
88 log_add(1, LOG_COLOR_BOLD_GREEN"done\n"LOG_COLOR_RESET);
91 log_add_verbose(1, "configuring NACM...");
92 rc = configure_nacm(session_running);
94 log_error("could not configure NACM\n");
95 return NTS_ERR_FAILED;
97 log_add(1, LOG_COLOR_BOLD_GREEN"done\n"LOG_COLOR_RESET);
99 // configure SSH connections
100 log_add_verbose(1, "Configuring connection endpoints...");
101 rc = configure_endpoints_connections(session_running);
103 log_error("could not configure endpoint connections for NETCONF Server\n");
104 return NTS_ERR_FAILED;
106 log_add(1, LOG_COLOR_BOLD_GREEN"done\n"LOG_COLOR_RESET);
111 static int load_ssh_keys(sr_session_ctx_t *session) {
116 struct lyd_node *rcl = 0;
118 rc = system(GEN_KEY_SCRIPT);
120 log_error("could not generate the SSH keys\n");
121 return NTS_ERR_FAILED;
124 struct lys_module *module;
125 module = (struct lys_module *)ly_ctx_get_module(session_context, IETF_KEYSTORE_MODULE, 0, 0);
127 log_error("could not get module %s from context\n", IETF_KEYSTORE_MODULE);
128 return NTS_ERR_FAILED;
131 struct lyd_node *keystore_node = 0;
132 keystore_node = lyd_new(NULL, module, "keystore");
133 if(keystore_node == 0) {
134 log_error("could not create a new lyd_node\n");
135 return NTS_ERR_FAILED;
138 sprintf(xpath, IETF_KEYSTORE_ASYMETRIC_KEY_SCHEMA_XPATH"/algorithm", KS_KEY_NAME);
139 rcl = lyd_new_path(keystore_node, 0, xpath, "rsa2048", 0, LYD_PATH_OPT_NOPARENTRET);
141 log_error("could not created yang path\n");
142 return NTS_ERR_FAILED;
145 char *private_key = read_key(SERVER_PRIVATE_KEY_PATH);
146 if(private_key == 0) {
147 log_error("could not read the private key from path=%s\n", SERVER_PRIVATE_KEY_PATH);
148 return NTS_ERR_FAILED;
150 log_add_verbose(2, "Private Key that was built: \n%s\n", private_key);
152 sprintf(xpath, IETF_KEYSTORE_ASYMETRIC_KEY_SCHEMA_XPATH"/private-key", KS_KEY_NAME);
153 rcl = lyd_new_path(keystore_node, 0, xpath, private_key, 0, LYD_PATH_OPT_NOPARENTRET);
155 log_error("could not created yang path\n");
156 return NTS_ERR_FAILED;
161 char *public_key = read_key(SERVER_PUBLIC_KEY_PATH);
162 if(public_key == 0) {
163 log_error("could not read the public key from path=%s\n", SERVER_PUBLIC_KEY_PATH);
164 return NTS_ERR_FAILED;
166 log_add_verbose(2, "Public Key that was built: \n%s\n", public_key);
168 sprintf(xpath, IETF_KEYSTORE_ASYMETRIC_KEY_SCHEMA_XPATH"/public-key", KS_KEY_NAME);
169 rcl = lyd_new_path(keystore_node, 0, xpath, public_key, 0, LYD_PATH_OPT_NOPARENTRET);
171 log_error("could not created yang path\n");
172 return NTS_ERR_FAILED;
177 char *certificate = read_key(SERVER_CERT_PATH);
178 if(certificate == 0) {
179 log_error("could not read the certificate from path=%s\n", SERVER_CERT_PATH);
180 return NTS_ERR_FAILED;
182 log_add_verbose(2, "Certificate that was built: \n%s\n", certificate);
184 sprintf(xpath, IETF_KEYSTORE_ASYMETRIC_KEY_SCHEMA_XPATH"/certificates/certificate[name='%s']/cert", KS_KEY_NAME, KS_CERT_NAME);
185 rcl = lyd_new_path(keystore_node, 0, xpath, certificate, 0, LYD_PATH_OPT_NOPARENTRET);
187 log_error("could not created yang path\n");
188 return NTS_ERR_FAILED;
193 rc = sr_edit_batch(session, keystore_node, "replace");
194 if(rc != SR_ERR_OK) {
195 log_error("could not edit batch on datastore\n");
196 return NTS_ERR_FAILED;
199 rc = sr_validate(session, IETF_KEYSTORE_MODULE, 0);
200 if(rc != SR_ERR_OK) {
201 struct ly_err_item *err = ly_err_first(session_context);
202 log_error("sr_validate issues on STARTUP: %s\n", err->msg);
206 rc = sr_apply_changes(session, 0, 0);
207 if(rc != SR_ERR_OK) {
208 log_error("could not apply changes on datastore\n");
209 return NTS_ERR_FAILED;
215 static int load_trusted_certificates(sr_session_ctx_t *session) {
219 struct lyd_node *rcl = 0;
221 struct lyd_node *trusted_certificate_node = 0;
222 struct lys_module *module;
223 module = (struct lys_module *)ly_ctx_get_module(session_context, IETF_TRUSTSTORE_MODULE, 0, 0);
225 log_error("could not get module %s from context\n", IETF_TRUSTSTORE_MODULE);
226 return NTS_ERR_FAILED;
229 trusted_certificate_node = lyd_new(NULL, module, "truststore");
230 if(trusted_certificate_node == 0) {
231 log_error("could not create a new lyd_node\n");
232 return NTS_ERR_FAILED;
235 char *client_cert = read_key(CLIENT_CERT_PATH);
236 rcl = lyd_new_path(trusted_certificate_node, 0, IETF_TRUSTSTORE_CERT_PATH_SCHEMA_XPATH, client_cert, 0, LYD_PATH_OPT_NOPARENTRET);
238 log_error("could not created yang path\n");
239 return NTS_ERR_FAILED;
243 char *ca_cert = read_key(CA_CERT_PATH);
244 rcl = lyd_new_path(trusted_certificate_node, 0, IETF_TRUSTSTORE_CA_CERT_PATH_SCHEMA_XPATH, ca_cert, 0, LYD_PATH_OPT_NOPARENTRET);
246 log_error("could not created yang path\n");
247 return NTS_ERR_FAILED;
251 rc = sr_edit_batch(session, trusted_certificate_node, "replace");
252 if(rc != SR_ERR_OK) {
253 log_error("could not edit batch on datastore\n");
254 return NTS_ERR_FAILED;
257 rc = sr_validate(session, IETF_TRUSTSTORE_MODULE, 0);
258 if(rc != SR_ERR_OK) {
259 struct ly_err_item *err = ly_err_first(session_context);
260 log_error("sr_validate issues: %s\n", err->msg);
261 return NTS_ERR_FAILED;
264 rc = sr_apply_changes(session, 0, 0);
265 if(rc != SR_ERR_OK) {
266 log_error("could not apply changes on datastore\n");
267 return NTS_ERR_FAILED;
273 static int configure_nacm(sr_session_ctx_t *session) {
277 struct lyd_node *rcl = 0;
279 struct lys_module *module = 0;
280 module = (struct lys_module *) ly_ctx_get_module(session_context, IETF_NETCONF_ACM_MODULE, 0, 0);
282 log_error("could not get module %s from context\n", IETF_NETCONF_ACM_MODULE);
283 return NTS_ERR_FAILED;
286 struct lyd_node *nacm_node = 0;
287 nacm_node = lyd_new(NULL, module, "nacm");
289 log_error("could not create a new lyd_node\n");
290 return NTS_ERR_FAILED;
293 rcl = lyd_new_path(nacm_node, 0, IETF_NETCONF_ACM_ENABLE_NACM_SCHEMA_XPATH, "true", 0, LYD_PATH_OPT_NOPARENTRET);
295 log_error("could not create yang path\n");
296 return NTS_ERR_FAILED;
299 // we hardcoded here the username to be used
300 rcl = lyd_new_path(nacm_node, 0, IETF_NETCONF_ACM_GROUPS_SCHEMA_XPATH"/group[name='sudo']/user-name", "netconf", 0, LYD_PATH_OPT_NOPARENTRET);
302 log_error("could not create yang path\n");
303 return NTS_ERR_FAILED;
306 rcl = lyd_new_path(nacm_node, 0, IETF_NETCONF_ACM_RULE_LIST_SCHEMA_XPATH"[name='sudo-rules']/group", "sudo", 0, LYD_PATH_OPT_NOPARENTRET);
308 log_error("could not create yang path\n");
309 return NTS_ERR_FAILED;
312 rcl = lyd_new_path(nacm_node, 0, IETF_NETCONF_ACM_RULE_LIST_SCHEMA_XPATH"[name='sudo-rules']/rule[name='allow-all-sudo']/module-name", "*", 0, LYD_PATH_OPT_NOPARENTRET);
314 log_error("could not create yang path\n");
315 return NTS_ERR_FAILED;
318 rcl = lyd_new_path(nacm_node, 0, IETF_NETCONF_ACM_RULE_LIST_SCHEMA_XPATH"[name='sudo-rules']/rule[name='allow-all-sudo']/path", "/", 0, LYD_PATH_OPT_NOPARENTRET);
320 log_error("could not create yang path\n");
321 return NTS_ERR_FAILED;
324 rcl = lyd_new_path(nacm_node, 0, IETF_NETCONF_ACM_RULE_LIST_SCHEMA_XPATH"[name='sudo-rules']/rule[name='allow-all-sudo']/access-operations", "*", 0, LYD_PATH_OPT_NOPARENTRET);
326 log_error("could not create yang path\n");
327 return NTS_ERR_FAILED;
330 rcl = lyd_new_path(nacm_node, 0, IETF_NETCONF_ACM_RULE_LIST_SCHEMA_XPATH"[name='sudo-rules']/rule[name='allow-all-sudo']/action", "permit", 0, LYD_PATH_OPT_NOPARENTRET);
332 log_error("could not create yang path\n");
333 return NTS_ERR_FAILED;
336 rcl = lyd_new_path(nacm_node, 0, IETF_NETCONF_ACM_RULE_LIST_SCHEMA_XPATH"[name='sudo-rules']/rule[name='allow-all-sudo']/comment", "Corresponds all the rules under the sudo group as defined in O-RAN.WG4.MP.0-v05.00", 0, LYD_PATH_OPT_NOPARENTRET);
338 log_error("could not create yang path\n");
339 return NTS_ERR_FAILED;
342 rc = sr_edit_batch(session, nacm_node, "replace");
343 if(rc != SR_ERR_OK) {
344 log_error("could not edit batch on datastore\n");
345 return NTS_ERR_FAILED;
348 rc = sr_validate(session, IETF_NETCONF_ACM_MODULE, 0);
349 if(rc != SR_ERR_OK) {
350 struct ly_err_item *err = ly_err_first(session_context);
351 log_error("sr_validate issues: %s\n", err->msg);
352 return NTS_ERR_FAILED;
355 rc = sr_apply_changes(session, 0, 0);
356 if(rc != SR_ERR_OK) {
357 log_error("could not apply changes on datastore\n");
358 return NTS_ERR_FAILED;
364 static int create_ssh_listen_endpoints(struct lyd_node *netconf_node, int ssh_connections) {
365 assert(netconf_node);
369 struct lyd_node *rcl = 0;
372 if(framework_environment.settings.ip_v6_enabled) {
373 sprintf(local_ip, "::");
376 sprintf(local_ip, "0.0.0.0");
379 char *public_ssh_key = read_key(SERVER_PUBLIC_SSH_KEY_PATH);
380 if(public_ssh_key == 0) {
381 log_error("could not read the public ssh key from file %s\n", SERVER_PUBLIC_SSH_KEY_PATH);
382 return NTS_ERR_FAILED;
385 char *ssh_key_string;
387 ssh_key_string = strtok(public_ssh_key, " ");
388 ssh_key_string = strtok(NULL, " ");
390 for(int i = 0; i < ssh_connections; ++i) {
391 char endpoint_name[100];
392 sprintf(endpoint_name, "mng-ssh-%d", i);
394 sprintf(xpath, IETF_NETCONF_SERVER_SSH_TCP_SERVER_PARAM_SCHEMA_XPATH"/local-address", endpoint_name);
395 rcl = lyd_new_path(netconf_node, 0, xpath, local_ip, 0, LYD_PATH_OPT_NOPARENTRET);
397 log_error("could not created yang path\n");
398 return NTS_ERR_FAILED;
402 sprintf(local_port, "%d", nc_config_netconf_port++);
403 sprintf(xpath, IETF_NETCONF_SERVER_SSH_TCP_SERVER_PARAM_SCHEMA_XPATH"/local-port", endpoint_name);
404 rcl = lyd_new_path(netconf_node, 0, xpath, local_port, 0, LYD_PATH_OPT_NOPARENTRET);
406 log_error("could not created yang path\n");
407 return NTS_ERR_FAILED;
410 sprintf(xpath, IETF_NETCONF_SERVER_SSH_TCP_SERVER_PARAM_SCHEMA_XPATH"/keepalives/idle-time", endpoint_name);
411 rcl = lyd_new_path(netconf_node, 0, xpath, "1", 0, LYD_PATH_OPT_NOPARENTRET);
413 log_error("could not created yang path\n");
414 return NTS_ERR_FAILED;
417 sprintf(xpath, IETF_NETCONF_SERVER_SSH_TCP_SERVER_PARAM_SCHEMA_XPATH"/keepalives/max-probes", endpoint_name);
418 rcl = lyd_new_path(netconf_node, 0, xpath, "10", 0, LYD_PATH_OPT_NOPARENTRET);
420 log_error("could not created yang path\n");
421 return NTS_ERR_FAILED;
424 sprintf(xpath, IETF_NETCONF_SERVER_SSH_TCP_SERVER_PARAM_SCHEMA_XPATH"/keepalives/probe-interval", endpoint_name);
425 rcl = lyd_new_path(netconf_node, 0, xpath, "5", 0, LYD_PATH_OPT_NOPARENTRET);
427 log_error("could not created yang path\n");
428 return NTS_ERR_FAILED;
431 sprintf(xpath, IETF_NETCONF_SERVER_SSH_SERVER_PARAM_SCHEMA_XPATH"/server-identity/host-key[name='default-key']/public-key/keystore-reference", endpoint_name);
432 rcl = lyd_new_path(netconf_node, 0, xpath, KS_KEY_NAME, 0, LYD_PATH_OPT_NOPARENTRET);
434 log_error("could not created yang path\n");
435 return NTS_ERR_FAILED;
438 sprintf(xpath, IETF_NETCONF_SERVER_SSH_SERVER_PARAM_SCHEMA_XPATH"/client-authentication/supported-authentication-methods/publickey", endpoint_name);
439 rcl = lyd_new_path(netconf_node, 0, xpath, "", 0, LYD_PATH_OPT_NOPARENTRET);
441 log_error("could not created yang path\n");
442 return NTS_ERR_FAILED;
445 sprintf(xpath, IETF_NETCONF_SERVER_SSH_SERVER_PARAM_SCHEMA_XPATH"/client-authentication/supported-authentication-methods/passsword", endpoint_name);
446 rcl = lyd_new_path(netconf_node, 0, xpath, "", 0, LYD_PATH_OPT_NOPARENTRET);
448 log_error("could not created yang path\n");
449 return NTS_ERR_FAILED;
452 sprintf(xpath, IETF_NETCONF_SERVER_SSH_SERVER_PARAM_SCHEMA_XPATH"/client-authentication/supported-authentication-methods/other", endpoint_name);
453 rcl = lyd_new_path(netconf_node, 0, xpath, "interactive", 0, LYD_PATH_OPT_NOPARENTRET);
455 log_error("could not created yang path\n");
456 return NTS_ERR_FAILED;
459 sprintf(xpath, IETF_NETCONF_SERVER_SSH_SERVER_PARAM_SCHEMA_XPATH"/client-authentication/users/user[name='netconf']/authorized-key[name='%s']/algorithm", endpoint_name, KS_KEY_NAME);
460 rcl = lyd_new_path(netconf_node, 0, xpath, "ssh-rsa", 0, LYD_PATH_OPT_NOPARENTRET);
462 log_error("could not created yang path\n");
463 return NTS_ERR_FAILED;
466 sprintf(xpath, IETF_NETCONF_SERVER_SSH_SERVER_PARAM_SCHEMA_XPATH"/client-authentication/users/user[name='netconf']/authorized-key[name='%s']/key-data", endpoint_name, KS_KEY_NAME);
467 rcl = lyd_new_path(netconf_node, 0, xpath, ssh_key_string, 0, LYD_PATH_OPT_NOPARENTRET);
469 log_error("could not created yang path\n");
470 return NTS_ERR_FAILED;
474 free(public_ssh_key);
479 static int create_tls_listen_endpoints(struct lyd_node *netconf_node, int tls_connections) {
480 assert(netconf_node);
482 struct lyd_node *rcl = 0;
486 if(framework_environment.settings.ip_v6_enabled) {
487 sprintf(local_ip, "::");
490 sprintf(local_ip, "0.0.0.0");
493 for(int i = 0; i < tls_connections + 1; ++i) {
494 char endpoint_name[100];
499 if(i == tls_connections) {
500 //manager connection port
501 sprintf(endpoint_name, "manger-tls-internal");
502 sprintf(local_port, "%d", CLIENT_CONFIG_TLS_PORT);
505 sprintf(endpoint_name, "mng-tls-%d", i);
506 sprintf(local_port, "%d", nc_config_netconf_port++);
509 sprintf(xpath, IETF_NETCONF_SERVER_TLS_TCP_SERVER_PARAM_SCHEMA_XPATH"/local-address", endpoint_name);
510 rcl = lyd_new_path(netconf_node, 0, xpath, local_ip, 0, LYD_PATH_OPT_NOPARENTRET);
512 log_error("could not created yang path\n");
513 return NTS_ERR_FAILED;
516 sprintf(xpath, IETF_NETCONF_SERVER_TLS_TCP_SERVER_PARAM_SCHEMA_XPATH"/local-port", endpoint_name);
517 rcl = lyd_new_path(netconf_node, 0, xpath, local_port, 0, LYD_PATH_OPT_NOPARENTRET);
519 log_error("could not created yang path\n");
520 return NTS_ERR_FAILED;
523 sprintf(xpath, IETF_NETCONF_SERVER_TLS_TCP_SERVER_PARAM_SCHEMA_XPATH"/keepalives/idle-time", endpoint_name);
524 rcl = lyd_new_path(netconf_node, 0, xpath, "1", 0, LYD_PATH_OPT_NOPARENTRET);
526 log_error("could not created yang path\n");
527 return NTS_ERR_FAILED;
530 sprintf(xpath, IETF_NETCONF_SERVER_TLS_TCP_SERVER_PARAM_SCHEMA_XPATH"/keepalives/max-probes", endpoint_name);
531 rcl = lyd_new_path(netconf_node, 0, xpath, "10", 0, LYD_PATH_OPT_NOPARENTRET);
533 log_error("could not created yang path\n");
534 return NTS_ERR_FAILED;
537 sprintf(xpath, IETF_NETCONF_SERVER_TLS_TCP_SERVER_PARAM_SCHEMA_XPATH"/keepalives/probe-interval", endpoint_name);
538 rcl = lyd_new_path(netconf_node, 0, xpath, "5", 0, LYD_PATH_OPT_NOPARENTRET);
540 log_error("could not created yang path\n");
541 return NTS_ERR_FAILED;
544 sprintf(xpath, IETF_NETCONF_SERVER_TLS_SERVER_PARAM_SCHEMA_XPATH"/server-identity/keystore-reference/asymmetric-key", endpoint_name);
545 rcl = lyd_new_path(netconf_node, 0, xpath, KS_KEY_NAME, 0, LYD_PATH_OPT_NOPARENTRET);
547 log_error("could not created yang path\n");
548 return NTS_ERR_FAILED;
551 sprintf(xpath, IETF_NETCONF_SERVER_TLS_SERVER_PARAM_SCHEMA_XPATH"/server-identity/keystore-reference/certificate", endpoint_name);
552 rcl = lyd_new_path(netconf_node, 0, xpath, KS_CERT_NAME, 0, LYD_PATH_OPT_NOPARENTRET);
554 log_error("could not created yang path\n");
555 return NTS_ERR_FAILED;
558 sprintf(xpath, IETF_NETCONF_SERVER_TLS_SERVER_PARAM_SCHEMA_XPATH"/client-authentication/required", endpoint_name);
559 rcl = lyd_new_path(netconf_node, 0, xpath, "", 0, LYD_PATH_OPT_NOPARENTRET);
561 log_error("could not created yang path\n");
562 return NTS_ERR_FAILED;
565 sprintf(xpath, IETF_NETCONF_SERVER_TLS_SERVER_PARAM_SCHEMA_XPATH"/client-authentication/ca-certs", endpoint_name);
566 rcl = lyd_new_path(netconf_node, 0, xpath, "cacerts", 0, LYD_PATH_OPT_NOPARENTRET);
568 log_error("could not created yang path\n");
569 return NTS_ERR_FAILED;
572 sprintf(xpath, IETF_NETCONF_SERVER_TLS_SERVER_PARAM_SCHEMA_XPATH"/client-authentication/client-certs", endpoint_name);
573 rcl = lyd_new_path(netconf_node, 0, xpath, "clientcerts", 0, LYD_PATH_OPT_NOPARENTRET);
575 log_error("could not created yang path\n");
576 return NTS_ERR_FAILED;
579 sprintf(xpath, IETF_NETCONF_SERVER_TLS_SERVER_PARAM_SCHEMA_XPATH"/client-authentication/cert-maps/cert-to-name[id='1']/fingerprint", endpoint_name);
580 rcl = lyd_new_path(netconf_node, 0, xpath, "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);
582 log_error("could not created yang path\n");
583 return NTS_ERR_FAILED;
586 sprintf(xpath, IETF_NETCONF_SERVER_TLS_SERVER_PARAM_SCHEMA_XPATH"/client-authentication/cert-maps/cert-to-name[id='1']/map-type", endpoint_name);
587 rcl = lyd_new_path(netconf_node, session_context, xpath, "ietf-x509-cert-to-name:specified", 0, LYD_PATH_OPT_NOPARENTRET);
589 log_error("could not created yang path\n");
590 return NTS_ERR_FAILED;
593 sprintf(xpath, IETF_NETCONF_SERVER_TLS_SERVER_PARAM_SCHEMA_XPATH"/client-authentication/cert-maps/cert-to-name[id='1']/name", endpoint_name);
594 rcl = lyd_new_path(netconf_node, 0, xpath, "netconf", 0, LYD_PATH_OPT_NOPARENTRET);
596 log_error("could not created yang path\n");
597 return NTS_ERR_FAILED;
604 static int configure_endpoints_connections(sr_session_ctx_t *session) {
609 struct lys_module *module = 0;
610 module = (struct lys_module *)ly_ctx_get_module(session_context, IETF_NETCONF_SERVER_MODULE, 0, 0);
612 log_error("could not get module %s from context\n", IETF_NETCONF_SERVER_MODULE);
613 return NTS_ERR_FAILED;
617 struct lyd_node *netconf_node = 0;
618 netconf_node = lyd_new_path(NULL, session_context, IETF_NETCONF_SERVER_SCHEMA_XPATH, 0, 0, 0);
619 if(netconf_node == 0) {
620 log_error("could not create a new lyd_node\n");
621 return NTS_ERR_FAILED;
624 // create the SSH endpoints in ietf-netconf-server
625 int ssh_connections = 0;
626 if(framework_arguments.nts_mode == NTS_MODE_MANAGER) {
630 ssh_connections = framework_environment.settings.ssh_connections;
633 if(ssh_connections + framework_environment.settings.tls_connections == 0) {
634 log_error("ssh_connections + tls_connections must be at least 1\n");
635 return NTS_ERR_FAILED;
638 if (ssh_connections > 0) {
639 rc = create_ssh_listen_endpoints(netconf_node, ssh_connections);
640 if(rc != NTS_ERR_OK) {
641 log_error("could not create %d SSH Listen endpoints on the NETCONF Server\n", ssh_connections);
642 return NTS_ERR_FAILED;
646 // create the TLS endpoints in ietf-netconf-server
647 if(framework_arguments.nts_mode != NTS_MODE_MANAGER) {
648 rc = create_tls_listen_endpoints(netconf_node, framework_environment.settings.tls_connections);
649 if(rc != NTS_ERR_OK) {
650 log_error("could not create %d TLS Listen endpoints on the NETCONF Server\n", framework_environment.settings.tls_connections);
651 return NTS_ERR_FAILED;
655 rc = sr_edit_batch(session, netconf_node, "replace");
656 if(rc != SR_ERR_OK) {
657 log_error("could not edit batch on datastore\n");
658 return NTS_ERR_FAILED;
661 rc = sr_validate(session, IETF_NETCONF_SERVER_MODULE, 0);
662 if(rc != SR_ERR_OK) {
663 struct ly_err_item *err = ly_err_first(session_context);
664 log_error("sr_validate issues on STARTUP: %s\n", err->msg);
665 return NTS_ERR_FAILED;
668 rc = sr_apply_changes(session, 0, 0);
669 if(rc != SR_ERR_OK) {
670 log_error("could not apply changes on datastore\n");
671 return NTS_ERR_FAILED;