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