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 * Code to connect to a remote host, and to perform the client side of the
6 * login (authentication) dialog.
7 *
8 * As far as I am concerned, the code I have written for this software
9 * can be used freely for any purpose. Any derived versions of this
10 * software must be clearly marked as such, and if the derived work is
11 * incompatible with the protocol description in the RFC file, it must be
12 * called by a name other than "ssh" or "Secure Shell".
13 */
14 /*
15 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
16 * Use is subject to license terms.
17 *
18 * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
19 */
20
21 #include "includes.h"
22 RCSID("$OpenBSD: sshconnect.c,v 1.135 2002/09/19 01:58:18 djm Exp $");
23
24 #include <openssl/bn.h>
25
26 #include "ssh.h"
27 #include "xmalloc.h"
28 #include "rsa.h"
29 #include "buffer.h"
30 #include "packet.h"
31 #include "uidswap.h"
32 #include "compat.h"
33 #include "key.h"
34 #include "sshconnect.h"
35 #include "hostfile.h"
36 #include "log.h"
37 #include "readconf.h"
38 #include "atomicio.h"
39 #include "misc.h"
40 #include "readpass.h"
41 #include <langinfo.h>
42 #include <regex.h>
43 #include <err.h>
44 #include "engine.h"
45
46 char *client_version_string = NULL;
47 char *server_version_string = NULL;
48
49 /* import */
50 extern Options options;
51 extern char *__progname;
52 extern uid_t original_real_uid;
53 extern uid_t original_effective_uid;
54 extern pid_t proxy_command_pid;
55 extern ENGINE *e;
56
57 #ifndef INET6_ADDRSTRLEN /* for non IPv6 machines */
58 #define INET6_ADDRSTRLEN 46
59 #endif
60
61 static int show_other_keys(const char *, Key *);
62
63 /*
64 * Connect to the given ssh server using a proxy command.
65 */
66 static int
ssh_proxy_connect(const char * host,u_short port,const char * proxy_command)67 ssh_proxy_connect(const char *host, u_short port, const char *proxy_command)
68 {
69 Buffer command;
70 const char *cp;
71 char *command_string;
72 int pin[2], pout[2];
73 pid_t pid;
74 char strport[NI_MAXSERV];
75
76 /* Convert the port number into a string. */
77 snprintf(strport, sizeof strport, "%hu", port);
78
79 /*
80 * Build the final command string in the buffer by making the
81 * appropriate substitutions to the given proxy command.
82 *
83 * Use "exec" to avoid "sh -c" processes on some platforms
84 * (e.g. Solaris)
85 */
86 buffer_init(&command);
87
88 #define EXECLEN (sizeof ("exec") - 1)
89 for (cp = proxy_command; *cp && isspace(*cp) ; cp++)
90 ;
91 if (strncmp(cp, "exec", EXECLEN) != 0 ||
92 (strlen(cp) >= EXECLEN && !isspace(*(cp + EXECLEN))))
93 buffer_append(&command, "exec ", EXECLEN + 1);
94 #undef EXECLEN
95
96 for (cp = proxy_command; *cp; cp++) {
97 if (cp[0] == '%' && cp[1] == '%') {
98 buffer_append(&command, "%", 1);
99 cp++;
100 continue;
101 }
102 if (cp[0] == '%' && cp[1] == 'h') {
103 buffer_append(&command, host, strlen(host));
104 cp++;
105 continue;
106 }
107 if (cp[0] == '%' && cp[1] == 'p') {
108 buffer_append(&command, strport, strlen(strport));
109 cp++;
110 continue;
111 }
112 buffer_append(&command, cp, 1);
113 }
114 buffer_append(&command, "\0", 1);
115
116 /* Get the final command string. */
117 command_string = buffer_ptr(&command);
118
119 /* Create pipes for communicating with the proxy. */
120 if (pipe(pin) < 0 || pipe(pout) < 0)
121 fatal("Could not create pipes to communicate with the proxy: %.100s",
122 strerror(errno));
123
124 debug("Executing proxy command: %.500s", command_string);
125
126 /* Fork and execute the proxy command. */
127 if ((pid = fork()) == 0) {
128 char *argv[10];
129
130 /* Child. Permanently give up superuser privileges. */
131 seteuid(original_real_uid);
132 setuid(original_real_uid);
133
134 /* Redirect stdin and stdout. */
135 close(pin[1]);
136 if (pin[0] != 0) {
137 if (dup2(pin[0], 0) < 0)
138 perror("dup2 stdin");
139 close(pin[0]);
140 }
141 close(pout[0]);
142 if (dup2(pout[1], 1) < 0)
143 perror("dup2 stdout");
144 /* Cannot be 1 because pin allocated two descriptors. */
145 close(pout[1]);
146
147 /* Stderr is left as it is so that error messages get
148 printed on the user's terminal. */
149 argv[0] = _PATH_BSHELL;
150 argv[1] = "-c";
151 argv[2] = command_string;
152 argv[3] = NULL;
153
154 /* Execute the proxy command. Note that we gave up any
155 extra privileges above. */
156 execv(argv[0], argv);
157 perror(argv[0]);
158 exit(1);
159 }
160 /* Parent. */
161 if (pid < 0)
162 fatal("fork failed: %.100s", strerror(errno));
163 else
164 proxy_command_pid = pid; /* save pid to clean up later */
165
166 /* Close child side of the descriptors. */
167 close(pin[0]);
168 close(pout[1]);
169
170 /* Free the command name. */
171 buffer_free(&command);
172
173 /* Set the connection file descriptors. */
174 packet_set_connection(pout[0], pin[1]);
175
176 /* Indicate OK return */
177 return 0;
178 }
179
180 /*
181 * Creates a (possibly privileged) socket for use as the ssh connection.
182 */
183 static int
ssh_create_socket(int privileged,int family)184 ssh_create_socket(int privileged, int family)
185 {
186 int sock, gaierr;
187 struct addrinfo hints, *res;
188
189 /*
190 * If we are running as root and want to connect to a privileged
191 * port, bind our own socket to a privileged port.
192 */
193 if (privileged) {
194 int p = IPPORT_RESERVED - 1;
195 PRIV_START;
196 sock = rresvport_af(&p, family);
197 PRIV_END;
198 if (sock < 0)
199 error("rresvport: af=%d %.100s", family, strerror(errno));
200 else
201 debug("Allocated local port %d.", p);
202 return sock;
203 }
204 sock = socket(family, SOCK_STREAM, 0);
205 if (sock < 0)
206 error("socket: %.100s", strerror(errno));
207
208 /* Bind the socket to an alternative local IP address */
209 if (options.bind_address == NULL)
210 return sock;
211
212 memset(&hints, 0, sizeof(hints));
213 hints.ai_family = family;
214 hints.ai_socktype = SOCK_STREAM;
215 hints.ai_flags = AI_PASSIVE;
216 gaierr = getaddrinfo(options.bind_address, "0", &hints, &res);
217 if (gaierr) {
218 error("getaddrinfo: %s: %s", options.bind_address,
219 gai_strerror(gaierr));
220 close(sock);
221 return -1;
222 }
223 if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) {
224 error("bind: %s: %s", options.bind_address, strerror(errno));
225 close(sock);
226 freeaddrinfo(res);
227 return -1;
228 }
229 freeaddrinfo(res);
230 return sock;
231 }
232
233 /*
234 * Connect with timeout. Implements ConnectTimeout option.
235 */
236 static int
timeout_connect(int sockfd,const struct sockaddr * serv_addr,socklen_t addrlen,int timeout)237 timeout_connect(int sockfd, const struct sockaddr *serv_addr,
238 socklen_t addrlen, int timeout)
239 {
240 fd_set *fdset;
241 struct timeval tv;
242 socklen_t optlen;
243 int optval, rc, result = -1;
244
245 if (timeout <= 0)
246 return (connect(sockfd, serv_addr, addrlen));
247
248 set_nonblock(sockfd);
249 rc = connect(sockfd, serv_addr, addrlen);
250 if (rc == 0) {
251 unset_nonblock(sockfd);
252 return (0);
253 }
254 if (errno != EINPROGRESS)
255 return (-1);
256
257 fdset = (fd_set *)xcalloc(howmany(sockfd + 1, NFDBITS),
258 sizeof(fd_mask));
259 FD_SET(sockfd, fdset);
260 tv.tv_sec = timeout;
261 tv.tv_usec = 0;
262
263 for (;;) {
264 rc = select(sockfd + 1, NULL, fdset, NULL, &tv);
265 if (rc != -1 || errno != EINTR)
266 break;
267 }
268
269 switch (rc) {
270 case 0:
271 /* Timed out */
272 errno = ETIMEDOUT;
273 break;
274 case -1:
275 /* Select error */
276 debug("select: %s", strerror(errno));
277 break;
278 case 1:
279 /* Completed or failed */
280 optval = 0;
281 optlen = sizeof(optval);
282 if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &optval,
283 &optlen) == -1) {
284 debug("getsockopt: %s", strerror(errno));
285 break;
286 }
287 if (optval != 0) {
288 errno = optval;
289 break;
290 }
291 result = 0;
292 unset_nonblock(sockfd);
293 break;
294 default:
295 /* Should not occur */
296 fatal("Bogus return (%d) from select()", rc);
297 }
298
299 xfree(fdset);
300 return (result);
301 }
302
303 /*
304 * Opens a TCP/IP connection to the remote server on the given host.
305 * The address of the remote host will be returned in hostaddr.
306 * If port is 0, the default port will be used. If needpriv is true,
307 * a privileged port will be allocated to make the connection.
308 * This requires super-user privileges if needpriv is true.
309 * Connection_attempts specifies the maximum number of tries (one per
310 * second). If proxy_command is non-NULL, it specifies the command (with %h
311 * and %p substituted for host and port, respectively) to use to contact
312 * the daemon.
313 * Return values:
314 * 0 for OK
315 * ECONNREFUSED if we got a "Connection Refused" by the peer on any address
316 * ECONNABORTED if we failed without a "Connection refused"
317 * Suitable error messages for the connection failure will already have been
318 * printed.
319 */
320 int
ssh_connect(const char * host,struct sockaddr_storage * hostaddr,ushort_t port,int family,int connection_attempts,int needpriv,const char * proxy_command)321 ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
322 ushort_t port, int family, int connection_attempts,
323 int needpriv, const char *proxy_command)
324 {
325 int gaierr;
326 int on = 1;
327 int sock = -1, attempt;
328 char ntop[NI_MAXHOST], strport[NI_MAXSERV];
329 struct addrinfo hints, *ai, *aitop;
330 struct servent *sp;
331 /*
332 * Did we get only other errors than "Connection refused" (which
333 * should block fallback to rsh and similar), or did we get at least
334 * one "Connection refused"?
335 */
336 int full_failure = 1;
337
338 debug("ssh_connect: needpriv %d", needpriv);
339
340 /* Get default port if port has not been set. */
341 if (port == 0) {
342 sp = getservbyname(SSH_SERVICE_NAME, "tcp");
343 if (sp)
344 port = ntohs(sp->s_port);
345 else
346 port = SSH_DEFAULT_PORT;
347 }
348 /* If a proxy command is given, connect using it. */
349 if (proxy_command != NULL)
350 return ssh_proxy_connect(host, port, proxy_command);
351
352 /* No proxy command. */
353
354 memset(&hints, 0, sizeof(hints));
355 hints.ai_family = family;
356 hints.ai_socktype = SOCK_STREAM;
357 snprintf(strport, sizeof strport, "%u", port);
358 if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0)
359 fatal("%s: %.100s: %s", __progname, host,
360 gai_strerror(gaierr));
361
362 /*
363 * Try to connect several times. On some machines, the first time
364 * will sometimes fail. In general socket code appears to behave
365 * quite magically on many machines.
366 */
367 for (attempt = 0; ;) {
368 if (attempt > 0)
369 debug("Trying again...");
370
371 /* Loop through addresses for this host, and try each one in
372 sequence until the connection succeeds. */
373 for (ai = aitop; ai; ai = ai->ai_next) {
374 if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
375 continue;
376 if (getnameinfo(ai->ai_addr, ai->ai_addrlen,
377 ntop, sizeof(ntop), strport, sizeof(strport),
378 NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
379 error("ssh_connect: getnameinfo failed");
380 continue;
381 }
382 debug("Connecting to %.200s [%.100s] port %s.",
383 host, ntop, strport);
384
385 /* Create a socket for connecting. */
386 sock = ssh_create_socket(needpriv, ai->ai_family);
387 if (sock < 0)
388 /* Any error is already output */
389 continue;
390
391 if (timeout_connect(sock, ai->ai_addr, ai->ai_addrlen,
392 options.connection_timeout) >= 0) {
393 /* Successful connection. */
394 memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen);
395 break;
396 } else {
397 if (errno == ECONNREFUSED)
398 full_failure = 0;
399 debug("connect to address %s port %s: %s",
400 ntop, strport, strerror(errno));
401 /*
402 * Close the failed socket; there appear to
403 * be some problems when reusing a socket for
404 * which connect() has already returned an
405 * error.
406 */
407 close(sock);
408 }
409 }
410 if (ai)
411 break; /* Successful connection. */
412
413 attempt++;
414 if (attempt >= connection_attempts)
415 break;
416 /* Sleep a moment before retrying. */
417 sleep(1);
418 }
419
420 freeaddrinfo(aitop);
421
422 /* Return failure if we didn't get a successful connection. */
423 if (attempt >= connection_attempts) {
424 log("ssh: connect to host %s port %s: %s",
425 host, strport, strerror(errno));
426 return full_failure ? ECONNABORTED : ECONNREFUSED;
427 }
428
429 debug("Connection established.");
430
431 /* Set keepalives if requested. */
432 if (options.keepalives &&
433 setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&on,
434 sizeof(on)) < 0)
435 debug2("setsockopt SO_KEEPALIVE: %.100s", strerror(errno));
436
437 /* Set the connection. */
438 packet_set_connection(sock, sock);
439
440 return 0;
441 }
442
443 /*
444 * Waits for the server identification string, and sends our own
445 * identification string.
446 */
447 static void
ssh_exchange_identification(void)448 ssh_exchange_identification(void)
449 {
450 char buf[256], remote_version[256]; /* must be same size! */
451 int remote_major, remote_minor, i, mismatch;
452 int connection_in = packet_get_connection_in();
453 int connection_out = packet_get_connection_out();
454 int minor1 = PROTOCOL_MINOR_1;
455
456 /* Read other side\'s version identification. */
457 for (;;) {
458 for (i = 0; i < sizeof(buf) - 1; i++) {
459 int len = atomicio(read, connection_in, &buf[i], 1);
460 if (len < 0)
461 fatal("ssh_exchange_identification: read: %.100s", strerror(errno));
462 if (len != 1)
463 fatal("ssh_exchange_identification: Connection closed by remote host");
464 if (buf[i] == '\r') {
465 buf[i] = '\n';
466 buf[i + 1] = 0;
467 continue; /**XXX wait for \n */
468 }
469 if (buf[i] == '\n') {
470 buf[i + 1] = 0;
471 break;
472 }
473 }
474 buf[sizeof(buf) - 1] = 0;
475 if (strncmp(buf, "SSH-", 4) == 0)
476 break;
477 debug("ssh_exchange_identification: %s", buf);
478 }
479 server_version_string = xstrdup(buf);
480
481 /*
482 * Check that the versions match. In future this might accept
483 * several versions and set appropriate flags to handle them.
484 */
485 if (sscanf(server_version_string, "SSH-%d.%d-%[^\n]\n",
486 &remote_major, &remote_minor, remote_version) != 3)
487 fatal("Bad remote protocol version identification: '%.100s'", buf);
488 debug("Remote protocol version %d.%d, remote software version %.100s",
489 remote_major, remote_minor, remote_version);
490
491 compat_datafellows(remote_version);
492 mismatch = 0;
493
494 switch (remote_major) {
495 case 1:
496 if (remote_minor == 99 &&
497 (options.protocol & SSH_PROTO_2) &&
498 !(options.protocol & SSH_PROTO_1_PREFERRED)) {
499 enable_compat20();
500 break;
501 }
502 if (!(options.protocol & SSH_PROTO_1)) {
503 mismatch = 1;
504 break;
505 }
506 if (remote_minor < 3) {
507 fatal("Remote machine has too old SSH software version.");
508 } else if (remote_minor == 3 || remote_minor == 4) {
509 /* We speak 1.3, too. */
510 enable_compat13();
511 minor1 = 3;
512 if (options.forward_agent) {
513 log("Agent forwarding disabled for protocol 1.3");
514 options.forward_agent = 0;
515 }
516 }
517 break;
518 case 2:
519 if (options.protocol & SSH_PROTO_2) {
520 enable_compat20();
521 break;
522 }
523 /* FALLTHROUGH */
524 default:
525 mismatch = 1;
526 break;
527 }
528 if (mismatch)
529 fatal("Protocol major versions differ: %d vs. %d",
530 (options.protocol & SSH_PROTO_2) ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,
531 remote_major);
532 /* Send our own protocol version identification. */
533 snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n",
534 compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,
535 compat20 ? PROTOCOL_MINOR_2 : minor1,
536 SSH_VERSION);
537 if (atomicio(write, connection_out, buf, strlen(buf)) != strlen(buf))
538 fatal("write: %.100s", strerror(errno));
539 client_version_string = xstrdup(buf);
540 chop(client_version_string);
541 chop(server_version_string);
542 debug("Local version string %.100s", client_version_string);
543 }
544
545 /* defaults to 'no' */
546 static int
confirm(const char * prompt)547 confirm(const char *prompt)
548 {
549 const char *msg;
550 char *p, *again = NULL;
551 int n, ret = -1;
552 regex_t yesre, nore;
553 char *errstr;
554 int rerr, errlen;
555
556 if (options.batch_mode)
557 return 0;
558 n = snprintf(NULL, 0, gettext("Please type '%s' or '%s': "),
559 nl_langinfo(YESSTR), nl_langinfo(NOSTR));
560 again = xmalloc(n + 1);
561 (void) snprintf(again, n + 1, gettext("Please type '%s' or '%s': "),
562 nl_langinfo(YESSTR), nl_langinfo(NOSTR));
563
564 if ((rerr = regcomp(&yesre, nl_langinfo(YESEXPR), REG_EXTENDED)) != 0) {
565 errlen = regerror(rerr, &yesre, NULL, 0);
566 if ((errstr = malloc(errlen)) == NULL)
567 err(1, "malloc");
568 regerror(rerr, &yesre, errstr, errlen);
569 errx(1, "YESEXPR: %s: %s", nl_langinfo(YESEXPR), errstr);
570 }
571
572 if ((rerr = regcomp(&nore, nl_langinfo(NOEXPR), REG_EXTENDED)) != 0) {
573 errlen = regerror(rerr, &nore, NULL, 0);
574 if ((errstr = malloc(errlen)) == NULL)
575 err(1, "malloc");
576 regerror(rerr, &nore, errstr, errlen);
577 errx(1, "NOEXPR: %s: %s", nl_langinfo(NOEXPR), errstr);
578 }
579
580 for (msg = prompt;;msg = again) {
581 p = read_passphrase(msg, RP_ECHO);
582 if (p == NULL || (p[0] == '\0') || (p[0] == '\n') ||
583 regexec(&nore, p, 0, NULL, 0) == 0)
584 ret = 0;
585 if (p && regexec(&yesre, p, 0, NULL, 0) == 0)
586 ret = 1;
587 if (p)
588 xfree(p);
589 if (ret != -1) {
590 regfree(&yesre);
591 regfree(&nore);
592 return ret;
593 }
594 }
595 }
596
597 /*
598 * check whether the supplied host key is valid, return -1 if the key
599 * is not valid. the user_hostfile will not be updated if 'readonly' is true.
600 */
601 static int
check_host_key(char * host,struct sockaddr * hostaddr,Key * host_key,int validated,int readonly,const char * user_hostfile,const char * system_hostfile)602 check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key, int
603 validated, int readonly, const char *user_hostfile, const char
604 *system_hostfile)
605 {
606 Key *file_key;
607 char *type = key_type(host_key);
608 char *ip = NULL;
609 char hostline[1000], *hostp, *fp;
610 HostStatus host_status;
611 HostStatus ip_status;
612 int r, local = 0, host_ip_differ = 0;
613 int salen;
614 char ntop[NI_MAXHOST];
615 char msg[1024];
616 int len, host_line, ip_line, has_keys;
617 const char *host_file = NULL, *ip_file = NULL;
618
619 /*
620 * Force accepting of the host key for loopback/localhost. The
621 * problem is that if the home directory is NFS-mounted to multiple
622 * machines, localhost will refer to a different machine in each of
623 * them, and the user will get bogus HOST_CHANGED warnings. This
624 * essentially disables host authentication for localhost; however,
625 * this is probably not a real problem.
626 */
627 /** hostaddr == 0! */
628 switch (hostaddr->sa_family) {
629 case AF_INET:
630 /* LINTED */
631 local = (ntohl(((struct sockaddr_in *)hostaddr)->
632 sin_addr.s_addr) >> 24) == IN_LOOPBACKNET;
633 salen = sizeof(struct sockaddr_in);
634 break;
635 case AF_INET6:
636 /* LINTED */
637 local = IN6_IS_ADDR_LOOPBACK(
638 &(((struct sockaddr_in6 *)hostaddr)->sin6_addr));
639 salen = sizeof(struct sockaddr_in6);
640 break;
641 default:
642 local = 0;
643 salen = sizeof(struct sockaddr_storage);
644 break;
645 }
646 if (options.no_host_authentication_for_localhost == 1 && local &&
647 options.host_key_alias == NULL) {
648 debug("Forcing accepting of host key for "
649 "loopback/localhost.");
650 return 0;
651 }
652
653 /*
654 * We don't have the remote ip-address for connections
655 * using a proxy command
656 */
657 if (options.proxy_command == NULL) {
658 if (getnameinfo(hostaddr, salen, ntop, sizeof(ntop),
659 NULL, 0, NI_NUMERICHOST) != 0)
660 fatal("check_host_key: getnameinfo failed");
661 ip = xstrdup(ntop);
662 } else {
663 ip = xstrdup("<no hostip for proxy command>");
664 }
665 /*
666 * Turn off check_host_ip if the connection is to localhost, via proxy
667 * command or if we don't have a hostname to compare with
668 */
669 if (options.check_host_ip &&
670 (local || strcmp(host, ip) == 0 || options.proxy_command != NULL))
671 options.check_host_ip = 0;
672
673 /*
674 * Allow the user to record the key under a different name. This is
675 * useful for ssh tunneling over forwarded connections or if you run
676 * multiple sshd's on different ports on the same machine.
677 */
678 if (options.host_key_alias != NULL) {
679 host = options.host_key_alias;
680 debug("using hostkeyalias: %s", host);
681 }
682
683 /*
684 * Store the host key from the known host file in here so that we can
685 * compare it with the key for the IP address.
686 */
687 file_key = key_new(host_key->type);
688
689 /*
690 * Check if the host key is present in the user's list of known
691 * hosts or in the systemwide list.
692 */
693 host_file = user_hostfile;
694 host_status = check_host_in_hostfile(host_file, host, host_key,
695 file_key, &host_line);
696 if (host_status == HOST_NEW) {
697 host_file = system_hostfile;
698 host_status = check_host_in_hostfile(host_file, host, host_key,
699 file_key, &host_line);
700 }
701 /*
702 * Also perform check for the ip address, skip the check if we are
703 * localhost or the hostname was an ip address to begin with
704 */
705 if (options.check_host_ip) {
706 Key *ip_key = key_new(host_key->type);
707
708 ip_file = user_hostfile;
709 ip_status = check_host_in_hostfile(ip_file, ip, host_key,
710 ip_key, &ip_line);
711 if (ip_status == HOST_NEW) {
712 ip_file = system_hostfile;
713 ip_status = check_host_in_hostfile(ip_file, ip,
714 host_key, ip_key, &ip_line);
715 }
716 if (host_status == HOST_CHANGED &&
717 (ip_status != HOST_CHANGED || !key_equal(ip_key, file_key)))
718 host_ip_differ = 1;
719
720 key_free(ip_key);
721 } else
722 ip_status = host_status;
723
724 key_free(file_key);
725
726 switch (host_status) {
727 case HOST_OK:
728 /* The host is known and the key matches. */
729 if (validated)
730 debug("Host '%.200s' is known and matches the %s host key.",
731 host, type);
732 else
733 debug("Host '%.200s' is known and matches the %s host "
734 "key.", host, type);
735 debug("Found key in %s:%d", host_file, host_line);
736 if (options.check_host_ip && ip_status == HOST_NEW) {
737 if (readonly)
738 log("%s host key for IP address "
739 "'%.128s' not in list of known hosts.",
740 type, ip);
741 else if (!add_host_to_hostfile(user_hostfile, ip,
742 host_key, options.hash_known_hosts))
743 log("Failed to add the %s host key for IP "
744 "address '%.128s' to the list of known "
745 "hosts (%.30s).", type, ip, user_hostfile);
746 else
747 log("Warning: Permanently added the %s host "
748 "key for IP address '%.128s' to the list "
749 "of known hosts.", type, ip);
750 }
751 break;
752 case HOST_NEW:
753 if (readonly)
754 goto fail;
755 /* The host is new. */
756 if (!validated && options.strict_host_key_checking == 1) {
757 /*
758 * User has requested strict host key checking. We
759 * will not add the host key automatically. The only
760 * alternative left is to abort.
761 */
762 error("No %s host key is known for %.200s and you "
763 "have requested strict checking.", type, host);
764 goto fail;
765 } else if (!validated &&
766 options.strict_host_key_checking == 2) {
767 has_keys = show_other_keys(host, host_key);
768 /* The default */
769 fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
770 snprintf(msg, sizeof(msg),
771 gettext("The authenticity of host '%.200s (%s)' "
772 "can't be established%s\n%s key fingerprint "
773 "is %s.\n"
774 "Are you sure you want to continue connecting "
775 "(%s/%s)? "),
776 host, ip,
777 has_keys ? gettext(",\nbut keys of different type "
778 "are already known for this host.") : ".",
779 type, fp, nl_langinfo(YESSTR), nl_langinfo(NOSTR));
780 xfree(fp);
781 if (!confirm(msg))
782 goto fail;
783 }
784 /*
785 * If not in strict mode, add the key automatically to the
786 * local known_hosts file.
787 */
788 if (options.check_host_ip && ip_status == HOST_NEW) {
789 snprintf(hostline, sizeof(hostline), "%s,%s",
790 host, ip);
791 hostp = hostline;
792 if (options.hash_known_hosts) {
793 /* Add hash of host and IP separately */
794 r = add_host_to_hostfile(user_hostfile, host,
795 host_key, options.hash_known_hosts) &&
796 add_host_to_hostfile(user_hostfile, ip,
797 host_key, options.hash_known_hosts);
798 } else {
799 /* Add unhashed "host,ip" */
800 r = add_host_to_hostfile(user_hostfile,
801 hostline, host_key,
802 options.hash_known_hosts);
803 }
804 } else {
805 r = add_host_to_hostfile(user_hostfile, host, host_key,
806 options.hash_known_hosts);
807 hostp = host;
808 }
809
810 if (!r)
811 log("Failed to add the host to the list of known "
812 "hosts (%.500s).", user_hostfile);
813 else
814 log("Warning: Permanently added '%.200s' (%s) to the "
815 "list of known hosts.", hostp, type);
816 break;
817 case HOST_CHANGED:
818 if (validated) {
819 log("Warning: The host key for host %s has changed; "
820 "please update your known hosts file(s) "
821 "(%s:%d)", host, host_file, host_line);
822 if (options.check_host_ip && host_ip_differ) {
823 log("Warning: The host key for host %s has "
824 "changed; please update your known "
825 "hosts file(s) (%s:%d)", ip, host_file,
826 host_line);
827
828 }
829 break;
830 }
831 if (options.check_host_ip && host_ip_differ) {
832 char *msg;
833 if (ip_status == HOST_NEW)
834 msg = "is unknown";
835 else if (ip_status == HOST_OK)
836 msg = "is unchanged";
837 else
838 msg = "has a different value";
839 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"
840 "@ WARNING: POSSIBLE DNS SPOOFING DETECTED! @\n"
841 "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"
842 "The %s host key for %s has changed,\n"
843 "and the key for the according IP address %s\n"
844 "%s. This could either mean that\n"
845 "DNS SPOOFING is happening or the IP address for the host\n"
846 "and its host key have changed at the same time.\n",
847 type, host, ip, msg);
848 if (ip_status != HOST_NEW)
849 error("Offending key for IP in %s:%d", ip_file, ip_line);
850 }
851 /* The host key has changed. */
852 fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
853 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"
854 "@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @\n"
855 "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"
856 "IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!\n"
857 "Someone could be eavesdropping on you right now (man-in-the-middle attack)!\n"
858 "It is also possible that the %s host key has just been changed.\n"
859 "The fingerprint for the %s key sent by the remote host is\n%s.\n"
860 "Please contact your system administrator.\n"
861 "Add correct host key in %.100s to get rid of this message.\n"
862 "Offending key in %s:%d\n",
863 type, type, fp, user_hostfile, host_file, host_line);
864 xfree(fp);
865
866 /*
867 * If strict host key checking is in use, the user will have
868 * to edit the key manually and we can only abort.
869 */
870 if (options.strict_host_key_checking) {
871 error("%s host key for %.200s has changed and you have "
872 "requested strict checking.", type, host);
873 goto fail;
874 }
875
876 /*
877 * If strict host key checking has not been requested, allow
878 * the connection but without password authentication or
879 * agent forwarding.
880 */
881 if (options.password_authentication) {
882 error("Password authentication is disabled to avoid "
883 "man-in-the-middle attacks.");
884 options.password_authentication = 0;
885 }
886 if (options.forward_agent) {
887 error("Agent forwarding is disabled to avoid "
888 "man-in-the-middle attacks.");
889 options.forward_agent = 0;
890 }
891 if (options.forward_x11) {
892 error("X11 forwarding is disabled to avoid "
893 "man-in-the-middle attacks.");
894 options.forward_x11 = 0;
895 }
896 if (options.num_local_forwards > 0 ||
897 options.num_remote_forwards > 0) {
898 error("Port forwarding is disabled to avoid "
899 "man-in-the-middle attacks.");
900 options.num_local_forwards =
901 options.num_remote_forwards = 0;
902 }
903 /*
904 * XXX Should permit the user to change to use the new id.
905 * This could be done by converting the host key to an
906 * identifying sentence, tell that the host identifies itself
907 * by that sentence, and ask the user if he/she whishes to
908 * accept the authentication.
909 */
910 break;
911 case HOST_FOUND:
912 fatal("internal error");
913 break;
914 }
915
916 if (options.check_host_ip && host_status != HOST_CHANGED &&
917 ip_status == HOST_CHANGED) {
918 snprintf(msg, sizeof(msg),
919 gettext("Warning: the %s host key for '%.200s' "
920 "differs from the key for the IP address '%.128s'"
921 "\nOffending key for IP in %s:%d"),
922 type, host, ip, ip_file, ip_line);
923 if (host_status == HOST_OK) {
924 len = strlen(msg);
925 snprintf(msg + len, sizeof(msg) - len,
926 "\nMatching host key in %s:%d",
927 host_file, host_line);
928 }
929 if (!validated && options.strict_host_key_checking == 1) {
930 log(msg);
931 error("Exiting, you have requested strict checking.");
932 goto fail;
933 } else if (!validated &&
934 options.strict_host_key_checking == 2) {
935 snprintf(msg + strlen(msg), sizeof(msg) - strlen(msg),
936 gettext("\nAre you sure you want to continue "
937 "connecting (%s/%s)"),
938 nl_langinfo(YESSTR), nl_langinfo(NOSTR));
939 if (!confirm(msg))
940 goto fail;
941 } else {
942 log(msg);
943 }
944 }
945
946 xfree(ip);
947 return 0;
948
949 fail:
950 xfree(ip);
951 return -1;
952 }
953
954 int
verify_host_key(char * host,struct sockaddr * hostaddr,Key * host_key)955 verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)
956 {
957 struct stat st;
958
959 /* return ok if the key can be found in an old keyfile */
960 if (stat(options.system_hostfile2, &st) == 0 ||
961 stat(options.user_hostfile2, &st) == 0) {
962 if (check_host_key(host, hostaddr, host_key, 0, /*readonly*/ 1,
963 options.user_hostfile2, options.system_hostfile2) == 0)
964 return 0;
965 }
966 return check_host_key(host, hostaddr, host_key, 0, /*readonly*/ 0,
967 options.user_hostfile, options.system_hostfile);
968 }
969
970 int
accept_host_key(char * host,struct sockaddr * hostaddr,Key * host_key)971 accept_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)
972 {
973 struct stat st;
974
975 /* return ok if the key can be found in an old keyfile */
976 if (stat(options.system_hostfile2, &st) == 0 ||
977 stat(options.user_hostfile2, &st) == 0) {
978 if (check_host_key(host, hostaddr, host_key, 1, /*readonly*/ 1,
979 options.user_hostfile2, options.system_hostfile2) == 0)
980 return 0;
981 }
982 return check_host_key(host, hostaddr, host_key, 1, /*readonly*/ 0,
983 options.user_hostfile, options.system_hostfile);
984 }
985 /*
986 * Starts a dialog with the server, and authenticates the current user on the
987 * server. This does not need any extra privileges. The basic connection
988 * to the server must already have been established before this is called.
989 * If login fails, this function prints an error and never returns.
990 * This function does not require super-user privileges.
991 */
992 void
ssh_login(Sensitive * sensitive,const char * orighost,struct sockaddr * hostaddr,char * pw_name)993 ssh_login(Sensitive *sensitive, const char *orighost,
994 struct sockaddr *hostaddr, char *pw_name)
995 {
996 char *host, *cp;
997 char *server_user, *local_user;
998
999 local_user = xstrdup(pw_name);
1000 server_user = options.user ? options.user : local_user;
1001
1002 /* Convert the user-supplied hostname into all lowercase. */
1003 host = xstrdup(orighost);
1004 for (cp = host; *cp; cp++)
1005 if (isupper(*cp))
1006 *cp = tolower(*cp);
1007
1008 /* Exchange protocol version identification strings with the server. */
1009 ssh_exchange_identification();
1010
1011 /*
1012 * See comment at definition of will_daemonize for information why we
1013 * don't support the PKCS#11 engine with protocol 1.
1014 */
1015 if (compat20 == 1 && options.use_openssl_engine == 1) {
1016 /*
1017 * If this fails then 'e' will be NULL which means we do not use
1018 * the engine, as if UseOpenSSLEngine was set to "no". This is
1019 * important in case we go to the background after the
1020 * authentication.
1021 */
1022 e = pkcs11_engine_load(options.use_openssl_engine);
1023 }
1024
1025 /* Put the connection into non-blocking mode. */
1026 packet_set_nonblocking();
1027
1028 /* key exchange */
1029 /* authenticate user */
1030 if (compat20) {
1031 /*
1032 * Note that the host pointer is saved in ssh_kex2() for later
1033 * use during the key re-exchanges so we must not xfree() it.
1034 */
1035 ssh_kex2(host, hostaddr);
1036 ssh_userauth2(local_user, server_user, host, sensitive);
1037 } else {
1038 ssh_kex(host, hostaddr);
1039 ssh_userauth1(local_user, server_user, host, sensitive);
1040 }
1041
1042 xfree(local_user);
1043 }
1044
1045 void
ssh_put_password(char * password)1046 ssh_put_password(char *password)
1047 {
1048 int size;
1049 char *padded;
1050
1051 if (datafellows & SSH_BUG_PASSWORDPAD) {
1052 packet_put_cstring(password);
1053 return;
1054 }
1055 size = roundup(strlen(password) + 1, 32);
1056 padded = xmalloc(size);
1057 memset(padded, 0, size);
1058 strlcpy(padded, password, size);
1059 packet_put_string(padded, size);
1060 memset(padded, 0, size);
1061 xfree(padded);
1062 }
1063
1064 static int
show_key_from_file(const char * file,const char * host,int keytype)1065 show_key_from_file(const char *file, const char *host, int keytype)
1066 {
1067 Key *found;
1068 char *fp;
1069 int line, ret;
1070
1071 found = key_new(keytype);
1072 if ((ret = lookup_key_in_hostfile_by_type(file, host,
1073 keytype, found, &line))) {
1074 fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX);
1075 log("WARNING: %s key found for host %s\n"
1076 "in %s:%d\n"
1077 "%s key fingerprint %s.",
1078 key_type(found), host, file, line,
1079 key_type(found), fp);
1080 xfree(fp);
1081 }
1082 key_free(found);
1083 return (ret);
1084 }
1085
1086 /* print all known host keys for a given host, but skip keys of given type */
1087 static int
show_other_keys(const char * host,Key * key)1088 show_other_keys(const char *host, Key *key)
1089 {
1090 int type[] = { KEY_RSA1, KEY_RSA, KEY_DSA, -1};
1091 int i, found = 0;
1092
1093 for (i = 0; type[i] != -1; i++) {
1094 if (type[i] == key->type)
1095 continue;
1096 if (type[i] != KEY_RSA1 &&
1097 show_key_from_file(options.user_hostfile2, host, type[i])) {
1098 found = 1;
1099 continue;
1100 }
1101 if (type[i] != KEY_RSA1 &&
1102 show_key_from_file(options.system_hostfile2, host, type[i])) {
1103 found = 1;
1104 continue;
1105 }
1106 if (show_key_from_file(options.user_hostfile, host, type[i])) {
1107 found = 1;
1108 continue;
1109 }
1110 if (show_key_from_file(options.system_hostfile, host, type[i])) {
1111 found = 1;
1112 continue;
1113 }
1114 debug2("no key of type %d for host %s", type[i], host);
1115 }
1116 return (found);
1117 }
1118