Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/libexec/identd Add forward/proxy support to identd(8).



details:   https://anonhg.NetBSD.org/src/rev/1bffcc31fcab
branches:  trunk
changeset: 579987:1bffcc31fcab
user:      peter <peter%NetBSD.org@localhost>
date:      Sun Apr 03 22:15:32 2005 +0000

description:
Add forward/proxy support to identd(8).

Approved by christos.

diffstat:

 libexec/identd/Makefile |   19 +-
 libexec/identd/identd.8 |   51 +++++-
 libexec/identd/identd.c |  409 ++++++++++++++++++++++++++++++++++++++++-------
 libexec/identd/identd.h |   27 +++
 libexec/identd/ipf.c    |   97 +++++++++++
 libexec/identd/pf.c     |  101 +++++++++++
 6 files changed, 637 insertions(+), 67 deletions(-)

diffs (truncated from 1025 to 300 lines):

diff -r 1927c92fb6a7 -r 1bffcc31fcab libexec/identd/Makefile
--- a/libexec/identd/Makefile   Sun Apr 03 21:38:44 2005 +0000
+++ b/libexec/identd/Makefile   Sun Apr 03 22:15:32 2005 +0000
@@ -1,7 +1,22 @@
-# $NetBSD: Makefile,v 1.10 2004/01/31 21:47:17 christos Exp $
+# $NetBSD: Makefile,v 1.11 2005/04/03 22:15:32 peter Exp $
+
+.include <bsd.own.mk>
 
-WARNS=3
+WARNS= 4
 PROG=  identd
+SRCS=  identd.c
 MAN=   identd.8
 
+# Build with IP Filter support?
+.if (${MKIPFILTER} != "no")
+SRCS+= ipf.c
+CPPFLAGS+=-I${NETBSDSRCDIR}/sys/dist/ipf -DWITH_IPF
+.endif
+
+# Build with pf support?
+.if (${MKPF} != "no")
+SRCS+= pf.c
+CPPFLAGS+=-DWITH_PF
+.endif
+
 .include <bsd.prog.mk>
diff -r 1927c92fb6a7 -r 1bffcc31fcab libexec/identd/identd.8
--- a/libexec/identd/identd.8   Sun Apr 03 21:38:44 2005 +0000
+++ b/libexec/identd/identd.8   Sun Apr 03 22:15:32 2005 +0000
@@ -1,9 +1,9 @@
-.\" $NetBSD: identd.8,v 1.18 2004/01/31 22:39:24 wiz Exp $
+.\" $NetBSD: identd.8,v 1.19 2005/04/03 22:15:32 peter Exp $
 .\"
 .\" This software is in the public domain.
-.\" Written by Peter Postma <peter%pointless.nl@localhost>
+.\" Written by Peter Postma <peter%NetBSD.org@localhost>
 .\"
-.Dd January 31, 2004
+.Dd March 22, 2005
 .Dt IDENTD 8
 .Os
 .Sh NAME
@@ -18,7 +18,9 @@
 .Op Fl f Ar fallback
 .Op Fl g Ar uid
 .Op Fl L Ar username
+.Op Fl m Ar filter
 .Op Fl o Ar osname
+.Op Fl P Ar address
 .Op Fl p Ar portno
 .Op Fl t Ar seconds
 .Op Fl u Ar uid
@@ -95,7 +97,8 @@
 .Ar fallback
 username.
 If the lookup fails then this username will be returned.
-This can be useful for when running this service on a NAT host.
+This can be useful for when running this service on a NAT host and
+not using the forward/proxy functionality.
 .It Fl g Ar gid
 Specify the group id number or name which the server should switch to after
 binding itself to the TCP/IP port.
@@ -122,6 +125,40 @@
 Use
 .Xr syslogd 8
 for logging.
