Skip to content

Commit a9ec336

Browse files
romanmichalvasko
authored andcommitted
session server ssh UPDATE add local pubkey auth
1 parent 82ebf63 commit a9ec336

File tree

8 files changed

+551
-9
lines changed

8 files changed

+551
-9
lines changed

modules/[email protected]

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,17 @@ module libnetconf2-netconf-server {
260260
}
261261
}
262262

263+
grouping system-auth-public-keys-grouping {
264+
description
265+
"Grouping for using the system configured keys in the SSH public key authentication method.";
266+
267+
container use-system-keys {
268+
presence "Indicates that the given user will be authenticated using the system's configured public keys.";
269+
description
270+
"Authentication is done using the system's mechanisms.";
271+
}
272+
}
273+
263274
grouping keyboard-interactive-grouping {
264275
description
265276
"Grouping for the SSH Keyboard interactive authentication method.";
@@ -378,6 +389,20 @@ module libnetconf2-netconf-server {
378389
uses ssh-authentication-params-grouping;
379390
}
380391

392+
augment "/ncs:netconf-server/ncs:listen/ncs:endpoint/ncs:transport/ncs:ssh/ncs:ssh/ncs:ssh-server-parameters" +
393+
"/ncs:client-authentication/ncs:users/ncs:user/ncs:public-keys/ncs:inline-or-truststore" {
394+
case system-auth-public-keys {
395+
uses system-auth-public-keys-grouping;
396+
}
397+
}
398+
399+
augment "/ncs:netconf-server/ncs:call-home/ncs:netconf-client/ncs:endpoints/ncs:endpoint/ncs:transport/ncs:ssh" +
400+
"/ncs:ssh/ncs:ssh-server-parameters/ncs:client-authentication/ncs:users/ncs:user/ncs:public-keys/ncs:inline-or-truststore" {
401+
case system-auth-public-keys {
402+
uses system-auth-public-keys-grouping;
403+
}
404+
}
405+
381406
augment "/ncs:netconf-server/ncs:listen/ncs:endpoint/ncs:transport/ncs:ssh" +
382407
"/ncs:ssh/ncs:ssh-server-parameters/ncs:client-authentication/ncs:users/ncs:user" {
383408
uses keyboard-interactive-grouping;

src/server_config.c

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -652,7 +652,7 @@ nc_server_config_del_auth_client(struct nc_server_ssh_opts *opts, struct nc_auth
652652
for (i = 0; i < pubkey_count; i++) {
653653
nc_server_config_del_auth_client_pubkey(auth_client, &auth_client->pubkeys[i]);
654654
}
655-
} else {
655+
} else if (auth_client->store == NC_STORE_TRUSTSTORE) {
656656
free(auth_client->ts_ref);
657657
}
658658

@@ -797,7 +797,7 @@ nc_server_config_del_certs(struct nc_cert_grouping *certs_grp)
797797
}
798798
free(certs_grp->certs);
799799
certs_grp->certs = NULL;
800-
} else {
800+
} else if (certs_grp->store == NC_STORE_TRUSTSTORE) {
801801
free(certs_grp->ts_ref);
802802
}
803803
}
@@ -862,7 +862,7 @@ nc_server_config_del_tls_opts(struct nc_bind *bind, struct nc_server_tls_opts *o
862862
free(opts->pubkey_data);
863863
free(opts->privkey_data);
864864
free(opts->cert_data);
865-
} else {
865+
} else if (opts->store == NC_STORE_KEYSTORE) {
866866
free(opts->key_ref);
867867
free(opts->cert_ref);
868868
}
@@ -2309,6 +2309,38 @@ nc_server_config_truststore_reference(const struct lyd_node *node, NC_OPERATION
23092309
return ret;
23102310
}
23112311

