blob: d3c3d57e6f91bc92c7fe7522bb39d57bec980187 [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
roman9d5e5a52023-07-14 12:43:44 +020068 ret = nc_config_new_create_append(ctx, tree_path, "public-key-format", pubkey_format, config);
roman27215242023-03-10 14:55:00 +010069 if (ret) {
70 goto cleanup;
71 }
72
roman9d5e5a52023-07-14 12:43:44 +020073 ret = nc_config_new_create_append(ctx, tree_path, "public-key", pubkey, config);
roman27215242023-03-10 14:55:00 +010074 if (ret) {
75 goto cleanup;
76 }
77
roman9d5e5a52023-07-14 12:43:44 +020078 ret = nc_config_new_create_append(ctx, tree_path, "private-key-format", privkey_format, config);
roman3f9b65c2023-06-05 14:26:58 +020079 if (ret) {
80 goto cleanup;
81 }
82
roman9d5e5a52023-07-14 12:43:44 +020083 ret = nc_config_new_create_append(ctx, tree_path, "cleartext-private-key", privkey, config);
roman4f9bb442023-03-24 09:05:37 +010084 if (ret) {
85 goto cleanup;
86 }
87
roman27215242023-03-10 14:55:00 +010088cleanup:
roman466719d2023-05-05 16:14:37 +020089 free(privkey);
90 free(pubkey);
roman27215242023-03-10 14:55:00 +010091 return ret;
92}
93
roman8ba6efa2023-07-12 15:27:52 +020094API int
roman9d5e5a52023-07-14 12:43:44 +020095nc_server_config_new_ssh_hostkey(const struct ly_ctx *ctx, const char *endpt_name, const char *hostkey_name,
96 const char *privkey_path, const char *pubkey_path, struct lyd_node **config)
97{
98 int ret = 0;
99 char *path = NULL;
100
101 NC_CHECK_ARG_RET(NULL, ctx, endpt_name, hostkey_name, privkey_path, config, 1);
102
103 if (asprintf(&path, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/ssh-server-parameters/"
104 "server-identity/host-key[name='%s']/public-key/inline-definition", endpt_name, hostkey_name) == -1) {
105 ERRMEM;
106 path = NULL;
107 ret = 1;
108 goto cleanup;
109 }
110
111 ret = _nc_server_config_new_ssh_hostkey(ctx, path, privkey_path, pubkey_path, config);
112 if (ret) {
113 ERR(NULL, "Creating new hostkey YANG data nodes failed.");
114 goto cleanup;
115 }
116
117cleanup:
118 free(path);
119 return ret;
120}
121
122API int
123nc_server_config_new_ch_ssh_hostkey(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name,
124 const char *hostkey_name, const char *privkey_path, const char *pubkey_path, struct lyd_node **config)
125{
126 int ret = 0;
127 char *path = NULL;
128
129 NC_CHECK_ARG_RET(NULL, ctx, client_name, endpt_name, hostkey_name, privkey_path, 1);
130 NC_CHECK_ARG_RET(NULL, config, 1);
131
132 if (asprintf(&path, "/ietf-netconf-server:netconf-server/call-home/"
133 "netconf-client[name='%s']/endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/server-identity/"
134 "host-key[name='%s']/public-key/inline-definition", client_name, endpt_name, hostkey_name) == -1) {
135 ERRMEM;
136 path = NULL;
137 ret = 1;
138 goto cleanup;
139 }
140
141 ret = _nc_server_config_new_ssh_hostkey(ctx, path, privkey_path, pubkey_path, config);
142 if (ret) {
143 ERR(NULL, "Creating new Call-Home hostkey YANG data nodes failed.");
144 goto cleanup;
145 }
146
147cleanup:
148 free(path);
149 return ret;
150}
151
152API int
roman8ba6efa2023-07-12 15:27:52 +0200153nc_server_config_new_ssh_del_hostkey(const struct ly_ctx *ctx, const char *endpt_name, const char *hostkey_name,
154 struct lyd_node **config)
155{
156 NC_CHECK_ARG_RET(NULL, ctx, endpt_name, config, 1);
157
158 if (hostkey_name) {
159 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/ssh-server-parameters/"
160 "server-identity/host-key[name='%s']", endpt_name, hostkey_name);
161 } else {
162 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/ssh-server-parameters/"
163 "server-identity/host-key", endpt_name);
164 }
165}
166
roman9d5e5a52023-07-14 12:43:44 +0200167API int
168nc_server_config_new_ch_ssh_del_hostkey(const char *client_name, const char *endpt_name,
169 const char *hostkey_name, struct lyd_node **config)
170{
171 NC_CHECK_ARG_RET(NULL, client_name, endpt_name, config, 1);
172
173 if (hostkey_name) {
174 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/call-home/"
175 "netconf-client[name='%s']/endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/server-identity/"
176 "host-key[name='%s']", client_name, endpt_name, hostkey_name);
177 } else {
178 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/call-home/"
179 "netconf-client[name='%s']/endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/server-identity/"
180 "host-key", client_name, endpt_name);
181 }
182}
183
roman27215242023-03-10 14:55:00 +0100184static int
roman9d5e5a52023-07-14 12:43:44 +0200185nc_server_config_new_ssh_transport_params_prep(const struct ly_ctx *ctx, const char *client_name,
186 const char *endpt_name, struct lyd_node *config, struct lyd_node **new_tree, struct lyd_node **alg_tree)
roman27215242023-03-10 14:55:00 +0100187{
188 int ret = 0;
189 char *tree_path = NULL;
190
191 /* prepare path */
roman9d5e5a52023-07-14 12:43:44 +0200192 if (client_name) {
193 /* ch */
194 asprintf(&tree_path, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/endpoints/"
195 "endpoint[name='%s']/ssh/ssh-server-parameters/transport-params", client_name, endpt_name);
196 } else {
197 /* listen */
198 asprintf(&tree_path, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/"
199 "ssh/ssh-server-parameters/transport-params", endpt_name);
200 }
roman27215242023-03-10 14:55:00 +0100201 if (!tree_path) {
202 ERRMEM;
203 ret = 1;
204 goto cleanup;
205 }
206
207 /* create all the nodes in the path */
208 ret = lyd_new_path2(config, ctx, tree_path, NULL, 0, 0, LYD_NEW_PATH_UPDATE, new_tree, alg_tree);
209 if (ret) {
210 ERR(NULL, "Creating new path to transport-params failed.");
211 goto cleanup;
212 }
213
roman4f9bb442023-03-24 09:05:37 +0100214 if (!*alg_tree) {
215 /* no new nodes added */
216 ret = lyd_find_path(config, tree_path, 0, alg_tree);
217 if (ret) {
218 goto cleanup;
219 }
220 }
221
roman27215242023-03-10 14:55:00 +0100222cleanup:
223 free(tree_path);
224 return ret;
225}
226
227static int
roman9d5e5a52023-07-14 12:43:44 +0200228nc_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 +0100229 struct lyd_node *tree)
230{
231 int i, ret = 0;
232 char *alg, *alg_ident;
233 const char *module, *alg_path, *old_path;
234 struct lyd_node *old = NULL;
235
236 /* get the correct module with the indentity base and the path in the ietf-netconf-server module */
237 switch (alg_type) {
238 case NC_ALG_HOSTKEY:
239 module = "iana-ssh-public-key-algs";
240 alg_path = "host-key/host-key-alg";
241 old_path = "host-key";
242 break;
243 case NC_ALG_KEY_EXCHANGE:
244 module = "iana-ssh-key-exchange-algs";
245 alg_path = "key-exchange/key-exchange-alg";
246 old_path = "key-exchange";
247 break;
248 case NC_ALG_ENCRYPTION:
249 module = "iana-ssh-encryption-algs";
250 alg_path = "encryption/encryption-alg";
251 old_path = "encryption";
252 break;
253 case NC_ALG_MAC:
254 module = "iana-ssh-mac-algs";
255 alg_path = "mac/mac-alg";
256 old_path = "mac";
257 break;
258 default:
259 ret = 1;
260 ERR(NULL, "Unknown algorithm type.");
261 goto cleanup;
262 }
263
264 /* delete all older algorithms (if any) se they can be replaced by the new ones */
265 lyd_find_path(tree, old_path, 0, &old);
266 if (old) {
267 lyd_free_tree(old);
268 }
269
270 for (i = 0; i < alg_count; i++) {
271 alg = va_arg(ap, char *);
272
273 asprintf(&alg_ident, "%s:%s", module, alg);
274 if (!alg_ident) {
275 ERRMEM;
276 ret = 1;
277 goto cleanup;
278 }
279
280 /* create the leaf list */
281 ret = lyd_new_path(tree, ctx, alg_path, alg_ident, 0, NULL);
282 if (ret) {
283 ERR(NULL, "Creating new algorithm leaf-list failed.");
284 goto cleanup;
285 }
286
287 free(alg_ident);
288 }
289
290cleanup:
roman27215242023-03-10 14:55:00 +0100291 return ret;
292}
293
roman9d5e5a52023-07-14 12:43:44 +0200294static int
295nc_server_config_new_ssh_transport_params(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name,
296 NC_ALG_TYPE alg_type, int alg_count, va_list ap, struct lyd_node **config)
roman27215242023-03-10 14:55:00 +0100297{
298 int ret = 0;
299 struct lyd_node *new_tree, *alg_tree;
roman27215242023-03-10 14:55:00 +0100300
roman9d5e5a52023-07-14 12:43:44 +0200301 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 +0100302 if (ret) {
303 goto cleanup;
304 }
305
306 if (!*config) {
307 *config = new_tree;
308 }
309
roman9d5e5a52023-07-14 12:43:44 +0200310 ret = nc_server_config_new_ssh_transport_params_create(ctx, alg_type, alg_count, ap, alg_tree);
roman27215242023-03-10 14:55:00 +0100311 if (ret) {
312 goto cleanup;
313 }
314
roman4f9bb442023-03-24 09:05:37 +0100315 /* Add all default nodes */
316 ret = lyd_new_implicit_tree(*config, LYD_IMPLICIT_NO_STATE, NULL);
317 if (ret) {
318 goto cleanup;
319 }
roman27215242023-03-10 14:55:00 +0100320cleanup:
321 return ret;
322}
323
324API int
roman9d5e5a52023-07-14 12:43:44 +0200325nc_server_config_new_ssh_host_key_algs(const struct ly_ctx *ctx, const char *endpt_name, struct lyd_node **config,
326 int alg_count, ...)
327{
328 int ret = 0;
329 va_list ap;
330
331 NC_CHECK_ARG_RET(NULL, ctx, endpt_name, config, alg_count, 1);
332
333 va_start(ap, alg_count);
334
335 ret = nc_server_config_new_ssh_transport_params(ctx, NULL, endpt_name, NC_ALG_HOSTKEY, alg_count, ap, config);
336 if (ret) {
337 ERR(NULL, "Creating new hostkey algorithms failed.");
338 goto cleanup;
339 }
340
341cleanup:
342 va_end(ap);
343 return ret;
344}
345
346API int
347nc_server_config_new_ch_ssh_host_key_algs(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name,
348 struct lyd_node **config, int alg_count, ...)
349{
350 int ret = 0;
351 va_list ap;
352
353 NC_CHECK_ARG_RET(NULL, ctx, client_name, endpt_name, config, alg_count, 1);
354
355 va_start(ap, alg_count);
356
357 ret = nc_server_config_new_ssh_transport_params(ctx, client_name, endpt_name, NC_ALG_HOSTKEY, alg_count, ap, config);
358 if (ret) {
359 ERR(NULL, "Creating new hostkey algorithms failed.");
360 goto cleanup;
361 }
362
363cleanup:
364 va_end(ap);
365 return ret;
366}
367
368API int
roman8ba6efa2023-07-12 15:27:52 +0200369nc_server_config_new_ssh_del_host_key_alg(const char *endpt_name, const char *alg, struct lyd_node **config)
370{
371 NC_CHECK_ARG_RET(NULL, endpt_name, config, 1);
372
373 if (alg) {
374 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/"
375 "ssh/ssh-server-parameters/transport-params/host-key/"
376 "host-key-alg[.='iana-ssh-public-key-algs:%s']", endpt_name, alg);
377 } else {
378 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/"
379 "ssh/ssh-server-parameters/transport-params/host-key", endpt_name);
380 }
381}
382
383API int
roman9d5e5a52023-07-14 12:43:44 +0200384nc_server_config_new_ch_ssh_del_host_key_alg(const char *client_name, const char *endpt_name,
385 const char *alg, struct lyd_node **config)
386{
387 NC_CHECK_ARG_RET(NULL, client_name, endpt_name, config, 1);
388
389 if (alg) {
390 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/"
391 "endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/transport-params/host-key/"
392 "host-key-alg[.='iana-ssh-public-key-algs:%s']", client_name, endpt_name, alg);
393 } else {
394 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/"
395 "endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/transport-params/host-key", client_name, endpt_name);
396 }
397}
398
399API int
400nc_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 +0100401 int alg_count, ...)
402{
403 int ret = 0;
roman27215242023-03-10 14:55:00 +0100404 va_list ap;
405
roman9d5e5a52023-07-14 12:43:44 +0200406 NC_CHECK_ARG_RET(NULL, ctx, endpt_name, config, alg_count, 1);
roman27215242023-03-10 14:55:00 +0100407
408 va_start(ap, alg_count);
409
roman9d5e5a52023-07-14 12:43:44 +0200410 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 +0100411 if (ret) {
roman9d5e5a52023-07-14 12:43:44 +0200412 ERR(NULL, "Creating new key exchange algorithms failed.");
roman27215242023-03-10 14:55:00 +0100413 goto cleanup;
414 }
415
roman9d5e5a52023-07-14 12:43:44 +0200416cleanup:
417 va_end(ap);
418 return ret;
419}
420
421API int
422nc_server_config_new_ch_ssh_key_exchange_algs(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name,
423 struct lyd_node **config, int alg_count, ...)
424{
425 int ret = 0;
426 va_list ap;
427
428 NC_CHECK_ARG_RET(NULL, ctx, client_name, endpt_name, config, alg_count, 1);
429
430 va_start(ap, alg_count);
431
432 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 +0100433 if (ret) {
roman9d5e5a52023-07-14 12:43:44 +0200434 ERR(NULL, "Creating new key exchange algorithms failed.");
roman4f9bb442023-03-24 09:05:37 +0100435 goto cleanup;
436 }
roman9d5e5a52023-07-14 12:43:44 +0200437
roman27215242023-03-10 14:55:00 +0100438cleanup:
roman9d5e5a52023-07-14 12:43:44 +0200439 va_end(ap);
roman27215242023-03-10 14:55:00 +0100440 return ret;
441}
442
443API int
roman8ba6efa2023-07-12 15:27:52 +0200444nc_server_config_new_ssh_del_key_exchange_alg(const char *endpt_name, const char *alg, struct lyd_node **config)
445{
446 NC_CHECK_ARG_RET(NULL, endpt_name, config, 1);
447
448 if (alg) {
449 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/"
450 "ssh/ssh-server-parameters/transport-params/key-exchange/"
451 "key-exchange-alg[.='iana-ssh-key-exchange-algs:%s']", endpt_name, alg);
452 } else {
453 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/"
454 "ssh/ssh-server-parameters/transport-params/key-exchange", endpt_name);
455 }
456}
457
458API int
roman9d5e5a52023-07-14 12:43:44 +0200459nc_server_config_new_ch_ssh_del_key_exchange_alg(const char *client_name, const char *endpt_name,
460 const char *alg, struct lyd_node **config)
461{
462 NC_CHECK_ARG_RET(NULL, client_name, endpt_name, config, 1);
463
464 if (alg) {
465 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/"
466 "endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/transport-params/key-exchange/"
467 "key-exchange-alg[.='iana-ssh-key-exchange-algs:%s']", client_name, endpt_name, alg);
468 } else {
469 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/"
470 "endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/transport-params/key-exchange", client_name, endpt_name);
471 }
472}
473
474API int
roman466719d2023-05-05 16:14:37 +0200475nc_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 +0100476 int alg_count, ...)
477{
478 int ret = 0;
roman27215242023-03-10 14:55:00 +0100479 va_list ap;
480
roman9d5e5a52023-07-14 12:43:44 +0200481 NC_CHECK_ARG_RET(NULL, ctx, endpt_name, config, alg_count, 1);
roman27215242023-03-10 14:55:00 +0100482
483 va_start(ap, alg_count);
484
roman9d5e5a52023-07-14 12:43:44 +0200485 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 +0100486 if (ret) {
roman9d5e5a52023-07-14 12:43:44 +0200487 ERR(NULL, "Creating new encryption algorithms failed.");
roman27215242023-03-10 14:55:00 +0100488 goto cleanup;
489 }
490
roman9d5e5a52023-07-14 12:43:44 +0200491cleanup:
492 va_end(ap);
493 return ret;
494}
495
496API int
497nc_server_config_new_ch_ssh_encryption_algs(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name,
498 struct lyd_node **config, int alg_count, ...)
499{
500 int ret = 0;
501 va_list ap;
502
503 NC_CHECK_ARG_RET(NULL, ctx, client_name, endpt_name, config, alg_count, 1);
504
505 va_start(ap, alg_count);
506
507 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 +0100508 if (ret) {
roman9d5e5a52023-07-14 12:43:44 +0200509 ERR(NULL, "Creating new encryption algorithms failed.");
roman4f9bb442023-03-24 09:05:37 +0100510 goto cleanup;
511 }
roman9d5e5a52023-07-14 12:43:44 +0200512
roman27215242023-03-10 14:55:00 +0100513cleanup:
roman9d5e5a52023-07-14 12:43:44 +0200514 va_end(ap);
roman27215242023-03-10 14:55:00 +0100515 return ret;
516}
517
518API int
roman8ba6efa2023-07-12 15:27:52 +0200519nc_server_config_new_ssh_del_encryption_alg(const char *endpt_name, const char *alg, struct lyd_node **config)
520{
521 NC_CHECK_ARG_RET(NULL, endpt_name, config, 1);
522
523 if (alg) {
524 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/"
525 "ssh/ssh-server-parameters/transport-params/encryption/"
526 "encryption-alg[.='iana-ssh-encryption-algs:%s']", endpt_name, alg);
527 } else {
528 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/"
529 "ssh/ssh-server-parameters/transport-params/encryption", endpt_name);
530 }
531}
532
533API int
roman9d5e5a52023-07-14 12:43:44 +0200534nc_server_config_new_ch_ssh_del_encryption_alg(const char *client_name, const char *endpt_name,
535 const char *alg, struct lyd_node **config)
536{
537 NC_CHECK_ARG_RET(NULL, client_name, endpt_name, config, 1);
538
539 if (alg) {
540 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/"
541 "endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/transport-params/encryption/"
542 "encryption-alg[.='iana-ssh-encryption-algs:%s']", client_name, endpt_name, alg);
543 } else {
544 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/"
545 "endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/transport-params/encryption", client_name, endpt_name);
546 }
547}
548
549API int
roman27215242023-03-10 14:55:00 +0100550nc_server_config_ssh_new_mac_algs(const struct ly_ctx *ctx, const char *endpt_name, struct lyd_node **config,
551 int alg_count, ...)
552{
553 int ret = 0;
roman27215242023-03-10 14:55:00 +0100554 va_list ap;
555
roman9d5e5a52023-07-14 12:43:44 +0200556 NC_CHECK_ARG_RET(NULL, ctx, endpt_name, config, alg_count, 1);
roman27215242023-03-10 14:55:00 +0100557
558 va_start(ap, alg_count);
559
roman9d5e5a52023-07-14 12:43:44 +0200560 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 +0100561 if (ret) {
roman9d5e5a52023-07-14 12:43:44 +0200562 ERR(NULL, "Creating new mac algorithms failed.");
roman27215242023-03-10 14:55:00 +0100563 goto cleanup;
564 }
565
roman9d5e5a52023-07-14 12:43:44 +0200566cleanup:
567 va_end(ap);
568 return ret;
569}
570
571API int
572nc_server_config_new_ch_ssh_mac_algs(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name,
573 struct lyd_node **config, int alg_count, ...)
574{
575 int ret = 0;
576 va_list ap;
577
578 NC_CHECK_ARG_RET(NULL, ctx, client_name, endpt_name, config, alg_count, 1);
579
580 va_start(ap, alg_count);
581
582 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 +0100583 if (ret) {
roman9d5e5a52023-07-14 12:43:44 +0200584 ERR(NULL, "Creating new mac algorithms failed.");
roman4f9bb442023-03-24 09:05:37 +0100585 goto cleanup;
586 }
roman9d5e5a52023-07-14 12:43:44 +0200587
roman27215242023-03-10 14:55:00 +0100588cleanup:
roman9d5e5a52023-07-14 12:43:44 +0200589 va_end(ap);
roman27215242023-03-10 14:55:00 +0100590 return ret;
591}
roman4f9bb442023-03-24 09:05:37 +0100592
roman4f9bb442023-03-24 09:05:37 +0100593API int
roman8ba6efa2023-07-12 15:27:52 +0200594nc_server_config_new_ssh_del_mac_alg(const char *endpt_name, const char *alg, struct lyd_node **config)
595{
596 NC_CHECK_ARG_RET(NULL, endpt_name, config, 1);
597
598 if (alg) {
599 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/"
600 "ssh/ssh-server-parameters/transport-params/mac/"
601 "mac-alg[.='iana-ssh-mac-algs:%s']", endpt_name, alg);
602 } else {
603 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/"
604 "ssh/ssh-server-parameters/transport-params/mac", endpt_name);
605 }
606}
607
608API int
roman9d5e5a52023-07-14 12:43:44 +0200609nc_server_config_new_ch_ssh_del_mac_alg(const char *client_name, const char *endpt_name,
610 const char *alg, struct lyd_node **config)
611{
612 NC_CHECK_ARG_RET(NULL, client_name, endpt_name, config, 1);
613
614 if (alg) {
615 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/"
616 "endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/transport-params/mac/"
617 "mac-alg[.='iana-ssh-mac-algs:%s']", client_name, endpt_name, alg);
618 } else {
619 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/"
620 "endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/transport-params/mac", client_name, endpt_name);
621 }
622}
623
624API int
roman8ba6efa2023-07-12 15:27:52 +0200625nc_server_config_new_ssh_del_user(const char *endpt_name,
626 const char *user_name, struct lyd_node **config)
627{
628 NC_CHECK_ARG_RET(NULL, endpt_name, config, 1);
629
630 if (user_name) {
631 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/"
632 "ssh-server-parameters/client-authentication/users/user[name='%s']", endpt_name, user_name);
633 } else {
634 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/"
635 "ssh-server-parameters/client-authentication/users/user", endpt_name);
636 }
637}
638
639API int
roman9d5e5a52023-07-14 12:43:44 +0200640nc_server_config_new_ch_ssh_del_user(const char *client_name, const char *endpt_name,
641 const char *user_name, struct lyd_node **config)
642{
643 NC_CHECK_ARG_RET(NULL, client_name, endpt_name, config, 1);
644
645 if (user_name) {
646 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/endpoints/"
647 "endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/users/user[name='%s']", client_name,
648 endpt_name, user_name);
649 } else {
650 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/endpoints/"
651 "endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/users/user", client_name, endpt_name);
652 }
653}
654
655static int
656_nc_server_config_new_ssh_user_pubkey(const struct ly_ctx *ctx, const char *tree_path, const char *pubkey_path,
657 struct lyd_node **config)
roman4f9bb442023-03-24 09:05:37 +0100658{
659 int ret = 0;
romand30af552023-06-16 15:18:27 +0200660 char *pubkey = NULL;
roman3f9b65c2023-06-05 14:26:58 +0200661 NC_PUBKEY_FORMAT pubkey_type;
romand30af552023-06-16 15:18:27 +0200662 const char *pubkey_format;
roman4f9bb442023-03-24 09:05:37 +0100663
romand30af552023-06-16 15:18:27 +0200664 /* get pubkey data */
roman3f9b65c2023-06-05 14:26:58 +0200665 ret = nc_server_config_new_get_pubkey(pubkey_path, &pubkey, &pubkey_type);
roman4f9bb442023-03-24 09:05:37 +0100666 if (ret) {
667 goto cleanup;
668 }
669
romand30af552023-06-16 15:18:27 +0200670 /* get pubkey format */
roman3f9b65c2023-06-05 14:26:58 +0200671 if (pubkey_type == NC_PUBKEY_FORMAT_SSH2) {
romand30af552023-06-16 15:18:27 +0200672 pubkey_format = "ietf-crypto-types:ssh-public-key-format";
roman4f9bb442023-03-24 09:05:37 +0100673 } else {
romand30af552023-06-16 15:18:27 +0200674 pubkey_format = "ietf-crypto-types:subject-public-key-info-format";
roman4f9bb442023-03-24 09:05:37 +0100675 }
romand30af552023-06-16 15:18:27 +0200676
roman9d5e5a52023-07-14 12:43:44 +0200677 ret = nc_config_new_create_append(ctx, tree_path, "public-key-format", pubkey_format, config);
roman4f9bb442023-03-24 09:05:37 +0100678 if (ret) {
679 goto cleanup;
680 }
681
roman9d5e5a52023-07-14 12:43:44 +0200682 ret = nc_config_new_create_append(ctx, tree_path, "public-key", pubkey, config);
roman4f9bb442023-03-24 09:05:37 +0100683 if (ret) {
684 goto cleanup;
685 }
686
687cleanup:
roman4f9bb442023-03-24 09:05:37 +0100688 free(pubkey);
689 return ret;
690}
roman31820092023-03-24 15:26:21 +0100691
692API int
roman9d5e5a52023-07-14 12:43:44 +0200693nc_server_config_new_ssh_user_pubkey(const struct ly_ctx *ctx, const char *endpt_name,
694 const char *user_name, const char *pubkey_name, const char *pubkey_path, struct lyd_node **config)
695{
696 int ret = 0;
697 char *path = NULL;
698
699 NC_CHECK_ARG_RET(NULL, ctx, endpt_name, user_name, pubkey_name, pubkey_path, 1);
700 NC_CHECK_ARG_RET(NULL, config, 1);
701
702 if (asprintf(&path, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/"
703 "ssh-server-parameters/client-authentication/users/user[name='%s']/public-keys/inline-definition/"
704 "public-key[name='%s']", endpt_name, user_name, pubkey_name) == -1) {
705 ERRMEM;
706 path = NULL;
707 ret = 1;
708 goto cleanup;
709 }
710
711 ret = _nc_server_config_new_ssh_user_pubkey(ctx, path, pubkey_path, config);
712 if (ret) {
713 ERR(NULL, "Creating new user's public key failed.");
714 goto cleanup;
715 }
716
717cleanup:
718 free(path);
719 return ret;
720}
721
722API int
723nc_server_config_new_ch_ssh_user_pubkey(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name,
724 const char *user_name, const char *pubkey_name, const char *pubkey_path, struct lyd_node **config)
725{
726 int ret = 0;
727 char *path = NULL;
728
729 NC_CHECK_ARG_RET(NULL, ctx, client_name, endpt_name, user_name, pubkey_name, 1);
730 NC_CHECK_ARG_RET(NULL, pubkey_path, config, 1);
731
732 if (asprintf(&path, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/endpoints/"
733 "endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/"
734 "users/user[name='%s']/public-keys/inline-definition/public-key[name='%s']", client_name,
735 endpt_name, user_name, pubkey_name) == -1) {
736 ERRMEM;
737 path = NULL;
738 ret = 1;
739 goto cleanup;
740 }
741
742 ret = _nc_server_config_new_ssh_user_pubkey(ctx, path, pubkey_path, config);
743 if (ret) {
744 ERR(NULL, "Creating new user's public key failed.");
745 goto cleanup;
746 }
747
748cleanup:
749 free(path);
750 return ret;
751}
752
753API int
roman8ba6efa2023-07-12 15:27:52 +0200754nc_server_config_new_ssh_del_user_pubkey(const char *endpt_name, const char *user_name,
755 const char *pubkey_name, struct lyd_node **config)
756{
757 NC_CHECK_ARG_RET(NULL, endpt_name, user_name, config, 1);
758
759 if (pubkey_name) {
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']/public-keys/inline-definition/"
762 "public-key[name='%s']", endpt_name, user_name, pubkey_name);
763 } else {
764 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/"
765 "ssh-server-parameters/client-authentication/users/user[name='%s']/public-keys/inline-definition/"
766 "public-key", endpt_name, user_name);
767 }
768}
769
770API int
roman9d5e5a52023-07-14 12:43:44 +0200771nc_server_config_new_ch_ssh_del_user_pubkey(const char *client_name, const char *endpt_name,
772 const char *user_name, const char *pubkey_name, struct lyd_node **config)
773{
774 NC_CHECK_ARG_RET(NULL, client_name, endpt_name, user_name, config, 1);
775
776 if (pubkey_name) {
777 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/call-home/"
778 "netconf-client[name='%s']/endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/"
779 "users/user[name='%s']/public-keys/inline-definition/public-key[name='%s']", client_name,
780 endpt_name, user_name, pubkey_name);
781 } else {
782 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/call-home/"
783 "netconf-client[name='%s']/endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/"
784 "users/user[name='%s']/public-keys/inline-definition/public-key", client_name,
785 endpt_name, user_name);
786 }
787}
788
789static int
790_nc_server_config_new_ssh_user_password(const struct ly_ctx *ctx, const char *tree_path,
791 const char *password, struct lyd_node **config)
roman31820092023-03-24 15:26:21 +0100792{
793 int ret = 0;
romand30af552023-06-16 15:18:27 +0200794 char *hashed_pw = NULL;
roman31820092023-03-24 15:26:21 +0100795 const char *salt = "$6$idsizuippipk$";
796
797#ifdef HAVE_CRYPT_R
798 struct crypt_data cdata;
799#endif
800
roman31820092023-03-24 15:26:21 +0100801#ifdef HAVE_CRYPT_R
802 cdata.initialized = 0;
803 hashed_pw = crypt_r(password, salt, &data);
804#else
805 pthread_mutex_lock(&crypt_lock);
806 hashed_pw = crypt(password, salt);
807 pthread_mutex_unlock(&crypt_lock);
808#endif
809
810 if (!hashed_pw) {
811 ERR(NULL, "Hashing password failed.");
812 ret = 1;
813 goto cleanup;
814 }
815
roman9d5e5a52023-07-14 12:43:44 +0200816 ret = nc_config_new_create_append(ctx, tree_path, "password", hashed_pw, config);
roman31820092023-03-24 15:26:21 +0100817 if (ret) {
818 goto cleanup;
819 }
820
821cleanup:
roman31820092023-03-24 15:26:21 +0100822 return ret;
823}
824
825API int
roman9d5e5a52023-07-14 12:43:44 +0200826nc_server_config_new_ssh_user_password(const struct ly_ctx *ctx, const char *endpt_name,
827 const char *user_name, const char *password, struct lyd_node **config)
828{
829 int ret = 0;
830 char *path = NULL;
831
832 NC_CHECK_ARG_RET(NULL, ctx, endpt_name, user_name, password, config, 1);
833
834 if (asprintf(&path, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/ssh-server-parameters/"
835 "client-authentication/users/user[name='%s']", endpt_name, user_name) == -1) {
836 ERRMEM;
837 path = NULL;
838 ret = 1;
839 goto cleanup;
840 }
841
842 ret = _nc_server_config_new_ssh_user_password(ctx, path, password, config);
843 if (ret) {
844 ERR(NULL, "Creating new user's public key failed.");
845 goto cleanup;
846 }
847
848cleanup:
849 free(path);
850 return ret;
851}
852
853API int
854nc_server_config_new_ch_ssh_user_password(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name,
855 const char *user_name, const char *password, struct lyd_node **config)
856{
857 int ret = 0;
858 char *path = NULL;
859
860 NC_CHECK_ARG_RET(NULL, ctx, client_name, endpt_name, user_name, password, 1);
861 NC_CHECK_ARG_RET(NULL, config, 1);
862
863 if (asprintf(&path, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/endpoints/"
864 "endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/"
865 "users/user[name='%s']", client_name, endpt_name, user_name) == -1) {
866 ERRMEM;
867 path = NULL;
868 ret = 1;
869 goto cleanup;
870 }
871
872 ret = _nc_server_config_new_ssh_user_password(ctx, path, password, config);
873 if (ret) {
874 ERR(NULL, "Creating new user's password failed.");
875 goto cleanup;
876 }
877
878cleanup:
879 free(path);
880 return ret;
881}
882
883API int
roman8ba6efa2023-07-12 15:27:52 +0200884nc_server_config_new_ssh_del_user_password(const char *endpt_name, const char *user_name, struct lyd_node **config)
roman31820092023-03-24 15:26:21 +0100885{
roman8ba6efa2023-07-12 15:27:52 +0200886 NC_CHECK_ARG_RET(NULL, endpt_name, user_name, config, 1);
roman31820092023-03-24 15:26:21 +0100887
roman8ba6efa2023-07-12 15:27:52 +0200888 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/"
889 "ssh-server-parameters/client-authentication/users/user[name='%s']/password", endpt_name, user_name);
roman31820092023-03-24 15:26:21 +0100890}
891
892API int
roman9d5e5a52023-07-14 12:43:44 +0200893nc_server_config_new_ch_ssh_del_user_password(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']/password", client_name, endpt_name, user_name);
901}
902
903API int
roman8ba6efa2023-07-12 15:27:52 +0200904nc_server_config_new_ssh_user_none(const struct ly_ctx *ctx, const char *endpt_name,
905 const char *user_name, struct lyd_node **config)
906{
907 NC_CHECK_ARG_RET(NULL, ctx, endpt_name, user_name, config, 1);
908
909 return nc_config_new_create(ctx, config, NULL, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/"
910 "users/user[name='%s']/none", endpt_name, user_name);
911}
912
913API int
roman9d5e5a52023-07-14 12:43:44 +0200914nc_server_config_new_ch_ssh_user_none(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name,
915 const char *user_name, struct lyd_node **config)
916{
917 NC_CHECK_ARG_RET(NULL, ctx, client_name, endpt_name, user_name, config, 1);
918
919 return nc_config_new_create(ctx, config, NULL, "/ietf-netconf-server:netconf-server/call-home/"
920 "netconf-client[name='%s']/endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/"
921 "users/user[name='%s']/none", client_name, endpt_name, user_name);
922}
923
924API int
roman8ba6efa2023-07-12 15:27:52 +0200925nc_server_config_new_ssh_del_user_none(const char *endpt_name, const char *user_name, struct lyd_node **config)
926{
927 NC_CHECK_ARG_RET(NULL, endpt_name, user_name, config, 1);
928
929 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/"
930 "ssh-server-parameters/client-authentication/users/user[name='%s']/none", endpt_name, user_name);
931}
932
933API int
roman9d5e5a52023-07-14 12:43:44 +0200934nc_server_config_new_ch_ssh_del_user_none(const char *client_name, const char *endpt_name,
935 const char *user_name, struct lyd_node **config)
936{
937 NC_CHECK_ARG_RET(NULL, client_name, endpt_name, user_name, config, 1);
938
939 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/call-home/"
940 "netconf-client[name='%s']/endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/"
941 "users/user[name='%s']/none", client_name, endpt_name, user_name);
942}
943
944static int
945_nc_server_config_new_ssh_user_interactive(const struct ly_ctx *ctx, const char *tree_path,
946 const char *pam_config_name, const char *pam_config_dir, struct lyd_node **config)
roman31820092023-03-24 15:26:21 +0100947{
948 int ret = 0;
roman31820092023-03-24 15:26:21 +0100949
roman9d5e5a52023-07-14 12:43:44 +0200950 ret = nc_config_new_create_append(ctx, tree_path, "pam-config-file-name", pam_config_name, config);
roman31820092023-03-24 15:26:21 +0100951 if (ret) {
952 goto cleanup;
953 }
954
roman8ba6efa2023-07-12 15:27:52 +0200955 if (pam_config_dir) {
roman9d5e5a52023-07-14 12:43:44 +0200956 ret = nc_config_new_create_append(ctx, tree_path, "pam-config-file-dir", pam_config_dir, config);
roman8ba6efa2023-07-12 15:27:52 +0200957 if (ret) {
958 goto cleanup;
959 }
roman31820092023-03-24 15:26:21 +0100960 }
961
962cleanup:
roman31820092023-03-24 15:26:21 +0100963 return ret;
964}
roman2e797ef2023-06-19 10:47:49 +0200965
966API int
roman9d5e5a52023-07-14 12:43:44 +0200967nc_server_config_new_ssh_user_interactive(const struct ly_ctx *ctx, const char *endpt_name,
968 const char *user_name, const char *pam_config_name, const char *pam_config_dir, struct lyd_node **config)
969{
970 int ret = 0;
971 char *path = NULL;
972
973 NC_CHECK_ARG_RET(NULL, ctx, endpt_name, user_name, pam_config_name, config, 1);
974
975 if (asprintf(&path, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/ssh-server-parameters/"
976 "client-authentication/users/user[name='%s']/"
977 "libnetconf2-netconf-server:keyboard-interactive", endpt_name, user_name) == -1) {
978 ERRMEM;
979 path = NULL;
980 ret = 1;
981 goto cleanup;
982 }
983
984 ret = _nc_server_config_new_ssh_user_interactive(ctx, path, pam_config_name, pam_config_dir, config);
985 if (ret) {
986 ERR(NULL, "Creating new user's keyboard interactive nodes failed.");
987 goto cleanup;
988 }
989
990cleanup:
991 free(path);
992 return ret;
993}
994
995API int
996nc_server_config_new_ch_ssh_user_interactive(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name,
997 const char *user_name, const char *pam_config_name, const char *pam_config_dir, struct lyd_node **config)
998{
999 int ret = 0;
1000 char *path = NULL;
1001
1002 NC_CHECK_ARG_RET(NULL, ctx, client_name, endpt_name, user_name, pam_config_name, 1);
1003 NC_CHECK_ARG_RET(NULL, config, 1);
1004
1005 if (asprintf(&path, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/endpoints/"
1006 "endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/users/user[name='%s']/"
1007 "libnetconf2-netconf-server:keyboard-interactive", client_name, endpt_name, user_name) == -1) {
1008 ERRMEM;
1009 path = NULL;
1010 ret = 1;
1011 goto cleanup;
1012 }
1013
1014 ret = _nc_server_config_new_ssh_user_interactive(ctx, path, pam_config_name, pam_config_dir, config);
1015 if (ret) {
1016 ERR(NULL, "Creating new user's keyboard interactive nodes failed.");
1017 goto cleanup;
1018 }
1019
1020cleanup:
1021 free(path);
1022 return ret;
1023}
1024
1025API int
roman8ba6efa2023-07-12 15:27:52 +02001026nc_server_config_new_ssh_del_user_interactive(const char *endpt_name, const char *user_name, struct lyd_node **config)
roman2e797ef2023-06-19 10:47:49 +02001027{
roman8ba6efa2023-07-12 15:27:52 +02001028 NC_CHECK_ARG_RET(NULL, endpt_name, user_name, config, 1);
1029
1030 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/"
1031 "ssh-server-parameters/client-authentication/users/user[name='%s']/"
1032 "libnetconf2-netconf-server:keyboard-interactive", endpt_name, user_name);
1033}
1034
1035API int
roman9d5e5a52023-07-14 12:43:44 +02001036nc_server_config_new_ch_ssh_del_user_interactive(const char *client_name, const char *endpt_name,
1037 const char *user_name, struct lyd_node **config)
1038{
1039 NC_CHECK_ARG_RET(NULL, client_name, endpt_name, user_name, config, 1);
1040
1041 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/endpoints/"
1042 "endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/users/user[name='%s']/"
1043 "libnetconf2-netconf-server:keyboard-interactive", client_name, endpt_name, user_name);
1044}
1045
1046API int
roman8ba6efa2023-07-12 15:27:52 +02001047nc_config_new_ssh_endpoint_user_reference(const struct ly_ctx *ctx, const char *endpt_name,
1048 const char *referenced_endpt, struct lyd_node **config)
1049{
1050 NC_CHECK_ARG_RET(NULL, ctx, endpt_name, referenced_endpt, config, 1);
1051
roman5cbb6532023-06-22 12:53:17 +02001052 return nc_config_new_create(ctx, config, referenced_endpt, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/ssh-server-parameters/"
roman2e797ef2023-06-19 10:47:49 +02001053 "client-authentication/libnetconf2-netconf-server:endpoint-client-auth", endpt_name);
1054}
roman5cbb6532023-06-22 12:53:17 +02001055
1056API int
roman8ba6efa2023-07-12 15:27:52 +02001057nc_config_new_ssh_del_endpoint_user_reference(const char *endpt_name, struct lyd_node **config)
1058{
1059 NC_CHECK_ARG_RET(NULL, endpt_name, config, 1);
1060
1061 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/ssh-server-parameters/"
1062 "client-authentication/libnetconf2-netconf-server:endpoint-client-auth", endpt_name);
1063}
1064
1065API int
roman9d5e5a52023-07-14 12:43:44 +02001066nc_server_config_new_ch_ssh_keystore_reference(const struct ly_ctx *ctx, const char *client_name,
1067 const char *endpt_name, const char *hostkey_name, const char *keystore_reference, struct lyd_node **config)
roman5cbb6532023-06-22 12:53:17 +02001068{
roman9d5e5a52023-07-14 12:43:44 +02001069 NC_CHECK_ARG_RET(NULL, ctx, client_name, endpt_name, hostkey_name, keystore_reference, 1);
1070 NC_CHECK_ARG_RET(NULL, config, 1);
roman5cbb6532023-06-22 12:53:17 +02001071
roman9d5e5a52023-07-14 12:43:44 +02001072 return nc_config_new_create(ctx, config, keystore_reference, "/ietf-netconf-server:netconf-server/call-home/"
roman5cbb6532023-06-22 12:53:17 +02001073 "netconf-client[name='%s']/endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/server-identity/"
roman9d5e5a52023-07-14 12:43:44 +02001074 "host-key[name='%s']/public-key/keystore-reference", client_name, endpt_name, hostkey_name);
roman5cbb6532023-06-22 12:53:17 +02001075}
1076
1077API int
roman9d5e5a52023-07-14 12:43:44 +02001078nc_server_config_new_ch_ssh_del_keystore_reference(const char *client_name, const char *endpt_name,
roman8ba6efa2023-07-12 15:27:52 +02001079 const char *hostkey_name, struct lyd_node **config)
1080{
roman9d5e5a52023-07-14 12:43:44 +02001081 NC_CHECK_ARG_RET(NULL, client_name, endpt_name, hostkey_name, config, 1);
roman8ba6efa2023-07-12 15:27:52 +02001082
roman9d5e5a52023-07-14 12:43:44 +02001083 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/call-home/"
1084 "netconf-client[name='%s']/endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/server-identity/"
1085 "host-key[name='%s']/public-key/keystore-reference", client_name, endpt_name, hostkey_name);
roman8ba6efa2023-07-12 15:27:52 +02001086}
1087
1088API int
roman142718b2023-06-29 09:15:29 +02001089nc_server_config_new_ssh_keystore_reference(const struct ly_ctx *ctx, const char *endpt_name, const char *hostkey_name,
1090 const char *keystore_reference, struct lyd_node **config)
1091{
1092 NC_CHECK_ARG_RET(NULL, ctx, endpt_name, hostkey_name, keystore_reference, config, 1);
1093
1094 return nc_config_new_create(ctx, config, keystore_reference, "/ietf-netconf-server:netconf-server/listen/"
roman4cb8bb12023-06-29 09:16:46 +02001095 "endpoint[name='%s']/ssh/ssh-server-parameters/server-identity/host-key[name='%s']/public-key/"
1096 "keystore-reference", endpt_name, hostkey_name);
roman142718b2023-06-29 09:15:29 +02001097}
1098
1099API int
roman8ba6efa2023-07-12 15:27:52 +02001100nc_server_config_new_ssh_del_keystore_reference(const char *endpt_name, const char *hostkey_name,
1101 struct lyd_node **config)
1102{
1103 NC_CHECK_ARG_RET(NULL, endpt_name, config, 1);
1104
1105 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/listen/"
1106 "endpoint[name='%s']/ssh/ssh-server-parameters/server-identity/host-key[name='%s']/public-key/"
1107 "keystore-reference", endpt_name, hostkey_name);
1108}
1109
1110API int
roman142718b2023-06-29 09:15:29 +02001111nc_server_config_new_ssh_truststore_reference(const struct ly_ctx *ctx, const char *endpt_name, const char *user_name,
1112 const char *truststore_reference, struct lyd_node **config)
1113{
1114 NC_CHECK_ARG_RET(NULL, ctx, endpt_name, user_name, truststore_reference, config, 1);
1115
1116 return nc_config_new_create(ctx, config, truststore_reference, "/ietf-netconf-server:netconf-server/listen/"
roman4cb8bb12023-06-29 09:16:46 +02001117 "endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/users/user[name='%s']/public-keys/"
1118 "truststore-reference", endpt_name, user_name);
roman142718b2023-06-29 09:15:29 +02001119}
roman8ba6efa2023-07-12 15:27:52 +02001120
1121API int
roman9d5e5a52023-07-14 12:43:44 +02001122nc_server_config_new_ch_ssh_truststore_reference(const struct ly_ctx *ctx, const char *client_name,
1123 const char *endpt_name, const char *user_name, const char *truststore_reference, struct lyd_node **config)
1124{
1125 NC_CHECK_ARG_RET(NULL, ctx, client_name, endpt_name, user_name, truststore_reference, 1);
1126 NC_CHECK_ARG_RET(NULL, config, 1);
1127
1128 return nc_config_new_create(ctx, config, truststore_reference, "/ietf-netconf-server:netconf-server/call-home/"
1129 "netconf-client[name='%s']/endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/"
1130 "users/user[name='%s']/public-keys/truststore-reference", client_name, endpt_name, user_name);
1131}
1132
1133API int
roman8ba6efa2023-07-12 15:27:52 +02001134nc_server_config_new_ssh_del_truststore_reference(const char *endpt_name, const char *user_name,
1135 struct lyd_node **config)
1136{
1137 NC_CHECK_ARG_RET(NULL, endpt_name, user_name, config, 1);
1138
1139 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/listen/"
1140 "endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/users/user[name='%s']/public-keys/"
1141 "truststore-reference", endpt_name, user_name);
1142}
roman9d5e5a52023-07-14 12:43:44 +02001143
1144API int
1145nc_server_config_new_ch_ssh_del_truststore_reference(const char *client_name, const char *endpt_name,
1146 const char *user_name, struct lyd_node **config)
1147{
1148 NC_CHECK_ARG_RET(NULL, client_name, endpt_name, user_name, config, 1);
1149
1150 return nc_config_new_delete(config, "/ietf-netconf-server:netconf-server/call-home/"
1151 "netconf-client[name='%s']/endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/"
1152 "users/user[name='%s']/public-keys/truststore-reference", client_name, endpt_name, user_name);
1153}