+.It Fl m Ar filter
+Enables forwarding of ident queries.
+The
+.Ar filter
+argument specifies which packet filter should be used to lookup the
+connections, currently
+.Sq pf
+and
+.Sq ipfilter
+are supported packet filters.
+Note that
+.Nm
+changes the ident queries to use the local port on the NAT host instead of
+the local port on the forwarding host.
+This is needed because otherwise we can't do a lookup on the proxy host.
+On the proxy host,
+.Dq proxy mode
+should be enabled with the
+.Fl P
+flag or
+.Dq lying mode
+with the
+.Fl L
+flag.
+.Nm
+will need access to
+.Pa /etc/pf
+or
+.Pa /etc/ipnat
+so you either need to run
+.Nm
+under root or adjust group owner/permissions to the device(s) and run
+.Nm
+under that group.
 .It Fl N
 Enable
 .Pa .noident
@@ -136,6 +173,12 @@
 .Ar osname
 instead of the default
 .Dq UNIX .
+.It Fl P Ar address
+Specify a proxy server which will be used to receive proxied ident
+queries from.
+See also the
+.Fl m
+flag how this operates.
 .It Fl p Ar portno
 Specify an alternative port number under which the server should run.
 The default is port 113.
diff -r 1927c92fb6a7 -r 1bffcc31fcab libexec/identd/identd.c
--- a/libexec/identd/identd.c   Sun Apr 03 21:38:44 2005 +0000
+++ b/libexec/identd/identd.c   Sun Apr 03 22:15:32 2005 +0000
@@ -1,10 +1,10 @@
-/* $NetBSD: identd.c,v 1.25 2005/03/11 15:49:52 peter Exp $ */
+/* $NetBSD: identd.c,v 1.26 2005/04/03 22:15:32 peter Exp $ */
 
 /*
  * identd.c - TCP/IP Ident protocol server.
  *
  * This software is in the public domain.
- * Written by Peter Postma <peter%pointless.nl@localhost>
+ * Written by Peter Postma <peter%NetBSD.org@localhost>
  */
 
 #include <sys/types.h>
@@ -38,19 +38,26 @@
 #include <syslog.h>
 #include <unistd.h>
 
-__RCSID("$NetBSD: identd.c,v 1.25 2005/03/11 15:49:52 peter Exp $");
+#include "identd.h"
+
+__RCSID("$NetBSD: identd.c,v 1.26 2005/04/03 22:15:32 peter Exp $");
 
 #define OPSYS_NAME     "UNIX"
 #define IDENT_SERVICE  "auth"
 #define TIMEOUT                30      /* seconds */
 
 static int   idhandle(int, const char *, const char *, const char *,
-               const char *, int);
+               const char *, struct sockaddr *, int);
 static void  idparse(int, int, int, const char *, const char *, const char *);
 static void  iderror(int, int, int, const char *);
-static const char *gethost(struct sockaddr_storage *);
+static const char *gethost(struct sockaddr *);
 static int  *socketsetup(const char *, const char *, int);
+static int   ident_getuid(struct sockaddr_storage *, socklen_t,
+               struct sockaddr *, uid_t *);
 static int   sysctl_getuid(struct sockaddr_storage *, socklen_t, uid_t *);
+static int   sysctl_proxy_getuid(struct sockaddr_storage *,
+               struct sockaddr *, uid_t *);
+static int   forward(int, struct sockaddr *, int, int, int);
 static int   check_noident(const char *);
 static int   check_userident(const char *, char *, size_t);
 static void  random_string(char *, size_t);
@@ -58,18 +65,37 @@
 static void  timeout_handler(int);
 static void  waitchild(int);
 static void  fatal(const char *);
-static void  maybe_syslog(int, const char *, ...);
+static void  die(const char *, ...);
 
 static int   bflag, eflag, fflag, Fflag, iflag, Iflag;
 static int   lflag, Lflag, nflag, Nflag, rflag;
 
