sshconnect1.c revision 60574
169450Smsmith/* 269450Smsmith * Author: Tatu Ylonen <ylo@cs.hut.fi> 3167802Sjkim * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 469450Smsmith * All rights reserved 569450Smsmith * Created: Sat Mar 18 22:15:47 1995 ylo 669450Smsmith * Code to connect to a remote host, and to perform the client side of the 769450Smsmith * login (authentication) dialog. 869450Smsmith * 969450Smsmith */ 1069450Smsmith 11193267Sjkim#include "includes.h" 1270243SmsmithRCSID("$OpenBSD: sshconnect1.c,v 1.3 2000/05/08 17:12:16 markus Exp $"); 1369450Smsmith 1469450Smsmith#include <openssl/bn.h> 1569450Smsmith#include <openssl/dsa.h> 1669450Smsmith#include <openssl/rsa.h> 1769450Smsmith#include <openssl/evp.h> 1869450Smsmith 1969450Smsmith#include "xmalloc.h" 2069450Smsmith#include "rsa.h" 2169450Smsmith#include "ssh.h" 2269450Smsmith#include "buffer.h" 2369450Smsmith#include "packet.h" 2469450Smsmith#include "authfd.h" 2569450Smsmith#include "cipher.h" 2669450Smsmith#include "mpaux.h" 2769450Smsmith#include "uidswap.h" 2869450Smsmith#include "readconf.h" 2969450Smsmith#include "key.h" 3069450Smsmith#include "sshconnect.h" 3169450Smsmith#include "authfile.h" 3269450Smsmith 3369450Smsmith/* Session id for the current session. */ 3469450Smsmithunsigned char session_id[16]; 3569450Smsmithunsigned int supported_authentications = 0; 3669450Smsmith 3769450Smsmithextern Options options; 3869450Smsmithextern char *__progname; 3969450Smsmith 4069450Smsmith/* 4169450Smsmith * Checks if the user has an authentication agent, and if so, tries to 4269450Smsmith * authenticate using the agent. 4369450Smsmith */ 4469450Smsmithint 4569450Smsmithtry_agent_authentication() 4669450Smsmith{ 4769450Smsmith int status, type; 4869450Smsmith char *comment; 4969450Smsmith AuthenticationConnection *auth; 5069450Smsmith unsigned char response[16]; 5169450Smsmith unsigned int i; 5269450Smsmith BIGNUM *e, *n, *challenge; 5369450Smsmith 5469450Smsmith /* Get connection to the agent. */ 5569450Smsmith auth = ssh_get_authentication_connection(); 5669450Smsmith if (!auth) 5769450Smsmith return 0; 5869450Smsmith 5969450Smsmith e = BN_new(); 6069450Smsmith n = BN_new(); 6169450Smsmith challenge = BN_new(); 6269450Smsmith 6369450Smsmith /* Loop through identities served by the agent. */ 6469450Smsmith for (status = ssh_get_first_identity(auth, e, n, &comment); 6569450Smsmith status; 6669450Smsmith status = ssh_get_next_identity(auth, e, n, &comment)) { 6769450Smsmith int plen, clen; 6869450Smsmith 6969450Smsmith /* Try this identity. */ 7069450Smsmith debug("Trying RSA authentication via agent with '%.100s'", comment); 7169450Smsmith xfree(comment); 7269450Smsmith 7369450Smsmith /* Tell the server that we are willing to authenticate using this key. */ 7469450Smsmith packet_start(SSH_CMSG_AUTH_RSA); 7569450Smsmith packet_put_bignum(n); 7669450Smsmith packet_send(); 7769450Smsmith packet_write_wait(); 7869450Smsmith 7969450Smsmith /* Wait for server's response. */ 8069450Smsmith type = packet_read(&plen); 8169450Smsmith 8269450Smsmith /* The server sends failure if it doesn\'t like our key or 8369450Smsmith does not support RSA authentication. */ 8469450Smsmith if (type == SSH_SMSG_FAILURE) { 8569450Smsmith debug("Server refused our key."); 8669450Smsmith continue; 8769450Smsmith } 8869450Smsmith /* Otherwise it should have sent a challenge. */ 8969450Smsmith if (type != SSH_SMSG_AUTH_RSA_CHALLENGE) 9069450Smsmith packet_disconnect("Protocol error during RSA authentication: %d", 9169450Smsmith type); 9269450Smsmith 9369450Smsmith packet_get_bignum(challenge, &clen); 9469450Smsmith 9569450Smsmith packet_integrity_check(plen, clen, type); 9669450Smsmith 9769450Smsmith debug("Received RSA challenge from server."); 9869450Smsmith 9969450Smsmith /* Ask the agent to decrypt the challenge. */ 10069450Smsmith if (!ssh_decrypt_challenge(auth, e, n, challenge, 10169450Smsmith session_id, 1, response)) { 10269450Smsmith /* The agent failed to authenticate this identifier although it 10369450Smsmith advertised it supports this. Just return a wrong value. */ 10469450Smsmith log("Authentication agent failed to decrypt challenge."); 10569450Smsmith memset(response, 0, sizeof(response)); 10669450Smsmith } 10769450Smsmith debug("Sending response to RSA challenge."); 10869450Smsmith 10969450Smsmith /* Send the decrypted challenge back to the server. */ 11069450Smsmith packet_start(SSH_CMSG_AUTH_RSA_RESPONSE); 11169450Smsmith for (i = 0; i < 16; i++) 11269450Smsmith packet_put_char(response[i]); 11369450Smsmith packet_send(); 11469450Smsmith packet_write_wait(); 11569450Smsmith 11669450Smsmith /* Wait for response from the server. */ 11769450Smsmith type = packet_read(&plen); 11869450Smsmith 119167802Sjkim /* The server returns success if it accepted the authentication. */ 120167802Sjkim if (type == SSH_SMSG_SUCCESS) { 121167802Sjkim debug("RSA authentication accepted by server."); 122167802Sjkim BN_clear_free(e); 123167802Sjkim BN_clear_free(n); 124167802Sjkim BN_clear_free(challenge); 125167802Sjkim return 1; 126167802Sjkim } 127167802Sjkim /* Otherwise it should return failure. */ 128167802Sjkim if (type != SSH_SMSG_FAILURE) 129167802Sjkim packet_disconnect("Protocol error waiting RSA auth response: %d", 130167802Sjkim type); 131167802Sjkim } 132167802Sjkim 133167802Sjkim BN_clear_free(e); 134167802Sjkim BN_clear_free(n); 135193267Sjkim BN_clear_free(challenge); 136167802Sjkim 137167802Sjkim debug("RSA authentication using agent refused."); 138167802Sjkim return 0; 139167802Sjkim} 140167802Sjkim 141193267Sjkim/* 142193267Sjkim * Computes the proper response to a RSA challenge, and sends the response to 143193267Sjkim * the server. 144167802Sjkim */ 145193267Sjkimvoid 146167802Sjkimrespond_to_rsa_challenge(BIGNUM * challenge, RSA * prv) 147167802Sjkim{ 148167802Sjkim unsigned char buf[32], response[16]; 149193267Sjkim MD5_CTX md; 150167802Sjkim int i, len; 151167802Sjkim 152167802Sjkim /* Decrypt the challenge using the private key. */ 153167802Sjkim rsa_private_decrypt(challenge, challenge, prv); 154167802Sjkim 155193267Sjkim /* Compute the response. */ 156193267Sjkim /* The response is MD5 of decrypted challenge plus session id. */ 157167802Sjkim len = BN_num_bytes(challenge); 158167802Sjkim if (len <= 0 || len > sizeof(buf)) 159167802Sjkim packet_disconnect("respond_to_rsa_challenge: bad challenge length %d", 160167802Sjkim len); 161167802Sjkim 162167802Sjkim memset(buf, 0, sizeof(buf)); 163167802Sjkim BN_bn2bin(challenge, buf + sizeof(buf) - len); 16469450Smsmith MD5_Init(&md); 16569450Smsmith MD5_Update(&md, buf, 32); 16691116Smsmith MD5_Update(&md, session_id, 16); 167167802Sjkim MD5_Final(response, &md); 168167802Sjkim 169167802Sjkim debug("Sending response to host key RSA challenge."); 17091116Smsmith 171167802Sjkim /* Send the response back to the server. */ 172167802Sjkim packet_start(SSH_CMSG_AUTH_RSA_RESPONSE); 173193267Sjkim for (i = 0; i < 16; i++) 174167802Sjkim packet_put_char(response[i]); 175167802Sjkim packet_send(); 17669450Smsmith packet_write_wait(); 177167802Sjkim 178167802Sjkim memset(buf, 0, sizeof(buf)); 179151937Sjkim memset(response, 0, sizeof(response)); 180167802Sjkim memset(&md, 0, sizeof(md)); 18169450Smsmith} 18269450Smsmith 183193267Sjkim/* 184193267Sjkim * Checks if the user has authentication file, and if so, tries to authenticate 185193267Sjkim * the user using it. 186193267Sjkim */ 187193267Sjkimint 188193267Sjkimtry_rsa_authentication(const char *authfile) 189193267Sjkim{ 190193267Sjkim BIGNUM *challenge; 191193267Sjkim Key *public; 192193267Sjkim Key *private; 193193267Sjkim char *passphrase, *comment; 194193267Sjkim int type, i; 195193267Sjkim int plen, clen; 196193267Sjkim 197193267Sjkim /* Try to load identification for the authentication key. */ 198167802Sjkim public = key_new(KEY_RSA); 199167802Sjkim if (!load_public_key(authfile, public, &comment)) { 200167802Sjkim key_free(public); 201167802Sjkim /* Could not load it. Fail. */ 202167802Sjkim return 0; 203167802Sjkim } 204167802Sjkim debug("Trying RSA authentication with key '%.100s'", comment); 205167802Sjkim 206167802Sjkim /* Tell the server that we are willing to authenticate using this key. */ 207167802Sjkim packet_start(SSH_CMSG_AUTH_RSA); 208167802Sjkim packet_put_bignum(public->rsa->n); 209167802Sjkim packet_send(); 210167802Sjkim packet_write_wait(); 211167802Sjkim 212167802Sjkim /* We no longer need the public key. */ 213167802Sjkim key_free(public); 214167802Sjkim 215167802Sjkim /* Wait for server's response. */ 216167802Sjkim type = packet_read(&plen); 217167802Sjkim 218167802Sjkim /* 219167802Sjkim * The server responds with failure if it doesn\'t like our key or 220167802Sjkim * doesn\'t support RSA authentication. 221167802Sjkim */ 222167802Sjkim if (type == SSH_SMSG_FAILURE) { 223167802Sjkim debug("Server refused our key."); 224167802Sjkim xfree(comment); 225167802Sjkim return 0; 226167802Sjkim } 227167802Sjkim /* Otherwise, the server should respond with a challenge. */ 228167802Sjkim if (type != SSH_SMSG_AUTH_RSA_CHALLENGE) 229167802Sjkim packet_disconnect("Protocol error during RSA authentication: %d", type); 230167802Sjkim 231167802Sjkim /* Get the challenge from the packet. */ 232167802Sjkim challenge = BN_new(); 233167802Sjkim packet_get_bignum(challenge, &clen); 234167802Sjkim 235167802Sjkim packet_integrity_check(plen, clen, type); 23691116Smsmith 237167802Sjkim debug("Received RSA challenge from server."); 23891116Smsmith 239167802Sjkim private = key_new(KEY_RSA); 240167802Sjkim /* 241167802Sjkim * Load the private key. Try first with empty passphrase; if it 242167802Sjkim * fails, ask for a passphrase. 24369450Smsmith */ 244167802Sjkim if (!load_private_key(authfile, "", private, NULL)) { 245167802Sjkim char buf[300]; 246167802Sjkim snprintf(buf, sizeof buf, "Enter passphrase for RSA key '%.100s': ", 247167802Sjkim comment); 248167802Sjkim if (!options.batch_mode) 249167802Sjkim passphrase = read_passphrase(buf, 0); 250167802Sjkim else { 25169450Smsmith debug("Will not query passphrase for %.100s in batch mode.", 252167802Sjkim comment); 253151937Sjkim passphrase = xstrdup(""); 254167802Sjkim } 255151937Sjkim 256167802Sjkim /* Load the authentication file using the pasphrase. */ 257167802Sjkim if (!load_private_key(authfile, passphrase, private, NULL)) { 258167802Sjkim memset(passphrase, 0, strlen(passphrase)); 259167802Sjkim xfree(passphrase); 260167802Sjkim error("Bad passphrase."); 261167802Sjkim 262167802Sjkim /* Send a dummy response packet to avoid protocol error. */ 263151937Sjkim packet_start(SSH_CMSG_AUTH_RSA_RESPONSE); 264167802Sjkim for (i = 0; i < 16; i++) 26569450Smsmith packet_put_char(0); 266167802Sjkim packet_send(); 267167802Sjkim packet_write_wait(); 268167802Sjkim 269167802Sjkim /* Expect the server to reject it... */ 270167802Sjkim packet_read_expect(&plen, SSH_SMSG_FAILURE); 271167802Sjkim xfree(comment); 272167802Sjkim return 0; 273167802Sjkim } 274167802Sjkim /* Destroy the passphrase. */ 275167802Sjkim memset(passphrase, 0, strlen(passphrase)); 276167802Sjkim xfree(passphrase); 277167802Sjkim } 278167802Sjkim /* We no longer need the comment. */ 279167802Sjkim xfree(comment); 28069450Smsmith 281167802Sjkim /* Compute and send a response to the challenge. */ 282167802Sjkim respond_to_rsa_challenge(challenge, private->rsa); 283167802Sjkim 284167802Sjkim /* Destroy the private key. */ 285167802Sjkim key_free(private); 286167802Sjkim 287167802Sjkim /* We no longer need the challenge. */ 288167802Sjkim BN_clear_free(challenge); 289167802Sjkim 290167802Sjkim /* Wait for response from the server. */ 291167802Sjkim type = packet_read(&plen); 292167802Sjkim if (type == SSH_SMSG_SUCCESS) { 293167802Sjkim debug("RSA authentication accepted by server."); 294167802Sjkim return 1; 295167802Sjkim } 296167802Sjkim if (type != SSH_SMSG_FAILURE) 297167802Sjkim packet_disconnect("Protocol error waiting RSA auth response: %d", type); 298167802Sjkim debug("RSA authentication refused."); 299167802Sjkim return 0; 300167802Sjkim} 301167802Sjkim 302167802Sjkim/* 303167802Sjkim * Tries to authenticate the user using combined rhosts or /etc/hosts.equiv 304167802Sjkim * authentication and RSA host authentication. 305167802Sjkim */ 306167802Sjkimint 307167802Sjkimtry_rhosts_rsa_authentication(const char *local_user, RSA * host_key) 308167802Sjkim{ 309167802Sjkim int type; 310167802Sjkim BIGNUM *challenge; 311167802Sjkim int plen, clen; 312167802Sjkim 313167802Sjkim debug("Trying rhosts or /etc/hosts.equiv with RSA host authentication."); 314167802Sjkim 315167802Sjkim /* Tell the server that we are willing to authenticate using this key. */ 316167802Sjkim packet_start(SSH_CMSG_AUTH_RHOSTS_RSA); 317167802Sjkim packet_put_string(local_user, strlen(local_user)); 318167802Sjkim packet_put_int(BN_num_bits(host_key->n)); 319167802Sjkim packet_put_bignum(host_key->e); 320167802Sjkim packet_put_bignum(host_key->n); 321167802Sjkim packet_send(); 322167802Sjkim packet_write_wait(); 323167802Sjkim 324167802Sjkim /* Wait for server's response. */ 325167802Sjkim type = packet_read(&plen); 326167802Sjkim 327167802Sjkim /* The server responds with failure if it doesn't admit our 328167802Sjkim .rhosts authentication or doesn't know our host key. */ 329167802Sjkim if (type == SSH_SMSG_FAILURE) { 330167802Sjkim debug("Server refused our rhosts authentication or host key."); 331193267Sjkim return 0; 332193267Sjkim } 333193267Sjkim /* Otherwise, the server should respond with a challenge. */ 334193267Sjkim if (type != SSH_SMSG_AUTH_RSA_CHALLENGE) 335193267Sjkim packet_disconnect("Protocol error during RSA authentication: %d", type); 336193267Sjkim 337193267Sjkim /* Get the challenge from the packet. */ 338193267Sjkim challenge = BN_new(); 339193267Sjkim packet_get_bignum(challenge, &clen); 340193267Sjkim 341193267Sjkim packet_integrity_check(plen, clen, type); 342193267Sjkim 343193267Sjkim debug("Received RSA challenge for host key from server."); 344193267Sjkim 345193267Sjkim /* Compute a response to the challenge. */ 346193267Sjkim respond_to_rsa_challenge(challenge, host_key); 347193267Sjkim 348193267Sjkim /* We no longer need the challenge. */ 349193267Sjkim BN_clear_free(challenge); 350193267Sjkim 351193267Sjkim /* Wait for response from the server. */ 352193267Sjkim type = packet_read(&plen); 353193267Sjkim if (type == SSH_SMSG_SUCCESS) { 354193267Sjkim debug("Rhosts or /etc/hosts.equiv with RSA host authentication accepted by server."); 355193267Sjkim return 1; 356193267Sjkim } 357193267Sjkim if (type != SSH_SMSG_FAILURE) 358193267Sjkim packet_disconnect("Protocol error waiting RSA auth response: %d", type); 359193267Sjkim debug("Rhosts or /etc/hosts.equiv with RSA host authentication refused."); 360193267Sjkim return 0; 361193267Sjkim} 362193267Sjkim 363193267Sjkim#ifdef KRB4 364193267Sjkimint 365193267Sjkimtry_kerberos_authentication() 366167802Sjkim{ 367167802Sjkim KTEXT_ST auth; /* Kerberos data */ 368167802Sjkim char *reply; 369167802Sjkim char inst[INST_SZ]; 370167802Sjkim char *realm; 371167802Sjkim CREDENTIALS cred; 372167802Sjkim int r, type, plen; 373167802Sjkim socklen_t slen; 374167802Sjkim Key_schedule schedule; 375167802Sjkim u_long checksum, cksum; 376167802Sjkim MSG_DAT msg_data; 377167802Sjkim struct sockaddr_in local, foreign; 378167802Sjkim struct stat st; 379167802Sjkim 380167802Sjkim /* Don't do anything if we don't have any tickets. */ 381167802Sjkim if (stat(tkt_string(), &st) < 0) 382167802Sjkim return 0; 383167802Sjkim 384167802Sjkim strncpy(inst, (char *) krb_get_phost(get_canonical_hostname()), INST_SZ); 385167802Sjkim 386167802Sjkim realm = (char *) krb_realmofhost(get_canonical_hostname()); 387167802Sjkim if (!realm) { 388167802Sjkim debug("Kerberos V4: no realm for %s", get_canonical_hostname()); 389167802Sjkim return 0; 390167802Sjkim } 391167802Sjkim /* This can really be anything. */ 392167802Sjkim checksum = (u_long) getpid(); 393167802Sjkim 394167802Sjkim r = krb_mk_req(&auth, KRB4_SERVICE_NAME, inst, realm, checksum); 395167802Sjkim if (r != KSUCCESS) { 396167802Sjkim debug("Kerberos V4 krb_mk_req failed: %s", krb_err_txt[r]); 397167802Sjkim return 0; 398167802Sjkim } 399167802Sjkim /* Get session key to decrypt the server's reply with. */ 400167802Sjkim r = krb_get_cred(KRB4_SERVICE_NAME, inst, realm, &cred); 401167802Sjkim if (r != KSUCCESS) { 402167802Sjkim debug("get_cred failed: %s", krb_err_txt[r]); 403167802Sjkim return 0; 404167802Sjkim } 405167802Sjkim des_key_sched((des_cblock *) cred.session, schedule); 406167802Sjkim 407167802Sjkim /* Send authentication info to server. */ 408167802Sjkim packet_start(SSH_CMSG_AUTH_KERBEROS); 409167802Sjkim packet_put_string((char *) auth.dat, auth.length); 410167802Sjkim packet_send(); 411167802Sjkim packet_write_wait(); 412167802Sjkim 413167802Sjkim /* Zero the buffer. */ 414167802Sjkim (void) memset(auth.dat, 0, MAX_KTXT_LEN); 415167802Sjkim 416167802Sjkim slen = sizeof(local); 417167802Sjkim memset(&local, 0, sizeof(local)); 418167802Sjkim if (getsockname(packet_get_connection_in(), 419167802Sjkim (struct sockaddr *) & local, &slen) < 0) 420167802Sjkim debug("getsockname failed: %s", strerror(errno)); 421167802Sjkim 422167802Sjkim slen = sizeof(foreign); 423167802Sjkim memset(&foreign, 0, sizeof(foreign)); 424167802Sjkim if (getpeername(packet_get_connection_in(), 425193267Sjkim (struct sockaddr *) & foreign, &slen) < 0) { 426167802Sjkim debug("getpeername failed: %s", strerror(errno)); 427167802Sjkim fatal_cleanup(); 428167802Sjkim } 429167802Sjkim /* Get server reply. */ 430167802Sjkim type = packet_read(&plen); 431167802Sjkim switch (type) { 432167802Sjkim case SSH_SMSG_FAILURE: 433193267Sjkim /* Should really be SSH_SMSG_AUTH_KERBEROS_FAILURE */ 434193267Sjkim debug("Kerberos V4 authentication failed."); 435167802Sjkim return 0; 436167802Sjkim break; 437167802Sjkim 438193267Sjkim case SSH_SMSG_AUTH_KERBEROS_RESPONSE: 439193267Sjkim /* SSH_SMSG_AUTH_KERBEROS_SUCCESS */ 440193267Sjkim debug("Kerberos V4 authentication accepted."); 441193267Sjkim 442167802Sjkim /* Get server's response. */ 443167802Sjkim reply = packet_get_string((unsigned int *) &auth.length); 444167802Sjkim memcpy(auth.dat, reply, auth.length); 445167802Sjkim xfree(reply); 446167802Sjkim 447167802Sjkim packet_integrity_check(plen, 4 + auth.length, type); 448167802Sjkim 449167802Sjkim /* 450167802Sjkim * If his response isn't properly encrypted with the session 451167802Sjkim * key, and the decrypted checksum fails to match, he's 452167802Sjkim * bogus. Bail out. 453167802Sjkim */ 454167802Sjkim r = krb_rd_priv(auth.dat, auth.length, schedule, &cred.session, 455167802Sjkim &foreign, &local, &msg_data); 456167802Sjkim if (r != KSUCCESS) { 457193267Sjkim debug("Kerberos V4 krb_rd_priv failed: %s", krb_err_txt[r]); 458193267Sjkim packet_disconnect("Kerberos V4 challenge failed!"); 459167802Sjkim } 460167802Sjkim /* Fetch the (incremented) checksum that we supplied in the request. */ 461167802Sjkim (void) memcpy((char *) &cksum, (char *) msg_data.app_data, sizeof(cksum)); 462167802Sjkim cksum = ntohl(cksum); 463167802Sjkim 464167802Sjkim /* If it matches, we're golden. */ 465193267Sjkim if (cksum == checksum + 1) { 466193267Sjkim debug("Kerberos V4 challenge successful."); 467167802Sjkim return 1; 468167802Sjkim } else 469167802Sjkim packet_disconnect("Kerberos V4 challenge failed!"); 470167802Sjkim break; 471167802Sjkim 472167802Sjkim default: 473167802Sjkim packet_disconnect("Protocol error on Kerberos V4 response: %d", type); 474167802Sjkim } 475167802Sjkim return 0; 476167802Sjkim} 477167802Sjkim 478193267Sjkim#endif /* KRB4 */ 479193267Sjkim 480193267Sjkim#ifdef AFS 481167802Sjkimint 482167802Sjkimsend_kerberos_tgt() 483193267Sjkim{ 484193267Sjkim CREDENTIALS *creds; 485193267Sjkim char pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ]; 486193267Sjkim int r, type, plen; 487167802Sjkim char buffer[8192]; 488193267Sjkim struct stat st; 489193267Sjkim 49091116Smsmith /* Don't do anything if we don't have any tickets. */ 491167802Sjkim if (stat(tkt_string(), &st) < 0) 49291116Smsmith return 0; 493167802Sjkim 494167802Sjkim creds = xmalloc(sizeof(*creds)); 495167802Sjkim 496167802Sjkim if ((r = krb_get_tf_fullname(TKT_FILE, pname, pinst, prealm)) != KSUCCESS) { 49769450Smsmith debug("Kerberos V4 tf_fullname failed: %s", krb_err_txt[r]); 498167802Sjkim return 0; 499193267Sjkim } 500193267Sjkim if ((r = krb_get_cred("krbtgt", prealm, prealm, creds)) != GC_OK) { 501193267Sjkim debug("Kerberos V4 get_cred failed: %s", krb_err_txt[r]); 502167802Sjkim return 0; 50369450Smsmith } 504167802Sjkim if (time(0) > krb_life_to_time(creds->issue_date, creds->lifetime)) { 505151937Sjkim debug("Kerberos V4 ticket expired: %s", TKT_FILE); 506167802Sjkim return 0; 507151937Sjkim } 508167802Sjkim creds_to_radix(creds, (unsigned char *)buffer, sizeof buffer); 50969450Smsmith xfree(creds); 510167802Sjkim 511167802Sjkim packet_start(SSH_CMSG_HAVE_KERBEROS_TGT); 512167802Sjkim packet_put_string(buffer, strlen(buffer)); 513167802Sjkim packet_send(); 514167802Sjkim packet_write_wait(); 515193267Sjkim 516193267Sjkim type = packet_read(&plen); 517193267Sjkim 518167802Sjkim if (type == SSH_SMSG_FAILURE) 519167802Sjkim debug("Kerberos TGT for realm %s rejected.", prealm); 520167802Sjkim else if (type != SSH_SMSG_SUCCESS) 521167802Sjkim packet_disconnect("Protocol error on Kerberos TGT response: %d", type); 522167802Sjkim 523167802Sjkim return 1; 524167802Sjkim} 525167802Sjkim 526193267Sjkimvoid 527167802Sjkimsend_afs_tokens(void) 528193267Sjkim{ 529193267Sjkim CREDENTIALS creds; 530193267Sjkim struct ViceIoctl parms; 531193267Sjkim struct ClearToken ct; 532193267Sjkim int i, type, len, plen; 533193267Sjkim char buf[2048], *p, *server_cell; 534193267Sjkim char buffer[8192]; 535193267Sjkim 536193267Sjkim /* Move over ktc_GetToken, here's something leaner. */ 537193267Sjkim for (i = 0; i < 100; i++) { /* just in case */ 538193267Sjkim parms.in = (char *) &i; 539193267Sjkim parms.in_size = sizeof(i); 540193267Sjkim parms.out = buf; 541193267Sjkim parms.out_size = sizeof(buf); 542167802Sjkim if (k_pioctl(0, VIOCGETTOK, &parms, 0) != 0) 543167802Sjkim break; 544167802Sjkim p = buf; 545167802Sjkim 546167802Sjkim /* Get secret token. */ 547167802Sjkim memcpy(&creds.ticket_st.length, p, sizeof(unsigned int)); 548167802Sjkim if (creds.ticket_st.length > MAX_KTXT_LEN) 549167802Sjkim break; 550167802Sjkim p += sizeof(unsigned int); 551167802Sjkim memcpy(creds.ticket_st.dat, p, creds.ticket_st.length); 552167802Sjkim p += creds.ticket_st.length; 553167802Sjkim 554167802Sjkim /* Get clear token. */ 555167802Sjkim memcpy(&len, p, sizeof(len)); 556167802Sjkim if (len != sizeof(struct ClearToken)) 557167802Sjkim break; 558167802Sjkim p += sizeof(len); 559167802Sjkim memcpy(&ct, p, len); 560167802Sjkim p += len; 561167802Sjkim p += sizeof(len); /* primary flag */ 562193267Sjkim server_cell = p; 563193267Sjkim 564193267Sjkim /* Flesh out our credentials. */ 565193267Sjkim strlcpy(creds.service, "afs", sizeof creds.service); 566193267Sjkim creds.instance[0] = '\0'; 567193267Sjkim strlcpy(creds.realm, server_cell, REALM_SZ); 568193267Sjkim memcpy(creds.session, ct.HandShakeKey, DES_KEY_SZ); 569193267Sjkim creds.issue_date = ct.BeginTimestamp; 570193267Sjkim creds.lifetime = krb_time_to_life(creds.issue_date, ct.EndTimestamp); 571193267Sjkim creds.kvno = ct.AuthHandle; 572193267Sjkim snprintf(creds.pname, sizeof(creds.pname), "AFS ID %d", ct.ViceId); 573193267Sjkim creds.pinst[0] = '\0'; 574193267Sjkim 575193267Sjkim /* Encode token, ship it off. */ 576193267Sjkim if (creds_to_radix(&creds, (unsigned char*) buffer, sizeof buffer) <= 0) 577193267Sjkim break; 578193267Sjkim packet_start(SSH_CMSG_HAVE_AFS_TOKEN); 579193267Sjkim packet_put_string(buffer, strlen(buffer)); 580193267Sjkim packet_send(); 581193267Sjkim packet_write_wait(); 582193267Sjkim 583193267Sjkim /* Roger, Roger. Clearance, Clarence. What's your vector, 584193267Sjkim Victor? */ 585193267Sjkim type = packet_read(&plen); 586193267Sjkim 587193267Sjkim if (type == SSH_SMSG_FAILURE) 588193267Sjkim debug("AFS token for cell %s rejected.", server_cell); 589193267Sjkim else if (type != SSH_SMSG_SUCCESS) 590193267Sjkim packet_disconnect("Protocol error on AFS token response: %d", type); 591193267Sjkim } 592193267Sjkim} 593193267Sjkim 594193267Sjkim#endif /* AFS */ 595193267Sjkim 596193267Sjkim/* 597193267Sjkim * Tries to authenticate with any string-based challenge/response system. 598193267Sjkim * Note that the client code is not tied to s/key or TIS. 599193267Sjkim */ 600193267Sjkimint 601193267Sjkimtry_skey_authentication() 602193267Sjkim{ 603193267Sjkim int type, i; 604193267Sjkim int payload_len; 605193267Sjkim unsigned int clen; 606193267Sjkim char *challenge, *response; 607193267Sjkim 608193267Sjkim debug("Doing skey authentication."); 609193267Sjkim 610193267Sjkim /* request a challenge */ 611193267Sjkim packet_start(SSH_CMSG_AUTH_TIS); 612193267Sjkim packet_send(); 613193267Sjkim packet_write_wait(); 614193267Sjkim 615193267Sjkim type = packet_read(&payload_len); 616193267Sjkim if (type != SSH_SMSG_FAILURE && 617193267Sjkim type != SSH_SMSG_AUTH_TIS_CHALLENGE) { 618193267Sjkim packet_disconnect("Protocol error: got %d in response " 619193267Sjkim "to skey-auth", type); 620193267Sjkim } 621193267Sjkim if (type != SSH_SMSG_AUTH_TIS_CHALLENGE) { 622193267Sjkim debug("No challenge for skey authentication."); 623193267Sjkim return 0; 624193267Sjkim } 625193267Sjkim challenge = packet_get_string(&clen); 626193267Sjkim packet_integrity_check(payload_len, (4 + clen), type); 627193267Sjkim if (options.cipher == SSH_CIPHER_NONE) 628193267Sjkim log("WARNING: Encryption is disabled! " 629193267Sjkim "Reponse will be transmitted in clear text."); 630193267Sjkim fprintf(stderr, "%s\n", challenge); 631193267Sjkim xfree(challenge); 632193267Sjkim fflush(stderr); 633193267Sjkim for (i = 0; i < options.number_of_password_prompts; i++) { 634193267Sjkim if (i != 0) 635193267Sjkim error("Permission denied, please try again."); 636193267Sjkim response = read_passphrase("Response: ", 0); 637193267Sjkim packet_start(SSH_CMSG_AUTH_TIS_RESPONSE); 638193267Sjkim packet_put_string(response, strlen(response)); 639193267Sjkim memset(response, 0, strlen(response)); 640193267Sjkim xfree(response); 641193267Sjkim packet_send(); 642193267Sjkim packet_write_wait(); 643193267Sjkim type = packet_read(&payload_len); 644193267Sjkim if (type == SSH_SMSG_SUCCESS) 645193267Sjkim return 1; 646193267Sjkim if (type != SSH_SMSG_FAILURE) 647193267Sjkim packet_disconnect("Protocol error: got %d in response " 648193267Sjkim "to skey-auth-reponse", type); 649193267Sjkim } 650193267Sjkim /* failure */ 651193267Sjkim return 0; 652193267Sjkim} 653193267Sjkim 654193267Sjkim/* 655193267Sjkim * Tries to authenticate with plain passwd authentication. 656193267Sjkim */ 657193267Sjkimint 658193267Sjkimtry_password_authentication(char *prompt) 659193267Sjkim{ 660193267Sjkim int type, i, payload_len; 661193267Sjkim char *password; 662193267Sjkim 663193267Sjkim debug("Doing password authentication."); 664193267Sjkim if (options.cipher == SSH_CIPHER_NONE) 665193267Sjkim log("WARNING: Encryption is disabled! Password will be transmitted in clear text."); 666193267Sjkim for (i = 0; i < options.number_of_password_prompts; i++) { 667193267Sjkim if (i != 0) 668193267Sjkim error("Permission denied, please try again."); 669193267Sjkim password = read_passphrase(prompt, 0); 670193267Sjkim packet_start(SSH_CMSG_AUTH_PASSWORD); 671193267Sjkim packet_put_string(password, strlen(password)); 672193267Sjkim memset(password, 0, strlen(password)); 673193267Sjkim xfree(password); 674193267Sjkim packet_send(); 675193267Sjkim packet_write_wait(); 676193267Sjkim 677193267Sjkim type = packet_read(&payload_len); 678193267Sjkim if (type == SSH_SMSG_SUCCESS) 679193267Sjkim return 1; 680193267Sjkim if (type != SSH_SMSG_FAILURE) 681193267Sjkim packet_disconnect("Protocol error: got %d in response to passwd auth", type); 682193267Sjkim } 683193267Sjkim /* failure */ 684193267Sjkim return 0; 685193267Sjkim} 686193267Sjkim 687193267Sjkim/* 688193267Sjkim * SSH1 key exchange 689193267Sjkim */ 690193267Sjkimvoid 691193267Sjkimssh_kex(char *host, struct sockaddr *hostaddr) 692193267Sjkim{ 693193267Sjkim int i; 694193267Sjkim BIGNUM *key; 695193267Sjkim RSA *host_key; 696193267Sjkim RSA *public_key; 697193267Sjkim Key k; 698193267Sjkim int bits, rbits; 699193267Sjkim int ssh_cipher_default = SSH_CIPHER_3DES; 700193267Sjkim unsigned char session_key[SSH_SESSION_KEY_LENGTH]; 701193267Sjkim unsigned char cookie[8]; 702193267Sjkim unsigned int supported_ciphers; 703193267Sjkim unsigned int server_flags, client_flags; 704193267Sjkim int payload_len, clen, sum_len = 0; 705193267Sjkim u_int32_t rand = 0; 706193267Sjkim 707193267Sjkim debug("Waiting for server public key."); 708193267Sjkim 709193267Sjkim /* Wait for a public key packet from the server. */ 710193267Sjkim packet_read_expect(&payload_len, SSH_SMSG_PUBLIC_KEY); 711193267Sjkim 712193267Sjkim /* Get cookie from the packet. */ 713193267Sjkim for (i = 0; i < 8; i++) 714193267Sjkim cookie[i] = packet_get_char(); 715193267Sjkim 716193267Sjkim /* Get the public key. */ 717193267Sjkim public_key = RSA_new(); 718193267Sjkim bits = packet_get_int();/* bits */ 719193267Sjkim public_key->e = BN_new(); 720193267Sjkim packet_get_bignum(public_key->e, &clen); 721193267Sjkim sum_len += clen; 722193267Sjkim public_key->n = BN_new(); 723193267Sjkim packet_get_bignum(public_key->n, &clen); 724193267Sjkim sum_len += clen; 725193267Sjkim 726193267Sjkim rbits = BN_num_bits(public_key->n); 727193267Sjkim if (bits != rbits) { 728193267Sjkim log("Warning: Server lies about size of server public key: " 729193267Sjkim "actual size is %d bits vs. announced %d.", rbits, bits); 730193267Sjkim log("Warning: This may be due to an old implementation of ssh."); 731193267Sjkim } 732193267Sjkim /* Get the host key. */ 733193267Sjkim host_key = RSA_new(); 734193267Sjkim bits = packet_get_int();/* bits */ 735193267Sjkim host_key->e = BN_new(); 736193267Sjkim packet_get_bignum(host_key->e, &clen); 737193267Sjkim sum_len += clen; 738193267Sjkim host_key->n = BN_new(); 739193267Sjkim packet_get_bignum(host_key->n, &clen); 740193267Sjkim sum_len += clen; 741193267Sjkim 742193267Sjkim rbits = BN_num_bits(host_key->n); 743193267Sjkim if (bits != rbits) { 744193267Sjkim log("Warning: Server lies about size of server host key: " 745193267Sjkim "actual size is %d bits vs. announced %d.", rbits, bits); 746193267Sjkim log("Warning: This may be due to an old implementation of ssh."); 747193267Sjkim } 748193267Sjkim 749193267Sjkim /* Get protocol flags. */ 750193267Sjkim server_flags = packet_get_int(); 751193267Sjkim packet_set_protocol_flags(server_flags); 752193267Sjkim 753193267Sjkim supported_ciphers = packet_get_int(); 754193267Sjkim supported_authentications = packet_get_int(); 755193267Sjkim 756193267Sjkim debug("Received server public key (%d bits) and host key (%d bits).", 757193267Sjkim BN_num_bits(public_key->n), BN_num_bits(host_key->n)); 758193267Sjkim 759193267Sjkim packet_integrity_check(payload_len, 760193267Sjkim 8 + 4 + sum_len + 0 + 4 + 0 + 0 + 4 + 4 + 4, 761193267Sjkim SSH_SMSG_PUBLIC_KEY); 762193267Sjkim k.type = KEY_RSA; 763193267Sjkim k.rsa = host_key; 764193267Sjkim check_host_key(host, hostaddr, &k, 765193267Sjkim options.user_hostfile, options.system_hostfile); 766193267Sjkim 767193267Sjkim client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN; 768193267Sjkim 769193267Sjkim compute_session_id(session_id, cookie, host_key->n, public_key->n); 770193267Sjkim 771193267Sjkim /* Generate a session key. */ 772193267Sjkim arc4random_stir(); 773193267Sjkim 774193267Sjkim /* 775193267Sjkim * Generate an encryption key for the session. The key is a 256 bit 776193267Sjkim * random number, interpreted as a 32-byte key, with the least 777193267Sjkim * significant 8 bits being the first byte of the key. 778193267Sjkim */ 779193267Sjkim for (i = 0; i < 32; i++) { 780193267Sjkim if (i % 4 == 0) 781193267Sjkim rand = arc4random(); 782193267Sjkim session_key[i] = rand & 0xff; 783193267Sjkim rand >>= 8; 784193267Sjkim } 785193267Sjkim 786193267Sjkim /* 787193267Sjkim * According to the protocol spec, the first byte of the session key 788193267Sjkim * is the highest byte of the integer. The session key is xored with 789193267Sjkim * the first 16 bytes of the session id. 790193267Sjkim */ 791193267Sjkim key = BN_new(); 792193267Sjkim BN_set_word(key, 0); 793193267Sjkim for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++) { 794193267Sjkim BN_lshift(key, key, 8); 795193267Sjkim if (i < 16) 796193267Sjkim BN_add_word(key, session_key[i] ^ session_id[i]); 797193267Sjkim else 798193267Sjkim BN_add_word(key, session_key[i]); 799193267Sjkim } 800193267Sjkim 801193267Sjkim /* 802193267Sjkim * Encrypt the integer using the public key and host key of the 803193267Sjkim * server (key with smaller modulus first). 804193267Sjkim */ 805193267Sjkim if (BN_cmp(public_key->n, host_key->n) < 0) { 806193267Sjkim /* Public key has smaller modulus. */ 807193267Sjkim if (BN_num_bits(host_key->n) < 808193267Sjkim BN_num_bits(public_key->n) + SSH_KEY_BITS_RESERVED) { 809193267Sjkim fatal("respond_to_rsa_challenge: host_key %d < public_key %d + " 810193267Sjkim "SSH_KEY_BITS_RESERVED %d", 811193267Sjkim BN_num_bits(host_key->n), 812193267Sjkim BN_num_bits(public_key->n), 813193267Sjkim SSH_KEY_BITS_RESERVED); 814193267Sjkim } 815193267Sjkim rsa_public_encrypt(key, key, public_key); 816193267Sjkim rsa_public_encrypt(key, key, host_key); 817193267Sjkim } else { 818193267Sjkim /* Host key has smaller modulus (or they are equal). */ 819193267Sjkim if (BN_num_bits(public_key->n) < 820193267Sjkim BN_num_bits(host_key->n) + SSH_KEY_BITS_RESERVED) { 821193267Sjkim fatal("respond_to_rsa_challenge: public_key %d < host_key %d + " 822193267Sjkim "SSH_KEY_BITS_RESERVED %d", 823193267Sjkim BN_num_bits(public_key->n), 824193267Sjkim BN_num_bits(host_key->n), 825193267Sjkim SSH_KEY_BITS_RESERVED); 826193267Sjkim } 827193267Sjkim rsa_public_encrypt(key, key, host_key); 828193267Sjkim rsa_public_encrypt(key, key, public_key); 829193267Sjkim } 830193267Sjkim 831193267Sjkim /* Destroy the public keys since we no longer need them. */ 832193267Sjkim RSA_free(public_key); 833193267Sjkim RSA_free(host_key); 834193267Sjkim 835193267Sjkim if (options.cipher == SSH_CIPHER_ILLEGAL) { 836193267Sjkim log("No valid SSH1 cipher, using %.100s instead.", 837193267Sjkim cipher_name(SSH_FALLBACK_CIPHER)); 838193267Sjkim options.cipher = SSH_FALLBACK_CIPHER; 839193267Sjkim } else if (options.cipher == SSH_CIPHER_NOT_SET) { 840193267Sjkim if (cipher_mask1() & supported_ciphers & (1 << ssh_cipher_default)) 841193267Sjkim options.cipher = ssh_cipher_default; 842193267Sjkim else { 843193267Sjkim debug("Cipher %s not supported, using %.100s instead.", 844193267Sjkim cipher_name(ssh_cipher_default), 845193267Sjkim cipher_name(SSH_FALLBACK_CIPHER)); 846193267Sjkim options.cipher = SSH_FALLBACK_CIPHER; 847193267Sjkim } 848193267Sjkim } 849193267Sjkim /* Check that the selected cipher is supported. */ 850193267Sjkim if (!(supported_ciphers & (1 << options.cipher))) 851193267Sjkim fatal("Selected cipher type %.100s not supported by server.", 852193267Sjkim cipher_name(options.cipher)); 853193267Sjkim 854193267Sjkim debug("Encryption type: %.100s", cipher_name(options.cipher)); 855193267Sjkim 856193267Sjkim /* Send the encrypted session key to the server. */ 857193267Sjkim packet_start(SSH_CMSG_SESSION_KEY); 858193267Sjkim packet_put_char(options.cipher); 859193267Sjkim 860193267Sjkim /* Send the cookie back to the server. */ 861193267Sjkim for (i = 0; i < 8; i++) 862193267Sjkim packet_put_char(cookie[i]); 863193267Sjkim 864193267Sjkim /* Send and destroy the encrypted encryption key integer. */ 865193267Sjkim packet_put_bignum(key); 866193267Sjkim BN_clear_free(key); 867193267Sjkim 868193267Sjkim /* Send protocol flags. */ 869193267Sjkim packet_put_int(client_flags); 870193267Sjkim 871193267Sjkim /* Send the packet now. */ 872193267Sjkim packet_send(); 873193267Sjkim packet_write_wait(); 874193267Sjkim 875193267Sjkim debug("Sent encrypted session key."); 876193267Sjkim 877193267Sjkim /* Set the encryption key. */ 878193267Sjkim packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, options.cipher); 879193267Sjkim 880193267Sjkim /* We will no longer need the session key here. Destroy any extra copies. */ 881193267Sjkim memset(session_key, 0, sizeof(session_key)); 882193267Sjkim 883193267Sjkim /* 884193267Sjkim * Expect a success message from the server. Note that this message 885193267Sjkim * will be received in encrypted form. 886193267Sjkim */ 887193267Sjkim packet_read_expect(&payload_len, SSH_SMSG_SUCCESS); 888193267Sjkim 889193267Sjkim debug("Received encrypted confirmation."); 890193267Sjkim} 891193267Sjkim 892193267Sjkim/* 893193267Sjkim * Authenticate user 894193267Sjkim */ 895193267Sjkimvoid 896193267Sjkimssh_userauth( 897193267Sjkim const char* local_user, 898193267Sjkim const char* server_user, 899193267Sjkim char *host, 900193267Sjkim int host_key_valid, RSA *own_host_key) 901193267Sjkim{ 902193267Sjkim int i, type; 903193267Sjkim int payload_len; 904193267Sjkim 905193267Sjkim if (supported_authentications == 0) 906193267Sjkim fatal("ssh_userauth: server supports no auth methods"); 907193267Sjkim 908193267Sjkim /* Send the name of the user to log in as on the server. */ 909193267Sjkim packet_start(SSH_CMSG_USER); 910193267Sjkim packet_put_string(server_user, strlen(server_user)); 911193267Sjkim packet_send(); 912193267Sjkim packet_write_wait(); 913193267Sjkim 914193267Sjkim /* 915193267Sjkim * The server should respond with success if no authentication is 916193267Sjkim * needed (the user has no password). Otherwise the server responds 917193267Sjkim * with failure. 918193267Sjkim */ 919193267Sjkim type = packet_read(&payload_len); 920193267Sjkim 921193267Sjkim /* check whether the connection was accepted without authentication. */ 922193267Sjkim if (type == SSH_SMSG_SUCCESS) 923193267Sjkim return; 924193267Sjkim if (type != SSH_SMSG_FAILURE) 925193267Sjkim packet_disconnect("Protocol error: got %d in response to SSH_CMSG_USER", 926193267Sjkim type); 927193267Sjkim 928193267Sjkim#ifdef AFS 929193267Sjkim /* Try Kerberos tgt passing if the server supports it. */ 930193267Sjkim if ((supported_authentications & (1 << SSH_PASS_KERBEROS_TGT)) && 931193267Sjkim options.kerberos_tgt_passing) { 932193267Sjkim if (options.cipher == SSH_CIPHER_NONE) 933193267Sjkim log("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!"); 934193267Sjkim (void) send_kerberos_tgt(); 935193267Sjkim } 936193267Sjkim /* Try AFS token passing if the server supports it. */ 937193267Sjkim if ((supported_authentications & (1 << SSH_PASS_AFS_TOKEN)) && 938193267Sjkim options.afs_token_passing && k_hasafs()) { 939193267Sjkim if (options.cipher == SSH_CIPHER_NONE) 940193267Sjkim log("WARNING: Encryption is disabled! Token will be transmitted in the clear!"); 941193267Sjkim send_afs_tokens(); 942193267Sjkim } 943193267Sjkim#endif /* AFS */ 944193267Sjkim 945193267Sjkim#ifdef KRB4 946193267Sjkim if ((supported_authentications & (1 << SSH_AUTH_KERBEROS)) && 947193267Sjkim options.kerberos_authentication) { 948193267Sjkim debug("Trying Kerberos authentication."); 949193267Sjkim if (try_kerberos_authentication()) { 950193267Sjkim /* The server should respond with success or failure. */ 951193267Sjkim type = packet_read(&payload_len); 952193267Sjkim if (type == SSH_SMSG_SUCCESS) 953193267Sjkim return; 954193267Sjkim if (type != SSH_SMSG_FAILURE) 955193267Sjkim packet_disconnect("Protocol error: got %d in response to Kerberos auth", type); 956193267Sjkim } 957193267Sjkim } 958193267Sjkim#endif /* KRB4 */ 959193267Sjkim 960193267Sjkim /* 961193267Sjkim * Use rhosts authentication if running in privileged socket and we 962193267Sjkim * do not wish to remain anonymous. 963193267Sjkim */ 964193267Sjkim if ((supported_authentications & (1 << SSH_AUTH_RHOSTS)) && 965193267Sjkim options.rhosts_authentication) { 966193267Sjkim debug("Trying rhosts authentication."); 967193267Sjkim packet_start(SSH_CMSG_AUTH_RHOSTS); 968193267Sjkim packet_put_string(local_user, strlen(local_user)); 969193267Sjkim packet_send(); 970193267Sjkim packet_write_wait(); 971193267Sjkim 972193267Sjkim /* The server should respond with success or failure. */ 973193267Sjkim type = packet_read(&payload_len); 974193267Sjkim if (type == SSH_SMSG_SUCCESS) 975167802Sjkim return; 976167802Sjkim if (type != SSH_SMSG_FAILURE) 977167802Sjkim packet_disconnect("Protocol error: got %d in response to rhosts auth", 978167802Sjkim type); 979167802Sjkim } 980167802Sjkim /* 981167802Sjkim * Try .rhosts or /etc/hosts.equiv authentication with RSA host 982167802Sjkim * authentication. 983167802Sjkim */ 984167802Sjkim if ((supported_authentications & (1 << SSH_AUTH_RHOSTS_RSA)) && 985167802Sjkim options.rhosts_rsa_authentication && host_key_valid) { 986167802Sjkim if (try_rhosts_rsa_authentication(local_user, own_host_key)) 987167802Sjkim return; 988167802Sjkim } 989167802Sjkim /* Try RSA authentication if the server supports it. */ 990167802Sjkim if ((supported_authentications & (1 << SSH_AUTH_RSA)) && 991167802Sjkim options.rsa_authentication) { 992167802Sjkim /* 993167802Sjkim * Try RSA authentication using the authentication agent. The 994167802Sjkim * agent is tried first because no passphrase is needed for 995167802Sjkim * it, whereas identity files may require passphrases. 996167802Sjkim */ 997167802Sjkim if (try_agent_authentication()) 998167802Sjkim return; 999167802Sjkim 1000167802Sjkim /* Try RSA authentication for each identity. */ 1001193267Sjkim for (i = 0; i < options.num_identity_files; i++) 1002193267Sjkim if (try_rsa_authentication(options.identity_files[i])) 1003193267Sjkim return; 1004193267Sjkim } 1005193267Sjkim /* Try skey authentication if the server supports it. */ 1006193267Sjkim if ((supported_authentications & (1 << SSH_AUTH_TIS)) && 1007193267Sjkim options.skey_authentication && !options.batch_mode) { 1008193267Sjkim if (try_skey_authentication()) 1009193267Sjkim return; 1010193267Sjkim } 1011193267Sjkim /* Try password authentication if the server supports it. */ 1012193267Sjkim if ((supported_authentications & (1 << SSH_AUTH_PASSWORD)) && 1013193267Sjkim options.password_authentication && !options.batch_mode) { 1014193267Sjkim char prompt[80]; 1015193267Sjkim 1016193267Sjkim snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ", 1017193267Sjkim server_user, host); 1018193267Sjkim if (try_password_authentication(prompt)) 1019193267Sjkim return; 1020193267Sjkim } 1021193267Sjkim /* All authentication methods have failed. Exit with an error message. */ 1022193267Sjkim fatal("Permission denied."); 1023193267Sjkim /* NOTREACHED */ 1024193267Sjkim} 1025193267Sjkim