43402ebd6d1ef9150e3710593c905a8f2f5e5e7e
[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 #include <stdio.h>
25 #include <assert.h>
26
27 #include <libyang/libyang.h>
28 #include "core/session.h"
29 #include "core/framework.h"
30
31 #define GEN_KEY_SCRIPT                              "/home/netconf/.ssh/generate-ssh-keys.sh"
32 #define KS_CERT_NAME                                "melacon_server_cert"
33 #define SERVER_PRIVATE_KEY_PATH                     "/home/netconf/.ssh/melacon.server.key"
34 #define SERVER_PUBLIC_KEY_PATH                      "/home/netconf/.ssh/melacon.server.key.pub.pem"
35 #define SERVER_CERT_PATH                            "/home/netconf/.ssh/melacon.server.crt"
36 #define CLIENT_CERT_PATH                            "/home/netconf/.ssh/client.crt"
37 #define CA_CERT_PATH                                "/home/netconf/.ssh/ca.pem"
38
39 static int nc_config_netconf_port = STANDARD_NETCONF_PORT;
40
41 static int load_ssh_keys(sr_session_ctx_t *session);
42 static int load_trusted_certificates(sr_session_ctx_t *session);
43 static int remove_nacm(sr_session_ctx_t *session);
44 static int create_ssh_listen_endpoints(struct lyd_node *netconf_node, int ssh_connections);
45 static int create_tls_listen_endpoints(struct lyd_node *netconf_node, int tls_connections);
46 static int configure_endpoints_connections(sr_session_ctx_t *session);
47
48 int netconf_configure(void) {
49     int rc = NTS_ERR_OK;
50
51     nc_config_netconf_port = STANDARD_NETCONF_PORT;
52
53     sr_session_ctx_t *current_session;
54     rc = sr_session_start(session_connection, SR_DS_RUNNING, &current_session);
55     if(rc != 0) {
56         log_error("could not start session on running datastore");
57         return NTS_ERR_FAILED;
58     }
59
60     // generate and load private keys
61     log_message(1, "ietf-keystore startup datastore configuration...");     //checkAS e ok aici ?
62     rc = load_ssh_keys(current_session);
63     if(rc != 0) {
64         log_error("could not load SSH keys");
65         return NTS_ERR_FAILED;
66     }
67     log_message(1, LOG_COLOR_BOLD_GREEN"done\n"LOG_COLOR_RESET);
68
69     // load trusted certificates
70     log_message(1, "ietf-truststore startup datastore configuration...");
71     rc = load_trusted_certificates(current_session);
72     if(rc != 0) {
73         log_error("could not load trusted certificates");
74         return NTS_ERR_FAILED;
75     }
76     log_message(1, LOG_COLOR_BOLD_GREEN"done\n"LOG_COLOR_RESET);
77
78     // remove NACM
79     log_message(1, "Removing NACM...");
80     rc = remove_nacm(current_session);
81     if(rc != 0) {
82         log_error("could not remove NACM");
83         return NTS_ERR_FAILED;
84     }
85     log_message(1, LOG_COLOR_BOLD_GREEN"done\n"LOG_COLOR_RESET);
86
87     // configure SSH connections
88     log_message(1, "Configuring connection endpoints...");
89     rc = configure_endpoints_connections(current_session);
90     if(rc != 0) {
91         log_error("could not configure endpoint connections forNETCONF Server");
92         return NTS_ERR_FAILED;
93     }
94     log_message(1, LOG_COLOR_BOLD_GREEN"done\n"LOG_COLOR_RESET);
95
96     rc = sr_session_stop(current_session);
97     if(rc != 0) {
98         log_error("could not configure stop current sysrepo session");
99         return NTS_ERR_FAILED;
100     }
101
102     return NTS_ERR_OK;
103 }
104
105 static int load_ssh_keys(sr_session_ctx_t *session) {
106     assert(session);
107
108     int rc = NTS_ERR_OK;
109     char xpath[500];
110     struct lyd_node *rcl = 0;
111
112     rc = system(GEN_KEY_SCRIPT);
113     if(rc != 0) {
114         log_error("could not generate the SSH keys");
115         return NTS_ERR_FAILED;
116     }
117
118     struct lys_module *module;
119     module = (struct lys_module *)ly_ctx_get_module(session_context, "ietf-keystore", 0, 0);
120     if(module == 0) {
121         log_error("could not get module %s from context", "ietf-keystore");
122         return NTS_ERR_FAILED;
123     }
124     
125     struct lyd_node *keystore_node = 0;
126     keystore_node = lyd_new(NULL, module, "keystore");
127     if(keystore_node == 0) {
128         log_error("could not create a new lyd_node");
129         return NTS_ERR_FAILED;
130     }
131
132     sprintf(xpath, "/ietf-keystore:keystore/asymmetric-keys/asymmetric-key[name='%s']/algorithm", KS_KEY_NAME);
133     rcl = lyd_new_path(keystore_node, 0, xpath, "rsa2048", 0, LYD_PATH_OPT_NOPARENTRET);
134     if(rcl == 0) {
135         log_error("could not created yang path");
136         return NTS_ERR_FAILED;
137     }
138
139     char *private_key = read_key(SERVER_PRIVATE_KEY_PATH);
140     if(private_key == 0) {
141         log_error("could not read the private key from path=%s", SERVER_PRIVATE_KEY_PATH);
142         return NTS_ERR_FAILED;
143     }
144     log_message(2, "Private Key that was built: \n%s\n", private_key);
145
146     sprintf(xpath, "/ietf-keystore:keystore/asymmetric-keys/asymmetric-key[name='%s']/private-key", KS_KEY_NAME);
147     rcl = lyd_new_path(keystore_node, 0, xpath, private_key, 0, LYD_PATH_OPT_NOPARENTRET);
148     if(rcl == 0) {
149         log_error("could not created yang path");
150         return NTS_ERR_FAILED;
151     }
152
153     free(private_key);
154
155     char *public_key = read_key(SERVER_PUBLIC_KEY_PATH);
156     if(public_key == 0) {
157         log_error("could not read the public key from path=%s", SERVER_PUBLIC_KEY_PATH);
158         return NTS_ERR_FAILED;
159     }
160     log_message(2, "Public Key that was built: \n%s\n", public_key);
161
162     sprintf(xpath, "/ietf-keystore:keystore/asymmetric-keys/asymmetric-key[name='%s']/public-key", KS_KEY_NAME);
163     rcl = lyd_new_path(keystore_node, 0, xpath, public_key, 0, LYD_PATH_OPT_NOPARENTRET);
164     if(rcl == 0) {
165         log_error("could not created yang path");
166         return NTS_ERR_FAILED;
167     }
168
169     free(public_key);
170
171     char *certificate = read_key(SERVER_CERT_PATH);
172     if(certificate == 0) {
173         log_error("could not read the certificate from path=%s", SERVER_CERT_PATH);
174         return NTS_ERR_FAILED;
175     }
176     log_message(2, "Certificate that was built: \n%s\n", certificate);
177
178     sprintf(xpath, "/ietf-keystore:keystore/asymmetric-keys/asymmetric-key[name='%s']/certificates/certificate[name='%s']/cert", KS_KEY_NAME, KS_CERT_NAME);
179     rcl = lyd_new_path(keystore_node, 0, xpath, certificate, 0, LYD_PATH_OPT_NOPARENTRET);
180     if(rcl == 0) {
181         log_error("could not created yang path");
182         return NTS_ERR_FAILED;
183     }
184
185     free(certificate);
186
187     rc = sr_edit_batch(session, keystore_node, "replace");
188     if(rc != SR_ERR_OK) {
189         log_error("could not edit batch on datastore");
190         return NTS_ERR_FAILED;
191     }
192
193     rc = sr_validate(session, "ietf-keystore", 0);
194     if(rc != SR_ERR_OK) {
195         struct ly_err_item *err = ly_err_first(session_context);
196         log_error("sr_validate issues on STARTUP: %s", err->msg);
197         return false;
198     }
199
200     rc = sr_apply_changes(session, 0, 0);
201     if(rc != SR_ERR_OK) {
202         log_error("could not apply changes on datastore");
203         return NTS_ERR_FAILED;
204     }
205     
206     return NTS_ERR_OK;
207 }
208
209 static int load_trusted_certificates(sr_session_ctx_t *session) {
210     assert(session);
211
212     int rc = NTS_ERR_OK;
213     struct lyd_node *rcl = 0;
214
215     struct lyd_node *trusted_certificate_node = 0;
216     struct lys_module *module;
217     module = (struct lys_module *)ly_ctx_get_module(session_context, "ietf-truststore", 0, 0);
218     if(module == 0) {
219         log_error("could not get module %s from context", "ietf-truststore");
220         return NTS_ERR_FAILED;
221     }
222
223     trusted_certificate_node = lyd_new(NULL, module, "truststore");
224     if(trusted_certificate_node == 0) {
225         log_error("could not create a new lyd_node");
226         return NTS_ERR_FAILED;
227     }
228
229     char xpath[500];
230
231     sprintf(xpath, "/ietf-truststore:truststore/certificates[name='clientcerts']/certificate[name='clientcert']/cert");
232     char *client_cert = read_key(CLIENT_CERT_PATH);
233     rcl = lyd_new_path(trusted_certificate_node, 0, xpath, client_cert, 0, LYD_PATH_OPT_NOPARENTRET);
234     if(rcl == 0) {
235         log_error("could not created yang path");
236         return NTS_ERR_FAILED;
237     }
238     free(client_cert);
239
240     sprintf(xpath, "/ietf-truststore:truststore/certificates[name='cacerts']/certificate[name='cacert']/cert");
241     char *ca_cert = read_key(CA_CERT_PATH);
242     rcl = lyd_new_path(trusted_certificate_node, 0, xpath, ca_cert, 0, LYD_PATH_OPT_NOPARENTRET);
243     if(rcl == 0) {
244         log_error("could not created yang path");
245         return NTS_ERR_FAILED;
246     }
247     free(ca_cert);
248
249     rc = sr_edit_batch(session, trusted_certificate_node, "replace");
250     if(rc != SR_ERR_OK) {
251         log_error("could not edit batch on datastore");
252         return NTS_ERR_FAILED;
253     }
254
255     rc = sr_validate(session, "ietf-truststore", 0);
256     if(rc != SR_ERR_OK) {
257         struct ly_err_item *err = ly_err_first(session_context);
258         log_error("sr_validate issues on STARTUP: %s", err->msg);
259         return NTS_ERR_FAILED;
260     }
261
262     rc = sr_apply_changes(session, 0, 0);
263     if(rc != SR_ERR_OK) {
264         log_error("could not apply changes on datastore");
265         return NTS_ERR_FAILED;
266     }
267  
268     return NTS_ERR_OK;
269 }
270
271 static int remove_nacm(sr_session_ctx_t *session) {
272     assert(session);
273
274     int rc = NTS_ERR_OK;
275     struct lyd_node *rcl = 0;
276     char xpath[100];
277
278     struct lys_module *module = 0;
279     module = (struct lys_module *) ly_ctx_get_module(session_context, "ietf-netconf-acm", 0, 0);
280     if(module == 0) {
281         log_error("could not get module %s from context", "ietf-netconf-acm");
282         return NTS_ERR_FAILED;
283     }
284
285     struct lyd_node *nacm_node = 0;
286     nacm_node = lyd_new(NULL, module, "nacm");
287     if(nacm_node == 0) {
288         log_error("could not create a new lyd_node");
289         return NTS_ERR_FAILED;
290     }
291
292     sprintf(xpath, "/ietf-netconf-acm:nacm/enable-nacm");
293     rcl = lyd_new_path(nacm_node, 0, xpath, "false", 0, LYD_PATH_OPT_NOPARENTRET);
294     if(rcl == 0) {
295         log_error("could not created yang path");
296         return NTS_ERR_FAILED;
297     }
298
299     rc = sr_edit_batch(session, nacm_node, "replace");
300     if(rc != SR_ERR_OK) {
301         log_error("could not edit batch on datastore");
302         return NTS_ERR_FAILED;
303     }
304
305     rc = sr_validate(session, "ietf-netconf-acm", 0);
306     if(rc != SR_ERR_OK) {
307         struct ly_err_item *err = ly_err_first(session_context);
308         log_error("sr_validate issues on STARTUP: %s", err->msg);
309         return NTS_ERR_FAILED;
310     }
311
312     rc = sr_apply_changes(session, 0, 0);
313     if(rc != SR_ERR_OK) {
314         log_error("could not apply changes on datastore");
315         return NTS_ERR_FAILED;
316     }
317     
318     return NTS_ERR_OK;
319 }
320
321 static int create_ssh_listen_endpoints(struct lyd_node *netconf_node, int ssh_connections) {
322     assert(netconf_node);
323
324     char xpath[500];
325     char local_ip[30];
326     struct lyd_node *rcl = 0;
327
328     
329     if(framework_environment.ip_v6_enabled) {
330         sprintf(local_ip, "::");
331     }
332     else {
333         sprintf(local_ip, "0.0.0.0");
334     } 
335
336     char *public_ssh_key = read_key(SERVER_PUBLIC_SSH_KEY_PATH);
337     if(public_ssh_key == 0) {
338         log_error("could not read the public ssh key from file %s", SERVER_PUBLIC_SSH_KEY_PATH);
339         return NTS_ERR_FAILED;
340     }
341
342     char *ssh_key_string;
343
344     ssh_key_string = strtok(public_ssh_key, " ");
345     ssh_key_string = strtok(NULL, " ");
346
347     for(int i=0; i < ssh_connections; ++i) {
348         char endpoint_name[100];
349         sprintf(endpoint_name, "mng-ssh-%d", i);
350
351         sprintf(xpath, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/tcp-server-parameters/local-address", endpoint_name);
352         rcl = lyd_new_path(netconf_node, 0, xpath, local_ip, 0, LYD_PATH_OPT_NOPARENTRET);
353         if(rcl == 0) {
354             log_error("could not created yang path");
355             return NTS_ERR_FAILED;
356         }
357
358         char local_port[10];
359         sprintf(local_port, "%d", nc_config_netconf_port++);
360         sprintf(xpath, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/tcp-server-parameters/local-port", endpoint_name);
361         rcl = lyd_new_path(netconf_node, 0, xpath, local_port, 0, LYD_PATH_OPT_NOPARENTRET);
362         if(rcl == 0) {
363             log_error("could not created yang path");
364             return NTS_ERR_FAILED;
365         }
366
367         sprintf(xpath, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/tcp-server-parameters/keepalives/idle-time", endpoint_name);
368         rcl = lyd_new_path(netconf_node, 0, xpath, "1", 0, LYD_PATH_OPT_NOPARENTRET);
369         if(rcl == 0) {
370             log_error("could not created yang path");
371             return NTS_ERR_FAILED;
372         }
373
374         sprintf(xpath, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/tcp-server-parameters/keepalives/max-probes", endpoint_name);
375         rcl = lyd_new_path(netconf_node, 0, xpath, "10", 0, LYD_PATH_OPT_NOPARENTRET);
376         if(rcl == 0) {
377             log_error("could not created yang path");
378             return NTS_ERR_FAILED;
379         }
380
381         sprintf(xpath, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/tcp-server-parameters/keepalives/probe-interval", endpoint_name);
382         rcl = lyd_new_path(netconf_node, 0, xpath, "5", 0, LYD_PATH_OPT_NOPARENTRET);
383         if(rcl == 0) {
384             log_error("could not created yang path");
385             return NTS_ERR_FAILED;
386         }
387
388         sprintf(xpath, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/ssh-server-parameters/server-identity/host-key[name='default-key']/public-key/keystore-reference", endpoint_name);
389         rcl = lyd_new_path(netconf_node, 0, xpath, KS_KEY_NAME, 0, LYD_PATH_OPT_NOPARENTRET);
390         if(rcl == 0) {
391             log_error("could not created yang path");
392             return NTS_ERR_FAILED;
393         }
394
395         sprintf(xpath, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/supported-authentication-methods/publickey", endpoint_name);
396         rcl = lyd_new_path(netconf_node, 0, xpath, "", 0, LYD_PATH_OPT_NOPARENTRET);
397         if(rcl == 0) {
398             log_error("could not created yang path");
399             return NTS_ERR_FAILED;
400         }
401
402         sprintf(xpath, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/supported-authentication-methods/passsword", endpoint_name);
403         rcl = lyd_new_path(netconf_node, 0, xpath, "", 0, LYD_PATH_OPT_NOPARENTRET);
404         if(rcl == 0) {
405             log_error("could not created yang path");
406             return NTS_ERR_FAILED;
407         }
408
409         sprintf(xpath, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/supported-authentication-methods/other", endpoint_name);
410         rcl = lyd_new_path(netconf_node, 0, xpath, "interactive", 0, LYD_PATH_OPT_NOPARENTRET);
411         if(rcl == 0) {
412             log_error("could not created yang path");
413             return NTS_ERR_FAILED;
414         }
415
416         sprintf(xpath, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/users/user[name='netconf']/authorized-key[name='%s']/algorithm", endpoint_name, KS_KEY_NAME);
417         rcl = lyd_new_path(netconf_node, 0, xpath, "ssh-rsa", 0, LYD_PATH_OPT_NOPARENTRET);
418         if(rcl == 0) {
419             log_error("could not created yang path");
420             return NTS_ERR_FAILED;
421         }
422
423         sprintf(xpath, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/users/user[name='netconf']/authorized-key[name='%s']/key-data", endpoint_name, KS_KEY_NAME);
424         rcl = lyd_new_path(netconf_node, 0, xpath, ssh_key_string, 0, LYD_PATH_OPT_NOPARENTRET);
425         if(rcl == 0) {
426             log_error("could not created yang path");
427             return NTS_ERR_FAILED;
428         }
429     } 
430
431     free(public_ssh_key);
432
433     return NTS_ERR_OK;
434 }
435
436 static int create_tls_listen_endpoints(struct lyd_node *netconf_node, int tls_connections) {
437     assert(netconf_node);
438
439     struct lyd_node *rcl = 0;
440     char xpath[500];
441     char local_ip[30];
442
443     if(framework_environment.ip_v6_enabled) {
444         sprintf(local_ip, "::");
445     }
446     else {
447         sprintf(local_ip, "0.0.0.0");
448     } 
449
450     for(int i=0; i < tls_connections; ++i) {
451         char endpoint_name[100];
452         sprintf(endpoint_name, "mng-tls-%d", i);
453
454         sprintf(xpath, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/tls/tcp-server-parameters/local-address", endpoint_name);
455         rcl = lyd_new_path(netconf_node, 0, xpath, local_ip, 0, LYD_PATH_OPT_NOPARENTRET);
456         if(rcl == 0) {
457             log_error("could not created yang path");
458             return NTS_ERR_FAILED;
459         }
460
461         char local_port[10];
462         sprintf(local_port, "%d", nc_config_netconf_port++);
463         sprintf(xpath, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/tls/tcp-server-parameters/local-port", endpoint_name);
464         rcl = lyd_new_path(netconf_node, 0, xpath, local_port, 0, LYD_PATH_OPT_NOPARENTRET);
465         if(rcl == 0) {
466             log_error("could not created yang path");
467             return NTS_ERR_FAILED;
468         }
469
470         sprintf(xpath, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/tls/tcp-server-parameters/keepalives/idle-time", endpoint_name);
471         rcl = lyd_new_path(netconf_node, 0, xpath, "1", 0, LYD_PATH_OPT_NOPARENTRET);
472         if(rcl == 0) {
473             log_error("could not created yang path");
474             return NTS_ERR_FAILED;
475         }
476
477         sprintf(xpath, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/tls/tcp-server-parameters/keepalives/max-probes", endpoint_name);
478         rcl = lyd_new_path(netconf_node, 0, xpath, "10", 0, LYD_PATH_OPT_NOPARENTRET);
479         if(rcl == 0) {
480             log_error("could not created yang path");
481             return NTS_ERR_FAILED;
482         }
483
484         sprintf(xpath, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/tls/tcp-server-parameters/keepalives/probe-interval", endpoint_name);
485         rcl = lyd_new_path(netconf_node, 0, xpath, "5", 0, LYD_PATH_OPT_NOPARENTRET);
486         if(rcl == 0) {
487             log_error("could not created yang path");
488             return NTS_ERR_FAILED;
489         }
490
491         sprintf(xpath, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/tls/tls-server-parameters/server-identity/keystore-reference/asymmetric-key", endpoint_name);
492         rcl = lyd_new_path(netconf_node, 0, xpath, KS_KEY_NAME, 0, LYD_PATH_OPT_NOPARENTRET);
493         if(rcl == 0) {
494             log_error("could not created yang path");
495             return NTS_ERR_FAILED;
496         }
497
498         sprintf(xpath, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/tls/tls-server-parameters/server-identity/keystore-reference/certificate", endpoint_name);
499         rcl = lyd_new_path(netconf_node, 0, xpath, KS_CERT_NAME, 0, LYD_PATH_OPT_NOPARENTRET);
500         if(rcl == 0) {
501             log_error("could not created yang path");
502             return NTS_ERR_FAILED;
503         }
504
505         sprintf(xpath, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/tls/tls-server-parameters/client-authentication/required", endpoint_name);
506         rcl = lyd_new_path(netconf_node, 0, xpath, "", 0, LYD_PATH_OPT_NOPARENTRET);
507         if(rcl == 0) {
508             log_error("could not created yang path");
509             return NTS_ERR_FAILED;
510         }
511
512         sprintf(xpath, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/tls/tls-server-parameters/client-authentication/ca-certs", endpoint_name);
513         rcl = lyd_new_path(netconf_node, 0, xpath, "cacerts", 0, LYD_PATH_OPT_NOPARENTRET);
514         if(rcl == 0) {
515             log_error("could not created yang path");
516             return NTS_ERR_FAILED;
517         }
518
519         sprintf(xpath, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/tls/tls-server-parameters/client-authentication/client-certs", endpoint_name);
520         rcl = lyd_new_path(netconf_node, 0, xpath, "clientcerts", 0, LYD_PATH_OPT_NOPARENTRET);
521         if(rcl == 0) {
522             log_error("could not created yang path");
523             return NTS_ERR_FAILED;
524         }
525
526         sprintf(xpath, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/tls/tls-server-parameters/client-authentication/cert-maps/cert-to-name[id='1']/fingerprint", endpoint_name);
527         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);
528         if(rcl == 0) {
529             log_error("could not created yang path");
530             return NTS_ERR_FAILED;
531         }
532
533         sprintf(xpath, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/tls/tls-server-parameters/client-authentication/cert-maps/cert-to-name[id='1']/map-type", endpoint_name);
534         rcl = lyd_new_path(netconf_node, session_context, xpath, "ietf-x509-cert-to-name:specified", 0, LYD_PATH_OPT_NOPARENTRET);
535         if(rcl == 0) {
536             log_error("could not created yang path");
537             return NTS_ERR_FAILED;
538         }
539
540         sprintf(xpath, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/tls/tls-server-parameters/client-authentication/cert-maps/cert-to-name[id='1']/name", endpoint_name);
541         rcl = lyd_new_path(netconf_node, 0, xpath, "netconf-tls", 0, LYD_PATH_OPT_NOPARENTRET);
542         if(rcl == 0) {
543             log_error("could not created yang path");
544             return NTS_ERR_FAILED;
545         }
546     }
547
548     return NTS_ERR_OK;
549 }
550
551 static int configure_endpoints_connections(sr_session_ctx_t *session) {
552     assert(session);
553
554     int rc = NTS_ERR_OK;
555
556     struct lys_module *module = 0;
557     module = (struct lys_module *)ly_ctx_get_module(session_context, "ietf-netconf-server", 0, 0);
558     if(module == 0) {
559         log_error("could not get module %s from context", "ietf-netconf-server");
560         return NTS_ERR_FAILED;
561     }
562
563
564     struct lyd_node *netconf_node = 0;
565     netconf_node = lyd_new_path(NULL, session_context, "/ietf-netconf-server:netconf-server", 0, 0, 0);
566     if(netconf_node == 0) {
567         log_error("could not create a new lyd_node");
568         return NTS_ERR_FAILED;
569     }
570
571     // create the SSH endpoints in ietf-netconf-server
572     int ssh_connections = 0;
573     if(framework_arguments.manager) {
574         ssh_connections = 1;
575     }
576     else {
577         ssh_connections = framework_environment.ssh_connections;
578     }
579
580     if(ssh_connections == 0) {
581         log_error("ssh_connections must be at least 1");
582         return NTS_ERR_FAILED;
583     }
584
585     rc = create_ssh_listen_endpoints(netconf_node, ssh_connections);
586     if(rc != NTS_ERR_OK) {
587         log_error("could not create %d SSH Listen endpoints on the NETCONF Server", ssh_connections);
588         return NTS_ERR_FAILED;
589     }
590
591     // create the TLS endpoints in ietf-netconf-server
592     if(framework_arguments.manager == false) {
593         rc = create_tls_listen_endpoints(netconf_node, framework_environment.tls_connections);
594         if(rc != NTS_ERR_OK) {
595             log_error("could not create %d TLS Listen endpoints on the NETCONF Server", framework_environment.tls_connections);
596             return NTS_ERR_FAILED;
597         }
598     }
599     
600     rc = sr_edit_batch(session, netconf_node, "replace");
601     if(rc != SR_ERR_OK) {
602         log_error("could not edit batch on datastore");
603         return NTS_ERR_FAILED;
604     }
605
606     rc = sr_validate(session, "ietf-netconf-server", 0);
607     if(rc != SR_ERR_OK) {
608         struct ly_err_item *err = ly_err_first(session_context);
609         log_error("sr_validate issues on STARTUP: %s", err->msg);
610         return NTS_ERR_FAILED;
611     }
612
613     rc = sr_apply_changes(session, 0, 0);
614     if(rc != SR_ERR_OK) {
615         log_error("could not apply changes on datastore");
616         return NTS_ERR_FAILED;
617     }
618     
619     return NTS_ERR_OK;
620 }