2312+
static int
2313+
nc_server_config_use_system_keys(const struct lyd_node *node, NC_OPERATION op)
2314+
{
2315+
int ret = 0;
2316+
struct nc_auth_client *auth_client;
2317+
struct nc_ch_client *ch_client = NULL;
2318+
2319+
assert(!strcmp(LYD_NAME(node), "use-system-keys"));
2320+
2321+
/* LOCK */
2322+
if (is_ch(node) && nc_server_config_get_ch_client_with_lock(node, &ch_client)) {
2323+
/* to avoid unlock on fail */
2324+
return 1;
2325+
}
2326+
2327+
if (nc_server_config_get_auth_client(node, ch_client, &auth_client)) {
2328+
ret = 1;
2329+
goto cleanup;
2330+
}
2331+
2332+
if (op == NC_OP_CREATE) {
2333+
auth_client->store = NC_STORE_SYSTEM;
2334+
}
2335+
2336+
cleanup:
2337+
if (is_ch(node)) {
2338+
/* UNLOCK */
2339+
nc_ch_client_unlock(ch_client);
2340+
}
2341+
return ret;
2342+
}
2343+
23122344
/* leaf */
23132345
static int
23142346
nc_server_config_password(const struct lyd_node *node, NC_OPERATION op)
@@ -3917,6 +3949,8 @@ nc_server_config_parse_netconf_server(const struct lyd_node *node, NC_OPERATION
39173949
ret = nc_server_config_auth_timeout(node, op);
39183950
} else if (!strcmp(name, "truststore-reference")) {
39193951
ret = nc_server_config_truststore_reference(node, op);
3952+
} else if (!strcmp(name, "use-system-keys")) {
3953+
ret = nc_server_config_use_system_keys(node, op);
39203954
} else if (!strcmp(name, "password")) {
39213955
ret = nc_server_config_password(node, op);
39223956
} else if (!strcmp(name, "use-system-auth")) {

src/server_config.h

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,34 @@ int nc_server_config_add_ssh_user_pubkey(const struct ly_ctx *ctx, const char *e
353353
int nc_server_config_del_ssh_user_pubkey(const char *endpt_name, const char *user_name,
354354
const char *pubkey_name, struct lyd_node **config);
355355

356+
/**
357+
* @brief Creates new YANG configuration data nodes for an SSH user that will use system's authorized_keys to authenticate.
358+
*
359+
* The path to the authorized_keys file must be configured to successfully
360+
* authenticate, see ::nc_server_ssh_set_authkey_path_format().
361+
*
362+
* @param[in] ctx libyang context.
363+
* @param[in] endpt_name Arbitrary identifier of the endpoint.
364+
* If an endpoint with this identifier already exists, its user might be changed.
365+
* @param[in] user_name Arbitrary identifier of the user.
366+
* If an user with this identifier already exists, its contents will be changed.
367+
* @param[in,out] config Configuration YANG data tree. If *config is NULL, it will be created.
368+
* Otherwise the new YANG data will be added to the previous data and may override it.
369+
* @return 0 on success, non-zero otherwise.
370+
*/
371+
int nc_server_config_add_ssh_user_authkey(const struct ly_ctx *ctx, const char *endpt_name,
372+
const char *user_name, struct lyd_node **config);
373+
374+
/**
375+
* @brief Deletes an SSH user's authorized_keys method from the YANG data.
376+
*
377+
* @param[in] endpt_name Identifier of an existing endpoint.
378+
* @param[in] user_name Identifier of an existing user on the given endpoint.
379+
* @param[in,out] config Modified configuration YANG data tree.
380+
* @return 0 on success, non-zero otherwise.
381+
*/
382+
int nc_server_config_del_ssh_user_authkey(const char *endpt_name, const char *user_name, struct lyd_node **config);
383+
356384
/**
357385
* @brief Creates new YANG configuration data nodes for an SSH user's password authentication method.
358386
*
@@ -993,6 +1021,38 @@ int nc_server_config_add_ch_ssh_user_pubkey(const struct ly_ctx *ctx, const char
9931021
int nc_server_config_del_ch_ssh_user_pubkey(const char *client_name, const char *endpt_name,
9941022
const char *user_name, const char *pubkey_name, struct lyd_node **config);
9951023

1024+
/**
1025+
* @brief Creates new YANG configuration data nodes for a Call Home SSH user that will use system's authorized_keys to authenticate.
1026+
*
1027+
* The path to the authorized_keys file must be configured to successfully
1028+
* authenticate, see ::nc_server_ssh_set_authkey_path_format().
1029+
*
1030+
* @param[in] ctx libyang context.
1031+
* @param[in] client_name Arbitrary identifier of the Call Home client.
1032+
* If a Call Home client with this identifier already exists, its contents will be changed.
1033+
* @param[in] endpt_name Arbitrary identifier of the client's endpoint.
1034+
* If the client's endpoint with this identifier already exists, its contents will be changed.
1035+
* @param[in] user_name Arbitrary identifier of the endpoint's user.
1036+
* If the endpoint's user with this identifier already exists, its contents will be changed.
1037+
* @param[in,out] config Configuration YANG data tree. If *config is NULL, it will be created.
1038+
* Otherwise the new YANG data will be added to the previous data and may override it.
1039+
* @return 0 on success, non-zero otherwise.
1040+
*/
1041+
int nc_server_config_add_ch_ssh_user_authkey(const struct ly_ctx *ctx, const char *client_name,
1042+
const char *endpt_name, const char *user_name, struct lyd_node **config);
1043+
1044+
/**
1045+
* @brief Deletes a Call Home SSH user's authorized_keys method from the YANG data.
1046+
*
1047+
* @param[in] client_name Identifier of an existing Call Home client.
1048+
* @param[in] endpt_name Identifier of an existing endpoint that belongs to the given CH client.
1049+
* @param[in] user_name Identifier of an existing user on the given endpoint.
1050+
* @param[in,out] config Modified configuration YANG data tree.
1051+
* @return 0 on success, non-zero otherwise.
1052+
*/
1053+
int nc_server_config_ch_del_ssh_user_authkey(const char *client_name, const char *endpt_name,
1054+
const char *user_name, struct lyd_node **config);
1055+
9961056
/**
9971057
* @brief Creates new YANG data nodes for a Call Home SSH user's password authentication method.
9981058
*

src/server_config_util_ssh.c

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,14 @@ nc_server_config_add_ssh_user_pubkey(const struct ly_ctx *ctx, const char *endpt
303303
goto cleanup;
304304
}
305305

306+
/* delete use system auth if present */
307+
ret = nc_server_config_check_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/"
308+
"ssh-server-parameters/client-authentication/users/user[name='%s']/public-keys/"
309+
"libnetconf2-netconf-server:use-system-keys", endpt_name, user_name);
310+
if (ret) {
311+
goto cleanup;
312+
}
313+
306314
cleanup:
307315
free(path);
308316
return ret;
@@ -337,6 +345,15 @@ nc_server_config_add_ch_ssh_user_pubkey(const struct ly_ctx *ctx, const char *cl
337345
goto cleanup;
338346
}
339347

348+
/* delete use system auth if present */
349+
ret = nc_server_config_check_delete(config, "/ietf-netconf-server:netconf-server/call-home/"
350+
"netconf-client[name='%s']/endpoints/endpoint[name='%s']/ssh/"
351+
"ssh-server-parameters/client-authentication/users/user[name='%s']/public-keys/"
352+
"libnetconf2-netconf-server:use-system-keys", client_name, endpt_name, user_name);
353+
if (ret) {
354+
goto cleanup;
355+
}
356+
340357
cleanup:
341358
free(path);
342359
return ret;
@@ -378,6 +395,106 @@ nc_server_config_del_ch_ssh_user_pubkey(const char *client_name, const char *end
378395
}
379396
}
380397

