Source-Changes-HG archive

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

[src/trunk]: src/usr.sbin/inetd PR/56448: Solomon Ritzow: Various improvements.



details:   https://anonhg.NetBSD.org/src/rev/96978df5fe63
branches:  trunk
changeset: 1024219:96978df5fe63
user:      christos <christos%NetBSD.org@localhost>
date:      Tue Oct 12 19:08:04 2021 +0000

description:
PR/56448: Solomon Ritzow: Various improvements.

Rate limiting code has been moved to ratelimit.c. I renamed
clear_ip_list to rl_clear_ip_list and broke the code up into more
functions. I have also made the per-IP rate limiting allocation more
efficient. IP addresses are now stored in their network format instead
of a string from getnameinfo (see inetd.h struct rl_ip_node). malloc
calls use only the space needed by the structure by using offsetof on
union members (I suppose this can be a bit dangerous if not done
correctly...). Per-IP rate limiting still supports textual comparison
using getnameinfo for address families other than AF_INET and AF_INET6, but I
don't think there are any that are actually compatible or used by inetd (I
haven't tested UNIX sockets with a remote bound to another file, but I did test
using IPv6 with the textual format by commenting out the IPv6 specific
code, and it works properly). Still potentially handy for the future.
The IP node list (se_rl_ip_list) now uses the <sys/queue.h> SLIST macros
instead of a custom list. I've broken rl_process up into helper functions
for each type of rate limiting and created a separate function for
address stringification, for use with printouts from the -d flag. I
tried to reduce stack memory use by moving printing code involving
string buffers into separate functions. I haven't tested rl_ipv6_eq on
a 32-bit system.

The code for the positional syntax has also been moved to parse.c.
Function try_biltin has been added to remove parse.c:parse_server's
dependency on the biltin structure definition.

File inetd.h has been updated with the proper function prototypes, and
the servtab structure has been update with the new IP node SLIST. I also
moved things around a bit. The way we (a peer and myself)
formatted inetd.h previously was somewhat confusing. Function and global
variable prototypes are now organized by the source file they are
defined in.

