Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 10 Jan 2001 10:57:36 +0000
From:      David Malone <dwmalone@maths.tcd.ie>
To:        freebsd-net@freebsd.org
Cc:        netch@segfault.kiev.ua, green@freebsd.org, dwmalone@maths.tcd.ie
Subject:   PR 21998 - outgoing ident. 
Message-ID:   <200101101057.aa49553@salmon.maths.tcd.ie>

next in thread | raw e-mail | index | archive | help
In light of the chat on bugtraq about using ident services "backwards"
to find out who daemons are running as, I had a look at PR 21998:

	http://www.FreeBSD.org/cgi/query-pr.cgi?pr=21998

I've read through and tested the patch, and is seems like a reasonable
idea.  Basically, it adds a flag to sockets which have been created
via an accept() and then adds a new getcred_outgoing sysctl which
works just like getcred but returns EPERM it is not a outgoing
socket.

I've run the patch by Brian Feldman, who has no objections, but
suggested that I check the socket changes with people on freebsd-net.
The patch below is an slightly updated version of that in the PR.

	David.


Index: src/sys/kern/uipc_socket2.c
===================================================================
RCS file: /cvs/FreeBSD-CVS/src/sys/kern/uipc_socket2.c,v
retrieving revision 1.66
diff -u -r1.66 uipc_socket2.c
--- src/sys/kern/uipc_socket2.c	2000/11/19 22:22:47	1.66
+++ src/sys/kern/uipc_socket2.c	2001/01/09 22:19:57
@@ -235,7 +236,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;
Index: src/sys/netinet/tcp_subr.c
===================================================================
RCS file: /cvs/FreeBSD-CVS/src/sys/netinet/tcp_subr.c,v
retrieving revision 1.86
diff -u -r1.86 tcp_subr.c
--- src/sys/netinet/tcp_subr.c	2000/12/24 10:57:21	1.86
+++ src/sys/netinet/tcp_subr.c	2001/01/09 22:19:57
@@ -891,7 +891,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;
@@ -910,18 +912,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;
@@ -956,6 +981,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:
@@ -963,9 +992,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
 
 
Index: src/sys/sys/socketvar.h
===================================================================
RCS file: /cvs/FreeBSD-CVS/src/sys/sys/socketvar.h,v
retrieving revision 1.54
diff -u -r1.54 socketvar.h
--- src/sys/sys/socketvar.h	2000/12/31 10:23:24	1.54
+++ src/sys/sys/socketvar.h	2001/01/09 22:19:57
@@ -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 */
Index: src/usr.sbin/inetd/builtins.c
===================================================================
RCS file: /cvs/FreeBSD-CVS/src/usr.sbin/inetd/builtins.c,v
retrieving revision 1.29
diff -u -r1.29 builtins.c
--- src/usr.sbin/inetd/builtins.c	2000/12/05 13:56:01	1.29
+++ src/usr.sbin/inetd/builtins.c	2001/01/09 22:53:03
@@ -351,7 +351,7 @@
 	ssize_t ssize;
 	size_t size, bufsiz;
 	int c, fflag = 0, nflag = 0, rflag = 0, argc = 0, usedfallback = 0;
-	int gflag = 0, Fflag = 0, getcredfail = 0, onreadlen;
+	int aflag = 0, gflag = 0, Fflag = 0, getcredfail = 0, onreadlen;
 	u_short lport, fport;
 
 	inetd_setproctitle(sep->se_service, s);
@@ -373,8 +373,11 @@
 		size_t i;
 		u_int32_t random;
 
-		while ((c = getopt(argc, sep->se_argv, "d:fFgno:rt:")) != -1)
+		while ((c = getopt(argc, sep->se_argv, "ad:fFgno:rt:")) != -1)
 			switch (c) {
+			case 'a':
+				aflag = 1;
+				break;
 			case 'd':
 				fallback = optarg;
 				break;
@@ -530,7 +533,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(aflag ? "net.inet.tcp.getcred" :
+					"net.inet.tcp.getcred_outgoing",
+				&uc, &size, sin,
 				 sizeof(sin)) == -1)
 			getcredfail = errno;
 		break;
@@ -540,7 +545,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(aflag ? "net.inet6.tcp6.getcred" :
+					"net.inet6.tcp6.getcred_outgoing",
+				&uc, &size, sin6,
 				 sizeof(sin6)) == -1)
 			getcredfail = errno;
 		break;
Index: src/usr.sbin/inetd/inetd.8
===================================================================
RCS file: /cvs/FreeBSD-CVS/src/usr.sbin/inetd/inetd.8,v
retrieving revision 1.55
diff -u -r1.55 inetd.8
--- src/usr.sbin/inetd/inetd.8	2000/12/27 15:30:04	1.55
+++ src/usr.sbin/inetd/inetd.8	2001/01/09 22:29:21
@@ -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
+By default, ident only provides information for outgoing connections.
+This flag causes information to be provided for all connections.
 .It Fl d Ar fallback
 Provide a
 .Ar fallback


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-net" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi? <200101101057.aa49553>