blob: 290b70cd4c12454cb8c7c8c9d8782b0a71789a05 [file] [log] [blame]
roman27215242023-03-10 14:55:00 +01001/**
roman466719d2023-05-05 16:14:37 +02002 * @file config_new_ssh.c
roman27215242023-03-10 14:55:00 +01003 * @author Roman Janota <janota@cesnet.cz>
roman3f9b65c2023-06-05 14:26:58 +02004 * @brief libnetconf2 server new SSH configuration creation functions
roman27215242023-03-10 14:55:00 +01005 *
6 * @copyright
roman466719d2023-05-05 16:14:37 +02007 * Copyright (c) 2023 CESNET, z.s.p.o.
roman27215242023-03-10 14:55:00 +01008 *
9 * This source code is licensed under BSD 3-Clause License (the "License").
10 * You may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 * https://opensource.org/licenses/BSD-3-Clause
14 */
15
16#define _GNU_SOURCE
17
roman31820092023-03-24 15:26:21 +010018#include <crypt.h>
roman27215242023-03-10 14:55:00 +010019#include <stdarg.h>
20#include <stdio.h>
21#include <stdlib.h>
22#include <string.h>
23
roman3f9b65c2023-06-05 14:26:58 +020024#include <libyang/libyang.h>
roman27215242023-03-10 14:55:00 +010025
26#include "compat.h"
roman3f9b65c2023-06-05 14:26:58 +020027#include "config.h"
28#include "config_new.h"
29#include "log_p.h"
roman27215242023-03-10 14:55:00 +010030#include "server_config.h"
roman3f9b65c2023-06-05 14:26:58 +020031#include "session_p.h"
roman27215242023-03-10 14:55:00 +010032
roman31820092023-03-24 15:26:21 +010033#if !defined (HAVE_CRYPT_R)
34extern pthread_mutex_t crypt_lock;
35#endif
36
roman9d5e5a52023-07-14 12:43:44 +020037static int
38_nc_server_config_new_ssh_hostkey(const struct ly_ctx *ctx, const char *tree_path,
roman5cbb6532023-06-22 12:53:17 +020039 const char *privkey_path, const char *pubkey_path, struct lyd_node **config)
roman27215242023-03-10 14:55:00 +010040{
41 int ret = 0;
romand30af552023-06-16 15:18:27 +020042 char *pubkey = NULL, *privkey = NULL;
roman466719d2023-05-05 16:14:37 +020043 NC_PRIVKEY_FORMAT privkey_type;
roman3f9b65c2023-06-05 14:26:58 +020044 NC_PUBKEY_FORMAT pubkey_type;
romand30af552023-06-16 15:18:27 +020045 const char *privkey_format, *pubkey_format;
roman27215242023-03-10 14:55:00 +010046
roman27215242023-03-10 14:55:00 +010047 /* get the keys as a string from the given files */
roman3f9b65c2023-06-05 14:26:58 +020048 ret = nc_server_config_new_get_keys(privkey_path, pubkey_path, &privkey, &pubkey, &privkey_type, &pubkey_type);
roman27215242023-03-10 14:55:00 +010049 if (ret) {
50 ERR(NULL, "Getting keys from file(s) failed.");
51 goto cleanup;
52 }
53
romand30af552023-06-16 15:18:27 +020054 /* pubkey format to str */
roman3f9b65c2023-06-05 14:26:58 +020055 if (pubkey_type == NC_PUBKEY_FORMAT_SSH2) {
romand30af552023-06-16 15:18:27 +020056 pubkey_format = "ietf-crypto-types:ssh-public-key-format";
roman27215242023-03-10 14:55:00 +010057 } else {
romand30af552023-06-16 15:18:27 +020058 pubkey_format = "ietf-crypto-types:subject-public-key-info-format";
roman27215242023-03-10 14:55:00 +010059 }
60
roman3f9b65c2023-06-05 14:26:58 +020061 /* get privkey identityref value */
romand30af552023-06-16 15:18:27 +020062 privkey_format = nc_config_new_privkey_format_to_identityref(privkey_type);
63 if (!privkey_format) {
roman27215242023-03-10 14:55:00 +010064 ret = 1;
roman3f9b65c2023-06-05 14:26:58 +020065 goto cleanup;
roman27215242023-03-10 14:55:00 +010066 }
roman466719d2023-05-05 16:14:37 +020067
Roytakfa9068e2023-07-27 12:56:01 +020068 ret = nc_config_new_create_append(ctx, tree_path, "inline-definition/public-key-format", pubkey_format, config);
roman27215242023-03-10 14:55:00 +010069 if (ret) {
70 goto cleanup;
71 }
72
Roytakfa9068e2023-07-27 12:56:01 +020073 ret = nc_config_new_create_append(ctx, tree_path, "inline-definition/public-key", pubkey, config);
roman27215242023-03-10 14:55:00 +010074 if (ret) {
75 goto cleanup;
76 }
77
Roytakfa9068e2023-07-27 12:56:01 +020078 ret = nc_config_new_create_append(ctx, tree_path, "inline-definition/private-key-format", privkey_format, config);
roman3f9b65c2023-06-05 14:26:58 +020079 if (ret) {
80 goto cleanup;
81 }
82
Roytakfa9068e2023-07-27 12:56:01 +020083 ret = nc_config_new_create_append(ctx, tree_path, "inline-definition/cleartext-private-key", privkey, config);
84 if (ret) {
85 goto cleanup;
86 }
87
88 /* delete keystore choice nodes if present */
89 ret = nc_config_new_check_delete(config, "%s/keystore-reference", tree_path);
roman4f9bb442023-03-24 09:05:37 +010090 if (ret) {
91 goto cleanup;
92 }
93
roman27215242023-03-10 14:55:00 +010094cleanup:
roman466719d2023-05-05 16:14:37 +020095 free(privkey);
96 free(pubkey);
roman27215242023-03-10 14:55:00 +010097 return ret;
98}
99
roman8ba6efa2023-07-12 15:27:52 +0200100API int
roman9d5e5a52023-07-14 12:43:44 +0200101nc_server_config_new_ssh_hostkey(const struct ly_ctx *ctx, const char *endpt_name, const char *hostkey_name,
102 const char *privkey_path, const char *pubkey_path, struct lyd_node **config)
103{
104 int ret = 0;
105 char *path = NULL;
106
107 NC_CHECK_ARG_RET(NULL, ctx, endpt_name, hostkey_name, privkey_path, config, 1);
108
109 if (asprintf(&path, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/ssh-server-parameters/"
Roytakfa9068e2023-07-27 12:56:01 +0200110 "server-identity/host-key[name='%s']/public-key", endpt_name, hostkey_name) == -1) {
roman9d5e5a52023-07-14 12:43:44 +0200111 ERRMEM;
112 path = NULL;
113 ret = 1;
114 goto cleanup;
115 }
116
117 ret = _nc_server_config_new_ssh_hostkey(ctx, path, privkey_path, pubkey_path, config);
118 if (ret) {
119 ERR(NULL, "Creating new hostkey YANG data nodes failed.");
120 goto cleanup;
121 }
122
123cleanup:
124 free(path);
125 return ret;
126}
127
128API int
129nc_server_config_new_ch_ssh_hostkey(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name,
130 const char *hostkey_name, const char *privkey_path, const char *pubkey_path, struct lyd_node **config)
131{
132 int ret = 0;
133 char *path = NULL;
134
135 NC_CHECK_ARG_RET(NULL, ctx, client_name, endpt_name, hostkey_name, privkey_path, 1);
136 NC_CHECK_ARG_RET(NULL, config, 1);
137
138 if (asprintf(&path, "/ietf-netconf-server:netconf-server/call-home/"
139 "netconf-client[name='%s']/endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/server-identity/"
Roytakfa9068e2023-07-27 12:56:01 +0200140 "host-key[name='%s']/public-key", client_name, endpt_name, hostkey_name) == -1) {
roman9d5e5a52023-07-14 12:43:44 +0200141 ERRMEM;
142 path = NULL;
143 ret = 1;
144 goto cleanup;
145 }
146
147 ret = _nc_server_config_new_ssh_hostkey(ctx, path, privkey_path, pubkey_path, config);
148 if (ret) {
149 ERR(NULL, "Creating new Call-Home hostkey YANG data nodes failed.");
150 goto cleanup;
151 }
152
153cleanup:
154 free(path);
155 return ret;
156}
157
158API int
roman8ba6efa2023-07-12 15:27:52 +0200159nc_server_config_new_ssh_del_hostkey(const struct ly_ctx *ctx, const char *endpt_name, const char *hostkey_name,
160 struct lyd_node **config)
161{
162 NC_CHECK_ARG_RET(NULL, ctx, endpt_name, config, 1);
163
164 if (hostkey_name) {
165 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/ssh-server-parameters/"
166 "server-identity/host-key[name='%s']", endpt_name, hostkey_name);
167 } else {
168 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/ssh-server-parameters/"
169 "server-identity/host-key", endpt_name);
170 }
171}
172
roman9d5e5a52023-07-14 12:43:44 +0200173API int
174nc_server_config_new_ch_ssh_del_hostkey(const char *client_name, const char *endpt_name,
175 const char *hostkey_name, struct lyd_node **config)
176{
177 NC_CHECK_ARG_RET(NULL, client_name, endpt_name, config, 1);
178
179 if (hostkey_name) {
180 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/call-home/"
181 "netconf-client[name='%s']/endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/server-identity/"
182 "host-key[name='%s']", client_name, endpt_name, hostkey_name);
183 } else {
184 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/call-home/"
185 "netconf-client[name='%s']/endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/server-identity/"
186 "host-key", client_name, endpt_name);
187 }
188}
189
roman68404fd2023-07-24 10:40:59 +0200190API int
roman68404fd2023-07-24 10:40:59 +0200191nc_server_config_new_ssh_keystore_reference(const struct ly_ctx *ctx, const char *endpt_name, const char *hostkey_name,
192 const char *keystore_reference, struct lyd_node **config)
193{
Roytakfa9068e2023-07-27 12:56:01 +0200194 int ret = 0;
195
roman68404fd2023-07-24 10:40:59 +0200196 NC_CHECK_ARG_RET(NULL, ctx, endpt_name, hostkey_name, keystore_reference, config, 1);
197
Roytakfa9068e2023-07-27 12:56:01 +0200198 ret = nc_config_new_create(ctx, config, keystore_reference, "/ietf-netconf-server:netconf-server/listen/"
roman68404fd2023-07-24 10:40:59 +0200199 "endpoint[name='%s']/ssh/ssh-server-parameters/server-identity/host-key[name='%s']/public-key/"
200 "keystore-reference", endpt_name, hostkey_name);
Roytakfa9068e2023-07-27 12:56:01 +0200201 if (ret) {
202 goto cleanup;
203 }
204
205 /* delete inline definition nodes if present */
206 ret = nc_config_new_check_delete(config, "/ietf-netconf-server:netconf-server/listen/"
207 "endpoint[name='%s']/ssh/ssh-server-parameters/server-identity/host-key[name='%s']/public-key/"
208 "inline-definition", endpt_name, hostkey_name);
209 if (ret) {
210 goto cleanup;
211 }
212
213cleanup:
214 return ret;
215}
216
217API int
218nc_server_config_new_ch_ssh_keystore_reference(const struct ly_ctx *ctx, const char *client_name,
219 const char *endpt_name, const char *hostkey_name, const char *keystore_reference, struct lyd_node **config)
220{
221 int ret = 0;
222
223 NC_CHECK_ARG_RET(NULL, ctx, client_name, endpt_name, hostkey_name, keystore_reference, 1);
224 NC_CHECK_ARG_RET(NULL, config, 1);
225
226 ret = nc_config_new_create(ctx, config, keystore_reference, "/ietf-netconf-server:netconf-server/call-home/"
227 "netconf-client[name='%s']/endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/server-identity/"
228 "host-key[name='%s']/public-key/keystore-reference", client_name, endpt_name, hostkey_name);
229 if (ret) {
230 goto cleanup;
231 }
232
233 /* delete inline definition nodes if present */
234 ret = nc_config_new_check_delete(config, "/ietf-netconf-server:netconf-server/call-home/"
235 "netconf-client[name='%s']/endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/server-identity/"
236 "host-key[name='%s']/public-key/inline-definition", client_name, endpt_name, hostkey_name);
237 if (ret) {
238 goto cleanup;
239 }
240
241cleanup:
242 return ret;
roman68404fd2023-07-24 10:40:59 +0200243}
244
245API int
246nc_server_config_new_ssh_del_keystore_reference(const char *endpt_name, const char *hostkey_name,
247 struct lyd_node **config)
248{
249 NC_CHECK_ARG_RET(NULL, endpt_name, config, 1);
250
251 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/listen/"
252 "endpoint[name='%s']/ssh/ssh-server-parameters/server-identity/host-key[name='%s']/public-key/"
253 "keystore-reference", endpt_name, hostkey_name);
254}
255
256API int
Roytakfa9068e2023-07-27 12:56:01 +0200257nc_server_config_new_ch_ssh_del_keystore_reference(const char *client_name, const char *endpt_name,
258 const char *hostkey_name, struct lyd_node **config)
259{
260 NC_CHECK_ARG_RET(NULL, client_name, endpt_name, hostkey_name, config, 1);
261
262 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/call-home/"
263 "netconf-client[name='%s']/endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/server-identity/"
264 "host-key[name='%s']/public-key/keystore-reference", client_name, endpt_name, hostkey_name);
265}
266
267API int
roman68404fd2023-07-24 10:40:59 +0200268nc_server_config_new_ssh_auth_attempts(const struct ly_ctx *ctx, const char *endpt_name, uint16_t auth_attempts,
269 struct lyd_node **config)
270{
271 int ret = 0;
272 char *attempts_buf = NULL;
273
274 NC_CHECK_ARG_RET(NULL, ctx, endpt_name, config, 1);
275
276 /* uint to str */
277 if (asprintf(&attempts_buf, "%u", auth_attempts) == -1) {
278 ERRMEM;
279 attempts_buf = NULL;
280 ret = 1;
281 goto cleanup;
282 }
283
284 ret = nc_config_new_create(ctx, config, attempts_buf, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/"
285 "ssh-server-parameters/client-authentication/libnetconf2-netconf-server:auth-attempts", endpt_name);
286
287cleanup:
288 free(attempts_buf);
289 return ret;
290}
291
292API int
293nc_server_config_new_ssh_auth_timeout(const struct ly_ctx *ctx, const char *endpt_name, uint16_t auth_timeout,
294 struct lyd_node **config)
295{
296 int ret = 0;
297 char *timeout_buf = NULL;
298
299 NC_CHECK_ARG_RET(NULL, ctx, endpt_name, config, 1);
300
301 /* uint to str */
302 if (asprintf(&timeout_buf, "%u", auth_timeout) == -1) {
303 ERRMEM;
304 timeout_buf = NULL;
305 ret = 1;
306 goto cleanup;
307 }
308
309 ret = nc_config_new_create(ctx, config, timeout_buf, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/"
310 "ssh-server-parameters/client-authentication/libnetconf2-netconf-server:auth-timeout", endpt_name);
311
312cleanup:
313 free(timeout_buf);
314 return ret;
315}
316
317API int
318nc_server_config_new_ch_ssh_auth_attempts(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name,
319 uint16_t auth_attempts, struct lyd_node **config)
320{
321 int ret = 0;
322 char *attempts_buf = NULL;
323
324 NC_CHECK_ARG_RET(NULL, ctx, client_name, endpt_name, config, 1);
325
326 /* uint to str */
327 if (asprintf(&attempts_buf, "%u", auth_attempts) == -1) {
328 ERRMEM;
329 attempts_buf = NULL;
330 ret = 1;
331 goto cleanup;
332 }
333
334 ret = nc_config_new_create(ctx, config, attempts_buf, "/ietf-netconf-server:netconf-server/call-home/"
335 "netconf-client[name='%s']/endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/"
336 "libnetconf2-netconf-server:auth-attempts", client_name, endpt_name);
337
338cleanup:
339 free(attempts_buf);
340 return ret;
341}
342
343API int
344nc_server_config_new_ch_ssh_auth_timeout(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name,
345 uint16_t auth_timeout, struct lyd_node **config)
346{
347 int ret = 0;
348 char *timeout_buf = NULL;
349
350 NC_CHECK_ARG_RET(NULL, ctx, client_name, endpt_name, config, 1);
351
352 /* uint to str */
353 if (asprintf(&timeout_buf, "%u", auth_timeout) == -1) {
354 ERRMEM;
355 timeout_buf = NULL;
356 ret = 1;
357 goto cleanup;
358 }
359
360 ret = nc_config_new_create(ctx, config, timeout_buf, "/ietf-netconf-server:netconf-server/call-home/"
361 "netconf-client[name='%s']/endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/"
362 "libnetconf2-netconf-server:auth-timeout", client_name, endpt_name);
363
364cleanup:
365 free(timeout_buf);
366 return ret;
367}
368
369static int
370_nc_server_config_new_ssh_user_pubkey(const struct ly_ctx *ctx, const char *tree_path, const char *pubkey_path,
371 struct lyd_node **config)
372{
373 int ret = 0;
374 char *pubkey = NULL;
375 NC_PUBKEY_FORMAT pubkey_type;
376 const char *pubkey_format;
377
378 /* get pubkey data */
379 ret = nc_server_config_new_get_pubkey(pubkey_path, &pubkey, &pubkey_type);
380 if (ret) {
381 goto cleanup;
382 }
383
384 /* get pubkey format */
385 if (pubkey_type == NC_PUBKEY_FORMAT_SSH2) {
386 pubkey_format = "ietf-crypto-types:ssh-public-key-format";
387 } else {
388 pubkey_format = "ietf-crypto-types:subject-public-key-info-format";
389 }
390
391 ret = nc_config_new_create_append(ctx, tree_path, "public-key-format", pubkey_format, config);
392 if (ret) {
393 goto cleanup;
394 }
395
396 ret = nc_config_new_create_append(ctx, tree_path, "public-key", pubkey, config);
397 if (ret) {
398 goto cleanup;
399 }
400
401cleanup:
402 free(pubkey);
403 return ret;
404}
405
406API int
407nc_server_config_new_ssh_user_pubkey(const struct ly_ctx *ctx, const char *endpt_name,
408 const char *user_name, const char *pubkey_name, const char *pubkey_path, struct lyd_node **config)
409{
410 int ret = 0;
411 char *path = NULL;
412
413 NC_CHECK_ARG_RET(NULL, ctx, endpt_name, user_name, pubkey_name, pubkey_path, 1);
414 NC_CHECK_ARG_RET(NULL, config, 1);
415
416 if (asprintf(&path, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/"
417 "ssh-server-parameters/client-authentication/users/user[name='%s']/public-keys/inline-definition/"
418 "public-key[name='%s']", endpt_name, user_name, pubkey_name) == -1) {
419 ERRMEM;
420 path = NULL;
421 ret = 1;
422 goto cleanup;
423 }
424
425 ret = _nc_server_config_new_ssh_user_pubkey(ctx, path, pubkey_path, config);
426 if (ret) {
427 ERR(NULL, "Creating new user's public key failed.");
428 goto cleanup;
429 }
430
Roytakfa9068e2023-07-27 12:56:01 +0200431 /* delete truststore reference if present */
432 ret = nc_config_new_check_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/"
433 "ssh-server-parameters/client-authentication/users/user[name='%s']/public-keys/truststore-reference",
434 endpt_name, user_name);
435 if (ret) {
436 goto cleanup;
437 }
438
roman68404fd2023-07-24 10:40:59 +0200439cleanup:
440 free(path);
441 return ret;
442}
443
444API int
445nc_server_config_new_ch_ssh_user_pubkey(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name,
446 const char *user_name, const char *pubkey_name, const char *pubkey_path, struct lyd_node **config)
447{
448 int ret = 0;
449 char *path = NULL;
450
451 NC_CHECK_ARG_RET(NULL, ctx, client_name, endpt_name, user_name, pubkey_name, 1);
452 NC_CHECK_ARG_RET(NULL, pubkey_path, config, 1);
453
454 if (asprintf(&path, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/endpoints/"
455 "endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/"
456 "users/user[name='%s']/public-keys/inline-definition/public-key[name='%s']", client_name,
457 endpt_name, user_name, pubkey_name) == -1) {
458 ERRMEM;
459 path = NULL;
460 ret = 1;
461 goto cleanup;
462 }
463
464 ret = _nc_server_config_new_ssh_user_pubkey(ctx, path, pubkey_path, config);
465 if (ret) {
466 ERR(NULL, "Creating new user's public key failed.");
467 goto cleanup;
468 }
469
Roytakfa9068e2023-07-27 12:56:01 +0200470 /* delete truststore reference if present */
471 ret = nc_config_new_check_delete(config, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/"
472 "endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/users/user[name='%s']/"
473 "public-keys/truststore-reference", client_name, endpt_name, user_name);
474 if (ret) {
475 goto cleanup;
476 }
477
roman68404fd2023-07-24 10:40:59 +0200478cleanup:
479 free(path);
480 return ret;
481}
482
483API int
484nc_server_config_new_ssh_del_user_pubkey(const char *endpt_name, const char *user_name,
485 const char *pubkey_name, struct lyd_node **config)
486{
487 NC_CHECK_ARG_RET(NULL, endpt_name, user_name, config, 1);
488
489 if (pubkey_name) {
490 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/"
491 "ssh-server-parameters/client-authentication/users/user[name='%s']/public-keys/inline-definition/"
492 "public-key[name='%s']", endpt_name, user_name, pubkey_name);
493 } else {
494 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/"
495 "ssh-server-parameters/client-authentication/users/user[name='%s']/public-keys/inline-definition/"
496 "public-key", endpt_name, user_name);
497 }
498}
499
500API int
501nc_server_config_new_ch_ssh_del_user_pubkey(const char *client_name, const char *endpt_name,
502 const char *user_name, const char *pubkey_name, struct lyd_node **config)
503{
504 NC_CHECK_ARG_RET(NULL, client_name, endpt_name, user_name, config, 1);
505
506 if (pubkey_name) {
507 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/call-home/"
508 "netconf-client[name='%s']/endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/"
509 "users/user[name='%s']/public-keys/inline-definition/public-key[name='%s']", client_name,
510 endpt_name, user_name, pubkey_name);
511 } else {
512 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/call-home/"
513 "netconf-client[name='%s']/endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/"
514 "users/user[name='%s']/public-keys/inline-definition/public-key", client_name,
515 endpt_name, user_name);
516 }
517}
518
519static int
520_nc_server_config_new_ssh_user_password(const struct ly_ctx *ctx, const char *tree_path,
521 const char *password, struct lyd_node **config)
522{
523 int ret = 0;
524 char *hashed_pw = NULL;
525 const char *salt = "$6$idsizuippipk$";
526
527#ifdef HAVE_CRYPT_R
528 struct crypt_data cdata;
529#endif
530
531#ifdef HAVE_CRYPT_R
532 cdata.initialized = 0;
533 hashed_pw = crypt_r(password, salt, &data);
534#else
535 pthread_mutex_lock(&crypt_lock);
536 hashed_pw = crypt(password, salt);
537 pthread_mutex_unlock(&crypt_lock);
538#endif
539
540 if (!hashed_pw) {
541 ERR(NULL, "Hashing password failed.");
542 ret = 1;
543 goto cleanup;
544 }
545
546 ret = nc_config_new_create_append(ctx, tree_path, "password", hashed_pw, config);
547 if (ret) {
548 goto cleanup;
549 }
550
551cleanup:
552 return ret;
553}
554
555API int
556nc_server_config_new_ssh_user_password(const struct ly_ctx *ctx, const char *endpt_name,
557 const char *user_name, const char *password, struct lyd_node **config)
558{
559 int ret = 0;
560 char *path = NULL;
561
562 NC_CHECK_ARG_RET(NULL, ctx, endpt_name, user_name, password, config, 1);
563
564 if (asprintf(&path, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/ssh-server-parameters/"
565 "client-authentication/users/user[name='%s']", endpt_name, user_name) == -1) {
566 ERRMEM;
567 path = NULL;
568 ret = 1;
569 goto cleanup;
570 }
571
572 ret = _nc_server_config_new_ssh_user_password(ctx, path, password, config);
573 if (ret) {
574 ERR(NULL, "Creating new user's public key failed.");
575 goto cleanup;
576 }
577
578cleanup:
579 free(path);
580 return ret;
581}
582
583API int
584nc_server_config_new_ch_ssh_user_password(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name,
585 const char *user_name, const char *password, struct lyd_node **config)
586{
587 int ret = 0;
588 char *path = NULL;
589
590 NC_CHECK_ARG_RET(NULL, ctx, client_name, endpt_name, user_name, password, 1);
591 NC_CHECK_ARG_RET(NULL, config, 1);
592
593 if (asprintf(&path, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/endpoints/"
594 "endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/"
595 "users/user[name='%s']", client_name, endpt_name, user_name) == -1) {
596 ERRMEM;
597 path = NULL;
598 ret = 1;
599 goto cleanup;
600 }
601
602 ret = _nc_server_config_new_ssh_user_password(ctx, path, password, config);
603 if (ret) {
604 ERR(NULL, "Creating new user's password failed.");
605 goto cleanup;
606 }
607
608cleanup:
609 free(path);
610 return ret;
611}
612
613API int
614nc_server_config_new_ssh_del_user_password(const char *endpt_name, const char *user_name, struct lyd_node **config)
615{
616 NC_CHECK_ARG_RET(NULL, endpt_name, user_name, config, 1);
617
618 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/"
619 "ssh-server-parameters/client-authentication/users/user[name='%s']/password", endpt_name, user_name);
620}
621
622API int
623nc_server_config_new_ch_ssh_del_user_password(const char *client_name, const char *endpt_name,
624 const char *user_name, struct lyd_node **config)
625{
626 NC_CHECK_ARG_RET(NULL, client_name, endpt_name, user_name, config, 1);
627
628 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/call-home/"
629 "netconf-client[name='%s']/endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/"
630 "users/user[name='%s']/password", client_name, endpt_name, user_name);
631}
632
633API int
634nc_server_config_new_ssh_user_none(const struct ly_ctx *ctx, const char *endpt_name,
635 const char *user_name, struct lyd_node **config)
636{
637 NC_CHECK_ARG_RET(NULL, ctx, endpt_name, user_name, config, 1);
638
639 return nc_config_new_create(ctx, config, NULL, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/"
640 "users/user[name='%s']/none", endpt_name, user_name);
641}
642
643API int
644nc_server_config_new_ch_ssh_user_none(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name,
645 const char *user_name, struct lyd_node **config)
646{
647 NC_CHECK_ARG_RET(NULL, ctx, client_name, endpt_name, user_name, config, 1);
648
649 return nc_config_new_create(ctx, config, NULL, "/ietf-netconf-server:netconf-server/call-home/"
650 "netconf-client[name='%s']/endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/"
651 "users/user[name='%s']/none", client_name, endpt_name, user_name);
652}
653
654API int
655nc_server_config_new_ssh_del_user_none(const char *endpt_name, const char *user_name, struct lyd_node **config)
656{
657 NC_CHECK_ARG_RET(NULL, endpt_name, user_name, config, 1);
658
659 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/"
660 "ssh-server-parameters/client-authentication/users/user[name='%s']/none", endpt_name, user_name);
661}
662
663API int
664nc_server_config_new_ch_ssh_del_user_none(const char *client_name, const char *endpt_name,
665 const char *user_name, struct lyd_node **config)
666{
667 NC_CHECK_ARG_RET(NULL, client_name, endpt_name, user_name, config, 1);
668
669 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/call-home/"
670 "netconf-client[name='%s']/endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/"
671 "users/user[name='%s']/none", client_name, endpt_name, user_name);
672}
673
674static int
675_nc_server_config_new_ssh_user_interactive(const struct ly_ctx *ctx, const char *tree_path,
676 const char *pam_config_name, const char *pam_config_dir, struct lyd_node **config)
677{
678 int ret = 0;
679
680 ret = nc_config_new_create_append(ctx, tree_path, "pam-config-file-name", pam_config_name, config);
681 if (ret) {
682 goto cleanup;
683 }
684
685 if (pam_config_dir) {
686 ret = nc_config_new_create_append(ctx, tree_path, "pam-config-file-dir", pam_config_dir, config);
687 if (ret) {
688 goto cleanup;
689 }
690 }
691
692cleanup:
693 return ret;
694}
695
696API int
697nc_server_config_new_ssh_user_interactive(const struct ly_ctx *ctx, const char *endpt_name,
698 const char *user_name, const char *pam_config_name, const char *pam_config_dir, struct lyd_node **config)
699{
700 int ret = 0;
701 char *path = NULL;
702
703 NC_CHECK_ARG_RET(NULL, ctx, endpt_name, user_name, pam_config_name, config, 1);
704
705 if (asprintf(&path, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/ssh-server-parameters/"
706 "client-authentication/users/user[name='%s']/"
707 "libnetconf2-netconf-server:keyboard-interactive", endpt_name, user_name) == -1) {
708 ERRMEM;
709 path = NULL;
710 ret = 1;
711 goto cleanup;
712 }
713
714 ret = _nc_server_config_new_ssh_user_interactive(ctx, path, pam_config_name, pam_config_dir, config);
715 if (ret) {
716 ERR(NULL, "Creating new user's keyboard interactive nodes failed.");
717 goto cleanup;
718 }
719
720cleanup:
721 free(path);
722 return ret;
723}
724
725API int
726nc_server_config_new_ch_ssh_user_interactive(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name,
727 const char *user_name, const char *pam_config_name, const char *pam_config_dir, struct lyd_node **config)
728{
729 int ret = 0;
730 char *path = NULL;
731
732 NC_CHECK_ARG_RET(NULL, ctx, client_name, endpt_name, user_name, pam_config_name, 1);
733 NC_CHECK_ARG_RET(NULL, config, 1);
734
735 if (asprintf(&path, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/endpoints/"
736 "endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/users/user[name='%s']/"
737 "libnetconf2-netconf-server:keyboard-interactive", client_name, endpt_name, user_name) == -1) {
738 ERRMEM;
739 path = NULL;
740 ret = 1;
741 goto cleanup;
742 }
743
744 ret = _nc_server_config_new_ssh_user_interactive(ctx, path, pam_config_name, pam_config_dir, config);
745 if (ret) {
746 ERR(NULL, "Creating new user's keyboard interactive nodes failed.");
747 goto cleanup;
748 }
749
750cleanup:
751 free(path);
752 return ret;
753}
754
755API int
756nc_server_config_new_ssh_del_user_interactive(const char *endpt_name, const char *user_name, struct lyd_node **config)
757{
758 NC_CHECK_ARG_RET(NULL, endpt_name, user_name, config, 1);
759
760 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/"
761 "ssh-server-parameters/client-authentication/users/user[name='%s']/"
762 "libnetconf2-netconf-server:keyboard-interactive", endpt_name, user_name);
763}
764
765API int
766nc_server_config_new_ch_ssh_del_user_interactive(const char *client_name, const char *endpt_name,
767 const char *user_name, struct lyd_node **config)
768{
769 NC_CHECK_ARG_RET(NULL, client_name, endpt_name, user_name, config, 1);
770
771 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/endpoints/"
772 "endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/users/user[name='%s']/"
773 "libnetconf2-netconf-server:keyboard-interactive", client_name, endpt_name, user_name);
774}
775
776API int
777nc_server_config_new_ssh_del_user(const char *endpt_name,
778 const char *user_name, struct lyd_node **config)
779{
780 NC_CHECK_ARG_RET(NULL, endpt_name, config, 1);
781
782 if (user_name) {
783 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/"
784 "ssh-server-parameters/client-authentication/users/user[name='%s']", endpt_name, user_name);
785 } else {
786 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/"
787 "ssh-server-parameters/client-authentication/users/user", endpt_name);
788 }
789}
790
791API int
792nc_server_config_new_ch_ssh_del_user(const char *client_name, const char *endpt_name,
793 const char *user_name, struct lyd_node **config)
794{
795 NC_CHECK_ARG_RET(NULL, client_name, endpt_name, config, 1);
796
797 if (user_name) {
798 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/endpoints/"
799 "endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/users/user[name='%s']", client_name,
800 endpt_name, user_name);
801 } else {
802 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/endpoints/"
803 "endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/users/user", client_name, endpt_name);
804 }
805}
806
807API int
808nc_config_new_ssh_endpoint_user_reference(const struct ly_ctx *ctx, const char *endpt_name,
809 const char *referenced_endpt, struct lyd_node **config)
810{
811 NC_CHECK_ARG_RET(NULL, ctx, endpt_name, referenced_endpt, config, 1);
812
813 return nc_config_new_create(ctx, config, referenced_endpt, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/ssh-server-parameters/"
814 "client-authentication/libnetconf2-netconf-server:endpoint-client-auth", endpt_name);
815}
816
817API int
818nc_config_new_ssh_del_endpoint_user_reference(const char *endpt_name, struct lyd_node **config)
819{
820 NC_CHECK_ARG_RET(NULL, endpt_name, config, 1);
821
822 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/ssh-server-parameters/"
823 "client-authentication/libnetconf2-netconf-server:endpoint-client-auth", endpt_name);
824}
825
826API int
827nc_server_config_new_ssh_truststore_reference(const struct ly_ctx *ctx, const char *endpt_name, const char *user_name,
828 const char *truststore_reference, struct lyd_node **config)
829{
Roytakfa9068e2023-07-27 12:56:01 +0200830 int ret = 0;
831
roman68404fd2023-07-24 10:40:59 +0200832 NC_CHECK_ARG_RET(NULL, ctx, endpt_name, user_name, truststore_reference, config, 1);
833
Roytakfa9068e2023-07-27 12:56:01 +0200834 ret = nc_config_new_create(ctx, config, truststore_reference, "/ietf-netconf-server:netconf-server/listen/"
roman68404fd2023-07-24 10:40:59 +0200835 "endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/users/user[name='%s']/public-keys/"
836 "truststore-reference", endpt_name, user_name);
Roytakfa9068e2023-07-27 12:56:01 +0200837 if (ret) {
838 goto cleanup;
839 }
840
841 /* delete inline definition nodes if present */
842 ret = nc_config_new_check_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/"
843 "ssh-server-parameters/client-authentication/users/user[name='%s']/public-keys/inline-definition",
844 endpt_name, user_name);
845 if (ret) {
846 goto cleanup;
847 }
848
849cleanup:
850 return ret;
roman68404fd2023-07-24 10:40:59 +0200851}
852
853API int
854nc_server_config_new_ch_ssh_truststore_reference(const struct ly_ctx *ctx, const char *client_name,
855 const char *endpt_name, const char *user_name, const char *truststore_reference, struct lyd_node **config)
856{
Roytakfa9068e2023-07-27 12:56:01 +0200857 int ret = 0;
858
roman68404fd2023-07-24 10:40:59 +0200859 NC_CHECK_ARG_RET(NULL, ctx, client_name, endpt_name, user_name, truststore_reference, 1);
860 NC_CHECK_ARG_RET(NULL, config, 1);
861
Roytakfa9068e2023-07-27 12:56:01 +0200862 ret = nc_config_new_create(ctx, config, truststore_reference, "/ietf-netconf-server:netconf-server/call-home/"
roman68404fd2023-07-24 10:40:59 +0200863 "netconf-client[name='%s']/endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/"
864 "users/user[name='%s']/public-keys/truststore-reference", client_name, endpt_name, user_name);
Roytakfa9068e2023-07-27 12:56:01 +0200865 if (ret) {
866 goto cleanup;
867 }
868
869 /* delete inline definition nodes if present */
870 ret = nc_config_new_check_delete(config, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/"
871 "endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/users/user[name='%s']/"
872 "public-keys/inline-definition", client_name, endpt_name, user_name);
873 if (ret) {
874 goto cleanup;
875 }
876
877cleanup:
878 return ret;
roman68404fd2023-07-24 10:40:59 +0200879}
880
881API int
882nc_server_config_new_ssh_del_truststore_reference(const char *endpt_name, const char *user_name,
883 struct lyd_node **config)
884{
885 NC_CHECK_ARG_RET(NULL, endpt_name, user_name, config, 1);
886
887 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/listen/"
888 "endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/users/user[name='%s']/public-keys/"
889 "truststore-reference", endpt_name, user_name);
890}
891
892API int
893nc_server_config_new_ch_ssh_del_truststore_reference(const char *client_name, const char *endpt_name,
894 const char *user_name, struct lyd_node **config)
895{
896 NC_CHECK_ARG_RET(NULL, client_name, endpt_name, user_name, config, 1);
897
898 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/call-home/"
899 "netconf-client[name='%s']/endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/"
900 "users/user[name='%s']/public-keys/truststore-reference", client_name, endpt_name, user_name);
901}
902
roman27215242023-03-10 14:55:00 +0100903static int
roman9d5e5a52023-07-14 12:43:44 +0200904nc_server_config_new_ssh_transport_params_prep(const struct ly_ctx *ctx, const char *client_name,
905 const char *endpt_name, struct lyd_node *config, struct lyd_node **new_tree, struct lyd_node **alg_tree)
roman27215242023-03-10 14:55:00 +0100906{
907 int ret = 0;
908 char *tree_path = NULL;
909
910 /* prepare path */
roman9d5e5a52023-07-14 12:43:44 +0200911 if (client_name) {
912 /* ch */
913 asprintf(&tree_path, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/endpoints/"
914 "endpoint[name='%s']/ssh/ssh-server-parameters/transport-params", client_name, endpt_name);
915 } else {
916 /* listen */
917 asprintf(&tree_path, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/"
918 "ssh/ssh-server-parameters/transport-params", endpt_name);
919 }
roman27215242023-03-10 14:55:00 +0100920 if (!tree_path) {
921 ERRMEM;
922 ret = 1;
923 goto cleanup;
924 }
925
926 /* create all the nodes in the path */
927 ret = lyd_new_path2(config, ctx, tree_path, NULL, 0, 0, LYD_NEW_PATH_UPDATE, new_tree, alg_tree);
928 if (ret) {
929 ERR(NULL, "Creating new path to transport-params failed.");
930 goto cleanup;
931 }
932
roman4f9bb442023-03-24 09:05:37 +0100933 if (!*alg_tree) {
934 /* no new nodes added */
935 ret = lyd_find_path(config, tree_path, 0, alg_tree);
936 if (ret) {
937 goto cleanup;
938 }
939 }
940
roman27215242023-03-10 14:55:00 +0100941cleanup:
942 free(tree_path);
943 return ret;
944}
945
946static int
roman9d5e5a52023-07-14 12:43:44 +0200947nc_server_config_new_ssh_transport_params_create(const struct ly_ctx *ctx, NC_ALG_TYPE alg_type, int alg_count, va_list ap,
roman27215242023-03-10 14:55:00 +0100948 struct lyd_node *tree)
949{
950 int i, ret = 0;
951 char *alg, *alg_ident;
952 const char *module, *alg_path, *old_path;
953 struct lyd_node *old = NULL;
954
955 /* get the correct module with the indentity base and the path in the ietf-netconf-server module */
956 switch (alg_type) {
957 case NC_ALG_HOSTKEY:
958 module = "iana-ssh-public-key-algs";
959 alg_path = "host-key/host-key-alg";
960 old_path = "host-key";
961 break;
962 case NC_ALG_KEY_EXCHANGE:
963 module = "iana-ssh-key-exchange-algs";
964 alg_path = "key-exchange/key-exchange-alg";
965 old_path = "key-exchange";
966 break;
967 case NC_ALG_ENCRYPTION:
968 module = "iana-ssh-encryption-algs";
969 alg_path = "encryption/encryption-alg";
970 old_path = "encryption";
971 break;
972 case NC_ALG_MAC:
973 module = "iana-ssh-mac-algs";
974 alg_path = "mac/mac-alg";
975 old_path = "mac";
976 break;
977 default:
978 ret = 1;
979 ERR(NULL, "Unknown algorithm type.");
980 goto cleanup;
981 }
982
983 /* delete all older algorithms (if any) se they can be replaced by the new ones */
984 lyd_find_path(tree, old_path, 0, &old);
985 if (old) {
986 lyd_free_tree(old);
987 }
988
989 for (i = 0; i < alg_count; i++) {
990 alg = va_arg(ap, char *);
991
992 asprintf(&alg_ident, "%s:%s", module, alg);
993 if (!alg_ident) {
994 ERRMEM;
995 ret = 1;
996 goto cleanup;
997 }
998
999 /* create the leaf list */
1000 ret = lyd_new_path(tree, ctx, alg_path, alg_ident, 0, NULL);
1001 if (ret) {
1002 ERR(NULL, "Creating new algorithm leaf-list failed.");
1003 goto cleanup;
1004 }
1005
1006 free(alg_ident);
1007 }
1008
1009cleanup:
roman27215242023-03-10 14:55:00 +01001010 return ret;
1011}
1012
roman9d5e5a52023-07-14 12:43:44 +02001013static int
1014nc_server_config_new_ssh_transport_params(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name,
1015 NC_ALG_TYPE alg_type, int alg_count, va_list ap, struct lyd_node **config)
roman27215242023-03-10 14:55:00 +01001016{
1017 int ret = 0;
1018 struct lyd_node *new_tree, *alg_tree;
roman27215242023-03-10 14:55:00 +01001019
roman9d5e5a52023-07-14 12:43:44 +02001020 ret = nc_server_config_new_ssh_transport_params_prep(ctx, client_name, endpt_name, *config, &new_tree, &alg_tree);
roman27215242023-03-10 14:55:00 +01001021 if (ret) {
1022 goto cleanup;
1023 }
1024
1025 if (!*config) {
1026 *config = new_tree;
1027 }
1028
roman9d5e5a52023-07-14 12:43:44 +02001029 ret = nc_server_config_new_ssh_transport_params_create(ctx, alg_type, alg_count, ap, alg_tree);
roman27215242023-03-10 14:55:00 +01001030 if (ret) {
1031 goto cleanup;
1032 }
1033
roman4f9bb442023-03-24 09:05:37 +01001034 /* Add all default nodes */
1035 ret = lyd_new_implicit_tree(*config, LYD_IMPLICIT_NO_STATE, NULL);
1036 if (ret) {
1037 goto cleanup;
1038 }
roman27215242023-03-10 14:55:00 +01001039cleanup:
1040 return ret;
1041}
1042
1043API int
roman9d5e5a52023-07-14 12:43:44 +02001044nc_server_config_new_ssh_host_key_algs(const struct ly_ctx *ctx, const char *endpt_name, struct lyd_node **config,
1045 int alg_count, ...)
1046{
1047 int ret = 0;
1048 va_list ap;
1049
1050 NC_CHECK_ARG_RET(NULL, ctx, endpt_name, config, alg_count, 1);
1051
1052 va_start(ap, alg_count);
1053
1054 ret = nc_server_config_new_ssh_transport_params(ctx, NULL, endpt_name, NC_ALG_HOSTKEY, alg_count, ap, config);
1055 if (ret) {
1056 ERR(NULL, "Creating new hostkey algorithms failed.");
1057 goto cleanup;
1058 }
1059
1060cleanup:
1061 va_end(ap);
1062 return ret;
1063}
1064
1065API int
1066nc_server_config_new_ch_ssh_host_key_algs(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name,
1067 struct lyd_node **config, int alg_count, ...)
1068{
1069 int ret = 0;
1070 va_list ap;
1071
1072 NC_CHECK_ARG_RET(NULL, ctx, client_name, endpt_name, config, alg_count, 1);
1073
1074 va_start(ap, alg_count);
1075
1076 ret = nc_server_config_new_ssh_transport_params(ctx, client_name, endpt_name, NC_ALG_HOSTKEY, alg_count, ap, config);
1077 if (ret) {
1078 ERR(NULL, "Creating new hostkey algorithms failed.");
1079 goto cleanup;
1080 }
1081
1082cleanup:
1083 va_end(ap);
1084 return ret;
1085}
1086
1087API int
roman8ba6efa2023-07-12 15:27:52 +02001088nc_server_config_new_ssh_del_host_key_alg(const char *endpt_name, const char *alg, struct lyd_node **config)
1089{
1090 NC_CHECK_ARG_RET(NULL, endpt_name, config, 1);
1091
1092 if (alg) {
1093 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/"
1094 "ssh/ssh-server-parameters/transport-params/host-key/"
1095 "host-key-alg[.='iana-ssh-public-key-algs:%s']", endpt_name, alg);
1096 } else {
1097 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/"
1098 "ssh/ssh-server-parameters/transport-params/host-key", endpt_name);
1099 }
1100}
1101
1102API int
roman9d5e5a52023-07-14 12:43:44 +02001103nc_server_config_new_ch_ssh_del_host_key_alg(const char *client_name, const char *endpt_name,
1104 const char *alg, struct lyd_node **config)
1105{
1106 NC_CHECK_ARG_RET(NULL, client_name, endpt_name, config, 1);
1107
1108 if (alg) {
1109 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/"
1110 "endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/transport-params/host-key/"
1111 "host-key-alg[.='iana-ssh-public-key-algs:%s']", client_name, endpt_name, alg);
1112 } else {
1113 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/"
1114 "endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/transport-params/host-key", client_name, endpt_name);
1115 }
1116}
1117
1118API int
1119nc_server_config_new_ssh_key_exchange_algs(const struct ly_ctx *ctx, const char *endpt_name, struct lyd_node **config,
roman27215242023-03-10 14:55:00 +01001120 int alg_count, ...)
1121{
1122 int ret = 0;
roman27215242023-03-10 14:55:00 +01001123 va_list ap;
1124
roman9d5e5a52023-07-14 12:43:44 +02001125 NC_CHECK_ARG_RET(NULL, ctx, endpt_name, config, alg_count, 1);
roman27215242023-03-10 14:55:00 +01001126
1127 va_start(ap, alg_count);
1128
roman9d5e5a52023-07-14 12:43:44 +02001129 ret = nc_server_config_new_ssh_transport_params(ctx, NULL, endpt_name, NC_ALG_KEY_EXCHANGE, alg_count, ap, config);
roman27215242023-03-10 14:55:00 +01001130 if (ret) {
roman9d5e5a52023-07-14 12:43:44 +02001131 ERR(NULL, "Creating new key exchange algorithms failed.");
roman27215242023-03-10 14:55:00 +01001132 goto cleanup;
1133 }
1134
roman9d5e5a52023-07-14 12:43:44 +02001135cleanup:
1136 va_end(ap);
1137 return ret;
1138}
1139
1140API int
1141nc_server_config_new_ch_ssh_key_exchange_algs(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name,
1142 struct lyd_node **config, int alg_count, ...)
1143{
1144 int ret = 0;
1145 va_list ap;
1146
1147 NC_CHECK_ARG_RET(NULL, ctx, client_name, endpt_name, config, alg_count, 1);
1148
1149 va_start(ap, alg_count);
1150
1151 ret = nc_server_config_new_ssh_transport_params(ctx, client_name, endpt_name, NC_ALG_KEY_EXCHANGE, alg_count, ap, config);
roman4f9bb442023-03-24 09:05:37 +01001152 if (ret) {
roman9d5e5a52023-07-14 12:43:44 +02001153 ERR(NULL, "Creating new key exchange algorithms failed.");
roman4f9bb442023-03-24 09:05:37 +01001154 goto cleanup;
1155 }
roman9d5e5a52023-07-14 12:43:44 +02001156
roman27215242023-03-10 14:55:00 +01001157cleanup:
roman9d5e5a52023-07-14 12:43:44 +02001158 va_end(ap);
roman27215242023-03-10 14:55:00 +01001159 return ret;
1160}
1161
1162API int
roman8ba6efa2023-07-12 15:27:52 +02001163nc_server_config_new_ssh_del_key_exchange_alg(const char *endpt_name, const char *alg, struct lyd_node **config)
1164{
1165 NC_CHECK_ARG_RET(NULL, endpt_name, config, 1);
1166
1167 if (alg) {
1168 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/"
1169 "ssh/ssh-server-parameters/transport-params/key-exchange/"
1170 "key-exchange-alg[.='iana-ssh-key-exchange-algs:%s']", endpt_name, alg);
1171 } else {
1172 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/"
1173 "ssh/ssh-server-parameters/transport-params/key-exchange", endpt_name);
1174 }
1175}
1176
1177API int
roman9d5e5a52023-07-14 12:43:44 +02001178nc_server_config_new_ch_ssh_del_key_exchange_alg(const char *client_name, const char *endpt_name,
1179 const char *alg, struct lyd_node **config)
1180{
1181 NC_CHECK_ARG_RET(NULL, client_name, endpt_name, config, 1);
1182
1183 if (alg) {
1184 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/"
1185 "endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/transport-params/key-exchange/"
1186 "key-exchange-alg[.='iana-ssh-key-exchange-algs:%s']", client_name, endpt_name, alg);
1187 } else {
1188 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/"
1189 "endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/transport-params/key-exchange", client_name, endpt_name);
1190 }
1191}
1192
1193API int
roman466719d2023-05-05 16:14:37 +02001194nc_server_config_new_ssh_encryption_algs(const struct ly_ctx *ctx, const char *endpt_name, struct lyd_node **config,
roman27215242023-03-10 14:55:00 +01001195 int alg_count, ...)
1196{
1197 int ret = 0;
roman27215242023-03-10 14:55:00 +01001198 va_list ap;
1199
roman9d5e5a52023-07-14 12:43:44 +02001200 NC_CHECK_ARG_RET(NULL, ctx, endpt_name, config, alg_count, 1);
roman27215242023-03-10 14:55:00 +01001201
1202 va_start(ap, alg_count);
1203
roman9d5e5a52023-07-14 12:43:44 +02001204 ret = nc_server_config_new_ssh_transport_params(ctx, NULL, endpt_name, NC_ALG_ENCRYPTION, alg_count, ap, config);
roman27215242023-03-10 14:55:00 +01001205 if (ret) {
roman9d5e5a52023-07-14 12:43:44 +02001206 ERR(NULL, "Creating new encryption algorithms failed.");
roman27215242023-03-10 14:55:00 +01001207 goto cleanup;
1208 }
1209
roman9d5e5a52023-07-14 12:43:44 +02001210cleanup:
1211 va_end(ap);
1212 return ret;
1213}
1214
1215API int
1216nc_server_config_new_ch_ssh_encryption_algs(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name,
1217 struct lyd_node **config, int alg_count, ...)
1218{
1219 int ret = 0;
1220 va_list ap;
1221
1222 NC_CHECK_ARG_RET(NULL, ctx, client_name, endpt_name, config, alg_count, 1);
1223
1224 va_start(ap, alg_count);
1225
1226 ret = nc_server_config_new_ssh_transport_params(ctx, client_name, endpt_name, NC_ALG_ENCRYPTION, alg_count, ap, config);
roman4f9bb442023-03-24 09:05:37 +01001227 if (ret) {
roman9d5e5a52023-07-14 12:43:44 +02001228 ERR(NULL, "Creating new encryption algorithms failed.");
roman4f9bb442023-03-24 09:05:37 +01001229 goto cleanup;
1230 }
roman9d5e5a52023-07-14 12:43:44 +02001231
roman27215242023-03-10 14:55:00 +01001232cleanup:
roman9d5e5a52023-07-14 12:43:44 +02001233 va_end(ap);
roman27215242023-03-10 14:55:00 +01001234 return ret;
1235}
1236
1237API int
roman8ba6efa2023-07-12 15:27:52 +02001238nc_server_config_new_ssh_del_encryption_alg(const char *endpt_name, const char *alg, struct lyd_node **config)
1239{
1240 NC_CHECK_ARG_RET(NULL, endpt_name, config, 1);
1241
1242 if (alg) {
1243 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/"
1244 "ssh/ssh-server-parameters/transport-params/encryption/"
1245 "encryption-alg[.='iana-ssh-encryption-algs:%s']", endpt_name, alg);
1246 } else {
1247 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/"
1248 "ssh/ssh-server-parameters/transport-params/encryption", endpt_name);
1249 }
1250}
1251
1252API int
roman9d5e5a52023-07-14 12:43:44 +02001253nc_server_config_new_ch_ssh_del_encryption_alg(const char *client_name, const char *endpt_name,
1254 const char *alg, struct lyd_node **config)
1255{
1256 NC_CHECK_ARG_RET(NULL, client_name, endpt_name, config, 1);
1257
1258 if (alg) {
1259 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/"
1260 "endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/transport-params/encryption/"
1261 "encryption-alg[.='iana-ssh-encryption-algs:%s']", client_name, endpt_name, alg);
1262 } else {
1263 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/"
1264 "endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/transport-params/encryption", client_name, endpt_name);
1265 }
1266}
1267
1268API int
roman27215242023-03-10 14:55:00 +01001269nc_server_config_ssh_new_mac_algs(const struct ly_ctx *ctx, const char *endpt_name, struct lyd_node **config,
1270 int alg_count, ...)
1271{
1272 int ret = 0;
roman27215242023-03-10 14:55:00 +01001273 va_list ap;
1274
roman9d5e5a52023-07-14 12:43:44 +02001275 NC_CHECK_ARG_RET(NULL, ctx, endpt_name, config, alg_count, 1);
roman27215242023-03-10 14:55:00 +01001276
1277 va_start(ap, alg_count);
1278
roman9d5e5a52023-07-14 12:43:44 +02001279 ret = nc_server_config_new_ssh_transport_params(ctx, NULL, endpt_name, NC_ALG_MAC, alg_count, ap, config);
roman27215242023-03-10 14:55:00 +01001280 if (ret) {
roman9d5e5a52023-07-14 12:43:44 +02001281 ERR(NULL, "Creating new mac algorithms failed.");
roman27215242023-03-10 14:55:00 +01001282 goto cleanup;
1283 }
1284
roman9d5e5a52023-07-14 12:43:44 +02001285cleanup:
1286 va_end(ap);
1287 return ret;
1288}
1289
1290API int
1291nc_server_config_new_ch_ssh_mac_algs(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name,
1292 struct lyd_node **config, int alg_count, ...)
1293{
1294 int ret = 0;
1295 va_list ap;
1296
1297 NC_CHECK_ARG_RET(NULL, ctx, client_name, endpt_name, config, alg_count, 1);
1298
1299 va_start(ap, alg_count);
1300
1301 ret = nc_server_config_new_ssh_transport_params(ctx, client_name, endpt_name, NC_ALG_MAC, alg_count, ap, config);
roman4f9bb442023-03-24 09:05:37 +01001302 if (ret) {
roman9d5e5a52023-07-14 12:43:44 +02001303 ERR(NULL, "Creating new mac algorithms failed.");
roman4f9bb442023-03-24 09:05:37 +01001304 goto cleanup;
1305 }
roman9d5e5a52023-07-14 12:43:44 +02001306
roman27215242023-03-10 14:55:00 +01001307cleanup:
roman9d5e5a52023-07-14 12:43:44 +02001308 va_end(ap);
roman27215242023-03-10 14:55:00 +01001309 return ret;
1310}
roman4f9bb442023-03-24 09:05:37 +01001311
roman4f9bb442023-03-24 09:05:37 +01001312API int
roman8ba6efa2023-07-12 15:27:52 +02001313nc_server_config_new_ssh_del_mac_alg(const char *endpt_name, const char *alg, struct lyd_node **config)
1314{
1315 NC_CHECK_ARG_RET(NULL, endpt_name, config, 1);
1316
1317 if (alg) {
1318 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/"
1319 "ssh/ssh-server-parameters/transport-params/mac/"
1320 "mac-alg[.='iana-ssh-mac-algs:%s']", endpt_name, alg);
1321 } else {
1322 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/"
1323 "ssh/ssh-server-parameters/transport-params/mac", endpt_name);
1324 }
1325}
1326
1327API int
roman9d5e5a52023-07-14 12:43:44 +02001328nc_server_config_new_ch_ssh_del_mac_alg(const char *client_name, const char *endpt_name,
1329 const char *alg, struct lyd_node **config)
1330{
1331 NC_CHECK_ARG_RET(NULL, client_name, endpt_name, config, 1);
1332
1333 if (alg) {
1334 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/"
1335 "endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/transport-params/mac/"
1336 "mac-alg[.='iana-ssh-mac-algs:%s']", client_name, endpt_name, alg);
1337 } else {
1338 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/"
1339 "endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/transport-params/mac", client_name, endpt_name);
1340 }
1341}