I also added a -f flag that I saw in another problem report
(https://gnats.netbsd.org/12823) that I thought could be useful. It
runs inetd in the foreground but without debug printouts or SO_DEBUG.
I'm not completely sure about the line "if (foreground) setsid()" that
I changed from "if (debug) setsid()".

diffstat:

 usr.sbin/inetd/Makefile    |     4 +-
 usr.sbin/inetd/inetd.8     |    18 +-
 usr.sbin/inetd/inetd.c     |  1632 +-------------------------------------------
 usr.sbin/inetd/inetd.h     |   128 ++-
 usr.sbin/inetd/parse.c     |  1376 +++++++++++++++++++++++++++++++++++++
 usr.sbin/inetd/parse_v2.c  |     9 +-
 usr.sbin/inetd/ratelimit.c |   555 ++++++++++++++
 7 files changed, 2076 insertions(+), 1646 deletions(-)

diffs (truncated from 4045 to 300 lines):

diff -r fd375526790d -r 96978df5fe63 usr.sbin/inetd/Makefile
--- a/usr.sbin/inetd/Makefile   Tue Oct 12 19:05:22 2021 +0000
+++ b/usr.sbin/inetd/Makefile   Tue Oct 12 19:08:04 2021 +0000
@@ -1,12 +1,12 @@
 #      from: @(#)Makefile      8.1 (Berkeley) 6/6/93
-#      $NetBSD: Makefile,v 1.29 2021/09/03 20:24:28 rillig Exp $
+#      $NetBSD: Makefile,v 1.30 2021/10/12 19:08:04 christos Exp $
 
 .include <bsd.own.mk>
 
 USE_FORT?= yes # network server
 
 PROG=  inetd
-SRCS=  inetd.c parse_v2.c
+SRCS=  inetd.c parse.c parse_v2.c ratelimit.c
 MAN=   inetd.8
 MLINKS=        inetd.8 inetd.conf.5
 WARNS= 6
diff -r fd375526790d -r 96978df5fe63 usr.sbin/inetd/inetd.8
--- a/usr.sbin/inetd/inetd.8    Tue Oct 12 19:05:22 2021 +0000
+++ b/usr.sbin/inetd/inetd.8    Tue Oct 12 19:08:04 2021 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: inetd.8,v 1.64 2021/08/31 11:16:00 wiz Exp $
+.\"    $NetBSD: inetd.8,v 1.65 2021/10/12 19:08:04 christos Exp $
 .\"
 .\" Copyright (c) 1998 The NetBSD Foundation, Inc.
 .\" All rights reserved.
@@ -57,7 +57,7 @@
 .\"
 .\"     from: @(#)inetd.8       8.4 (Berkeley) 6/1/94
 .\"
-.Dd August 29, 2021
+.Dd October 12, 2021
 .Dt INETD 8
 .Os
 .Sh NAME
@@ -92,7 +92,9 @@
 .Nm :
 .Bl -tag -width Ds
 .It Fl d
-Turns on debugging.
+Turns on debugging and runs inetd in the foreground.
+.It Fl f
+Runs inetd in the foreground.
 .It Fl l
 Turns on libwrap connection logging.
 .El
@@ -519,7 +521,12 @@
 .It Sy ip_max
 Specifies the maximum number of server instances that may be spawned from
 .Nm
-within an interval of 60 seconds for a given IP address.
+within an interval of 60 seconds for a given IP address. Other address types 
+may also work if supported by
+.Xr getnameinfo 3
+, test thoroughly using -d. For example, connections from unnamed Unix sockets
+do not work, but connections from named Unix sockets may work. However, there is
+no way to only accept named Unix sockets.
 .It Sy user
 The user to run the program as.
 Equivalent to
@@ -860,9 +867,6 @@
 are not currently supported, as addresses of that form are not parsed by 
 .Xr inet_pton 3 .
 .Pp
-.Dq tcpmux
-on IPv6 is not tested enough.
-.Pp
 If a positional service definition has an invalid parameter and extends
 across multiple lines using tab characters, the subsequent lines after the 
 error are treated as new service definitions.
diff -r fd375526790d -r 96978df5fe63 usr.sbin/inetd/inetd.c
--- a/usr.sbin/inetd/inetd.c    Tue Oct 12 19:05:22 2021 +0000
+++ b/usr.sbin/inetd/inetd.c    Tue Oct 12 19:08:04 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: inetd.c,v 1.136 2021/09/03 21:02:04 rillig Exp $       */
+/*     $NetBSD: inetd.c,v 1.137 2021/10/12 19:08:04 christos Exp $     */
 
 /*-
  * Copyright (c) 1998, 2003 The NetBSD Foundation, Inc.
@@ -66,7 +66,7 @@
 #if 0
 static char sccsid[] = "@(#)inetd.c    8.4 (Berkeley) 4/13/94";
 #else
-__RCSID("$NetBSD: inetd.c,v 1.136 2021/09/03 21:02:04 rillig Exp $");
+__RCSID("$NetBSD: inetd.c,v 1.137 2021/10/12 19:08:04 christos Exp $");
 #endif
 #endif /* not lint */
 
@@ -191,6 +191,7 @@
 #include <sys/resource.h>
 #include <sys/event.h>
 #include <sys/socket.h>
+#include <sys/queue.h>
 
 
 #ifndef NO_RPC
@@ -242,9 +243,7 @@
 int deny_severity = LIBWRAP_DENY_FACILITY|LIBWRAP_DENY_SEVERITY;
 #endif
 
-#define        CNT_INTVL       ((time_t)60)    /* servers in CNT_INTVL sec. */
-#define        RETRYTIME       (60*10)         /* retry after bind or server fail */
-
+static bool foreground;
 int    debug;
 #ifdef LIBWRAP
 int    lflag;
@@ -272,32 +271,20 @@
 
 static void    chargen_dg(int, struct servtab *);
 static void    chargen_stream(int, struct servtab *);
-static void    close_sep(struct servtab *);
-static void    config(void);
 static void    daytime_dg(int, struct servtab *);
 static void    daytime_stream(int, struct servtab *);
 static void    discard_dg(int, struct servtab *);
 static void    discard_stream(int, struct servtab *);
 static void    echo_dg(int, struct servtab *);
 static void    echo_stream(int, struct servtab *);
-static void    endconfig(void);
-static struct servtab  *enter(struct servtab *);
-static struct servtab  *getconfigent(char **);
 __dead static void     goaway(void);
 static void    machtime_dg(int, struct servtab *);
 static void    machtime_stream(int, struct servtab *);
-#ifdef DEBUG_ENABLE
-static void    print_service(const char *, struct servtab *);
-#endif
 static void    reapchild(void);
 static void    retry(void);
 static void    run_service(int, struct servtab *, int);
-static void    setup(struct servtab *);
-static char    *skip(char **);
 static void    tcpmux(int, struct servtab *);
 __dead static void     usage(void);
-static void    register_rpc(struct servtab *);
-static void    unregister_rpc(struct servtab *);
 static void    bump_nofile(void);
 static void    inetd_setproctitle(char *, int);
 static void    initring(void);
@@ -308,25 +295,6 @@
 static struct kevent   *allocchange(void);
 static int     get_line(int, char *, int);
 static void    spawn(struct servtab *, int);
-static struct servtab  init_servtab(void);
-static int     rl_process(struct servtab *, int);
-static struct se_ip_list_node  *rl_add(struct servtab *, char *);
-static void    rl_reset(struct servtab *, time_t);
-static struct se_ip_list_node  *rl_try_get_ip(struct servtab *, char *);
-static void    include_configs(char *);
-static int     glob_error(const char *, int);
-static void    read_glob_configs(char *);
-static void    prepare_next_config(const char*);
-static bool    is_same_service(const struct servtab *, const struct servtab *);
-static char    *gen_file_pattern(const char *, const char *);
-static bool    check_no_reinclude(const char *);
-static void    include_matched_path(char *);
-static void    purge_unchecked(void);
-static void    config_root(void);
-static void    clear_ip_list(struct servtab *);
-static time_t  rl_time(void);
-static void    rl_get_name(struct servtab *, int, char *);
-static void    rl_drop_connection(struct servtab *, int);
 
 struct biltin {
        const char *bi_service;         /* internally provided service name */
@@ -356,9 +324,7 @@
        { "chargen",    SOCK_STREAM,    true, false,    chargen_stream },
        { "chargen",    SOCK_DGRAM,     false, false,   chargen_dg },
 
-       { "tcpmux",     SOCK_STREAM,    true, false,    tcpmux },
-
-       { NULL, 0, false, false, NULL }
+       { "tcpmux",     SOCK_STREAM,    true, false,    tcpmux }
 };
 
 /* list of "bad" ports. I.e. ports that are most obviously used for
@@ -382,16 +348,20 @@
 
        while ((ch = getopt(argc, argv,
 #ifdef LIBWRAP
-                                       "dl"
+                                       "dfl"
 #else
-                                       "d"
+                                       "df"
 #endif
                                           )) != -1)
                switch(ch) {
                case 'd':
+                       foreground = true;
                        debug = true;
                        options |= SO_DEBUG;
                        break;
+               case 'f':
+                       foreground = true;
+                       break;
 #ifdef LIBWRAP
                case 'l':
                        lflag = true;
@@ -407,7 +377,7 @@
        if (argc > 0)
                CONFIG = argv[0];
 
-       if (!debug)
+       if (!foreground)
                daemon(0, 0);
        openlog("inetd", LOG_PID | LOG_NOWAIT, LOG_DAEMON);
        pidfile(NULL);
@@ -537,14 +507,15 @@
 
                        for (n = 0; n < __arraycount(my_signals); n++)
                                (void) signal(my_signals[n], SIG_DFL);
-                       if (debug)
+                       /* Don't put services in terminal session */
+                       if (foreground)
                                setsid();
                }
        }
        if (pid == 0) {
                run_service(ctrl, sep, dofork);
                if (dofork)
-                       exit(0);
+                       exit(EXIT_SUCCESS);
        }
        if (sep->se_wait == 0 && sep->se_socktype == SOCK_STREAM)
                close(ctrl);
