]> andersk Git - openssh.git/blame - sshconnect.c
- Fixes to auth-skey to enable it to use the standard OpenSSL libraries
[openssh.git] / sshconnect.c
CommitLineData
8efc0c15 1/*
5260325f 2 * Author: Tatu Ylonen <ylo@cs.hut.fi>
3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4 * All rights reserved
5 * Created: Sat Mar 18 22:15:47 1995 ylo
6 * Code to connect to a remote host, and to perform the client side of the
7 * login (authentication) dialog.
8 */
8efc0c15 9
10#include "includes.h"
11RCSID("$Id$");
12
5881cd60 13#ifdef HAVE_OPENSSL
8efc0c15 14#include <openssl/bn.h>
5881cd60 15#include <openssl/md5.h>
16#endif
17#ifdef HAVE_SSL
18#include <ssl/bn.h>
19#include <ssl/md5.h>
20#endif
21
8efc0c15 22#include "xmalloc.h"
23#include "rsa.h"
24#include "ssh.h"
25#include "packet.h"
26#include "authfd.h"
27#include "cipher.h"
28#include "mpaux.h"
29#include "uidswap.h"
30#include "compat.h"
6fa724bc 31#include "readconf.h"
2bd61362 32#include "fingerprint.h"
8efc0c15 33
34/* Session id for the current session. */
35unsigned char session_id[16];
36
57112b5a 37extern Options options;
38
5260325f 39/*
40 * Connect to the given ssh server using a proxy command.
41 */
8efc0c15 42int
57112b5a 43ssh_proxy_connect(const char *host, u_short port, uid_t original_real_uid,
8efc0c15 44 const char *proxy_command)
45{
5260325f 46 Buffer command;
47 const char *cp;
48 char *command_string;
49 int pin[2], pout[2];
50 int pid;
51 char portstring[100];
52
53 /* Convert the port number into a string. */
57112b5a 54 snprintf(portstring, sizeof portstring, "%hu", port);
5260325f 55
56 /* Build the final command string in the buffer by making the
57 appropriate substitutions to the given proxy command. */
58 buffer_init(&command);
59 for (cp = proxy_command; *cp; cp++) {
60 if (cp[0] == '%' && cp[1] == '%') {
61 buffer_append(&command, "%", 1);
62 cp++;
63 continue;
64 }
65 if (cp[0] == '%' && cp[1] == 'h') {
66 buffer_append(&command, host, strlen(host));
67 cp++;
68 continue;
69 }
70 if (cp[0] == '%' && cp[1] == 'p') {
71 buffer_append(&command, portstring, strlen(portstring));
72 cp++;
73 continue;
74 }
75 buffer_append(&command, cp, 1);
8efc0c15 76 }
5260325f 77 buffer_append(&command, "\0", 1);
78
79 /* Get the final command string. */
80 command_string = buffer_ptr(&command);
81
82 /* Create pipes for communicating with the proxy. */
83 if (pipe(pin) < 0 || pipe(pout) < 0)
84 fatal("Could not create pipes to communicate with the proxy: %.100s",
85 strerror(errno));
86
87 debug("Executing proxy command: %.500s", command_string);
88
89 /* Fork and execute the proxy command. */
90 if ((pid = fork()) == 0) {
91 char *argv[10];
92
93 /* Child. Permanently give up superuser privileges. */
94 permanently_set_uid(original_real_uid);
95
96 /* Redirect stdin and stdout. */
97 close(pin[1]);
98 if (pin[0] != 0) {
99 if (dup2(pin[0], 0) < 0)
100 perror("dup2 stdin");
101 close(pin[0]);
102 }
103 close(pout[0]);
104 if (dup2(pout[1], 1) < 0)
105 perror("dup2 stdout");
106 /* Cannot be 1 because pin allocated two descriptors. */
107 close(pout[1]);
108
109 /* Stderr is left as it is so that error messages get
110 printed on the user's terminal. */
111 argv[0] = "/bin/sh";
112 argv[1] = "-c";
113 argv[2] = command_string;
114 argv[3] = NULL;
115
116 /* Execute the proxy command. Note that we gave up any
117 extra privileges above. */
118 execv("/bin/sh", argv);
119 perror("/bin/sh");
120 exit(1);
8efc0c15 121 }
5260325f 122 /* Parent. */
123 if (pid < 0)
124 fatal("fork failed: %.100s", strerror(errno));
125
126 /* Close child side of the descriptors. */
127 close(pin[0]);
128 close(pout[1]);
129
130 /* Free the command name. */
131 buffer_free(&command);
132
133 /* Set the connection file descriptors. */
134 packet_set_connection(pout[0], pin[1]);
8efc0c15 135
5260325f 136 return 1;
137}
8efc0c15 138
5260325f 139/*
140 * Creates a (possibly privileged) socket for use as the ssh connection.
141 */
142int
143ssh_create_socket(uid_t original_real_uid, int privileged)
8efc0c15 144{
5260325f 145 int sock;
146
aa3378df 147 /*
148 * If we are running as root and want to connect to a privileged
149 * port, bind our own socket to a privileged port.
150 */
5260325f 151 if (privileged) {
152 int p = IPPORT_RESERVED - 1;
153
154 sock = rresvport(&p);
155 if (sock < 0)
156 fatal("rresvport: %.100s", strerror(errno));
157 debug("Allocated local port %d.", p);
158 } else {
95f1eccc 159 /*
160 * Just create an ordinary socket on arbitrary port. We use
161 * the user's uid to create the socket.
162 */
5260325f 163 temporarily_use_uid(original_real_uid);
164 sock = socket(AF_INET, SOCK_STREAM, 0);
165 if (sock < 0)
166 fatal("socket: %.100s", strerror(errno));
167 restore_uid();
168 }
169 return sock;
8efc0c15 170}
171
5260325f 172/*
173 * Opens a TCP/IP connection to the remote server on the given host. If
174 * port is 0, the default port will be used. If anonymous is zero,
175 * a privileged port will be allocated to make the connection.
176 * This requires super-user privileges if anonymous is false.
177 * Connection_attempts specifies the maximum number of tries (one per
178 * second). If proxy_command is non-NULL, it specifies the command (with %h
179 * and %p substituted for host and port, respectively) to use to contact
180 * the daemon.
181 */
182int
183ssh_connect(const char *host, struct sockaddr_in * hostaddr,
57112b5a 184 u_short port, int connection_attempts,
5260325f 185 int anonymous, uid_t original_real_uid,
186 const char *proxy_command)
8efc0c15 187{
5260325f 188 int sock = -1, attempt, i;
189 int on = 1;
190 struct servent *sp;
191 struct hostent *hp;
192 struct linger linger;
193
194 debug("ssh_connect: getuid %d geteuid %d anon %d",
195 (int) getuid(), (int) geteuid(), anonymous);
196
197 /* Get default port if port has not been set. */
198 if (port == 0) {
199 sp = getservbyname(SSH_SERVICE_NAME, "tcp");
200 if (sp)
201 port = ntohs(sp->s_port);
202 else
203 port = SSH_DEFAULT_PORT;
8efc0c15 204 }
5260325f 205 /* If a proxy command is given, connect using it. */
206 if (proxy_command != NULL)
207 return ssh_proxy_connect(host, port, original_real_uid, proxy_command);
208
209 /* No proxy command. */
210
211 /* No host lookup made yet. */
212 hp = NULL;
213
95f1eccc 214 /*
215 * Try to connect several times. On some machines, the first time
216 * will sometimes fail. In general socket code appears to behave
217 * quite magically on many machines.
218 */
5260325f 219 for (attempt = 0; attempt < connection_attempts; attempt++) {
220 if (attempt > 0)
221 debug("Trying again...");
222
223 /* Try to parse the host name as a numeric inet address. */
224 memset(hostaddr, 0, sizeof(hostaddr));
225 hostaddr->sin_family = AF_INET;
226 hostaddr->sin_port = htons(port);
227 hostaddr->sin_addr.s_addr = inet_addr(host);
228 if ((hostaddr->sin_addr.s_addr & 0xffffffff) != 0xffffffff) {
229 /* Valid numeric IP address */
230 debug("Connecting to %.100s port %d.",
231 inet_ntoa(hostaddr->sin_addr), port);
232
233 /* Create a socket. */
234 sock = ssh_create_socket(original_real_uid,
235 !anonymous && geteuid() == 0 &&
236 port < IPPORT_RESERVED);
237
aa3378df 238 /*
239 * Connect to the host. We use the user's uid in the
240 * hope that it will help with the problems of
241 * tcp_wrappers showing the remote uid as root.
242 */
5260325f 243 temporarily_use_uid(original_real_uid);
244 if (connect(sock, (struct sockaddr *) hostaddr, sizeof(*hostaddr))
245 >= 0) {
246 /* Successful connect. */
247 restore_uid();
248 break;
249 }
250 debug("connect: %.100s", strerror(errno));
251 restore_uid();
252
253 /* Destroy the failed socket. */
254 shutdown(sock, SHUT_RDWR);
255 close(sock);
256 } else {
257 /* Not a valid numeric inet address. */
258 /* Map host name to an address. */
259 if (!hp)
260 hp = gethostbyname(host);
261 if (!hp)
262 fatal("Bad host name: %.100s", host);
263 if (!hp->h_addr_list[0])
264 fatal("Host does not have an IP address: %.100s", host);
265
266 /* Loop through addresses for this host, and try
267 each one in sequence until the connection
268 succeeds. */
269 for (i = 0; hp->h_addr_list[i]; i++) {
270 /* Set the address to connect to. */
271 hostaddr->sin_family = hp->h_addrtype;
272 memcpy(&hostaddr->sin_addr, hp->h_addr_list[i],
273 sizeof(hostaddr->sin_addr));
274
275 debug("Connecting to %.200s [%.100s] port %d.",
276 host, inet_ntoa(hostaddr->sin_addr), port);
277
278 /* Create a socket for connecting. */
279 sock = ssh_create_socket(original_real_uid,
280 !anonymous && geteuid() == 0 &&
281 port < IPPORT_RESERVED);
282
aa3378df 283 /*
284 * Connect to the host. We use the user's
285 * uid in the hope that it will help with
286 * tcp_wrappers showing the remote uid as
287 * root.
288 */
5260325f 289 temporarily_use_uid(original_real_uid);
290 if (connect(sock, (struct sockaddr *) hostaddr,
291 sizeof(*hostaddr)) >= 0) {
292 /* Successful connection. */
293 restore_uid();
294 break;
295 }
296 debug("connect: %.100s", strerror(errno));
297 restore_uid();
298
aa3378df 299 /*
300 * Close the failed socket; there appear to
301 * be some problems when reusing a socket for
302 * which connect() has already returned an
303 * error.
304 */
5260325f 305 shutdown(sock, SHUT_RDWR);
306 close(sock);
307 }
308 if (hp->h_addr_list[i])
309 break; /* Successful connection. */
8efc0c15 310 }
8efc0c15 311
5260325f 312 /* Sleep a moment before retrying. */
313 sleep(1);
314 }
315 /* Return failure if we didn't get a successful connection. */
316 if (attempt >= connection_attempts)
317 return 0;
8efc0c15 318
5260325f 319 debug("Connection established.");
8efc0c15 320
aa3378df 321 /*
322 * Set socket options. We would like the socket to disappear as soon
323 * as it has been closed for whatever reason.
324 */
325 /* setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)); */
5260325f 326 setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void *) &on, sizeof(on));
327 linger.l_onoff = 1;
328 linger.l_linger = 5;
329 setsockopt(sock, SOL_SOCKET, SO_LINGER, (void *) &linger, sizeof(linger));
8efc0c15 330
5260325f 331 /* Set the connection. */
332 packet_set_connection(sock, sock);
8efc0c15 333
5260325f 334 return 1;
8efc0c15 335}
336
5260325f 337/*
338 * Checks if the user has an authentication agent, and if so, tries to
339 * authenticate using the agent.
340 */
8efc0c15 341int
342try_agent_authentication()
343{
5260325f 344 int status, type;
345 char *comment;
346 AuthenticationConnection *auth;
347 unsigned char response[16];
348 unsigned int i;
349 BIGNUM *e, *n, *challenge;
350
351 /* Get connection to the agent. */
352 auth = ssh_get_authentication_connection();
353 if (!auth)
354 return 0;
355
356 e = BN_new();
357 n = BN_new();
358 challenge = BN_new();
359
360 /* Loop through identities served by the agent. */
361 for (status = ssh_get_first_identity(auth, e, n, &comment);
362 status;
363 status = ssh_get_next_identity(auth, e, n, &comment)) {
364 int plen, clen;
365
366 /* Try this identity. */
367 debug("Trying RSA authentication via agent with '%.100s'", comment);
368 xfree(comment);
369
370 /* Tell the server that we are willing to authenticate using this key. */
371 packet_start(SSH_CMSG_AUTH_RSA);
372 packet_put_bignum(n);
373 packet_send();
374 packet_write_wait();
375
376 /* Wait for server's response. */
377 type = packet_read(&plen);
378
379 /* The server sends failure if it doesn\'t like our key or
380 does not support RSA authentication. */
381 if (type == SSH_SMSG_FAILURE) {
382 debug("Server refused our key.");
383 continue;
384 }
385 /* Otherwise it should have sent a challenge. */
386 if (type != SSH_SMSG_AUTH_RSA_CHALLENGE)
387 packet_disconnect("Protocol error during RSA authentication: %d",
388 type);
8efc0c15 389
5260325f 390 packet_get_bignum(challenge, &clen);
8efc0c15 391
5260325f 392 packet_integrity_check(plen, clen, type);
8efc0c15 393
5260325f 394 debug("Received RSA challenge from server.");
395
396 /* Ask the agent to decrypt the challenge. */
397 if (!ssh_decrypt_challenge(auth, e, n, challenge,
398 session_id, 1, response)) {
399 /* The agent failed to authenticate this identifier although it
400 advertised it supports this. Just return a wrong value. */
401 log("Authentication agent failed to decrypt challenge.");
402 memset(response, 0, sizeof(response));
403 }
404 debug("Sending response to RSA challenge.");
405
406 /* Send the decrypted challenge back to the server. */
407 packet_start(SSH_CMSG_AUTH_RSA_RESPONSE);
408 for (i = 0; i < 16; i++)
409 packet_put_char(response[i]);
410 packet_send();
411 packet_write_wait();
412
413 /* Wait for response from the server. */
414 type = packet_read(&plen);
415
416 /* The server returns success if it accepted the authentication. */
417 if (type == SSH_SMSG_SUCCESS) {
418 debug("RSA authentication accepted by server.");
419 BN_clear_free(e);
420 BN_clear_free(n);
421 BN_clear_free(challenge);
422 return 1;
423 }
424 /* Otherwise it should return failure. */
425 if (type != SSH_SMSG_FAILURE)
426 packet_disconnect("Protocol error waiting RSA auth response: %d",
427 type);
428 }
429
430 BN_clear_free(e);
431 BN_clear_free(n);
432 BN_clear_free(challenge);
8efc0c15 433
5260325f 434 debug("RSA authentication using agent refused.");
435 return 0;
436}
8efc0c15 437
5260325f 438/*
439 * Computes the proper response to a RSA challenge, and sends the response to
440 * the server.
441 */
8efc0c15 442void
5260325f 443respond_to_rsa_challenge(BIGNUM * challenge, RSA * prv)
8efc0c15 444{
5260325f 445 unsigned char buf[32], response[16];
446 MD5_CTX md;
447 int i, len;
448
449 /* Decrypt the challenge using the private key. */
450 rsa_private_decrypt(challenge, challenge, prv);
451
452 /* Compute the response. */
453 /* The response is MD5 of decrypted challenge plus session id. */
454 len = BN_num_bytes(challenge);
455 if (len <= 0 || len > sizeof(buf))
456 packet_disconnect("respond_to_rsa_challenge: bad challenge length %d",
457 len);
458
459 memset(buf, 0, sizeof(buf));
460 BN_bn2bin(challenge, buf + sizeof(buf) - len);
461 MD5_Init(&md);
462 MD5_Update(&md, buf, 32);
463 MD5_Update(&md, session_id, 16);
464 MD5_Final(response, &md);
465
466 debug("Sending response to host key RSA challenge.");
467
468 /* Send the response back to the server. */
469 packet_start(SSH_CMSG_AUTH_RSA_RESPONSE);
470 for (i = 0; i < 16; i++)
471 packet_put_char(response[i]);
472 packet_send();
473 packet_write_wait();
8efc0c15 474
5260325f 475 memset(buf, 0, sizeof(buf));
476 memset(response, 0, sizeof(response));
477 memset(&md, 0, sizeof(md));
478}
8efc0c15 479
5260325f 480/*
481 * Checks if the user has authentication file, and if so, tries to authenticate
482 * the user using it.
483 */
8efc0c15 484int
57112b5a 485try_rsa_authentication(const char *authfile)
8efc0c15 486{
5260325f 487 BIGNUM *challenge;
488 RSA *private_key;
489 RSA *public_key;
490 char *passphrase, *comment;
491 int type, i;
492 int plen, clen;
493
494 /* Try to load identification for the authentication key. */
495 public_key = RSA_new();
496 if (!load_public_key(authfile, public_key, &comment)) {
497 RSA_free(public_key);
57112b5a 498 /* Could not load it. Fail. */
499 return 0;
8efc0c15 500 }
5260325f 501 debug("Trying RSA authentication with key '%.100s'", comment);
502
503 /* Tell the server that we are willing to authenticate using this key. */
504 packet_start(SSH_CMSG_AUTH_RSA);
505 packet_put_bignum(public_key->n);
506 packet_send();
507 packet_write_wait();
508
509 /* We no longer need the public key. */
510 RSA_free(public_key);
511
512 /* Wait for server's response. */
513 type = packet_read(&plen);
514
aa3378df 515 /*
516 * The server responds with failure if it doesn\'t like our key or
517 * doesn\'t support RSA authentication.
518 */
5260325f 519 if (type == SSH_SMSG_FAILURE) {
520 debug("Server refused our key.");
521 xfree(comment);
57112b5a 522 return 0;
8efc0c15 523 }
5260325f 524 /* Otherwise, the server should respond with a challenge. */
525 if (type != SSH_SMSG_AUTH_RSA_CHALLENGE)
526 packet_disconnect("Protocol error during RSA authentication: %d", type);
527
528 /* Get the challenge from the packet. */
529 challenge = BN_new();
530 packet_get_bignum(challenge, &clen);
531
532 packet_integrity_check(plen, clen, type);
533
534 debug("Received RSA challenge from server.");
535
536 private_key = RSA_new();
aa3378df 537 /*
538 * Load the private key. Try first with empty passphrase; if it
539 * fails, ask for a passphrase.
540 */
5260325f 541 if (!load_private_key(authfile, "", private_key, NULL)) {
542 char buf[300];
543 snprintf(buf, sizeof buf, "Enter passphrase for RSA key '%.100s': ",
a408af76 544 comment);
5260325f 545 if (!options.batch_mode)
546 passphrase = read_passphrase(buf, 0);
547 else {
548 debug("Will not query passphrase for %.100s in batch mode.",
549 comment);
550 passphrase = xstrdup("");
551 }
8efc0c15 552
5260325f 553 /* Load the authentication file using the pasphrase. */
554 if (!load_private_key(authfile, passphrase, private_key, NULL)) {
555 memset(passphrase, 0, strlen(passphrase));
556 xfree(passphrase);
557 error("Bad passphrase.");
558
559 /* Send a dummy response packet to avoid protocol error. */
560 packet_start(SSH_CMSG_AUTH_RSA_RESPONSE);
561 for (i = 0; i < 16; i++)
562 packet_put_char(0);
563 packet_send();
564 packet_write_wait();
565
566 /* Expect the server to reject it... */
567 packet_read_expect(&plen, SSH_SMSG_FAILURE);
568 xfree(comment);
569 return 0;
570 }
571 /* Destroy the passphrase. */
572 memset(passphrase, 0, strlen(passphrase));
573 xfree(passphrase);
574 }
575 /* We no longer need the comment. */
576 xfree(comment);
577
578 /* Compute and send a response to the challenge. */
579 respond_to_rsa_challenge(challenge, private_key);
580
581 /* Destroy the private key. */
582 RSA_free(private_key);
8efc0c15 583
5260325f 584 /* We no longer need the challenge. */
585 BN_clear_free(challenge);
586
587 /* Wait for response from the server. */
588 type = packet_read(&plen);
589 if (type == SSH_SMSG_SUCCESS) {
590 debug("RSA authentication accepted by server.");
591 return 1;
592 }
593 if (type != SSH_SMSG_FAILURE)
594 packet_disconnect("Protocol error waiting RSA auth response: %d", type);
595 debug("RSA authentication refused.");
596 return 0;
597}
8efc0c15 598
5260325f 599/*
600 * Tries to authenticate the user using combined rhosts or /etc/hosts.equiv
601 * authentication and RSA host authentication.
602 */
8efc0c15 603int
5260325f 604try_rhosts_rsa_authentication(const char *local_user, RSA * host_key)
8efc0c15 605{
5260325f 606 int type;
607 BIGNUM *challenge;
608 int plen, clen;
609
610 debug("Trying rhosts or /etc/hosts.equiv with RSA host authentication.");
611
612 /* Tell the server that we are willing to authenticate using this key. */
613 packet_start(SSH_CMSG_AUTH_RHOSTS_RSA);
614 packet_put_string(local_user, strlen(local_user));
615 packet_put_int(BN_num_bits(host_key->n));
616 packet_put_bignum(host_key->e);
617 packet_put_bignum(host_key->n);
618 packet_send();
619 packet_write_wait();
620
621 /* Wait for server's response. */
622 type = packet_read(&plen);
623
624 /* The server responds with failure if it doesn't admit our
625 .rhosts authentication or doesn't know our host key. */
626 if (type == SSH_SMSG_FAILURE) {
627 debug("Server refused our rhosts authentication or host key.");
628 return 0;
629 }
630 /* Otherwise, the server should respond with a challenge. */
631 if (type != SSH_SMSG_AUTH_RSA_CHALLENGE)
632 packet_disconnect("Protocol error during RSA authentication: %d", type);
633
634 /* Get the challenge from the packet. */
635 challenge = BN_new();
636 packet_get_bignum(challenge, &clen);
637
638 packet_integrity_check(plen, clen, type);
639
640 debug("Received RSA challenge for host key from server.");
641
642 /* Compute a response to the challenge. */
643 respond_to_rsa_challenge(challenge, host_key);
644
645 /* We no longer need the challenge. */
646 BN_clear_free(challenge);
647
648 /* Wait for response from the server. */
649 type = packet_read(&plen);
650 if (type == SSH_SMSG_SUCCESS) {
651 debug("Rhosts or /etc/hosts.equiv with RSA host authentication accepted by server.");
652 return 1;
653 }
654 if (type != SSH_SMSG_FAILURE)
655 packet_disconnect("Protocol error waiting RSA auth response: %d", type);
656 debug("Rhosts or /etc/hosts.equiv with RSA host authentication refused.");
657 return 0;
8efc0c15 658}
659
660#ifdef KRB4
5260325f 661int
662try_kerberos_authentication()
8efc0c15 663{
5260325f 664 KTEXT_ST auth; /* Kerberos data */
665 char *reply;
666 char inst[INST_SZ];
667 char *realm;
668 CREDENTIALS cred;
669 int r, type, plen;
670 Key_schedule schedule;
671 u_long checksum, cksum;
672 MSG_DAT msg_data;
673 struct sockaddr_in local, foreign;
674 struct stat st;
675
676 /* Don't do anything if we don't have any tickets. */
677 if (stat(tkt_string(), &st) < 0)
678 return 0;
679
680 strncpy(inst, (char *) krb_get_phost(get_canonical_hostname()), INST_SZ);
681
682 realm = (char *) krb_realmofhost(get_canonical_hostname());
683 if (!realm) {
684 debug("Kerberos V4: no realm for %s", get_canonical_hostname());
685 return 0;
686 }
687 /* This can really be anything. */
688 checksum = (u_long) getpid();
689
690 r = krb_mk_req(&auth, KRB4_SERVICE_NAME, inst, realm, checksum);
691 if (r != KSUCCESS) {
692 debug("Kerberos V4 krb_mk_req failed: %s", krb_err_txt[r]);
693 return 0;
694 }
695 /* Get session key to decrypt the server's reply with. */
696 r = krb_get_cred(KRB4_SERVICE_NAME, inst, realm, &cred);
697 if (r != KSUCCESS) {
698 debug("get_cred failed: %s", krb_err_txt[r]);
699 return 0;
700 }
701 des_key_sched((des_cblock *) cred.session, schedule);
702
703 /* Send authentication info to server. */
704 packet_start(SSH_CMSG_AUTH_KERBEROS);
705 packet_put_string((char *) auth.dat, auth.length);
706 packet_send();
707 packet_write_wait();
708
709 /* Zero the buffer. */
710 (void) memset(auth.dat, 0, MAX_KTXT_LEN);
711
712 r = sizeof(local);
713 memset(&local, 0, sizeof(local));
714 if (getsockname(packet_get_connection_in(),
715 (struct sockaddr *) & local, &r) < 0)
716 debug("getsockname failed: %s", strerror(errno));
717
718 r = sizeof(foreign);
719 memset(&foreign, 0, sizeof(foreign));
720 if (getpeername(packet_get_connection_in(),
721 (struct sockaddr *) & foreign, &r) < 0) {
722 debug("getpeername failed: %s", strerror(errno));
723 fatal_cleanup();
724 }
725 /* Get server reply. */
726 type = packet_read(&plen);
727 switch (type) {
728 case SSH_SMSG_FAILURE:
729 /* Should really be SSH_SMSG_AUTH_KERBEROS_FAILURE */
730 debug("Kerberos V4 authentication failed.");
731 return 0;
732 break;
733
734 case SSH_SMSG_AUTH_KERBEROS_RESPONSE:
735 /* SSH_SMSG_AUTH_KERBEROS_SUCCESS */
736 debug("Kerberos V4 authentication accepted.");
737
738 /* Get server's response. */
739 reply = packet_get_string((unsigned int *) &auth.length);
740 memcpy(auth.dat, reply, auth.length);
741 xfree(reply);
742
743 packet_integrity_check(plen, 4 + auth.length, type);
744
aa3378df 745 /*
746 * If his response isn't properly encrypted with the session
747 * key, and the decrypted checksum fails to match, he's
748 * bogus. Bail out.
749 */
5260325f 750 r = krb_rd_priv(auth.dat, auth.length, schedule, &cred.session,
751 &foreign, &local, &msg_data);
752 if (r != KSUCCESS) {
753 debug("Kerberos V4 krb_rd_priv failed: %s", krb_err_txt[r]);
754 packet_disconnect("Kerberos V4 challenge failed!");
755 }
756 /* Fetch the (incremented) checksum that we supplied in the request. */
757 (void) memcpy((char *) &cksum, (char *) msg_data.app_data, sizeof(cksum));
758 cksum = ntohl(cksum);
759
760 /* If it matches, we're golden. */
761 if (cksum == checksum + 1) {
762 debug("Kerberos V4 challenge successful.");
763 return 1;
764 } else
765 packet_disconnect("Kerberos V4 challenge failed!");
766 break;
767
768 default:
769 packet_disconnect("Protocol error on Kerberos V4 response: %d", type);
770 }
771 return 0;
8efc0c15 772}
5260325f 773
8efc0c15 774#endif /* KRB4 */
775
776#ifdef AFS
5260325f 777int
778send_kerberos_tgt()
8efc0c15 779{
5260325f 780 CREDENTIALS *creds;
781 char pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ];
782 int r, type, plen;
783 unsigned char buffer[8192];
784 struct stat st;
785
786 /* Don't do anything if we don't have any tickets. */
787 if (stat(tkt_string(), &st) < 0)
788 return 0;
789
790 creds = xmalloc(sizeof(*creds));
791
792 if ((r = krb_get_tf_fullname(TKT_FILE, pname, pinst, prealm)) != KSUCCESS) {
793 debug("Kerberos V4 tf_fullname failed: %s", krb_err_txt[r]);
794 return 0;
795 }
796 if ((r = krb_get_cred("krbtgt", prealm, prealm, creds)) != GC_OK) {
797 debug("Kerberos V4 get_cred failed: %s", krb_err_txt[r]);
798 return 0;
799 }
800 if (time(0) > krb_life_to_time(creds->issue_date, creds->lifetime)) {
801 debug("Kerberos V4 ticket expired: %s", TKT_FILE);
802 return 0;
803 }
804 creds_to_radix(creds, buffer);
805 xfree(creds);
806
807 packet_start(SSH_CMSG_HAVE_KERBEROS_TGT);
808 packet_put_string((char *) buffer, strlen(buffer));
809 packet_send();
810 packet_write_wait();
811
812 type = packet_read(&plen);
813
814 if (type == SSH_SMSG_FAILURE)
815 debug("Kerberos TGT for realm %s rejected.", prealm);
816 else if (type != SSH_SMSG_SUCCESS)
817 packet_disconnect("Protocol error on Kerberos TGT response: %d", type);
818
819 return 1;
8efc0c15 820}
821
5260325f 822void
823send_afs_tokens(void)
8efc0c15 824{
5260325f 825 CREDENTIALS creds;
826 struct ViceIoctl parms;
827 struct ClearToken ct;
828 int i, type, len, plen;
829 char buf[2048], *p, *server_cell;
830 unsigned char buffer[8192];
831
832 /* Move over ktc_GetToken, here's something leaner. */
833 for (i = 0; i < 100; i++) { /* just in case */
834 parms.in = (char *) &i;
835 parms.in_size = sizeof(i);
836 parms.out = buf;
837 parms.out_size = sizeof(buf);
838 if (k_pioctl(0, VIOCGETTOK, &parms, 0) != 0)
839 break;
840 p = buf;
841
842 /* Get secret token. */
843 memcpy(&creds.ticket_st.length, p, sizeof(unsigned int));
844 if (creds.ticket_st.length > MAX_KTXT_LEN)
845 break;
846 p += sizeof(unsigned int);
847 memcpy(creds.ticket_st.dat, p, creds.ticket_st.length);
848 p += creds.ticket_st.length;
849
850 /* Get clear token. */
851 memcpy(&len, p, sizeof(len));
852 if (len != sizeof(struct ClearToken))
853 break;
854 p += sizeof(len);
855 memcpy(&ct, p, len);
856 p += len;
857 p += sizeof(len); /* primary flag */
858 server_cell = p;
859
860 /* Flesh out our credentials. */
861 strlcpy(creds.service, "afs", sizeof creds.service);
862 creds.instance[0] = '\0';
863 strlcpy(creds.realm, server_cell, REALM_SZ);
864 memcpy(creds.session, ct.HandShakeKey, DES_KEY_SZ);
865 creds.issue_date = ct.BeginTimestamp;
866 creds.lifetime = krb_time_to_life(creds.issue_date, ct.EndTimestamp);
867 creds.kvno = ct.AuthHandle;
868 snprintf(creds.pname, sizeof(creds.pname), "AFS ID %d", ct.ViceId);
869 creds.pinst[0] = '\0';
870
871 /* Encode token, ship it off. */
872 if (!creds_to_radix(&creds, buffer))
873 break;
874 packet_start(SSH_CMSG_HAVE_AFS_TOKEN);
875 packet_put_string((char *) buffer, strlen(buffer));
876 packet_send();
877 packet_write_wait();
878
879 /* Roger, Roger. Clearance, Clarence. What's your vector,
880 Victor? */
881 type = packet_read(&plen);
882
883 if (type == SSH_SMSG_FAILURE)
884 debug("AFS token for cell %s rejected.", server_cell);
885 else if (type != SSH_SMSG_SUCCESS)
886 packet_disconnect("Protocol error on AFS token response: %d", type);
887 }
8efc0c15 888}
8efc0c15 889
5260325f 890#endif /* AFS */
8efc0c15 891
57112b5a 892/*
893 * Tries to authenticate with any string-based challenge/response system.
894 * Note that the client code is not tied to s/key or TIS.
895 */
896int
897try_skey_authentication()
898{
899 int type, i, payload_len;
900 char *challenge, *response;
901
902 debug("Doing skey authentication.");
903
904 /* request a challenge */
905 packet_start(SSH_CMSG_AUTH_TIS);
906 packet_send();
907 packet_write_wait();
908
909 type = packet_read(&payload_len);
910 if (type != SSH_SMSG_FAILURE &&
911 type != SSH_SMSG_AUTH_TIS_CHALLENGE) {
912 packet_disconnect("Protocol error: got %d in response "
913 "to skey-auth", type);
914 }
915 if (type != SSH_SMSG_AUTH_TIS_CHALLENGE) {
916 debug("No challenge for skey authentication.");
917 return 0;
918 }
919 challenge = packet_get_string(&payload_len);
920 if (options.cipher == SSH_CIPHER_NONE)
921 log("WARNING: Encryption is disabled! "
922 "Reponse will be transmitted in clear text.");
923 fprintf(stderr, "%s\n", challenge);
924 fflush(stderr);
925 for (i = 0; i < options.number_of_password_prompts; i++) {
926 if (i != 0)
927 error("Permission denied, please try again.");
928 response = read_passphrase("Response: ", 0);
929 packet_start(SSH_CMSG_AUTH_TIS_RESPONSE);
930 packet_put_string(response, strlen(response));
931 memset(response, 0, strlen(response));
932 xfree(response);
933 packet_send();
934 packet_write_wait();
935 type = packet_read(&payload_len);
936 if (type == SSH_SMSG_SUCCESS)
937 return 1;
938 if (type != SSH_SMSG_FAILURE)
939 packet_disconnect("Protocol error: got %d in response "
940 "to skey-auth-reponse", type);
941 }
942 /* failure */
943 return 0;
944}
945
946/*
947 * Tries to authenticate with plain passwd authentication.
948 */
949int
950try_password_authentication(char *prompt)
951{
952 int type, i, payload_len;
953 char *password;
954
955 debug("Doing password authentication.");
956 if (options.cipher == SSH_CIPHER_NONE)
957 log("WARNING: Encryption is disabled! Password will be transmitted in clear text.");
958 for (i = 0; i < options.number_of_password_prompts; i++) {
959 if (i != 0)
960 error("Permission denied, please try again.");
961 password = read_passphrase(prompt, 0);
962 packet_start(SSH_CMSG_AUTH_PASSWORD);
963 packet_put_string(password, strlen(password));
964 memset(password, 0, strlen(password));
965 xfree(password);
966 packet_send();
967 packet_write_wait();
968
969 type = packet_read(&payload_len);
970 if (type == SSH_SMSG_SUCCESS)
971 return 1;
972 if (type != SSH_SMSG_FAILURE)
973 packet_disconnect("Protocol error: got %d in response to passwd auth", type);
974 }
975 /* failure */
976 return 0;
977}
978
5260325f 979/*
980 * Waits for the server identification string, and sends our own
981 * identification string.
982 */
983void
984ssh_exchange_identification()
8efc0c15 985{
5260325f 986 char buf[256], remote_version[256]; /* must be same size! */
987 int remote_major, remote_minor, i;
988 int connection_in = packet_get_connection_in();
989 int connection_out = packet_get_connection_out();
5260325f 990
991 /* Read other side\'s version identification. */
992 for (i = 0; i < sizeof(buf) - 1; i++) {
993 if (read(connection_in, &buf[i], 1) != 1)
994 fatal("ssh_exchange_identification: read: %.100s", strerror(errno));
995 if (buf[i] == '\r') {
996 buf[i] = '\n';
997 buf[i + 1] = 0;
998 break;
999 }
1000 if (buf[i] == '\n') {
1001 buf[i + 1] = 0;
1002 break;
1003 }
8efc0c15 1004 }
5260325f 1005 buf[sizeof(buf) - 1] = 0;
1006
aa3378df 1007 /*
1008 * Check that the versions match. In future this might accept
1009 * several versions and set appropriate flags to handle them.
1010 */
5260325f 1011 if (sscanf(buf, "SSH-%d.%d-%[^\n]\n", &remote_major, &remote_minor,
1012 remote_version) != 3)
1013 fatal("Bad remote protocol version identification: '%.100s'", buf);
1014 debug("Remote protocol version %d.%d, remote software version %.100s",
1015 remote_major, remote_minor, remote_version);
1016
1017 /* Check if the remote protocol version is too old. */
1018 if (remote_major == 1 && remote_minor < 3)
1019 fatal("Remote machine has too old SSH software version.");
1020
1021 /* We speak 1.3, too. */
1022 if (remote_major == 1 && remote_minor == 3) {
1023 enable_compat13();
e02735bb 1024 if (options.forward_agent && strcmp(remote_version, "OpenSSH-1.1") != 0) {
5260325f 1025 log("Agent forwarding disabled, remote version '%s' is not compatible.",
1026 remote_version);
1027 options.forward_agent = 0;
1028 }
8efc0c15 1029 }
8efc0c15 1030#if 0
aa3378df 1031 /*
1032 * Removed for now, to permit compatibility with latter versions. The
1033 * server will reject our version and disconnect if it doesn't
1034 * support it.
1035 */
5260325f 1036 if (remote_major != PROTOCOL_MAJOR)
1037 fatal("Protocol major versions differ: %d vs. %d",
1038 PROTOCOL_MAJOR, remote_major);
8efc0c15 1039#endif
1040
5260325f 1041 /* Send our own protocol version identification. */
1042 snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n",
a408af76 1043 PROTOCOL_MAJOR, PROTOCOL_MINOR, SSH_VERSION);
1044 if (atomicio(write, connection_out, buf, strlen(buf)) != strlen(buf))
5260325f 1045 fatal("write: %.100s", strerror(errno));
8efc0c15 1046}
1047
1048int ssh_cipher_default = SSH_CIPHER_3DES;
1049
5260325f 1050int
1051read_yes_or_no(const char *prompt, int defval)
8efc0c15 1052{
5260325f 1053 char buf[1024];
1054 FILE *f;
1055 int retval = -1;
1056
1057 if (isatty(0))
1058 f = stdin;
1059 else
1060 f = fopen("/dev/tty", "rw");
1061
1062 if (f == NULL)
1063 return 0;
1064
1065 fflush(stdout);
1066
1067 while (1) {
1068 fprintf(stderr, "%s", prompt);
1069 if (fgets(buf, sizeof(buf), f) == NULL) {
1070 /* Print a newline (the prompt probably didn\'t have one). */
1071 fprintf(stderr, "\n");
1072 strlcpy(buf, "no", sizeof buf);
1073 }
1074 /* Remove newline from response. */
1075 if (strchr(buf, '\n'))
1076 *strchr(buf, '\n') = 0;
1077
1078 if (buf[0] == 0)
1079 retval = defval;
1080 if (strcmp(buf, "yes") == 0)
1081 retval = 1;
1082 if (strcmp(buf, "no") == 0)
1083 retval = 0;
1084
1085 if (retval != -1) {
1086 if (f != stdin)
1087 fclose(f);
1088 return retval;
1089 }
8efc0c15 1090 }
8efc0c15 1091}
1092
5260325f 1093/*
95f1eccc 1094 * check whether the supplied host key is valid, return only if ok.
5260325f 1095 */
95f1eccc 1096
5260325f 1097void
95f1eccc 1098check_host_key(char *host,
1099 struct sockaddr_in *hostaddr,
1100 RSA *host_key)
8efc0c15 1101{
95f1eccc 1102 RSA *file_key;
1103 char *ip = NULL;
5260325f 1104 char hostline[1000], *hostp;
5260325f 1105 HostStatus host_status;
1106 HostStatus ip_status;
1107 int host_ip_differ = 0;
1108 int local = (ntohl(hostaddr->sin_addr.s_addr) >> 24) == IN_LOOPBACKNET;
5260325f 1109
57112b5a 1110 /*
1111 * Turn off check_host_ip for proxy connects, since
1112 * we don't have the remote ip-address
1113 */
1114 if (options.proxy_command != NULL && options.check_host_ip)
1115 options.check_host_ip = 0;
1116
5260325f 1117 if (options.check_host_ip)
1118 ip = xstrdup(inet_ntoa(hostaddr->sin_addr));
1119
95f1eccc 1120 /*
1121 * Store the host key from the known host file in here so that we can
1122 * compare it with the key for the IP address.
1123 */
5260325f 1124 file_key = RSA_new();
1125 file_key->n = BN_new();
1126 file_key->e = BN_new();
1127
aa3378df 1128 /*
1129 * Check if the host key is present in the user\'s list of known
1130 * hosts or in the systemwide list.
1131 */
5260325f 1132 host_status = check_host_in_hostfile(options.user_hostfile, host,
1133 host_key->e, host_key->n,
1134 file_key->e, file_key->n);
1135 if (host_status == HOST_NEW)
1136 host_status = check_host_in_hostfile(options.system_hostfile, host,
1137 host_key->e, host_key->n,
1138 file_key->e, file_key->n);
aa3378df 1139 /*
1140 * Force accepting of the host key for localhost and 127.0.0.1. The
1141 * problem is that if the home directory is NFS-mounted to multiple
1142 * machines, localhost will refer to a different machine in each of
1143 * them, and the user will get bogus HOST_CHANGED warnings. This
1144 * essentially disables host authentication for localhost; however,
1145 * this is probably not a real problem.
1146 */
5260325f 1147 if (local) {
1148 debug("Forcing accepting of host key for localhost.");
1149 host_status = HOST_OK;
1150 }
aa3378df 1151 /*
1152 * Also perform check for the ip address, skip the check if we are
1153 * localhost or the hostname was an ip address to begin with
1154 */
5260325f 1155 if (options.check_host_ip && !local && strcmp(host, ip)) {
1156 RSA *ip_key = RSA_new();
1157 ip_key->n = BN_new();
1158 ip_key->e = BN_new();
1159 ip_status = check_host_in_hostfile(options.user_hostfile, ip,
1160 host_key->e, host_key->n,
1161 ip_key->e, ip_key->n);
1162
1163 if (ip_status == HOST_NEW)
1164 ip_status = check_host_in_hostfile(options.system_hostfile, ip,
1165 host_key->e, host_key->n,
1166 ip_key->e, ip_key->n);
1167 if (host_status == HOST_CHANGED &&
1168 (ip_status != HOST_CHANGED ||
1169 (BN_cmp(ip_key->e, file_key->e) || BN_cmp(ip_key->n, file_key->n))))
1170 host_ip_differ = 1;
1171
1172 RSA_free(ip_key);
1173 } else
1174 ip_status = host_status;
1175
1176 RSA_free(file_key);
1177
1178 switch (host_status) {
1179 case HOST_OK:
1180 /* The host is known and the key matches. */
1181 debug("Host '%.200s' is known and matches the host key.", host);
1182 if (options.check_host_ip) {
1183 if (ip_status == HOST_NEW) {
1184 if (!add_host_to_hostfile(options.user_hostfile, ip,
1185 host_key->e, host_key->n))
1186 log("Failed to add the host key for IP address '%.30s' to the list of known hosts (%.30s).",
1187 ip, options.user_hostfile);
1188 else
1189 log("Warning: Permanently added host key for IP address '%.30s' to the list of known hosts.",
1190 ip);
1191 } else if (ip_status != HOST_OK)
1192 log("Warning: the host key for '%.200s' differs from the key for the IP address '%.30s'",
1193 host, ip);
1194 }
1195 break;
1196 case HOST_NEW:
1197 /* The host is new. */
1198 if (options.strict_host_key_checking == 1) {
1199 /* User has requested strict host key checking. We will not add the host key
1200 automatically. The only alternative left is to abort. */
1201 fatal("No host key is known for %.200s and you have requested strict checking.", host);
1202 } else if (options.strict_host_key_checking == 2) {
1203 /* The default */
1204 char prompt[1024];
1205 char *fp = fingerprint(host_key->e, host_key->n);
1206 snprintf(prompt, sizeof(prompt),
a408af76 1207 "The authenticity of host '%.200s' can't be established.\n"
1208 "Key fingerprint is %d %s.\n"
1209 "Are you sure you want to continue connecting (yes/no)? ",
1210 host, BN_num_bits(host_key->n), fp);
5260325f 1211 if (!read_yes_or_no(prompt, -1))
1212 fatal("Aborted by user!\n");
1213 }
1214 if (options.check_host_ip && ip_status == HOST_NEW && strcmp(host, ip)) {
1215 snprintf(hostline, sizeof(hostline), "%s,%s", host, ip);
1216 hostp = hostline;
1217 } else
1218 hostp = host;
1219
1220 /* If not in strict mode, add the key automatically to the local known_hosts file. */
1221 if (!add_host_to_hostfile(options.user_hostfile, hostp,
1222 host_key->e, host_key->n))
1223 log("Failed to add the host to the list of known hosts (%.500s).",
1224 options.user_hostfile);
1225 else
1226 log("Warning: Permanently added '%.200s' to the list of known hosts.",
1227 hostp);
1228 break;
1229 case HOST_CHANGED:
1230 if (options.check_host_ip && host_ip_differ) {
1231 char *msg;
1232 if (ip_status == HOST_NEW)
1233 msg = "is unknown";
1234 else if (ip_status == HOST_OK)
1235 msg = "is unchanged";
1236 else
1237 msg = "has a different value";
1238 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
1239 error("@ WARNING: POSSIBLE DNS SPOOFING DETECTED! @");
1240 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
1241 error("The host key for %s has changed,", host);
1242 error("and the key for the according IP address %s", ip);
1243 error("%s. This could either mean that", msg);
1244 error("DNS SPOOFING is happening or the IP address for the host");
1245 error("and its host key have changed at the same time");
1246 }
1247 /* The host key has changed. */
1248 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
ae2f7af7 1249 error("@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @");
5260325f 1250 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
1251 error("IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!");
1252 error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!");
1253 error("It is also possible that the host key has just been changed.");
1254 error("Please contact your system administrator.");
1255 error("Add correct host key in %.100s to get rid of this message.",
1256 options.user_hostfile);
1257
aa3378df 1258 /*
1259 * If strict host key checking is in use, the user will have
1260 * to edit the key manually and we can only abort.
1261 */
5260325f 1262 if (options.strict_host_key_checking)
1263 fatal("Host key for %.200s has changed and you have requested strict checking.", host);
1264
aa3378df 1265 /*
1266 * If strict host key checking has not been requested, allow
1267 * the connection but without password authentication or
1268 * agent forwarding.
1269 */
5260325f 1270 if (options.password_authentication) {
1271 error("Password authentication is disabled to avoid trojan horses.");
1272 options.password_authentication = 0;
1273 }
1274 if (options.forward_agent) {
1275 error("Agent forwarding is disabled to avoid trojan horses.");
1276 options.forward_agent = 0;
1277 }
aa3378df 1278 /*
1279 * XXX Should permit the user to change to use the new id.
1280 * This could be done by converting the host key to an
1281 * identifying sentence, tell that the host identifies itself
1282 * by that sentence, and ask the user if he/she whishes to
1283 * accept the authentication.
1284 */
5260325f 1285 break;
1286 }
5260325f 1287 if (options.check_host_ip)
1288 xfree(ip);
95f1eccc 1289}
1290
1291/*
1292 * Starts a dialog with the server, and authenticates the current user on the
1293 * server. This does not need any extra privileges. The basic connection
1294 * to the server must already have been established before this is called.
1295 * User is the remote user; if it is NULL, the current local user name will
1296 * be used. Anonymous indicates that no rhosts authentication will be used.
1297 * If login fails, this function prints an error and never returns.
1298 * This function does not require super-user privileges.
1299 */
1300void
1301ssh_login(int host_key_valid,
1302 RSA *own_host_key,
1303 const char *orighost,
1304 struct sockaddr_in *hostaddr,
1305 uid_t original_real_uid)
1306{
1307 int i, type;
1308 struct passwd *pw;
1309 BIGNUM *key;
1310 RSA *host_key;
1311 RSA *public_key;
1312 int bits, rbits;
1313 unsigned char session_key[SSH_SESSION_KEY_LENGTH];
1314 const char *server_user, *local_user;
1315 char *host, *cp;
1316 unsigned char check_bytes[8];
1317 unsigned int supported_ciphers, supported_authentications;
1318 unsigned int server_flags, client_flags;
1319 int payload_len, clen, sum_len = 0;
1320 u_int32_t rand = 0;
1321
1322 /* Convert the user-supplied hostname into all lowercase. */
1323 host = xstrdup(orighost);
1324 for (cp = host; *cp; cp++)
1325 if (isupper(*cp))
1326 *cp = tolower(*cp);
1327
1328 /* Exchange protocol version identification strings with the server. */
1329 ssh_exchange_identification();
1330
1331 /* Put the connection into non-blocking mode. */
1332 packet_set_nonblocking();
1333
1334 /* Get local user name. Use it as server user if no user name was given. */
1335 pw = getpwuid(original_real_uid);
1336 if (!pw)
1337 fatal("User id %d not found from user database.", original_real_uid);
1338 local_user = xstrdup(pw->pw_name);
1339 server_user = options.user ? options.user : local_user;
1340
1341 debug("Waiting for server public key.");
1342
1343 /* Wait for a public key packet from the server. */
1344 packet_read_expect(&payload_len, SSH_SMSG_PUBLIC_KEY);
1345
1346 /* Get check bytes from the packet. */
1347 for (i = 0; i < 8; i++)
1348 check_bytes[i] = packet_get_char();
1349
1350 /* Get the public key. */
1351 public_key = RSA_new();
1352 bits = packet_get_int();/* bits */
1353 public_key->e = BN_new();
1354 packet_get_bignum(public_key->e, &clen);
1355 sum_len += clen;
1356 public_key->n = BN_new();
1357 packet_get_bignum(public_key->n, &clen);
1358 sum_len += clen;
1359
1360 rbits = BN_num_bits(public_key->n);
1361 if (bits != rbits) {
1362 log("Warning: Server lies about size of server public key: "
1363 "actual size is %d bits vs. announced %d.", rbits, bits);
1364 log("Warning: This may be due to an old implementation of ssh.");
1365 }
1366 /* Get the host key. */
1367 host_key = RSA_new();
1368 bits = packet_get_int();/* bits */
1369 host_key->e = BN_new();
1370 packet_get_bignum(host_key->e, &clen);
1371 sum_len += clen;
1372 host_key->n = BN_new();
1373 packet_get_bignum(host_key->n, &clen);
1374 sum_len += clen;
1375
1376 rbits = BN_num_bits(host_key->n);
1377 if (bits != rbits) {
1378 log("Warning: Server lies about size of server host key: "
1379 "actual size is %d bits vs. announced %d.", rbits, bits);
1380 log("Warning: This may be due to an old implementation of ssh.");
1381 }
1382
1383 /* Get protocol flags. */
1384 server_flags = packet_get_int();
1385 packet_set_protocol_flags(server_flags);
1386
1387 supported_ciphers = packet_get_int();
1388 supported_authentications = packet_get_int();
1389
1390 debug("Received server public key (%d bits) and host key (%d bits).",
1391 BN_num_bits(public_key->n), BN_num_bits(host_key->n));
1392
1393 packet_integrity_check(payload_len,
1394 8 + 4 + sum_len + 0 + 4 + 0 + 0 + 4 + 4 + 4,
1395 SSH_SMSG_PUBLIC_KEY);
1396
1397 check_host_key(host, hostaddr, host_key);
1398
1399 client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN;
1400
1401 compute_session_id(session_id, check_bytes, host_key->n, public_key->n);
5260325f 1402
1403 /* Generate a session key. */
1404 arc4random_stir();
1405
aa3378df 1406 /*
1407 * Generate an encryption key for the session. The key is a 256 bit
1408 * random number, interpreted as a 32-byte key, with the least
1409 * significant 8 bits being the first byte of the key.
1410 */
5260325f 1411 for (i = 0; i < 32; i++) {
1412 if (i % 4 == 0)
1413 rand = arc4random();
1414 session_key[i] = rand & 0xff;
1415 rand >>= 8;
1416 }
1417
aa3378df 1418 /*
1419 * According to the protocol spec, the first byte of the session key
1420 * is the highest byte of the integer. The session key is xored with
1421 * the first 16 bytes of the session id.
1422 */
5260325f 1423 key = BN_new();
1424 BN_set_word(key, 0);
1425 for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++) {
1426 BN_lshift(key, key, 8);
1427 if (i < 16)
1428 BN_add_word(key, session_key[i] ^ session_id[i]);
1429 else
1430 BN_add_word(key, session_key[i]);
1431 }
1432
aa3378df 1433 /*
1434 * Encrypt the integer using the public key and host key of the
1435 * server (key with smaller modulus first).
1436 */
5260325f 1437 if (BN_cmp(public_key->n, host_key->n) < 0) {
1438 /* Public key has smaller modulus. */
1439 if (BN_num_bits(host_key->n) <
1440 BN_num_bits(public_key->n) + SSH_KEY_BITS_RESERVED) {
1441 fatal("respond_to_rsa_challenge: host_key %d < public_key %d + "
1442 "SSH_KEY_BITS_RESERVED %d",
1443 BN_num_bits(host_key->n),
1444 BN_num_bits(public_key->n),
1445 SSH_KEY_BITS_RESERVED);
1446 }
1447 rsa_public_encrypt(key, key, public_key);
1448 rsa_public_encrypt(key, key, host_key);
1449 } else {
1450 /* Host key has smaller modulus (or they are equal). */
1451 if (BN_num_bits(public_key->n) <
1452 BN_num_bits(host_key->n) + SSH_KEY_BITS_RESERVED) {
1453 fatal("respond_to_rsa_challenge: public_key %d < host_key %d + "
1454 "SSH_KEY_BITS_RESERVED %d",
1455 BN_num_bits(public_key->n),
1456 BN_num_bits(host_key->n),
1457 SSH_KEY_BITS_RESERVED);
1458 }
1459 rsa_public_encrypt(key, key, host_key);
1460 rsa_public_encrypt(key, key, public_key);
1461 }
1462
1463 if (options.cipher == SSH_CIPHER_NOT_SET) {
1464 if (cipher_mask() & supported_ciphers & (1 << ssh_cipher_default))
1465 options.cipher = ssh_cipher_default;
1466 else {
1467 debug("Cipher %s not supported, using %.100s instead.",
1468 cipher_name(ssh_cipher_default),
1469 cipher_name(SSH_FALLBACK_CIPHER));
1470 options.cipher = SSH_FALLBACK_CIPHER;
1471 }
1472 }
1473 /* Check that the selected cipher is supported. */
1474 if (!(supported_ciphers & (1 << options.cipher)))
1475 fatal("Selected cipher type %.100s not supported by server.",
1476 cipher_name(options.cipher));
1477
1478 debug("Encryption type: %.100s", cipher_name(options.cipher));
1479
1480 /* Send the encrypted session key to the server. */
1481 packet_start(SSH_CMSG_SESSION_KEY);
1482 packet_put_char(options.cipher);
1483
1484 /* Send the check bytes back to the server. */
1485 for (i = 0; i < 8; i++)
1486 packet_put_char(check_bytes[i]);
1487
1488 /* Send the encrypted encryption key. */
1489 packet_put_bignum(key);
1490
1491 /* Send protocol flags. */
95f1eccc 1492 packet_put_int(client_flags);
5260325f 1493
1494 /* Send the packet now. */
8efc0c15 1495 packet_send();
1496 packet_write_wait();
5260325f 1497
1498 /* Destroy the session key integer and the public keys since we no longer need them. */
1499 BN_clear_free(key);
1500 RSA_free(public_key);
1501 RSA_free(host_key);
1502
1503 debug("Sent encrypted session key.");
1504
1505 /* Set the encryption key. */
1506 packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, options.cipher);
1507
1508 /* We will no longer need the session key here. Destroy any extra copies. */
1509 memset(session_key, 0, sizeof(session_key));
1510
aa3378df 1511 /*
1512 * Expect a success message from the server. Note that this message
1513 * will be received in encrypted form.
1514 */
5260325f 1515 packet_read_expect(&payload_len, SSH_SMSG_SUCCESS);
1516
1517 debug("Received encrypted confirmation.");
1518
1519 /* Send the name of the user to log in as on the server. */
1520 packet_start(SSH_CMSG_USER);
1521 packet_put_string(server_user, strlen(server_user));
1522 packet_send();
1523 packet_write_wait();
1524
aa3378df 1525 /*
1526 * The server should respond with success if no authentication is
1527 * needed (the user has no password). Otherwise the server responds
1528 * with failure.
1529 */
8efc0c15 1530 type = packet_read(&payload_len);
5260325f 1531
1532 /* check whether the connection was accepted without authentication. */
8efc0c15 1533 if (type == SSH_SMSG_SUCCESS)
5260325f 1534 return;
8efc0c15 1535 if (type != SSH_SMSG_FAILURE)
5260325f 1536 packet_disconnect("Protocol error: got %d in response to SSH_CMSG_USER",
1537 type);
1538
1539#ifdef AFS
1540 /* Try Kerberos tgt passing if the server supports it. */
1541 if ((supported_authentications & (1 << SSH_PASS_KERBEROS_TGT)) &&
1542 options.kerberos_tgt_passing) {
1543 if (options.cipher == SSH_CIPHER_NONE)
1544 log("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!");
1545 (void) send_kerberos_tgt();
1546 }
1547 /* Try AFS token passing if the server supports it. */
1548 if ((supported_authentications & (1 << SSH_PASS_AFS_TOKEN)) &&
1549 options.afs_token_passing && k_hasafs()) {
1550 if (options.cipher == SSH_CIPHER_NONE)
1551 log("WARNING: Encryption is disabled! Token will be transmitted in the clear!");
1552 send_afs_tokens();
1553 }
1554#endif /* AFS */
8efc0c15 1555
5260325f 1556#ifdef KRB4
1557 if ((supported_authentications & (1 << SSH_AUTH_KERBEROS)) &&
1558 options.kerberos_authentication) {
1559 debug("Trying Kerberos authentication.");
1560 if (try_kerberos_authentication()) {
1561 /* The server should respond with success or failure. */
1562 type = packet_read(&payload_len);
1563 if (type == SSH_SMSG_SUCCESS)
1564 return;
1565 if (type != SSH_SMSG_FAILURE)
1566 packet_disconnect("Protocol error: got %d in response to Kerberos auth", type);
1567 }
1568 }
1569#endif /* KRB4 */
1570
aa3378df 1571 /*
1572 * Use rhosts authentication if running in privileged socket and we
1573 * do not wish to remain anonymous.
1574 */
5260325f 1575 if ((supported_authentications & (1 << SSH_AUTH_RHOSTS)) &&
1576 options.rhosts_authentication) {
1577 debug("Trying rhosts authentication.");
1578 packet_start(SSH_CMSG_AUTH_RHOSTS);
1579 packet_put_string(local_user, strlen(local_user));
1580 packet_send();
1581 packet_write_wait();
1582
1583 /* The server should respond with success or failure. */
1584 type = packet_read(&payload_len);
1585 if (type == SSH_SMSG_SUCCESS)
1586 return;
1587 if (type != SSH_SMSG_FAILURE)
1588 packet_disconnect("Protocol error: got %d in response to rhosts auth",
1589 type);
1590 }
aa3378df 1591 /*
1592 * Try .rhosts or /etc/hosts.equiv authentication with RSA host
1593 * authentication.
1594 */
5260325f 1595 if ((supported_authentications & (1 << SSH_AUTH_RHOSTS_RSA)) &&
1596 options.rhosts_rsa_authentication && host_key_valid) {
1597 if (try_rhosts_rsa_authentication(local_user, own_host_key))
1598 return;
1599 }
1600 /* Try RSA authentication if the server supports it. */
1601 if ((supported_authentications & (1 << SSH_AUTH_RSA)) &&
1602 options.rsa_authentication) {
aa3378df 1603 /*
1604 * Try RSA authentication using the authentication agent. The
1605 * agent is tried first because no passphrase is needed for
1606 * it, whereas identity files may require passphrases.
1607 */
5260325f 1608 if (try_agent_authentication())
1609 return;
1610
1611 /* Try RSA authentication for each identity. */
1612 for (i = 0; i < options.num_identity_files; i++)
57112b5a 1613 if (try_rsa_authentication(options.identity_files[i]))
5260325f 1614 return;
1615 }
1616 /* Try skey authentication if the server supports it. */
1617 if ((supported_authentications & (1 << SSH_AUTH_TIS)) &&
1618 options.skey_authentication && !options.batch_mode) {
57112b5a 1619 if (try_skey_authentication())
1620 return;
5260325f 1621 }
1622 /* Try password authentication if the server supports it. */
1623 if ((supported_authentications & (1 << SSH_AUTH_PASSWORD)) &&
1624 options.password_authentication && !options.batch_mode) {
1625 char prompt[80];
a408af76 1626
57112b5a 1627 snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ",
a408af76 1628 server_user, host);
57112b5a 1629 if (try_password_authentication(prompt))
1630 return;
5260325f 1631 }
1632 /* All authentication methods have failed. Exit with an error message. */
1633 fatal("Permission denied.");
1634 /* NOTREACHED */
8efc0c15 1635}
This page took 0.299581 seconds and 5 git commands to generate.