diff options
author | Damien Miller <djm@mindrot.org> | 2000-01-14 15:45:46 +1100 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2000-01-14 15:45:46 +1100 |
commit | 34132e54cbd221d17d373fc54f4e3f7b85727f7f (patch) | |
tree | 7c73917b1082ff91786f9e02d25b853bedd1d472 /ssh.c | |
parent | 25e4256ad4f453d8a7c1866243ec1984f859b1de (diff) |
- Merged OpenBSD IPv6 patch:
- [sshd.c sshd.8 sshconnect.c ssh.h ssh.c servconf.h servconf.c scp.1]
[scp.c packet.h packet.c login.c log.c canohost.c channels.c]
[hostfile.c sshd_config]
ipv6 support: mostly gethostbyname->getaddrinfo/getnameinfo, new
features: sshd allows multiple ListenAddress and Port options. note
that libwrap is not IPv6-ready. (based on patches from
fujiwara@rcac.tdi.co.jp)
- [ssh.c canohost.c]
more hints (hints.ai_socktype=SOCK_STREAM) for getaddrinfo,
from itojun@
- [channels.c]
listen on _all_ interfaces for X11-Fwd (hints.ai_flags = AI_PASSIVE)
- [packet.h]
allow auth-kerberos for IPv4 only
- [scp.1 sshd.8 servconf.h scp.c]
document -4, -6, and 'ssh -L 2022/::1/22'
- [ssh.c]
'ssh @host' is illegal (null user name), from
karsten@gedankenpolizei.de
- [sshconnect.c]
better error message
- [sshd.c]
allow auth-kerberos for IPv4 only
- Big IPv6 merge:
- Cleanup overrun in sockaddr copying on RHL 6.1
- Replacements for getaddrinfo, getnameinfo, etc based on versions
from patch from KIKUCHI Takahiro <kick@kyoto.wide.ad.jp>
- Replacement for missing structures on systems that lack IPv6
- record_login needed to know about AF_INET6 addresses
- Borrowed more code from OpenBSD: rresvport_af and requisites
Diffstat (limited to 'ssh.c')
-rw-r--r-- | ssh.c | 54 |
1 files changed, 39 insertions, 15 deletions
@@ -11,7 +11,7 @@ */ #include "includes.h" -RCSID("$Id: ssh.c,v 1.15 1999/12/28 23:17:09 damien Exp $"); +RCSID("$Id: ssh.c,v 1.16 2000/01/14 04:45:51 damien Exp $"); #include "xmalloc.h" #include "ssh.h" @@ -27,6 +27,10 @@ extern char *__progname; const char *__progname = "ssh"; #endif /* HAVE___PROGNAME */ +/* Flag indicating whether IPv4 or IPv6. This can be set on the command line. + Default value is AF_UNSPEC means both IPv4 and IPv6. */ +int IPv4or6 = AF_UNSPEC; + /* Flag indicating whether debug mode is on. This can be set on the command line. */ int debug_flag = 0; @@ -59,7 +63,7 @@ Options options; char *host; /* socket address the host resolves to */ -struct sockaddr_in hostaddr; +struct sockaddr_storage hostaddr; /* * Flag to indicate that we have received a window change signal which has @@ -114,6 +118,8 @@ usage() fprintf(stderr, " forward them to the other side by connecting to host:port.\n"); fprintf(stderr, " -C Enable compression.\n"); fprintf(stderr, " -g Allow remote hosts to connect to forwarded ports.\n"); + fprintf(stderr, " -4 Use IPv4 only.\n"); + fprintf(stderr, " -6 Use IPv6 only.\n"); fprintf(stderr, " -o 'option' Process the option as if it was read from a configuration file.\n"); exit(1); } @@ -227,6 +233,8 @@ main(int ac, char **av) if (host) break; if ((cp = strchr(av[optind], '@'))) { + if(cp == av[optind]) + usage(); options.user = av[optind]; *cp = '\0'; host = ++cp; @@ -250,6 +258,14 @@ main(int ac, char **av) optarg = NULL; } switch (opt) { + case '4': + IPv4or6 = AF_INET; + break; + + case '6': + IPv4or6 = AF_INET6; + break; + case 'n': stdin_null_flag = 1; break; @@ -351,8 +367,10 @@ main(int ac, char **av) break; case 'R': - if (sscanf(optarg, "%hu:%255[^:]:%hu", &fwd_port, buf, - &fwd_host_port) != 3) { + if (sscanf(optarg, "%hu/%255[^/]/%hu", &fwd_port, buf, + &fwd_host_port) != 3 && + sscanf(optarg, "%hu:%255[^:]:%hu", &fwd_port, buf, + &fwd_host_port) != 3) { fprintf(stderr, "Bad forwarding specification '%s'.\n", optarg); usage(); /* NOTREACHED */ @@ -361,8 +379,10 @@ main(int ac, char **av) break; case 'L': - if (sscanf(optarg, "%hu:%255[^:]:%hu", &fwd_port, buf, - &fwd_host_port) != 3) { + if (sscanf(optarg, "%hu/%255[^/]/%hu", &fwd_port, buf, + &fwd_host_port) != 3 && + sscanf(optarg, "%hu:%255[^:]:%hu", &fwd_port, buf, + &fwd_host_port) != 3) { fprintf(stderr, "Bad forwarding specification '%s'.\n", optarg); usage(); /* NOTREACHED */ @@ -473,14 +493,18 @@ main(int ac, char **av) /* Find canonic host name. */ if (strchr(host, '.') == 0) { - struct hostent *hp = gethostbyname(host); - if (hp != 0) { - if (strchr(hp->h_name, '.') != 0) - host = xstrdup(hp->h_name); - else if (hp->h_aliases != 0 - && hp->h_aliases[0] != 0 - && strchr(hp->h_aliases[0], '.') != 0) - host = xstrdup(hp->h_aliases[0]); + struct addrinfo hints; + struct addrinfo *ai = NULL; + int errgai; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_flags = AI_CANONNAME; + hints.ai_socktype = SOCK_STREAM; + errgai = getaddrinfo(host, NULL, &hints, &ai); + if (errgai == 0) { + if (ai->ai_canonname != NULL) + host = xstrdup(ai->ai_canonname); + freeaddrinfo(ai); } } /* Disable rhosts authentication if not running as root. */ @@ -587,7 +611,7 @@ main(int ac, char **av) /* Log into the remote system. This never returns if the login fails. */ ssh_login(host_private_key_loaded, host_private_key, - host, &hostaddr, original_real_uid); + host, (struct sockaddr *)&hostaddr, original_real_uid); /* We no longer need the host private key. Clear it now. */ if (host_private_key_loaded) |