diff options
author | shin <shin@FreeBSD.org> | 2000-01-25 14:52:10 +0000 |
---|---|---|
committer | shin <shin@FreeBSD.org> | 2000-01-25 14:52:10 +0000 |
commit | fc29f7bcf7236935ba5c171ea553ac7dca533e8c (patch) | |
tree | 13e93b815761d57bc661099e5a2b7bcb2882b762 /libexec | |
parent | 4497b0fbabcff52472040173a4ea879ec212ecaa (diff) | |
download | FreeBSD-src-fc29f7bcf7236935ba5c171ea553ac7dca533e8c.zip FreeBSD-src-fc29f7bcf7236935ba5c171ea553ac7dca533e8c.tar.gz |
several tcp apps IPv6 update
-inetd
-rshd
-rlogind
-telnetd
-rsh
-rlogin
Reviewed by: freebsd-arch, cvs-committers
Obtained from: KAME project
Diffstat (limited to 'libexec')
-rw-r--r-- | libexec/rlogind/Makefile | 2 | ||||
-rw-r--r-- | libexec/rlogind/rlogind.8 | 2 | ||||
-rw-r--r-- | libexec/rlogind/rlogind.c | 85 | ||||
-rw-r--r-- | libexec/rshd/Makefile | 3 | ||||
-rw-r--r-- | libexec/rshd/rshd.8 | 2 | ||||
-rw-r--r-- | libexec/rshd/rshd.c | 83 | ||||
-rw-r--r-- | libexec/telnetd/Makefile | 1 | ||||
-rw-r--r-- | libexec/telnetd/telnetd.8 | 2 | ||||
-rw-r--r-- | libexec/telnetd/telnetd.c | 88 |
9 files changed, 192 insertions, 76 deletions
diff --git a/libexec/rlogind/Makefile b/libexec/rlogind/Makefile index bae4a4b..f22df18 100644 --- a/libexec/rlogind/Makefile +++ b/libexec/rlogind/Makefile @@ -6,7 +6,7 @@ SRCS= rlogind.c MAN8= rlogind.8 DPADD= ${LIBUTIL} LDADD= -lutil -CFLAGS+= -Wall +CFLAGS+= -Wall -DINET6 .if defined(NOPAM) CFLAGS+= -DNO_PAM diff --git a/libexec/rlogind/rlogind.8 b/libexec/rlogind/rlogind.8 index 14d7a93..969fb08 100644 --- a/libexec/rlogind/rlogind.8 +++ b/libexec/rlogind/rlogind.8 @@ -204,3 +204,5 @@ The .Nm command appeared in .Bx 4.2 . +.Pp +IPv6 support was added by WIDE/KAME project.
\ No newline at end of file diff --git a/libexec/rlogind/rlogind.c b/libexec/rlogind/rlogind.c index 111a56b..817f6c8 100644 --- a/libexec/rlogind/rlogind.c +++ b/libexec/rlogind/rlogind.c @@ -91,6 +91,11 @@ static const char rcsid[] = #define ARGSTR "Dalnx" +/* wrapper for KAME-special getnameinfo() */ +#ifndef NI_WITHSCOPEID +#define NI_WITHSCOPEID 0 +#endif + char *env[2]; #define NMAX 30 char lusername[NMAX+1], rusername[NMAX+1]; @@ -102,12 +107,25 @@ int no_delay; struct passwd *pwd; -void doit __P((int, struct sockaddr_in *)); +union sockunion { + struct sockinet { + u_char si_len; + u_char si_family; + u_short si_port; + } su_si; + struct sockaddr_in su_sin; + struct sockaddr_in6 su_sin6; +}; +#define su_len su_si.si_len +#define su_family su_si.si_family +#define su_port su_si.si_port + +void doit __P((int, union sockunion *)); int control __P((int, char *, int)); void protocol __P((int, int)); void cleanup __P((int)); void fatal __P((int, char *, int)); -int do_rlogin __P((struct sockaddr_in *)); +int do_rlogin __P((union sockunion *)); void getstr __P((char *, int, char *)); void setup_term __P((int)); int do_krb_login __P((struct sockaddr_in *)); @@ -123,7 +141,7 @@ main(argc, argv) char *argv[]; { extern int __check_rhosts_file; - struct sockaddr_in from; + union sockunion from; int ch, fromlen, on; openlog("rlogind", LOG_PID | LOG_CONS, LOG_AUTH); @@ -168,9 +186,12 @@ main(argc, argv) if (no_delay && setsockopt(0, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) < 0) syslog(LOG_WARNING, "setsockopt (TCP_NODELAY): %m"); + if (from.su_family == AF_INET) + { on = IPTOS_LOWDELAY; if (setsockopt(0, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0) syslog(LOG_WARNING, "setsockopt (IP_TOS): %m"); + } doit(0, &from); return 0; @@ -187,11 +208,12 @@ struct winsize win = { 0, 0, 0, 0 }; void doit(f, fromp) int f; - struct sockaddr_in *fromp; + union sockunion *fromp; { int master, pid, on = 1; int authenticated = 0; - char hostname[MAXHOSTNAMELEN]; + char hostname[2 * MAXHOSTNAMELEN + 1]; + char nameinfo[2 * INET6_ADDRSTRLEN + 1]; char c; alarm(60); @@ -201,20 +223,33 @@ doit(f, fromp) exit(1); alarm(0); - fromp->sin_port = ntohs((u_short)fromp->sin_port); - realhostname(hostname, sizeof(hostname) - 1, &fromp->sin_addr); + + realhostname_sa(hostname, sizeof(hostname) - 1, + (struct sockaddr *)fromp, fromp->su_len); + /* error check ? */ + fromp->su_port = ntohs((u_short)fromp->su_port); hostname[sizeof(hostname) - 1] = '\0'; { - if (fromp->sin_family != AF_INET || - fromp->sin_port >= IPPORT_RESERVED || - fromp->sin_port < IPPORT_RESERVED/2) { + if ((fromp->su_family != AF_INET && +#ifdef INET6 + fromp->su_family != AF_INET6 +#endif + ) || + fromp->su_port >= IPPORT_RESERVED || + fromp->su_port < IPPORT_RESERVED/2) { + getnameinfo((struct sockaddr *)fromp, + fromp->su_len, + nameinfo, sizeof(nameinfo), NULL, 0, + NI_NUMERICHOST|NI_WITHSCOPEID); + /* error check ? */ syslog(LOG_NOTICE, "Connection from %s on illegal port", - inet_ntoa(fromp->sin_addr)); + nameinfo); fatal(f, "Permission denied", 0); } #ifdef IP_OPTIONS - { + if (fromp->su_family == AF_INET) + { u_char optbuf[BUFSIZ/3]; int optsize = sizeof(optbuf), ipproto, i; struct protoent *ip; @@ -230,7 +265,7 @@ doit(f, fromp) if (c == IPOPT_LSRR || c == IPOPT_SSRR) { syslog(LOG_NOTICE, "Connection refused from %s with IP option %s", - inet_ntoa(fromp->sin_addr), + inet_ntoa(fromp->su_sin.sin_addr), c == IPOPT_LSRR ? "LSRR" : "SSRR"); exit(1); } @@ -239,7 +274,7 @@ doit(f, fromp) i += (c == IPOPT_NOP) ? 1 : optbuf[i+1]; } } - } + } #endif if (do_rlogin(fromp) == 0) authenticated++; @@ -533,9 +568,11 @@ fatal(f, msg, syserr) int do_rlogin(dest) - struct sockaddr_in *dest; + union sockunion *dest; { int retval; + int af; + char *addr; getstr(rusername, sizeof(rusername), "remuser too long"); getstr(lusername, sizeof(lusername), "locuser too long"); @@ -559,8 +596,22 @@ do_rlogin(dest) if (pwd == NULL) return (-1); /* XXX why don't we syslog() failure? */ - return (iruserok(dest->sin_addr.s_addr, pwd->pw_uid == 0, - rusername, lusername)); + + af = dest->su_family; + switch (af) { + case AF_INET: + addr = (char *)&dest->su_sin.sin_addr; + break; +#ifdef INET6 + case AF_INET6: + addr = (char *)&dest->su_sin6.sin6_addr; + break; +#endif + default: + return -1; /*EAFNOSUPPORT*/ + } + + return (iruserok_af(addr, pwd->pw_uid == 0, rusername, lusername, af)); } void diff --git a/libexec/rshd/Makefile b/libexec/rshd/Makefile index 2005122..ca0d155 100644 --- a/libexec/rshd/Makefile +++ b/libexec/rshd/Makefile @@ -19,6 +19,9 @@ CFLAGS+=-DLOGIN_CAP -Wall DPADD+= ${LIBUTIL} LDADD+= -lutil +# IPv6 support +CFLAGS+= -DINET6 + .include <bsd.prog.mk> .PATH: ${.CURDIR}/../rlogind diff --git a/libexec/rshd/rshd.8 b/libexec/rshd/rshd.8 index 80cdbc1..cba4482 100644 --- a/libexec/rshd/rshd.8 +++ b/libexec/rshd/rshd.8 @@ -250,3 +250,5 @@ A facility to allow all data exchanges to be encrypted should be present. .Pp A more extensible protocol (such as Telnet) should be used. +.Sh HISTORY +IPv6 support was added by WIDE/KAME project. diff --git a/libexec/rshd/rshd.c b/libexec/rshd/rshd.c index 8533644..54fa4a6 100644 --- a/libexec/rshd/rshd.c +++ b/libexec/rshd/rshd.c @@ -80,6 +80,11 @@ static const char rcsid[] = #include <login_cap.h> #endif +/* wrapper for KAME-special getnameinfo() */ +#ifndef NI_WITHSCOPEID +#define NI_WITHSCOPEID 0 +#endif + int keepalive = 1; int log_success; /* If TRUE, log all successful accesses */ int sent_null; @@ -88,7 +93,20 @@ int no_delay; int doencrypt = 0; #endif -void doit __P((struct sockaddr_in *)); +union sockunion { + struct sockinet { + u_char si_len; + u_char si_family; + u_short si_port; + } su_si; + struct sockaddr_in su_sin; + struct sockaddr_in6 su_sin6; +}; +#define su_len su_si.si_len +#define su_family su_si.si_family +#define su_port su_si.si_port + +void doit __P((union sockunion *)); void error __P((const char *, ...)); void getstr __P((char *, int, char *)); int local_domain __P((char *)); @@ -109,7 +127,7 @@ main(argc, argv) extern int __check_rhosts_file; struct linger linger; int ch, on = 1, fromlen; - struct sockaddr_in from; + struct sockaddr_storage from; openlog("rshd", LOG_PID | LOG_ODELAY, LOG_DAEMON); @@ -169,7 +187,7 @@ main(argc, argv) if (no_delay && setsockopt(0, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) < 0) syslog(LOG_WARNING, "setsockopt (TCP_NODELAY): %m"); - doit(&from); + doit((union sockunion *)&from); /* NOTREACHED */ return(0); } @@ -184,7 +202,7 @@ char **environ; void doit(fromp) - struct sockaddr_in *fromp; + union sockunion *fromp; { extern char *__rcmd_errstr; /* syslog hook from libc/net/rcmd.c. */ struct passwd *pwd; @@ -195,7 +213,9 @@ doit(fromp) char *errorstr; char *cp, sig, buf[BUFSIZ]; char cmdbuf[NCARGS+1], locuser[16], remuser[16]; - char fromhost[MAXHOSTNAMELEN]; + char fromhost[2 * MAXHOSTNAMELEN + 1]; + char numericname[INET6_ADDRSTRLEN]; + int af = fromp->su_family, err; int retval; #ifdef CRYPT int rc; @@ -216,14 +236,21 @@ doit(fromp) } } #endif - fromp->sin_port = ntohs((u_short)fromp->sin_port); - if (fromp->sin_family != AF_INET) { - syslog(LOG_ERR, "malformed \"from\" address (af %d)", - fromp->sin_family); + fromp->su_port = ntohs((u_short)fromp->su_port); + if (af != AF_INET +#ifdef INET6 + && af != AF_INET6 +#endif + ) { + syslog(LOG_ERR, "malformed \"from\" address (af %d)\n", af); exit(1); } + err = getnameinfo((struct sockaddr *)fromp, fromp->su_len, numericname, + sizeof(numericname), NULL, 0, + NI_NUMERICHOST|NI_WITHSCOPEID); + /* XXX: do 'err' check */ #ifdef IP_OPTIONS - { + if (af == AF_INET) { u_char optbuf[BUFSIZ/3]; int optsize = sizeof(optbuf), ipproto, i; struct protoent *ip; @@ -239,7 +266,7 @@ doit(fromp) if (c == IPOPT_LSRR || c == IPOPT_SSRR) { syslog(LOG_NOTICE, "connection refused from %s with IP option %s", - inet_ntoa(fromp->sin_addr), + numericname, c == IPOPT_LSRR ? "LSRR" : "SSRR"); exit(1); } @@ -251,12 +278,12 @@ doit(fromp) } #endif - if (fromp->sin_port >= IPPORT_RESERVED || - fromp->sin_port < IPPORT_RESERVED/2) { + if (fromp->su_port >= IPPORT_RESERVED || + fromp->su_port < IPPORT_RESERVED/2) { syslog(LOG_NOTICE|LOG_AUTH, "connection from %s on illegal port %u", - inet_ntoa(fromp->sin_addr), - fromp->sin_port); + numericname, + fromp->su_port); exit(1); } @@ -279,7 +306,7 @@ doit(fromp) (void) alarm(0); if (port != 0) { int lport = IPPORT_RESERVED - 1; - s = rresvport(&lport); + s = rresvport_af(&lport, af); if (s < 0) { syslog(LOG_ERR, "can't get stderr port: %m"); exit(1); @@ -288,11 +315,11 @@ doit(fromp) port < IPPORT_RESERVED/2) { syslog(LOG_NOTICE|LOG_AUTH, "2nd socket from %s on unreserved port %u", - inet_ntoa(fromp->sin_addr), + numericname, port); exit(1); } - fromp->sin_port = htons(port); + fromp->su_port = htons(port); if (connect(s, (struct sockaddr *)fromp, sizeof (*fromp)) < 0) { syslog(LOG_INFO, "connect second port %d: %m", port); exit(1); @@ -300,11 +327,13 @@ doit(fromp) } errorstr = NULL; - realhostname(fromhost, sizeof(fromhost) - 1, &fromp->sin_addr); + realhostname_sa(fromhost, sizeof(fromhost) - 1, + (struct sockaddr *)fromp, + fromp->su_len); fromhost[sizeof(fromhost) - 1] = '\0'; #ifdef CRYPT - if (doencrypt) { + if (doencrypt && af == AF_INET) { struct sockaddr_in local_addr; rc = sizeof(local_addr); if (getsockname(0, (struct sockaddr *)&local_addr, @@ -379,8 +408,14 @@ doit(fromp) if (errorstr || (pwd->pw_expire && time(NULL) >= pwd->pw_expire) || (pwd->pw_passwd != 0 && *pwd->pw_passwd != '\0' && - iruserok(fromp->sin_addr.s_addr, pwd->pw_uid == 0, - remuser, locuser) < 0)) { + iruserok_af( +#ifdef INET6 + (af == AF_INET6) + ? (void *)&fromp->su_sin6.sin6_addr : +#endif + (void *)&fromp->su_sin.sin_addr, + pwd->pw_uid == 0, + remuser, locuser, af) < 0)) { if (__rcmd_errstr) syslog(LOG_INFO|LOG_AUTH, "%s@%s as %s: permission denied (%s). cmd='%.80s'", @@ -402,10 +437,10 @@ fail: exit(1); } #ifdef LOGIN_CAP - if (lc != NULL) { + if (lc != NULL && fromp->su_family == AF_INET) { /*XXX*/ char remote_ip[MAXHOSTNAMELEN]; - strncpy(remote_ip, inet_ntoa(fromp->sin_addr), + strncpy(remote_ip, numericname, sizeof(remote_ip) - 1); remote_ip[sizeof(remote_ip) - 1] = 0; if (!auth_hostok(lc, fromhost, remote_ip)) { diff --git a/libexec/telnetd/Makefile b/libexec/telnetd/Makefile index 068087a..7766276 100644 --- a/libexec/telnetd/Makefile +++ b/libexec/telnetd/Makefile @@ -6,6 +6,7 @@ CFLAGS+=-DLINEMODE -DUSE_TERMIO -DDIAGNOSTICS #CFLAGS+=-DKLUDGELINEMODE CFLAGS+=-DOLD_ENVIRON -DENV_HACK CFLAGS+=-I${.CURDIR}/../../lib +CFLAGS+=-DINET6 SRCS= global.c slc.c state.c sys_term.c telnetd.c \ termstat.c utility.c DPADD= ${LIBUTIL} ${LIBTERMCAP} ${LIBTELNET} diff --git a/libexec/telnetd/telnetd.8 b/libexec/telnetd/telnetd.8 index a2973ef..06e98f9 100644 --- a/libexec/telnetd/telnetd.8 +++ b/libexec/telnetd/telnetd.8 @@ -623,3 +623,5 @@ never sends .Tn TELNET .Dv IAC GA (go ahead) commands. +.Sh HISTORY +IPv6 support was added by WIDE/KAME project.
\ No newline at end of file diff --git a/libexec/telnetd/telnetd.c b/libexec/telnetd/telnetd.c index 5141c2a..57a972a 100644 --- a/libexec/telnetd/telnetd.c +++ b/libexec/telnetd/telnetd.c @@ -71,6 +71,12 @@ static const char rcsid[] = #include <sys/secparm.h> #include <sys/usrv.h> # endif /* SO_SEC_MULTI */ + +/* wrapper for KAME-special getnameinfo() */ +#ifndef NI_WITHSCOPEID +#define NI_WITHSCOPEID 0 +#endif + int secflag; char tty_dev[16]; struct secdev dv; @@ -137,7 +143,7 @@ int debug = 0; int keepalive = 1; char *altlogin; -void doit __P((struct sockaddr_in *)); +void doit __P((struct sockaddr *)); int terminaltypeok __P((char *)); void startslave __P((char *, int, char *)); extern void usage P((void)); @@ -149,6 +155,7 @@ extern void usage P((void)); */ char valid_opts[] = { 'd', ':', 'h', 'k', 'n', 'p', ':', 'S', ':', 'u', ':', 'U', + '4', '6', #ifdef AUTHENTICATION 'a', ':', 'X', ':', #endif @@ -173,11 +180,13 @@ char valid_opts[] = { '\0' }; - int +int family = AF_INET; + +int main(argc, argv) char *argv[]; { - struct sockaddr_in from; + struct sockaddr_storage from; int on = 1, fromlen; register int ch; #if defined(IPPROTO_IP) && defined(IP_TOS) @@ -381,6 +390,16 @@ main(argc, argv) break; #endif /* AUTHENTICATION */ + case '4': + family = AF_INET; + break; + +#ifdef INET6 + case '6': + family = AF_INET6; + break; +#endif + default: warnx("%c: unknown option", ch); /* FALLTHROUGH */ @@ -394,43 +413,41 @@ main(argc, argv) argv += optind; if (debug) { - int s, ns, foo; - struct servent *sp; - static struct sockaddr_in sin = { AF_INET }; + int s, ns, foo, error; + char *service = "telnet"; + struct addrinfo hints, *res; if (argc > 1) { usage(); /* NOT REACHED */ - } else if (argc == 1) { - if ((sp = getservbyname(*argv, "tcp"))) { - sin.sin_port = sp->s_port; - } else { - sin.sin_port = atoi(*argv); - if ((int)sin.sin_port <= 0) { - warnx("%s: bad port #", *argv); - usage(); - /* NOT REACHED */ - } - sin.sin_port = htons((u_short)sin.sin_port); - } - } else { - sp = getservbyname("telnet", "tcp"); - if (sp == 0) - errx(1, "tcp/telnet: unknown service"); - sin.sin_port = sp->s_port; + } else if (argc == 1) + service = *argv; + + memset(&hints, 0, sizeof(hints)); + hints.ai_flags = AI_PASSIVE; + hints.ai_family = family; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = 0; + error = getaddrinfo(NULL, service, &hints, &res); + + if (error) { + errx(1, "tcp/%s: %s\n", service, gai_strerror(error)); + if (error == EAI_SYSTEM) + errx(1, "tcp/%s: %s\n", service, strerror(errno)); + usage(); } - s = socket(AF_INET, SOCK_STREAM, 0); + s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (s < 0) err(1, "socket"); (void) setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)); - if (bind(s, (struct sockaddr *)&sin, sizeof sin) < 0) + if (bind(s, res->ai_addr, res->ai_addrlen) < 0) err(1, "bind"); if (listen(s, 1) < 0) err(1, "listen"); - foo = sizeof sin; - ns = accept(s, (struct sockaddr *)&sin, &foo); + foo = res->ai_addrlen; + ns = accept(s, res->ai_addr, &foo); if (ns < 0) err(1, "accept"); (void) dup2(ns, 0); @@ -512,7 +529,7 @@ main(argc, argv) } #if defined(IPPROTO_IP) && defined(IP_TOS) - { + if (from.ss_family == AF_INET) { # if defined(HAS_GETTOS) struct tosent *tp; if (tos < 0 && (tp = gettosbyname("telnet", "tcp"))) @@ -528,7 +545,7 @@ main(argc, argv) } #endif /* defined(IPPROTO_IP) && defined(IP_TOS) */ net = 0; - doit(&from); + doit((struct sockaddr *)&from); /* NOTREACHED */ return(0); } /* end of main */ @@ -773,8 +790,9 @@ char user_name[256]; */ void doit(who) - struct sockaddr_in *who; + struct sockaddr *who; { + int err; int ptynum; /* @@ -817,16 +835,18 @@ doit(who) #endif /* _SC_CRAY_SECURE_SYS */ /* get name of connected client */ - if (realhostname(remote_hostname, sizeof(remote_hostname) - 1, - &who->sin_addr) == HOSTNAME_INVALIDADDR && registerd_host_only) + if (realhostname_sa(remote_hostname, sizeof(remote_hostname) - 1, + who, who->sa_len) == HOSTNAME_INVALIDADDR && registerd_host_only) fatal(net, "Couldn't resolve your address into a host name.\r\n\ Please contact your net administrator"); remote_hostname[sizeof(remote_hostname) - 1] = '\0'; trimdomain(remote_hostname, UT_HOSTSIZE); if (!isdigit(remote_hostname[0]) && strlen(remote_hostname) > utmp_len) - strncpy(remote_hostname, inet_ntoa(who->sin_addr), - sizeof(remote_hostname) - 1); + err = getnameinfo(who, who->sa_len, remote_hostname, + sizeof(remote_hostname), NULL, 0, + NI_NUMERICHOST|NI_WITHSCOPEID); + /* XXX: do 'err' check */ (void) gethostname(host_name, sizeof(host_name) - 1); host_name[sizeof(host_name) - 1] = '\0'; |