Skip to content

Commit 808f3f6

Browse files
romanmichalvasko
authored andcommitted
server config UPDATE keyboard interactive
These changes include: - PAM filename is set globally for all clients - PAM directory not configurable (security reasons) - Removal of the ln2 PAM module and its use in a test - Description added to the ln2 YANG module - Change of add_user_interactive API to only enable kbint for a user
1 parent 5748ef4 commit 808f3f6

File tree

14 files changed

+131
-587
lines changed

14 files changed

+131
-587
lines changed

CMakeLists.txt

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,7 @@ set(format_sources
160160
examples/*.h*
161161
src/*.c
162162
src/*.h
163-
tests/*.c
164-
tests/pam/*.c)
163+
tests/*.c)
165164

166165
#
167166
# checks
@@ -255,13 +254,6 @@ if(ENABLE_SSH_TLS)
255254
if(LibPAM_FOUND)
256255
set(HAVE_LIBPAM TRUE)
257256

258-
# enable PAM test if a PAM header file contains a declaration of a function pam_start_confdir
259-
if (LIBPAM_HAVE_CONFDIR)
260-
message(STATUS "LibPAM found, version >= 1.4, enabled PAM tests")
261-
else()
262-
message(STATUS "LibPAM found, version < 1.4, disabled PAM tests")
263-
endif()
264-
265257
target_link_libraries(netconf2 ${LIBPAM_LIBRARIES})
266258
list(APPEND CMAKE_REQUIRED_LIBRARIES ${LIBPAM_LIBRARIES})
267259
include_directories(${LIBPAM_INCLUDE_DIRS})

CMakeModules/FindLibPAM.cmake

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
# LIBPAM_FOUND - system has LibPAM
55
# LIBPAM_INCLUDE_DIRS - the LibPAM include directory
66
# LIBPAM_LIBRARIES - link these to use LibPAM
7-
# LIBPAM_HAVE_CONFDIR - LibPAM version >= 1.4
87
#
98
# Author Roman Janota <[email protected]>
109
# Copyright (c) 2022 CESNET, z.s.p.o.
@@ -63,14 +62,6 @@ else()
6362

6463
if(LIBPAM_INCLUDE_DIR AND LIBPAM_LIBRARY)
6564
set(LIBPAM_FOUND TRUE)
66-
# there is no reliable way to check the version of PAM, so see if the declaration of a function pam_start_confdir
67-
# is in the header file (added in PAM 1.4)
68-
file(STRINGS ${LIBPAM_INCLUDE_DIR}/security/pam_appl.h PAM_CONFDIR REGEX "pam_start_confdir")
69-
if ("${PAM_CONFDIR}" STREQUAL "")
70-
set(LIBPAM_HAVE_CONFDIR FALSE)
71-
else()
72-
set(LIBPAM_HAVE_CONFDIR TRUE)
73-
endif()
7465
else()
7566
set(LIBPAM_FOUND FALSE)
7667
endif()

modules/[email protected]

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -265,35 +265,33 @@ module libnetconf2-netconf-server {
265265
"Grouping for the SSH Keyboard interactive authentication method.";
266266

267267
container keyboard-interactive {
268-
presence "Indicates that PAM configuration file name has been configured.
269-
This statement is present so the mandatory descendant
270-
nodes do not imply that this node must be
271-
configured.";
268+
presence "Indicates that PAM configuration file name has been configured and that
269+
the given client supportsthe SSH Keyboard Interactive authentication method.";
272270
description
273271
"Keyboard interactive SSH authentication method.";
274-
leaf pam-config-file-name {
275-
type string;
276-
mandatory true;
277-
}
278-
leaf pam-config-file-dir {
279-
type string;
280-
}
272+
273+
reference
274+
"RFC 4256:
275+
Generic Message Exchange Authentication for
276+
the Secure Shell Protocol (SSH)";
281277
}
282278
}
283279

284280
grouping endpoint-reference-grouping {
285281
description
286-
"Reference to another endpoint. The purpose is to use the referenced endpoint's authentication mechanisms.
287-
If a connection occurs on an endpoint, the connecting user will be tried to be authenticated
288-
using the given endpoint's defined methods. If the user wasn't authenticated and the endpoint
289-
references another endpoint, the authentication will be tried again. However, this time
290-
using the referenced endpoint's mechanisms. The references can be
291-
multiple, however there must not be a cycle.";
282+
"Grouping for the endpoint reference.";
292283

293284
leaf endpoint-reference {
294285
type leafref {
295286
path "/ncs:netconf-server/ncs:listen/ncs:endpoint/ncs:name";
296287
}
288+
description
289+
"Reference to another endpoint. The purpose is to use the referenced endpoint's authentication mechanisms.
290+
If a connection occurs on an endpoint, the connecting user will be tried to be authenticated
291+
using the given endpoint's defined methods. If the user wasn't authenticated and the endpoint
292+
references another endpoint, the authentication will be tried again. However, this time
293+
using the referenced endpoint's mechanisms. The references can be
294+
multiple, however there must not be a cycle.";
297295
}
298296
}
299297

src/config.h.in

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,6 @@
4444
*/
4545
#cmakedefine HAVE_LIBPAM
4646

47-
/*
48-
* Support for older PAM versions
49-
*/
50-
#cmakedefine LIBPAM_HAVE_CONFDIR
51-
5247
/*
5348
* Location of installed YANG modules on the system
5449
*/

src/server_config.c

Lines changed: 10 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -735,8 +735,6 @@ nc_server_config_del_auth_client(struct nc_server_ssh_opts *opts, struct nc_auth
735735
}
736736

737737
free(auth_client->password);
738-
free(auth_client->pam_config_name);
739-
free(auth_client->pam_config_dir);
740738

741739
opts->client_count--;
742740
if (!opts->client_count) {
@@ -2502,50 +2500,13 @@ nc_server_config_password(const struct lyd_node *node, NC_OPERATION op)
25022500
}
25032501

25042502
static int
2505-
nc_server_config_pam_name(const struct lyd_node *node, NC_OPERATION op)
2503+
nc_server_config_kb_int(const struct lyd_node *node, NC_OPERATION op)
25062504
{
25072505
int ret = 0;
25082506
struct nc_auth_client *auth_client;
2509-
struct nc_ch_client *ch_client;
2510-
2511-
assert(!strcmp(LYD_NAME(node), "pam-config-file-name"));
2512-
2513-
/* LOCK */
2514-
if (is_ch(node) && nc_server_config_get_ch_client_with_lock(node, &ch_client)) {
2515-
/* to avoid unlock on fail */
2516-
return 1;
2517-
}
2518-
2519-
if (nc_server_config_get_auth_client(node, &auth_client)) {
2520-
ret = 1;
2521-
goto cleanup;
2522-
}
2523-
2524-
if ((op == NC_OP_CREATE) || (op == NC_OP_REPLACE)) {
2525-
free(auth_client->pam_config_name);
2526-
auth_client->pam_config_name = strdup(lyd_get_value(node));
2527-
NC_CHECK_ERRMEM_GOTO(!auth_client->pam_config_name, ret = 1, cleanup);
2528-
} else {
2529-
free(auth_client->pam_config_name);
2530-
auth_client->pam_config_name = NULL;
2531-
}
2532-
2533-
cleanup:
2534-
if (is_ch(node)) {
2535-
/* UNLOCK */
2536-
nc_ch_client_unlock(ch_client);
2537-
}
2538-
return ret;
2539-
}
2540-
2541-
static int
2542-
nc_server_config_pam_dir(const struct lyd_node *node, NC_OPERATION op)
2543-
{
2544-
int ret = 0;
2545-
struct nc_auth_client *auth_client;
2546-
struct nc_ch_client *ch_client;
2507+
struct nc_ch_client *ch_client = NULL;
25472508

2548-
assert(!strcmp(LYD_NAME(node), "pam-config-file-dir"));
2509+
assert(!strcmp(LYD_NAME(node), "keyboard-interactive"));
25492510

25502511
/* LOCK */
25512512
if (is_ch(node) && nc_server_config_get_ch_client_with_lock(node, &ch_client)) {
@@ -2558,13 +2519,10 @@ nc_server_config_pam_dir(const struct lyd_node *node, NC_OPERATION op)
25582519
goto cleanup;
25592520
}
25602521

2561-
if ((op == NC_OP_CREATE) || (op == NC_OP_REPLACE)) {
2562-
free(auth_client->pam_config_dir);
2563-
auth_client->pam_config_dir = strdup(lyd_get_value(node));
2564-
NC_CHECK_ERRMEM_GOTO(!auth_client->pam_config_dir, ret = 1, cleanup);
2522+
if (op == NC_OP_CREATE) {
2523+
auth_client->kb_int_enabled = 1;
25652524
} else {
2566-
free(auth_client->pam_config_dir);
2567-
auth_client->pam_config_dir = NULL;
2525+
auth_client->kb_int_enabled = 0;
25682526
}
25692527

25702528
cleanup:
@@ -2597,9 +2555,9 @@ nc_server_config_none(const struct lyd_node *node, NC_OPERATION op)
25972555
}
25982556

25992557
if (op == NC_OP_CREATE) {
2600-
auth_client->supports_none = 1;
2558+
auth_client->none_enabled = 1;
26012559
} else {
2602-
auth_client->supports_none = 0;
2560+
auth_client->none_enabled = 0;
26032561
}
26042562

26052563
cleanup:
@@ -4204,10 +4162,8 @@ nc_server_config_parse_netconf_server(const struct lyd_node *node, NC_OPERATION
42044162
ret = nc_server_config_truststore_reference(node, op);
42054163
} else if (!strcmp(name, "password")) {
42064164
ret = nc_server_config_password(node, op);
4207-
} else if (!strcmp(name, "pam-config-file-name")) {
4208-
ret = nc_server_config_pam_name(node, op);
4209-
} else if (!strcmp(name, "pam-config-file-dir")) {
4210-
ret = nc_server_config_pam_dir(node, op);
4165+
} else if (!strcmp(name, "keyboard-interactive")) {
4166+
ret = nc_server_config_kb_int(node, op);
42114167
} else if (!strcmp(name, "none")) {
42124168
ret = nc_server_config_none(node, op);
42134169
} else if (!strcmp(name, "host-key-alg")) {

src/server_config.h

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -413,8 +413,23 @@ int nc_server_config_del_ssh_user_password(const char *endpt_name, const char *u
413413
* Otherwise the new YANG data will be added to the previous data and may override it.
414414
* @return 0 on success, non-zero otherwise.
415415
*/
416+
417+
/**
418+
* @brief Creates new YANG configuration data nodes for an SSH user's keyboard interactive authentication method.
419+
*
420+
* To set the PAM configuration filename, see ::nc_server_ssh_set_pam_conf_filename().
421+
*
422+
* @param[in] ctx libyang context.
423+
* @param[in] endpt_name Arbitrary identifier of the endpoint.
424+
* If an endpoint with this identifier already exists, its user might be changed.
425+
* @param[in] user_name Arbitrary identifier of the user.
426+
* If an user with this identifier already exists, its contents will be changed.
427+
* @param[in,out] config Configuration YANG data tree. If *config is NULL, it will be created.
428+
* Otherwise the new YANG data will be added to the previous data and may override it.
429+
* @return 0 on success, non-zero otherwise.
430+
*/
416431
int nc_server_config_add_ssh_user_interactive(const struct ly_ctx *ctx, const char *endpt_name,
417-
const char *user_name, const char *pam_config_name, const char *pam_config_dir, struct lyd_node **config);
432+
const char *user_name, struct lyd_node **config);
418433

419434
/**
420435
* @brief Deletes an SSH user's keyboard interactive authentication from the YANG data.
@@ -1045,23 +1060,21 @@ int nc_server_config_del_ch_ssh_user_password(const char *client_name, const cha
10451060
/**
10461061
* @brief Creates new YANG configuration data nodes for a Call Home SSH user's keyboard interactive authentication method.
10471062
*
1063+
* To set the PAM configuration filename, see ::nc_server_ssh_set_pam_conf_filename().
1064+
*
10481065
* @param[in] ctx libyang context.
10491066
* @param[in] client_name Arbitrary identifier of the Call Home client.
10501067
* If a Call Home client with this identifier already exists, its contents will be changed.
10511068
* @param[in] endpt_name Arbitrary identifier of the client's endpoint.
10521069
* If the client's endpoint with this identifier already exists, its contents will be changed.
10531070
* @param[in] user_name Arbitrary identifier of the endpoint's user.
10541071
* If the endpoint's user with this identifier already exists, its contents will be changed.
1055-
* @param[in] pam_config_name Name of the PAM configuration file.
1056-
* @param[in] pam_config_dir Optional. The absolute path to the directory in which the configuration file
1057-
* with the name pam_config_name is located. A newer version (>= 1.4) of PAM library is required to be able to specify
1058-
* the path. If NULL is passed, then the PAM's system directories will be searched (usually /etc/pam.d/).
10591072
* @param[in,out] config Configuration YANG data tree. If *config is NULL, it will be created.
10601073
* Otherwise the new YANG data will be added to the previous data and may override it.
10611074
* @return 0 on success, non-zero otherwise.
10621075
*/
10631076
int nc_server_config_add_ch_ssh_user_interactive(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name,
1064-
const char *user_name, const char *pam_config_name, const char *pam_config_dir, struct lyd_node **config);
1077+
const char *user_name, struct lyd_node **config);
10651078

10661079
/**
10671080
* @brief Deletes a Call Home SSH user's keyboard interactive authentication from the YANG data.

src/server_config_util_ssh.c

Lines changed: 9 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -474,45 +474,21 @@ nc_server_config_del_ch_ssh_user_password(const char *client_name, const char *e
474474
"users/user[name='%s']/password", client_name, endpt_name, user_name);
475475
}
476476

477-
static int
478-
_nc_server_config_add_ssh_user_interactive(const struct ly_ctx *ctx, const char *tree_path,
479-
const char *pam_config_name, const char *pam_config_dir, struct lyd_node **config)
480-
{
481-
int ret = 0;
482-
483-
ret = nc_server_config_append(ctx, tree_path, "pam-config-file-name", pam_config_name, config);
484-
if (ret) {
485-
goto cleanup;
486-
}
487-
488-
if (pam_config_dir) {
489-
ret = nc_server_config_append(ctx, tree_path, "pam-config-file-dir", pam_config_dir, config);
490-
if (ret) {
491-
goto cleanup;
492-
}
493-
}
494-
495-
cleanup:
496-
return ret;
497-
}
498-
499477
API int
500478
nc_server_config_add_ssh_user_interactive(const struct ly_ctx *ctx, const char *endpt_name,
501-
const char *user_name, const char *pam_config_name, const char *pam_config_dir, struct lyd_node **config)
479+
const char *user_name, struct lyd_node **config)
502480
{
503481
int ret = 0;
504482
char *path = NULL;
505483

506-
NC_CHECK_ARG_RET(NULL, ctx, endpt_name, user_name, pam_config_name, config, 1);
484+
NC_CHECK_ARG_RET(NULL, ctx, endpt_name, user_name, config, 1);
507485

508486
ret = asprintf(&path, "/ietf-netconf-server:netconf-server/listen/endpoint[name='%s']/ssh/ssh-server-parameters/"
509-
"client-authentication/users/user[name='%s']/"
510-
"libnetconf2-netconf-server:keyboard-interactive", endpt_name, user_name);
487+
"client-authentication/users/user[name='%s']", endpt_name, user_name);
511488
NC_CHECK_ERRMEM_GOTO(ret == -1, path = NULL; ret = 1, cleanup);
512489

513-
ret = _nc_server_config_add_ssh_user_interactive(ctx, path, pam_config_name, pam_config_dir, config);
490+
ret = nc_server_config_append(ctx, path, "libnetconf2-netconf-server:keyboard-interactive", NULL, config);
514491
if (ret) {
515-
ERR(NULL, "Creating new SSH user's keyboard interactive nodes failed.");
516492
goto cleanup;
517493
}
518494

@@ -523,21 +499,20 @@ nc_server_config_add_ssh_user_interactive(const struct ly_ctx *ctx, const char *
523499

524500
API int
525501
nc_server_config_add_ch_ssh_user_interactive(const struct ly_ctx *ctx, const char *client_name, const char *endpt_name,
526-
const char *user_name, const char *pam_config_name, const char *pam_config_dir, struct lyd_node **config)
502+
const char *user_name, struct lyd_node **config)
527503
{
528504
int ret = 0;
529505
char *path = NULL;
530506

531-
NC_CHECK_ARG_RET(NULL, ctx, client_name, endpt_name, user_name, pam_config_name, config, 1);
507+
NC_CHECK_ARG_RET(NULL, ctx, client_name, endpt_name, user_name, config, 1);
532508

533509
ret = asprintf(&path, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/endpoints/"
534-
"endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/users/user[name='%s']/"
535-
"libnetconf2-netconf-server:keyboard-interactive", client_name, endpt_name, user_name);
510+
"endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/users/user[name='%s']",
511+
client_name, endpt_name, user_name);
536512
NC_CHECK_ERRMEM_GOTO(ret == -1, path = NULL; ret = 1, cleanup);
537513

538-
ret = _nc_server_config_add_ssh_user_interactive(ctx, path, pam_config_name, pam_config_dir, config);
514+
ret = nc_server_config_append(ctx, path, "libnetconf2-netconf-server:keyboard-interactive", NULL, config);
539515
if (ret) {
540-
ERR(NULL, "Creating new CH SSH user's keyboard interactive nodes failed.");
541516
goto cleanup;
542517
}
543518

src/session_p.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -174,9 +174,8 @@ struct nc_auth_client {
174174
};
175175

176176
char *password; /**< Client's password */
177-
char *pam_config_name; /**< Client's PAM configuration file name. */
178-
char *pam_config_dir; /**< Client's PAM configuration file directory. */
179-
int supports_none; /**< Implies that the client supports the none authentication method. */
177+
int kb_int_enabled; /**< Indicates that the client supports keyboard-interactive authentication. */
178+
int none_enabled; /**< Implies that the client supports the none authentication method. */
180179
};
181180

182181
/**
@@ -429,6 +428,7 @@ struct nc_server_opts {
429428
uint16_t idle_timeout;
430429

431430
#ifdef NC_ENABLED_SSH_TLS
431+
char *pam_config_name; /**< PAM configuration file name. */
432432
int (*interactive_auth_clb)(const struct nc_session *session, ssh_session ssh_sess, ssh_message msg, void *user_data);
433433
void *interactive_auth_data;
434434
void (*interactive_auth_data_free)(void *data);
@@ -732,9 +732,9 @@ struct nc_ntf_thread_arg {
732732
* @brief PAM callback arguments.
733733
*/
734734
struct nc_pam_thread_arg {
735-
ssh_message msg; /**< libssh message */
736-
struct nc_session *session; /**< NETCONF session */
737-
struct nc_server_ssh_opts *opts; /**< SSH server opts */
735+
ssh_message msg; /**< libssh message */
736+
struct nc_session *session; /**< NETCONF session */
737+
uint16_t auth_timeout; /**< Authentication timeout. */
738738
};
739739

740740
/**

src/session_server.c

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

852852
#ifdef NC_ENABLED_SSH_TLS
853+
free(server_opts.pam_config_name);
854+
server_opts.pam_config_name = NULL;
853855
if (server_opts.interactive_auth_data && server_opts.interactive_auth_data_free) {
854856
server_opts.interactive_auth_data_free(server_opts.interactive_auth_data);
855857
}

0 commit comments

Comments
 (0)