Skip to content

Commit 85744b2

Browse files
committed
Merge branch 'devel' of https://github.com/bhart3/libnetconf2 into devel
2 parents 80848e6 + 37f94a7 commit 85744b2

3 files changed

Lines changed: 97 additions & 28 deletions

File tree

src/session_p.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,14 @@ struct nc_server_opts {
169169
int (*passwd_auth_clb)(const struct nc_session *session, const char *password, void *user_data);
170170
void *passwd_auth_data;
171171
void (*passwd_auth_data_free)(void *data);
172+
173+
int (*pubkey_auth_clb)(const struct nc_session *session, ssh_key key, void *user_data);
174+
void *pubkey_auth_data;
175+
void (*pubkey_auth_data_free)(void *data);
176+
177+
int (*interactive_auth_clb)(const struct nc_session *session, ssh_message msg, void *user_data);
178+
void *interactive_auth_data;
179+
void (*interactive_auth_data_free)(void *data);
172180
#endif
173181
#ifdef NC_ENABLED_TLS
174182
int (*user_verify_clb)(const struct nc_session *session);

src/session_server.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@
2222
# include <openssl/x509.h>
2323
#endif
2424

25+
#ifdef NC_ENABLED_SSH
26+
# include <libssh/libssh.h>
27+
# include <libssh/callbacks.h>
28+
# include <libssh/server.h>
29+
#endif
30+
2531
#include "session.h"
2632
#include "netconf.h"
2733

@@ -507,6 +513,29 @@ void nc_server_ssh_set_passwd_auth_clb(int (*passwd_auth_clb)(const struct nc_se
507513
void *user_data),
508514
void *user_data, void (*free_user_data)(void *user_data));
509515

516+
/**
517+
* @brief Set the callback for SSH interactive authentication. If none is set, local system users are used.
518+
*
519+
* @param[in] interactive_auth_clb Callback that should authenticate the user.
520+
* Zero return indicates success, non-zero an error.
521+
* @param[in] user_data Optional arbitrary user data that will be passed to \p passwd_auth_clb.
522+
* @param[in] free_user_data Optional callback that will be called during cleanup to free any \p user_data.
523+
*/
524+
void ncserver_ssh_set_interactive_auth_clb(int (*interactive_auth_clb)(const struct nc_session *session, const struct ssh_message msg,
525+
void *user_data),
526+
void *user_data, void (*free_user_data)(void *user_data));
527+
528+
/**
529+
* @brief Set the callback for SSH public key authentication. If none is set, local system users are used.
530+
*
531+
* @param[in] pubkey_auth_clb Callback that should authenticate the user.
532+
* Zero return indicates success, non-zero an error.
533+
* @param[in] user_data Optional arbitrary user data that will be passed to \p passwd_auth_clb.
534+
* @param[in] free_user_data Optional callback that will be called during cleanup to free any \p user_data.
535+
*/
536+
void ncserver_ssh_set_pubkey_auth_clb(int (*pubkey_auth_clb)(const struct nc_session *session, ssh_key key, void *user_data),
537+
void *user_data, void (*free_user_data)(void *user_data));
538+
510539
/**
511540
* @brief Set the callback for retrieving host keys. Any RSA, DSA, and ECDSA keys can be added. However,
512541
* a maximum of one key of each type will be used during SSH authentication, later keys replacing

src/session_server_ssh.c

Lines changed: 60 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,25 @@ nc_server_ssh_set_passwd_auth_clb(int (*passwd_auth_clb)(const struct nc_session
142142
server_opts.passwd_auth_data_free = free_user_data;
143143
}
144144

145+
API void
146+
nc_server_ssh_set_interactive_auth_clb(int (*interactive_auth_clb)(const struct nc_session *session, ssh_message msg, void *user_data),
147+
void *user_data, void (*free_user_data)(void *user_data))
148+
{
149+
server_opts.interactive_auth_clb = interactive_auth_clb;
150+
server_opts.interactive_auth_data = user_data;
151+
server_opts.interactive_auth_data_free = free_user_data;
152+
}
153+
154+
API void
155+
nc_server_ssh_set_pubkey_auth_clb(int (*pubkey_auth_clb)(const struct nc_session *session, ssh_key key, void *user_data),
156+
void *user_data, void (*free_user_data)(void *user_data))
157+
{
158+
server_opts.pubkey_auth_clb = pubkey_auth_clb;
159+
server_opts.pubkey_auth_data = user_data;
160+
server_opts.pubkey_auth_data_free = free_user_data;
161+
}
162+
163+
145164
API int
146165
nc_server_ssh_ch_client_add_hostkey(const char *client_name, const char *name, int16_t idx)
147166
{
@@ -825,33 +844,39 @@ nc_sshcb_auth_password(struct nc_session *session, ssh_message msg)
825844
static void
826845
nc_sshcb_auth_kbdint(struct nc_session *session, ssh_message msg)
827846
{
847+
int auth_ret = 1;
828848
char *pass_hash;
829849

830-
if (!ssh_message_auth_kbdint_is_response(msg)) {
831-
const char *prompts[] = {"Password: "};
832-
char echo[] = {0};
833-
834-
ssh_message_auth_interactive_request(msg, "Interactive SSH Authentication", "Type your password:", 1, prompts, echo);
850+
if (server_opts.interactive_auth_clb) {
851+
auth_ret = server_opts.interactive_auth_clb(session, msg, server_opts.interactive_auth_data);
835852
} else {
836-
if (ssh_userauth_kbdint_getnanswers(session->ti.libssh.session) != 1) {
837-
ssh_message_reply_default(msg);
838-
return;
839-
}
840-
pass_hash = auth_password_get_pwd_hash(session->username);
841-
if (!pass_hash) {
842-
ssh_message_reply_default(msg);
843-
return;
844-
}
845-
if (!auth_password_compare_pwd(pass_hash, ssh_userauth_kbdint_getanswer(session->ti.libssh.session, 0))) {
846-
VRB("User \"%s\" authenticated.", session->username);
847-
session->flags |= NC_SESSION_SSH_AUTHENTICATED;
848-
ssh_message_auth_reply_success(msg, 0);
853+
if (!ssh_message_auth_kbdint_is_response(msg)) {
854+
const char *prompts[] = {"Password: "};
855+
char echo[] = {0};
856+
857+
ssh_message_auth_interactive_request(msg, "Interactive SSH Authentication", "Type your password:", 1, prompts, echo);
849858
} else {
850-
++session->opts.server.ssh_auth_attempts;
851-
VRB("Failed user \"%s\" authentication attempt (#%d).", session->username, session->opts.server.ssh_auth_attempts);
852-
ssh_message_reply_default(msg);
859+
if (ssh_userauth_kbdint_getnanswers(session->ti.libssh.session) != 1) {// failed session
860+
ssh_message_reply_default(msg);
861+
return;
862+
}
863+
pass_hash = auth_password_get_pwd_hash(session->username);// get hashed password
864+
if (pass_hash) {
865+
auth_ret = auth_password_compare_pwd(pass_hash, ssh_userauth_kbdint_getanswer(session->ti.libssh.session, 0));
866+
free(pass_hash);// free hashed password
867+
}
853868
}
854-
free(pass_hash);
869+
}
870+
871+
/* Authenticate message based on outcome */
872+
if (!auth_ret) {
873+
session->flags |= NC_SESSION_SSH_AUTHENTICATED;
874+
VRB("User \"%s\" authenticated.", session->username);
875+
ssh_message_auth_reply_success(msg, 0);
876+
} else {
877+
++session->opts.server.ssh_auth_attempts;
878+
VRB("Failed user \"%s\" authentication attempt (#%d).", session->username, session->opts.server.ssh_auth_attempts);
879+
ssh_message_reply_default(msg);
855880
}
856881
}
857882

