diff options
-rw-r--r-- | usr.sbin/snmpd/application.h | 4 | ||||
-rw-r--r-- | usr.sbin/snmpd/application_internal.c | 98 | ||||
-rw-r--r-- | usr.sbin/snmpd/parse.y | 75 |
3 files changed, 140 insertions, 37 deletions
diff --git a/usr.sbin/snmpd/application.h b/usr.sbin/snmpd/application.h index 7519a7d7009..d6129634670 100644 --- a/usr.sbin/snmpd/application.h +++ b/usr.sbin/snmpd/application.h @@ -1,4 +1,4 @@ -/* $OpenBSD: application.h,v 1.11 2023/11/08 20:07:14 martijn Exp $ */ +/* $OpenBSD: application.h,v 1.12 2023/11/12 16:03:41 martijn Exp $ */ /* * Copyright (c) 2021 Martijn van Duren <martijn@openbsd.org> @@ -160,3 +160,5 @@ void appl_blocklist_shutdown(void); /* application_internal.c */ void appl_internal_init(void); void appl_internal_shutdown(void); +const char *appl_internal_object_int(struct ber_oid *, int32_t); +const char *appl_internal_object_string(struct ber_oid *, char *); diff --git a/usr.sbin/snmpd/application_internal.c b/usr.sbin/snmpd/application_internal.c index a59fe5a291b..9553a1489df 100644 --- a/usr.sbin/snmpd/application_internal.c +++ b/usr.sbin/snmpd/application_internal.c @@ -1,4 +1,4 @@ -/* $OpenBSD: application_internal.c,v 1.7 2023/11/08 19:46:28 martijn Exp $ */ +/* $OpenBSD: application_internal.c,v 1.8 2023/11/12 16:03:41 martijn Exp $ */ /* * Copyright (c) 2023 Martijn van Duren <martijn@openbsd.org> @@ -18,8 +18,10 @@ #include <sys/tree.h> +#include <errno.h> #include <event.h> #include <stdlib.h> +#include <string.h> #include <unistd.h> #include "application.h" @@ -34,6 +36,9 @@ struct appl_internal_object { /* No getnext means the object is scalar */ struct ber_element * (*getnext)(int8_t, struct ber_oid *); + int32_t intval; + char *stringval; + RB_ENTRY(appl_internal_object) entry; }; @@ -49,6 +54,8 @@ struct ber_element *appl_internal_snmp(struct ber_oid *); struct ber_element *appl_internal_engine(struct ber_oid *); struct ber_element *appl_internal_usmstats(struct ber_oid *); struct ber_element *appl_internal_system(struct ber_oid *); +struct ber_element *appl_internal_get_int(struct ber_oid *); +struct ber_element *appl_internal_get_string(struct ber_oid *); struct appl_internal_object *appl_internal_object_parent(struct ber_oid *); int appl_internal_object_cmp(struct appl_internal_object *, struct appl_internal_object *); @@ -67,14 +74,26 @@ struct appl_backend appl_internal = { .ab_fn = &appl_internal_functions }; +struct appl_backend appl_config = { + .ab_name = "config", + .ab_cookie = NULL, + .ab_retries = 0, + .ab_range = 1, + .ab_fn = &appl_internal_functions +}; + static RB_HEAD(appl_internal_objects, appl_internal_object) - appl_internal_objects = RB_INITIALIZER(&appl_internal_objects); + appl_internal_objects = RB_INITIALIZER(&appl_internal_objects), + appl_internal_objects_conf = RB_INITIALIZER(&appl_internal_objects_conf); RB_PROTOTYPE_STATIC(appl_internal_objects, appl_internal_object, entry, appl_internal_object_cmp); void appl_internal_init(void) { + struct appl_internal_object *obj; + struct ber_oid oid; + appl_internal_region(&OID(MIB_system)); appl_internal_object(&OID(MIB_sysDescr), appl_internal_system, NULL); appl_internal_object(&OID(MIB_sysOID), appl_internal_system, NULL); @@ -178,6 +197,22 @@ appl_internal_init(void) appl_internal_usmstats, NULL); appl_internal_object(&OID(MIB_usmStatsDecryptionErrors), appl_internal_usmstats, NULL); + + while ((obj = RB_MIN(appl_internal_objects, + &appl_internal_objects_conf)) != NULL) { + RB_REMOVE(appl_internal_objects, + &appl_internal_objects_conf, obj); + oid = obj->oid; + oid.bo_id[oid.bo_n++] = 0; + if (appl_register(NULL, 150, 1, &oid, + 1, 1, 0, 0, &appl_config) != APPL_ERROR_NOERROR) { + if (obj->stringval != NULL) + free(obj->stringval); + free(obj); + } else + RB_INSERT(appl_internal_objects, &appl_internal_objects, + obj); + } } void @@ -227,6 +262,47 @@ appl_internal_object(struct ber_oid *oid, RB_INSERT(appl_internal_objects, &appl_internal_objects, obj); } +const char * +appl_internal_object_int(struct ber_oid *oid, int32_t val) +{ + struct appl_internal_object *obj; + + if ((obj = calloc(1, sizeof(*obj))) == NULL) + return strerror(errno); + obj->oid = *oid; + obj->get = appl_internal_get_int; + obj->getnext = NULL; + obj->intval = val; + obj->stringval = NULL; + + if (RB_INSERT(appl_internal_objects, + &appl_internal_objects_conf, obj) != NULL) { + free(obj); + return "OID already defined"; + } + return NULL; +} + +const char * +appl_internal_object_string(struct ber_oid *oid, char *val) +{ + struct appl_internal_object *obj; + + if ((obj = calloc(1, sizeof(*obj))) == NULL) + return strerror(errno); + obj->oid = *oid; + obj->get = appl_internal_get_string; + obj->getnext = NULL; + obj->stringval = val; + + if (RB_INSERT(appl_internal_objects, + &appl_internal_objects_conf, obj) != NULL) { + free(obj); + return "OID already defined"; + } + return NULL; +} + void appl_internal_get(struct appl_backend *backend, __unused int32_t transactionid, int32_t requestid, __unused const char *ctx, struct appl_varbind *vblist) @@ -502,6 +578,24 @@ appl_internal_system(struct ber_oid *oid) return value; } +struct ber_element * +appl_internal_get_int(struct ber_oid *oid) +{ + struct appl_internal_object *obj; + + obj = appl_internal_object_parent(oid); + return ober_add_integer(NULL, obj->intval); +} + +struct ber_element * +appl_internal_get_string(struct ber_oid *oid) +{ + struct appl_internal_object *obj; + + obj = appl_internal_object_parent(oid); + return ober_add_string(NULL, obj->stringval); +} + struct appl_internal_object * appl_internal_object_parent(struct ber_oid *oid) { diff --git a/usr.sbin/snmpd/parse.y b/usr.sbin/snmpd/parse.y index deded9ab0cf..7e1b8d889cb 100644 --- a/usr.sbin/snmpd/parse.y +++ b/usr.sbin/snmpd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.80 2023/11/04 09:38:47 martijn Exp $ */ +/* $OpenBSD: parse.y,v 1.81 2023/11/12 16:03:41 martijn Exp $ */ /* * Copyright (c) 2007, 2008, 2012 Reyk Floeter <reyk@openbsd.org> @@ -54,6 +54,7 @@ #include <string.h> #include <syslog.h> +#include "application.h" #include "snmpd.h" #include "mib.h" @@ -98,6 +99,7 @@ char *symget(const char *); struct snmpd *conf = NULL; static int errors = 0; static struct usmuser *user = NULL; +static struct oid *smi_object; static uint8_t engineid[SNMPD_MAXENGINEIDLEN]; static int32_t enginepen; @@ -148,7 +150,7 @@ typedef struct { %type <v.number> listenproto listenflag listenflags %type <v.string> srcaddr port %type <v.number> optwrite yesno seclevel -%type <v.data> objtype cmd hostauth hostauthv3 usmauthopts usmauthopt +%type <v.data> cmd hostauth hostauthv3 usmauthopts usmauthopt %type <v.oid> oid hostoid trapoid %type <v.auth> auth %type <v.enc> enc @@ -162,7 +164,7 @@ grammar : /* empty */ | grammar varset '\n' | grammar main '\n' | grammar system '\n' - | grammar mib '\n' + | grammar object '\n' | grammar error '\n' { file->errors++; } ; @@ -845,50 +847,55 @@ sysmib : CONTACT STRING { } ; -mib : OBJECTID oid NAME STRING optwrite objtype { - struct oid *oid; - if ((oid = (struct oid *) - calloc(1, sizeof(*oid))) == NULL) { +object : OBJECTID oid NAME STRING optwrite { + smi_object = calloc(1, sizeof(*smi_object)); + if (smi_object == NULL) { yyerror("calloc"); free($2); - free($6.data); + free($4); YYERROR; } - smi_oidlen($2); - bcopy($2, &oid->o_id, sizeof(struct ber_oid)); - free($2); - oid->o_name = $4; - oid->o_data = $6.data; - oid->o_val = $6.value; - switch ($6.type) { - case 1: - oid->o_get = mps_getint; - break; - case 2: - oid->o_get = mps_getstr; - break; - } - oid->o_flags = OID_RD|OID_DYNAMIC; + smi_object->o_id = *$2; + smi_object->o_name = $4; - if (smi_insert(oid) == -1) { + if (smi_insert(smi_object) == -1) { yyerror("duplicate oid"); - free(oid->o_name); - free(oid->o_data); + free($2); + free($4); + free(smi_object); YYERROR; } - } + } objectvalue ; -objtype : INTEGER NUMBER { - $$.type = 1; - $$.data = NULL; - $$.value = $2; +objectvalue : INTEGER NUMBER { + const char *error; + + if ($2 < INT32_MIN) { + yyerror("number too small"); + YYERROR; + } + if ($2 > INT32_MAX) { + yyerror("number too large"); + YYERROR; + } + error = appl_internal_object_int(&smi_object->o_id, $2); + if (error != NULL) { + yyerror("%s", error); + YYERROR; + } } | OCTETSTRING STRING { - $$.type = 2; - $$.data = $2; - $$.value = strlen($2); + const char *error; + + if ((error = appl_internal_object_string( + &smi_object->o_id, $2)) != NULL) { + yyerror("%s", error); + free($2); + YYERROR; + } + } ; |