diff options
Diffstat (limited to 'ssh.c')
-rw-r--r-- | ssh.c | 54 |
1 files changed, 39 insertions, 15 deletions
@@ -11,7 +11,7 @@ | |||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include "includes.h" | 13 | #include "includes.h" |
14 | RCSID("$Id: ssh.c,v 1.15 1999/12/28 23:17:09 damien Exp $"); | 14 | RCSID("$Id: ssh.c,v 1.16 2000/01/14 04:45:51 damien Exp $"); |
15 | 15 | ||
16 | #include "xmalloc.h" | 16 | #include "xmalloc.h" |
17 | #include "ssh.h" | 17 | #include "ssh.h" |
@@ -27,6 +27,10 @@ extern char *__progname; | |||
27 | const char *__progname = "ssh"; | 27 | const char *__progname = "ssh"; |
28 | #endif /* HAVE___PROGNAME */ | 28 | #endif /* HAVE___PROGNAME */ |
29 | 29 | ||
30 | /* Flag indicating whether IPv4 or IPv6. This can be set on the command line. | ||
31 | Default value is AF_UNSPEC means both IPv4 and IPv6. */ | ||
32 | int IPv4or6 = AF_UNSPEC; | ||
33 | |||
30 | /* Flag indicating whether debug mode is on. This can be set on the command line. */ | 34 | /* Flag indicating whether debug mode is on. This can be set on the command line. */ |
31 | int debug_flag = 0; | 35 | int debug_flag = 0; |
32 | 36 | ||
@@ -59,7 +63,7 @@ Options options; | |||
59 | char *host; | 63 | char *host; |
60 | 64 | ||
61 | /* socket address the host resolves to */ | 65 | /* socket address the host resolves to */ |
62 | struct sockaddr_in hostaddr; | 66 | struct sockaddr_storage hostaddr; |
63 | 67 | ||
64 | /* | 68 | /* |
65 | * Flag to indicate that we have received a window change signal which has | 69 | * Flag to indicate that we have received a window change signal which has |
@@ -114,6 +118,8 @@ usage() | |||
114 | fprintf(stderr, " forward them to the other side by connecting to host:port.\n"); | 118 | fprintf(stderr, " forward them to the other side by connecting to host:port.\n"); |
115 | fprintf(stderr, " -C Enable compression.\n"); | 119 | fprintf(stderr, " -C Enable compression.\n"); |
116 | fprintf(stderr, " -g Allow remote hosts to connect to forwarded ports.\n"); | 120 | fprintf(stderr, " -g Allow remote hosts to connect to forwarded ports.\n"); |
121 | fprintf(stderr, " -4 Use IPv4 only.\n"); | ||
122 | fprintf(stderr, " -6 Use IPv6 only.\n"); | ||
117 | fprintf(stderr, " -o 'option' Process the option as if it was read from a configuration file.\n"); | 123 | fprintf(stderr, " -o 'option' Process the option as if it was read from a configuration file.\n"); |
118 | exit(1); | 124 | exit(1); |
119 | } | 125 | } |
@@ -227,6 +233,8 @@ main(int ac, char **av) | |||
227 | if (host) | 233 | if (host) |
228 | break; | 234 | break; |
229 | if ((cp = strchr(av[optind], '@'))) { | 235 | if ((cp = strchr(av[optind], '@'))) { |
236 | if(cp == av[optind]) | ||
237 | usage(); | ||
230 | options.user = av[optind]; | 238 | options.user = av[optind]; |
231 | *cp = '\0'; | 239 | *cp = '\0'; |
232 | host = ++cp; | 240 | host = ++cp; |
@@ -250,6 +258,14 @@ main(int ac, char **av) | |||
250 | optarg = NULL; | 258 | optarg = NULL; |
251 | } | 259 | } |
252 | switch (opt) { | 260 | switch (opt) { |
261 | case '4': | ||
262 | IPv4or6 = AF_INET; | ||
263 | break; | ||
264 | |||
265 | case '6': | ||
266 | IPv4or6 = AF_INET6; | ||
267 | break; | ||
268 | |||
253 | case 'n': | 269 | case 'n': |
254 | stdin_null_flag = 1; | 270 | stdin_null_flag = 1; |
255 | break; | 271 | break; |
@@ -351,8 +367,10 @@ main(int ac, char **av) | |||
351 | break; | 367 | break; |
352 | 368 | ||
353 | case 'R': | 369 | case 'R': |
354 | if (sscanf(optarg, "%hu:%255[^:]:%hu", &fwd_port, buf, | 370 | if (sscanf(optarg, "%hu/%255[^/]/%hu", &fwd_port, buf, |
355 | &fwd_host_port) != 3) { | 371 | &fwd_host_port) != 3 && |
372 | sscanf(optarg, "%hu:%255[^:]:%hu", &fwd_port, buf, | ||
373 | &fwd_host_port) != 3) { | ||
356 | fprintf(stderr, "Bad forwarding specification '%s'.\n", optarg); | 374 | fprintf(stderr, "Bad forwarding specification '%s'.\n", optarg); |
357 | usage(); | 375 | usage(); |
358 | /* NOTREACHED */ | 376 | /* NOTREACHED */ |
@@ -361,8 +379,10 @@ main(int ac, char **av) | |||
361 | break; | 379 | break; |
362 | 380 | ||
363 | case 'L': | 381 | case 'L': |
364 | if (sscanf(optarg, "%hu:%255[^:]:%hu", &fwd_port, buf, | 382 | if (sscanf(optarg, "%hu/%255[^/]/%hu", &fwd_port, buf, |
365 | &fwd_host_port) != 3) { | 383 | &fwd_host_port) != 3 && |
384 | sscanf(optarg, "%hu:%255[^:]:%hu", &fwd_port, buf, | ||
385 | &fwd_host_port) != 3) { | ||
366 | fprintf(stderr, "Bad forwarding specification '%s'.\n", optarg); | 386 | fprintf(stderr, "Bad forwarding specification '%s'.\n", optarg); |
367 | usage(); | 387 | usage(); |
368 | /* NOTREACHED */ | 388 | /* NOTREACHED */ |
@@ -473,14 +493,18 @@ main(int ac, char **av) | |||
473 | 493 | ||
474 | /* Find canonic host name. */ | 494 | /* Find canonic host name. */ |
475 | if (strchr(host, '.') == 0) { | 495 | if (strchr(host, '.') == 0) { |
476 | struct hostent *hp = gethostbyname(host); | 496 | struct addrinfo hints; |
477 | if (hp != 0) { | 497 | struct addrinfo *ai = NULL; |
478 | if (strchr(hp->h_name, '.') != 0) | 498 | int errgai; |
479 | host = xstrdup(hp->h_name); | 499 | memset(&hints, 0, sizeof(hints)); |
480 | else if (hp->h_aliases != 0 | 500 | hints.ai_family = AF_UNSPEC; |
481 | && hp->h_aliases[0] != 0 | 501 | hints.ai_flags = AI_CANONNAME; |
482 | && strchr(hp->h_aliases[0], '.') != 0) | 502 | hints.ai_socktype = SOCK_STREAM; |
483 | host = xstrdup(hp->h_aliases[0]); | 503 | errgai = getaddrinfo(host, NULL, &hints, &ai); |
504 | if (errgai == 0) { | ||
505 | if (ai->ai_canonname != NULL) | ||
506 | host = xstrdup(ai->ai_canonname); | ||
507 | freeaddrinfo(ai); | ||
484 | } | 508 | } |
485 | } | 509 | } |
486 | /* Disable rhosts authentication if not running as root. */ | 510 | /* Disable rhosts authentication if not running as root. */ |
@@ -587,7 +611,7 @@ main(int ac, char **av) | |||
587 | 611 | ||
588 | /* Log into the remote system. This never returns if the login fails. */ | 612 | /* Log into the remote system. This never returns if the login fails. */ |
589 | ssh_login(host_private_key_loaded, host_private_key, | 613 | ssh_login(host_private_key_loaded, host_private_key, |
590 | host, &hostaddr, original_real_uid); | 614 | host, (struct sockaddr *)&hostaddr, original_real_uid); |
591 | 615 | ||
592 | /* We no longer need the host private key. Clear it now. */ | 616 | /* We no longer need the host private key. Clear it now. */ |
593 | if (host_private_key_loaded) | 617 | if (host_private_key_loaded) |