@@ -914,12 +939,19 @@ nc_sshcb_auth_pubkey(struct nc_session *session, ssh_message msg)
914939
const char *username;
915940
int signature_state;
916941

917-
if ((username = auth_pubkey_compare_key(ssh_message_auth_pubkey(msg))) == NULL) {
918-
VRB("User \"%s\" tried to use an unknown (unauthorized) public key.", session->username);
919-
goto fail;
920-
} else if (strcmp(session->username, username)) {
921-
VRB("User \"%s\" is not the username identified with the presented public key.", session->username);
922-
goto fail;
942+
if(server_opts.pubkey_auth_clb){
943+
if(server_opts.pubkey_auth_clb(session, ssh_message_auth_pubkey(msg), server_opts.pubkey_auth_data)){
944+
goto fail;
945+
}
946+
}
947+
else{
948+
if ((username = auth_pubkey_compare_key(ssh_message_auth_pubkey(msg))) == NULL) {
949+
VRB("User \"%s\" tried to use an unknown (unauthorized) public key.", session->username);
950+
goto fail;
951+
} else if (strcmp(session->username, username)) {
952+
VRB("User \"%s\" is not the username identified with the presented public key.", session->username);
953+
goto fail;
954+
}
923955
}
924956

925957
signature_state = ssh_message_auth_publickey_state(msg);

0 commit comments

Comments
 (0)