Skip to content

Commit 942e414

Browse files
committed
session server ssh BUGFIX kbdint auth change
Fix a bug where changing config from kbdint auth to any other type of auth requires you to still auth via kbdint. This commit also makes it possible for further extension of kbdint auth methods.
1 parent 2da933c commit 942e414

File tree

4 files changed

+83
-25
lines changed

4 files changed

+83
-25
lines changed

modules/[email protected]

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,6 @@ module libnetconf2-netconf-server {
312312
"Grouping for the SSH Keyboard interactive authentication method.";
313313

314314
container keyboard-interactive {
315-
presence "Indicates that the given client supports the SSH Keyboard Interactive authentication method.";
316315
description
317316
"Keyboard interactive SSH authentication method.";
318317

@@ -322,7 +321,6 @@ module libnetconf2-netconf-server {
322321
the Secure Shell Protocol (SSH)";
323322

324323
choice method {
325-
mandatory true;
326324
description
327325
"Method to perform the authentication with.";
328326

src/server_config.c

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2188,6 +2188,33 @@ nc_server_config_password(const struct lyd_node *node, enum nc_operation op)
21882188
return ret;
21892189
}
21902190

2191+
static int
2192+
nc_server_config_keyboard_interactive(const struct lyd_node *node, enum nc_operation op)
2193+
{
2194+
struct nc_auth_client *auth_client;
2195+
struct nc_ch_client *ch_client = NULL;
2196+
2197+
assert(!strcmp(LYD_NAME(node), "keyboard-interactive"));
2198+
2199+
if (op != NC_OP_DELETE) {
2200+
/* only do something on delete */
2201+
return 0;
2202+
}
2203+
2204+
if (is_ch(node) && nc_server_config_get_ch_client(node, &ch_client)) {
2205+
return 1;
2206+
}
2207+
2208+
if (nc_server_config_get_auth_client(node, ch_client, &auth_client)) {
2209+
return 1;
2210+
}
2211+
2212+
/* delete the keyboard-interactive authentication method */
2213+
auth_client->kbdint_method = NC_KBDINT_AUTH_METHOD_NONE;
2214+
2215+
return 0;
2216+
}
2217+
21912218
static int
21922219
nc_server_config_use_system_auth(const struct lyd_node *node, enum nc_operation op)
21932220
{
@@ -2207,9 +2234,9 @@ nc_server_config_use_system_auth(const struct lyd_node *node, enum nc_operation
22072234
}
22082235

22092236
if (op == NC_OP_CREATE) {
2210-
auth_client->kb_int_enabled = 1;
2237+
auth_client->kbdint_method = NC_KBDINT_AUTH_METHOD_SYSTEM;
22112238
} else {
2212-
auth_client->kb_int_enabled = 0;
2239+
auth_client->kbdint_method = NC_KBDINT_AUTH_METHOD_NONE;
22132240
}
22142241

22152242
cleanup:
@@ -3598,6 +3625,8 @@ nc_server_config_parse_netconf_server(const struct lyd_node *node, enum nc_opera
35983625
ret = nc_server_config_idle_time(node, op);
35993626
} else if (!strcmp(name, "keepalives")) {
36003627
ret = nc_server_config_keepalives(node, op);
3628+
} else if (!strcmp(name, "keyboard-interactive")) {
3629+
ret = nc_server_config_keyboard_interactive(node, op);
36013630
} else if (!strcmp(name, "key-exchange-alg")) {
36023631
ret = nc_server_config_kex_alg(node, op);
36033632
} else if (!strcmp(name, "local-address")) {

src/session_p.h

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,14 @@ enum nc_privkey_format {
9090
NC_PRIVKEY_FORMAT_UNKNOWN /**< Unknown format */
9191
};
9292

93+
/**
94+
* @brief Enumeration of SSH keyboard-interactive authentication methods.
95+
*/
96+
enum nc_kbdint_auth_method {
97+
NC_KBDINT_AUTH_METHOD_NONE = 0, /**< Keyboard-interactive authentication disabled. */
98+
NC_KBDINT_AUTH_METHOD_SYSTEM /**< Keyboard-interactive authentication is left to the system (PAM, shadow, etc.). */
99+
};
100+
93101
/**
94102
* @brief A basic certificate.
95103
*/
@@ -175,20 +183,20 @@ struct nc_auth_state {
175183
* @brief A server's authorized client.
176184
*/
177185
struct nc_auth_client {
178-
char *username; /**< Arbitrary username. */
186+
char *username; /**< Arbitrary username. */
179187

180-
enum nc_store_type store; /**< Specifies how/where the client's public key is stored. */
188+
enum nc_store_type store; /**< Specifies how/where the client's public key is stored. */
181189
union {
182190
struct {
183-
struct nc_public_key *pubkeys; /**< The client's public keys. */
184-
uint16_t pubkey_count; /**< The number of client's public keys. */
191+
struct nc_public_key *pubkeys; /**< The client's public keys. */
192+
uint16_t pubkey_count; /**< The number of client's public keys. */
185193
};
186-
char *ts_ref; /**< Name of the referenced truststore key. */
194+
char *ts_ref; /**< Name of the referenced truststore key. */
187195
};
188196

189-
char *password; /**< Client's password */
190-
int kb_int_enabled; /**< Indicates that the client supports keyboard-interactive authentication. */
191-
int none_enabled; /**< Implies that the client supports the none authentication method. */
197+
char *password; /**< Client's password */
198+
enum nc_kbdint_auth_method kbdint_method; /**< Keyboard-interactive authentication method. */
199+
int none_enabled; /**< Implies that the client supports the none authentication method. */
192200
};
193201

194202
/**

src/session_server_ssh.c

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -923,7 +923,7 @@ nc_server_ssh_auth_kbdint_pam(struct nc_session *session, const char *username,
923923
* @return 0 on success, non-zero otherwise.
924924
*/
925925
static int
926-
nc_server_ssh_auth_kbdint_system(struct nc_session *session, const char *username, ssh_message msg)
926+
nc_server_ssh_auth_kbdint_passwd(struct nc_session *session, const char *username, ssh_message msg)
927927
{
928928
int ret = 0, n_answers;
929929
const char *name = "Keyboard-Interactive Authentication";
@@ -975,6 +975,32 @@ nc_server_ssh_auth_kbdint_system(struct nc_session *session, const char *usernam
975975

976976
#endif
977977

978+
/**
979+
* @brief Keyboard-interactive authentication method using the system's authentication methods.
980+
*
981+
* @param[in] session NETCONF session.
982+
* @param[in] msg SSH message with a keyboard-interactive authentication request.
983+
* @return 0 on success, non-zero otherwise.
984+
*/
985+
static int
986+
nc_server_ssh_auth_kbdint_system(struct nc_session *session, ssh_message msg)
987+
{
988+
int rc;
989+
990+
#ifdef HAVE_LIBPAM
991+
/* authenticate using PAM */
992+
rc = nc_server_ssh_auth_kbdint_pam(session, session->username, msg);
993+
#elif defined (HAVE_SHADOW)
994+
/* authenticate using /etc/passwd and /etc/shadow */
995+
rc = nc_server_ssh_auth_kbdint_passwd(session, session->username, msg);
996+
#else
997+
ERR(NULL, "Keyboard-interactive method not supported.");
998+
rc = 1;
999+
#endif
1000+
1001+
return rc;
1002+
}
1003+
9781004
API void
9791005
nc_server_ssh_set_interactive_auth_clb(int (*interactive_auth_clb)(const struct nc_session *session, ssh_session ssh_sess, ssh_message msg, void *user_data),
9801006
void *user_data, void (*free_user_data)(void *user_data))
@@ -1319,22 +1345,19 @@ nc_server_ssh_auth_kbdint(struct nc_session *session, int local_users_supported,
13191345

13201346
assert(!local_users_supported || auth_client);
13211347

1322-
if (local_users_supported && !auth_client->kb_int_enabled) {
1348+
if (local_users_supported && !auth_client->kbdint_method) {
13231349
VRB(session, "User \"%s\" does not have Keyboard-interactive method configured, but a request was received.", session->username);
13241350
return 1;
13251351
} else if (server_opts.interactive_auth_clb) {
13261352
rc = server_opts.interactive_auth_clb(session, session->ti.libssh.session, msg, server_opts.interactive_auth_data);
13271353
} else {
1328-
#ifdef HAVE_LIBPAM
1329-
/* authenticate using PAM */
1330-
rc = nc_server_ssh_auth_kbdint_pam(session, session->username, msg);
1331-
#elif defined (HAVE_SHADOW)
1332-
/* authenticate using the system */
1333-
rc = nc_server_ssh_auth_kbdint_system(session, session->username, msg);
1334-
#else
1335-
ERR(NULL, "Keyboard-interactive method not supported.");
1336-
return 1;
1337-
#endif
1354+
/* perform the authentication based on the configured method */
1355+
if (auth_client->kbdint_method == NC_KBDINT_AUTH_METHOD_SYSTEM) {
1356+
rc = nc_server_ssh_auth_kbdint_system(session, msg);
1357+
} else {
1358+
ERR(session, "Keyboard-interactive authentication method not supported.");
1359+
rc = 1;
1360+
}
13381361
}
13391362

13401363
return rc ? 1 : 0;
@@ -1509,7 +1532,7 @@ nc_server_ssh_auth(struct nc_session *session, struct nc_server_ssh_opts *opts,
15091532
auth_state->methods |= SSH_AUTH_METHOD_PASSWORD;
15101533
auth_state->method_count++;
15111534
}
1512-
if (auth_client->kb_int_enabled) {
1535+
if (auth_client->kbdint_method) {
15131536
auth_state->methods |= SSH_AUTH_METHOD_INTERACTIVE;
15141537
auth_state->method_count++;
15151538
}

0 commit comments

Comments
 (0)