From 1c2d26583ce1a9284398fb0b9636f7fd18b1b3eb Mon Sep 17 00:00:00 2001 From: Michal Vasko Date: Tue, 17 Oct 2023 08:53:36 +0200 Subject: [PATCH] session server UPDATE interactive auth session cb --- src/session_p.h | 4 ++++ src/session_server.c | 18 ++++++++++++++++++ src/session_server.h | 14 ++++++++++---- src/session_server_ssh.c | 19 ++++++++++++++++--- 4 files changed, 48 insertions(+), 7 deletions(-) diff --git a/src/session_p.h b/src/session_p.h index c5c54e8a..b352cc44 100644 --- a/src/session_p.h +++ b/src/session_p.h @@ -204,6 +204,10 @@ struct nc_server_opts { void *pubkey_auth_data; void (*pubkey_auth_data_free)(void *data); + int (*interactive_auth_sess_clb)(const struct nc_session *session, ssh_session ssh_sess, ssh_message msg, void *user_data); + void *interactive_auth_sess_data; + void (*interactive_auth_sess_data_free)(void *data); + int (*interactive_auth_clb)(const struct nc_session *session, ssh_message msg, void *user_data); void *interactive_auth_data; void (*interactive_auth_data_free)(void *data); diff --git a/src/session_server.c b/src/session_server.c index cbeb9249..2db7d3de 100644 --- a/src/session_server.c +++ b/src/session_server.c @@ -770,6 +770,24 @@ nc_server_destroy(void) server_opts.passwd_auth_data = NULL; server_opts.passwd_auth_data_free = NULL; + if (server_opts.pubkey_auth_data && server_opts.pubkey_auth_data_free) { + server_opts.pubkey_auth_data_free(server_opts.pubkey_auth_data); + } + server_opts.pubkey_auth_data = NULL; + server_opts.pubkey_auth_data_free = NULL; + + if (server_opts.interactive_auth_sess_data && server_opts.interactive_auth_sess_data_free) { + server_opts.interactive_auth_sess_data_free(server_opts.interactive_auth_sess_data); + } + server_opts.interactive_auth_sess_data = NULL; + server_opts.interactive_auth_sess_data_free = NULL; + + if (server_opts.interactive_auth_data && server_opts.interactive_auth_data_free) { + server_opts.interactive_auth_data_free(server_opts.interactive_auth_data); + } + server_opts.interactive_auth_data = NULL; + server_opts.interactive_auth_data_free = NULL; + nc_server_ssh_del_authkey(NULL, NULL, 0, NULL); if (server_opts.hostkey_data && server_opts.hostkey_data_free) { diff --git a/src/session_server.h b/src/session_server.h index 4837b38e..64dadbcd 100644 --- a/src/session_server.h +++ b/src/session_server.h @@ -596,20 +596,26 @@ void nc_server_ssh_set_passwd_auth_clb(int (*passwd_auth_clb)(const struct nc_se void *user_data), void *user_data, void (*free_user_data)(void *user_data)); /** - * @brief Set the callback for SSH interactive authentication. If none is set, local system users are used. + * @brief Set the callback for SSH interactive authentication. If none is set, local PAM-based authentication is used. * - * @param[in] interactive_auth_clb Callback that should authenticate the user. + * @param[in] interactive_auth_sess_clb Callback that should authenticate the user. * Zero return indicates success, non-zero an error. - * @param[in] user_data Optional arbitrary user data that will be passed to @p interactive_auth_clb. + * @param[in] user_data Optional arbitrary user data that will be passed to @p interactive_auth_sess_clb. * @param[in] free_user_data Optional callback that will be called during cleanup to free any @p user_data. */ +void nc_server_ssh_set_interactive_auth_sess_clb(int (*interactive_auth_sess_clb)(const struct nc_session *session, + ssh_session ssh_sess, ssh_message msg, void *user_data), void *user_data, void (*free_user_data)(void *user_data)); + +/** + * @brief Deprecated, use ::nc_server_ssh_set_interactive_auth_sess_clb() instead. + */ void nc_server_ssh_set_interactive_auth_clb(int (*interactive_auth_clb)(const struct nc_session *session, const ssh_message msg, void *user_data), void *user_data, void (*free_user_data)(void *user_data)); /** * @brief Set the name and a path to a PAM configuration file. * - * @p conf_name has to be set via this function prior to using keyboard-interactive authentication method. + * @p conf_name has to be set via this function prior to using PAM keyboard-interactive authentication method. * * @param[in] conf_name Name of the configuration file. * @param[in] conf_dir Optional. The absolute path to the directory in which the configuration file diff --git a/src/session_server_ssh.c b/src/session_server_ssh.c index db45b428..c6b744d9 100644 --- a/src/session_server_ssh.c +++ b/src/session_server_ssh.c @@ -170,6 +170,15 @@ nc_server_ssh_set_passwd_auth_clb(int (*passwd_auth_clb)(const struct nc_session server_opts.passwd_auth_data_free = free_user_data; } +API void +nc_server_ssh_set_interactive_auth_sess_clb(int (*interactive_auth_sess_clb)(const struct nc_session *session, + ssh_session ssh_sess, ssh_message msg, void *user_data), void *user_data, void (*free_user_data)(void *user_data)) +{ + server_opts.interactive_auth_sess_clb = interactive_auth_sess_clb; + server_opts.interactive_auth_sess_data = user_data; + server_opts.interactive_auth_sess_data_free = free_user_data; +} + API void nc_server_ssh_set_interactive_auth_clb(int (*interactive_auth_clb)(const struct nc_session *session, ssh_message msg, void *user_data), void *user_data, void (*free_user_data)(void *user_data)) @@ -447,9 +456,10 @@ nc_server_ssh_ch_client_endpt_mov_hostkey(const char *client_name, const char *e static int nc_server_ssh_set_auth_methods(int auth_methods, struct nc_server_ssh_opts *opts) { - if ((auth_methods & NC_SSH_AUTH_INTERACTIVE) && !server_opts.conf_name) { + if ((auth_methods & NC_SSH_AUTH_INTERACTIVE) && !server_opts.conf_name && !server_opts.interactive_auth_clb && + !server_opts.interactive_auth_sess_clb) { /* path to a configuration file not set */ - ERR(NULL, "Unable to use Keyboard-Interactive authentication method without setting the name of the PAM configuration file first."); + ERR(NULL, "To use Keyboard-Interactive authentication method, set the PAM configuration file or a callback."); return 1; } opts->auth_methods = auth_methods; @@ -1238,7 +1248,10 @@ nc_sshcb_auth_kbdint(struct nc_session *session, ssh_message msg) { int auth_ret = 1; - if (server_opts.interactive_auth_clb) { + if (server_opts.interactive_auth_sess_clb) { + auth_ret = server_opts.interactive_auth_sess_clb(session, session->ti.libssh.session, msg, + server_opts.interactive_auth_data); + } else if (server_opts.interactive_auth_clb) { auth_ret = server_opts.interactive_auth_clb(session, msg, server_opts.interactive_auth_data); } else { #ifdef HAVE_LIBPAM