Date: Sun, 15 Oct 2000 13:16:56 +0300 (EEST) From: netch@segfault.kiev.ua (Valentin Nechayev) To: FreeBSD-gnats-submit@freebsd.org Subject: misc/21998: ident only for outgoing connections Message-ID: <200010151016.e9FAGun01111@nn.kiev.ua>
index | next in thread | raw e-mail
>Number: 21998
>Category: misc
>Synopsis: ident only for outgoing connections
>Confidential: no
>Severity: serious
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: change-request
>Submitter-Id: current-users
>Arrival-Date: Sun Oct 15 03:20:01 PDT 2000
>Closed-Date:
>Last-Modified:
>Originator: netch@netch.kiev.ua (Valentin Nechayev)
>Release: FreeBSD 5.0(13)-CURRENT-20001014 i386
>Organization:
private
>Environment:
>Description:
The bugfeature of identd is known (since 1996): anyone can connect to production
service on host running identd and query owner of remote side socket. This
can be used by bad guy to find objects to attack; i.e. nmap scanner uses it.
>How-To-Repeat:
>Fix:
diff -rNu src.orig/sys/kern/uipc_socket2.c src/sys/kern/uipc_socket2.c
--- src.orig/sys/kern/uipc_socket2.c Fri Sep 8 22:21:49 2000
+++ src/sys/kern/uipc_socket2.c Sun Oct 15 12:50:55 2000
@@ -235,7 +235,7 @@
so->so_type = head->so_type;
so->so_options = head->so_options &~ SO_ACCEPTCONN;
so->so_linger = head->so_linger;
- so->so_state = head->so_state | SS_NOFDREF;
+ so->so_state = head->so_state | SS_NOFDREF | SS_ISACCEPTED;
so->so_proto = head->so_proto;
so->so_timeo = head->so_timeo;
so->so_cred = p ? p->p_ucred : head->so_cred;
diff -rNu src.orig/sys/netinet/tcp_subr.c src/sys/netinet/tcp_subr.c
--- src.orig/sys/netinet/tcp_subr.c Sat Sep 30 21:44:07 2000
+++ src/sys/netinet/tcp_subr.c Sun Oct 15 12:49:48 2000
@@ -872,7 +872,9 @@
tcp_pcblist, "S,xtcpcb", "List of active TCP connections");
static int
-tcp_getcred(SYSCTL_HANDLER_ARGS)
+tcp_getcred_common(req, all)
+ struct sysctl_req *req;
+ int all;
{
struct sockaddr_in addrs[2];
struct inpcb *inp;
@@ -891,18 +893,41 @@
error = ENOENT;
goto out;
}
+ if (!all && (inp->inp_socket->so_state & SS_ISACCEPTED)) {
+ error = EPERM;
+ goto out;
+ }
error = SYSCTL_OUT(req, inp->inp_socket->so_cred, sizeof(struct ucred));
out:
splx(s);
return (error);
}
+static int
+tcp_getcred_outgoing(SYSCTL_HANDLER_ARGS)
+{
+ return tcp_getcred_common(req, 0);
+}
+
+SYSCTL_PROC(_net_inet_tcp, OID_AUTO, getcred_outgoing,
+ CTLTYPE_OPAQUE|CTLFLAG_RW,
+ 0, 0, tcp_getcred_outgoing, "S,ucred",
+ "Get the ucred of a TCP connection (outgoing connections only)");
+
+static int
+tcp_getcred_any(SYSCTL_HANDLER_ARGS)
+{
+ return tcp_getcred_common(req, 1);
+}
+
SYSCTL_PROC(_net_inet_tcp, OID_AUTO, getcred, CTLTYPE_OPAQUE|CTLFLAG_RW,
- 0, 0, tcp_getcred, "S,ucred", "Get the ucred of a TCP connection");
+ 0, 0, tcp_getcred_any, "S,ucred", "Get the ucred of a TCP connection");
#ifdef INET6
static int
-tcp6_getcred(SYSCTL_HANDLER_ARGS)
+tcp6_getcred_common(req, all)
+ struct sysctl_req *req;
+ int all;
{
struct sockaddr_in6 addrs[2];
struct inpcb *inp;
@@ -937,6 +962,10 @@
error = ENOENT;
goto out;
}
+ if (!all && (inp->inp_socket->so_state & SS_ISACCEPTED)) {
+ error = EPERM;
+ goto out;
+ }
error = SYSCTL_OUT(req, inp->inp_socket->so_cred,
sizeof(struct ucred));
out:
@@ -944,9 +973,27 @@
return (error);
}
+static int
+tcp6_getcred_outgoing(SYSCTL_HANDLER_ARGS)
+{
+ return tcp6_getcred_common(req, 0);
+}
+
+SYSCTL_PROC(_net_inet6_tcp6, OID_AUTO, getcred_outgoing,
+ CTLTYPE_OPAQUE|CTLFLAG_RW,
+ 0, 0,
+ tcp6_getcred_outgoing, "S,ucred",
+ "Get the ucred of a TCP6 connection (outgoing only)");
+
+static int
+tcp6_getcred_any(SYSCTL_HANDLER_ARGS)
+{
+ return tcp6_getcred_common(req, 1);
+}
+
SYSCTL_PROC(_net_inet6_tcp6, OID_AUTO, getcred, CTLTYPE_OPAQUE|CTLFLAG_RW,
0, 0,
- tcp6_getcred, "S,ucred", "Get the ucred of a TCP6 connection");
+ tcp6_getcred_any, "S,ucred", "Get the ucred of a TCP6 connection");
#endif
diff -rNu src.orig/sys/sys/socketvar.h src/sys/sys/socketvar.h
--- src.orig/sys/sys/socketvar.h Fri Sep 8 22:22:38 2000
+++ src/sys/sys/socketvar.h Sun Oct 15 12:49:17 2000
@@ -131,6 +131,7 @@
#define SS_CANTSENDMORE 0x0010 /* can't send more data to peer */
#define SS_CANTRCVMORE 0x0020 /* can't receive more data from peer */
#define SS_RCVATMARK 0x0040 /* at mark on input */
+#define SS_ISACCEPTED 0x0080 /* obtained from accept() */
#define SS_NBIO 0x0100 /* non-blocking ops */
#define SS_ASYNC 0x0200 /* async i/o notify */
diff -rNu src.orig/usr.sbin/inetd/builtins.c src/usr.sbin/inetd/builtins.c
--- src.orig/usr.sbin/inetd/builtins.c Sun Oct 15 00:44:36 2000
+++ src/usr.sbin/inetd/builtins.c Sun Oct 15 12:59:11 2000
@@ -352,6 +352,7 @@
ssize_t ssize;
size_t size, bufsiz;
int c, fflag = 0, nflag = 0, rflag = 0, argc = 0, usedfallback = 0;
+ int getcred_all = 0;
int gflag = 0, getcredfail = 0, onreadlen;
u_short lport, fport;
@@ -374,8 +375,11 @@
size_t i;
u_int32_t random;
- while ((c = getopt(argc, sep->se_argv, "d:fgno:rt:")) != -1)
+ while ((c = getopt(argc, sep->se_argv, "ad:fgno:rt:")) != -1)
switch (c) {
+ case 'a':
+ getcred_all = 1;
+ break;
case 'd':
fallback = optarg;
break;
@@ -526,7 +530,9 @@
sin[0].sin_port = htons(lport);
sin[1] = *(struct sockaddr_in *)&ss[1];
sin[1].sin_port = htons(fport);
- if (sysctlbyname("net.inet.tcp.getcred", &uc, &size, sin,
+ if (sysctlbyname(getcred_all ? "net.inet.tcp.getcred" :
+ "net.inet.tcp.getcred_outgoing",
+ &uc, &size, sin,
sizeof(sin)) == -1)
getcredfail = 1;
break;
@@ -536,7 +542,9 @@
sin6[0].sin6_port = htons(lport);
sin6[1] = *(struct sockaddr_in6 *)&ss[1];
sin6[1].sin6_port = htons(fport);
- if (sysctlbyname("net.inet6.tcp6.getcred", &uc, &size, sin6,
+ if (sysctlbyname(getcred_all ? "net.inet6.tcp6.getcred" :
+ "net.inet6.tcp6.getcred_outgoing",
+ &uc, &size, sin6,
sizeof(sin6)) == -1)
getcredfail = 1;
break;
diff -rNu src.orig/usr.sbin/inetd/inetd.8 src/usr.sbin/inetd/inetd.8
--- src.orig/usr.sbin/inetd/inetd.8 Sun Aug 13 00:46:18 2000
+++ src/usr.sbin/inetd/inetd.8 Sun Oct 15 13:09:15 2000
@@ -438,6 +438,9 @@
.Dq ERROR\ : HIDDEN-USER .
The available arguments to this service that alter its behavior are:
.Bl -tag -width indent
+.It Fl a
+Provide owner information for any connection, not only outgoing. By default,
+ident does not provide information for incoming connections.
.It Fl d Ar fallback
Provide a
.Ar fallback
>Release-Note:
>Audit-Trail:
>Unformatted:
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200010151016.e9FAGun01111>
