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