+/* NAT lookup function pointer. */
+static int  (*nat_lookup)(struct sockaddr_storage *, struct sockaddr *, int *);
+
+/* Packet filters. */
+static const struct {
+       const char *name;
+       int (*fn)(struct sockaddr_storage *, struct sockaddr *, int *);
+} filters[] = {
+#ifdef WITH_PF
+       { "pf", pf_natlookup },
+#endif
+#ifdef WITH_IPF
+       { "ipfilter", ipf_natlookup },
+#endif
+       { NULL, NULL }
+};
+
 int
 main(int argc, char *argv[])
 {
-       int IPv4or6, ch, *socks, timeout;
+       int IPv4or6, ch, error, i, *socks, timeout;
+       const char *filter, *osname, *portno, *proxy;
        char *address, *charset, *fmt, *p;
-       const char *osname, *portno;
        char user[LOGIN_NAME_MAX];
+       struct addrinfo *ai, hints;
+       struct sockaddr *proxy_addr;
        struct group *grp;
        struct passwd *pw;
        gid_t gid;
@@ -79,6 +105,9 @@
        osname = OPSYS_NAME;
        portno = IDENT_SERVICE;
        timeout = TIMEOUT;
+       nat_lookup = NULL;
+       proxy_addr = NULL;
+       filter = proxy = NULL;
        address = charset = fmt = NULL;
        uid = gid = 0;
        bflag = eflag = fflag = Fflag = iflag = Iflag = 0;
@@ -89,7 +118,8 @@
                bflag = 1;
 
        /* Parse command line arguments. */
-       while ((ch = getopt(argc, argv, "46a:bceF:f:g:IiL:lNno:p:rt:u:")) != -1)
+       while ((ch = getopt(argc, argv,
+           "46a:bceF:f:g:IiL:lm:Nno:P:p:rt:u:")) != -1) {
                switch (ch) {
                case '4':
                        IPv4or6 = AF_INET;
@@ -123,8 +153,7 @@
                                if ((grp = getgrnam(optarg)) != NULL)
                                        gid = grp->gr_gid;
                                else
-                                       errx(EXIT_FAILURE,
-                                           "No such group '%s'", optarg);
+                                       die("No such group `%s'", optarg);
                        }
                        break;
                case 'I':
@@ -138,8 +167,13 @@
                        (void)strlcpy(user, optarg, sizeof(user));
                        break;
                case 'l':
+                       if (!lflag)
+                               openlog("identd", LOG_PID, LOG_DAEMON);
                        lflag = 1;
                        break;
+               case 'm':
+                       filter = optarg;
+                       break;
                case 'N':
                        Nflag = 1;
                        break;
@@ -149,6 +183,9 @@
                case 'o':
                        osname = optarg;
                        break;
+               case 'P':
+                       proxy = optarg;
+                       break;
                case 'p':
                        portno = optarg;
                        break;
@@ -157,9 +194,8 @@
                        break;
                case 't':
                        timeout = (int)strtol(optarg, &p, 0);
-                       if (*p != '\0') 
-                               errx(EXIT_FAILURE,
-                                   "Invalid timeout value '%s'", optarg);
+                       if (*p != '\0' || timeout < 1) 
+                               die("Invalid timeout value `%s'", optarg);
                        break;
                case 'u':
                        uid = (uid_t)strtol(optarg, &p, 0);
@@ -168,34 +204,49 @@
                                        uid = pw->pw_uid;
                                        gid = pw->pw_gid;
                                } else
-                                       errx(EXIT_FAILURE,
-                                           "No such user '%s'", optarg);
+                                       die("No such user `%s'", optarg);
                        }
                        break;
                default:
                        exit(EXIT_FAILURE);
                }
+       }
 
-       if (lflag)
-               openlog("identd", LOG_PID, LOG_DAEMON);
+       /* Verify proxy address, if enabled. */
+       if (proxy != NULL) {
+               (void)memset(&hints, 0, sizeof(hints));
+               hints.ai_family = IPv4or6;
+               hints.ai_socktype = SOCK_STREAM;
+               error = getaddrinfo(proxy, NULL, &hints, &ai);
+               if (error != 0)
+                       die("Bad proxy `%s': %s", proxy, gai_strerror(error));
+               if (ai->ai_next != NULL)
+                       die("Bad proxy `%s': resolves to multiple addresses",
+                           proxy);
+               proxy_addr = ai->ai_addr;
+       }



Home | Main Index | Thread Index | Old Index