source: trunk/third/ssh/sshconnect.c @ 12138

Revision 12138, 54.1 KB checked in by ghudson, 26 years ago (diff)
Close some possible buffer overflows.
Line 
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/*
18 * $Id: sshconnect.c,v 1.2 1998-11-09 16:25:24 ghudson Exp $
19 * $Log: not supported by cvs2svn $
20 * Revision 1.1.1.3  1998/05/13 19:11:27  danw
21 * Import of ssh 1.2.23
22 *
23 * Revision 1.26  1998/04/30 01:56:01  kivinen
24 *      Added PasswordPromptLogin and PasswordPromptHost option code.
25 *      Added check that proxy command isn't empty.
26 *
27 * Revision 1.25  1998/03/27 17:04:04  kivinen
28 *      Changed socks support to support socks.h. Added
29 *      ENABLE_TCP_NODELAY support. Fixed kerberos initialization code
30 *      so ssh will check the error codes of initialization function.
31 *
32 * Revision 1.24  1998/01/02 06:23:28  kivinen
33 *      Changed "foo's password" prompt to "foo@bar's password".
34 *
35 * Revision 1.23  1997/04/27 21:55:51  kivinen
36 *      Added F-SECURE stuff.
37 *
38 * Revision 1.22  1997/04/23 00:05:01  kivinen
39 *      Implemented NumberOfPasswordPrompts option.
40 *
41 * Revision 1.21  1997/04/17 04:16:32  kivinen
42 *      Added strict_host_key_checking == 2 (== ask) support.
43 *      Moved asking of confirmation from user to read_confirmation
44 *      function.
45 *      Added checks that if in batch_mode do not ask confirmations.
46 *
47 * Revision 1.20  1997/04/05 22:02:04  kivinen
48 *      Removed restriction that ssh only used priviledged port if
49 *      server port was < 1024. Fixed KRB5 support.
50 *
51 * Revision 1.19  1997/03/27 03:11:35  kivinen
52 *      Added kerberos patches from Glenn Machin.
53 *
54 * Revision 1.18  1997/03/26 07:11:08  kivinen
55 *      Added local localhost mapping.
56 *      Fixed some messages.
57 *      Allow password authentication even when host key have
58 *      changed, because we ask about it from user.
59 *
60 * Revision 1.17  1997/03/26 05:35:30  kivinen
61 *      Changed uid 0 to UID_ROOT.
62 *
63 * Revision 1.16  1997/03/25 05:47:15  kivinen
64 *      Added Rgethostbyname for SOCKS5.
65 *
66 * Revision 1.15  1997/03/19 21:16:22  kivinen
67 *      Added local mapping of "localhost" to "127.0.0.1" to avoid dns
68 *      attacks for localhost (the host key checking is disabled for
69 *      localhost).
70 *      Added yes/no prompt if host key is not known or changed.
71 *      Disabled x11 and port forwardings if host key have changed.
72 *
73 * Revision 1.14  1997/03/19 17:45:36  kivinen
74 *      Added SECURE_RPC, SECURE_NFS and NIS_PLUS support from Andy
75 *      Polyakov <appro@fy.chalmers.se>.
76 *      Disabled agent forwarding if host key doesn't match.
77 *      Added TIS authentication code from Andre April
78 *      <Andre.April@cediti.be>.
79 *
80 * Revision 1.13  1996/12/04 18:15:08  ttsalo
81 *     Added calls to ssh_close_authentication_connection
82 *
83 * Revision 1.12  1996/11/12 18:44:41  kivinen
84 *      Changed password back to foos's password, as I was informed
85 *      that Webster was in illiterate and the previous version was
86 *      correct when using English grammar.
87 *
88 * Revision 1.11  1996/11/07 06:48:12  kivinen
89 *      Fixed foos's password: prompt to foos' password:.
90 *
91 * Revision 1.10  1996/11/04 16:19:29  ttsalo
92 *       Improved error handling in code receiving protocol version byte
93 *
94 * Revision 1.9  1996/11/04 14:37:16  ttsalo
95 *       Fixed someone's typo (...VERSION_MAJOR... -> ...MAJOR_VERSION...)
96 *
97 * Revision 1.8  1996/11/04 06:34:24  ylo
98 *      Updated processing of check_emulation output.
99 *
100 * Revision 1.7  1996/10/29 22:47:16  kivinen
101 *      log -> log_msg.
102 *      Added username to password prompt.
103 *
104 * Revision 1.6  1996/05/25 23:33:12  ylo
105 *      Fixed a minor bug in the logic used to determine whether to allocate
106 *      a privileged local port.
107 *
108 * Revision 1.5  1996/04/26 00:24:10  ylo
109 *      Fixed SOCKS code.
110 *      Fixed reconnecting with SOCKS.
111 *
112 * Revision 1.4  1996/04/22 23:49:46  huima
113 * Changed protocol version to 1.4, added calls to emulate module.
114 *
115 * Revision 1.3  1996/02/19  16:07:23  huima
116 *      Minor fixes.
117 *
118 * Revision 1.2  1996/02/18  21:50:23  ylo
119 *      Added a call to userfile_close_pipes in proxy code.
120 *
121 * Revision 1.1.1.1  1996/02/18 21:38:12  ylo
122 *      Imported ssh-1.2.13.
123 *
124 * Revision 1.15  1995/09/27  02:16:40  ylo
125 *      Eliminated compiler warning.
126 *
127 * Revision 1.14  1995/09/25  00:02:55  ylo
128 *      Added connection_attempts.
129 *      Added screen number forwarding.
130 *
131 * Revision 1.13  1995/09/22  22:23:23  ylo
132 *      Changed interface of ssh_login to use the option structure
133 *      instead of numerous individual arguments.
134 *
135 * Revision 1.12  1995/09/21  17:17:44  ylo
136 *      Added original_real_uid argument to ssh_connect.
137 *
138 * Revision 1.11  1995/09/13  12:03:55  ylo
139 *      Added debugging output to print uids.
140 *
141 * Revision 1.10  1995/09/10  22:48:29  ylo
142 *      Added original_real_uid parameter to ssh_login.  Changed to
143 *      use it.
144 *      Fixed read_passphrase arguments.
145 *
146 * Revision 1.9  1995/09/09  21:26:46  ylo
147 * /m/shadows/u2/users/ylo/ssh/README
148 *
149 * Revision 1.8  1995/09/06  16:01:12  ylo
150 *      Added BROKEN_INET_ADDR.
151 *
152 * Revision 1.7  1995/08/31  09:24:23  ylo
153 *      Fixed user_hostfile name processing.
154 *
155 * Revision 1.6  1995/08/21  23:29:32  ylo
156 *      Clear sockaddr_in before using.
157 *      Pass session_id and response_type to ssh_decrypt_challenge.
158 *
159 * Revision 1.5  1995/07/27  02:18:13  ylo
160 *      Tell packet_set_encryption_key that we are the client.
161 *
162 * Revision 1.4  1995/07/27  00:40:56  ylo
163 *      Added GlobalKnownHostsFile and UserKnownHostsFile.
164 *
165 * Revision 1.3  1995/07/26  23:19:20  ylo
166 *      Removed include version.h.
167 *
168 *      Added code for protocol version 1.1.  This involves changes in
169 *      the session key exchange code and RSA responses to make
170 *      replay impossible and to bind RSA responses to a particular
171 *      session so that a corrupt server cannot pass them on to
172 *      another connection.  Moved rsa response code to a separate function.
173 *
174 *      Fixed session key exchange to match the RFC draft.
175 *
176 *      Prints a warning if server uses older protocol version (but
177 *      compatibility code still supports the older version).
178 *
179 * Revision 1.2  1995/07/13  01:40:32  ylo
180 *      Removed "Last modified" header.
181 *      Added cvs log.
182 *
183 * $Endlog$
184 */
185
186#include "includes.h"
187#include <gmp.h>
188#include "xmalloc.h"
189#include "randoms.h"
190#include "rsa.h"
191#include "ssh.h"
192#include "packet.h"
193#include "authfd.h"
194#include "cipher.h"
195#include "md5.h"
196#include "mpaux.h"
197#include "userfile.h"
198#include "emulate.h"
199
200#ifdef KERBEROS
201#ifdef KRB5
202#include <krb5.h>
203
204/* Global the contexts */
205krb5_context ssh_context = 0;
206krb5_auth_context auth_context = 0;
207#endif /* KRB5 */
208#endif /* KERBEROS */
209
210/* Session id for the current session. */
211unsigned char session_id[16];
212
213/* Connect to the given ssh server using a proxy command. */
214
215int ssh_proxy_connect(const char *host, int port, uid_t original_real_uid,
216                      const char *proxy_command, RandomState *random_state)
217{
218  Buffer command;
219  const char *cp;
220  char *command_string;
221  int pin[2], pout[2];
222  int pid;
223  char portstring[100];
224
225  /* Convert the port number into a string. */
226  sprintf(portstring, "%d", port);
227
228  /* Build the final command string in the buffer by making the appropriate
229     substitutions to the given proxy command. */
230  buffer_init(&command);
231  for (cp = proxy_command; *cp; cp++)
232    {
233      if (cp[0] == '%' && cp[1] == '%')
234        {
235          buffer_append(&command, "%", 1);
236          cp++;
237          continue;
238        }
239      if (cp[0] == '%' && cp[1] == 'h')
240        {
241          buffer_append(&command, host, strlen(host));
242          cp++;
243          continue;
244        }
245      if (cp[0] == '%' && cp[1] == 'p')
246        {
247          buffer_append(&command, portstring, strlen(portstring));
248          cp++;
249          continue;
250        }
251      buffer_append(&command, cp, 1);
252    }
253  buffer_append(&command, "\0", 1);
254
255  /* Get the final command string. */
256  command_string = buffer_ptr(&command);
257
258  /* Create pipes for communicating with the proxy. */
259  if (pipe(pin) < 0 || pipe(pout) < 0)
260    fatal("Could not create pipes to communicate with the proxy: %.100s",
261          strerror(errno));
262
263  debug("Executing proxy command: %.500s", command_string);
264
265  /* Fork and execute the proxy command. */
266  if ((pid = fork()) == 0)
267    {
268      char *argv[10];
269
270      /* Close all pipes to userfile. */
271      userfile_close_pipes();
272
273      /* Child.  Permanently give up superuser privileges. */
274      if (setuid(getuid()) < 0)
275        fatal("setuid: %.100s", strerror(errno));
276
277      /* Redirect stdin and stdout. */
278      close(pin[1]);
279      if (pin[0] != 0)
280        {
281          if (dup2(pin[0], 0) < 0)
282            perror("dup2 stdin");
283          close(pin[0]);
284        }
285      close(pout[0]);
286      if (dup2(pout[1], 1) < 0)
287        perror("dup2 stdout");
288      close(pout[1]); /* Cannot be 1 because pin allocated two descriptors. */
289
290      /* Stderr is left as it is so that error messages get printed on
291         the user's terminal. */
292      argv[0] = "/bin/sh";
293      argv[1] = "-c";
294      argv[2] = command_string;
295      argv[3] = NULL;
296     
297      /* Execute the proxy command.  Note that we gave up any extra
298         privileges above. */
299      execv("/bin/sh", argv);
300      perror("/bin/sh");
301      exit(1);
302    }
303  /* Parent. */
304  if (pid < 0)
305    fatal("fork failed: %.100s", strerror(errno));
306 
307  /* Close child side of the descriptors. */
308  close(pin[0]);
309  close(pout[1]);
310
311  /* Free the command name. */
312  buffer_free(&command);
313 
314  /* Set the connection file descriptors. */
315  packet_set_connection(pout[0], pin[1], random_state);
316
317  return 1;
318}
319
320/* Creates a (possibly privileged) socket for use as the ssh connection. */
321
322int ssh_create_socket(uid_t original_real_uid, int privileged)
323{
324  int sock;
325
326  /* If we are running as root and want to connect to a privileged port,
327     bind our own socket to a privileged port. */
328  if (privileged)
329    {
330      struct sockaddr_in sin;
331      int p;
332      for (p = 1023; p > 512; p--)
333        {
334          sock = socket(AF_INET, SOCK_STREAM, 0);
335          if (sock < 0)
336            fatal("socket: %.100s", strerror(errno));
337         
338          /* Initialize the desired sockaddr_in structure. */
339          memset(&sin, 0, sizeof(sin));
340          sin.sin_family = AF_INET;
341          sin.sin_addr.s_addr = INADDR_ANY;
342          sin.sin_port = htons(p);
343
344          /* Try to bind the socket to the privileged port. */
345#if defined(SOCKS) && !defined(HAVE_SOCKS_H)
346          if (Rbind(sock, (struct sockaddr *)&sin, sizeof(sin)) >= 0)
347            break; /* Success. */
348#else /* SOCKS */
349          if (bind(sock, (struct sockaddr *)&sin, sizeof(sin)) >= 0)
350            break; /* Success. */
351#endif /* SOCKS */
352          if (errno == EADDRINUSE)
353            {
354              close(sock);
355              continue;
356            }
357          fatal("bind: %.100s", strerror(errno));
358        }
359      debug("Allocated local port %d.", p);
360    }
361  else
362    {
363      /* Just create an ordinary socket on arbitrary port.  */
364      sock = socket(AF_INET, SOCK_STREAM, 0);
365      if (sock < 0)
366        fatal("socket: %.100s", strerror(errno));
367    }
368  return sock;
369}
370
371/* Opens a TCP/IP connection to the remote server on the given host.  If
372   port is 0, the default port will be used.  If anonymous is zero,
373   a privileged port will be allocated to make the connection.
374   This requires super-user privileges if anonymous is false.
375   Connection_attempts specifies the maximum number of tries (one per
376   second).  If proxy_command is non-NULL, it specifies the command (with %h
377   and %p substituted for host and port, respectively) to use to contact
378   the daemon. */
379
380int ssh_connect(const char *host, int port, int connection_attempts,
381                int anonymous, uid_t original_real_uid,
382                const char *proxy_command, RandomState *random_state)
383{
384  int sock = -1, attempt, i;
385  int on = 1;
386  struct servent *sp;
387  struct hostent *hp;
388  struct sockaddr_in hostaddr;
389#ifdef SO_LINGER
390  struct linger linger;
391#endif /* SO_LINGER */
392
393  debug("ssh_connect: getuid %d geteuid %d anon %d",
394        (int)getuid(), (int)geteuid(), anonymous);
395
396  /* Get default port if port has not been set. */
397  if (port == 0)
398    {
399      sp = getservbyname(SSH_SERVICE_NAME, "tcp");
400      if (sp)
401        port = ntohs(sp->s_port);
402      else
403        port = SSH_DEFAULT_PORT;
404    }
405
406  /* Map localhost to ip-address locally */
407  if (strcmp(host, "localhost") == 0)
408    host = "127.0.0.1";
409 
410  /* If a proxy command is given, connect using it. */
411  if (proxy_command != NULL && *proxy_command)
412    return ssh_proxy_connect(host, port, original_real_uid, proxy_command,
413                             random_state);
414
415  /* No proxy command. */
416
417  /* No host lookup made yet. */
418  hp = NULL;
419 
420  /* Try to connect several times.  On some machines, the first time will
421     sometimes fail.  In general socket code appears to behave quite
422     magically on many machines. */
423  for (attempt = 0; attempt < connection_attempts; attempt++)
424    {
425      if (attempt > 0)
426        debug("Trying again...");
427
428      /* Try to parse the host name as a numeric inet address. */
429      memset(&hostaddr, 0, sizeof(hostaddr));
430      hostaddr.sin_family = AF_INET;
431      hostaddr.sin_port = htons(port);
432#ifdef BROKEN_INET_ADDR
433      hostaddr.sin_addr.s_addr = inet_network(host);
434#else /* BROKEN_INET_ADDR */
435      hostaddr.sin_addr.s_addr = inet_addr(host);
436#endif /* BROKEN_INET_ADDR */
437      if ((hostaddr.sin_addr.s_addr & 0xffffffff) != 0xffffffff)
438        {
439          /* Valid numeric IP address */
440          debug("Connecting to %.100s port %d.",
441                inet_ntoa(hostaddr.sin_addr), port);
442     
443          /* Create a socket. */
444          sock = ssh_create_socket(original_real_uid,
445                                   !anonymous && geteuid() == UID_ROOT);
446     
447          /* Connect to the host. */
448#if defined(SOCKS) && !defined(HAVE_SOCKS_H)
449          if (Rconnect(sock, (struct sockaddr *)&hostaddr, sizeof(hostaddr))
450#else /* SOCKS */
451          if (connect(sock, (struct sockaddr *)&hostaddr, sizeof(hostaddr))
452#endif /* SOCKS */
453              >= 0)
454            {
455              /* Successful connect. */
456              break;
457            }
458          debug("connect: %.100s", strerror(errno));
459
460          /* Destroy the failed socket. */
461          shutdown(sock, 2);
462          close(sock);
463        }
464      else
465        {
466          /* Not a valid numeric inet address. */
467          /* Map host name to an address. */
468          if (!hp)
469            {
470              struct hostent *hp_static;
471
472#if defined(SOCKS5) && !defined(HAVE_SOCKS_H)
473              hp_static = Rgethostbyname(host);
474#else
475              hp_static = gethostbyname(host);
476#endif
477              if (hp_static)
478                {
479                  hp = xmalloc(sizeof(struct hostent));
480                  memcpy(hp, hp_static, sizeof(struct hostent));
481
482                  /* Copy list of addresses, not just pointers.
483                     We don't use h_name & h_aliases so leave them as is */
484                  for (i = 0; hp_static->h_addr_list[i]; i++)
485                    ; /* count them */
486                  hp->h_addr_list = xmalloc((i + 1) *
487                                            sizeof(hp_static->h_addr_list[0]));
488                  for (i = 0; hp_static->h_addr_list[i]; i++)
489                    {
490                      hp->h_addr_list[i] = xmalloc(hp->h_length);
491                      memcpy(hp->h_addr_list[i], hp_static->h_addr_list[i],
492                             hp->h_length);
493                    }
494                  hp->h_addr_list[i] = NULL; /* last one */
495                }
496            }
497          if (!hp)
498            fatal("Bad host name: %.100s", host);
499          if (!hp->h_addr_list[0])
500            fatal("Host does not have an IP address: %.100s", host);
501
502          /* Loop through addresses for this host, and try each one in
503             sequence until the connection succeeds. */
504          for (i = 0; hp->h_addr_list[i]; i++)
505            {
506              /* Set the address to connect to. */
507              hostaddr.sin_family = hp->h_addrtype;
508              memcpy(&hostaddr.sin_addr, hp->h_addr_list[i],
509                     sizeof(hostaddr.sin_addr));
510
511              debug("Connecting to %.200s [%.100s] port %d.",
512                    host, inet_ntoa(hostaddr.sin_addr), port);
513
514              /* Create a socket for connecting. */
515              sock = ssh_create_socket(original_real_uid,
516                                       !anonymous && geteuid() == UID_ROOT);
517
518              /* Connect to the host. */
519#if defined(SOCKS) && !defined(HAVE_SOCKS_H)
520              if (Rconnect(sock, (struct sockaddr *)&hostaddr,
521                           sizeof(hostaddr)) >= 0)
522#else /* SOCKS */
523              if (connect(sock, (struct sockaddr *)&hostaddr,
524                          sizeof(hostaddr)) >= 0)
525#endif /* SOCKS */
526                {
527                  /* Successful connection. */
528                  break;
529                }
530              debug("connect: %.100s", strerror(errno));
531
532              /* Close the failed socket; there appear to be some problems
533                 when reusing a socket for which connect() has already
534                 returned an error. */
535              shutdown(sock, 2);
536              close(sock);
537            }
538          if (hp->h_addr_list[i])
539            break; /* Successful connection. */
540        }
541
542      /* Sleep a moment before retrying. */
543      sleep(1);
544    }
545
546  if (hp)
547    {
548      for (i = 0; hp->h_addr_list[i]; i++)
549        xfree(hp->h_addr_list[i]);
550      xfree(hp->h_addr_list);
551      xfree(hp);
552    }
553
554  /* Return failure if we didn't get a successful connection. */
555  if (attempt >= connection_attempts)
556    return 0;
557
558  debug("Connection established.");
559
560  /* Set socket options.  We would like the socket to disappear as soon as
561     it has been closed for whatever reason. */
562  /* setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)); */
563#if defined(TCP_NODELAY) && defined(ENABLE_TCP_NODELAY)
564  setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void *)&on, sizeof(on));
565#endif /* TCP_NODELAY */
566#ifdef SO_LINGER
567  linger.l_onoff = 1;
568  linger.l_linger = 15;
569  setsockopt(sock, SOL_SOCKET, SO_LINGER, (void *)&linger, sizeof(linger));
570#endif /* SO_LINGER */
571
572  /* Set the connection. */
573  packet_set_connection(sock, sock, random_state);
574
575  return 1;
576}
577
578/* Checks if the user has an authentication agent, and if so, tries to
579   authenticate using the agent. */
580
581int try_agent_authentication()
582{
583  int status, type, bits;
584  MP_INT e, n, challenge;
585  char *comment;
586  AuthenticationConnection *auth;
587  unsigned char response[16];
588  unsigned int i;
589 
590  /* Get connection to the agent. */
591  auth = ssh_get_authentication_connection();
592  if (!auth)
593    return 0;
594 
595  mpz_init(&e);
596  mpz_init(&n);
597  mpz_init(&challenge);
598 
599  /* Loop through identities served by the agent. */
600  for (status = ssh_get_first_identity(auth, &bits, &e, &n, &comment);
601       status;
602       status = ssh_get_next_identity(auth, &bits, &e, &n, &comment))
603    {
604      /* Try this identity. */
605      debug("Trying RSA authentication via agent with '%.100s'", comment);
606      xfree(comment);
607     
608      /* Tell the server that we are willing to authenticate using this key. */
609      packet_start(SSH_CMSG_AUTH_RSA);
610      packet_put_mp_int(&n);
611      packet_send();
612      packet_write_wait();
613     
614      /* Wait for server's response. */
615      type = packet_read();
616     
617      /* The server sends failure if it doesn\'t like our key or does not
618         support RSA authentication. */
619      if (type == SSH_SMSG_FAILURE)
620        {
621          debug("Server refused our key.");
622          continue;
623        }
624     
625      /* Otherwise it should have sent a challenge. */
626      if (type != SSH_SMSG_AUTH_RSA_CHALLENGE)
627        packet_disconnect("Protocol error during RSA authentication: %d",
628                          type);
629     
630      packet_get_mp_int(&challenge);
631     
632      debug("Received RSA challenge from server.");
633     
634      /* Ask the agent to decrypt the challenge. */
635      if (!ssh_decrypt_challenge(auth, bits, &e, &n, &challenge,
636                                 session_id, 1, response))
637        {
638          /* The agent failed to authenticate this identifier although it
639             advertised it supports this.  Just return a wrong value. */
640          log_msg("Authentication agent failed to decrypt challenge.");
641          memset(response, 0, sizeof(response));
642        }
643     
644      debug("Sending response to RSA challenge.");
645     
646      /* Send the decrypted challenge back to the server. */
647      packet_start(SSH_CMSG_AUTH_RSA_RESPONSE);
648      for (i = 0; i < 16; i++)
649        packet_put_char(response[i]);
650      packet_send();
651      packet_write_wait();
652     
653      /* Wait for response from the server. */
654      type = packet_read();
655
656      /* The server returns success if it accepted the authentication. */
657      if (type == SSH_SMSG_SUCCESS)
658        {
659          debug("RSA authentication accepted by server.");
660          mpz_clear(&e);
661          mpz_clear(&n);
662          mpz_clear(&challenge);
663          ssh_close_authentication_connection(auth);
664          return 1;
665        }
666
667      /* Otherwise it should return failure. */
668      if (type != SSH_SMSG_FAILURE)
669        {
670          ssh_close_authentication_connection(auth);
671          packet_disconnect("Protocol error waiting RSA auth response: %d",
672                            type);
673        }
674    }
675
676  mpz_clear(&e);
677  mpz_clear(&n);
678  mpz_clear(&challenge);
679
680  ssh_close_authentication_connection(auth);
681
682  debug("RSA authentication using agent refused.");
683  return 0;
684}
685
686/* Computes the proper response to a RSA challenge, and sends the response to
687   the server. */
688
689void respond_to_rsa_challenge(MP_INT *challenge, RSAPrivateKey *prv)
690{
691  unsigned char buf[32], response[16];
692  struct MD5Context md;
693  int i;
694
695  /* Decrypt the challenge using the private key. */
696  rsa_private_decrypt(challenge, challenge, prv);
697
698  /* Compute the response. */
699  /* The response is MD5 of decrypted challenge plus session id. */
700  mp_linearize_msb_first(buf, 32, challenge);
701  MD5Init(&md);
702  MD5Update(&md, buf, 32);
703  MD5Update(&md, session_id, 16);
704  MD5Final(response, &md);
705 
706  debug("Sending response to host key RSA challenge.");
707
708  /* Send the response back to the server. */
709  packet_start(SSH_CMSG_AUTH_RSA_RESPONSE);
710  for (i = 0; i < 16; i++)
711    packet_put_char(response[i]);
712  packet_send();
713  packet_write_wait();
714 
715  memset(buf, 0, sizeof(buf));
716  memset(response, 0, sizeof(response));
717  memset(&md, 0, sizeof(md));
718}
719
720/* Checks if the user has authentication file, and if so, tries to authenticate
721   the user using it. */
722
723int try_rsa_authentication(struct passwd *pw, const char *authfile,
724                           int may_ask_passphrase)
725{
726  MP_INT challenge;
727  RSAPrivateKey private_key;
728  RSAPublicKey public_key;
729  char *passphrase, *comment;
730  int type, i;
731  int done;
732 
733  /* Try to load identification for the authentication key. */
734  if (!load_public_key(pw->pw_uid, authfile, &public_key, &comment))
735    return 0; /* Could not load it.  Fail. */
736
737  debug("Trying RSA authentication with key '%.100s'", comment);
738
739  /* Tell the server that we are willing to authenticate using this key. */
740  packet_start(SSH_CMSG_AUTH_RSA);
741  packet_put_mp_int(&public_key.n);
742  packet_send();
743  packet_write_wait();
744
745  /* We no longer need the public key. */
746  rsa_clear_public_key(&public_key);
747 
748  /* Wait for server's response. */
749  type = packet_read();
750
751  /* The server responds with failure if it doesn\'t like our key or doesn\'t
752     support RSA authentication. */
753  if (type == SSH_SMSG_FAILURE)
754    {
755      debug("Server refused our key.");
756      xfree(comment);
757      return 0; /* Server refuses to authenticate with this key. */
758    }
759
760  /* Otherwise, the server should respond with a challenge. */
761  if (type != SSH_SMSG_AUTH_RSA_CHALLENGE)
762    packet_disconnect("Protocol error during RSA authentication: %d", type);
763
764  /* Get the challenge from the packet. */
765  mpz_init(&challenge);
766  packet_get_mp_int(&challenge);
767
768  debug("Received RSA challenge from server.");
769
770  /* Load the private key.  Try first with empty passphrase; if it fails,
771     ask for a passphrase. */
772  done = load_private_key(pw->pw_uid, authfile, "", &private_key, NULL);
773#ifdef SECURE_RPC
774  if (!done)
775    {
776      passphrase = userfile_get_des_1_magic_phrase(pw->pw_uid);
777      if (passphrase != NULL)
778        {
779          done = load_private_key(pw->pw_uid, authfile, passphrase,
780                                  &private_key, NULL);
781          if (done)
782            debug("Using SUN-DES-1 magic phrase to decrypt the private key.");
783          memset(passphrase, 0, strlen(passphrase));
784          xfree(passphrase);
785        }
786    }
787#endif
788  if (!done)
789    {
790      char buf[300];
791      /* Request passphrase from the user.  We read from /dev/tty to make
792         this work even if stdin has been redirected.  If running in
793         batch mode, we just use the empty passphrase, which will fail and
794         return. */
795      sprintf(buf, "Enter passphrase for RSA key '%.100s': ", comment);
796      if (may_ask_passphrase)
797        passphrase = read_passphrase(pw->pw_uid, buf, 0);
798      else
799        {
800          debug("Will not query passphrase for %.100s in batch mode.",
801                comment);
802          passphrase = xstrdup("");
803        }
804     
805      /* Load the authentication file using the pasphrase. */
806      if (!load_private_key(pw->pw_uid, authfile, passphrase, &private_key,
807                            NULL))
808        {
809          memset(passphrase, 0, strlen(passphrase));
810          xfree(passphrase);
811          error("Bad passphrase.");
812
813          /* Send a dummy response packet to avoid protocol error. */
814          packet_start(SSH_CMSG_AUTH_RSA_RESPONSE);
815          for (i = 0; i < 16; i++)
816            packet_put_char(0);
817          packet_send();
818          packet_write_wait();
819
820          /* Expect the server to reject it... */
821          packet_read_expect(SSH_SMSG_FAILURE);
822          xfree(comment);
823          return 0;
824        }
825
826      /* Destroy the passphrase. */
827      memset(passphrase, 0, strlen(passphrase));
828      xfree(passphrase);
829    }
830 
831  /* We no longer need the comment. */
832  xfree(comment);
833
834  /* Compute and send a response to the challenge. */
835  respond_to_rsa_challenge(&challenge, &private_key);
836 
837  /* Destroy the private key. */
838  rsa_clear_private_key(&private_key);
839
840  /* We no longer need the challenge. */
841  mpz_clear(&challenge);
842 
843  /* Wait for response from the server. */
844  type = packet_read();
845  if (type == SSH_SMSG_SUCCESS)
846    {
847      debug("RSA authentication accepted by server.");
848      return 1;
849    }
850  if (type != SSH_SMSG_FAILURE)
851    packet_disconnect("Protocol error waiting RSA auth response: %d", type);
852  debug("RSA authentication refused.");
853  return 0;
854}
855
856/* Tries to authenticate the user using combined rhosts or /etc/hosts.equiv
857   authentication and RSA host authentication. */
858
859int try_rhosts_rsa_authentication(const char *local_user,
860                                  RSAPrivateKey *host_key)
861{
862  int type;
863  MP_INT challenge;
864
865  debug("Trying rhosts or /etc/hosts.equiv with RSA host authentication.");
866
867  /* Tell the server that we are willing to authenticate using this key. */
868  packet_start(SSH_CMSG_AUTH_RHOSTS_RSA);
869  packet_put_string(local_user, strlen(local_user));
870  packet_put_int(host_key->bits);
871  packet_put_mp_int(&host_key->e);
872  packet_put_mp_int(&host_key->n);
873  packet_send();
874  packet_write_wait();
875
876  /* Wait for server's response. */
877  type = packet_read();
878
879  /* The server responds with failure if it doesn't admit our .rhosts
880     authentication or doesn't know our host key. */
881  if (type == SSH_SMSG_FAILURE)
882    {
883      debug("Server refused our rhosts authentication or host key.");
884      return 0; /* Server refuses to authenticate us with this method. */
885    }
886
887  /* Otherwise, the server should respond with a challenge. */
888  if (type != SSH_SMSG_AUTH_RSA_CHALLENGE)
889    packet_disconnect("Protocol error during RSA authentication: %d", type);
890
891  /* Get the challenge from the packet. */
892  mpz_init(&challenge);
893  packet_get_mp_int(&challenge);
894
895  debug("Received RSA challenge for host key from server.");
896
897  /* Compute a response to the challenge. */
898  respond_to_rsa_challenge(&challenge, host_key);
899
900  /* We no longer need the challenge. */
901  mpz_clear(&challenge);
902 
903  /* Wait for response from the server. */
904  type = packet_read();
905  if (type == SSH_SMSG_SUCCESS)
906    {
907      debug("Rhosts or /etc/hosts.equiv with RSA host authentication accepted by server.");
908      return 1;
909    }
910  if (type != SSH_SMSG_FAILURE)
911    packet_disconnect("Protocol error waiting RSA auth response: %d", type);
912  debug("Rhosts or /etc/hosts.equiv with RSA host authentication refused.");
913  return 0;
914}
915
916#ifdef KERBEROS
917int try_kerberos_authentication()
918{
919#ifdef KRB5
920  char *remotehost;
921  krb5_data auth;
922  krb5_error_code r;
923  int  tempint, type;
924  krb5_ccache ccache;
925  krb5_creds creds;
926  krb5_creds * new_creds = 0;
927  int ap_opts, ret_stat = 0;
928  krb5_keyblock   *session_key = 0;
929  krb5_ap_rep_enc_part *repl = 0;
930  struct sockaddr_in local, foreign;
931 
932  memset(&auth, 0 , sizeof(auth));
933  remotehost = (char *) get_canonical_hostname();
934  if (!ssh_context)
935    {
936      if ((r = krb5_init_context(&ssh_context)))
937        fatal("Kerberos V5: %.100s while initializing krb5.", error_message(r));
938      krb5_init_ets(ssh_context);
939    }
940 
941  if ((r = krb5_cc_default(ssh_context, &ccache)))
942    {
943      debug("Kerberos V5: could not get default ccache.");
944      goto cleanup;
945    }
946 
947  memset((char *)&creds, 0, sizeof(creds));
948  if ((r = krb5_sname_to_principal(ssh_context, remotehost,
949                                   "host", KRB5_NT_SRV_HST,
950                                   &creds.server)))
951    {
952      debug("Kerberos V5: error while constructing service name: %.100s.",
953            error_message(r));
954      goto cleanup;
955    }
956  if ((r = krb5_cc_get_principal(ssh_context, ccache,
957                                 &creds.client)))
958    {
959      debug("Kerberos V5: failure on principal (%.100s).",
960            error_message(r));
961      goto cleanup;
962    }
963 
964  creds.keyblock.enctype=ENCTYPE_DES_CBC_CRC;
965  if ((r = krb5_get_credentials(ssh_context, 0,
966                                ccache, &creds, &new_creds)))
967    {
968      debug("Kerberos V5: failure on credentials(%.100s).",
969            error_message(r));
970      goto cleanup;
971    }
972 
973  /* ap_opts = AP_OPTS_MUTUAL_REQUIRED | AP_OPTS_USE_SUBKEY; */
974  ap_opts = 0;
975
976  if (!auth_context)
977    {
978      if ((r = krb5_auth_con_init(ssh_context, &auth_context)))
979        {
980          debug("Kerberos V5: failed to init auth_context (%.100s)",
981                error_message(r));
982          goto cleanup;
983        }
984      krb5_auth_con_setflags(ssh_context, auth_context,
985                             KRB5_AUTH_CONTEXT_RET_TIME);
986    }
987 
988  if ((r = krb5_mk_req_extended(ssh_context, &auth_context, ap_opts,
989                                0, new_creds, &auth)))
990    {
991      debug("Kerberos V5: failed krb5_mk_req_extended (%.100s)",
992            error_message(r));
993      goto cleanup;
994    }
995 
996  /* Send authentication info to server. */
997  packet_start(SSH_CMSG_AUTH_KERBEROS);
998  packet_put_string((char *) auth.data, auth.length);
999  packet_send();
1000  packet_write_wait();
1001 
1002  tempint = sizeof(local);
1003  memset(&local, 0, tempint);
1004  if (getsockname(packet_get_connection_in(),
1005                  (struct sockaddr *) &local, &tempint) < 0)
1006    debug("getsockname failed: %.100s", strerror(errno));
1007 
1008  tempint = sizeof(foreign);
1009  memset(&foreign, 0, tempint);
1010  if (getpeername(packet_get_connection_in(),
1011                  (struct sockaddr *)&foreign, &tempint) < 0)
1012    debug("getpeername failed: %.100s", strerror(errno));
1013 
1014  if (auth.data)
1015    {
1016      free(auth.data);
1017      auth.data = 0;
1018    }
1019 
1020    /* Get server reply. */
1021  type = packet_read();
1022  switch(type)
1023    {
1024    case SSH_SMSG_FAILURE:
1025      debug("Kerberos V5 authentication failed.");
1026      goto cleanup;
1027     
1028    case SSH_SMSG_AUTH_KERBEROS_RESPONSE:
1029      /* Get server's response. */
1030      auth.data = packet_get_string((unsigned int *) &auth.length);
1031     
1032      /* If his response isn't properly encrypted with the session key,
1033         he's bogus. Also krb5_rd_rep will fail when MUTUAL AUTH is
1034         requested and the server does not send back a session encrypted
1035         time stamp */
1036     
1037      if (r = krb5_rd_rep(ssh_context, auth_context, &auth, &repl))
1038        {
1039          packet_disconnect("Kerberos V5 Authentication failed: %.100s",
1040                            error_message(r));
1041          goto cleanup;
1042        }
1043      else
1044        {
1045          debug("Kerberos V5 authentication accepted.");
1046          ret_stat = 1;
1047        }
1048      break;
1049     
1050    default:
1051      packet_disconnect("Protocol error on Kerberos V5 response: %d", type);
1052      goto cleanup;
1053    }
1054 
1055cleanup:
1056  krb5_free_cred_contents(ssh_context, &creds);
1057  if (new_creds)
1058    krb5_free_creds(ssh_context, new_creds);
1059  if (session_key)
1060    krb5_free_keyblock(ssh_context, session_key);
1061  if (auth.data)
1062    free(auth.data);
1063  if (repl)
1064    krb5_free_ap_rep_enc_part(ssh_context, repl);
1065 
1066  return(ret_stat);
1067#endif /* KRB5 */
1068}
1069#endif /* KERBEROS */
1070
1071#ifdef KERBEROS_TGT_PASSING
1072/* Forward our local Kerberos tgt to the server. */
1073int send_kerberos_tgt()
1074{
1075#ifdef KRB5
1076  char *remotehost;
1077  krb5_principal client;
1078  krb5_principal server;
1079  krb5_ccache ccache;
1080  krb5_data outbuf;
1081  krb5_error_code r;
1082  int type;
1083  char server_name[512];
1084 
1085  remotehost = (char *) get_canonical_hostname();
1086  memset(&outbuf, 0 , sizeof(outbuf));
1087 
1088  debug("Trying Kerberos V5 TGT passing.");
1089 
1090  if (!ssh_context)
1091    {
1092      if ((r = krb5_init_context(&ssh_context)))
1093        fatal("Kerberos V5: %.100s while initializing krb5.", error_message(r));
1094      krb5_init_ets(ssh_context);
1095    }
1096  if (!auth_context)
1097    {
1098      if ((r = krb5_auth_con_init(ssh_context, &auth_context)))
1099        {
1100          debug("Kerberos V5: failed to init auth_context (%.100s)",
1101                error_message(r));
1102          return 0 ;
1103        }
1104      krb5_auth_con_setflags(ssh_context, auth_context,
1105                             KRB5_AUTH_CONTEXT_RET_TIME);
1106    }
1107 
1108  if ((r = krb5_cc_default(ssh_context, &ccache)))
1109    {
1110      debug("Kerberos V5: could not get default ccache.");
1111      return 0 ;
1112    }
1113 
1114    if ((r = krb5_cc_get_principal(ssh_context, ccache,
1115                                   &client)))
1116      {
1117        debug("Kerberos V5: failure on principal (%.100s)",
1118              error_message(r));
1119        return 0 ;
1120      }
1121   
1122    /* Somewhat of a hack here. We need to get the TGT for the
1123       clients realm. However if remotehost is in another realm
1124       krb5_fwd_tgt_creds will try to go to that realm to get
1125       the TGT, which will fail. So we create the server
1126       principal and point it to clients realm. This way
1127       we pass over a TGT of the clients realm. */
1128   
1129    sprintf(server_name,"host/%.100s@", remotehost);
1130    strncat(server_name,client->realm.data,client->realm.length);
1131    krb5_parse_name(ssh_context,server_name, &server);
1132    server->type = KRB5_NT_SRV_HST;
1133   
1134   
1135    if ((r = krb5_fwd_tgt_creds(ssh_context, auth_context, 0, client,
1136                                server, ccache, 1, &outbuf)))
1137      {
1138        debug("Kerberos V5 krb5_fwd_tgt_creds failure (%.100s)",
1139              error_message(r));
1140        krb5_free_principal(ssh_context, client);
1141        krb5_free_principal(ssh_context, server);
1142        return 0 ;
1143      }
1144    packet_start(SSH_CMSG_HAVE_KERBEROS_TGT);
1145    packet_put_string((char *)outbuf.data, outbuf.length);
1146    packet_send();
1147    packet_write_wait();
1148   
1149    if (outbuf.data)
1150      free(outbuf.data);
1151    krb5_free_principal(ssh_context, client);
1152    krb5_free_principal(ssh_context, server);
1153   
1154    type = packet_read();
1155    if (type == SSH_SMSG_SUCCESS)
1156      {
1157        debug("Kerberos V5 TGT passing was successful.");
1158        return 1;
1159      }
1160    else
1161      if (type != SSH_SMSG_FAILURE)
1162        packet_disconnect("Protocol error on Kerberos tgt response: %d", type);
1163      else
1164        debug("Kerberos V5 TGT passing failed.");
1165   
1166    return 0;
1167#endif /* KRB5 */
1168}
1169#endif /* KERBEROS_TGT_PASSING */
1170
1171/* Waits for the server identification string, and sends our own identification
1172   string. */
1173
1174void ssh_exchange_identification()
1175{
1176  char buf[256], remote_version[256]; /* must be same size! */
1177  int remote_major, remote_minor, i;
1178  int my_major, my_minor;
1179  int len;
1180  int connection_in = packet_get_connection_in();
1181  int connection_out = packet_get_connection_out();
1182
1183  /* Read other side\'s version identification. */
1184  for (i = 0; i < sizeof(buf) - 1; i++)
1185    {
1186      len = read(connection_in, &buf[i], 1);
1187      if (len == 0)
1188        fatal("Connection closed by foreign host.");
1189      else
1190        if (len < 0)
1191          fatal("read: %.100s", strerror(errno));
1192      if (buf[i] == '\r')
1193        {
1194          buf[i] = '\n';
1195          buf[i + 1] = 0;
1196          break;
1197        }
1198      if (buf[i] == '\n')
1199        {
1200          buf[i + 1] = 0;
1201          break;
1202        }
1203    }
1204  buf[sizeof(buf) - 1] = 0;
1205 
1206  /* Check that the versions match.  In future this might accept several
1207     versions and set appropriate flags to handle them. */
1208  if (sscanf(buf, "SSH-%d.%d-%[^\n]\n", &remote_major, &remote_minor,
1209             remote_version) != 3)
1210    fatal("Bad remote protocol version identification: '%.100s'", buf);
1211  debug("Remote protocol version %d.%d, remote software version %.100s",
1212        remote_major, remote_minor, remote_version);
1213
1214  switch (check_emulation(remote_major, remote_minor,
1215                     &my_major, &my_minor))
1216    {
1217    case EMULATE_VERSION_TOO_OLD:
1218      fatal("Remote machine has too old SSH software version.");
1219    case EMULATE_MAJOR_VERSION_MISMATCH:
1220      fatal("Major protocol versions incompatible.");
1221    case EMULATE_VERSION_NEWER:
1222      /* We will emulate the old version. */
1223      break;
1224    case EMULATE_VERSION_OK:
1225      break;
1226    default:
1227      fatal("Unexpected return value from check_emulation.");
1228    }
1229 
1230  sprintf(buf, "SSH-%d.%d-%.100s",
1231          my_major, my_minor, SSH_VERSION);
1232#ifdef F_SECURE_COMMERCIAL
1233
1234#endif /* F_SECURE_COMMERCIAL */
1235  strcat(buf, "\n");
1236  if (write(connection_out, buf, strlen(buf)) != strlen(buf))
1237    fatal("write: %.100s", strerror(errno));
1238}
1239
1240/* Starts a dialog with the server, and authenticates the current user on the
1241   server.  This does not need any extra privileges.  The basic connection
1242   to the server must already have been established before this is called.
1243   User is the remote user; if it is NULL, the current local user name will
1244   be used.  Anonymous indicates that no rhosts authentication will be used.
1245   If login fails, this function prints an error and never returns.
1246   This function does not require super-user privileges. */
1247
1248void ssh_login(RandomState *state, int host_key_valid,
1249               RSAPrivateKey *own_host_key,
1250               const char *orighost,
1251               Options *options, uid_t original_real_uid)
1252{
1253  int i, type, len, f;
1254  char buf[1024], seedbuf[16];
1255  char *password;
1256  struct passwd *pw;
1257  MP_INT key;
1258  RSAPublicKey host_key;
1259  RSAPublicKey public_key;
1260  unsigned char session_key[SSH_SESSION_KEY_LENGTH];
1261  const char *server_user, *local_user;
1262  char *cp, *host;
1263  struct stat st;
1264  unsigned char check_bytes[8];
1265  unsigned int supported_ciphers, supported_authentications, protocol_flags;
1266  HostStatus host_status;
1267#ifdef KERBEROS
1268#ifdef KRB5
1269  char *kuser;
1270  krb5_ccache ccache;
1271  krb5_error_code problem;
1272  krb5_principal client;
1273#endif
1274#endif
1275 
1276  /* Convert the user-supplied hostname into all lowercase. */
1277  host = xstrdup(orighost);
1278  for (cp = host; *cp; cp++)
1279    if (isupper(*cp))
1280      *cp = tolower(*cp);
1281
1282  /* Map localhost to ip-address locally */
1283  if (strcmp(host, "localhost") == 0)
1284    {
1285      xfree(host);
1286      host = xstrdup("127.0.0.1");
1287    }
1288 
1289  /* Exchange protocol version identification strings with the server. */
1290  ssh_exchange_identification();
1291
1292  /* Put the connection into non-blocking mode. */
1293  packet_set_nonblocking();
1294
1295  /* Get local user name.  Use it as server user if no user name
1296     was given. */
1297  pw = getpwuid(original_real_uid);
1298  if (!pw)
1299    fatal("User id %d not found from user database.", original_real_uid);
1300  local_user = xstrdup(pw->pw_name);
1301  server_user = options->user ? options->user : local_user;
1302
1303  debug("Waiting for server public key.");
1304
1305  /* Wait for a public key packet from the server. */
1306  packet_read_expect(SSH_SMSG_PUBLIC_KEY);
1307
1308  /* Get check bytes from the packet. */
1309  for (i = 0; i < 8; i++)
1310    check_bytes[i] = packet_get_char();
1311
1312  /* Get the public key. */
1313  public_key.bits = packet_get_int();
1314  mpz_init(&public_key.e);
1315  packet_get_mp_int(&public_key.e);
1316  mpz_init(&public_key.n);
1317  packet_get_mp_int(&public_key.n);
1318
1319  /* Get the host key. */
1320  host_key.bits = packet_get_int();
1321  mpz_init(&host_key.e);
1322  packet_get_mp_int(&host_key.e);
1323  mpz_init(&host_key.n);
1324  packet_get_mp_int(&host_key.n);
1325
1326  /* Get protocol flags. */
1327  protocol_flags = packet_get_int();
1328  packet_set_protocol_flags(protocol_flags);
1329
1330  /* Get supported cipher types. */
1331  supported_ciphers = packet_get_int();
1332
1333  /* Get supported authentication types. */
1334  supported_authentications = packet_get_int();
1335
1336  debug("Received server public key (%d bits) and host key (%d bits).",
1337        public_key.bits, host_key.bits);
1338
1339  /* Compute the session id. */
1340  compute_session_id(session_id, check_bytes, host_key.bits, &host_key.n,
1341                     public_key.bits, &public_key.n);
1342
1343  /* Check if the host key is present in the user's list of known hosts
1344     or in the systemwide list. */
1345  host_status = check_host_in_hostfile(original_real_uid,
1346                                       options->user_hostfile,
1347                                       host, host_key.bits,
1348                                       &host_key.e, &host_key.n);
1349  if (host_status == HOST_NEW)
1350    host_status = check_host_in_hostfile(original_real_uid,
1351                                         options->system_hostfile, host,
1352                                         host_key.bits, &host_key.e,
1353                                         &host_key.n);
1354
1355  /* Force accepting of the host key for localhost and 127.0.0.1.
1356     The problem is that if the home directory is NFS-mounted to multiple
1357     machines, localhost will refer to a different machine in each of them,
1358     and the user will get bogus HOST_CHANGED warnings.  This essentially
1359     disables host authentication for localhost; however, this is probably
1360     not a real problem. */
1361  if (strcmp(host, "127.0.0.1") == 0)
1362    {
1363      debug("Forcing accepting of host key for localhost.");
1364      host_status = HOST_OK;
1365    }
1366
1367  switch (host_status)
1368    {
1369    case HOST_OK:
1370      /* The host is known and the key matches. */
1371      debug("Host '%.200s' is known and matches the host key.", host);
1372      break;
1373    case HOST_NEW:
1374      /* The host is new. */
1375      if (options->strict_host_key_checking == 1)
1376        { /* User has requested strict host key checking.  We will not
1377             add the host key automatically.  The only alternative left
1378             is to abort. */
1379          fatal("No host key is known for %.200s and you have requested strict checking.", host);
1380        }
1381
1382      error("Host key not found from the list of known hosts.");
1383      if (options->strict_host_key_checking == 2)
1384        {
1385          if (options->batch_mode)
1386            fatal("No host key is known for %.200s and cannot confirm operation when running in batch mode.", host);
1387
1388          read_confirmation("Are you sure you want to continue connecting (yes/no)? ");
1389        }
1390      /* If not in strict mode, add the key automatically to the local
1391         known_hosts file. */
1392      if (!add_host_to_hostfile(original_real_uid,
1393                                options->user_hostfile, host, host_key.bits,
1394                                &host_key.e, &host_key.n))
1395        log_msg("Failed to add the host to the list of known hosts (%.500s).",
1396                options->user_hostfile);
1397      else
1398        log_msg("Host '%.200s' added to the list of known hosts.", host);
1399      break;
1400    case HOST_CHANGED:
1401      /* The host key has changed. */
1402      error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
1403      error("@       WARNING: HOST IDENTIFICATION HAS CHANGED!         @");
1404      error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
1405      error("IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!");
1406      error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!");
1407      error("It is also possible that the host key has just been changed.");
1408      error("Please contact your system administrator.");
1409      error("Add correct host key in %.100s to get rid of this message.",
1410            options->user_hostfile);
1411     
1412      /* If strict host key checking is in use, the user will have to edit
1413         the key manually and we can only abort. */
1414      if (options->strict_host_key_checking == 1)
1415        fatal("Host key for %.200s has changed and you have requested strict checking.", host);
1416     
1417      /* If strict host key checking has not been requested, allow the
1418         connection but without password authentication. */
1419      if (options->forward_agent)
1420        {
1421          error("Agent forwarding is disabled to avoid attacks by corrupted servers.");
1422          options->forward_agent = 0;
1423        }
1424      if (options->forward_x11)
1425        {
1426          error("X11 forwarding is disabled to avoid attacks by corrupted servers.");
1427          options->forward_x11 = 0;
1428        }
1429      if (options->num_local_forwards > 0)
1430        {
1431          error("Local port forwarding is disabled to avoid attacks by corrupted servers.");
1432          options->num_local_forwards = 0;
1433        }
1434      if (options->num_remote_forwards)
1435        {
1436          error("Remote port forwarding is disabled to avoid attacks by corrupted servers.");
1437          options->num_remote_forwards = 0;
1438        }
1439     
1440      if (options->strict_host_key_checking == 2)
1441        {
1442          if (options->batch_mode)
1443            fatal("No host key is known for %.200s and cannot confirm operation when running in batch mode.", host);
1444         
1445          read_confirmation("Are you sure you want to continue connecting (yes/no)? ");
1446        }
1447     
1448      /* XXX Should permit the user to change to use the new id.  This could
1449         be done by converting the host key to an identifying sentence, tell
1450         that the host identifies itself by that sentence, and ask the user
1451         if he/she whishes to accept the authentication. */
1452      break;
1453    }
1454  /* Generate a session key. */
1455 
1456  /* Initialize the random number generator. */
1457  sprintf(buf, "%.500s/%.200s", pw->pw_dir, SSH_CLIENT_SEEDFILE);
1458  if (userfile_stat(pw->pw_uid, buf, &st) < 0)
1459    log_msg("Creating random seed file ~/%.200s.  This may take a while.",
1460        SSH_CLIENT_SEEDFILE);
1461  else
1462    debug("Initializing random; seed file %.900s", buf);
1463  random_initialize(state, pw->pw_uid, buf);
1464
1465  /* Read also some random data from the systemwide random seed file to
1466     avoid the user being able to guess his own session key when running
1467     as root. */
1468  f = open(SSH_DAEMON_SEED_FILE, O_RDONLY);
1469  if (f >= 0)
1470    {
1471      len = read(f, seedbuf, sizeof(seedbuf)); /* Try to read 128 bits. */
1472      if (len > 0)
1473        {
1474          random_add_noise(state, seedbuf, len);
1475          random_stir(state);
1476        }
1477      close(f);
1478    }
1479
1480  /* Generate an encryption key for the session.   The key is a 256 bit
1481     random number, interpreted as a 32-byte key, with the least significant
1482     8 bits being the first byte of the key. */
1483  for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++)
1484    session_key[i] = random_get_byte(state);
1485
1486  /* Save the new random state. */
1487  random_save(state, pw->pw_uid, buf);
1488
1489  /* According to the protocol spec, the first byte of the session key is
1490     the highest byte of the integer.  The session key is xored with the
1491     first 16 bytes of the session id. */
1492  mpz_init_set_ui(&key, 0);
1493  for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++)
1494    {
1495      mpz_mul_2exp(&key, &key, 8);
1496      if (i < 16)
1497        mpz_add_ui(&key, &key, session_key[i] ^ session_id[i]);
1498      else
1499        mpz_add_ui(&key, &key, session_key[i]);
1500    }
1501
1502  /* Encrypt the integer using the public key and host key of the server
1503     (key with smaller modulus first). */
1504  if (mpz_cmp(&public_key.n, &host_key.n) < 0)
1505    {
1506      /* Public key has smaller modulus. */
1507      assert(host_key.bits >= public_key.bits + SSH_KEY_BITS_RESERVED);
1508
1509      rsa_public_encrypt(&key, &key, &public_key, state);
1510      rsa_public_encrypt(&key, &key, &host_key, state);
1511    }
1512  else
1513    {
1514      /* Host key has smaller modulus (or they are equal). */
1515      assert(public_key.bits >= host_key.bits + SSH_KEY_BITS_RESERVED);
1516
1517      rsa_public_encrypt(&key, &key, &host_key, state);
1518      rsa_public_encrypt(&key, &key, &public_key, state);
1519    }
1520
1521  if (options->cipher == SSH_CIPHER_NOT_SET)
1522    if (cipher_mask() & supported_ciphers & (1 << SSH_CIPHER_IDEA))
1523      options->cipher = SSH_CIPHER_IDEA;
1524    else
1525      {
1526        debug("IDEA not supported, using %.100s instead.",
1527              cipher_name(SSH_FALLBACK_CIPHER));
1528        options->cipher = SSH_FALLBACK_CIPHER;
1529      }
1530
1531  /* Check that the selected cipher is supported. */
1532  if (!(supported_ciphers & (1 << options->cipher)))
1533    fatal("Selected cipher type %.100s not supported by server.",
1534          cipher_name(options->cipher));
1535
1536  debug("Encryption type: %.100s", cipher_name(options->cipher));
1537
1538  /* Send the encrypted session key to the server. */
1539  packet_start(SSH_CMSG_SESSION_KEY);
1540  packet_put_char(options->cipher);
1541
1542  /* Send the check bytes back to the server. */
1543  for (i = 0; i < 8; i++)
1544    packet_put_char(check_bytes[i]);
1545
1546  /* Send the encrypted encryption key. */
1547  packet_put_mp_int(&key);
1548
1549  /* Send protocol flags. */
1550  packet_put_int(SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN);
1551
1552  /* Send the packet now. */
1553  packet_send();
1554  packet_write_wait();
1555
1556  /* Destroy the session key integer and the public keys since we no longer
1557     need them. */
1558  mpz_clear(&key);
1559  rsa_clear_public_key(&public_key);
1560  rsa_clear_public_key(&host_key);
1561
1562  debug("Sent encrypted session key.");
1563 
1564  /* Set the encryption key. */
1565  packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH,
1566                            options->cipher, 1);
1567
1568  /* We will no longer need the session key here.  Destroy any extra copies. */
1569  memset(session_key, 0, sizeof(session_key));
1570
1571  /* Expect a success message from the server.  Note that this message will
1572     be received in encrypted form. */
1573  packet_read_expect(SSH_SMSG_SUCCESS);
1574
1575  debug("Received encrypted confirmation.");
1576
1577#ifdef KERBEROS
1578#ifdef KRB5
1579  if (!ssh_context)
1580    {
1581      if ((problem = krb5_init_context(&ssh_context)))
1582        fatal("Kerberos V5: %.100s while initializing krb5.",
1583              error_message(problem));
1584      krb5_init_ets(ssh_context);
1585    }
1586  if ((supported_authentications & (1 << SSH_AUTH_KERBEROS)) &&
1587      options->kerberos_authentication && options->no_user_given )
1588    {
1589      /* Send over fully qualified kerberos username for the
1590         remote username. Let the server figure out what the
1591         localname should be. */
1592     
1593      if (!krb5_cc_default(ssh_context, &ccache))
1594        {
1595          if ((problem = krb5_cc_get_principal(ssh_context, ccache,
1596                                               &client)))
1597            {
1598              debug("Kerberos V5: failure on principal (%.100s).",
1599                    error_message(problem));
1600            }
1601          else {
1602            if (!krb5_unparse_name(ssh_context, client, &kuser))
1603              server_user = kuser;
1604            krb5_free_principal(ssh_context, client);
1605          }
1606        }
1607      else
1608        debug("Kerberos V5: could not get default ccache.");
1609    }
1610#endif /* KRB5 */
1611#endif /* KERBEROS */
1612 
1613  /* Send the name of the user to log in as on the server. */
1614  packet_start(SSH_CMSG_USER);
1615  packet_put_string(server_user, strlen(server_user));
1616  packet_send();
1617  packet_write_wait();
1618
1619  /* The server should respond with success if no authentication is needed
1620     (the user has no password).  Otherwise the server responds with
1621     failure. */
1622  type = packet_read();
1623  if (type == SSH_SMSG_SUCCESS)
1624    return;  /* Connection was accepted without authentication. */
1625  if (type != SSH_SMSG_FAILURE)
1626    packet_disconnect("Protocol error: got %d in response to SSH_CMSG_USER",
1627                      type);
1628
1629#ifdef KERBEROS_TGT_PASSING
1630  /* Try Kerberos tgt passing if the server supports it. */
1631  if ((supported_authentications & (1 << SSH_PASS_KERBEROS_TGT)) &&
1632      options->kerberos_tgt_passing)
1633    {
1634      if (options->cipher == SSH_CIPHER_NONE)
1635        log_msg("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!");
1636      (void)send_kerberos_tgt();
1637    }
1638#endif /* KERBEROS_TGT_PASSING */
1639 
1640#ifdef KERBEROS
1641#ifdef KRB5
1642  if ((supported_authentications & (1 << SSH_AUTH_KERBEROS)) &&
1643      options->kerberos_authentication)
1644    {
1645      debug("Trying Kerberos V5 authentication.");
1646#endif
1647      if (try_kerberos_authentication()) {
1648        /* The server should respond with success or failure. */
1649        type = packet_read();
1650        if (type == SSH_SMSG_SUCCESS)
1651          return; /* Successful connection. */
1652        if (type != SSH_SMSG_FAILURE)
1653          packet_disconnect("Protocol error: got %d in response to Kerberos auth", type);
1654      }
1655#ifdef KRB5
1656    }
1657#endif
1658#endif /* KERBEROS */
1659
1660  /* Use rhosts authentication if running in privileged socket and we do not
1661     wish to remain anonymous. */
1662  if ((supported_authentications & (1 << SSH_AUTH_RHOSTS)) &&
1663      options->rhosts_authentication)
1664    {
1665      debug("Trying rhosts authentication.");
1666      packet_start(SSH_CMSG_AUTH_RHOSTS);
1667      packet_put_string(local_user, strlen(local_user));
1668      packet_send();
1669      packet_write_wait();
1670
1671      /* The server should respond with success or failure. */
1672      type = packet_read();
1673      if (type == SSH_SMSG_SUCCESS)
1674        return; /* Successful connection. */
1675      if (type != SSH_SMSG_FAILURE)
1676        packet_disconnect("Protocol error: got %d in response to rhosts auth",
1677                          type);
1678    }
1679
1680  /* Try .rhosts or /etc/hosts.equiv authentication with RSA host
1681     authentication. */
1682  if ((supported_authentications & (1 << SSH_AUTH_RHOSTS_RSA)) &&
1683      options->rhosts_rsa_authentication && host_key_valid)
1684    {
1685      if (try_rhosts_rsa_authentication(local_user, own_host_key))
1686        return; /* Successful authentication. */
1687    }
1688
1689  /* Try RSA authentication if the server supports it. */
1690  if ((supported_authentications & (1 << SSH_AUTH_RSA)) &&
1691      options->rsa_authentication)
1692    {
1693      /* Try RSA authentication using the authentication agent.  The agent
1694         is tried first because no passphrase is needed for it, whereas
1695         identity files may require passphrases. */
1696      if (try_agent_authentication())
1697        return; /* Successful connection. */
1698
1699      /* Try RSA authentication for each identity. */
1700      for (i = 0; i < options->num_identity_files; i++)
1701        if (try_rsa_authentication(pw, options->identity_files[i],
1702                                   !options->batch_mode))
1703          return; /* Successful connection. */
1704    }
1705 
1706  /* Support for TIS authentication server
1707     Contributed by Andre April <Andre.April@cediti.be>. */
1708  /* Try Tis authentication daemon if the server supports it. */
1709  if ((supported_authentications & (1 << SSH_AUTH_TIS)) &&
1710      options->tis_authentication && !options->batch_mode)
1711    {
1712      char *prompt;
1713      debug("Doing TIS authentication.");
1714      if (options->cipher == SSH_CIPHER_NONE)
1715        log_msg("WARNING: Encryption is disabled! Password will be transmitted in clear text.");
1716      packet_start(SSH_CMSG_AUTH_TIS);
1717      packet_send();
1718      packet_write_wait();
1719     
1720      type = packet_read();
1721      if (type == SSH_SMSG_FAILURE) {
1722        /* Authentication failure : either the authentication server is */
1723        /* not accessible (or unknown) or the user is not registered on */
1724        /* the authentication server. Try next authentication method. */
1725        debug("User cannot be identifier on authentication server.");
1726      } else {
1727        if (type != SSH_SMSG_AUTH_TIS_CHALLENGE) {
1728          packet_disconnect("Protocol error: got %d in response to TIS auth request",
1729                            type);
1730        }
1731        prompt = packet_get_string(NULL);
1732        /* Asks for password */
1733        password = read_passphrase(pw->pw_uid, prompt, 0);
1734        packet_start(SSH_CMSG_AUTH_TIS_RESPONSE);
1735        packet_put_string(password, strlen(password));
1736        memset(password, 0, strlen(password));
1737        xfree(password);
1738        packet_send();
1739        packet_write_wait();
1740       
1741        type = packet_read();
1742        if (type == SSH_SMSG_SUCCESS)
1743          return; /* Successful connection. */
1744        if (type != SSH_SMSG_FAILURE)
1745          packet_disconnect("Protocol error: got %d in response to TIS auth",
1746                            type);
1747      }
1748    }
1749 
1750  /* Try password authentication if the server supports it. */
1751  if ((supported_authentications & (1 << SSH_AUTH_PASSWORD)) &&
1752      options->password_authentication && !options->batch_mode)
1753    {
1754      char prompt[80];
1755      debug("Doing password authentication.");
1756      if (options->cipher == SSH_CIPHER_NONE)
1757        log_msg("WARNING: Encryption is disabled! Password will be transmitted in clear text.");
1758      if (options->password_prompt_login && options->password_prompt_host)
1759        sprintf(prompt, "%.30s@%.30s's password: ", server_user, host);
1760      else if (!options->password_prompt_login &&
1761               !options->password_prompt_host)
1762        sprintf(prompt, "Password: ");
1763      else if (options->password_prompt_login)
1764        sprintf(prompt, "%.30s's password: ", server_user);
1765      else
1766        sprintf(prompt, "%.30s password: ", host);
1767     
1768      for(i = 0; i < options->number_of_password_prompts; i++)
1769        {
1770          password = read_passphrase(pw->pw_uid, prompt, 0);
1771          packet_start(SSH_CMSG_AUTH_PASSWORD);
1772          packet_put_string(password, strlen(password));
1773          memset(password, 0, strlen(password));
1774          xfree(password);
1775          packet_send();
1776          packet_write_wait();
1777         
1778          type = packet_read();
1779          if (type == SSH_SMSG_SUCCESS)
1780            return; /* Successful connection. */
1781          if (type != SSH_SMSG_FAILURE)
1782            packet_disconnect("Protocol error: got %d in response to passwd auth",
1783                              type);
1784        }
1785    }
1786
1787  /* All authentication methods have failed.  Exit with an error message. */
1788  fatal("Permission denied.");
1789  /*NOTREACHED*/
1790}
Note: See TracBrowser for help on using the repository browser.