770059529ef61e917929af142e5b3bcf846d7eea
[sim/o1-interface.git] / ntsimulator / ntsim-ng / core / nc_config.c
1 /*************************************************************************
2 *
3 * Copyright 2020 highstreet technologies GmbH and others
4 *
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
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
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 ***************************************************************************/
17
18 #define _GNU_SOURCE
19
20 #include "nc_config.h"
21 #include "utils/log_utils.h"
22 #include "utils/sys_utils.h"
23 #include "utils/http_client.h"
24
25 #include <string.h>
26 #include <stdint.h>
27 #include <stdio.h>
28 #include <assert.h>
29
30 #include <libyang/libyang.h>
31 #include "core/session.h"
32 #include "core/xpath.h"
33 #include "core/framework.h"
34
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"
41
42 static int nc_config_netconf_port = STANDARD_NETCONF_PORT;
43
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);
50
51 int netconf_configure(void) {
52     int rc = NTS_ERR_OK;
53
54     nc_config_netconf_port = STANDARD_NETCONF_PORT;
55
56     //check if was already ran
57     sr_val_t *val = 0;
58     rc = sr_get_item(session_running, IETF_KEYSTORE_SCHEMA_XPATH, 0, &val);
59     if(rc != SR_ERR_OK) {
60         log_error("sr_get_item failed\n");
61         return NTS_ERR_FAILED;
62     }
63     
64     bool already_done = (val->dflt == false);
65     sr_free_val(val);
66     val = 0;
67     if(already_done) {
68         log_add_verbose(2, "netconf_configure() already ran, skipping...\n");
69         return NTS_ERR_OK;
70     }
71
72     // generate and load private keys
73     log_add_verbose(1, "ietf-keystore startup datastore configuration...");
74     rc = load_ssh_keys(session_running);
75     if(rc != 0) {
76         log_error("could not load SSH keys\n");
77         return NTS_ERR_FAILED;
78     }
79     log_add(1, LOG_COLOR_BOLD_GREEN"done\n"LOG_COLOR_RESET);
80
81     // load trusted certificates
82     log_add_verbose(1, "ietf-truststore startup datastore configuration...");
83     rc = load_trusted_certificates(session_running);
84     if(rc != 0) {
85         log_error("could not load trusted certificates\n");
86         return NTS_ERR_FAILED;
87     }
88     log_add(1, LOG_COLOR_BOLD_GREEN"done\n"LOG_COLOR_RESET);
89
90     // configuring NACM
91     log_add_verbose(1, "configuring NACM...");
92     rc = configure_nacm(session_running);
93     if(rc != 0) {
94         log_error("could not configure NACM\n");
95         return NTS_ERR_FAILED;
96     }
97     log_add(1, LOG_COLOR_BOLD_GREEN"done\n"LOG_COLOR_RESET);
98
99     // configure SSH connections
100     log_add_verbose(1, "Configuring connection endpoints...");
101     rc = configure_endpoints_connections(session_running);
102     if(rc != 0) {
103         log_error("could not configure endpoint connections for NETCONF Server\n");
104         return NTS_ERR_FAILED;
105     }
106     log_add(1, LOG_COLOR_BOLD_GREEN"done\n"LOG_COLOR_RESET);
107
108     return NTS_ERR_OK;
109 }
110
111 static int load_ssh_keys(sr_session_ctx_t *session) {
112     assert(session);
113
114     int rc = NTS_ERR_OK;
115     char xpath[500];
116     struct lyd_node *rcl = 0;
117
118     rc = system(GEN_KEY_SCRIPT);
119     if(rc != 0) {
120         log_error("could not generate the SSH keys\n");
121         return NTS_ERR_FAILED;
122     }
123
124     struct lys_module *module;
125     module = (struct lys_module *)ly_ctx_get_module(session_context, IETF_KEYSTORE_MODULE, 0, 0);
126     if(module == 0) {
127         log_error("could not get module %s from context\n", IETF_KEYSTORE_MODULE);
128         return NTS_ERR_FAILED;
129     }
130     
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;
136     }
137
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);
140     if(rcl == 0) {
141         log_error("could not created yang path\n");
142         return NTS_ERR_FAILED;
143     }
144
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;
149     }
150     log_add_verbose(2, "Private Key that was built: \n%s\n", private_key);
151
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);
154     if(rcl == 0) {
155         log_error("could not created yang path\n");
156         return NTS_ERR_FAILED;
157     }
158
159     free(private_key);
160
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;
165     }
166     log_add_verbose(2, "Public Key that was built: \n%s\n", public_key);
167
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);
170     if(rcl == 0) {
171         log_error("could not created yang path\n");
172         return NTS_ERR_FAILED;
173     }
174
175     free(public_key);
176
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;
181     }
182     log_add_verbose(2, "Certificate that was built: \n%s\n", certificate);
183
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);
186     if(rcl == 0) {
187         log_error("could not created yang path\n");
188         return NTS_ERR_FAILED;
189     }
190
191     free(certificate);
192
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;
197     }
198
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);
203         return false;
204     }
205
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;
210     }
211     
212     return NTS_ERR_OK;
213 }
214
215 static int load_trusted_certificates(sr_session_ctx_t *session) {
216     assert(session);
217
218     int rc = NTS_ERR_OK;
219     struct lyd_node *rcl = 0;
220
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);
224     if(module == 0) {
225         log_error("could not get module %s from context\n", IETF_TRUSTSTORE_MODULE);
226         return NTS_ERR_FAILED;
227     }
228
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;
233     }
234
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);
237     if(rcl == 0) {
238         log_error("could not created yang path\n");
239         return NTS_ERR_FAILED;
240     }
241     free(client_cert);
242
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);
245     if(rcl == 0) {
246         log_error("could not created yang path\n");
247         return NTS_ERR_FAILED;
248     }
249     free(ca_cert);
250
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;
255     }
256
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;
262     }
263
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;
268     }
269  
270     return NTS_ERR_OK;
271 }
272
273 static int configure_nacm(sr_session_ctx_t *session) {
274     assert(session);
275
276     int rc = NTS_ERR_OK;
277     struct lyd_node *rcl = 0;
278
279     struct lys_module *module = 0;
280     module = (struct lys_module *) ly_ctx_get_module(session_context, IETF_NETCONF_ACM_MODULE, 0, 0);
281     if(module == 0) {
282         log_error("could not get module %s from context\n", IETF_NETCONF_ACM_MODULE);
283         return NTS_ERR_FAILED;
284     }
285
286     struct lyd_node *nacm_node = 0;
287     nacm_node = lyd_new(NULL, module, "nacm");
288     if(nacm_node == 0) {
289         log_error("could not create a new lyd_node\n");
290         return NTS_ERR_FAILED;
291     }
292
293     rcl = lyd_new_path(nacm_node, 0, IETF_NETCONF_ACM_ENABLE_NACM_SCHEMA_XPATH, "true", 0, LYD_PATH_OPT_NOPARENTRET);
294     if(rcl == 0) {
295         log_error("could not create yang path\n");
296         return NTS_ERR_FAILED;
297     }
298
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);
301     if(rcl == 0) {
302         log_error("could not create yang path\n");
303         return NTS_ERR_FAILED;
304     }
305
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);
307     if(rcl == 0) {
308         log_error("could not create yang path\n");
309         return NTS_ERR_FAILED;
310     }
311
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);
313     if(rcl == 0) {
314         log_error("could not create yang path\n");
315         return NTS_ERR_FAILED;
316     }
317
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);
319     if(rcl == 0) {
320         log_error("could not create yang path\n");
321         return NTS_ERR_FAILED;
322     }
323
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);
325     if(rcl == 0) {
326         log_error("could not create yang path\n");
327         return NTS_ERR_FAILED;
328     }
329
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);
331     if(rcl == 0) {
332         log_error("could not create yang path\n");
333         return NTS_ERR_FAILED;
334     }
335
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);
337     if(rcl == 0) {
338         log_error("could not create yang path\n");
339         return NTS_ERR_FAILED;
340     }
341
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;
346     }
347
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;
353     }
354
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;
359     }
360     
361     return NTS_ERR_OK;
362 }
363
364 static int create_ssh_listen_endpoints(struct lyd_node *netconf_node, int ssh_connections) {
365     assert(netconf_node);
366
367     char xpath[500];
368     char local_ip[30];
369     struct lyd_node *rcl = 0;
370
371     
372     if(framework_environment.settings.ip_v6_enabled) {
373         sprintf(local_ip, "::");
374     }
375     else {
376         sprintf(local_ip, "0.0.0.0");
377     } 
378
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;
383     }
384
385     char *ssh_key_string;
386
387     ssh_key_string = strtok(public_ssh_key, " ");
388     ssh_key_string = strtok(NULL, " ");
389
390     for(int i = 0; i < ssh_connections; ++i) {
391         char endpoint_name[100];
392         sprintf(endpoint_name, "mng-ssh-%d", i);
393
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);
396         if(rcl == 0) {
397             log_error("could not created yang path\n");
398             return NTS_ERR_FAILED;
399         }
400
401         char local_port[10];
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);
405         if(rcl == 0) {
406             log_error("could not created yang path\n");
407             return NTS_ERR_FAILED;
408         }
409
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);
412         if(rcl == 0) {
413             log_error("could not created yang path\n");
414             return NTS_ERR_FAILED;
415         }
416
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);
419         if(rcl == 0) {
420             log_error("could not created yang path\n");
421             return NTS_ERR_FAILED;
422         }
423
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);
426         if(rcl == 0) {
427             log_error("could not created yang path\n");
428             return NTS_ERR_FAILED;
429         }
430
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);
433         if(rcl == 0) {
434             log_error("could not created yang path\n");
435             return NTS_ERR_FAILED;
436         }
437
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);
440         if(rcl == 0) {
441             log_error("could not created yang path\n");
442             return NTS_ERR_FAILED;
443         }
444
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);
447         if(rcl == 0) {
448             log_error("could not created yang path\n");
449             return NTS_ERR_FAILED;
450         }
451
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);
454         if(rcl == 0) {
455             log_error("could not created yang path\n");
456             return NTS_ERR_FAILED;
457         }
458
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);
461         if(rcl == 0) {
462             log_error("could not created yang path\n");
463             return NTS_ERR_FAILED;
464         }
465
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);
468         if(rcl == 0) {
469             log_error("could not created yang path\n");
470             return NTS_ERR_FAILED;
471         }
472     } 
473
474     free(public_ssh_key);
475
476     return NTS_ERR_OK;
477 }
478
479 static int create_tls_listen_endpoints(struct lyd_node *netconf_node, int tls_connections) {
480     assert(netconf_node);
481
482     struct lyd_node *rcl = 0;
483     char xpath[500];
484     char local_ip[30];
485
486     if(framework_environment.settings.ip_v6_enabled) {
487         sprintf(local_ip, "::");
488     }
489     else {
490         sprintf(local_ip, "0.0.0.0");
491     } 
492
493     for(int i = 0; i < tls_connections + 1; ++i) {
494         char endpoint_name[100];
495         char local_port[10];
496         
497         
498
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);
503         }
504         else {
505             sprintf(endpoint_name, "mng-tls-%d", i);
506             sprintf(local_port, "%d", nc_config_netconf_port++);
507         }
508
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);
511         if(rcl == 0) {
512             log_error("could not created yang path\n");
513             return NTS_ERR_FAILED;
514         }
515
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);
518         if(rcl == 0) {
519             log_error("could not created yang path\n");
520             return NTS_ERR_FAILED;
521         }
522
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);
525         if(rcl == 0) {
526             log_error("could not created yang path\n");
527             return NTS_ERR_FAILED;
528         }
529
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);
532         if(rcl == 0) {
533             log_error("could not created yang path\n");
534             return NTS_ERR_FAILED;
535         }
536
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);
539         if(rcl == 0) {
540             log_error("could not created yang path\n");
541             return NTS_ERR_FAILED;
542         }
543
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);
546         if(rcl == 0) {
547             log_error("could not created yang path\n");
548             return NTS_ERR_FAILED;
549         }
550
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);
553         if(rcl == 0) {
554             log_error("could not created yang path\n");
555             return NTS_ERR_FAILED;
556         }
557
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);
560         if(rcl == 0) {
561             log_error("could not created yang path\n");
562             return NTS_ERR_FAILED;
563         }
564
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);
567         if(rcl == 0) {
568             log_error("could not created yang path\n");
569             return NTS_ERR_FAILED;
570         }
571
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);
574         if(rcl == 0) {
575             log_error("could not created yang path\n");
576             return NTS_ERR_FAILED;
577         }
578
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);
581         if(rcl == 0) {
582             log_error("could not created yang path\n");
583             return NTS_ERR_FAILED;
584         }
585
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);
588         if(rcl == 0) {
589             log_error("could not created yang path\n");
590             return NTS_ERR_FAILED;
591         }
592
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);
595         if(rcl == 0) {
596             log_error("could not created yang path\n");
597             return NTS_ERR_FAILED;
598         }
599     }
600
601     return NTS_ERR_OK;
602 }
603
604 static int configure_endpoints_connections(sr_session_ctx_t *session) {
605     assert(session);
606
607     int rc = NTS_ERR_OK;
608
609     struct lys_module *module = 0;
610     module = (struct lys_module *)ly_ctx_get_module(session_context, IETF_NETCONF_SERVER_MODULE, 0, 0);
611     if(module == 0) {
612         log_error("could not get module %s from context\n", IETF_NETCONF_SERVER_MODULE);
613         return NTS_ERR_FAILED;
614     }
615
616
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;
622     }
623
624     // create the SSH endpoints in ietf-netconf-server
625     int ssh_connections = 0;
626     if(framework_arguments.nts_mode == NTS_MODE_MANAGER) {
627         ssh_connections = 1;
628     }
629     else {
630         ssh_connections = framework_environment.settings.ssh_connections;
631     }
632
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;
636     }
637
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;
643         }
644     }
645
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;
652         }
653     }
654     
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;
659     }
660
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;
666     }
667
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;
672     }
673     
674     return NTS_ERR_OK;
675 }