blob: 8ecd7f2d90e3a90fe3e03a56630a6ff47986b28d [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
roman5cbb6532023-06-22 12:53:17 +020038nc_server_config_new_ssh_hostkey(const struct ly_ctx *ctx, const char *endpt_name, const char *hostkey_name,
39 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
roman40672412023-05-04 11:10:22 +020047 NC_CHECK_ARG_RET(NULL, privkey_path, config, ctx, endpt_name, hostkey_name, 1);
roman27215242023-03-10 14:55:00 +010048
49 /* get the keys as a string from the given files */
roman3f9b65c2023-06-05 14:26:58 +020050 ret = nc_server_config_new_get_keys(privkey_path, pubkey_path, &privkey, &pubkey, &privkey_type, &pubkey_type);
roman27215242023-03-10 14:55:00 +010051 if (ret) {
52 ERR(NULL, "Getting keys from file(s) failed.");
53 goto cleanup;
54 }
55
romand30af552023-06-16 15:18:27 +020056 /* pubkey format to str */
roman3f9b65c2023-06-05 14:26:58 +020057 if (pubkey_type == NC_PUBKEY_FORMAT_SSH2) {
romand30af552023-06-16 15:18:27 +020058 pubkey_format = "ietf-crypto-types:ssh-public-key-format";
roman27215242023-03-10 14:55:00 +010059 } else {
romand30af552023-06-16 15:18:27 +020060 pubkey_format = "ietf-crypto-types:subject-public-key-info-format";
roman27215242023-03-10 14:55:00 +010061 }
62
roman3f9b65c2023-06-05 14:26:58 +020063 /* get privkey identityref value */
romand30af552023-06-16 15:18:27 +020064 privkey_format = nc_config_new_privkey_format_to_identityref(privkey_type);
65 if (!privkey_format) {
roman27215242023-03-10 14:55:00 +010066 ret = 1;
roman3f9b65c2023-06-05 14:26:58 +020067 goto cleanup;
roman27215242023-03-10 14:55:00 +010068 }
roman466719d2023-05-05 16:14:37 +020069
roman5cbb6532023-06-22 12:53:17 +020070 ret = nc_config_new_create(ctx, config, pubkey_format, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/ssh-server-parameters/"
romand30af552023-06-16 15:18:27 +020071 "server-identity/host-key[name='%s']/public-key/inline-definition/public-key-format", endpt_name, hostkey_name);
roman27215242023-03-10 14:55:00 +010072 if (ret) {
73 goto cleanup;
74 }
75
roman5cbb6532023-06-22 12:53:17 +020076 ret = nc_config_new_create(ctx, config, pubkey, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/ssh-server-parameters/"
romand30af552023-06-16 15:18:27 +020077 "server-identity/host-key[name='%s']/public-key/inline-definition/public-key", endpt_name, hostkey_name);
roman27215242023-03-10 14:55:00 +010078 if (ret) {
79 goto cleanup;
80 }
81
roman5cbb6532023-06-22 12:53:17 +020082 ret = nc_config_new_create(ctx, config, privkey_format, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/ssh-server-parameters/"
romand30af552023-06-16 15:18:27 +020083 "server-identity/host-key[name='%s']/public-key/inline-definition/private-key-format", endpt_name, hostkey_name);
roman3f9b65c2023-06-05 14:26:58 +020084 if (ret) {
85 goto cleanup;
86 }
87
roman5cbb6532023-06-22 12:53:17 +020088 ret = nc_config_new_create(ctx, config, privkey, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/ssh-server-parameters/"
romand30af552023-06-16 15:18:27 +020089 "server-identity/host-key[name='%s']/public-key/inline-definition/cleartext-private-key", endpt_name, hostkey_name);
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
roman27215242023-03-10 14:55:00 +0100100static int
roman466719d2023-05-05 16:14:37 +0200101nc_server_config_new_ssh_transport_params_prep(const struct ly_ctx *ctx, const char *endpt_name,
roman27215242023-03-10 14:55:00 +0100102 struct lyd_node *config, struct lyd_node **new_tree, struct lyd_node **alg_tree)
103{
104 int ret = 0;
105 char *tree_path = NULL;
106
107 /* prepare path */
108 asprintf(&tree_path, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/"
109 "ssh/ssh-server-parameters/transport-params", endpt_name);
110 if (!tree_path) {
111 ERRMEM;
112 ret = 1;
113 goto cleanup;
114 }
115
116 /* create all the nodes in the path */
117 ret = lyd_new_path2(config, ctx, tree_path, NULL, 0, 0, LYD_NEW_PATH_UPDATE, new_tree, alg_tree);
118 if (ret) {
119 ERR(NULL, "Creating new path to transport-params failed.");
120 goto cleanup;
121 }
122
roman4f9bb442023-03-24 09:05:37 +0100123 if (!*alg_tree) {
124 /* no new nodes added */
125 ret = lyd_find_path(config, tree_path, 0, alg_tree);
126 if (ret) {
127 goto cleanup;
128 }
129 }
130
roman27215242023-03-10 14:55:00 +0100131cleanup:
132 free(tree_path);
133 return ret;
134}
135
136static int
roman466719d2023-05-05 16:14:37 +0200137nc_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 +0100138 struct lyd_node *tree)
139{
140 int i, ret = 0;
141 char *alg, *alg_ident;
142 const char *module, *alg_path, *old_path;
143 struct lyd_node *old = NULL;
144
145 /* get the correct module with the indentity base and the path in the ietf-netconf-server module */
146 switch (alg_type) {
147 case NC_ALG_HOSTKEY:
148 module = "iana-ssh-public-key-algs";
149 alg_path = "host-key/host-key-alg";
150 old_path = "host-key";
151 break;
152 case NC_ALG_KEY_EXCHANGE:
153 module = "iana-ssh-key-exchange-algs";
154 alg_path = "key-exchange/key-exchange-alg";
155 old_path = "key-exchange";
156 break;
157 case NC_ALG_ENCRYPTION:
158 module = "iana-ssh-encryption-algs";
159 alg_path = "encryption/encryption-alg";
160 old_path = "encryption";
161 break;
162 case NC_ALG_MAC:
163 module = "iana-ssh-mac-algs";
164 alg_path = "mac/mac-alg";
165 old_path = "mac";
166 break;
167 default:
168 ret = 1;
169 ERR(NULL, "Unknown algorithm type.");
170 goto cleanup;
171 }
172
173 /* delete all older algorithms (if any) se they can be replaced by the new ones */
174 lyd_find_path(tree, old_path, 0, &old);
175 if (old) {
176 lyd_free_tree(old);
177 }
178
179 for (i = 0; i < alg_count; i++) {
180 alg = va_arg(ap, char *);
181
182 asprintf(&alg_ident, "%s:%s", module, alg);
183 if (!alg_ident) {
184 ERRMEM;
185 ret = 1;
186 goto cleanup;
187 }
188
189 /* create the leaf list */
190 ret = lyd_new_path(tree, ctx, alg_path, alg_ident, 0, NULL);
191 if (ret) {
192 ERR(NULL, "Creating new algorithm leaf-list failed.");
193 goto cleanup;
194 }
195
196 free(alg_ident);
197 }
198
199cleanup:
200 va_end(ap);
201 return ret;
202}
203
204API int
roman466719d2023-05-05 16:14:37 +0200205nc_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 +0100206 int alg_count, ...)
207{
208 int ret = 0;
209 struct lyd_node *new_tree, *alg_tree;
210 va_list ap;
211
roman466719d2023-05-05 16:14:37 +0200212 ret = nc_server_config_new_ssh_transport_params_prep(ctx, endpt_name, *config, &new_tree, &alg_tree);
roman27215242023-03-10 14:55:00 +0100213 if (ret) {
214 goto cleanup;
215 }
216
217 if (!*config) {
218 *config = new_tree;
219 }
220
221 va_start(ap, alg_count);
222
roman466719d2023-05-05 16:14:37 +0200223 ret = nc_server_config_new_ssh_transport_params(ctx, NC_ALG_HOSTKEY, alg_count, ap, alg_tree);
roman27215242023-03-10 14:55:00 +0100224 if (ret) {
225 goto cleanup;
226 }
227
roman4f9bb442023-03-24 09:05:37 +0100228 /* Add all default nodes */
229 ret = lyd_new_implicit_tree(*config, LYD_IMPLICIT_NO_STATE, NULL);
230 if (ret) {
231 goto cleanup;
232 }
roman27215242023-03-10 14:55:00 +0100233cleanup:
234 return ret;
235}
236
237API int
238nc_server_config_ssh_new_key_exchange_algs(const struct ly_ctx *ctx, const char *endpt_name, struct lyd_node **config,
239 int alg_count, ...)
240{
241 int ret = 0;
242 struct lyd_node *new_tree, *alg_tree;
243 va_list ap;
244
roman466719d2023-05-05 16:14:37 +0200245 ret = nc_server_config_new_ssh_transport_params_prep(ctx, endpt_name, *config, &new_tree, &alg_tree);
roman27215242023-03-10 14:55:00 +0100246 if (ret) {
247 goto cleanup;
248 }
249
250 if (!*config) {
251 *config = new_tree;
252 }
253
254 va_start(ap, alg_count);
255
roman466719d2023-05-05 16:14:37 +0200256 ret = nc_server_config_new_ssh_transport_params(ctx, NC_ALG_KEY_EXCHANGE, alg_count, ap, alg_tree);
roman27215242023-03-10 14:55:00 +0100257 if (ret) {
258 goto cleanup;
259 }
260
roman4f9bb442023-03-24 09:05:37 +0100261 /* Add all default nodes */
262 ret = lyd_new_implicit_tree(*config, LYD_IMPLICIT_NO_STATE, NULL);
263 if (ret) {
264 goto cleanup;
265 }
roman27215242023-03-10 14:55:00 +0100266cleanup:
267 return ret;
268}
269
270API int
roman466719d2023-05-05 16:14:37 +0200271nc_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 +0100272 int alg_count, ...)
273{
274 int ret = 0;
275 struct lyd_node *new_tree, *alg_tree;
276 va_list ap;
277
roman466719d2023-05-05 16:14:37 +0200278 ret = nc_server_config_new_ssh_transport_params_prep(ctx, endpt_name, *config, &new_tree, &alg_tree);
roman27215242023-03-10 14:55:00 +0100279 if (ret) {
280 goto cleanup;
281 }
282
283 if (!*config) {
284 *config = new_tree;
285 }
286
287 va_start(ap, alg_count);
288
roman466719d2023-05-05 16:14:37 +0200289 ret = nc_server_config_new_ssh_transport_params(ctx, NC_ALG_ENCRYPTION, alg_count, ap, alg_tree);
roman27215242023-03-10 14:55:00 +0100290 if (ret) {
291 goto cleanup;
292 }
293
roman4f9bb442023-03-24 09:05:37 +0100294 /* Add all default nodes */
295 ret = lyd_new_implicit_tree(*config, LYD_IMPLICIT_NO_STATE, NULL);
296 if (ret) {
297 goto cleanup;
298 }
roman27215242023-03-10 14:55:00 +0100299cleanup:
300 return ret;
301}
302
303API int
304nc_server_config_ssh_new_mac_algs(const struct ly_ctx *ctx, const char *endpt_name, struct lyd_node **config,
305 int alg_count, ...)
306{
307 int ret = 0;
308 struct lyd_node *new_tree, *alg_tree;
309 va_list ap;
310
roman466719d2023-05-05 16:14:37 +0200311 ret = nc_server_config_new_ssh_transport_params_prep(ctx, endpt_name, *config, &new_tree, &alg_tree);
roman27215242023-03-10 14:55:00 +0100312 if (ret) {
313 goto cleanup;
314 }
315
316 if (!*config) {
317 *config = new_tree;
318 }
319
320 va_start(ap, alg_count);
321
roman466719d2023-05-05 16:14:37 +0200322 ret = nc_server_config_new_ssh_transport_params(ctx, NC_ALG_MAC, alg_count, ap, alg_tree);
roman27215242023-03-10 14:55:00 +0100323 if (ret) {
324 goto cleanup;
325 }
326
roman4f9bb442023-03-24 09:05:37 +0100327 /* Add all default nodes */
328 ret = lyd_new_implicit_tree(*config, LYD_IMPLICIT_NO_STATE, NULL);
329 if (ret) {
330 goto cleanup;
331 }
roman27215242023-03-10 14:55:00 +0100332cleanup:
333 return ret;
334}
roman4f9bb442023-03-24 09:05:37 +0100335
roman4f9bb442023-03-24 09:05:37 +0100336API int
roman3f9b65c2023-06-05 14:26:58 +0200337nc_server_config_new_ssh_client_auth_pubkey(const struct ly_ctx *ctx, const char *endpt_name,
338 const char *user_name, const char *pubkey_name, const char *pubkey_path, struct lyd_node **config)
roman4f9bb442023-03-24 09:05:37 +0100339{
340 int ret = 0;
romand30af552023-06-16 15:18:27 +0200341 char *pubkey = NULL;
roman3f9b65c2023-06-05 14:26:58 +0200342 NC_PUBKEY_FORMAT pubkey_type;
romand30af552023-06-16 15:18:27 +0200343 const char *pubkey_format;
roman4f9bb442023-03-24 09:05:37 +0100344
romand30af552023-06-16 15:18:27 +0200345 /* get pubkey data */
roman3f9b65c2023-06-05 14:26:58 +0200346 ret = nc_server_config_new_get_pubkey(pubkey_path, &pubkey, &pubkey_type);
roman4f9bb442023-03-24 09:05:37 +0100347 if (ret) {
348 goto cleanup;
349 }
350
romand30af552023-06-16 15:18:27 +0200351 /* get pubkey format */
roman3f9b65c2023-06-05 14:26:58 +0200352 if (pubkey_type == NC_PUBKEY_FORMAT_SSH2) {
romand30af552023-06-16 15:18:27 +0200353 pubkey_format = "ietf-crypto-types:ssh-public-key-format";
roman4f9bb442023-03-24 09:05:37 +0100354 } else {
romand30af552023-06-16 15:18:27 +0200355 pubkey_format = "ietf-crypto-types:subject-public-key-info-format";
roman4f9bb442023-03-24 09:05:37 +0100356 }
romand30af552023-06-16 15:18:27 +0200357
roman5cbb6532023-06-22 12:53:17 +0200358 ret = nc_config_new_create(ctx, config, pubkey_format, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/"
romand30af552023-06-16 15:18:27 +0200359 "users/user[name='%s']/public-keys/inline-definition/public-key[name='%s']/public-key-format", endpt_name, user_name, pubkey_name);
roman4f9bb442023-03-24 09:05:37 +0100360 if (ret) {
361 goto cleanup;
362 }
363
roman5cbb6532023-06-22 12:53:17 +0200364 ret = nc_config_new_create(ctx, config, pubkey, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/"
romand30af552023-06-16 15:18:27 +0200365 "users/user[name='%s']/public-keys/inline-definition/public-key[name='%s']/public-key", endpt_name, user_name, pubkey_name);
roman4f9bb442023-03-24 09:05:37 +0100366 if (ret) {
367 goto cleanup;
368 }
369
370cleanup:
roman4f9bb442023-03-24 09:05:37 +0100371 free(pubkey);
372 return ret;
373}
roman31820092023-03-24 15:26:21 +0100374
375API int
roman3f9b65c2023-06-05 14:26:58 +0200376nc_server_config_new_ssh_client_auth_password(const struct ly_ctx *ctx, const char *endpt_name,
377 const char *user_name, const char *password, struct lyd_node **config)
roman31820092023-03-24 15:26:21 +0100378{
379 int ret = 0;
romand30af552023-06-16 15:18:27 +0200380 char *hashed_pw = NULL;
roman31820092023-03-24 15:26:21 +0100381 const char *salt = "$6$idsizuippipk$";
382
383#ifdef HAVE_CRYPT_R
384 struct crypt_data cdata;
385#endif
386
roman31820092023-03-24 15:26:21 +0100387#ifdef HAVE_CRYPT_R
388 cdata.initialized = 0;
389 hashed_pw = crypt_r(password, salt, &data);
390#else
391 pthread_mutex_lock(&crypt_lock);
392 hashed_pw = crypt(password, salt);
393 pthread_mutex_unlock(&crypt_lock);
394#endif
395
396 if (!hashed_pw) {
397 ERR(NULL, "Hashing password failed.");
398 ret = 1;
399 goto cleanup;
400 }
401
roman5cbb6532023-06-22 12:53:17 +0200402 ret = nc_config_new_create(ctx, config, hashed_pw, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/"
romand30af552023-06-16 15:18:27 +0200403 "users/user[name='%s']/password", endpt_name, user_name);
roman31820092023-03-24 15:26:21 +0100404 if (ret) {
405 goto cleanup;
406 }
407
408cleanup:
roman31820092023-03-24 15:26:21 +0100409 return ret;
410}
411
412API int
roman466719d2023-05-05 16:14:37 +0200413nc_server_config_new_ssh_client_auth_none(const struct ly_ctx *ctx, const char *endpt_name,
roman31820092023-03-24 15:26:21 +0100414 const char *user_name, struct lyd_node **config)
415{
416 int ret = 0;
roman31820092023-03-24 15:26:21 +0100417
roman5cbb6532023-06-22 12:53:17 +0200418 ret = nc_config_new_create(ctx, config, NULL, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/"
romand30af552023-06-16 15:18:27 +0200419 "users/user[name='%s']/none", endpt_name, user_name);
roman31820092023-03-24 15:26:21 +0100420 if (ret) {
421 goto cleanup;
422 }
423
424cleanup:
roman31820092023-03-24 15:26:21 +0100425 return ret;
426}
427
428API int
roman3f9b65c2023-06-05 14:26:58 +0200429nc_server_config_new_ssh_client_auth_interactive(const struct ly_ctx *ctx, const char *endpt_name,
430 const char *user_name, const char *pam_config_name, const char *pam_config_dir, struct lyd_node **config)
roman31820092023-03-24 15:26:21 +0100431{
432 int ret = 0;
roman31820092023-03-24 15:26:21 +0100433
roman5cbb6532023-06-22 12:53:17 +0200434 ret = nc_config_new_create(ctx, config, pam_config_name, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/"
romand30af552023-06-16 15:18:27 +0200435 "users/user[name='%s']/libnetconf2-netconf-server:keyboard-interactive/pam-config-file-name", endpt_name, user_name);
roman31820092023-03-24 15:26:21 +0100436 if (ret) {
437 goto cleanup;
438 }
439
roman5cbb6532023-06-22 12:53:17 +0200440 ret = nc_config_new_create(ctx, config, pam_config_dir, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/"
romand30af552023-06-16 15:18:27 +0200441 "users/user[name='%s']/libnetconf2-netconf-server:keyboard-interactive/pam-config-file-dir", endpt_name, user_name);
roman31820092023-03-24 15:26:21 +0100442 if (ret) {
443 goto cleanup;
444 }
445
446cleanup:
roman31820092023-03-24 15:26:21 +0100447 return ret;
448}
roman2e797ef2023-06-19 10:47:49 +0200449
450API int
451nc_config_new_ssh_endpoint_client_reference(const struct ly_ctx *ctx, const char *endpt_name, const char *referenced_endpt, struct lyd_node **config)
452{
roman5cbb6532023-06-22 12:53:17 +0200453 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 +0200454 "client-authentication/libnetconf2-netconf-server:endpoint-client-auth", endpt_name);
455}
roman5cbb6532023-06-22 12:53:17 +0200456
457API int
458nc_server_config_new_ssh_ch_hostkey(const struct ly_ctx *ctx, const char *ch_client_name, const char *endpt_name,
459 const char *hostkey_name, const char *privkey_path, const char *pubkey_path, struct lyd_node **config)
460{
461 int ret = 0;
462 char *pubkey = NULL, *privkey = NULL;
463 NC_PRIVKEY_FORMAT privkey_type;
464 NC_PUBKEY_FORMAT pubkey_type;
465 const char *privkey_format, *pubkey_format;
466
467 NC_CHECK_ARG_RET(NULL, privkey_path, config, ctx, endpt_name, hostkey_name, 1);
468
469 /* get the keys as a string from the given files */
470 ret = nc_server_config_new_get_keys(privkey_path, pubkey_path, &privkey, &pubkey, &privkey_type, &pubkey_type);
471 if (ret) {
472 ERR(NULL, "Getting keys from file(s) failed.");
473 goto cleanup;
474 }
475
476 /* pubkey format to str */
477 if (pubkey_type == NC_PUBKEY_FORMAT_SSH2) {
478 pubkey_format = "ietf-crypto-types:ssh-public-key-format";
479 } else {
480 pubkey_format = "ietf-crypto-types:subject-public-key-info-format";
481 }
482
483 /* get privkey identityref value */
484 privkey_format = nc_config_new_privkey_format_to_identityref(privkey_type);
485 if (!privkey_format) {
486 ret = 1;
487 goto cleanup;
488 }
489
490 ret = nc_config_new_create(ctx, config, pubkey_format, "/ietf-netconf-server:netconf-server/call-home/"
491 "netconf-client[name='%s']/endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/server-identity/"
492 "host-key[name='%s']/public-key/inline-definition/public-key-format", ch_client_name, endpt_name, hostkey_name);
493 if (ret) {
494 goto cleanup;
495 }
496
497 ret = nc_config_new_create(ctx, config, pubkey, "/ietf-netconf-server:netconf-server/call-home/"
498 "netconf-client[name='%s']/endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/server-identity/"
499 "host-key[name='%s']/public-key/inline-definition/public-key", ch_client_name, endpt_name, hostkey_name);
500 if (ret) {
501 goto cleanup;
502 }
503
504 ret = nc_config_new_create(ctx, config, privkey_format, "/ietf-netconf-server:netconf-server/call-home/"
505 "netconf-client[name='%s']/endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/server-identity/"
506 "host-key[name='%s']/public-key/inline-definition/private-key-format", ch_client_name, endpt_name, hostkey_name);
507 if (ret) {
508 goto cleanup;
509 }
510
511 ret = nc_config_new_create(ctx, config, privkey, "/ietf-netconf-server:netconf-server/call-home/"
512 "netconf-client[name='%s']/endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/server-identity/"
513 "host-key[name='%s']/public-key/inline-definition/cleartext-private-key", ch_client_name, endpt_name, hostkey_name);
514 if (ret) {
515 goto cleanup;
516 }
517
518cleanup:
519 free(privkey);
520 free(pubkey);
521 return ret;
522}
523
524API int
525nc_server_config_new_ssh_ch_client_auth_pubkey(const struct ly_ctx *ctx, const char *ch_client_name, const char *endpt_name,
526 const char *user_name, const char *pubkey_name, const char *pubkey_path, struct lyd_node **config)
527{
528 int ret = 0;
529 char *pubkey = NULL;
530 NC_PUBKEY_FORMAT pubkey_type;
531 const char *pubkey_format;
532
533 /* get pubkey data */
534 ret = nc_server_config_new_get_pubkey(pubkey_path, &pubkey, &pubkey_type);
535 if (ret) {
536 goto cleanup;
537 }
538
539 /* get pubkey format */
540 if (pubkey_type == NC_PUBKEY_FORMAT_SSH2) {
541 pubkey_format = "ietf-crypto-types:ssh-public-key-format";
542 } else {
543 pubkey_format = "ietf-crypto-types:subject-public-key-info-format";
544 }
545
546 ret = nc_config_new_create(ctx, config, pubkey_format, "/ietf-netconf-server:netconf-server/call-home/"
547 "netconf-client[name='%s']/endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/"
548 "users/user[name='%s']/public-keys/inline-definition/public-key[name='%s']/"
549 "public-key-format", ch_client_name, endpt_name, user_name, pubkey_name);
550 if (ret) {
551 goto cleanup;
552 }
553
554 ret = nc_config_new_create(ctx, config, pubkey, "/ietf-netconf-server:netconf-server/call-home/"
555 "netconf-client[name='%s']/endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/"
556 "users/user[name='%s']/public-keys/inline-definition/public-key[name='%s']/"
557 "public-key", ch_client_name, endpt_name, user_name, pubkey_name);
558 if (ret) {
559 goto cleanup;
560 }
561
562cleanup:
563 free(pubkey);
564 return ret;
565}
roman142718b2023-06-29 09:15:29 +0200566
567API int
568nc_server_config_new_ssh_keystore_reference(const struct ly_ctx *ctx, const char *endpt_name, const char *hostkey_name,
569 const char *keystore_reference, struct lyd_node **config)
570{
571 NC_CHECK_ARG_RET(NULL, ctx, endpt_name, hostkey_name, keystore_reference, config, 1);
572
573 return nc_config_new_create(ctx, config, keystore_reference, "/ietf-netconf-server:netconf-server/listen/"
roman4cb8bb12023-06-29 09:16:46 +0200574 "endpoint[name='%s']/ssh/ssh-server-parameters/server-identity/host-key[name='%s']/public-key/"
575 "keystore-reference", endpt_name, hostkey_name);
roman142718b2023-06-29 09:15:29 +0200576}
577
578API int
579nc_server_config_new_ssh_truststore_reference(const struct ly_ctx *ctx, const char *endpt_name, const char *user_name,
580 const char *truststore_reference, struct lyd_node **config)
581{
582 NC_CHECK_ARG_RET(NULL, ctx, endpt_name, user_name, truststore_reference, config, 1);
583
584 return nc_config_new_create(ctx, config, truststore_reference, "/ietf-netconf-server:netconf-server/listen/"
roman4cb8bb12023-06-29 09:16:46 +0200585 "endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/users/user[name='%s']/public-keys/"
586 "truststore-reference", endpt_name, user_name);
roman142718b2023-06-29 09:15:29 +0200587}