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