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>