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

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