2 /* $OpenBSD: sshconnect1.c,v 1.70 2006/11/06 21:25:28 markus Exp $ */
4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
5 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
7 * Code to connect to a remote host, and to perform the client side of the
8 * login (authentication) dialog.
10 * As far as I am concerned, the code I have written for this software
11 * can be used freely for any purpose. Any derived versions of this
12 * software must be clearly marked as such, and if the derived work is
13 * incompatible with the protocol description in the RFC file, it must be
14 * called by a name other than "ssh" or "Secure Shell".
18 __RCSID("$NetBSD: sshconnect1.c,v 1.32 2007/03/10 22:52:10 christos Exp $");
19 #include <sys/types.h>
20 #include <sys/socket.h>
23 #include <openssl/bn.h>
24 #include <openssl/md5.h>
57 #include "sshconnect.h"
64 /* Session id for the current session. */
65 u_char session_id
[16];
66 u_int supported_authentications
= 0;
68 extern Options options
;
69 extern char *__progname
;
72 * Checks if the user has an authentication agent, and if so, tries to
73 * authenticate using the agent.
76 try_agent_authentication(void)
80 AuthenticationConnection
*auth
;
86 /* Get connection to the agent. */
87 auth
= ssh_get_authentication_connection();
91 if ((challenge
= BN_new()) == NULL
)
92 fatal("try_agent_authentication: BN_new failed");
93 /* Loop through identities served by the agent. */
94 for (key
= ssh_get_first_identity(auth
, &comment
, 1);
96 key
= ssh_get_next_identity(auth
, &comment
, 1)) {
98 /* Try this identity. */
99 debug("Trying RSA authentication via agent with '%.100s'", comment
);
102 /* Tell the server that we are willing to authenticate using this key. */
103 packet_start(SSH_CMSG_AUTH_RSA
);
104 packet_put_bignum(key
->rsa
->n
);
108 /* Wait for server's response. */
109 type
= packet_read();
111 /* The server sends failure if it doesn't like our key or
112 does not support RSA authentication. */
113 if (type
== SSH_SMSG_FAILURE
) {
114 debug("Server refused our key.");
118 /* Otherwise it should have sent a challenge. */
119 if (type
!= SSH_SMSG_AUTH_RSA_CHALLENGE
)
120 packet_disconnect("Protocol error during RSA authentication: %d",
123 packet_get_bignum(challenge
);
126 debug("Received RSA challenge from server.");
128 /* Ask the agent to decrypt the challenge. */
129 if (!ssh_decrypt_challenge(auth
, key
, challenge
, session_id
, 1, response
)) {
131 * The agent failed to authenticate this identifier
132 * although it advertised it supports this. Just
133 * return a wrong value.
135 logit("Authentication agent failed to decrypt challenge.");
136 memset(response
, 0, sizeof(response
));
139 debug("Sending response to RSA challenge.");
141 /* Send the decrypted challenge back to the server. */
142 packet_start(SSH_CMSG_AUTH_RSA_RESPONSE
);
143 for (i
= 0; i
< 16; i
++)
144 packet_put_char(response
[i
]);
148 /* Wait for response from the server. */
149 type
= packet_read();
151 /* The server returns success if it accepted the authentication. */
152 if (type
== SSH_SMSG_SUCCESS
) {
153 ssh_close_authentication_connection(auth
);
154 BN_clear_free(challenge
);
155 debug("RSA authentication accepted by server.");
158 /* Otherwise it should return failure. */
159 if (type
!= SSH_SMSG_FAILURE
)
160 packet_disconnect("Protocol error waiting RSA auth response: %d",
163 ssh_close_authentication_connection(auth
);
164 BN_clear_free(challenge
);
165 debug("RSA authentication using agent refused.");
170 * Computes the proper response to a RSA challenge, and sends the response to
174 respond_to_rsa_challenge(BIGNUM
* challenge
, RSA
* prv
)
176 u_char buf
[32], response
[16];
180 /* Decrypt the challenge using the private key. */
181 /* XXX think about Bleichenbacher, too */
182 if (rsa_private_decrypt(challenge
, challenge
, prv
) <= 0)
184 "respond_to_rsa_challenge: rsa_private_decrypt failed");
186 /* Compute the response. */
187 /* The response is MD5 of decrypted challenge plus session id. */
188 len
= BN_num_bytes(challenge
);
189 if (len
<= 0 || (u_int
)len
> sizeof(buf
))
191 "respond_to_rsa_challenge: bad challenge length %d", len
);
193 memset(buf
, 0, sizeof(buf
));
194 BN_bn2bin(challenge
, buf
+ sizeof(buf
) - len
);
196 MD5_Update(&md
, buf
, 32);
197 MD5_Update(&md
, session_id
, 16);
198 MD5_Final(response
, &md
);
200 debug("Sending response to host key RSA challenge.");
202 /* Send the response back to the server. */
203 packet_start(SSH_CMSG_AUTH_RSA_RESPONSE
);
204 for (i
= 0; i
< 16; i
++)
205 packet_put_char(response
[i
]);
209 memset(buf
, 0, sizeof(buf
));
210 memset(response
, 0, sizeof(response
));
211 memset(&md
, 0, sizeof(md
));
216 try_krb4_authentication(void)
218 KTEXT_ST auth
; /* Kerberos data */
225 Key_schedule schedule
;
226 u_long checksum
, cksum
;
228 struct sockaddr_in local
, foreign
;
231 /* Don't do anything if we don't have any tickets. */
232 if (stat(tkt_string(), &st
) < 0)
235 strlcpy(inst
, (char *)krb_get_phost(get_canonical_hostname(1)),
238 realm
= (char *)krb_realmofhost(get_canonical_hostname(1));
240 debug("Kerberos v4: no realm for %s", get_canonical_hostname(1));
243 /* This can really be anything. */
244 checksum
= (u_long
)getpid();
246 r
= krb_mk_req(&auth
, KRB4_SERVICE_NAME
, inst
, realm
, checksum
);
248 debug("Kerberos v4 krb_mk_req failed: %s", krb_err_txt
[r
]);
251 /* Get session key to decrypt the server's reply with. */
252 r
= krb_get_cred(KRB4_SERVICE_NAME
, inst
, realm
, &cred
);
254 debug("get_cred failed: %s", krb_err_txt
[r
]);
257 des_key_sched((des_cblock
*) cred
.session
, schedule
);
259 /* Send authentication info to server. */
260 packet_start(SSH_CMSG_AUTH_KERBEROS
);
261 packet_put_string((char *) auth
.dat
, auth
.length
);
265 /* Zero the buffer. */
266 (void) memset(auth
.dat
, 0, MAX_KTXT_LEN
);
268 slen
= sizeof(local
);
269 memset(&local
, 0, sizeof(local
));
270 if (getsockname(packet_get_connection_in(),
271 (struct sockaddr
*)&local
, &slen
) < 0)
272 debug("getsockname failed: %s", strerror(errno
));
274 slen
= sizeof(foreign
);
275 memset(&foreign
, 0, sizeof(foreign
));
276 if (getpeername(packet_get_connection_in(),
277 (struct sockaddr
*)&foreign
, &slen
) < 0) {
278 debug("getpeername failed: %s", strerror(errno
));
281 /* Get server reply. */
282 type
= packet_read();
284 case SSH_SMSG_FAILURE
:
285 /* Should really be SSH_SMSG_AUTH_KERBEROS_FAILURE */
286 debug("Kerberos v4 authentication failed.");
290 case SSH_SMSG_AUTH_KERBEROS_RESPONSE
:
291 /* SSH_SMSG_AUTH_KERBEROS_SUCCESS */
292 debug("Kerberos v4 authentication accepted.");
294 /* Get server's response. */
295 reply
= packet_get_string((u_int
*) &auth
.length
);
296 if (auth
.length
>= MAX_KTXT_LEN
)
297 fatal("Kerberos v4: Malformed response from server");
298 memcpy(auth
.dat
, reply
, auth
.length
);
304 * If his response isn't properly encrypted with the session
305 * key, and the decrypted checksum fails to match, he's
308 r
= krb_rd_priv(auth
.dat
, auth
.length
, (void *)schedule
,
309 &cred
.session
, &foreign
, &local
, &msg_data
);
311 debug("Kerberos v4 krb_rd_priv failed: %s",
313 packet_disconnect("Kerberos v4 challenge failed!");
315 /* Fetch the (incremented) checksum that we supplied in the request. */
316 memcpy((char *)&cksum
, (char *)msg_data
.app_data
,
318 cksum
= ntohl(cksum
);
320 /* If it matches, we're golden. */
321 if (cksum
== checksum
+ 1) {
322 debug("Kerberos v4 challenge successful.");
325 packet_disconnect("Kerberos v4 challenge failed!");
329 packet_disconnect("Protocol error on Kerberos v4 response: %d", type
);
337 * Checks if the user has authentication file, and if so, tries to authenticate
341 try_rsa_authentication(int idx
)
344 Key
*public, *private;
345 char buf
[300], *passphrase
, *comment
, *authfile
;
346 int i
, perm_ok
= 1, type
, quit
;
348 public = options
.identity_keys
[idx
];
349 authfile
= options
.identity_files
[idx
];
350 comment
= xstrdup(authfile
);
352 debug("Trying RSA authentication with key '%.100s'", comment
);
354 /* Tell the server that we are willing to authenticate using this key. */
355 packet_start(SSH_CMSG_AUTH_RSA
);
356 packet_put_bignum(public->rsa
->n
);
360 /* Wait for server's response. */
361 type
= packet_read();
364 * The server responds with failure if it doesn't like our key or
365 * doesn't support RSA authentication.
367 if (type
== SSH_SMSG_FAILURE
) {
368 debug("Server refused our key.");
372 /* Otherwise, the server should respond with a challenge. */
373 if (type
!= SSH_SMSG_AUTH_RSA_CHALLENGE
)
374 packet_disconnect("Protocol error during RSA authentication: %d", type
);
376 /* Get the challenge from the packet. */
377 if ((challenge
= BN_new()) == NULL
)
378 fatal("try_rsa_authentication: BN_new failed");
379 packet_get_bignum(challenge
);
382 debug("Received RSA challenge from server.");
385 * If the key is not stored in external hardware, we have to
386 * load the private key. Try first with empty passphrase; if it
387 * fails, ask for a passphrase.
389 if (public->flags
& KEY_FLAG_EXT
)
392 private = key_load_private_type(KEY_RSA1
, authfile
, "", NULL
,
394 if (private == NULL
&& !options
.batch_mode
&& perm_ok
) {
395 snprintf(buf
, sizeof(buf
),
396 "Enter passphrase for RSA key '%.100s': ", comment
);
397 for (i
= 0; i
< options
.number_of_password_prompts
; i
++) {
398 passphrase
= read_passphrase(buf
, 0);
399 if (strcmp(passphrase
, "") != 0) {
400 private = key_load_private_type(KEY_RSA1
,
401 authfile
, passphrase
, NULL
, NULL
);
404 debug2("no passphrase given, try next key");
407 memset(passphrase
, 0, strlen(passphrase
));
409 if (private != NULL
|| quit
)
411 debug2("bad passphrase given, try again...");
414 /* We no longer need the comment. */
417 if (private == NULL
) {
418 if (!options
.batch_mode
&& perm_ok
)
419 error("Bad passphrase.");
421 /* Send a dummy response packet to avoid protocol error. */
422 packet_start(SSH_CMSG_AUTH_RSA_RESPONSE
);
423 for (i
= 0; i
< 16; i
++)
428 /* Expect the server to reject it... */
429 packet_read_expect(SSH_SMSG_FAILURE
);
430 BN_clear_free(challenge
);
434 /* Compute and send a response to the challenge. */
435 respond_to_rsa_challenge(challenge
, private->rsa
);
437 /* Destroy the private key unless it in external hardware. */
438 if (!(private->flags
& KEY_FLAG_EXT
))
441 /* We no longer need the challenge. */
442 BN_clear_free(challenge
);
444 /* Wait for response from the server. */
445 type
= packet_read();
446 if (type
== SSH_SMSG_SUCCESS
) {
447 debug("RSA authentication accepted by server.");
450 if (type
!= SSH_SMSG_FAILURE
)
451 packet_disconnect("Protocol error waiting RSA auth response: %d", type
);
452 debug("RSA authentication refused.");
458 try_krb5_authentication(krb5_context
*context
, krb5_auth_context
*auth_context
)
460 krb5_error_code problem
;
463 krb5_ccache ccache
= NULL
;
464 const char *remotehost
;
467 krb5_ap_rep_enc_part
*reply
= NULL
;
470 memset(&ap
, 0, sizeof(ap
));
472 problem
= krb5_init_context(context
);
474 debug("Kerberos v5: krb5_init_context failed");
479 tkfile
= krb5_cc_default_name(*context
);
480 if (strncmp(tkfile
, "FILE:", 5) == 0)
483 if (stat(tkfile
, &buf
) == 0 && getuid() != buf
.st_uid
) {
484 debug("Kerberos v5: could not get default ccache (permission denied).");
489 problem
= krb5_cc_default(*context
, &ccache
);
491 debug("Kerberos v5: krb5_cc_default failed: %s",
492 krb5_get_err_text(*context
, problem
));
497 remotehost
= get_canonical_hostname(1);
499 problem
= krb5_mk_req(*context
, auth_context
, AP_OPTS_MUTUAL_REQUIRED
,
500 "host", remotehost
, NULL
, ccache
, &ap
);
502 debug("Kerberos v5: krb5_mk_req failed: %s",
503 krb5_get_err_text(*context
, problem
));
508 packet_start(SSH_CMSG_AUTH_KERBEROS
);
509 packet_put_string((char *) ap
.data
, ap
.length
);
516 type
= packet_read();
518 case SSH_SMSG_FAILURE
:
519 /* Should really be SSH_SMSG_AUTH_KERBEROS_FAILURE */
520 debug("Kerberos v5 authentication failed.");
524 case SSH_SMSG_AUTH_KERBEROS_RESPONSE
:
525 /* SSH_SMSG_AUTH_KERBEROS_SUCCESS */
526 debug("Kerberos v5 authentication accepted.");
528 /* Get server's response. */
529 ap
.data
= packet_get_string((unsigned int *) &ap
.length
);
531 /* XXX je to dobre? */
533 problem
= krb5_rd_rep(*context
, *auth_context
, &ap
, &reply
);
541 packet_disconnect("Protocol error on Kerberos v5 response: %d",
550 krb5_cc_close(*context
, ccache
);
552 krb5_free_ap_rep_enc_part(*context
, reply
);
560 send_krb5_tgt(krb5_context context
, krb5_auth_context auth_context
)
563 krb5_error_code problem
;
565 krb5_ccache ccache
= NULL
;
567 krb5_kdc_flags flags
;
568 const char *remotehost
;
570 memset(&creds
, 0, sizeof(creds
));
571 memset(&outbuf
, 0, sizeof(outbuf
));
573 fd
= packet_get_connection_in();
575 problem
= krb5_auth_con_setaddrs_from_fd(context
, auth_context
, &fd
);
579 problem
= krb5_cc_default(context
, &ccache
);
583 problem
= krb5_cc_get_principal(context
, ccache
, &creds
.client
);
587 problem
= krb5_build_principal(context
, &creds
.server
,
588 strlen(creds
.client
->realm
), creds
.client
->realm
,
589 "krbtgt", creds
.client
->realm
, NULL
);
593 creds
.times
.endtime
= 0;
596 flags
.b
.forwarded
= 1;
597 flags
.b
.forwardable
= krb5_config_get_bool(context
, NULL
,
598 "libdefaults", "forwardable", NULL
);
600 remotehost
= get_canonical_hostname(1);
602 problem
= krb5_get_forwarded_creds(context
, auth_context
,
603 ccache
, flags
.i
, remotehost
, &creds
, &outbuf
);
607 packet_start(SSH_CMSG_HAVE_KERBEROS_TGT
);
608 packet_put_string((char *)outbuf
.data
, outbuf
.length
);
612 type
= packet_read();
614 if (type
== SSH_SMSG_SUCCESS
) {
617 krb5_unparse_name(context
, creds
.client
, &pname
);
618 debug("Kerberos v5 TGT forwarded (%s).", pname
);
621 debug("Kerberos v5 TGT forwarding failed.");
627 debug("Kerberos v5 TGT forwarding failed: %s",
628 krb5_get_err_text(context
, problem
));
630 krb5_free_principal(context
, creds
.client
);
632 krb5_free_principal(context
, creds
.server
);
634 krb5_cc_close(context
, ccache
);
647 char buffer
[4096], pname
[ANAME_SZ
], pinst
[INST_SZ
], prealm
[REALM_SZ
];
650 /* Don't do anything if we don't have any tickets. */
651 if (stat(tkt_string(), &st
) < 0)
654 creds
= xmalloc(sizeof(*creds
));
656 problem
= krb_get_tf_fullname(TKT_FILE
, pname
, pinst
, prealm
);
660 problem
= krb_get_cred("krbtgt", prealm
, prealm
, creds
);
664 if (time(0) > krb_life_to_time(creds
->issue_date
, creds
->lifetime
)) {
668 creds_to_radix(creds
, (u_char
*)buffer
, sizeof(buffer
));
670 packet_start(SSH_CMSG_HAVE_KERBEROS_TGT
);
671 packet_put_cstring(buffer
);
675 type
= packet_read();
677 if (type
== SSH_SMSG_SUCCESS
)
678 debug("Kerberos v4 TGT forwarded (%s%s%s@%s).",
679 creds
->pname
, creds
->pinst
[0] ? "." : "",
680 creds
->pinst
, creds
->realm
);
682 debug("Kerberos v4 TGT rejected.");
688 debug("Kerberos v4 TGT passing failed: %s", krb_err_txt
[problem
]);
693 send_afs_tokens(void)
696 struct ViceIoctl parms
;
697 struct ClearToken ct
;
699 char buf
[2048], *p
, *server_cell
;
702 /* Move over ktc_GetToken, here's something leaner. */
703 for (i
= 0; i
< 100; i
++) { /* just in case */
704 parms
.in
= (char *) &i
;
705 parms
.in_size
= sizeof(i
);
707 parms
.out_size
= sizeof(buf
);
708 if (k_pioctl(0, VIOCGETTOK
, &parms
, 0) != 0)
712 /* Get secret token. */
713 memcpy(&creds
.ticket_st
.length
, p
, sizeof(u_int
));
714 if (creds
.ticket_st
.length
> MAX_KTXT_LEN
)
717 memcpy(creds
.ticket_st
.dat
, p
, creds
.ticket_st
.length
);
718 p
+= creds
.ticket_st
.length
;
720 /* Get clear token. */
721 memcpy(&len
, p
, sizeof(len
));
722 if (len
!= sizeof(struct ClearToken
))
727 p
+= sizeof(len
); /* primary flag */
730 /* Flesh out our credentials. */
731 strlcpy(creds
.service
, "afs", sizeof(creds
.service
));
732 creds
.instance
[0] = '\0';
733 strlcpy(creds
.realm
, server_cell
, REALM_SZ
);
734 memcpy(creds
.session
, ct
.HandShakeKey
, DES_KEY_SZ
);
735 creds
.issue_date
= ct
.BeginTimestamp
;
736 creds
.lifetime
= krb_time_to_life(creds
.issue_date
,
738 creds
.kvno
= ct
.AuthHandle
;
739 snprintf(creds
.pname
, sizeof(creds
.pname
), "AFS ID %d", ct
.ViceId
);
740 creds
.pinst
[0] = '\0';
742 /* Encode token, ship it off. */
743 if (creds_to_radix(&creds
, (u_char
*)buffer
,
744 sizeof(buffer
)) <= 0)
746 packet_start(SSH_CMSG_HAVE_AFS_TOKEN
);
747 packet_put_cstring(buffer
);
751 /* Roger, Roger. Clearance, Clarence. What's your vector,
753 type
= packet_read();
755 if (type
== SSH_SMSG_FAILURE
)
756 debug("AFS token for cell %s rejected.", server_cell
);
757 else if (type
!= SSH_SMSG_SUCCESS
)
758 packet_disconnect("Protocol error on AFS token response: %d", type
);
766 * Tries to authenticate the user using combined rhosts or /etc/hosts.equiv
767 * authentication and RSA host authentication.
770 try_rhosts_rsa_authentication(const char *local_user
, Key
* host_key
)
775 debug("Trying rhosts or /etc/hosts.equiv with RSA host authentication.");
777 /* Tell the server that we are willing to authenticate using this key. */
778 packet_start(SSH_CMSG_AUTH_RHOSTS_RSA
);
779 packet_put_cstring(local_user
);
780 packet_put_int(BN_num_bits(host_key
->rsa
->n
));
781 packet_put_bignum(host_key
->rsa
->e
);
782 packet_put_bignum(host_key
->rsa
->n
);
786 /* Wait for server's response. */
787 type
= packet_read();
789 /* The server responds with failure if it doesn't admit our
790 .rhosts authentication or doesn't know our host key. */
791 if (type
== SSH_SMSG_FAILURE
) {
792 debug("Server refused our rhosts authentication or host key.");
795 /* Otherwise, the server should respond with a challenge. */
796 if (type
!= SSH_SMSG_AUTH_RSA_CHALLENGE
)
797 packet_disconnect("Protocol error during RSA authentication: %d", type
);
799 /* Get the challenge from the packet. */
800 if ((challenge
= BN_new()) == NULL
)
801 fatal("try_rhosts_rsa_authentication: BN_new failed");
802 packet_get_bignum(challenge
);
805 debug("Received RSA challenge for host key from server.");
807 /* Compute a response to the challenge. */
808 respond_to_rsa_challenge(challenge
, host_key
->rsa
);
810 /* We no longer need the challenge. */
811 BN_clear_free(challenge
);
813 /* Wait for response from the server. */
814 type
= packet_read();
815 if (type
== SSH_SMSG_SUCCESS
) {
816 debug("Rhosts or /etc/hosts.equiv with RSA host authentication accepted by server.");
819 if (type
!= SSH_SMSG_FAILURE
)
820 packet_disconnect("Protocol error waiting RSA auth response: %d", type
);
821 debug("Rhosts or /etc/hosts.equiv with RSA host authentication refused.");
826 * Tries to authenticate with any string-based challenge/response system.
827 * Note that the client code is not tied to s/key or TIS.
830 try_challenge_response_authentication(void)
835 char *challenge
, *response
;
837 debug("Doing challenge response authentication.");
839 for (i
= 0; i
< options
.number_of_password_prompts
; i
++) {
840 /* request a challenge */
841 packet_start(SSH_CMSG_AUTH_TIS
);
845 type
= packet_read();
846 if (type
!= SSH_SMSG_FAILURE
&&
847 type
!= SSH_SMSG_AUTH_TIS_CHALLENGE
) {
848 packet_disconnect("Protocol error: got %d in response "
849 "to SSH_CMSG_AUTH_TIS", type
);
851 if (type
!= SSH_SMSG_AUTH_TIS_CHALLENGE
) {
852 debug("No challenge.");
855 challenge
= packet_get_string(&clen
);
857 snprintf(prompt
, sizeof prompt
, "%s%s", challenge
,
858 strchr(challenge
, '\n') ? "" : "\nResponse: ");
861 error("Permission denied, please try again.");
862 if (options
.cipher
== SSH_CIPHER_NONE
)
863 logit("WARNING: Encryption is disabled! "
864 "Response will be transmitted in clear text.");
865 response
= read_passphrase(prompt
, 0);
866 if (strcmp(response
, "") == 0) {
870 packet_start(SSH_CMSG_AUTH_TIS_RESPONSE
);
871 ssh_put_password(response
);
872 memset(response
, 0, strlen(response
));
876 type
= packet_read();
877 if (type
== SSH_SMSG_SUCCESS
)
879 if (type
!= SSH_SMSG_FAILURE
)
880 packet_disconnect("Protocol error: got %d in response "
881 "to SSH_CMSG_AUTH_TIS_RESPONSE", type
);
888 * Tries to authenticate with plain passwd authentication.
891 try_password_authentication(char *prompt
)
896 debug("Doing password authentication.");
897 if (options
.cipher
== SSH_CIPHER_NONE
)
898 logit("WARNING: Encryption is disabled! Password will be transmitted in clear text.");
899 for (i
= 0; i
< options
.number_of_password_prompts
; i
++) {
901 error("Permission denied, please try again.");
902 password
= read_passphrase(prompt
, 0);
903 packet_start(SSH_CMSG_AUTH_PASSWORD
);
904 ssh_put_password(password
);
905 memset(password
, 0, strlen(password
));
910 type
= packet_read();
911 if (type
== SSH_SMSG_SUCCESS
)
913 if (type
!= SSH_SMSG_FAILURE
)
914 packet_disconnect("Protocol error: got %d in response to passwd auth", type
);
924 ssh_kex(char *host
, struct sockaddr
*hostaddr
)
928 Key
*host_key
, *server_key
;
930 int ssh_cipher_default
= SSH_CIPHER_3DES
;
931 u_char session_key
[SSH_SESSION_KEY_LENGTH
];
933 u_int supported_ciphers
;
934 u_int server_flags
, client_flags
;
937 debug("Waiting for server public key.");
939 /* Wait for a public key packet from the server. */
940 packet_read_expect(SSH_SMSG_PUBLIC_KEY
);
942 /* Get cookie from the packet. */
943 for (i
= 0; i
< 8; i
++)
944 cookie
[i
] = packet_get_char();
946 /* Get the public key. */
947 server_key
= key_new(KEY_RSA1
);
948 bits
= packet_get_int();
949 packet_get_bignum(server_key
->rsa
->e
);
950 packet_get_bignum(server_key
->rsa
->n
);
952 rbits
= BN_num_bits(server_key
->rsa
->n
);
954 logit("Warning: Server lies about size of server public key: "
955 "actual size is %d bits vs. announced %d.", rbits
, bits
);
956 logit("Warning: This may be due to an old implementation of ssh.");
958 /* Get the host key. */
959 host_key
= key_new(KEY_RSA1
);
960 bits
= packet_get_int();
961 packet_get_bignum(host_key
->rsa
->e
);
962 packet_get_bignum(host_key
->rsa
->n
);
964 rbits
= BN_num_bits(host_key
->rsa
->n
);
966 logit("Warning: Server lies about size of server host key: "
967 "actual size is %d bits vs. announced %d.", rbits
, bits
);
968 logit("Warning: This may be due to an old implementation of ssh.");
971 /* Get protocol flags. */
972 server_flags
= packet_get_int();
973 packet_set_protocol_flags(server_flags
);
975 supported_ciphers
= packet_get_int();
976 supported_authentications
= packet_get_int();
979 debug("Received server public key (%d bits) and host key (%d bits).",
980 BN_num_bits(server_key
->rsa
->n
), BN_num_bits(host_key
->rsa
->n
));
982 if (verify_host_key(host
, hostaddr
, host_key
) == -1)
983 fatal("Host key verification failed.");
985 client_flags
= SSH_PROTOFLAG_SCREEN_NUMBER
| SSH_PROTOFLAG_HOST_IN_FWD_OPEN
;
987 derive_ssh1_session_id(host_key
->rsa
->n
, server_key
->rsa
->n
, cookie
, session_id
);
989 /* Generate a session key. */
993 * Generate an encryption key for the session. The key is a 256 bit
994 * random number, interpreted as a 32-byte key, with the least
995 * significant 8 bits being the first byte of the key.
997 for (i
= 0; i
< 32; i
++) {
1000 session_key
[i
] = rnd
& 0xff;
1005 * According to the protocol spec, the first byte of the session key
1006 * is the highest byte of the integer. The session key is xored with
1007 * the first 16 bytes of the session id.
1009 if ((key
= BN_new()) == NULL
)
1010 fatal("ssh_kex: BN_new failed");
1011 if (BN_set_word(key
, 0) == 0)
1012 fatal("ssh_kex: BN_set_word failed");
1013 for (i
= 0; i
< SSH_SESSION_KEY_LENGTH
; i
++) {
1014 if (BN_lshift(key
, key
, 8) == 0)
1015 fatal("ssh_kex: BN_lshift failed");
1017 if (BN_add_word(key
, session_key
[i
] ^ session_id
[i
])
1019 fatal("ssh_kex: BN_add_word failed");
1021 if (BN_add_word(key
, session_key
[i
]) == 0)
1022 fatal("ssh_kex: BN_add_word failed");
1027 * Encrypt the integer using the public key and host key of the
1028 * server (key with smaller modulus first).
1030 if (BN_cmp(server_key
->rsa
->n
, host_key
->rsa
->n
) < 0) {
1031 /* Public key has smaller modulus. */
1032 if (BN_num_bits(host_key
->rsa
->n
) <
1033 BN_num_bits(server_key
->rsa
->n
) + SSH_KEY_BITS_RESERVED
) {
1034 fatal("respond_to_rsa_challenge: host_key %d < server_key %d + "
1035 "SSH_KEY_BITS_RESERVED %d",
1036 BN_num_bits(host_key
->rsa
->n
),
1037 BN_num_bits(server_key
->rsa
->n
),
1038 SSH_KEY_BITS_RESERVED
);
1040 rsa_public_encrypt(key
, key
, server_key
->rsa
);
1041 rsa_public_encrypt(key
, key
, host_key
->rsa
);
1043 /* Host key has smaller modulus (or they are equal). */
1044 if (BN_num_bits(server_key
->rsa
->n
) <
1045 BN_num_bits(host_key
->rsa
->n
) + SSH_KEY_BITS_RESERVED
) {
1046 fatal("respond_to_rsa_challenge: server_key %d < host_key %d + "
1047 "SSH_KEY_BITS_RESERVED %d",
1048 BN_num_bits(server_key
->rsa
->n
),
1049 BN_num_bits(host_key
->rsa
->n
),
1050 SSH_KEY_BITS_RESERVED
);
1052 rsa_public_encrypt(key
, key
, host_key
->rsa
);
1053 rsa_public_encrypt(key
, key
, server_key
->rsa
);
1056 /* Destroy the public keys since we no longer need them. */
1057 key_free(server_key
);
1060 if (options
.cipher
== SSH_CIPHER_NOT_SET
) {
1061 if (cipher_mask_ssh1(1) & supported_ciphers
& (1 << ssh_cipher_default
))
1062 options
.cipher
= ssh_cipher_default
;
1063 } else if (options
.cipher
== SSH_CIPHER_INVALID
||
1064 !(cipher_mask_ssh1(1) & (1 << options
.cipher
))) {
1065 logit("No valid SSH1 cipher, using %.100s instead.",
1066 cipher_name(ssh_cipher_default
));
1067 options
.cipher
= ssh_cipher_default
;
1069 /* Check that the selected cipher is supported. */
1070 if (!(supported_ciphers
& (1 << options
.cipher
)))
1071 fatal("Selected cipher type %.100s not supported by server.",
1072 cipher_name(options
.cipher
));
1074 debug("Encryption type: %.100s", cipher_name(options
.cipher
));
1076 /* Send the encrypted session key to the server. */
1077 packet_start(SSH_CMSG_SESSION_KEY
);
1078 packet_put_char(options
.cipher
);
1080 /* Send the cookie back to the server. */
1081 for (i
= 0; i
< 8; i
++)
1082 packet_put_char(cookie
[i
]);
1084 /* Send and destroy the encrypted encryption key integer. */
1085 packet_put_bignum(key
);
1088 /* Send protocol flags. */
1089 packet_put_int(client_flags
);
1091 /* Send the packet now. */
1093 packet_write_wait();
1095 debug("Sent encrypted session key.");
1097 /* Set the encryption key. */
1098 packet_set_encryption_key(session_key
, SSH_SESSION_KEY_LENGTH
, options
.cipher
);
1100 /* We will no longer need the session key here. Destroy any extra copies. */
1101 memset(session_key
, 0, sizeof(session_key
));
1104 * Expect a success message from the server. Note that this message
1105 * will be received in encrypted form.
1107 packet_read_expect(SSH_SMSG_SUCCESS
);
1109 debug("Received encrypted confirmation.");
1116 ssh_userauth1(const char *local_user
, const char *server_user
, char *host
,
1117 Sensitive
*sensitive
)
1120 krb5_context context
= NULL
;
1121 krb5_auth_context auth_context
= NULL
;
1125 if (supported_authentications
== 0)
1126 fatal("ssh_userauth1: server supports no auth methods");
1128 /* Send the name of the user to log in as on the server. */
1129 packet_start(SSH_CMSG_USER
);
1130 packet_put_cstring(server_user
);
1132 packet_write_wait();
1135 * The server should respond with success if no authentication is
1136 * needed (the user has no password). Otherwise the server responds
1139 type
= packet_read();
1141 /* check whether the connection was accepted without authentication. */
1142 if (type
== SSH_SMSG_SUCCESS
)
1144 if (type
!= SSH_SMSG_FAILURE
)
1145 packet_disconnect("Protocol error: got %d in response to SSH_CMSG_USER", type
);
1148 if ((supported_authentications
& (1 << SSH_AUTH_KERBEROS
)) &&
1149 options
.kerberos_authentication
) {
1150 debug("Trying Kerberos v5 authentication.");
1152 if (try_krb5_authentication(&context
, &auth_context
)) {
1153 type
= packet_read();
1154 if (type
== SSH_SMSG_SUCCESS
)
1156 if (type
!= SSH_SMSG_FAILURE
)
1157 packet_disconnect("Protocol error: got %d in response to Kerberos v5 auth", type
);
1163 if ((supported_authentications
& (1 << SSH_AUTH_KERBEROS
)) &&
1164 options
.kerberos_authentication
) {
1165 debug("Trying Kerberos v4 authentication.");
1167 if (try_krb4_authentication()) {
1168 type
= packet_read();
1169 if (type
== SSH_SMSG_SUCCESS
)
1171 if (type
!= SSH_SMSG_FAILURE
)
1172 packet_disconnect("Protocol error: got %d in response to Kerberos v4 auth", type
);
1178 * Try .rhosts or /etc/hosts.equiv authentication with RSA host
1181 if ((supported_authentications
& (1 << SSH_AUTH_RHOSTS_RSA
)) &&
1182 options
.rhosts_rsa_authentication
) {
1183 for (i
= 0; i
< sensitive
->nkeys
; i
++) {
1184 if (sensitive
->keys
[i
] != NULL
&&
1185 sensitive
->keys
[i
]->type
== KEY_RSA1
&&
1186 try_rhosts_rsa_authentication(local_user
,
1187 sensitive
->keys
[i
]))
1191 /* Try RSA authentication if the server supports it. */
1192 if ((supported_authentications
& (1 << SSH_AUTH_RSA
)) &&
1193 options
.rsa_authentication
) {
1195 * Try RSA authentication using the authentication agent. The
1196 * agent is tried first because no passphrase is needed for
1197 * it, whereas identity files may require passphrases.
1199 if (try_agent_authentication())
1202 /* Try RSA authentication for each identity. */
1203 for (i
= 0; i
< options
.num_identity_files
; i
++)
1204 if (options
.identity_keys
[i
] != NULL
&&
1205 options
.identity_keys
[i
]->type
== KEY_RSA1
&&
1206 try_rsa_authentication(i
))
1209 /* Try challenge response authentication if the server supports it. */
1210 if ((supported_authentications
& (1 << SSH_AUTH_TIS
)) &&
1211 options
.challenge_response_authentication
&& !options
.batch_mode
) {
1212 if (try_challenge_response_authentication())
1215 /* Try password authentication if the server supports it. */
1216 if ((supported_authentications
& (1 << SSH_AUTH_PASSWORD
)) &&
1217 options
.password_authentication
&& !options
.batch_mode
) {
1220 snprintf(prompt
, sizeof(prompt
), "%.30s@%.128s's password: ",
1222 if (try_password_authentication(prompt
))
1225 /* All authentication methods have failed. Exit with an error message. */
1226 fatal("Permission denied.");
1231 /* Try Kerberos v5 TGT passing. */
1232 if ((supported_authentications
& (1 << SSH_PASS_KERBEROS_TGT
)) &&
1233 options
.kerberos_tgt_passing
&& context
&& auth_context
) {
1234 if (options
.cipher
== SSH_CIPHER_NONE
)
1235 logit("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!");
1236 send_krb5_tgt(context
, auth_context
);
1239 krb5_auth_con_free(context
, auth_context
);
1241 krb5_free_context(context
);
1246 /* Try Kerberos v4 TGT passing if the server supports it. */
1247 if ((supported_authentications
& (1 << SSH_PASS_KERBEROS_TGT
)) &&
1248 options
.kerberos_tgt_passing
) {
1249 if (options
.cipher
== SSH_CIPHER_NONE
)
1250 logit("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!");
1253 /* Try AFS token passing if the server supports it. */
1254 if ((supported_authentications
& (1 << SSH_PASS_AFS_TOKEN
)) &&
1255 options
.afs_token_passing
&& k_hasafs()) {
1256 if (options
.cipher
== SSH_CIPHER_NONE
)
1257 logit("WARNING: Encryption is disabled! Token will be transmitted in the clear!");
1263 return; /* need statement after label */