Introduce a blocklist backend and keyword.
authormartijn <martijn@openbsd.org>
Thu, 30 Jun 2022 11:28:36 +0000 (11:28 +0000)
committermartijn <martijn@openbsd.org>
Thu, 30 Jun 2022 11:28:36 +0000 (11:28 +0000)
This allows the admin to specify a full region of the OID tree to be
blocked and simply returns NOSUCHOBJECT/ENDOFMIBVIEW.

This deprecates filter-pf-addresses in favour of:
blocklist pfTblAddrTable

OK tb@

usr.sbin/snmpd/Makefile
usr.sbin/snmpd/application.c
usr.sbin/snmpd/application.h
usr.sbin/snmpd/application_blocklist.c [new file with mode: 0644]
usr.sbin/snmpd/mib.c
usr.sbin/snmpd/parse.y
usr.sbin/snmpd/snmpd.conf.5
usr.sbin/snmpd/snmpd.h

index 9fbe1ae..f49829c 100644 (file)
@@ -1,8 +1,9 @@
-#      $OpenBSD: Makefile,v 1.18 2022/01/19 11:00:56 martijn Exp $
+#      $OpenBSD: Makefile,v 1.19 2022/06/30 11:28:36 martijn Exp $
 
 PROG=          snmpd
 MAN=           snmpd.8 snmpd.conf.5
 SRCS=          parse.y log.c snmpe.c application.c application_legacy.c \
+                   application_blocklist.c \
                    mps.c trap.c mib.c smi.c kroute.c snmpd.c timer.c \
                    pf.c proc.c usm.c traphandler.c util.c
 
index 4727bee..0fb8a45 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: application.c,v 1.5 2022/06/27 10:31:17 martijn Exp $ */
+/*     $OpenBSD: application.c,v 1.6 2022/06/30 11:28:36 martijn Exp $ */
 
 /*
  * Copyright (c) 2021 Martijn van Duren <martijn@openbsd.org>
@@ -148,6 +148,7 @@ RB_PROTOTYPE_STATIC(appl_requests, appl_request_downstream, ard_entry,
 void
 appl_init(void)
 {
+       appl_blocklist_init();
        appl_legacy_init();
 }
 
@@ -156,6 +157,7 @@ appl_shutdown(void)
 {
        struct appl_context *ctx, *tctx;
 
+       appl_blocklist_shutdown();
        appl_legacy_shutdown();
 
        TAILQ_FOREACH_SAFE(ctx, &contexts, ac_entries, tctx) {
index e65c6e7..fd5b814 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: application.h,v 1.1 2022/01/19 10:59:35 martijn Exp $ */
+/*     $OpenBSD: application.h,v 1.2 2022/06/30 11:28:36 martijn Exp $ */
 
 /*
  * Copyright (c) 2021 Martijn van Duren <martijn@openbsd.org>
@@ -133,3 +133,7 @@ struct ber_element *appl_exception(enum appl_exception);
 /* application_legacy.c */
 void    appl_legacy_init(void);
 void    appl_legacy_shutdown(void);