@@ -703,215 +674,6 @@
        }
 }
 
-size_t line_number;
-
-/*
- * Recursively merge loaded service definitions with any defined
- * in the current or included config files.
- */
-static void
-config(void)
-{
-       struct servtab *sep, *cp;
-       /*
-        * Current position in line, used with key-values notation,
-        * saves cp across getconfigent calls.
-        */
-       char *current_pos;
-       size_t n;
-
-       /* open config file from beginning */
-       fconfig = fopen(CONFIG, "r");
-       if(fconfig == NULL) {
-               syslog(LOG_ERR, "%s: %m", CONFIG);
-               return;
-       }
-
-       /* First call to nextline will advance line_number to 1 */
-       line_number = 0;
-
-       /* Start parsing at the beginning of the first line */
-       current_pos = nextline(fconfig);
-
-       while ((cp = getconfigent(&current_pos)) != NULL) {
-               /* Find an already existing service definition */
-               for (sep = servtab; sep != NULL; sep = sep->se_next)
-                       if (is_same_service(sep, cp))
-                               break;
-               if (sep != NULL) {
-                       int i;
-
-#define SWAP(type, a, b) {type c = a; a = b; b = c;}
-
-                       /*
-                        * sep->se_wait may be holding the pid of a daemon
-                        * that we're waiting for.  If so, don't overwrite
-                        * it unless the config file explicitly says don't
-                        * wait.
-                        */
-                       if (cp->se_bi == 0 &&
-                           (sep->se_wait == 1 || cp->se_wait == 0))
-                               sep->se_wait = cp->se_wait;
-                       SWAP(char *, sep->se_user, cp->se_user);
-                       SWAP(char *, sep->se_group, cp->se_group);
-                       SWAP(char *, sep->se_server, cp->se_server);
-                       for (i = 0; i < MAXARGV; i++)
-                               SWAP(char *, sep->se_argv[i], cp->se_argv[i]);
-#ifdef IPSEC
-                       SWAP(char *, sep->se_policy, cp->se_policy);
-#endif
-                       SWAP(service_type, cp->se_type, sep->se_type);
-                       SWAP(size_t, cp->se_service_max, sep->se_service_max);
-                       SWAP(size_t, cp->se_ip_max, sep->se_ip_max);
-#undef SWAP
-                       if (isrpcservice(sep))
-                               unregister_rpc(sep);
-                       sep->se_rpcversl = cp->se_rpcversl;
-                       sep->se_rpcversh = cp->se_rpcversh;
-                       freeconfig(cp);
-#ifdef DEBUG_ENABLE
-                       if (debug)



Home | Main Index | Thread Index | Old Index