398+
API int
399+
nc_server_config_add_ssh_user_authkey(const struct ly_ctx *ctx, const char *endpt_name,
400+
const char *user_name, struct lyd_node **config)
401+
{
402+
int ret = 0;
403+
char *path = NULL;
404+
405+
NC_CHECK_ARG_RET(NULL, ctx, endpt_name, user_name, config, 1);
406+
407+
ret = asprintf(&path, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/ssh-server-parameters/"
408+
"client-authentication/users/user[name='%s']/public-keys", endpt_name, user_name);
409+
NC_CHECK_ERRMEM_GOTO(ret == -1, path = NULL; ret = 1, cleanup);
410+
411+
ret = nc_server_config_append(ctx, path, "libnetconf2-netconf-server:use-system-keys", NULL, config);
412+
if (ret) {
413+
goto cleanup;
414+
}
415+
416+
/* delete inline definition nodes if present */
417+
ret = nc_server_config_check_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/"
418+
"ssh-server-parameters/client-authentication/users/user[name='%s']/public-keys/inline-definition",
419+
endpt_name, user_name);
420+
if (ret) {
421+
goto cleanup;
422+
}
423+
424+
/* delete truststore reference if present */
425+
ret = nc_server_config_check_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/"
426+
"ssh-server-parameters/client-authentication/users/user[name='%s']/public-keys/truststore-reference",
427+
endpt_name, user_name);
428+
if (ret) {
429+
goto cleanup;
430+
}
431+
432+
cleanup:
433+
free(path);
434+
return ret;
435+
}
436+
437+
API int
438+
nc_server_config_add_ch_ssh_user_authkey(const struct ly_ctx *ctx, const char *client_name,
439+
const char *endpt_name, const char *user_name, struct lyd_node **config)
440+
{
441+
int ret = 0;
442+
char *path = NULL;
443+
444+
NC_CHECK_ARG_RET(NULL, ctx, client_name, endpt_name, user_name, config, 1);
445+
446+
ret = asprintf(&path, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/endpoints/"
447+
"endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/users"
448+
"/user[name='%s']/public-keys", client_name, endpt_name, user_name);
449+
NC_CHECK_ERRMEM_GOTO(ret == -1, path = NULL; ret = 1, cleanup);
450+
451+
ret = nc_server_config_append(ctx, path, "libnetconf2-netconf-server:use-system-keys", NULL, config);
452+
if (ret) {
453+
goto cleanup;
454+
}
455+
456+
/* delete inline definition nodes if present */
457+
ret = nc_server_config_check_delete(config, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/"
458+
"endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/users/user[name='%s']/"
459+
"public-keys/inline-definition", client_name, endpt_name, user_name);
460+
if (ret) {
461+
goto cleanup;
462+
}
463+
464+
/* delete truststore reference if present */
465+
ret = nc_server_config_check_delete(config, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/"
466+
"endpoints/endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/users/user[name='%s']/"
467+
"public-keys/truststore-reference", client_name, endpt_name, user_name);
468+
if (ret) {
469+
goto cleanup;
470+
}
471+
472+
cleanup:
473+
free(path);
474+
return ret;
475+
}
476+
477+
API int
478+
nc_server_config_del_ssh_user_authkey(const char *endpt_name, const char *user_name, struct lyd_node **config)
479+
{
480+
NC_CHECK_ARG_RET(NULL, endpt_name, user_name, config, 1);
481+
482+
return nc_server_config_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/"
483+
"ssh-server-parameters/client-authentication/users/user[name='%s']/"
484+
"public-keys/libnetconf2-netconf-server:use-system-keys", endpt_name, user_name);
485+
}
486+
487+
API int
488+
nc_server_config_ch_del_ssh_user_authkey(const char *client_name, const char *endpt_name,
489+
const char *user_name, struct lyd_node **config)
490+
{
491+
NC_CHECK_ARG_RET(NULL, client_name, endpt_name, user_name, config, 1);
492+
493+
return nc_server_config_delete(config, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/endpoints/"
494+
"endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/users/user[name='%s']/"
495+
"public-keys/libnetconf2-netconf-server:use-system-keys", endpt_name, user_name);
496+
}
497+
381498
static int
382499
_nc_server_config_add_ssh_user_password(const struct ly_ctx *ctx, const char *tree_path,
383500
const char *password, struct lyd_node **config)
@@ -615,6 +732,14 @@ nc_server_config_add_ssh_truststore_ref(const struct ly_ctx *ctx, const char *en
615732
goto cleanup;
616733
}
617734

