From 3c0a4781e49a4912e191b20ea8ccaeb884eb9dcd Mon Sep 17 00:00:00 2001 From: milo Date: Tue, 8 Feb 2011 00:40:18 +0100 Subject: Added the keyboard-interactive authentication method --- src/server.c | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) (limited to 'src/server.c') diff --git a/src/server.c b/src/server.c index e4ecbe1e..86c4b84e 100644 --- a/src/server.c +++ b/src/server.c @@ -747,6 +747,14 @@ enum ssh_publickey_state_e ssh_message_auth_publickey_state(ssh_message msg){ return msg->auth_request.signature_state; } +int ssh_message_auth_kbdint_is_response(ssh_message msg) { + if (msg == NULL) { + return -1; + } + + return msg->auth_request.kbdint_response != 0; +} + int ssh_message_auth_set_methods(ssh_message msg, int methods) { if (msg == NULL || msg->session == NULL) { return -1; @@ -757,6 +765,131 @@ int ssh_message_auth_set_methods(ssh_message msg, int methods) { return 0; } +int ssh_message_auth_interactive_request(ssh_message msg, const char *name, + const char *instruction, unsigned int num_prompts, + const char **prompts, char *echo) { + int r; + unsigned int i = 0; + ssh_string tmp = NULL; + + if(name == NULL || instruction == NULL) { + return SSH_ERROR; + } + if(num_prompts > 0 && (prompts == NULL || echo == NULL)) { + return SSH_ERROR; + } + + if (buffer_add_u8(msg->session->out_buffer, SSH2_MSG_USERAUTH_INFO_REQUEST) < 0) { + return SSH_ERROR; + } + + /* name */ + tmp = ssh_string_from_char(name); + if (buffer_add_ssh_string(msg->session->out_buffer, tmp) < 0) { + return SSH_ERROR; + } + ssh_string_free(tmp); tmp = NULL; + + /* instruction */ + tmp = ssh_string_from_char(instruction); + if (buffer_add_ssh_string(msg->session->out_buffer, tmp) < 0) { + return SSH_ERROR; + } + ssh_string_free(tmp); tmp = NULL; + + /* language tag */ + tmp = ssh_string_from_char(""); + if (buffer_add_ssh_string(msg->session->out_buffer, tmp) < 0) { + return SSH_ERROR; + } + ssh_string_free(tmp); tmp = NULL; + + /* num prompts */ + if (buffer_add_u32(msg->session->out_buffer, ntohl(num_prompts)) < 0) { + return SSH_ERROR; + } + + for(i = 0; i < num_prompts; i++) { + /* prompt[i] */ + tmp = ssh_string_from_char(prompts[i]); + if (buffer_add_ssh_string(msg->session->out_buffer, tmp) < 0) { + goto error; + } + ssh_string_free(tmp); tmp = NULL; + + /* echo[i] */ + if (buffer_add_u8(msg->session->out_buffer, echo[i]) < 0) { + return SSH_ERROR; + } + } + + r = packet_send(msg->session); + + /* fill in the kbdint structure */ + if (msg->session->kbdint == NULL) { + ssh_log(msg->session, SSH_LOG_PROTOCOL, "Warning: Got a " + "keyboard-interactive response but it " + "seems we didn't send the request."); + + msg->session->kbdint = kbdint_new(); + if (msg->session->kbdint == NULL) { + ssh_set_error_oom(msg->session); + + return SSH_ERROR; + } + } else { + kbdint_clean(msg->session->kbdint); + } + + msg->session->kbdint->name = strdup(name); + if(msg->session->kbdint->name == NULL) { + ssh_set_error_oom(msg->session); + kbdint_free(msg->session->kbdint); + msg->session->kbdint = NULL; + return SSH_PACKET_USED; + } + msg->session->kbdint->instruction = strdup(instruction); + if(msg->session->kbdint->instruction == NULL) { + ssh_set_error_oom(msg->session); + kbdint_free(msg->session->kbdint); + msg->session->kbdint = NULL; + return SSH_PACKET_USED; + } + + msg->session->kbdint->nprompts = num_prompts; + msg->session->kbdint->prompts = malloc(num_prompts * sizeof(char *)); + if (msg->session->kbdint->prompts == NULL) { + msg->session->kbdint->nprompts = 0; + ssh_set_error_oom(msg->session); + kbdint_free(msg->session->kbdint); + msg->session->kbdint = NULL; + return SSH_ERROR; + } + msg->session->kbdint->echo = malloc(num_prompts * sizeof(char)); + if (msg->session->kbdint->echo == NULL) { + ssh_set_error_oom(msg->session); + kbdint_free(msg->session->kbdint); + msg->session->kbdint = NULL; + return SSH_ERROR; + } + for (i = 0; i < num_prompts; i++) { + msg->session->kbdint->echo[i] = echo[i]; + msg->session->kbdint->prompts[i] = strdup(prompts[i]); + if (msg->session->kbdint->prompts[i] == NULL) { + ssh_set_error_oom(msg->session); + msg->session->kbdint->nprompts = i; + kbdint_free(msg->session->kbdint); + msg->session->kbdint = NULL; + return SSH_PACKET_USED; + } + } + + return r; +error: + if(tmp) ssh_string_free(tmp); + return SSH_ERROR; +} + int ssh_message_auth_reply_success(ssh_message msg, int partial) { int r; -- cgit v1.2.3