| auth.c | auth.c | |||
|---|---|---|---|---|
| skipping to change at line 35 | skipping to change at line 35 | |||
| #include <stdlib.h> | #include <stdlib.h> | |||
| #include <stdio.h> | #include <stdio.h> | |||
| #include <string.h> | #include <string.h> | |||
| #ifndef _WIN32 | #ifndef _WIN32 | |||
| #include <arpa/inet.h> | #include <arpa/inet.h> | |||
| #endif | #endif | |||
| #include "libssh/priv.h" | #include "libssh/priv.h" | |||
| #include "libssh/ssh2.h" | #include "libssh/ssh2.h" | |||
| #include "libssh/buffer.h" | ||||
| #include "libssh/agent.h" | ||||
| #include "libssh/keyfiles.h" | ||||
| #include "libssh/packet.h" | ||||
| #include "libssh/session.h" | ||||
| #include "libssh/keys.h" | ||||
| /** \defgroup ssh_auth SSH Authentication functions | /** \defgroup ssh_auth SSH Authentication functions | |||
| * \brief functions to authenticate to servers | * \brief functions to authenticate to servers | |||
| */ | */ | |||
| /** \addtogroup ssh_auth | /** \addtogroup ssh_auth | |||
| * @{ */ | * @{ */ | |||
| static int ask_userauth(SSH_SESSION *session) { | static int ask_userauth(ssh_session session) { | |||
| int rc = 0; | int rc = 0; | |||
| enter_function(); | enter_function(); | |||
| if (session->auth_service_asked) { | if (session->auth_service_asked) { | |||
| rc = 0; | rc = 0; | |||
| } else if (ssh_service_request(session,"ssh-userauth")) { | } else if (ssh_service_request(session,"ssh-userauth")) { | |||
| rc = -1; | rc = -1; | |||
| } else { | } else { | |||
| session->auth_service_asked++; | session->auth_service_asked++; | |||
| } | } | |||
| leave_function(); | leave_function(); | |||
| return rc; | return rc; | |||
| } | } | |||
| static int wait_auth_status(SSH_SESSION *session, int kbdint) { | static int wait_auth_status(ssh_session session, int kbdint) { | |||
| char *auth_methods = NULL; | char *auth_methods = NULL; | |||
| STRING *auth; | ssh_string auth; | |||
| int rc = SSH_AUTH_ERROR; | int rc = SSH_AUTH_ERROR; | |||
| int cont = 1; | int cont = 1; | |||
| u8 partial = 0; | uint8_t partial = 0; | |||
| enter_function(); | enter_function(); | |||
| while (cont) { | while (cont) { | |||
| if (packet_read(session) != SSH_OK) { | if (packet_read(session) != SSH_OK) { | |||
| break; | break; | |||
| } | } | |||
| if (packet_translate(session) != SSH_OK) { | if (packet_translate(session) != SSH_OK) { | |||
| break; | break; | |||
| } | } | |||
| skipping to change at line 142 | skipping to change at line 148 | |||
| cont = 0; | cont = 0; | |||
| break; | break; | |||
| } | } | |||
| /* continue through success */ | /* continue through success */ | |||
| case SSH2_MSG_USERAUTH_SUCCESS: | case SSH2_MSG_USERAUTH_SUCCESS: | |||
| rc = SSH_AUTH_SUCCESS; | rc = SSH_AUTH_SUCCESS; | |||
| cont = 0; | cont = 0; | |||
| break; | break; | |||
| case SSH2_MSG_USERAUTH_BANNER: | case SSH2_MSG_USERAUTH_BANNER: | |||
| { | { | |||
| STRING *banner; | ssh_string banner; | |||
| banner = buffer_get_ssh_string(session->in_buffer); | banner = buffer_get_ssh_string(session->in_buffer); | |||
| if (banner == NULL) { | if (banner == NULL) { | |||
| ssh_log(session, SSH_LOG_PACKET, | ssh_log(session, SSH_LOG_PACKET, | |||
| "The banner message was invalid. Continuing though\n"); | "The banner message was invalid. Continuing though\n"); | |||
| break; | break; | |||
| } | } | |||
| ssh_log(session, SSH_LOG_PACKET, | ssh_log(session, SSH_LOG_PACKET, | |||
| "Received a message banner\n"); | "Received a message banner\n"); | |||
| string_free(session->banner); /* erase the older one */ | string_free(session->banner); /* erase the older one */ | |||
| skipping to change at line 166 | skipping to change at line 172 | |||
| default: | default: | |||
| packet_parse(session); | packet_parse(session); | |||
| break; | break; | |||
| } | } | |||
| } | } | |||
| leave_function(); | leave_function(); | |||
| return rc; | return rc; | |||
| } | } | |||
| int ssh_auth_list(SSH_SESSION *session) { | int ssh_auth_list(ssh_session session) { | |||
| if (session == NULL) { | if (session == NULL) { | |||
| return -1; | return -1; | |||
| } | } | |||
| return session->auth_methods; | return session->auth_methods; | |||
| } | } | |||
| int ssh_userauth_list(SSH_SESSION *session, const char *username) { | int ssh_userauth_list(ssh_session session, const char *username) { | |||
| if (session == NULL || username == NULL) { | if (session == NULL || username == NULL) { | |||
| return SSH_AUTH_ERROR; | return SSH_AUTH_ERROR; | |||
| } | } | |||
| if (session->auth_methods == 0) { | if (session->auth_methods == 0) { | |||
| ssh_userauth_none(session, username); | ssh_userauth_none(session, username); | |||
| } | } | |||
| return ssh_auth_list(session); | return ssh_auth_list(session); | |||
| } | } | |||
| skipping to change at line 203 | skipping to change at line 209 | |||
| * @param username The username to authenticate. You can specify NULL if | * @param username The username to authenticate. You can specify NULL if | |||
| * ssh_option_set_username() has been used. You cannot try | * ssh_option_set_username() has been used. You cannot try | |||
| * two different logins in a row. | * two different logins in a row. | |||
| * | * | |||
| * @returns SSH_AUTH_ERROR: A serious error happened.\n | * @returns SSH_AUTH_ERROR: A serious error happened.\n | |||
| * SSH_AUTH_DENIED: Authentication failed: use another method\n | * SSH_AUTH_DENIED: Authentication failed: use another method\n | |||
| * SSH_AUTH_PARTIAL: You've been partially authenticated, you stil l | * SSH_AUTH_PARTIAL: You've been partially authenticated, you stil l | |||
| * have to use another method\n | * have to use another method\n | |||
| * SSH_AUTH_SUCCESS: Authentication success | * SSH_AUTH_SUCCESS: Authentication success | |||
| */ | */ | |||
| int ssh_userauth_none(SSH_SESSION *session, const char *username) { | int ssh_userauth_none(ssh_session session, const char *username) { | |||
| STRING *user = NULL; | ssh_string user = NULL; | |||
| STRING *service = NULL; | ssh_string service = NULL; | |||
| STRING *method = NULL; | ssh_string method = NULL; | |||
| int rc = SSH_AUTH_ERROR; | int rc = SSH_AUTH_ERROR; | |||
| enter_function(); | enter_function(); | |||
| #ifdef WITH_SSH1 | #ifdef WITH_SSH1 | |||
| if (session->version == 1) { | if (session->version == 1) { | |||
| ssh_userauth1_none(session, username); | ssh_userauth1_none(session, username); | |||
| leave_function(); | leave_function(); | |||
| return rc; | return rc; | |||
| } | } | |||
| #endif | #endif | |||
| if (username == NULL) { | if (username == NULL) { | |||
| if (session->options->username == NULL) { | if (session->username == NULL) { | |||
| if (ssh_options_default_username(session->options) < 0) { | if (ssh_options_set(session, SSH_OPTIONS_USER, NULL) < 0) { | |||
| leave_function(); | leave_function(); | |||
| return rc; | return rc; | |||
| } | } | |||
| } | } | |||
| user = string_from_char(session->options->username); | user = string_from_char(session->username); | |||
| } else { | } else { | |||
| user = string_from_char(username); | user = string_from_char(username); | |||
| } | } | |||
| if (user == NULL) { | if (user == NULL) { | |||
| leave_function(); | leave_function(); | |||
| return rc; | return rc; | |||
| } | } | |||
| if (ask_userauth(session) < 0) { | if (ask_userauth(session) < 0) { | |||
| skipping to change at line 307 | skipping to change at line 313 | |||
| * method.\n | * method.\n | |||
| * SSH_AUTH_PARTIAL: You've been partially authenticated, you stil l | * SSH_AUTH_PARTIAL: You've been partially authenticated, you stil l | |||
| * have to use another method.\n | * have to use another method.\n | |||
| * SSH_AUTH_SUCCESS: The public key is accepted, you want now to u se | * SSH_AUTH_SUCCESS: The public key is accepted, you want now to u se | |||
| * ssh_userauth_pubkey(). | * ssh_userauth_pubkey(). | |||
| * | * | |||
| * @see publickey_from_file() | * @see publickey_from_file() | |||
| * @see privatekey_from_file() | * @see privatekey_from_file() | |||
| * @see ssh_userauth_pubkey() | * @see ssh_userauth_pubkey() | |||
| */ | */ | |||
| int ssh_userauth_offer_pubkey(SSH_SESSION *session, const char *username, | int ssh_userauth_offer_pubkey(ssh_session session, const char *username, | |||
| int type, STRING *publickey) { | int type, ssh_string publickey) { | |||
| STRING *user = NULL; | ssh_string user = NULL; | |||
| STRING *service = NULL; | ssh_string service = NULL; | |||
| STRING *method = NULL; | ssh_string method = NULL; | |||
| STRING *algo = NULL; | ssh_string algo = NULL; | |||
| int rc = SSH_AUTH_ERROR; | int rc = SSH_AUTH_ERROR; | |||
| enter_function(); | enter_function(); | |||
| #ifdef WITH_SSH1 | #ifdef WITH_SSH1 | |||
| if (session->version == 1) { | if (session->version == 1) { | |||
| ssh_userauth1_offer_pubkey(session, username, type, publickey); | ssh_userauth1_offer_pubkey(session, username, type, publickey); | |||
| leave_function(); | leave_function(); | |||
| return rc; | return rc; | |||
| } | } | |||
| #endif | #endif | |||
| if (username == NULL) { | if (username == NULL) { | |||
| if (session->options->username == NULL) { | if (session->username == NULL) { | |||
| if (ssh_options_default_username(session->options) < 0) { | if (ssh_options_set(session, SSH_OPTIONS_USER, NULL) < 0) { | |||
| leave_function(); | leave_function(); | |||
| return rc; | return rc; | |||
| } | } | |||
| } | } | |||
| user = string_from_char(session->options->username); | user = string_from_char(session->username); | |||
| } else { | } else { | |||
| user = string_from_char(username); | user = string_from_char(username); | |||
| } | } | |||
| if (user == NULL) { | if (user == NULL) { | |||
| leave_function(); | leave_function(); | |||
| return rc; | return rc; | |||
| } | } | |||
| if (ask_userauth(session) < 0) { | if (ask_userauth(session) < 0) { | |||
| skipping to change at line 419 | skipping to change at line 425 | |||
| * SSH_AUTH_DENIED: Authentication failed: use another method.\n | * SSH_AUTH_DENIED: Authentication failed: use another method.\n | |||
| * SSH_AUTH_PARTIAL: You've been partially authenticated, you stil l | * SSH_AUTH_PARTIAL: You've been partially authenticated, you stil l | |||
| * have to use another method.\n | * have to use another method.\n | |||
| * SSH_AUTH_SUCCESS: Authentication successful. | * SSH_AUTH_SUCCESS: Authentication successful. | |||
| * | * | |||
| * @see publickey_from_file() | * @see publickey_from_file() | |||
| * @see privatekey_from_file() | * @see privatekey_from_file() | |||
| * @see privatekey_free() | * @see privatekey_free() | |||
| * @see ssh_userauth_offer_pubkey() | * @see ssh_userauth_offer_pubkey() | |||
| */ | */ | |||
| int ssh_userauth_pubkey(SSH_SESSION *session, const char *username, | int ssh_userauth_pubkey(ssh_session session, const char *username, | |||
| STRING *publickey, PRIVATE_KEY *privatekey) { | ssh_string publickey, ssh_private_key privatekey) { | |||
| STRING *user = NULL; | ssh_string user = NULL; | |||
| STRING *service = NULL; | ssh_string service = NULL; | |||
| STRING *method = NULL; | ssh_string method = NULL; | |||
| STRING *algo = NULL; | ssh_string algo = NULL; | |||
| STRING *sign = NULL; | ssh_string sign = NULL; | |||
| int rc = SSH_AUTH_ERROR; | int rc = SSH_AUTH_ERROR; | |||
| enter_function(); | enter_function(); | |||
| #if 0 | #if 0 | |||
| if (session->version == 1) { | if (session->version == 1) { | |||
| return ssh_userauth1_pubkey(session, username, publickey, privatekey); | return ssh_userauth1_pubkey(session, username, publickey, privatekey); | |||
| } | } | |||
| #endif | #endif | |||
| if (username == NULL) { | if (username == NULL) { | |||
| if (session->options->username == NULL) { | if (session->username == NULL) { | |||
| if (ssh_options_default_username(session->options) < 0) { | if (ssh_options_set(session, SSH_OPTIONS_USER, NULL) < 0) { | |||
| leave_function(); | leave_function(); | |||
| return rc; | return rc; | |||
| } | } | |||
| } | } | |||
| user = string_from_char(session->options->username); | user = string_from_char(session->username); | |||
| } else { | } else { | |||
| user = string_from_char(username); | user = string_from_char(username); | |||
| } | } | |||
| if (user == NULL) { | if (user == NULL) { | |||
| leave_function(); | leave_function(); | |||
| return rc; | return rc; | |||
| } | } | |||
| if (ask_userauth(session) < 0) { | if (ask_userauth(session) < 0) { | |||
| skipping to change at line 538 | skipping to change at line 544 | |||
| * SSH_AUTH_DENIED: Authentication failed: use another method.\n | * SSH_AUTH_DENIED: Authentication failed: use another method.\n | |||
| * SSH_AUTH_PARTIAL: You've been partially authenticated, you stil l | * SSH_AUTH_PARTIAL: You've been partially authenticated, you stil l | |||
| * have to use another method.\n | * have to use another method.\n | |||
| * SSH_AUTH_SUCCESS: Authentication successful. | * SSH_AUTH_SUCCESS: Authentication successful. | |||
| * | * | |||
| * @see publickey_from_file() | * @see publickey_from_file() | |||
| * @see privatekey_from_file() | * @see privatekey_from_file() | |||
| * @see privatekey_free() | * @see privatekey_free() | |||
| * @see ssh_userauth_offer_pubkey() | * @see ssh_userauth_offer_pubkey() | |||
| */ | */ | |||
| int ssh_userauth_agent_pubkey(SSH_SESSION *session, const char *username, | int ssh_userauth_agent_pubkey(ssh_session session, const char *username, | |||
| PUBLIC_KEY *publickey) { | ssh_public_key publickey) { | |||
| STRING *user = NULL; | ssh_string user = NULL; | |||
| STRING *service = NULL; | ssh_string service = NULL; | |||
| STRING *method = NULL; | ssh_string method = NULL; | |||
| STRING *algo = NULL; | ssh_string algo = NULL; | |||
| STRING *key = NULL; | ssh_string key = NULL; | |||
| STRING *sign = NULL; | ssh_string sign = NULL; | |||
| int rc = SSH_AUTH_ERROR; | int rc = SSH_AUTH_ERROR; | |||
| enter_function(); | enter_function(); | |||
| if (! agent_is_running(session)) { | if (! agent_is_running(session)) { | |||
| return rc; | return rc; | |||
| } | } | |||
| if (username == NULL) { | if (username == NULL) { | |||
| if (session->options->username == NULL) { | if (session->username == NULL) { | |||
| if (ssh_options_default_username(session->options) < 0) { | if (ssh_options_set(session, SSH_OPTIONS_USER, NULL) < 0) { | |||
| leave_function(); | leave_function(); | |||
| return rc; | return rc; | |||
| } | } | |||
| } | } | |||
| user = string_from_char(session->options->username); | user = string_from_char(session->username); | |||
| } else { | } else { | |||
| user = string_from_char(username); | user = string_from_char(username); | |||
| } | } | |||
| if (user == NULL) { | if (user == NULL) { | |||
| leave_function(); | leave_function(); | |||
| return rc; | return rc; | |||
| } | } | |||
| if (ask_userauth(session) < 0) { | if (ask_userauth(session) < 0) { | |||
| skipping to change at line 663 | skipping to change at line 669 | |||
| * | * | |||
| * @returns SSH_AUTH_ERROR: A serious error happened.\n | * @returns SSH_AUTH_ERROR: A serious error happened.\n | |||
| * SSH_AUTH_DENIED: Authentication failed: use another method.\n | * SSH_AUTH_DENIED: Authentication failed: use another method.\n | |||
| * SSH_AUTH_PARTIAL: You've been partially authenticated, you stil l | * SSH_AUTH_PARTIAL: You've been partially authenticated, you stil l | |||
| * have to use another method.\n | * have to use another method.\n | |||
| * SSH_AUTH_SUCCESS: Authentication successful. | * SSH_AUTH_SUCCESS: Authentication successful. | |||
| * | * | |||
| * @see ssh_userauth_kbdint() | * @see ssh_userauth_kbdint() | |||
| * @see BURN_STRING | * @see BURN_STRING | |||
| */ | */ | |||
| int ssh_userauth_password(SSH_SESSION *session, const char *username, | int ssh_userauth_password(ssh_session session, const char *username, | |||
| const char *password) { | const char *password) { | |||
| STRING *user = NULL; | ssh_string user = NULL; | |||
| STRING *service = NULL; | ssh_string service = NULL; | |||
| STRING *method = NULL; | ssh_string method = NULL; | |||
| STRING *pwd = NULL; | ssh_string pwd = NULL; | |||
| int rc = SSH_AUTH_ERROR; | int rc = SSH_AUTH_ERROR; | |||
| enter_function(); | enter_function(); | |||
| #ifdef WITH_SSH1 | #ifdef WITH_SSH1 | |||
| if (session->version == 1) { | if (session->version == 1) { | |||
| rc = ssh_userauth1_password(session, username, password); | rc = ssh_userauth1_password(session, username, password); | |||
| leave_function(); | leave_function(); | |||
| return rc; | return rc; | |||
| } | } | |||
| #endif | #endif | |||
| if (username == NULL) { | if (username == NULL) { | |||
| if (session->options->username == NULL) { | if (session->username == NULL) { | |||
| if (ssh_options_default_username(session->options) < 0) { | if (ssh_options_set(session, SSH_OPTIONS_USER, NULL) < 0) { | |||
| leave_function(); | leave_function(); | |||
| return rc; | return rc; | |||
| } | } | |||
| } | } | |||
| user = string_from_char(session->options->username); | user = string_from_char(session->username); | |||
| } else { | } else { | |||
| user = string_from_char(username); | user = string_from_char(username); | |||
| } | } | |||
| if (user == NULL) { | if (user == NULL) { | |||
| leave_function(); | leave_function(); | |||
| return rc; | return rc; | |||
| } | } | |||
| if (ask_userauth(session) < 0) { | if (ask_userauth(session) < 0) { | |||
| skipping to change at line 752 | skipping to change at line 758 | |||
| string_free(user); | string_free(user); | |||
| string_free(service); | string_free(service); | |||
| string_free(method); | string_free(method); | |||
| string_burn(pwd); | string_burn(pwd); | |||
| string_free(pwd); | string_free(pwd); | |||
| leave_function(); | leave_function(); | |||
| return rc; | return rc; | |||
| } | } | |||
| static struct keys_struct keytab[] = { | #ifdef _MSC_VER | |||
| static const char privKey_1[] = "SSH_DIR/identity"; | ||||
| static const char pubKey_1[] = "SSH_DIR/identity.pub"; | ||||
| static const char privKey_2[] = "SSH_DIR/id_dsa"; | ||||
| static const char pubKey_2[] = "SSH_DIR/id_dsa.pub"; | ||||
| static const char privKey_3[] = "SSH_DIR/id_rsa"; | ||||
| static const char pubKey_3[] = "SSH_DIR/id_rsa.pub"; | ||||
| /** Used different var to allow const char[] declaration */ | ||||
| static struct ssh_keys_struct keytab[] = { | ||||
| { privKey_1, pubKey_1}, | ||||
| { privKey_2, pubKey_2}, | ||||
| { privKey_3, pubKey_3}, | ||||
| {0} | ||||
| }; | ||||
| #else | ||||
| /* This requires GCC extensions */ | ||||
| static struct ssh_keys_struct keytab[] = { | ||||
| { | { | |||
| .privatekey = "%s/.ssh/identity", | .privatekey = "SSH_DIR/identity", | |||
| .publickey = "%s/.ssh/identity.pub" | .publickey = "SSH_DIR/identity.pub" | |||
| }, | }, | |||
| { | { | |||
| .privatekey = "%s/.ssh/id_dsa", | .privatekey = "SSH_DIR/id_dsa", | |||
| .publickey = "%s/.ssh/id_dsa.pub", | .publickey = "SSH_DIR/id_dsa.pub", | |||
| }, | }, | |||
| { | { | |||
| .privatekey = "%s/.ssh/id_rsa", | .privatekey = "SSH_DIR/id_rsa", | |||
| .publickey = "%s/.ssh/id_rsa.pub", | .publickey = "SSH_DIR/id_rsa.pub", | |||
| }, | }, | |||
| { | { | |||
| .privatekey = NULL, | .privatekey = NULL, | |||
| .publickey = NULL | .publickey = NULL | |||
| } | } | |||
| }; | }; | |||
| #endif | ||||
| /* this function initialy was in the client */ | ||||
| /* but the fools are the ones who never change mind */ | ||||
| /** | /** | |||
| * @brief Tries to automaticaly authenticate with public key and "none" | * @brief Tries to automaticaly authenticate with public key and "none" | |||
| * | * | |||
| * It may fail, for instance it doesn't ask for a password and uses a defau lt | * It may fail, for instance it doesn't ask for a password and uses a defau lt | |||
| * asker for passphrases (in case the private key is encrypted). | * asker for passphrases (in case the private key is encrypted). | |||
| * | * | |||
| * @param session The ssh session to authenticate with. | * @param session The ssh session to authenticate with. | |||
| * | * | |||
| * @param passphrase Use this passphrase to unlock the privatekey. Use N ULL | * @param passphrase Use this passphrase to unlock the privatekey. Use N ULL | |||
| skipping to change at line 794 | skipping to change at line 814 | |||
| * should be asked. | * should be asked. | |||
| * | * | |||
| * @returns SSH_AUTH_ERROR: A serious error happened\n | * @returns SSH_AUTH_ERROR: A serious error happened\n | |||
| * SSH_AUTH_DENIED: Authentication failed: use another method\n | * SSH_AUTH_DENIED: Authentication failed: use another method\n | |||
| * SSH_AUTH_PARTIAL: You've been partially authenticated, you stil l | * SSH_AUTH_PARTIAL: You've been partially authenticated, you stil l | |||
| * have to use another method\n | * have to use another method\n | |||
| * SSH_AUTH_SUCCESS: Authentication success | * SSH_AUTH_SUCCESS: Authentication success | |||
| * | * | |||
| * @see ssh_userauth_kbdint() | * @see ssh_userauth_kbdint() | |||
| * @see ssh_userauth_password() | * @see ssh_userauth_password() | |||
| * @see ssh_options_set_identity() | * @see ssh_options_set() | |||
| */ | */ | |||
| int ssh_userauth_autopubkey(SSH_SESSION *session, const char *passphrase) { | int ssh_userauth_autopubkey(ssh_session session, const char *passphrase) { | |||
| struct public_key_struct *publickey; | struct ssh_public_key_struct *publickey; | |||
| STRING *pubkey; | ssh_string pubkey; | |||
| PRIVATE_KEY *privkey; | ssh_private_key privkey; | |||
| char *privkeyfile = NULL; | char *privkeyfile = NULL; | |||
| char *id = NULL; | char *id = NULL; | |||
| size_t size; | size_t size; | |||
| unsigned int i = 0; | unsigned int i = 0; | |||
| int type = 0; | int type = 0; | |||
| int rc; | int rc; | |||
| enter_function(); | enter_function(); | |||
| /* Always test none authentication */ | /* Always test none authentication */ | |||
| rc = ssh_userauth_none(session, NULL); | rc = ssh_userauth_none(session, NULL); | |||
| if (rc == SSH_AUTH_ERROR || rc == SSH_AUTH_SUCCESS) { | if (rc == SSH_AUTH_ERROR || rc == SSH_AUTH_SUCCESS) { | |||
| leave_function(); | leave_function(); | |||
| return rc; | return rc; | |||
| } | } | |||
| /* Try authentication with ssh-agent first */ | /* Try authentication with ssh-agent first */ | |||
| #ifndef _WIN32 | #ifndef _WIN32 | |||
| if (agent_is_running(session)) { | if (agent_is_running(session)) { | |||
| ssh_log(session, SSH_LOG_RARE, | ssh_log(session, SSH_LOG_RARE, | |||
| "Trying to authenticate with SSH agent keys"); | "Trying to authenticate with SSH agent keys as user: %s", | |||
| session->username); | ||||
| for (publickey = agent_get_first_ident(session, &privkeyfile); | for (publickey = agent_get_first_ident(session, &privkeyfile); | |||
| publickey != NULL; | publickey != NULL; | |||
| publickey = agent_get_next_ident(session, &privkeyfile)) { | publickey = agent_get_next_ident(session, &privkeyfile)) { | |||
| ssh_log(session, SSH_LOG_RARE, "Trying identity %s", privkeyfile); | ssh_log(session, SSH_LOG_RARE, "Trying identity %s", privkeyfile); | |||
| pubkey = publickey_to_string(publickey); | pubkey = publickey_to_string(publickey); | |||
| if (pubkey) { | if (pubkey) { | |||
| rc = ssh_userauth_offer_pubkey(session, NULL, publickey->type, pubk ey); | rc = ssh_userauth_offer_pubkey(session, NULL, publickey->type, pubk ey); | |||
| skipping to change at line 884 | skipping to change at line 905 | |||
| return SSH_AUTH_SUCCESS; | return SSH_AUTH_SUCCESS; | |||
| } /* if pubkey */ | } /* if pubkey */ | |||
| SAFE_FREE(id); | SAFE_FREE(id); | |||
| SAFE_FREE(privkeyfile); | SAFE_FREE(privkeyfile); | |||
| publickey_free(publickey); | publickey_free(publickey); | |||
| } /* for each privkey */ | } /* for each privkey */ | |||
| } /* if agent is running */ | } /* if agent is running */ | |||
| #endif | #endif | |||
| size = ARRAY_SIZE(keytab); | size = ARRAY_SIZE(keytab); | |||
| if (session->options->identity) { | if (session->identity) { | |||
| ssh_log(session, SSH_LOG_RARE, | ssh_log(session, SSH_LOG_RARE, | |||
| "Trying identity file %s\n", session->options->identity); | "Trying identity file %s\n", session->identity); | |||
| id = malloc(strlen(session->options->identity) + 1 + 4); | id = malloc(strlen(session->identity) + 1 + 4); | |||
| if (id == NULL) { | if (id == NULL) { | |||
| leave_function(); | leave_function(); | |||
| return SSH_AUTH_ERROR; | return SSH_AUTH_ERROR; | |||
| } | } | |||
| sprintf(id, "%s.pub", session->options->identity); | sprintf(id, "%s.pub", session->identity); | |||
| keytab[size - 1].privatekey = session->options->identity; | keytab[size - 1].privatekey = session->identity; | |||
| keytab[size - 1].publickey = id; | keytab[size - 1].publickey = id; | |||
| } | } | |||
| for (i = 0, pubkey = try_publickey_from_file(session, keytab[i], | for (i = 0, pubkey = try_publickey_from_file(session, keytab[i], | |||
| &privkeyfile, &type); | &privkeyfile, &type); | |||
| i < size; | i < size; | |||
| pubkey = try_publickey_from_file(session, keytab[i++], | pubkey = try_publickey_from_file(session, keytab[i++], | |||
| &privkeyfile, &type)) { | &privkeyfile, &type)) { | |||
| if (pubkey == NULL) { | if (pubkey == NULL) { | |||
| continue; | continue; | |||
| skipping to change at line 917 | skipping to change at line 938 | |||
| rc = ssh_userauth_offer_pubkey(session, NULL, type, pubkey); | rc = ssh_userauth_offer_pubkey(session, NULL, type, pubkey); | |||
| if (rc == SSH_AUTH_ERROR){ | if (rc == SSH_AUTH_ERROR){ | |||
| if (id != NULL) { | if (id != NULL) { | |||
| keytab[size - 1].privatekey = NULL; | keytab[size - 1].privatekey = NULL; | |||
| keytab[size - 1].publickey = NULL; | keytab[size - 1].publickey = NULL; | |||
| SAFE_FREE(id); | SAFE_FREE(id); | |||
| } | } | |||
| string_free(pubkey); | string_free(pubkey); | |||
| SAFE_FREE(privkeyfile); | SAFE_FREE(privkeyfile); | |||
| ssh_log(session, SSH_LOG_RARE, "Publickey authentication error"); | ||||
| leave_function(); | leave_function(); | |||
| return rc; | return rc; | |||
| } else { | } else { | |||
| if (rc != SSH_AUTH_SUCCESS){ | if (rc != SSH_AUTH_SUCCESS){ | |||
| ssh_log(session, SSH_LOG_RARE, "Public key refused by server"); | ssh_log(session, SSH_LOG_RARE, "Publickey refused by server"); | |||
| string_free(pubkey); | string_free(pubkey); | |||
| pubkey = NULL; | pubkey = NULL; | |||
| SAFE_FREE(privkeyfile); | SAFE_FREE(privkeyfile); | |||
| privkeyfile = NULL; | privkeyfile = NULL; | |||
| continue; | continue; | |||
| } | } | |||
| } | } | |||
| /* Public key accepted by server! */ | /* Public key accepted by server! */ | |||
| ssh_log(session, SSH_LOG_RARE, "Trying to read privatekey %s", privkeyf ile); | ||||
| privkey = privatekey_from_file(session, privkeyfile, type, passphrase); | privkey = privatekey_from_file(session, privkeyfile, type, passphrase); | |||
| if (privkey == NULL) { | if (privkey == NULL) { | |||
| ssh_log(session, SSH_LOG_FUNCTIONS, | ssh_log(session, SSH_LOG_FUNCTIONS, | |||
| "Reading private key %s failed (bad passphrase ?)", | "Reading private key %s failed (bad passphrase ?)", | |||
| privkeyfile); | privkeyfile); | |||
| string_free(pubkey); | string_free(pubkey); | |||
| pubkey = NULL; | pubkey = NULL; | |||
| SAFE_FREE(privkeyfile); | SAFE_FREE(privkeyfile); | |||
| privkeyfile = NULL; | privkeyfile = NULL; | |||
| continue; /* continue the loop with other pubkey */ | continue; /* continue the loop with other pubkey */ | |||
| skipping to change at line 997 | skipping to change at line 1020 | |||
| if (id) { | if (id) { | |||
| keytab[size - 1].privatekey = NULL; | keytab[size - 1].privatekey = NULL; | |||
| keytab[size - 1].publickey = NULL; | keytab[size - 1].publickey = NULL; | |||
| SAFE_FREE(id); | SAFE_FREE(id); | |||
| } | } | |||
| leave_function(); | leave_function(); | |||
| return SSH_AUTH_DENIED; | return SSH_AUTH_DENIED; | |||
| } | } | |||
| static struct ssh_kbdint *kbdint_new(void) { | struct ssh_kbdint_struct { | |||
| struct ssh_kbdint *kbd; | uint32_t nprompts; | |||
| char *name; | ||||
| char *instruction; | ||||
| char **prompts; | ||||
| unsigned char *echo; /* bool array */ | ||||
| char **answers; | ||||
| }; | ||||
| static ssh_kbdint kbdint_new(void) { | ||||
| ssh_kbdint kbd; | ||||
| kbd = malloc(sizeof (struct ssh_kbdint)); | kbd = malloc(sizeof (struct ssh_kbdint_struct)); | |||
| if (kbd == NULL) { | if (kbd == NULL) { | |||
| return NULL; | return NULL; | |||
| } | } | |||
| ZERO_STRUCTP(kbd); | ZERO_STRUCTP(kbd); | |||
| return kbd; | return kbd; | |||
| } | } | |||
| static void kbdint_free(struct ssh_kbdint *kbd) { | static void kbdint_free(ssh_kbdint kbd) { | |||
| int i, n; | int i, n; | |||
| if (kbd == NULL) { | if (kbd == NULL) { | |||
| return; | return; | |||
| } | } | |||
| n = kbd->nprompts; | n = kbd->nprompts; | |||
| SAFE_FREE(kbd->name); | SAFE_FREE(kbd->name); | |||
| SAFE_FREE(kbd->instruction); | SAFE_FREE(kbd->instruction); | |||
| skipping to change at line 1040 | skipping to change at line 1072 | |||
| for (i = 0; i < n; i++) { | for (i = 0; i < n; i++) { | |||
| BURN_STRING(kbd->answers[i]); | BURN_STRING(kbd->answers[i]); | |||
| SAFE_FREE(kbd->answers[i]); | SAFE_FREE(kbd->answers[i]); | |||
| } | } | |||
| SAFE_FREE(kbd->answers); | SAFE_FREE(kbd->answers); | |||
| } | } | |||
| SAFE_FREE(kbd); | SAFE_FREE(kbd); | |||
| } | } | |||
| static void kbdint_clean(struct ssh_kbdint *kbd) { | static void kbdint_clean(ssh_kbdint kbd) { | |||
| int i, n; | int i, n; | |||
| if (kbd == NULL) { | if (kbd == NULL) { | |||
| return; | return; | |||
| } | } | |||
| n = kbd->nprompts; | n = kbd->nprompts; | |||
| SAFE_FREE(kbd->name); | SAFE_FREE(kbd->name); | |||
| SAFE_FREE(kbd->instruction); | SAFE_FREE(kbd->instruction); | |||
| skipping to change at line 1074 | skipping to change at line 1106 | |||
| SAFE_FREE(kbd->answers[i]); | SAFE_FREE(kbd->answers[i]); | |||
| } | } | |||
| SAFE_FREE(kbd->answers); | SAFE_FREE(kbd->answers); | |||
| } | } | |||
| kbd->nprompts = 0; | kbd->nprompts = 0; | |||
| } | } | |||
| /* this function sends the first packet as explained in section 3.1 | /* this function sends the first packet as explained in section 3.1 | |||
| * of the draft */ | * of the draft */ | |||
| static int kbdauth_init(SSH_SESSION *session, const char *user, | static int kbdauth_init(ssh_session session, const char *user, | |||
| const char *submethods) { | const char *submethods) { | |||
| STRING *usr = NULL; | ssh_string usr = NULL; | |||
| STRING *sub = NULL; | ssh_string sub = NULL; | |||
| STRING *service = NULL; | ssh_string service = NULL; | |||
| STRING *method = NULL; | ssh_string method = NULL; | |||
| int rc = SSH_AUTH_ERROR; | int rc = SSH_AUTH_ERROR; | |||
| enter_function(); | enter_function(); | |||
| usr = string_from_char(user); | usr = string_from_char(user); | |||
| if (usr == NULL) { | if (usr == NULL) { | |||
| goto error; | goto error; | |||
| } | } | |||
| sub = (submethods ? string_from_char(submethods) : string_from_char("")); | sub = (submethods ? string_from_char(submethods) : string_from_char("")); | |||
| if (sub == NULL) { | if (sub == NULL) { | |||
| skipping to change at line 1134 | skipping to change at line 1166 | |||
| buffer_reinit(session->out_buffer); | buffer_reinit(session->out_buffer); | |||
| string_free(usr); | string_free(usr); | |||
| string_free(service); | string_free(service); | |||
| string_free(method); | string_free(method); | |||
| string_free(sub); | string_free(sub); | |||
| leave_function(); | leave_function(); | |||
| return rc; | return rc; | |||
| } | } | |||
| static int kbdauth_info_get(SSH_SESSION *session) { | static int kbdauth_info_get(ssh_session session) { | |||
| STRING *name; /* name of the "asking" window showed to client */ | ssh_string name; /* name of the "asking" window showed to client */ | |||
| STRING *instruction; | ssh_string instruction; | |||
| STRING *tmp; | ssh_string tmp; | |||
| u32 nprompts; | uint32_t nprompts; | |||
| u32 i; | uint32_t i; | |||
| enter_function(); | enter_function(); | |||
| name = buffer_get_ssh_string(session->in_buffer); | name = buffer_get_ssh_string(session->in_buffer); | |||
| instruction = buffer_get_ssh_string(session->in_buffer); | instruction = buffer_get_ssh_string(session->in_buffer); | |||
| tmp = buffer_get_ssh_string(session->in_buffer); | tmp = buffer_get_ssh_string(session->in_buffer); | |||
| buffer_get_u32(session->in_buffer, &nprompts); | buffer_get_u32(session->in_buffer, &nprompts); | |||
| if (name == NULL || instruction == NULL || tmp == NULL) { | if (name == NULL || instruction == NULL || tmp == NULL) { | |||
| string_free(name); | string_free(name); | |||
| skipping to change at line 1251 | skipping to change at line 1283 | |||
| leave_function(); | leave_function(); | |||
| return SSH_AUTH_ERROR; | return SSH_AUTH_ERROR; | |||
| } | } | |||
| } | } | |||
| leave_function(); | leave_function(); | |||
| return SSH_AUTH_INFO; /* we are not auth. but we parsed the packet */ | return SSH_AUTH_INFO; /* we are not auth. but we parsed the packet */ | |||
| } | } | |||
| /* sends challenge back to the server */ | /* sends challenge back to the server */ | |||
| static int kbdauth_send(SSH_SESSION *session) { | static int kbdauth_send(ssh_session session) { | |||
| STRING *answer = NULL; | ssh_string answer = NULL; | |||
| int rc = SSH_AUTH_ERROR; | int rc = SSH_AUTH_ERROR; | |||
| u32 i; | uint32_t i; | |||
| enter_function(); | enter_function(); | |||
| if (buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_INFO_RESPONSE) < 0 || | if (buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_INFO_RESPONSE) < 0 || | |||
| buffer_add_u32(session->out_buffer, | buffer_add_u32(session->out_buffer, | |||
| htonl(session->kbdint->nprompts)) < 0) { | htonl(session->kbdint->nprompts)) < 0) { | |||
| goto error; | goto error; | |||
| } | } | |||
| for (i = 0; i < session->kbdint->nprompts; i++) { | for (i = 0; i < session->kbdint->nprompts; i++) { | |||
| skipping to change at line 1324 | skipping to change at line 1356 | |||
| * SSH_AUTH_SUCCESS: Authentication success\n | * SSH_AUTH_SUCCESS: Authentication success\n | |||
| * SSH_AUTH_INFO: The server asked some questions. Use | * SSH_AUTH_INFO: The server asked some questions. Use | |||
| * ssh_userauth_kbdint_getnprompts() and such. | * ssh_userauth_kbdint_getnprompts() and such. | |||
| * | * | |||
| * @see ssh_userauth_kbdint_getnprompts() | * @see ssh_userauth_kbdint_getnprompts() | |||
| * @see ssh_userauth_kbdint_getname() | * @see ssh_userauth_kbdint_getname() | |||
| * @see ssh_userauth_kbdint_getinstruction() | * @see ssh_userauth_kbdint_getinstruction() | |||
| * @see ssh_userauth_kbdint_getprompt() | * @see ssh_userauth_kbdint_getprompt() | |||
| * @see ssh_userauth_kbdint_setanswer() | * @see ssh_userauth_kbdint_setanswer() | |||
| */ | */ | |||
| int ssh_userauth_kbdint(SSH_SESSION *session, const char *user, | int ssh_userauth_kbdint(ssh_session session, const char *user, | |||
| const char *submethods) { | const char *submethods) { | |||
| int rc = SSH_AUTH_ERROR; | int rc = SSH_AUTH_ERROR; | |||
| if (session->version == 1) { | if (session->version == 1) { | |||
| /* No keyb-interactive for ssh1 */ | /* No keyb-interactive for ssh1 */ | |||
| return SSH_AUTH_DENIED; | return SSH_AUTH_DENIED; | |||
| } | } | |||
| enter_function(); | enter_function(); | |||
| if (session->kbdint == NULL) { | if (session->kbdint == NULL) { | |||
| /* first time we call. we must ask for a challenge */ | /* first time we call. we must ask for a challenge */ | |||
| if (user == NULL) { | if (user == NULL) { | |||
| if ((user = session->options->username) == NULL) { | if ((user = session->username) == NULL) { | |||
| if (ssh_options_default_username(session->options) < 0) { | if (ssh_options_set(session, SSH_OPTIONS_USER, NULL) < 0) { | |||
| leave_function(); | leave_function(); | |||
| return SSH_AUTH_ERROR; | return SSH_AUTH_ERROR; | |||
| } else { | } else { | |||
| user = session->options->username; | user = session->username; | |||
| } | } | |||
| } | } | |||
| } | } | |||
| if (ask_userauth(session)) { | if (ask_userauth(session)) { | |||
| leave_function(); | leave_function(); | |||
| return SSH_AUTH_ERROR; | return SSH_AUTH_ERROR; | |||
| } | } | |||
| rc = kbdauth_init(session, user, submethods); | rc = kbdauth_init(session, user, submethods); | |||
| skipping to change at line 1404 | skipping to change at line 1436 | |||
| /** | /** | |||
| * @brief Get the number of prompts (questions) the server has given. | * @brief Get the number of prompts (questions) the server has given. | |||
| * | * | |||
| * You have called ssh_userauth_kbdint() and got SSH_AUTH_INFO. This | * You have called ssh_userauth_kbdint() and got SSH_AUTH_INFO. This | |||
| * function returns the questions from the server. | * function returns the questions from the server. | |||
| * | * | |||
| * @param session The ssh session to use. | * @param session The ssh session to use. | |||
| * | * | |||
| * @returns The number of prompts. | * @returns The number of prompts. | |||
| */ | */ | |||
| int ssh_userauth_kbdint_getnprompts(SSH_SESSION *session) { | int ssh_userauth_kbdint_getnprompts(ssh_session session) { | |||
| return session->kbdint->nprompts; | return session->kbdint->nprompts; | |||
| } | } | |||
| /** | /** | |||
| * @brief Get the "name" of the message block. | * @brief Get the "name" of the message block. | |||
| * | * | |||
| * You have called ssh_userauth_kbdint() and got SSH_AUTH_INFO. This | * You have called ssh_userauth_kbdint() and got SSH_AUTH_INFO. This | |||
| * function returns the questions from the server. | * function returns the questions from the server. | |||
| * | * | |||
| * @param session The ssh session to use. | * @param session The ssh session to use. | |||
| * | * | |||
| * @returns The name of the message block. Do not free it. | * @returns The name of the message block. Do not free it. | |||
| */ | */ | |||
| const char *ssh_userauth_kbdint_getname(SSH_SESSION *session) { | const char *ssh_userauth_kbdint_getname(ssh_session session) { | |||
| return session->kbdint->name; | return session->kbdint->name; | |||
| } | } | |||
| /** | /** | |||
| * @brief Get the "instruction" of the message block. | * @brief Get the "instruction" of the message block. | |||
| * | * | |||
| * You have called ssh_userauth_kbdint() and got SSH_AUTH_INFO. This | * You have called ssh_userauth_kbdint() and got SSH_AUTH_INFO. This | |||
| * function returns the questions from the server. | * function returns the questions from the server. | |||
| * | * | |||
| * @param session The ssh session to use. | * @param session The ssh session to use. | |||
| * | * | |||
| * @returns The instruction of the message block. | * @returns The instruction of the message block. | |||
| */ | */ | |||
| const char *ssh_userauth_kbdint_getinstruction(SSH_SESSION *session) { | const char *ssh_userauth_kbdint_getinstruction(ssh_session session) { | |||
| return session->kbdint->instruction; | return session->kbdint->instruction; | |||
| } | } | |||
| /** | /** | |||
| * @brief Get a prompt from a message block. | * @brief Get a prompt from a message block. | |||
| * | * | |||
| * You have called ssh_userauth_kbdint() and got SSH_AUTH_INFO. This | * You have called ssh_userauth_kbdint() and got SSH_AUTH_INFO. This | |||
| * function returns the questions from the server. | * function returns the questions from the server. | |||
| * | * | |||
| * @param session The ssh session to use. | * @param session The ssh session to use. | |||
| * | * | |||
| * @param i The inndex number of the i'th prompt. | * @param i The inndex number of the i'th prompt. | |||
| * | * | |||
| * @param echo When different of NULL, it will obtain a boolean me aning | * @param echo When different of NULL, it will obtain a boolean me aning | |||
| * that the resulting user input should be echoed or n ot | * that the resulting user input should be echoed or n ot | |||
| * (like passwords). | * (like passwords). | |||
| * | * | |||
| * @returns A pointer to the prompt. Do not free it. | * @returns A pointer to the prompt. Do not free it. | |||
| */ | */ | |||
| const char *ssh_userauth_kbdint_getprompt(SSH_SESSION *session, unsigned in t i, | const char *ssh_userauth_kbdint_getprompt(ssh_session session, unsigned int i, | |||
| char *echo) { | char *echo) { | |||
| if (i > session->kbdint->nprompts) { | if (i > session->kbdint->nprompts) { | |||
| return NULL; | return NULL; | |||
| } | } | |||
| if (echo) { | if (echo) { | |||
| *echo = session->kbdint->echo[i]; | *echo = session->kbdint->echo[i]; | |||
| } | } | |||
| return session->kbdint->prompts[i]; | return session->kbdint->prompts[i]; | |||
| } | } | |||
| /** You have called ssh_userauth_kbdint() and got SSH_AUTH_INFO. this | /** You have called ssh_userauth_kbdint() and got SSH_AUTH_INFO. this | |||
| * function returns the questions from the server | * function returns the questions from the server | |||
| * \brief set the answer for a question from a message block. | * \brief set the answer for a question from a message block. | |||
| * \param session ssh session | * \param session ssh session | |||
| * \param i index number of the ith prompt | * \param i index number of the ith prompt | |||
| * \param answer answer to give to server | * \param answer answer to give to server | |||
| * \return 0 on success, < 0 on error. | * \return 0 on success, < 0 on error. | |||
| */ | */ | |||
| int ssh_userauth_kbdint_setanswer(SSH_SESSION *session, unsigned int i, | int ssh_userauth_kbdint_setanswer(ssh_session session, unsigned int i, | |||
| const char *answer) { | const char *answer) { | |||
| if (session == NULL || answer == NULL || i > session->kbdint->nprompts) { | if (session == NULL || answer == NULL || i > session->kbdint->nprompts) { | |||
| return -1; | return -1; | |||
| } | } | |||
| if (session->kbdint->answers == NULL) { | if (session->kbdint->answers == NULL) { | |||
| session->kbdint->answers = malloc(sizeof(char*) * session->kbdint->npro mpts); | session->kbdint->answers = malloc(sizeof(char*) * session->kbdint->npro mpts); | |||
| if (session->kbdint->answers == NULL) { | if (session->kbdint->answers == NULL) { | |||
| return -1; | return -1; | |||
| } | } | |||
| End of changes. 57 change blocks. | ||||
| 102 lines changed or deleted | 134 lines changed or added | |||
This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ | ||||