1d059297112922cabb0c674840589be8db821fd9aAdam Langley/* $OpenBSD: sshconnect1.c,v 1.77 2015/01/14 20:05:27 djm Exp $ */ 2bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* 3bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Author: Tatu Ylonen <ylo@cs.hut.fi> 4bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 5bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * All rights reserved 6bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Code to connect to a remote host, and to perform the client side of the 7bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * login (authentication) dialog. 8bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * 9bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * As far as I am concerned, the code I have written for this software 10bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * can be used freely for any purpose. Any derived versions of this 11bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * software must be clearly marked as such, and if the derived work is 12bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * incompatible with the protocol description in the RFC file, it must be 13bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * called by a name other than "ssh" or "Secure Shell". 14bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 15bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 16bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "includes.h" 17bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 18d059297112922cabb0c674840589be8db821fd9aAdam Langley#ifdef WITH_SSH1 19d059297112922cabb0c674840589be8db821fd9aAdam Langley 20bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <sys/types.h> 21bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <sys/socket.h> 22bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 23bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <openssl/bn.h> 24bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 25d059297112922cabb0c674840589be8db821fd9aAdam Langley#include <errno.h> 26bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <stdarg.h> 27bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <stdio.h> 28bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <stdlib.h> 29bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <string.h> 30bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <signal.h> 31bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <pwd.h> 32bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 33bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "xmalloc.h" 34bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "ssh.h" 35bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "ssh1.h" 36bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "rsa.h" 37bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "buffer.h" 38bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "packet.h" 39bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "key.h" 40bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "cipher.h" 41bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "kex.h" 42bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "uidswap.h" 43bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "log.h" 44d059297112922cabb0c674840589be8db821fd9aAdam Langley#include "misc.h" 45bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "readconf.h" 46bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "authfd.h" 47bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "sshconnect.h" 48bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "authfile.h" 49bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "canohost.h" 50bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "hostfile.h" 51bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "auth.h" 52d059297112922cabb0c674840589be8db821fd9aAdam Langley#include "digest.h" 53d059297112922cabb0c674840589be8db821fd9aAdam Langley#include "ssherr.h" 54bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 55bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* Session id for the current session. */ 56bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanu_char session_id[16]; 57bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanu_int supported_authentications = 0; 58bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 59bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanextern Options options; 60bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanextern char *__progname; 61bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 62bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* 63bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Checks if the user has an authentication agent, and if so, tries to 64bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * authenticate using the agent. 65bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 66bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstatic int 67bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmantry_agent_authentication(void) 68bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 69d059297112922cabb0c674840589be8db821fd9aAdam Langley int r, type, agent_fd, ret = 0; 70bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman u_char response[16]; 71d059297112922cabb0c674840589be8db821fd9aAdam Langley size_t i; 72bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman BIGNUM *challenge; 73d059297112922cabb0c674840589be8db821fd9aAdam Langley struct ssh_identitylist *idlist = NULL; 74bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 75bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Get connection to the agent. */ 76d059297112922cabb0c674840589be8db821fd9aAdam Langley if ((r = ssh_get_authentication_socket(&agent_fd)) != 0) { 77d059297112922cabb0c674840589be8db821fd9aAdam Langley if (r != SSH_ERR_AGENT_NOT_PRESENT) 78d059297112922cabb0c674840589be8db821fd9aAdam Langley debug("%s: ssh_get_authentication_socket: %s", 79d059297112922cabb0c674840589be8db821fd9aAdam Langley __func__, ssh_err(r)); 80bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 0; 81d059297112922cabb0c674840589be8db821fd9aAdam Langley } 82bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 83bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if ((challenge = BN_new()) == NULL) 84bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fatal("try_agent_authentication: BN_new failed"); 85bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 86d059297112922cabb0c674840589be8db821fd9aAdam Langley /* Loop through identities served by the agent. */ 87d059297112922cabb0c674840589be8db821fd9aAdam Langley if ((r = ssh_fetch_identitylist(agent_fd, 1, &idlist)) != 0) { 88d059297112922cabb0c674840589be8db821fd9aAdam Langley if (r != SSH_ERR_AGENT_NO_IDENTITIES) 89d059297112922cabb0c674840589be8db821fd9aAdam Langley debug("%s: ssh_fetch_identitylist: %s", 90d059297112922cabb0c674840589be8db821fd9aAdam Langley __func__, ssh_err(r)); 91d059297112922cabb0c674840589be8db821fd9aAdam Langley goto out; 92d059297112922cabb0c674840589be8db821fd9aAdam Langley } 93d059297112922cabb0c674840589be8db821fd9aAdam Langley for (i = 0; i < idlist->nkeys; i++) { 94bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Try this identity. */ 95d059297112922cabb0c674840589be8db821fd9aAdam Langley debug("Trying RSA authentication via agent with '%.100s'", 96d059297112922cabb0c674840589be8db821fd9aAdam Langley idlist->comments[i]); 97bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 98bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Tell the server that we are willing to authenticate using this key. */ 99bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_start(SSH_CMSG_AUTH_RSA); 100d059297112922cabb0c674840589be8db821fd9aAdam Langley packet_put_bignum(idlist->keys[i]->rsa->n); 101bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_send(); 102bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_write_wait(); 103bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 104bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Wait for server's response. */ 105bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman type = packet_read(); 106bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 107bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* The server sends failure if it doesn't like our key or 108bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman does not support RSA authentication. */ 109bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (type == SSH_SMSG_FAILURE) { 110bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("Server refused our key."); 111bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman continue; 112bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 113bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Otherwise it should have sent a challenge. */ 114bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (type != SSH_SMSG_AUTH_RSA_CHALLENGE) 115bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_disconnect("Protocol error during RSA authentication: %d", 116bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman type); 117bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 118bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_get_bignum(challenge); 119bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_check_eom(); 120bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 121bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("Received RSA challenge from server."); 122bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 123bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Ask the agent to decrypt the challenge. */ 124d059297112922cabb0c674840589be8db821fd9aAdam Langley if ((r = ssh_decrypt_challenge(agent_fd, idlist->keys[i], 125d059297112922cabb0c674840589be8db821fd9aAdam Langley challenge, session_id, response)) != 0) { 126bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* 127bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * The agent failed to authenticate this identifier 128bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * although it advertised it supports this. Just 129bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * return a wrong value. 130bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 131d059297112922cabb0c674840589be8db821fd9aAdam Langley logit("Authentication agent failed to decrypt " 132d059297112922cabb0c674840589be8db821fd9aAdam Langley "challenge: %s", ssh_err(r)); 133d059297112922cabb0c674840589be8db821fd9aAdam Langley explicit_bzero(response, sizeof(response)); 134bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 135bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("Sending response to RSA challenge."); 136bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 137bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Send the decrypted challenge back to the server. */ 138bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_start(SSH_CMSG_AUTH_RSA_RESPONSE); 139bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman for (i = 0; i < 16; i++) 140bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_char(response[i]); 141bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_send(); 142bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_write_wait(); 143bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 144bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Wait for response from the server. */ 145bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman type = packet_read(); 146bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 147d059297112922cabb0c674840589be8db821fd9aAdam Langley /* 148d059297112922cabb0c674840589be8db821fd9aAdam Langley * The server returns success if it accepted the 149d059297112922cabb0c674840589be8db821fd9aAdam Langley * authentication. 150d059297112922cabb0c674840589be8db821fd9aAdam Langley */ 151bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (type == SSH_SMSG_SUCCESS) { 152bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("RSA authentication accepted by server."); 153d059297112922cabb0c674840589be8db821fd9aAdam Langley ret = 1; 154d059297112922cabb0c674840589be8db821fd9aAdam Langley break; 155d059297112922cabb0c674840589be8db821fd9aAdam Langley } else if (type != SSH_SMSG_FAILURE) 156d059297112922cabb0c674840589be8db821fd9aAdam Langley packet_disconnect("Protocol error waiting RSA auth " 157d059297112922cabb0c674840589be8db821fd9aAdam Langley "response: %d", type); 158bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 159d059297112922cabb0c674840589be8db821fd9aAdam Langley if (ret != 1) 160d059297112922cabb0c674840589be8db821fd9aAdam Langley debug("RSA authentication using agent refused."); 161d059297112922cabb0c674840589be8db821fd9aAdam Langley out: 162d059297112922cabb0c674840589be8db821fd9aAdam Langley ssh_free_identitylist(idlist); 163d059297112922cabb0c674840589be8db821fd9aAdam Langley ssh_close_authentication_socket(agent_fd); 164bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman BN_clear_free(challenge); 165d059297112922cabb0c674840589be8db821fd9aAdam Langley return ret; 166bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 167bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 168bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* 169bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Computes the proper response to a RSA challenge, and sends the response to 170bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * the server. 171bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 172bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstatic void 173bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanrespond_to_rsa_challenge(BIGNUM * challenge, RSA * prv) 174bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 175bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman u_char buf[32], response[16]; 176d059297112922cabb0c674840589be8db821fd9aAdam Langley struct ssh_digest_ctx *md; 177bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int i, len; 178bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 179bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Decrypt the challenge using the private key. */ 180bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* XXX think about Bleichenbacher, too */ 181d059297112922cabb0c674840589be8db821fd9aAdam Langley if (rsa_private_decrypt(challenge, challenge, prv) != 0) 182bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_disconnect( 183bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman "respond_to_rsa_challenge: rsa_private_decrypt failed"); 184bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 185bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Compute the response. */ 186bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* The response is MD5 of decrypted challenge plus session id. */ 187bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman len = BN_num_bytes(challenge); 188bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (len <= 0 || (u_int)len > sizeof(buf)) 189bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_disconnect( 190bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman "respond_to_rsa_challenge: bad challenge length %d", len); 191bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 192bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman memset(buf, 0, sizeof(buf)); 193bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman BN_bn2bin(challenge, buf + sizeof(buf) - len); 194d059297112922cabb0c674840589be8db821fd9aAdam Langley if ((md = ssh_digest_start(SSH_DIGEST_MD5)) == NULL || 195d059297112922cabb0c674840589be8db821fd9aAdam Langley ssh_digest_update(md, buf, 32) < 0 || 196d059297112922cabb0c674840589be8db821fd9aAdam Langley ssh_digest_update(md, session_id, 16) < 0 || 197d059297112922cabb0c674840589be8db821fd9aAdam Langley ssh_digest_final(md, response, sizeof(response)) < 0) 198d059297112922cabb0c674840589be8db821fd9aAdam Langley fatal("%s: md5 failed", __func__); 199d059297112922cabb0c674840589be8db821fd9aAdam Langley ssh_digest_free(md); 200bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 201bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("Sending response to host key RSA challenge."); 202bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 203bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Send the response back to the server. */ 204bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_start(SSH_CMSG_AUTH_RSA_RESPONSE); 205bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman for (i = 0; i < 16; i++) 206bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_char(response[i]); 207bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_send(); 208bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_write_wait(); 209bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 210d059297112922cabb0c674840589be8db821fd9aAdam Langley explicit_bzero(buf, sizeof(buf)); 211d059297112922cabb0c674840589be8db821fd9aAdam Langley explicit_bzero(response, sizeof(response)); 212d059297112922cabb0c674840589be8db821fd9aAdam Langley explicit_bzero(&md, sizeof(md)); 213bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 214bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 215bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* 216bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Checks if the user has authentication file, and if so, tries to authenticate 217bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * the user using it. 218bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 219bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstatic int 220bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmantry_rsa_authentication(int idx) 221bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 222bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman BIGNUM *challenge; 223bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman Key *public, *private; 224bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman char buf[300], *passphrase, *comment, *authfile; 225bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int i, perm_ok = 1, type, quit; 226bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 227bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman public = options.identity_keys[idx]; 228bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authfile = options.identity_files[idx]; 229bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman comment = xstrdup(authfile); 230bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 231bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("Trying RSA authentication with key '%.100s'", comment); 232bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 233bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Tell the server that we are willing to authenticate using this key. */ 234bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_start(SSH_CMSG_AUTH_RSA); 235bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_bignum(public->rsa->n); 236bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_send(); 237bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_write_wait(); 238bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 239bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Wait for server's response. */ 240bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman type = packet_read(); 241bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 242bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* 243bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * The server responds with failure if it doesn't like our key or 244bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * doesn't support RSA authentication. 245bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 246bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (type == SSH_SMSG_FAILURE) { 247bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("Server refused our key."); 248d059297112922cabb0c674840589be8db821fd9aAdam Langley free(comment); 249bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 0; 250bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 251bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Otherwise, the server should respond with a challenge. */ 252bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (type != SSH_SMSG_AUTH_RSA_CHALLENGE) 253bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_disconnect("Protocol error during RSA authentication: %d", type); 254bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 255bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Get the challenge from the packet. */ 256bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if ((challenge = BN_new()) == NULL) 257bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fatal("try_rsa_authentication: BN_new failed"); 258bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_get_bignum(challenge); 259bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_check_eom(); 260bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 261bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("Received RSA challenge from server."); 262bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 263bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* 264bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * If the key is not stored in external hardware, we have to 265bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * load the private key. Try first with empty passphrase; if it 266bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * fails, ask for a passphrase. 267bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 268d059297112922cabb0c674840589be8db821fd9aAdam Langley if (public->flags & SSHKEY_FLAG_EXT) 269bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman private = public; 270bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman else 271bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman private = key_load_private_type(KEY_RSA1, authfile, "", NULL, 272bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman &perm_ok); 273bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (private == NULL && !options.batch_mode && perm_ok) { 274bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman snprintf(buf, sizeof(buf), 275bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman "Enter passphrase for RSA key '%.100s': ", comment); 276bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman for (i = 0; i < options.number_of_password_prompts; i++) { 277bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman passphrase = read_passphrase(buf, 0); 278bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (strcmp(passphrase, "") != 0) { 279bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman private = key_load_private_type(KEY_RSA1, 280bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authfile, passphrase, NULL, NULL); 281bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman quit = 0; 282bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } else { 283bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug2("no passphrase given, try next key"); 284bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman quit = 1; 285bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 286d059297112922cabb0c674840589be8db821fd9aAdam Langley explicit_bzero(passphrase, strlen(passphrase)); 287d059297112922cabb0c674840589be8db821fd9aAdam Langley free(passphrase); 288bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (private != NULL || quit) 289bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman break; 290bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug2("bad passphrase given, try again..."); 291bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 292bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 293bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* We no longer need the comment. */ 294d059297112922cabb0c674840589be8db821fd9aAdam Langley free(comment); 295bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 296bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (private == NULL) { 297bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (!options.batch_mode && perm_ok) 298bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman error("Bad passphrase."); 299bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 300bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Send a dummy response packet to avoid protocol error. */ 301bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_start(SSH_CMSG_AUTH_RSA_RESPONSE); 302bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman for (i = 0; i < 16; i++) 303bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_char(0); 304bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_send(); 305bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_write_wait(); 306bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 307bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Expect the server to reject it... */ 308bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_read_expect(SSH_SMSG_FAILURE); 309bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman BN_clear_free(challenge); 310bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 0; 311bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 312bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 313bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Compute and send a response to the challenge. */ 314bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman respond_to_rsa_challenge(challenge, private->rsa); 315bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 316bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Destroy the private key unless it in external hardware. */ 317d059297112922cabb0c674840589be8db821fd9aAdam Langley if (!(private->flags & SSHKEY_FLAG_EXT)) 318bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman key_free(private); 319bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 320bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* We no longer need the challenge. */ 321bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman BN_clear_free(challenge); 322bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 323bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Wait for response from the server. */ 324bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman type = packet_read(); 325bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (type == SSH_SMSG_SUCCESS) { 326bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("RSA authentication accepted by server."); 327bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 1; 328bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 329bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (type != SSH_SMSG_FAILURE) 330bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_disconnect("Protocol error waiting RSA auth response: %d", type); 331bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("RSA authentication refused."); 332bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 0; 333bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 334bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 335bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* 336bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Tries to authenticate the user using combined rhosts or /etc/hosts.equiv 337bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * authentication and RSA host authentication. 338bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 339bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstatic int 340bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmantry_rhosts_rsa_authentication(const char *local_user, Key * host_key) 341bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 342bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int type; 343bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman BIGNUM *challenge; 344bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 345bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("Trying rhosts or /etc/hosts.equiv with RSA host authentication."); 346bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 347bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Tell the server that we are willing to authenticate using this key. */ 348bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_start(SSH_CMSG_AUTH_RHOSTS_RSA); 349bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_cstring(local_user); 350bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_int(BN_num_bits(host_key->rsa->n)); 351bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_bignum(host_key->rsa->e); 352bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_bignum(host_key->rsa->n); 353bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_send(); 354bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_write_wait(); 355bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 356bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Wait for server's response. */ 357bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman type = packet_read(); 358bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 359bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* The server responds with failure if it doesn't admit our 360bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman .rhosts authentication or doesn't know our host key. */ 361bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (type == SSH_SMSG_FAILURE) { 362bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("Server refused our rhosts authentication or host key."); 363bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 0; 364bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 365bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Otherwise, the server should respond with a challenge. */ 366bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (type != SSH_SMSG_AUTH_RSA_CHALLENGE) 367bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_disconnect("Protocol error during RSA authentication: %d", type); 368bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 369bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Get the challenge from the packet. */ 370bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if ((challenge = BN_new()) == NULL) 371bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fatal("try_rhosts_rsa_authentication: BN_new failed"); 372bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_get_bignum(challenge); 373bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_check_eom(); 374bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 375bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("Received RSA challenge for host key from server."); 376bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 377bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Compute a response to the challenge. */ 378bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman respond_to_rsa_challenge(challenge, host_key->rsa); 379bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 380bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* We no longer need the challenge. */ 381bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman BN_clear_free(challenge); 382bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 383bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Wait for response from the server. */ 384bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman type = packet_read(); 385bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (type == SSH_SMSG_SUCCESS) { 386bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("Rhosts or /etc/hosts.equiv with RSA host authentication accepted by server."); 387bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 1; 388bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 389bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (type != SSH_SMSG_FAILURE) 390bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_disconnect("Protocol error waiting RSA auth response: %d", type); 391bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("Rhosts or /etc/hosts.equiv with RSA host authentication refused."); 392bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 0; 393bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 394bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 395bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* 396bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Tries to authenticate with any string-based challenge/response system. 397bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Note that the client code is not tied to s/key or TIS. 398bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 399bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstatic int 400bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmantry_challenge_response_authentication(void) 401bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 402bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int type, i; 403bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman u_int clen; 404bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman char prompt[1024]; 405bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman char *challenge, *response; 406bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 407bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("Doing challenge response authentication."); 408bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 409bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman for (i = 0; i < options.number_of_password_prompts; i++) { 410bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* request a challenge */ 411bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_start(SSH_CMSG_AUTH_TIS); 412bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_send(); 413bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_write_wait(); 414bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 415bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman type = packet_read(); 416bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (type != SSH_SMSG_FAILURE && 417bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman type != SSH_SMSG_AUTH_TIS_CHALLENGE) { 418bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_disconnect("Protocol error: got %d in response " 419bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman "to SSH_CMSG_AUTH_TIS", type); 420bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 421bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (type != SSH_SMSG_AUTH_TIS_CHALLENGE) { 422bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("No challenge."); 423bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 0; 424bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 425bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman challenge = packet_get_string(&clen); 426bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_check_eom(); 427bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman snprintf(prompt, sizeof prompt, "%s%s", challenge, 428bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman strchr(challenge, '\n') ? "" : "\nResponse: "); 429d059297112922cabb0c674840589be8db821fd9aAdam Langley free(challenge); 430bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (i != 0) 431bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman error("Permission denied, please try again."); 432bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (options.cipher == SSH_CIPHER_NONE) 433bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman logit("WARNING: Encryption is disabled! " 434bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman "Response will be transmitted in clear text."); 435bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman response = read_passphrase(prompt, 0); 436bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (strcmp(response, "") == 0) { 437d059297112922cabb0c674840589be8db821fd9aAdam Langley free(response); 438bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman break; 439bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 440bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_start(SSH_CMSG_AUTH_TIS_RESPONSE); 441bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman ssh_put_password(response); 442d059297112922cabb0c674840589be8db821fd9aAdam Langley explicit_bzero(response, strlen(response)); 443d059297112922cabb0c674840589be8db821fd9aAdam Langley free(response); 444bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_send(); 445bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_write_wait(); 446bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman type = packet_read(); 447bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (type == SSH_SMSG_SUCCESS) 448bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 1; 449bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (type != SSH_SMSG_FAILURE) 450bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_disconnect("Protocol error: got %d in response " 451bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman "to SSH_CMSG_AUTH_TIS_RESPONSE", type); 452bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 453bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* failure */ 454bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 0; 455bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 456bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 457bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* 458bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Tries to authenticate with plain passwd authentication. 459bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 460bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstatic int 461bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmantry_password_authentication(char *prompt) 462bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 463bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int type, i; 464bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman char *password; 465bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 466bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("Doing password authentication."); 467bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (options.cipher == SSH_CIPHER_NONE) 468bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman logit("WARNING: Encryption is disabled! Password will be transmitted in clear text."); 469bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman for (i = 0; i < options.number_of_password_prompts; i++) { 470bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (i != 0) 471bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman error("Permission denied, please try again."); 472bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman password = read_passphrase(prompt, 0); 473bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_start(SSH_CMSG_AUTH_PASSWORD); 474bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman ssh_put_password(password); 475d059297112922cabb0c674840589be8db821fd9aAdam Langley explicit_bzero(password, strlen(password)); 476d059297112922cabb0c674840589be8db821fd9aAdam Langley free(password); 477bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_send(); 478bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_write_wait(); 479bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 480bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman type = packet_read(); 481bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (type == SSH_SMSG_SUCCESS) 482bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 1; 483bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (type != SSH_SMSG_FAILURE) 484bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_disconnect("Protocol error: got %d in response to passwd auth", type); 485bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 486bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* failure */ 487bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 0; 488bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 489bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 490bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* 491bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * SSH1 key exchange 492bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 493bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanvoid 494bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanssh_kex(char *host, struct sockaddr *hostaddr) 495bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 496bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int i; 497bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman BIGNUM *key; 498bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman Key *host_key, *server_key; 499bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int bits, rbits; 500bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int ssh_cipher_default = SSH_CIPHER_3DES; 501bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman u_char session_key[SSH_SESSION_KEY_LENGTH]; 502bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman u_char cookie[8]; 503bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman u_int supported_ciphers; 504bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman u_int server_flags, client_flags; 505bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman u_int32_t rnd = 0; 506bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 507bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("Waiting for server public key."); 508bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 509bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Wait for a public key packet from the server. */ 510bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_read_expect(SSH_SMSG_PUBLIC_KEY); 511bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 512bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Get cookie from the packet. */ 513bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman for (i = 0; i < 8; i++) 514bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman cookie[i] = packet_get_char(); 515bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 516bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Get the public key. */ 517bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman server_key = key_new(KEY_RSA1); 518bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman bits = packet_get_int(); 519bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_get_bignum(server_key->rsa->e); 520bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_get_bignum(server_key->rsa->n); 521bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 522bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman rbits = BN_num_bits(server_key->rsa->n); 523bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (bits != rbits) { 524bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman logit("Warning: Server lies about size of server public key: " 525bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman "actual size is %d bits vs. announced %d.", rbits, bits); 526bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman logit("Warning: This may be due to an old implementation of ssh."); 527bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 528bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Get the host key. */ 529bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman host_key = key_new(KEY_RSA1); 530bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman bits = packet_get_int(); 531bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_get_bignum(host_key->rsa->e); 532bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_get_bignum(host_key->rsa->n); 533bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 534bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman rbits = BN_num_bits(host_key->rsa->n); 535bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (bits != rbits) { 536bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman logit("Warning: Server lies about size of server host key: " 537bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman "actual size is %d bits vs. announced %d.", rbits, bits); 538bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman logit("Warning: This may be due to an old implementation of ssh."); 539bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 540bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 541bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Get protocol flags. */ 542bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman server_flags = packet_get_int(); 543bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_set_protocol_flags(server_flags); 544bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 545bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman supported_ciphers = packet_get_int(); 546bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman supported_authentications = packet_get_int(); 547bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_check_eom(); 548bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 549bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("Received server public key (%d bits) and host key (%d bits).", 550bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman BN_num_bits(server_key->rsa->n), BN_num_bits(host_key->rsa->n)); 551bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 552bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (verify_host_key(host, hostaddr, host_key) == -1) 553bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fatal("Host key verification failed."); 554bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 555bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN; 556bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 557bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman derive_ssh1_session_id(host_key->rsa->n, server_key->rsa->n, cookie, session_id); 558bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 559bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* 560bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Generate an encryption key for the session. The key is a 256 bit 561bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * random number, interpreted as a 32-byte key, with the least 562bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * significant 8 bits being the first byte of the key. 563bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 564bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman for (i = 0; i < 32; i++) { 565bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (i % 4 == 0) 566bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman rnd = arc4random(); 567bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman session_key[i] = rnd & 0xff; 568bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman rnd >>= 8; 569bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 570bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 571bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* 572bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * According to the protocol spec, the first byte of the session key 573bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * is the highest byte of the integer. The session key is xored with 574bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * the first 16 bytes of the session id. 575bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 576bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if ((key = BN_new()) == NULL) 577bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fatal("ssh_kex: BN_new failed"); 578bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (BN_set_word(key, 0) == 0) 579bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fatal("ssh_kex: BN_set_word failed"); 580bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++) { 581bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (BN_lshift(key, key, 8) == 0) 582bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fatal("ssh_kex: BN_lshift failed"); 583bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (i < 16) { 584bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (BN_add_word(key, session_key[i] ^ session_id[i]) 585bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman == 0) 586bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fatal("ssh_kex: BN_add_word failed"); 587bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } else { 588bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (BN_add_word(key, session_key[i]) == 0) 589bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fatal("ssh_kex: BN_add_word failed"); 590bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 591bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 592bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 593bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* 594bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Encrypt the integer using the public key and host key of the 595bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * server (key with smaller modulus first). 596bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 597bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (BN_cmp(server_key->rsa->n, host_key->rsa->n) < 0) { 598bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Public key has smaller modulus. */ 599bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (BN_num_bits(host_key->rsa->n) < 600bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman BN_num_bits(server_key->rsa->n) + SSH_KEY_BITS_RESERVED) { 601bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fatal("respond_to_rsa_challenge: host_key %d < server_key %d + " 602bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman "SSH_KEY_BITS_RESERVED %d", 603bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman BN_num_bits(host_key->rsa->n), 604bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman BN_num_bits(server_key->rsa->n), 605bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman SSH_KEY_BITS_RESERVED); 606bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 607d059297112922cabb0c674840589be8db821fd9aAdam Langley if (rsa_public_encrypt(key, key, server_key->rsa) != 0 || 608d059297112922cabb0c674840589be8db821fd9aAdam Langley rsa_public_encrypt(key, key, host_key->rsa) != 0) 609d059297112922cabb0c674840589be8db821fd9aAdam Langley fatal("%s: rsa_public_encrypt failed", __func__); 610bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } else { 611bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Host key has smaller modulus (or they are equal). */ 612bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (BN_num_bits(server_key->rsa->n) < 613bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman BN_num_bits(host_key->rsa->n) + SSH_KEY_BITS_RESERVED) { 614bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fatal("respond_to_rsa_challenge: server_key %d < host_key %d + " 615bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman "SSH_KEY_BITS_RESERVED %d", 616bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman BN_num_bits(server_key->rsa->n), 617bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman BN_num_bits(host_key->rsa->n), 618bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman SSH_KEY_BITS_RESERVED); 619bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 620d059297112922cabb0c674840589be8db821fd9aAdam Langley if (rsa_public_encrypt(key, key, host_key->rsa) != 0 || 621d059297112922cabb0c674840589be8db821fd9aAdam Langley rsa_public_encrypt(key, key, server_key->rsa) != 0) 622d059297112922cabb0c674840589be8db821fd9aAdam Langley fatal("%s: rsa_public_encrypt failed", __func__); 623bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 624bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 625bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Destroy the public keys since we no longer need them. */ 626bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman key_free(server_key); 627bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman key_free(host_key); 628bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 629bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (options.cipher == SSH_CIPHER_NOT_SET) { 630bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (cipher_mask_ssh1(1) & supported_ciphers & (1 << ssh_cipher_default)) 631bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman options.cipher = ssh_cipher_default; 632bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } else if (options.cipher == SSH_CIPHER_INVALID || 633bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman !(cipher_mask_ssh1(1) & (1 << options.cipher))) { 634bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman logit("No valid SSH1 cipher, using %.100s instead.", 635bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman cipher_name(ssh_cipher_default)); 636bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman options.cipher = ssh_cipher_default; 637bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 638bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Check that the selected cipher is supported. */ 639bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (!(supported_ciphers & (1 << options.cipher))) 640bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fatal("Selected cipher type %.100s not supported by server.", 641bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman cipher_name(options.cipher)); 642bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 643bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("Encryption type: %.100s", cipher_name(options.cipher)); 644bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 645bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Send the encrypted session key to the server. */ 646bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_start(SSH_CMSG_SESSION_KEY); 647bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_char(options.cipher); 648bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 649bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Send the cookie back to the server. */ 650bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman for (i = 0; i < 8; i++) 651bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_char(cookie[i]); 652bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 653bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Send and destroy the encrypted encryption key integer. */ 654bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_bignum(key); 655bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman BN_clear_free(key); 656bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 657bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Send protocol flags. */ 658bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_int(client_flags); 659bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 660bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Send the packet now. */ 661bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_send(); 662bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_write_wait(); 663bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 664bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("Sent encrypted session key."); 665bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 666bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Set the encryption key. */ 667bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, options.cipher); 668bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 669d059297112922cabb0c674840589be8db821fd9aAdam Langley /* 670d059297112922cabb0c674840589be8db821fd9aAdam Langley * We will no longer need the session key here. 671d059297112922cabb0c674840589be8db821fd9aAdam Langley * Destroy any extra copies. 672d059297112922cabb0c674840589be8db821fd9aAdam Langley */ 673d059297112922cabb0c674840589be8db821fd9aAdam Langley explicit_bzero(session_key, sizeof(session_key)); 674bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 675bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* 676bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Expect a success message from the server. Note that this message 677bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * will be received in encrypted form. 678bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 679bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_read_expect(SSH_SMSG_SUCCESS); 680bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 681bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("Received encrypted confirmation."); 682bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 683bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 684bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* 685bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Authenticate user 686bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 687bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanvoid 688bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanssh_userauth1(const char *local_user, const char *server_user, char *host, 689bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman Sensitive *sensitive) 690bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 691bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int i, type; 692bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 693bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (supported_authentications == 0) 694bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fatal("ssh_userauth1: server supports no auth methods"); 695bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 696bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Send the name of the user to log in as on the server. */ 697bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_start(SSH_CMSG_USER); 698bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_cstring(server_user); 699bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_send(); 700bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_write_wait(); 701bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 702bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* 703bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * The server should respond with success if no authentication is 704bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * needed (the user has no password). Otherwise the server responds 705bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * with failure. 706bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 707bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman type = packet_read(); 708bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 709bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* check whether the connection was accepted without authentication. */ 710bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (type == SSH_SMSG_SUCCESS) 711bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman goto success; 712bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (type != SSH_SMSG_FAILURE) 713bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_disconnect("Protocol error: got %d in response to SSH_CMSG_USER", type); 714bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 715bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* 716bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Try .rhosts or /etc/hosts.equiv authentication with RSA host 717bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * authentication. 718bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 719bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if ((supported_authentications & (1 << SSH_AUTH_RHOSTS_RSA)) && 720bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman options.rhosts_rsa_authentication) { 721bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman for (i = 0; i < sensitive->nkeys; i++) { 722bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (sensitive->keys[i] != NULL && 723bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman sensitive->keys[i]->type == KEY_RSA1 && 724bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman try_rhosts_rsa_authentication(local_user, 725bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman sensitive->keys[i])) 726bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman goto success; 727bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 728bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 729bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Try RSA authentication if the server supports it. */ 730bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if ((supported_authentications & (1 << SSH_AUTH_RSA)) && 731bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman options.rsa_authentication) { 732bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* 733bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Try RSA authentication using the authentication agent. The 734bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * agent is tried first because no passphrase is needed for 735bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * it, whereas identity files may require passphrases. 736bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 737bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (try_agent_authentication()) 738bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman goto success; 739bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 740bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Try RSA authentication for each identity. */ 741bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman for (i = 0; i < options.num_identity_files; i++) 742bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (options.identity_keys[i] != NULL && 743bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman options.identity_keys[i]->type == KEY_RSA1 && 744bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman try_rsa_authentication(i)) 745bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman goto success; 746bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 747bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Try challenge response authentication if the server supports it. */ 748bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if ((supported_authentications & (1 << SSH_AUTH_TIS)) && 749bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman options.challenge_response_authentication && !options.batch_mode) { 750bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (try_challenge_response_authentication()) 751bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman goto success; 752bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 753bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Try password authentication if the server supports it. */ 754bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if ((supported_authentications & (1 << SSH_AUTH_PASSWORD)) && 755bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman options.password_authentication && !options.batch_mode) { 756bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman char prompt[80]; 757bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 758bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ", 759bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman server_user, host); 760bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (try_password_authentication(prompt)) 761bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman goto success; 762bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 763bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* All authentication methods have failed. Exit with an error message. */ 764bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fatal("Permission denied."); 765bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* NOTREACHED */ 766bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 767bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman success: 768bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return; /* need statement after label */ 769bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 770d059297112922cabb0c674840589be8db821fd9aAdam Langley 771d059297112922cabb0c674840589be8db821fd9aAdam Langley#endif /* WITH_SSH1 */ 772