blob: a64a8a1447f67c47d8fce03c34d7cd7ec233527e [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
roman27215242023-03-10 14:55:00 +010037API int
roman3f9b65c2023-06-05 14:26:58 +020038nc_server_config_new_ssh_hostkey(const struct ly_ctx *ctx,
39 const char *endpt_name, const char *hostkey_name, const char *privkey_path, const char *pubkey_path, struct lyd_node **config)
roman27215242023-03-10 14:55:00 +010040{
41 int ret = 0;
roman466719d2023-05-05 16:14:37 +020042 char *pubkey = NULL, *privkey = NULL, *pubkey_stripped, *privkey_stripped;
roman27215242023-03-10 14:55:00 +010043 struct lyd_node *new_tree;
44 char *tree_path = NULL;
roman466719d2023-05-05 16:14:37 +020045 NC_PRIVKEY_FORMAT privkey_type;
roman3f9b65c2023-06-05 14:26:58 +020046 NC_PUBKEY_FORMAT pubkey_type;
47 const char *privkey_identity;
roman27215242023-03-10 14:55:00 +010048
roman40672412023-05-04 11:10:22 +020049 NC_CHECK_ARG_RET(NULL, privkey_path, config, ctx, endpt_name, hostkey_name, 1);
roman27215242023-03-10 14:55:00 +010050
51 /* get the keys as a string from the given files */
roman3f9b65c2023-06-05 14:26:58 +020052 ret = nc_server_config_new_get_keys(privkey_path, pubkey_path, &privkey, &pubkey, &privkey_type, &pubkey_type);
roman27215242023-03-10 14:55:00 +010053 if (ret) {
54 ERR(NULL, "Getting keys from file(s) failed.");
55 goto cleanup;
56 }
57
58 /* prepare path where leaves will get inserted */
59 asprintf(&tree_path, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/ssh-server-parameters/"
60 "server-identity/host-key[name='%s']/public-key/local-definition", endpt_name, hostkey_name);
61 if (!tree_path) {
62 ERRMEM;
63 ret = 1;
64 goto cleanup;
65 }
66
67 /* create all the nodes in the path if they weren't there */
68 ret = lyd_new_path(*config, ctx, tree_path, NULL, LYD_NEW_PATH_UPDATE, &new_tree);
69 if (ret) {
70 goto cleanup;
71 }
72 if (!*config) {
73 *config = new_tree;
74 }
75
roman27215242023-03-10 14:55:00 +010076 /* find the node where leaves will get inserted */
77 ret = lyd_find_path(*config, tree_path, 0, &new_tree);
78 if (ret) {
79 goto cleanup;
80 }
81
82 /* insert pubkey format */
roman3f9b65c2023-06-05 14:26:58 +020083 if (pubkey_type == NC_PUBKEY_FORMAT_SSH2) {
roman27215242023-03-10 14:55:00 +010084 ret = lyd_new_term(new_tree, NULL, "public-key-format", "ietf-crypto-types:ssh-public-key-format", 0, NULL);
85 } else {
86 ret = lyd_new_term(new_tree, NULL, "public-key-format", "ietf-crypto-types:subject-public-key-info-format", 0, NULL);
87 }
88 if (ret) {
89 goto cleanup;
90 }
91
roman466719d2023-05-05 16:14:37 +020092 /* strip pubkey's header and footer only if it's generated from pkcs8 key (using OpenSSL),
93 * otherwise it's already stripped
94 */
roman3f9b65c2023-06-05 14:26:58 +020095 if (!pubkey_path && (privkey_type == NC_PRIVKEY_FORMAT_X509)) {
96 pubkey_stripped = pubkey + strlen(NC_SUBJECT_PUBKEY_INFO_HEADER);
97 pubkey_stripped[strlen(pubkey_stripped) - strlen(NC_SUBJECT_PUBKEY_INFO_FOOTER)] = '\0';
roman466719d2023-05-05 16:14:37 +020098 } else {
99 pubkey_stripped = pubkey;
100 }
roman27215242023-03-10 14:55:00 +0100101
102 /* insert pubkey b64 */
roman466719d2023-05-05 16:14:37 +0200103 ret = lyd_new_term(new_tree, NULL, "public-key", pubkey_stripped, 0, NULL);
roman27215242023-03-10 14:55:00 +0100104 if (ret) {
105 goto cleanup;
106 }
107
roman3f9b65c2023-06-05 14:26:58 +0200108 /* get privkey identityref value */
109 privkey_identity = nc_config_new_privkey_format_to_identityref(privkey_type);
110 if (!privkey_identity) {
roman27215242023-03-10 14:55:00 +0100111 ret = 1;
roman3f9b65c2023-06-05 14:26:58 +0200112 goto cleanup;
roman27215242023-03-10 14:55:00 +0100113 }
roman466719d2023-05-05 16:14:37 +0200114
roman3f9b65c2023-06-05 14:26:58 +0200115 /* insert private key format */
116 ret = lyd_new_term(new_tree, NULL, "private-key-format", privkey_identity, 0, NULL);
roman27215242023-03-10 14:55:00 +0100117 if (ret) {
118 goto cleanup;
119 }
120
roman466719d2023-05-05 16:14:37 +0200121 if (privkey_type == NC_PRIVKEY_FORMAT_OPENSSH) {
122 /* only OpenSSH private keys have different header and footer after processing */
123 privkey_stripped = privkey + strlen(NC_OPENSSH_PRIVKEY_HEADER);
124 privkey_stripped[strlen(privkey_stripped) - strlen(NC_OPENSSH_PRIVKEY_FOOTER)] = '\0';
125 } else {
126 /* the rest share the same header and footer */
127 privkey_stripped = privkey + strlen(NC_PKCS8_PRIVKEY_HEADER);
128 privkey_stripped[strlen(privkey_stripped) - strlen(NC_PKCS8_PRIVKEY_FOOTER)] = '\0';
129 }
roman27215242023-03-10 14:55:00 +0100130
roman466719d2023-05-05 16:14:37 +0200131 ret = lyd_new_term(new_tree, NULL, "cleartext-private-key", privkey_stripped, 0, NULL);
roman27215242023-03-10 14:55:00 +0100132 if (ret) {
133 goto cleanup;
134 }
135
roman3f9b65c2023-06-05 14:26:58 +0200136 /* check if top-level container has operation and if not, add it */
137 ret = nc_config_new_check_add_operation(ctx, *config);
138 if (ret) {
139 goto cleanup;
140 }
141
roman4f9bb442023-03-24 09:05:37 +0100142 /* Add all default nodes */
143 ret = lyd_new_implicit_tree(*config, LYD_IMPLICIT_NO_STATE, NULL);
144 if (ret) {
145 goto cleanup;
146 }
147
roman27215242023-03-10 14:55:00 +0100148cleanup:
roman466719d2023-05-05 16:14:37 +0200149 free(privkey);
150 free(pubkey);
roman27215242023-03-10 14:55:00 +0100151 free(tree_path);
152 return ret;
153}
154
roman27215242023-03-10 14:55:00 +0100155static int
roman466719d2023-05-05 16:14:37 +0200156nc_server_config_new_ssh_transport_params_prep(const struct ly_ctx *ctx, const char *endpt_name,
roman27215242023-03-10 14:55:00 +0100157 struct lyd_node *config, struct lyd_node **new_tree, struct lyd_node **alg_tree)
158{
159 int ret = 0;
160 char *tree_path = NULL;
161
162 /* prepare path */
163 asprintf(&tree_path, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/"
164 "ssh/ssh-server-parameters/transport-params", endpt_name);
165 if (!tree_path) {
166 ERRMEM;
167 ret = 1;
168 goto cleanup;
169 }
170
171 /* create all the nodes in the path */
172 ret = lyd_new_path2(config, ctx, tree_path, NULL, 0, 0, LYD_NEW_PATH_UPDATE, new_tree, alg_tree);
173 if (ret) {
174 ERR(NULL, "Creating new path to transport-params failed.");
175 goto cleanup;
176 }
177
roman4f9bb442023-03-24 09:05:37 +0100178 if (!*alg_tree) {
179 /* no new nodes added */
180 ret = lyd_find_path(config, tree_path, 0, alg_tree);
181 if (ret) {
182 goto cleanup;
183 }
184 }
185
roman27215242023-03-10 14:55:00 +0100186cleanup:
187 free(tree_path);
188 return ret;
189}
190
191static int
roman466719d2023-05-05 16:14:37 +0200192nc_server_config_new_ssh_transport_params(const struct ly_ctx *ctx, NC_ALG_TYPE alg_type, int alg_count, va_list ap,
roman27215242023-03-10 14:55:00 +0100193 struct lyd_node *tree)
194{
195 int i, ret = 0;
196 char *alg, *alg_ident;
197 const char *module, *alg_path, *old_path;
198 struct lyd_node *old = NULL;
199
200 /* get the correct module with the indentity base and the path in the ietf-netconf-server module */
201 switch (alg_type) {
202 case NC_ALG_HOSTKEY:
203 module = "iana-ssh-public-key-algs";
204 alg_path = "host-key/host-key-alg";
205 old_path = "host-key";
206 break;
207 case NC_ALG_KEY_EXCHANGE:
208 module = "iana-ssh-key-exchange-algs";
209 alg_path = "key-exchange/key-exchange-alg";
210 old_path = "key-exchange";
211 break;
212 case NC_ALG_ENCRYPTION:
213 module = "iana-ssh-encryption-algs";
214 alg_path = "encryption/encryption-alg";
215 old_path = "encryption";
216 break;
217 case NC_ALG_MAC:
218 module = "iana-ssh-mac-algs";
219 alg_path = "mac/mac-alg";
220 old_path = "mac";
221 break;
222 default:
223 ret = 1;
224 ERR(NULL, "Unknown algorithm type.");
225 goto cleanup;
226 }
227
228 /* delete all older algorithms (if any) se they can be replaced by the new ones */
229 lyd_find_path(tree, old_path, 0, &old);
230 if (old) {
231 lyd_free_tree(old);
232 }
233
234 for (i = 0; i < alg_count; i++) {
235 alg = va_arg(ap, char *);
236
237 asprintf(&alg_ident, "%s:%s", module, alg);
238 if (!alg_ident) {
239 ERRMEM;
240 ret = 1;
241 goto cleanup;
242 }
243
244 /* create the leaf list */
245 ret = lyd_new_path(tree, ctx, alg_path, alg_ident, 0, NULL);
246 if (ret) {
247 ERR(NULL, "Creating new algorithm leaf-list failed.");
248 goto cleanup;
249 }
250
251 free(alg_ident);
252 }
253
254cleanup:
255 va_end(ap);
256 return ret;
257}
258
259API int
roman466719d2023-05-05 16:14:37 +0200260nc_server_config_new_ssh_host_key_algs(const struct ly_ctx *ctx, const char *endpt_name, struct lyd_node **config,
roman27215242023-03-10 14:55:00 +0100261 int alg_count, ...)
262{
263 int ret = 0;
264 struct lyd_node *new_tree, *alg_tree;
265 va_list ap;
266
roman466719d2023-05-05 16:14:37 +0200267 ret = nc_server_config_new_ssh_transport_params_prep(ctx, endpt_name, *config, &new_tree, &alg_tree);
roman27215242023-03-10 14:55:00 +0100268 if (ret) {
269 goto cleanup;
270 }
271
272 if (!*config) {
273 *config = new_tree;
274 }
275
276 va_start(ap, alg_count);
277
roman466719d2023-05-05 16:14:37 +0200278 ret = nc_server_config_new_ssh_transport_params(ctx, NC_ALG_HOSTKEY, alg_count, ap, alg_tree);
roman27215242023-03-10 14:55:00 +0100279 if (ret) {
280 goto cleanup;
281 }
282
roman3f9b65c2023-06-05 14:26:58 +0200283 /* check if top-level container has operation and if not, add it */
284 ret = nc_config_new_check_add_operation(ctx, *config);
285 if (ret) {
286 goto cleanup;
287 }
288
roman4f9bb442023-03-24 09:05:37 +0100289 /* Add all default nodes */
290 ret = lyd_new_implicit_tree(*config, LYD_IMPLICIT_NO_STATE, NULL);
291 if (ret) {
292 goto cleanup;
293 }
roman27215242023-03-10 14:55:00 +0100294cleanup:
295 return ret;
296}
297
298API int
299nc_server_config_ssh_new_key_exchange_algs(const struct ly_ctx *ctx, const char *endpt_name, struct lyd_node **config,
300 int alg_count, ...)
301{
302 int ret = 0;
303 struct lyd_node *new_tree, *alg_tree;
304 va_list ap;
305
roman466719d2023-05-05 16:14:37 +0200306 ret = nc_server_config_new_ssh_transport_params_prep(ctx, endpt_name, *config, &new_tree, &alg_tree);
roman27215242023-03-10 14:55:00 +0100307 if (ret) {
308 goto cleanup;
309 }
310
311 if (!*config) {
312 *config = new_tree;
313 }
314
315 va_start(ap, alg_count);
316
roman466719d2023-05-05 16:14:37 +0200317 ret = nc_server_config_new_ssh_transport_params(ctx, NC_ALG_KEY_EXCHANGE, alg_count, ap, alg_tree);
roman27215242023-03-10 14:55:00 +0100318 if (ret) {
319 goto cleanup;
320 }
321
roman3f9b65c2023-06-05 14:26:58 +0200322 /* check if top-level container has operation and if not, add it */
323 ret = nc_config_new_check_add_operation(ctx, *config);
324 if (ret) {
325 goto cleanup;
326 }
327
roman4f9bb442023-03-24 09:05:37 +0100328 /* Add all default nodes */
329 ret = lyd_new_implicit_tree(*config, LYD_IMPLICIT_NO_STATE, NULL);
330 if (ret) {
331 goto cleanup;
332 }
roman27215242023-03-10 14:55:00 +0100333cleanup:
334 return ret;
335}
336
337API int
roman466719d2023-05-05 16:14:37 +0200338nc_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 +0100339 int alg_count, ...)
340{
341 int ret = 0;
342 struct lyd_node *new_tree, *alg_tree;
343 va_list ap;
344
roman466719d2023-05-05 16:14:37 +0200345 ret = nc_server_config_new_ssh_transport_params_prep(ctx, endpt_name, *config, &new_tree, &alg_tree);
roman27215242023-03-10 14:55:00 +0100346 if (ret) {
347 goto cleanup;
348 }
349
350 if (!*config) {
351 *config = new_tree;
352 }
353
354 va_start(ap, alg_count);
355
roman466719d2023-05-05 16:14:37 +0200356 ret = nc_server_config_new_ssh_transport_params(ctx, NC_ALG_ENCRYPTION, alg_count, ap, alg_tree);
roman27215242023-03-10 14:55:00 +0100357 if (ret) {
358 goto cleanup;
359 }
360
roman3f9b65c2023-06-05 14:26:58 +0200361 /* check if top-level container has operation and if not, add it */
362 ret = nc_config_new_check_add_operation(ctx, *config);
363 if (ret) {
364 goto cleanup;
365 }
366
roman4f9bb442023-03-24 09:05:37 +0100367 /* Add all default nodes */
368 ret = lyd_new_implicit_tree(*config, LYD_IMPLICIT_NO_STATE, NULL);
369 if (ret) {
370 goto cleanup;
371 }
roman27215242023-03-10 14:55:00 +0100372cleanup:
373 return ret;
374}
375
376API int
377nc_server_config_ssh_new_mac_algs(const struct ly_ctx *ctx, const char *endpt_name, struct lyd_node **config,
378 int alg_count, ...)
379{
380 int ret = 0;
381 struct lyd_node *new_tree, *alg_tree;
382 va_list ap;
383
roman466719d2023-05-05 16:14:37 +0200384 ret = nc_server_config_new_ssh_transport_params_prep(ctx, endpt_name, *config, &new_tree, &alg_tree);
roman27215242023-03-10 14:55:00 +0100385 if (ret) {
386 goto cleanup;
387 }
388
389 if (!*config) {
390 *config = new_tree;
391 }
392
393 va_start(ap, alg_count);
394
roman466719d2023-05-05 16:14:37 +0200395 ret = nc_server_config_new_ssh_transport_params(ctx, NC_ALG_MAC, alg_count, ap, alg_tree);
roman27215242023-03-10 14:55:00 +0100396 if (ret) {
397 goto cleanup;
398 }
399
roman3f9b65c2023-06-05 14:26:58 +0200400 /* check if top-level container has operation and if not, add it */
401 ret = nc_config_new_check_add_operation(ctx, *config);
402 if (ret) {
403 goto cleanup;
404 }
405
roman4f9bb442023-03-24 09:05:37 +0100406 /* Add all default nodes */
407 ret = lyd_new_implicit_tree(*config, LYD_IMPLICIT_NO_STATE, NULL);
408 if (ret) {
409 goto cleanup;
410 }
roman27215242023-03-10 14:55:00 +0100411cleanup:
412 return ret;
413}
roman4f9bb442023-03-24 09:05:37 +0100414
roman4f9bb442023-03-24 09:05:37 +0100415API int
roman3f9b65c2023-06-05 14:26:58 +0200416nc_server_config_new_ssh_client_auth_pubkey(const struct ly_ctx *ctx, const char *endpt_name,
417 const char *user_name, const char *pubkey_name, const char *pubkey_path, struct lyd_node **config)
roman4f9bb442023-03-24 09:05:37 +0100418{
419 int ret = 0;
420 char *pubkey = NULL, *tree_path = NULL;
421 struct lyd_node *new_tree;
roman3f9b65c2023-06-05 14:26:58 +0200422 NC_PUBKEY_FORMAT pubkey_type;
roman4f9bb442023-03-24 09:05:37 +0100423
roman3f9b65c2023-06-05 14:26:58 +0200424 ret = nc_server_config_new_get_pubkey(pubkey_path, &pubkey, &pubkey_type);
roman4f9bb442023-03-24 09:05:37 +0100425 if (ret) {
426 goto cleanup;
427 }
428
429 /* prepare path where leaves will get inserted */
430 asprintf(&tree_path, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/"
431 "users/user[name='%s']/public-keys/local-definition/public-key[name='%s']", endpt_name, user_name, pubkey_name);
432 if (!tree_path) {
433 ERRMEM;
434 ret = 1;
435 goto cleanup;
436 }
437
438 /* create all the nodes in the path if they weren't there */
439 ret = lyd_new_path(*config, ctx, tree_path, NULL, LYD_NEW_PATH_UPDATE, &new_tree);
440 if (ret) {
441 goto cleanup;
442 }
443 if (!*config) {
444 *config = new_tree;
445 }
446
447 /* find the node where leaves will get inserted */
448 ret = lyd_find_path(*config, tree_path, 0, &new_tree);
449 if (ret) {
450 goto cleanup;
451 }
452
453 /* insert pubkey format */
roman3f9b65c2023-06-05 14:26:58 +0200454 if (pubkey_type == NC_PUBKEY_FORMAT_SSH2) {
roman4f9bb442023-03-24 09:05:37 +0100455 ret = lyd_new_term(new_tree, NULL, "public-key-format", "ietf-crypto-types:ssh-public-key-format", 0, NULL);
456 } else {
457 ret = lyd_new_term(new_tree, NULL, "public-key-format", "ietf-crypto-types:subject-public-key-info-format", 0, NULL);
458 }
459 if (ret) {
460 goto cleanup;
461 }
462
463 /* insert pubkey b64 */
464 ret = lyd_new_term(new_tree, NULL, "public-key", pubkey, 0, NULL);
465 if (ret) {
466 goto cleanup;
467 }
468
roman3f9b65c2023-06-05 14:26:58 +0200469 /* check if top-level container has operation and if not, add it */
470 ret = nc_config_new_check_add_operation(ctx, *config);
471 if (ret) {
472 goto cleanup;
473 }
474
roman4f9bb442023-03-24 09:05:37 +0100475 /* Add all default nodes */
476 ret = lyd_new_implicit_tree(*config, LYD_IMPLICIT_NO_STATE, NULL);
477 if (ret) {
478 goto cleanup;
479 }
480
481cleanup:
482 free(tree_path);
483 free(pubkey);
484 return ret;
485}
roman31820092023-03-24 15:26:21 +0100486
487API int
roman3f9b65c2023-06-05 14:26:58 +0200488nc_server_config_new_ssh_client_auth_password(const struct ly_ctx *ctx, const char *endpt_name,
489 const char *user_name, const char *password, struct lyd_node **config)
roman31820092023-03-24 15:26:21 +0100490{
491 int ret = 0;
492 char *tree_path = NULL, *hashed_pw = NULL;
493 struct lyd_node *new_tree;
494 const char *salt = "$6$idsizuippipk$";
495
496#ifdef HAVE_CRYPT_R
497 struct crypt_data cdata;
498#endif
499
500 /* prepare path where the leaf will get inserted */
501 asprintf(&tree_path, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/"
502 "users/user[name='%s']", endpt_name, user_name);
503 if (!tree_path) {
504 ERRMEM;
505 ret = 1;
506 goto cleanup;
507 }
508
509 /* create all the nodes in the path if they weren't there */
510 ret = lyd_new_path(*config, ctx, tree_path, NULL, LYD_NEW_PATH_UPDATE, &new_tree);
511 if (ret) {
512 goto cleanup;
513 }
514 if (!*config) {
515 *config = new_tree;
516 }
517
518 /* find the node where the leaf will get inserted */
519 ret = lyd_find_path(*config, tree_path, 0, &new_tree);
520 if (ret) {
521 goto cleanup;
522 }
523
524#ifdef HAVE_CRYPT_R
525 cdata.initialized = 0;
526 hashed_pw = crypt_r(password, salt, &data);
527#else
528 pthread_mutex_lock(&crypt_lock);
529 hashed_pw = crypt(password, salt);
530 pthread_mutex_unlock(&crypt_lock);
531#endif
532
533 if (!hashed_pw) {
534 ERR(NULL, "Hashing password failed.");
535 ret = 1;
536 goto cleanup;
537 }
538
539 /* insert SHA-512 hashed password */
540 ret = lyd_new_term(new_tree, NULL, "password", hashed_pw, 0, NULL);
541 if (ret) {
542 goto cleanup;
543 }
544
roman3f9b65c2023-06-05 14:26:58 +0200545 /* check if top-level container has operation and if not, add it */
546 ret = nc_config_new_check_add_operation(ctx, *config);
547 if (ret) {
548 goto cleanup;
549 }
550
roman31820092023-03-24 15:26:21 +0100551 /* Add all default nodes */
552 ret = lyd_new_implicit_tree(*config, LYD_IMPLICIT_NO_STATE, NULL);
553 if (ret) {
554 goto cleanup;
555 }
556
557cleanup:
558 free(tree_path);
559 return ret;
560}
561
562API int
roman466719d2023-05-05 16:14:37 +0200563nc_server_config_new_ssh_client_auth_none(const struct ly_ctx *ctx, const char *endpt_name,
roman31820092023-03-24 15:26:21 +0100564 const char *user_name, struct lyd_node **config)
565{
566 int ret = 0;
567 char *tree_path = NULL;
568 struct lyd_node *new_tree;
569
570 /* prepare path where the leaf will get inserted */
571 asprintf(&tree_path, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/"
572 "users/user[name='%s']", endpt_name, user_name);
573 if (!tree_path) {
574 ERRMEM;
575 ret = 1;
576 goto cleanup;
577 }
578
579 /* create all the nodes in the path if they weren't there */
580 ret = lyd_new_path(*config, ctx, tree_path, NULL, LYD_NEW_PATH_UPDATE, &new_tree);
581 if (ret) {
582 goto cleanup;
583 }
584 if (!*config) {
585 *config = new_tree;
586 }
587
588 /* find the node where the leaf will get inserted */
589 ret = lyd_find_path(*config, tree_path, 0, &new_tree);
590 if (ret) {
591 goto cleanup;
592 }
593
594 /* insert none leaf */
595 ret = lyd_new_term(new_tree, NULL, "none", NULL, 0, NULL);
596 if (ret) {
597 goto cleanup;
598 }
599
roman3f9b65c2023-06-05 14:26:58 +0200600 /* check if top-level container has operation and if not, add it */
601 ret = nc_config_new_check_add_operation(ctx, *config);
602 if (ret) {
603 goto cleanup;
604 }
605
roman31820092023-03-24 15:26:21 +0100606 /* Add all default nodes */
607 ret = lyd_new_implicit_tree(*config, LYD_IMPLICIT_NO_STATE, NULL);
608 if (ret) {
609 goto cleanup;
610 }
611
612cleanup:
613 free(tree_path);
614 return ret;
615}
616
617API int
roman3f9b65c2023-06-05 14:26:58 +0200618nc_server_config_new_ssh_client_auth_interactive(const struct ly_ctx *ctx, const char *endpt_name,
619 const char *user_name, const char *pam_config_name, const char *pam_config_dir, struct lyd_node **config)
roman31820092023-03-24 15:26:21 +0100620{
621 int ret = 0;
622 char *tree_path = NULL;
623 struct lyd_node *new_tree;
624
625 /* prepare path where the leaf will get inserted */
626 asprintf(&tree_path, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/"
627 "users/user[name='%s']/libnetconf2-netconf-server:keyboard-interactive", endpt_name, user_name);
628 if (!tree_path) {
629 ERRMEM;
630 ret = 1;
631 goto cleanup;
632 }
633
634 /* create all the nodes in the path if they weren't there */
635 ret = lyd_new_path(*config, ctx, tree_path, NULL, LYD_NEW_PATH_UPDATE, &new_tree);
636 if (ret) {
637 goto cleanup;
638 }
639 if (!*config) {
640 *config = new_tree;
641 }
642
643 /* find the node where the leaf will get inserted */
644 ret = lyd_find_path(*config, tree_path, 0, &new_tree);
645 if (ret) {
646 goto cleanup;
647 }
648
649 /* insert file-name leaf */
650 ret = lyd_new_term(new_tree, NULL, "pam-config-file-name", pam_config_name, 0, NULL);
651 if (ret) {
652 goto cleanup;
653 }
654
655 if (pam_config_dir) {
656 /* insert file-path leaf */
657 ret = lyd_new_term(new_tree, NULL, "pam-config-file-dir", pam_config_dir, 0, NULL);
658 if (ret) {
659 goto cleanup;
660 }
661 }
662
roman3f9b65c2023-06-05 14:26:58 +0200663 /* check if top-level container has operation and if not, add it */
664 ret = nc_config_new_check_add_operation(ctx, *config);
665 if (ret) {
666 goto cleanup;
667 }
668
roman31820092023-03-24 15:26:21 +0100669 /* Add all default nodes */
670 ret = lyd_new_implicit_tree(*config, LYD_IMPLICIT_NO_STATE, NULL);
671 if (ret) {
672 goto cleanup;
673 }
674
675cleanup:
676 free(tree_path);
677 return ret;
678}