735+
/* delete use system auth if present */
736+
ret = nc_server_config_check_delete(config, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/"
737+
"ssh-server-parameters/client-authentication/users/user[name='%s']/public-keys/"
738+
"libnetconf2-netconf-server:use-system-keys", endpt_name, user_name);
739+
if (ret) {
740+
goto cleanup;
741+
}
742+
618743
cleanup:
619744
return ret;
620745
}
@@ -642,6 +767,15 @@ nc_server_config_add_ch_ssh_truststore_ref(const struct ly_ctx *ctx, const char
642767
goto cleanup;
643768
}
644769

770+
/* delete use system auth if present */
771+
ret = nc_server_config_check_delete(config, "/ietf-netconf-server:netconf-server/call-home/"
772+
"netconf-client[name='%s']/endpoints/endpoint[name='%s']/ssh/"
773+
"ssh-server-parameters/client-authentication/users/user[name='%s']/public-keys/"
774+
"libnetconf2-netconf-server:use-system-keys", client_name, endpt_name, user_name);
775+
if (ret) {
776+
goto cleanup;
777+
}
778+
645779
cleanup:
646780
return ret;
647781
}

src/session_p.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ typedef enum {
4646
typedef enum {
4747
NC_STORE_LOCAL, /**< key/certificate is stored locally in the ietf-netconf-server YANG data */
4848
NC_STORE_KEYSTORE, /**< key/certificate is stored externally in a keystore module YANG data */
49-
NC_STORE_TRUSTSTORE /**< key/certificate is stored externally in a truststore module YANG data */
49+
NC_STORE_TRUSTSTORE, /**< key/certificate is stored externally in a truststore module YANG data */
50+
NC_STORE_SYSTEM /**< key/certificate is managed by the system */
5051
} NC_STORE_TYPE;
5152

5253
#ifdef NC_ENABLED_SSH_TLS
@@ -428,6 +429,7 @@ struct nc_server_opts {
428429
uint16_t idle_timeout;
429430

430431
#ifdef NC_ENABLED_SSH_TLS
432+
char *authkey_path_fmt; /**< Path to users' public keys that may contain tokens with special meaning. */
431433
char *pam_config_name; /**< PAM configuration file name. */
432434
int (*interactive_auth_clb)(const struct nc_session *session, ssh_session ssh_sess, ssh_message msg, void *user_data);
433435
void *interactive_auth_data;

src/session_server.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -853,6 +853,8 @@ nc_server_destroy(void)
853853
pthread_mutex_destroy(&server_opts.bind_lock);
854854

855855
#ifdef NC_ENABLED_SSH_TLS
856+
free(server_opts.authkey_path_fmt);
857+
server_opts.authkey_path_fmt = NULL;
856858
free(server_opts.pam_config_name);
857859
server_opts.pam_config_name = NULL;
858860
if (server_opts.interactive_auth_data && server_opts.interactive_auth_data_free) {

0 commit comments

Comments
 (0)