1264377Sdes/* $OpenBSD: sshconnect1.c,v 1.74 2014/02/02 03:44:32 djm Exp $ */ 260573Skris/* 360573Skris * Author: Tatu Ylonen <ylo@cs.hut.fi> 460573Skris * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 560573Skris * All rights reserved 660573Skris * Code to connect to a remote host, and to perform the client side of the 760573Skris * login (authentication) dialog. 860573Skris * 965674Skris * As far as I am concerned, the code I have written for this software 1065674Skris * can be used freely for any purpose. Any derived versions of this 1165674Skris * software must be clearly marked as such, and if the derived work is 1265674Skris * incompatible with the protocol description in the RFC file, it must be 1365674Skris * called by a name other than "ssh" or "Secure Shell". 1460573Skris */ 1560573Skris 1660573Skris#include "includes.h" 1760573Skris 18162856Sdes#include <sys/types.h> 19162856Sdes#include <sys/socket.h> 20162856Sdes 2160573Skris#include <openssl/bn.h> 2260573Skris 23162856Sdes#include <stdarg.h> 24162856Sdes#include <stdio.h> 25162856Sdes#include <stdlib.h> 26162856Sdes#include <string.h> 27162856Sdes#include <signal.h> 28162856Sdes#include <pwd.h> 29162856Sdes 30162856Sdes#include "xmalloc.h" 3176262Sgreen#include "ssh.h" 3276262Sgreen#include "ssh1.h" 3360573Skris#include "rsa.h" 3460573Skris#include "buffer.h" 3560573Skris#include "packet.h" 36162856Sdes#include "key.h" 37162856Sdes#include "cipher.h" 38137019Sdes#include "kex.h" 3960573Skris#include "uidswap.h" 4076262Sgreen#include "log.h" 4160573Skris#include "readconf.h" 4265674Skris#include "authfd.h" 4360573Skris#include "sshconnect.h" 4460573Skris#include "authfile.h" 45137019Sdes#include "misc.h" 4676262Sgreen#include "canohost.h" 47162856Sdes#include "hostfile.h" 4876265Sgreen#include "auth.h" 49264377Sdes#include "digest.h" 5060573Skris 5160573Skris/* Session id for the current session. */ 5276262Sgreenu_char session_id[16]; 5376262Sgreenu_int supported_authentications = 0; 5460573Skris 5560573Skrisextern Options options; 5660573Skrisextern char *__progname; 5760573Skris 5860573Skris/* 5960573Skris * Checks if the user has an authentication agent, and if so, tries to 6060573Skris * authenticate using the agent. 6160573Skris */ 6292559Sdesstatic int 6376262Sgreentry_agent_authentication(void) 6460573Skris{ 6565674Skris int type; 6660573Skris char *comment; 6760573Skris AuthenticationConnection *auth; 6876262Sgreen u_char response[16]; 6976262Sgreen u_int i; 7065674Skris Key *key; 7165674Skris BIGNUM *challenge; 7260573Skris 7360573Skris /* Get connection to the agent. */ 7460573Skris auth = ssh_get_authentication_connection(); 7560573Skris if (!auth) 7660573Skris return 0; 7760573Skris 7892559Sdes if ((challenge = BN_new()) == NULL) 7992559Sdes fatal("try_agent_authentication: BN_new failed"); 8060573Skris /* Loop through identities served by the agent. */ 8165674Skris for (key = ssh_get_first_identity(auth, &comment, 1); 8292559Sdes key != NULL; 8392559Sdes key = ssh_get_next_identity(auth, &comment, 1)) { 8460573Skris 8560573Skris /* Try this identity. */ 8660573Skris debug("Trying RSA authentication via agent with '%.100s'", comment); 87255767Sdes free(comment); 8860573Skris 8960573Skris /* Tell the server that we are willing to authenticate using this key. */ 9060573Skris packet_start(SSH_CMSG_AUTH_RSA); 9165674Skris packet_put_bignum(key->rsa->n); 9260573Skris packet_send(); 9360573Skris packet_write_wait(); 9460573Skris 9560573Skris /* Wait for server's response. */ 9692559Sdes type = packet_read(); 9760573Skris 98157019Sdes /* The server sends failure if it doesn't like our key or 9960573Skris does not support RSA authentication. */ 10060573Skris if (type == SSH_SMSG_FAILURE) { 10160573Skris debug("Server refused our key."); 10265674Skris key_free(key); 10360573Skris continue; 10460573Skris } 10560573Skris /* Otherwise it should have sent a challenge. */ 10660573Skris if (type != SSH_SMSG_AUTH_RSA_CHALLENGE) 10760573Skris packet_disconnect("Protocol error during RSA authentication: %d", 10860573Skris type); 10960573Skris 11092559Sdes packet_get_bignum(challenge); 11192559Sdes packet_check_eom(); 11260573Skris 11360573Skris debug("Received RSA challenge from server."); 11460573Skris 11560573Skris /* Ask the agent to decrypt the challenge. */ 11665674Skris if (!ssh_decrypt_challenge(auth, key, challenge, session_id, 1, response)) { 11765674Skris /* 11865674Skris * The agent failed to authenticate this identifier 11965674Skris * although it advertised it supports this. Just 12065674Skris * return a wrong value. 12165674Skris */ 122124211Sdes logit("Authentication agent failed to decrypt challenge."); 123264377Sdes explicit_bzero(response, sizeof(response)); 12460573Skris } 12565674Skris key_free(key); 12660573Skris debug("Sending response to RSA challenge."); 12760573Skris 12860573Skris /* Send the decrypted challenge back to the server. */ 12960573Skris packet_start(SSH_CMSG_AUTH_RSA_RESPONSE); 13060573Skris for (i = 0; i < 16; i++) 13160573Skris packet_put_char(response[i]); 13260573Skris packet_send(); 13360573Skris packet_write_wait(); 13460573Skris 13560573Skris /* Wait for response from the server. */ 13692559Sdes type = packet_read(); 13760573Skris 13860573Skris /* The server returns success if it accepted the authentication. */ 13960573Skris if (type == SSH_SMSG_SUCCESS) { 14076262Sgreen ssh_close_authentication_connection(auth); 14165674Skris BN_clear_free(challenge); 14260573Skris debug("RSA authentication accepted by server."); 14360573Skris return 1; 14460573Skris } 14560573Skris /* Otherwise it should return failure. */ 14660573Skris if (type != SSH_SMSG_FAILURE) 14760573Skris packet_disconnect("Protocol error waiting RSA auth response: %d", 14860573Skris type); 14960573Skris } 15076262Sgreen ssh_close_authentication_connection(auth); 15160573Skris BN_clear_free(challenge); 15260573Skris debug("RSA authentication using agent refused."); 15360573Skris return 0; 15460573Skris} 15560573Skris 15660573Skris/* 15760573Skris * Computes the proper response to a RSA challenge, and sends the response to 15860573Skris * the server. 15960573Skris */ 16092559Sdesstatic void 16160573Skrisrespond_to_rsa_challenge(BIGNUM * challenge, RSA * prv) 16260573Skris{ 16376262Sgreen u_char buf[32], response[16]; 164264377Sdes struct ssh_digest_ctx *md; 16560573Skris int i, len; 16660573Skris 16760573Skris /* Decrypt the challenge using the private key. */ 16872397Skris /* XXX think about Bleichenbacher, too */ 16972397Skris if (rsa_private_decrypt(challenge, challenge, prv) <= 0) 17072397Skris packet_disconnect( 17172397Skris "respond_to_rsa_challenge: rsa_private_decrypt failed"); 17260573Skris 17360573Skris /* Compute the response. */ 17460573Skris /* The response is MD5 of decrypted challenge plus session id. */ 17560573Skris len = BN_num_bytes(challenge); 176149753Sdes if (len <= 0 || (u_int)len > sizeof(buf)) 17772397Skris packet_disconnect( 17872397Skris "respond_to_rsa_challenge: bad challenge length %d", len); 17960573Skris 18060573Skris memset(buf, 0, sizeof(buf)); 18160573Skris BN_bn2bin(challenge, buf + sizeof(buf) - len); 182264377Sdes if ((md = ssh_digest_start(SSH_DIGEST_MD5)) == NULL || 183264377Sdes ssh_digest_update(md, buf, 32) < 0 || 184264377Sdes ssh_digest_update(md, session_id, 16) < 0 || 185264377Sdes ssh_digest_final(md, response, sizeof(response)) < 0) 186264377Sdes fatal("%s: md5 failed", __func__); 187264377Sdes ssh_digest_free(md); 18860573Skris 18960573Skris debug("Sending response to host key RSA challenge."); 19060573Skris 19160573Skris /* Send the response back to the server. */ 19260573Skris packet_start(SSH_CMSG_AUTH_RSA_RESPONSE); 19360573Skris for (i = 0; i < 16; i++) 19460573Skris packet_put_char(response[i]); 19560573Skris packet_send(); 19660573Skris packet_write_wait(); 19760573Skris 198264377Sdes explicit_bzero(buf, sizeof(buf)); 199264377Sdes explicit_bzero(response, sizeof(response)); 200264377Sdes explicit_bzero(&md, sizeof(md)); 20160573Skris} 20260573Skris 20360573Skris/* 20460573Skris * Checks if the user has authentication file, and if so, tries to authenticate 20560573Skris * the user using it. 20660573Skris */ 20792559Sdesstatic int 20892559Sdestry_rsa_authentication(int idx) 20960573Skris{ 21060573Skris BIGNUM *challenge; 21192559Sdes Key *public, *private; 21292559Sdes char buf[300], *passphrase, *comment, *authfile; 213162856Sdes int i, perm_ok = 1, type, quit; 21460573Skris 21592559Sdes public = options.identity_keys[idx]; 21692559Sdes authfile = options.identity_files[idx]; 21792559Sdes comment = xstrdup(authfile); 21892559Sdes 21960573Skris debug("Trying RSA authentication with key '%.100s'", comment); 22060573Skris 22160573Skris /* Tell the server that we are willing to authenticate using this key. */ 22260573Skris packet_start(SSH_CMSG_AUTH_RSA); 22360573Skris packet_put_bignum(public->rsa->n); 22460573Skris packet_send(); 22560573Skris packet_write_wait(); 22660573Skris 22760573Skris /* Wait for server's response. */ 22892559Sdes type = packet_read(); 22960573Skris 23060573Skris /* 231157019Sdes * The server responds with failure if it doesn't like our key or 232157019Sdes * doesn't support RSA authentication. 23360573Skris */ 23460573Skris if (type == SSH_SMSG_FAILURE) { 23560573Skris debug("Server refused our key."); 236255767Sdes free(comment); 23760573Skris return 0; 23860573Skris } 23960573Skris /* Otherwise, the server should respond with a challenge. */ 24060573Skris if (type != SSH_SMSG_AUTH_RSA_CHALLENGE) 24160573Skris packet_disconnect("Protocol error during RSA authentication: %d", type); 24260573Skris 24360573Skris /* Get the challenge from the packet. */ 24492559Sdes if ((challenge = BN_new()) == NULL) 24592559Sdes fatal("try_rsa_authentication: BN_new failed"); 24692559Sdes packet_get_bignum(challenge); 24792559Sdes packet_check_eom(); 24860573Skris 24960573Skris debug("Received RSA challenge from server."); 25060573Skris 25160573Skris /* 25292559Sdes * If the key is not stored in external hardware, we have to 25392559Sdes * load the private key. Try first with empty passphrase; if it 25460573Skris * fails, ask for a passphrase. 25560573Skris */ 256106130Sdes if (public->flags & KEY_FLAG_EXT) 25792559Sdes private = public; 25892559Sdes else 259162856Sdes private = key_load_private_type(KEY_RSA1, authfile, "", NULL, 260162856Sdes &perm_ok); 261162856Sdes if (private == NULL && !options.batch_mode && perm_ok) { 26292559Sdes snprintf(buf, sizeof(buf), 26392559Sdes "Enter passphrase for RSA key '%.100s': ", comment); 26492559Sdes for (i = 0; i < options.number_of_password_prompts; i++) { 26560573Skris passphrase = read_passphrase(buf, 0); 26692559Sdes if (strcmp(passphrase, "") != 0) { 26792559Sdes private = key_load_private_type(KEY_RSA1, 268162856Sdes authfile, passphrase, NULL, NULL); 26992559Sdes quit = 0; 27092559Sdes } else { 27192559Sdes debug2("no passphrase given, try next key"); 27292559Sdes quit = 1; 27392559Sdes } 274264377Sdes explicit_bzero(passphrase, strlen(passphrase)); 275255767Sdes free(passphrase); 27692559Sdes if (private != NULL || quit) 27792559Sdes break; 27892559Sdes debug2("bad passphrase given, try again..."); 27960573Skris } 28060573Skris } 28160573Skris /* We no longer need the comment. */ 282255767Sdes free(comment); 28360573Skris 28492559Sdes if (private == NULL) { 285162856Sdes if (!options.batch_mode && perm_ok) 28692559Sdes error("Bad passphrase."); 28792559Sdes 28892559Sdes /* Send a dummy response packet to avoid protocol error. */ 28992559Sdes packet_start(SSH_CMSG_AUTH_RSA_RESPONSE); 29092559Sdes for (i = 0; i < 16; i++) 29192559Sdes packet_put_char(0); 29292559Sdes packet_send(); 29392559Sdes packet_write_wait(); 29492559Sdes 29592559Sdes /* Expect the server to reject it... */ 29692559Sdes packet_read_expect(SSH_SMSG_FAILURE); 29792559Sdes BN_clear_free(challenge); 29892559Sdes return 0; 29992559Sdes } 30092559Sdes 30160573Skris /* Compute and send a response to the challenge. */ 30260573Skris respond_to_rsa_challenge(challenge, private->rsa); 30360573Skris 30492559Sdes /* Destroy the private key unless it in external hardware. */ 30592559Sdes if (!(private->flags & KEY_FLAG_EXT)) 30692559Sdes key_free(private); 30760573Skris 30860573Skris /* We no longer need the challenge. */ 30960573Skris BN_clear_free(challenge); 31060573Skris 31160573Skris /* Wait for response from the server. */ 31292559Sdes type = packet_read(); 31360573Skris if (type == SSH_SMSG_SUCCESS) { 31460573Skris debug("RSA authentication accepted by server."); 31560573Skris return 1; 31660573Skris } 31760573Skris if (type != SSH_SMSG_FAILURE) 31860573Skris packet_disconnect("Protocol error waiting RSA auth response: %d", type); 31960573Skris debug("RSA authentication refused."); 32060573Skris return 0; 32160573Skris} 32260573Skris 32360573Skris/* 32460573Skris * Tries to authenticate the user using combined rhosts or /etc/hosts.equiv 32560573Skris * authentication and RSA host authentication. 32660573Skris */ 32792559Sdesstatic int 32876262Sgreentry_rhosts_rsa_authentication(const char *local_user, Key * host_key) 32960573Skris{ 33060573Skris int type; 33160573Skris BIGNUM *challenge; 33260573Skris 33360573Skris debug("Trying rhosts or /etc/hosts.equiv with RSA host authentication."); 33460573Skris 33560573Skris /* Tell the server that we are willing to authenticate using this key. */ 33660573Skris packet_start(SSH_CMSG_AUTH_RHOSTS_RSA); 33792559Sdes packet_put_cstring(local_user); 33876262Sgreen packet_put_int(BN_num_bits(host_key->rsa->n)); 33976262Sgreen packet_put_bignum(host_key->rsa->e); 34076262Sgreen packet_put_bignum(host_key->rsa->n); 34160573Skris packet_send(); 34260573Skris packet_write_wait(); 34360573Skris 34460573Skris /* Wait for server's response. */ 34592559Sdes type = packet_read(); 34660573Skris 34760573Skris /* The server responds with failure if it doesn't admit our 34860573Skris .rhosts authentication or doesn't know our host key. */ 34960573Skris if (type == SSH_SMSG_FAILURE) { 35060573Skris debug("Server refused our rhosts authentication or host key."); 35160573Skris return 0; 35260573Skris } 35360573Skris /* Otherwise, the server should respond with a challenge. */ 35460573Skris if (type != SSH_SMSG_AUTH_RSA_CHALLENGE) 35560573Skris packet_disconnect("Protocol error during RSA authentication: %d", type); 35660573Skris 35760573Skris /* Get the challenge from the packet. */ 35892559Sdes if ((challenge = BN_new()) == NULL) 35992559Sdes fatal("try_rhosts_rsa_authentication: BN_new failed"); 36092559Sdes packet_get_bignum(challenge); 36192559Sdes packet_check_eom(); 36260573Skris 36360573Skris debug("Received RSA challenge for host key from server."); 36460573Skris 36560573Skris /* Compute a response to the challenge. */ 36676262Sgreen respond_to_rsa_challenge(challenge, host_key->rsa); 36760573Skris 36860573Skris /* We no longer need the challenge. */ 36960573Skris BN_clear_free(challenge); 37060573Skris 37160573Skris /* Wait for response from the server. */ 37292559Sdes type = packet_read(); 37360573Skris if (type == SSH_SMSG_SUCCESS) { 37460573Skris debug("Rhosts or /etc/hosts.equiv with RSA host authentication accepted by server."); 37560573Skris return 1; 37660573Skris } 37760573Skris if (type != SSH_SMSG_FAILURE) 37860573Skris packet_disconnect("Protocol error waiting RSA auth response: %d", type); 37960573Skris debug("Rhosts or /etc/hosts.equiv with RSA host authentication refused."); 38060573Skris return 0; 38160573Skris} 38260573Skris 38360573Skris/* 38460573Skris * Tries to authenticate with any string-based challenge/response system. 38560573Skris * Note that the client code is not tied to s/key or TIS. 38660573Skris */ 38792559Sdesstatic int 38892559Sdestry_challenge_response_authentication(void) 38960573Skris{ 39060573Skris int type, i; 39176262Sgreen u_int clen; 39276262Sgreen char prompt[1024]; 39360573Skris char *challenge, *response; 39460573Skris 39592559Sdes debug("Doing challenge response authentication."); 39660573Skris 39792559Sdes for (i = 0; i < options.number_of_password_prompts; i++) { 39892559Sdes /* request a challenge */ 39992559Sdes packet_start(SSH_CMSG_AUTH_TIS); 40092559Sdes packet_send(); 40192559Sdes packet_write_wait(); 40260573Skris 40392559Sdes type = packet_read(); 40492559Sdes if (type != SSH_SMSG_FAILURE && 40592559Sdes type != SSH_SMSG_AUTH_TIS_CHALLENGE) { 40692559Sdes packet_disconnect("Protocol error: got %d in response " 40792559Sdes "to SSH_CMSG_AUTH_TIS", type); 40892559Sdes } 40992559Sdes if (type != SSH_SMSG_AUTH_TIS_CHALLENGE) { 41092559Sdes debug("No challenge."); 41192559Sdes return 0; 41292559Sdes } 41392559Sdes challenge = packet_get_string(&clen); 41492559Sdes packet_check_eom(); 41592559Sdes snprintf(prompt, sizeof prompt, "%s%s", challenge, 41692559Sdes strchr(challenge, '\n') ? "" : "\nResponse: "); 417255767Sdes free(challenge); 41860573Skris if (i != 0) 41960573Skris error("Permission denied, please try again."); 42076262Sgreen if (options.cipher == SSH_CIPHER_NONE) 421124211Sdes logit("WARNING: Encryption is disabled! " 42298684Sdes "Response will be transmitted in clear text."); 42376262Sgreen response = read_passphrase(prompt, 0); 42476262Sgreen if (strcmp(response, "") == 0) { 425255767Sdes free(response); 42676262Sgreen break; 42776262Sgreen } 42860573Skris packet_start(SSH_CMSG_AUTH_TIS_RESPONSE); 42974500Sgreen ssh_put_password(response); 430264377Sdes explicit_bzero(response, strlen(response)); 431255767Sdes free(response); 43260573Skris packet_send(); 43360573Skris packet_write_wait(); 43492559Sdes type = packet_read(); 43560573Skris if (type == SSH_SMSG_SUCCESS) 43660573Skris return 1; 43760573Skris if (type != SSH_SMSG_FAILURE) 43860573Skris packet_disconnect("Protocol error: got %d in response " 43976262Sgreen "to SSH_CMSG_AUTH_TIS_RESPONSE", type); 44060573Skris } 44160573Skris /* failure */ 44260573Skris return 0; 44360573Skris} 44460573Skris 44560573Skris/* 44660573Skris * Tries to authenticate with plain passwd authentication. 44760573Skris */ 44892559Sdesstatic int 44960573Skristry_password_authentication(char *prompt) 45060573Skris{ 45192559Sdes int type, i; 45260573Skris char *password; 45360573Skris 45460573Skris debug("Doing password authentication."); 45560573Skris if (options.cipher == SSH_CIPHER_NONE) 456124211Sdes logit("WARNING: Encryption is disabled! Password will be transmitted in clear text."); 45760573Skris for (i = 0; i < options.number_of_password_prompts; i++) { 45860573Skris if (i != 0) 45960573Skris error("Permission denied, please try again."); 46060573Skris password = read_passphrase(prompt, 0); 46160573Skris packet_start(SSH_CMSG_AUTH_PASSWORD); 46274500Sgreen ssh_put_password(password); 463264377Sdes explicit_bzero(password, strlen(password)); 464255767Sdes free(password); 46560573Skris packet_send(); 46660573Skris packet_write_wait(); 46760573Skris 46892559Sdes type = packet_read(); 46960573Skris if (type == SSH_SMSG_SUCCESS) 47060573Skris return 1; 47160573Skris if (type != SSH_SMSG_FAILURE) 47260573Skris packet_disconnect("Protocol error: got %d in response to passwd auth", type); 47360573Skris } 47460573Skris /* failure */ 47560573Skris return 0; 47660573Skris} 47760573Skris 47860573Skris/* 47960573Skris * SSH1 key exchange 48060573Skris */ 48160573Skrisvoid 48260573Skrisssh_kex(char *host, struct sockaddr *hostaddr) 48360573Skris{ 48460573Skris int i; 48560573Skris BIGNUM *key; 48692559Sdes Key *host_key, *server_key; 48760573Skris int bits, rbits; 48860573Skris int ssh_cipher_default = SSH_CIPHER_3DES; 48976262Sgreen u_char session_key[SSH_SESSION_KEY_LENGTH]; 49076262Sgreen u_char cookie[8]; 49176262Sgreen u_int supported_ciphers; 49276262Sgreen u_int server_flags, client_flags; 493137019Sdes u_int32_t rnd = 0; 49460573Skris 49560573Skris debug("Waiting for server public key."); 49660573Skris 49760573Skris /* Wait for a public key packet from the server. */ 49892559Sdes packet_read_expect(SSH_SMSG_PUBLIC_KEY); 49960573Skris 50060573Skris /* Get cookie from the packet. */ 50160573Skris for (i = 0; i < 8; i++) 50260573Skris cookie[i] = packet_get_char(); 50360573Skris 50460573Skris /* Get the public key. */ 50592559Sdes server_key = key_new(KEY_RSA1); 50692559Sdes bits = packet_get_int(); 50792559Sdes packet_get_bignum(server_key->rsa->e); 50892559Sdes packet_get_bignum(server_key->rsa->n); 50960573Skris 51092559Sdes rbits = BN_num_bits(server_key->rsa->n); 51160573Skris if (bits != rbits) { 512124211Sdes logit("Warning: Server lies about size of server public key: " 51360573Skris "actual size is %d bits vs. announced %d.", rbits, bits); 514124211Sdes logit("Warning: This may be due to an old implementation of ssh."); 51560573Skris } 51660573Skris /* Get the host key. */ 51792559Sdes host_key = key_new(KEY_RSA1); 51892559Sdes bits = packet_get_int(); 51992559Sdes packet_get_bignum(host_key->rsa->e); 52092559Sdes packet_get_bignum(host_key->rsa->n); 52160573Skris 52292559Sdes rbits = BN_num_bits(host_key->rsa->n); 52360573Skris if (bits != rbits) { 524124211Sdes logit("Warning: Server lies about size of server host key: " 52560573Skris "actual size is %d bits vs. announced %d.", rbits, bits); 526124211Sdes logit("Warning: This may be due to an old implementation of ssh."); 52760573Skris } 52860573Skris 52960573Skris /* Get protocol flags. */ 53060573Skris server_flags = packet_get_int(); 53160573Skris packet_set_protocol_flags(server_flags); 53260573Skris 53360573Skris supported_ciphers = packet_get_int(); 53460573Skris supported_authentications = packet_get_int(); 53592559Sdes packet_check_eom(); 53660573Skris 53760573Skris debug("Received server public key (%d bits) and host key (%d bits).", 53892559Sdes BN_num_bits(server_key->rsa->n), BN_num_bits(host_key->rsa->n)); 53960573Skris 54092559Sdes if (verify_host_key(host, hostaddr, host_key) == -1) 54192559Sdes fatal("Host key verification failed."); 54260573Skris 54360573Skris client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN; 54460573Skris 545137019Sdes derive_ssh1_session_id(host_key->rsa->n, server_key->rsa->n, cookie, session_id); 54660573Skris 54760573Skris /* 54860573Skris * Generate an encryption key for the session. The key is a 256 bit 54960573Skris * random number, interpreted as a 32-byte key, with the least 55060573Skris * significant 8 bits being the first byte of the key. 55160573Skris */ 55260573Skris for (i = 0; i < 32; i++) { 55360573Skris if (i % 4 == 0) 554137019Sdes rnd = arc4random(); 555137019Sdes session_key[i] = rnd & 0xff; 556137019Sdes rnd >>= 8; 55760573Skris } 55860573Skris 55960573Skris /* 56060573Skris * According to the protocol spec, the first byte of the session key 56160573Skris * is the highest byte of the integer. The session key is xored with 56260573Skris * the first 16 bytes of the session id. 56360573Skris */ 56492559Sdes if ((key = BN_new()) == NULL) 565164149Sdes fatal("ssh_kex: BN_new failed"); 566164149Sdes if (BN_set_word(key, 0) == 0) 567164149Sdes fatal("ssh_kex: BN_set_word failed"); 56860573Skris for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++) { 569164149Sdes if (BN_lshift(key, key, 8) == 0) 570164149Sdes fatal("ssh_kex: BN_lshift failed"); 571164149Sdes if (i < 16) { 572164149Sdes if (BN_add_word(key, session_key[i] ^ session_id[i]) 573164149Sdes == 0) 574164149Sdes fatal("ssh_kex: BN_add_word failed"); 575164149Sdes } else { 576164149Sdes if (BN_add_word(key, session_key[i]) == 0) 577164149Sdes fatal("ssh_kex: BN_add_word failed"); 578164149Sdes } 57960573Skris } 58060573Skris 58160573Skris /* 58260573Skris * Encrypt the integer using the public key and host key of the 58360573Skris * server (key with smaller modulus first). 58460573Skris */ 58592559Sdes if (BN_cmp(server_key->rsa->n, host_key->rsa->n) < 0) { 58660573Skris /* Public key has smaller modulus. */ 58792559Sdes if (BN_num_bits(host_key->rsa->n) < 58892559Sdes BN_num_bits(server_key->rsa->n) + SSH_KEY_BITS_RESERVED) { 58992559Sdes fatal("respond_to_rsa_challenge: host_key %d < server_key %d + " 59092559Sdes "SSH_KEY_BITS_RESERVED %d", 59192559Sdes BN_num_bits(host_key->rsa->n), 59292559Sdes BN_num_bits(server_key->rsa->n), 59392559Sdes SSH_KEY_BITS_RESERVED); 59460573Skris } 59592559Sdes rsa_public_encrypt(key, key, server_key->rsa); 59692559Sdes rsa_public_encrypt(key, key, host_key->rsa); 59760573Skris } else { 59860573Skris /* Host key has smaller modulus (or they are equal). */ 59992559Sdes if (BN_num_bits(server_key->rsa->n) < 60092559Sdes BN_num_bits(host_key->rsa->n) + SSH_KEY_BITS_RESERVED) { 60192559Sdes fatal("respond_to_rsa_challenge: server_key %d < host_key %d + " 60292559Sdes "SSH_KEY_BITS_RESERVED %d", 60392559Sdes BN_num_bits(server_key->rsa->n), 60492559Sdes BN_num_bits(host_key->rsa->n), 60592559Sdes SSH_KEY_BITS_RESERVED); 60660573Skris } 60792559Sdes rsa_public_encrypt(key, key, host_key->rsa); 60892559Sdes rsa_public_encrypt(key, key, server_key->rsa); 60960573Skris } 61060573Skris 61160573Skris /* Destroy the public keys since we no longer need them. */ 61292559Sdes key_free(server_key); 61392559Sdes key_free(host_key); 61460573Skris 61576262Sgreen if (options.cipher == SSH_CIPHER_NOT_SET) { 61676262Sgreen if (cipher_mask_ssh1(1) & supported_ciphers & (1 << ssh_cipher_default)) 61776262Sgreen options.cipher = ssh_cipher_default; 618137019Sdes } else if (options.cipher == SSH_CIPHER_INVALID || 61976262Sgreen !(cipher_mask_ssh1(1) & (1 << options.cipher))) { 620124211Sdes logit("No valid SSH1 cipher, using %.100s instead.", 62169591Sgreen cipher_name(ssh_cipher_default)); 62269591Sgreen options.cipher = ssh_cipher_default; 62360573Skris } 62460573Skris /* Check that the selected cipher is supported. */ 62560573Skris if (!(supported_ciphers & (1 << options.cipher))) 62660573Skris fatal("Selected cipher type %.100s not supported by server.", 62792559Sdes cipher_name(options.cipher)); 62860573Skris 62960573Skris debug("Encryption type: %.100s", cipher_name(options.cipher)); 63060573Skris 63160573Skris /* Send the encrypted session key to the server. */ 63260573Skris packet_start(SSH_CMSG_SESSION_KEY); 63360573Skris packet_put_char(options.cipher); 63460573Skris 63560573Skris /* Send the cookie back to the server. */ 63660573Skris for (i = 0; i < 8; i++) 63760573Skris packet_put_char(cookie[i]); 63860573Skris 63960573Skris /* Send and destroy the encrypted encryption key integer. */ 64060573Skris packet_put_bignum(key); 64160573Skris BN_clear_free(key); 64260573Skris 64360573Skris /* Send protocol flags. */ 64460573Skris packet_put_int(client_flags); 64560573Skris 64660573Skris /* Send the packet now. */ 64760573Skris packet_send(); 64860573Skris packet_write_wait(); 64960573Skris 65060573Skris debug("Sent encrypted session key."); 65160573Skris 65260573Skris /* Set the encryption key. */ 65360573Skris packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, options.cipher); 65460573Skris 655264377Sdes /* 656264377Sdes * We will no longer need the session key here. 657264377Sdes * Destroy any extra copies. 658264377Sdes */ 659264377Sdes explicit_bzero(session_key, sizeof(session_key)); 66060573Skris 66160573Skris /* 66260573Skris * Expect a success message from the server. Note that this message 66360573Skris * will be received in encrypted form. 66460573Skris */ 66592559Sdes packet_read_expect(SSH_SMSG_SUCCESS); 66660573Skris 66760573Skris debug("Received encrypted confirmation."); 66860573Skris} 66960573Skris 67060573Skris/* 67160573Skris * Authenticate user 67260573Skris */ 67360573Skrisvoid 67476262Sgreenssh_userauth1(const char *local_user, const char *server_user, char *host, 67598684Sdes Sensitive *sensitive) 67660573Skris{ 67760573Skris int i, type; 67860573Skris 67960573Skris if (supported_authentications == 0) 68076262Sgreen fatal("ssh_userauth1: server supports no auth methods"); 68160573Skris 68260573Skris /* Send the name of the user to log in as on the server. */ 68360573Skris packet_start(SSH_CMSG_USER); 68492559Sdes packet_put_cstring(server_user); 68560573Skris packet_send(); 68660573Skris packet_write_wait(); 68760573Skris 68860573Skris /* 68960573Skris * The server should respond with success if no authentication is 69060573Skris * needed (the user has no password). Otherwise the server responds 69160573Skris * with failure. 69260573Skris */ 69392559Sdes type = packet_read(); 69460573Skris 69560573Skris /* check whether the connection was accepted without authentication. */ 69660573Skris if (type == SSH_SMSG_SUCCESS) 69792559Sdes goto success; 69860573Skris if (type != SSH_SMSG_FAILURE) 69992559Sdes packet_disconnect("Protocol error: got %d in response to SSH_CMSG_USER", type); 70060573Skris 70160573Skris /* 70260573Skris * Try .rhosts or /etc/hosts.equiv authentication with RSA host 70360573Skris * authentication. 70460573Skris */ 70560573Skris if ((supported_authentications & (1 << SSH_AUTH_RHOSTS_RSA)) && 70676262Sgreen options.rhosts_rsa_authentication) { 70798684Sdes for (i = 0; i < sensitive->nkeys; i++) { 70898684Sdes if (sensitive->keys[i] != NULL && 70998684Sdes sensitive->keys[i]->type == KEY_RSA1 && 71098684Sdes try_rhosts_rsa_authentication(local_user, 71198684Sdes sensitive->keys[i])) 71292559Sdes goto success; 71376262Sgreen } 71460573Skris } 71560573Skris /* Try RSA authentication if the server supports it. */ 71660573Skris if ((supported_authentications & (1 << SSH_AUTH_RSA)) && 71760573Skris options.rsa_authentication) { 71860573Skris /* 71960573Skris * Try RSA authentication using the authentication agent. The 72060573Skris * agent is tried first because no passphrase is needed for 72160573Skris * it, whereas identity files may require passphrases. 72260573Skris */ 72360573Skris if (try_agent_authentication()) 72492559Sdes goto success; 72560573Skris 72660573Skris /* Try RSA authentication for each identity. */ 72760573Skris for (i = 0; i < options.num_identity_files; i++) 72876262Sgreen if (options.identity_keys[i] != NULL && 72976262Sgreen options.identity_keys[i]->type == KEY_RSA1 && 73092559Sdes try_rsa_authentication(i)) 73192559Sdes goto success; 73260573Skris } 73376262Sgreen /* Try challenge response authentication if the server supports it. */ 73460573Skris if ((supported_authentications & (1 << SSH_AUTH_TIS)) && 73592559Sdes options.challenge_response_authentication && !options.batch_mode) { 73692559Sdes if (try_challenge_response_authentication()) 73792559Sdes goto success; 73860573Skris } 73960573Skris /* Try password authentication if the server supports it. */ 74060573Skris if ((supported_authentications & (1 << SSH_AUTH_PASSWORD)) && 74160573Skris options.password_authentication && !options.batch_mode) { 74260573Skris char prompt[80]; 74360573Skris 74476262Sgreen snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ", 74560573Skris server_user, host); 74660573Skris if (try_password_authentication(prompt)) 74792559Sdes goto success; 74860573Skris } 74960573Skris /* All authentication methods have failed. Exit with an error message. */ 75060573Skris fatal("Permission denied."); 75160573Skris /* NOTREACHED */ 75292559Sdes 75392559Sdes success: 75492559Sdes return; /* need statement after label */ 75560573Skris} 756