+
+/* application_blocklist.c */
+void    appl_blocklist_init(void);
+void    appl_blocklist_shutdown(void);
diff --git a/usr.sbin/snmpd/application_blocklist.c b/usr.sbin/snmpd/application_blocklist.c
new file mode 100644 (file)
index 0000000..e3bb1b9
--- /dev/null
@@ -0,0 +1,141 @@
+/*     $OpenBSD: application_blocklist.c,v 1.1 2022/06/30 11:28:36 martijn Exp $       */
+
+/*
+ * Copyright (c) 2022 Martijn van Duren <martijn@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <event.h>
+#include <stdlib.h>
+
+#include "application.h"
+#include "snmpd.h"
+
+struct appl_varbind *appl_blocklist_response(size_t);
+void appl_blocklist_get(struct appl_backend *, int32_t, int32_t, const char *,
+    struct appl_varbind *);
+void appl_blocklist_getnext(struct appl_backend *, int32_t, int32_t,
+    const char *, struct appl_varbind *);
+
+struct appl_backend_functions appl_blocklist_functions = {
+       .ab_get = appl_blocklist_get,
+       .ab_getnext = appl_blocklist_getnext,
+       .ab_getbulk = NULL,
+};
+
+struct appl_backend appl_blocklist = {
+       .ab_name = "blocklist",
+       .ab_cookie = NULL,
+       .ab_retries = 0,
+       .ab_fn = &appl_blocklist_functions
+};
+
+static struct appl_varbind *response = NULL;
+static size_t responsesz = 0;
+
+struct appl_varbind *
+appl_blocklist_response(size_t nvarbind)
+{
+       struct appl_varbind *tmp;
+       size_t i;
+
+       if (responsesz < nvarbind) {
+               if ((tmp = recallocarray(response, responsesz, nvarbind,
+                   sizeof(*response))) == NULL) {
+                       log_warn(NULL);
+                       return NULL;
+               }
+               responsesz = nvarbind;
+               response = tmp;
+       }
+       for (i = 0; i < nvarbind; i++)
+               response[i].av_next = i + 1 == nvarbind ?
+                   NULL : &(response[i + 1]);
+       return response;
+}
+
+void
+appl_blocklist_init(void)
+{
+       extern struct snmpd *snmpd_env;
+       size_t i;
+
+       for (i = 0; i < snmpd_env->sc_nblocklist; i++)
+               appl_register(NULL, 150, 1, &(snmpd_env->sc_blocklist[i]),
+                   0, 1, 0, 0, &appl_blocklist);
+}
+
+void
+appl_blocklist_shutdown(void)
+{
+       appl_close(&appl_blocklist);
+       free(response);
+}
+
+void
+appl_blocklist_get(struct appl_backend *backend, __unused int32_t transactionid,
+    int32_t requestid, __unused const char *ctx, struct appl_varbind *vblist)
+{
+       struct appl_varbind *vb, *rvb, *rvblist;
+       size_t i;
+
+       for (i = 0, vb = vblist; vb != NULL; vb = vb->av_next)
+               i++;
+       if ((rvblist = appl_blocklist_response(i)) == NULL)
+               goto fail;
+       rvb = rvblist;
+       for (vb = vblist; vb != NULL; vb = vb->av_next, rvb = rvb->av_next) {
+               rvb->av_oid = vb->av_oid;
+               rvb->av_value = appl_exception(APPL_EXC_NOSUCHOBJECT);
+               if (rvb->av_value == NULL)
+                       goto fail;
+       }
+
+       appl_response(backend, requestid, APPL_ERROR_NOERROR, 0, rvblist);
+       return;
+ fail:
+       for (rvb = rvblist; rvb != NULL && rvb->av_value != NULL;
+           rvb = rvb->av_next)
+               ober_free_elements(rvb->av_value);
+       appl_response(backend, requestid, APPL_ERROR_GENERR, 1, vb);
+}
+
+void
+appl_blocklist_getnext(struct appl_backend *backend,
+    __unused int32_t transactionid, int32_t requestid, __unused const char *ctx,
+    struct appl_varbind *vblist)
+{
+       struct appl_varbind *vb, *rvb, *rvblist;
+       size_t i;
+
+       for (i = 0, vb = vblist; vb != NULL; vb = vb->av_next)
+               i++;
+       if ((rvblist = appl_blocklist_response(i)) == NULL)
+               goto fail;
+       rvb = rvblist;
+       for (vb = vblist; vb != NULL; vb = vb->av_next, rvb = rvb->av_next) {
+               rvb->av_oid = vb->av_oid;
+               rvb->av_value = appl_exception(APPL_EXC_ENDOFMIBVIEW);
+               if (rvb->av_value == NULL)
+                       goto fail;
+       }
+
+       appl_response(backend, requestid, APPL_ERROR_NOERROR, 0, rvblist);
+       return;
+ fail:
+       for (rvb = rvblist; rvb != NULL && rvb->av_value != NULL;
+           rvb = rvb->av_next)
+               ober_free_elements(rvb->av_value);
+       appl_response(backend, requestid, APPL_ERROR_GENERR, 1, vb);
+}
index a157064..b034ab8 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: mib.c,v 1.102 2021/09/01 15:54:40 deraadt Exp $       */
+/*     $OpenBSD: mib.c,v 1.103 2022/06/30 11:28:36 martijn Exp $       */
 
 /*
  * Copyright (c) 2012 Joel Knight <joel@openbsd.org>
@@ -2223,9 +2223,6 @@ mib_pftableaddrs(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
        struct pfr_astats        as;
        int                      tblidx;
 
-       if (snmpd_env->sc_pfaddrfilter)
-               return (-1);
-
        tblidx = o->bo_id[OIDIDX_pfTblAddr + 1];
        mps_decodeinaddr(o, &as.pfras_a.pfra_ip4addr, OIDIDX_pfTblAddr + 2);
        as.pfras_a.pfra_net = o->bo_id[OIDIDX_pfTblAddr + 6];
@@ -2314,9 +2311,6 @@ mib_pftableaddrstable(struct oid *oid, struct ber_oid *o, struct ber_oid *no)
        struct oid               a, b;
        u_int32_t                id, tblidx;
 
-       if (snmpd_env->sc_pfaddrfilter)
-               return (NULL);
-
        bcopy(&oid->o_id, no, sizeof(*no));
        id = oid->o_oidlen - 1;
 
index b390ff6..a64df11 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: parse.y,v 1.74 2022/06/28 09:11:33 martijn Exp $      */
+/*     $OpenBSD: parse.y,v 1.75 2022/06/30 11:28:36 martijn Exp $      */
 
 /*
  * Copyright (c) 2007, 2008, 2012 Reyk Floeter <reyk@openbsd.org>
@@ -130,7 +130,7 @@ typedef struct {
 %token SYSTEM CONTACT DESCR LOCATION NAME OBJECTID SERVICES RTFILTER
 %token READONLY READWRITE OCTETSTRING INTEGER COMMUNITY TRAP RECEIVER
 %token SECLEVEL NONE AUTH ENC USER AUTHKEY ENCKEY ERROR
-%token HANDLE DEFAULT SRCADDR TCP UDP PFADDRFILTER PORT
+%token HANDLE DEFAULT SRCADDR TCP UDP PFADDRFILTER BLOCKLIST PORT
 %token <v.string>      STRING
 %token <v.number>      NUMBER
 %type  <v.string>      usmuser community optcommunity
@@ -255,6 +255,20 @@ main               : LISTEN ON listen_udptcp
                        }
                        conf->sc_traphandler = 1;
                }
+               | BLOCKLIST oid {
+                       struct ber_oid *blocklist;
+
+                       blocklist = recallocarray(conf->sc_blocklist,
+                           conf->sc_nblocklist, conf->sc_nblocklist + 1,
+                           sizeof(*blocklist));
+                       if (blocklist == NULL) {
+                               yyerror("malloc");
+                               YYERROR;
+                       }
+                       conf->sc_blocklist = blocklist;
+                       blocklist[conf->sc_nblocklist++] = *$2;
+                       free($2);
+               }
                | RTFILTER yesno                {
                        if ($2 == 1)
                                conf->sc_rtfilter = ROUTE_FILTER(RTM_NEWADDR) |
@@ -264,8 +278,25 @@ main               : LISTEN ON listen_udptcp
                        else
                                conf->sc_rtfilter = 0;
                }
+               /* XXX Remove after 7.4 */
                | PFADDRFILTER yesno            {
-                       conf->sc_pfaddrfilter = $2;
+                       struct ber_oid *blocklist;
+
+                       log_warnx("filter-pf-addresses is deprecated. "
+                           "Please use blocklist instead.");
+                       if ($2) {
+                               blocklist = recallocarray(conf->sc_blocklist,
+                                   conf->sc_nblocklist,
+                                   conf->sc_nblocklist + 1,
+                                   sizeof(*blocklist));
+                               if (blocklist == NULL) {
+                                       yyerror("malloc");
+                                       YYERROR;
+                               }
+                               conf->sc_blocklist = blocklist;
+                               smi_string2oid("pfTblAddrTable",
+                                   &(blocklist[conf->sc_nblocklist++]));
+                       }
                }
                | seclevel {
                        conf->sc_min_seclevel = $1;
@@ -995,6 +1026,7 @@ lookup(char *s)
                { "agentid",                    AGENTID },
                { "auth",                       AUTH },
                { "authkey",                    AUTHKEY },
+               { "blocklist",                  BLOCKLIST },
                { "community",                  COMMUNITY },
                { "contact",                    CONTACT },
                { "default",                    DEFAULT },
index fa84838..a415f03 100644 (file)
@@ -1,4 +1,4 @@
-.\" $OpenBSD: snmpd.conf.5,v 1.59 2022/03/31 17:27:31 naddy Exp $
+.\" $OpenBSD: snmpd.conf.5,v 1.60 2022/06/30 11:28:36 martijn Exp $
 .\"
 .\" Copyright (c) 2007, 2008, 2012 Reyk Floeter <reyk@openbsd.org>
 .\"
@@ -14,7 +14,7 @@
 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
-.Dd $Mdocdate: March 31 2022 $
+.Dd $Mdocdate: June 30 2022 $
 .Dt SNMPD.CONF 5
 .Os
 .Sh NAME
@@ -78,15 +78,13 @@ listen on $ext_addr
 .Sh GLOBAL CONFIGURATION
 The following options can be set globally:
 .Bl -tag -width Ds
-.It Ic filter-pf-addresses Pq Ic yes | no
-If set to
-.Ic yes ,
-.Xr snmpd 8
-will filter out the OPENBSD-PF-MIB::pfTblAddrTable tree.
-Addresses stored in PF tables will not be available, but CPU use will be
-reduced during bulk walks.
-The default is
-.Ic no .
+.It Ic blocklist Ar oid
+Remove the
+.Ar oid
+subtree from view.
+Multiple
+.Ic blocklist
+statements are supported.
 .It Ic filter-routes Pq Ic yes | no
 If set to
 .Ic yes ,
index e86a8d3..fa4d9ae 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: snmpd.h,v 1.102 2022/01/19 10:25:04 martijn Exp $     */
+/*     $OpenBSD: snmpd.h,v 1.103 2022/06/30 11:28:36 martijn Exp $     */
 
 /*
  * Copyright (c) 2007, 2008, 2012 Reyk Floeter <reyk@openbsd.org>
@@ -591,8 +591,9 @@ struct snmpd {
 
        int                      sc_ncpu;
        int64_t                 *sc_cpustates;
+       struct ber_oid          *sc_blocklist;
+       size_t                   sc_nblocklist;
        int                      sc_rtfilter;
-       int                      sc_pfaddrfilter;
 
        int                      sc_min_seclevel;
        int                      sc_traphandler;