From owner-svn-src-head@freebsd.org Wed Apr 1 15:41:17 2020 Return-Path: Delivered-To: svn-src-head@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id DF7612BF064; Wed, 1 Apr 2020 15:41:16 +0000 (UTC) (envelope-from harti@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 48sr5S4Kk6z4Hsb; Wed, 1 Apr 2020 15:41:16 +0000 (UTC) (envelope-from harti@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id B9D54276B0; Wed, 1 Apr 2020 15:25:18 +0000 (UTC) (envelope-from harti@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 031FPILE079725; Wed, 1 Apr 2020 15:25:18 GMT (envelope-from harti@FreeBSD.org) Received: (from harti@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 031FPGKm079714; Wed, 1 Apr 2020 15:25:16 GMT (envelope-from harti@FreeBSD.org) Message-Id: <202004011525.031FPGKm079714@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: harti set sender to harti@FreeBSD.org using -f From: Hartmut Brandt Date: Wed, 1 Apr 2020 15:25:16 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r359512 - in head: contrib/bsnmp/lib contrib/bsnmp/snmp_mibII contrib/bsnmp/snmp_usm contrib/bsnmp/snmp_vacm contrib/bsnmp/snmpd contrib/bsnmp/tests lib/libbsnmp/libbsnmp X-SVN-Group: head X-SVN-Commit-Author: harti X-SVN-Commit-Paths: in head: contrib/bsnmp/lib contrib/bsnmp/snmp_mibII contrib/bsnmp/snmp_usm contrib/bsnmp/snmp_vacm contrib/bsnmp/snmpd contrib/bsnmp/tests lib/libbsnmp/libbsnmp X-SVN-Commit-Revision: 359512 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 01 Apr 2020 15:41:17 -0000 Author: harti Date: Wed Apr 1 15:25:16 2020 New Revision: 359512 URL: https://svnweb.freebsd.org/changeset/base/359512 Log: Merge release 1.14 of bsnmp. Added: head/contrib/bsnmp/tests/ - copied from r359490, vendor/bsnmp/dist/tests/ Replaced: head/contrib/bsnmp/snmpd/trans_inet.c - copied unchanged from r359490, vendor/bsnmp/dist/snmpd/trans_inet.c head/contrib/bsnmp/snmpd/trans_inet.h - copied unchanged from r359490, vendor/bsnmp/dist/snmpd/trans_inet.h Modified: head/contrib/bsnmp/lib/asn1.c head/contrib/bsnmp/lib/bsnmpclient.3 head/contrib/bsnmp/lib/snmpclient.c head/contrib/bsnmp/lib/snmpcrypto.c head/contrib/bsnmp/snmp_mibII/mibII.c head/contrib/bsnmp/snmp_mibII/mibII.h head/contrib/bsnmp/snmp_usm/usm_snmp.c head/contrib/bsnmp/snmp_vacm/vacm_snmp.c head/contrib/bsnmp/snmpd/snmpd.config head/lib/libbsnmp/libbsnmp/Makefile Directory Properties: head/contrib/bsnmp/ (props changed) Modified: head/contrib/bsnmp/lib/asn1.c ============================================================================== --- head/contrib/bsnmp/lib/asn1.c Wed Apr 1 15:12:51 2020 (r359511) +++ head/contrib/bsnmp/lib/asn1.c Wed Apr 1 15:25:16 2020 (r359512) @@ -65,8 +65,8 @@ asn_get_header(struct asn_buf *b, u_char *type, asn_le return (ASN_ERR_EOBUF); } *type = *b->asn_cptr; - if ((*type & ASN_TYPE_MASK) > 0x30) { - asn_error(b, "types > 0x30 not supported (%u)", + if ((*type & ASN_TYPE_MASK) > 0x1e) { + asn_error(b, "tags > 0x1e not supported (%#x)", *type & ASN_TYPE_MASK); return (ASN_ERR_FAILED); } @@ -100,11 +100,19 @@ asn_get_header(struct asn_buf *b, u_char *type, asn_le *len = *b->asn_cptr++; b->asn_len--; } + +#ifdef BOGUS_CVE_2019_5610_FIX + /* + * This is the fix from CVE-2019-5610. + * + * This is the wrong place. Each of the asn functions should check + * that it has enough info for its own work. + */ if (*len > b->asn_len) { - asn_error(b, "len %u exceeding asn_len %u", *len, b->asn_len); + asn_error(b, "lenen %u exceeding asn_len %u", *len, b->asn_len); return (ASN_ERR_EOBUF); } - +#endif return (ASN_ERR_OK); } @@ -147,7 +155,7 @@ asn_put_len(u_char *ptr, asn_len_t len) /* * Write a header (tag and length fields). - * Tags are restricted to one byte tags (value <= 0x30) and the + * Tags are restricted to one byte tags (value <= 0x1e) and the * lenght field to 16-bit. All errors stop the encoding. */ enum asn_err @@ -156,8 +164,8 @@ asn_put_header(struct asn_buf *b, u_char type, asn_len u_int lenlen; /* tag field */ - if ((type & ASN_TYPE_MASK) > 0x30) { - asn_error(NULL, "types > 0x30 not supported (%u)", + if ((type & ASN_TYPE_MASK) > 0x1e) { + asn_error(NULL, "types > 0x1e not supported (%#x)", type & ASN_TYPE_MASK); return (ASN_ERR_FAILED); } @@ -251,9 +259,10 @@ asn_get_real_integer(struct asn_buf *b, asn_len_t len, return (ASN_ERR_BADLEN); } err = ASN_ERR_OK; - if (len > 8) + if (len > 8) { + asn_error(b, "integer too long"); err = ASN_ERR_RANGE; - else if (len > 1 && + } else if (len > 1 && ((*b->asn_cptr == 0x00 && (b->asn_cptr[1] & 0x80) == 0) || (*b->asn_cptr == 0xff && (b->asn_cptr[1] & 0x80) == 0x80))) { asn_error(b, "non-minimal integer"); @@ -331,27 +340,35 @@ asn_put_real_integer(struct asn_buf *b, u_char type, i static enum asn_err asn_get_real_unsigned(struct asn_buf *b, asn_len_t len, uint64_t *vp) { - enum asn_err err; - + *vp = 0; if (b->asn_len < len) { asn_error(b, "truncated integer"); return (ASN_ERR_EOBUF); } if (len == 0) { + /* X.690: 8.3.1 */ asn_error(b, "zero-length integer"); - *vp = 0; return (ASN_ERR_BADLEN); } - err = ASN_ERR_OK; - *vp = 0; - if ((*b->asn_cptr & 0x80) || (len == 9 && *b->asn_cptr != 0)) { + if (len > 1 && *b->asn_cptr == 0x00 && (b->asn_cptr[1] & 0x80) == 0) { + /* X.690: 8.3.2 */ + asn_error(b, "non-minimal unsigned"); + b->asn_cptr += len; + b->asn_len -= len; + return (ASN_ERR_BADLEN); + + } + + enum asn_err err = ASN_ERR_OK; + + if ((*b->asn_cptr & 0x80) || len > 9 || + (len == 9 && *b->asn_cptr != 0)) { /* negative integer or too larger */ *vp = 0xffffffffffffffffULL; - err = ASN_ERR_RANGE; - } else if (len > 1 && - *b->asn_cptr == 0x00 && (b->asn_cptr[1] & 0x80) == 0) { - asn_error(b, "non-minimal unsigned"); - err = ASN_ERR_BADLEN; + asn_error(b, "unsigned too large or negative"); + b->asn_cptr += len; + b->asn_len -= len; + return (ASN_ERR_RANGE); } while (len--) { @@ -405,11 +422,14 @@ asn_get_integer_raw(struct asn_buf *b, asn_len_t len, enum asn_err ret; if ((ret = asn_get_real_integer(b, len, &val)) == ASN_ERR_OK) { - if (len > 4) + if (len > 4) { + asn_error(b, "integer too long"); ret = ASN_ERR_BADLEN; - else if (val > INT32_MAX || val < INT32_MIN) + } else if (val > INT32_MAX || val < INT32_MIN) { /* may not happen */ + asn_error(b, "integer out of range"); ret = ASN_ERR_RANGE; + } *vp = (int32_t)val; } return (ret); @@ -589,7 +609,7 @@ asn_get_objid_raw(struct asn_buf *b, asn_len_t len, st return (ASN_ERR_EOBUF); } if (subid > (ASN_MAXID >> 7)) { - asn_error(b, "OBID subid too larger"); + asn_error(b, "OID subid too larger"); err = ASN_ERR_RANGE; } subid = (subid << 7) | (*b->asn_cptr & 0x7f); @@ -645,7 +665,7 @@ asn_put_objid(struct asn_buf *b, const struct asn_oid oidlen = 2; } else if (oid->len == 1) { /* illegal */ - asn_error(b, "short oid"); + asn_error(NULL, "short oid"); if (oid->subs[0] > 2) asn_error(NULL, "oid[0] too large (%u)", oid->subs[0]); err = ASN_ERR_RANGE; @@ -657,7 +677,8 @@ asn_put_objid(struct asn_buf *b, const struct asn_oid err = ASN_ERR_RANGE; } if (oid->subs[0] > 2 || - (oid->subs[0] < 2 && oid->subs[1] >= 40)) { + (oid->subs[0] < 2 && oid->subs[1] >= 40) || + (oid->subs[0] == 2 && oid->subs[1] > ASN_MAXID - 2 * 40)) { asn_error(NULL, "oid out of range (%u,%u)", oid->subs[0], oid->subs[1]); err = ASN_ERR_RANGE; @@ -814,10 +835,7 @@ asn_get_uint32_raw(struct asn_buf *b, asn_len_t len, u enum asn_err err; if ((err = asn_get_real_unsigned(b, len, &v)) == ASN_ERR_OK) { - if (len > 5) { - asn_error(b, "uint32 too long %u", len); - err = ASN_ERR_BADLEN; - } else if (v > UINT32_MAX) { + if (v > UINT32_MAX) { asn_error(b, "uint32 too large %llu", v); err = ASN_ERR_RANGE; } Modified: head/contrib/bsnmp/lib/bsnmpclient.3 ============================================================================== --- head/contrib/bsnmp/lib/bsnmpclient.3 Wed Apr 1 15:12:51 2020 (r359511) +++ head/contrib/bsnmp/lib/bsnmpclient.3 Wed Apr 1 15:25:16 2020 (r359512) @@ -31,7 +31,7 @@ .\" .\" $Begemot: bsnmp/lib/bsnmpclient.3,v 1.12 2005/10/04 08:46:50 brandt_h Exp $ .\" -.Dd December 31, 2016 +.Dd March 31, 2020 .Dt BSNMPCLIENT 3 .Os .Sh NAME @@ -177,7 +177,9 @@ If it is a local stream socket is used. For .Dv SNMP_TRANS_UDP -a UDP socket is created. +a UDPv4 socket and for +.Dv SNMP_TRANS_UDP6 +a UDPv6 socket is created. It uses the .Va chost field as the path to the server's socket for local sockets. @@ -675,7 +677,12 @@ The syntax of a server specification is .Pp where .Va trans -is the transport name (one of udp, stream or dgram), +is the transport name (one of +.Qq udp , +.Qq udp6 , +.Qq stream +or +.Qq dgram ) , .Va community is the string to be used for both the read and the write community, .Va server @@ -685,13 +692,51 @@ of a local socket, and is the port in case of UDP transport. The function returns 0 in the case of success and return -1 and sets the error string in case of an error. +.Pp +The function +.Fn snmp_parse_serverr +fills the transport, the port number and the community strings with +reasonable default values when they are not specified. +The default transport +is +.Dv SNMP_TRANS_UDP . +If the host name contains a slash the default is modified to +.Dv SNMP_TRANS_LOC_DGRAM . +If the host name looks like a numeric IPv6 address the default is +.Dv SNMP_TRANS_UDP6 . +For numeric IPv6 addresses the transport name udp is automatically +translated as +.Dv SNMP_TRANS_UDP6 . +The default port number (for +.Dv udp +or +.Dv udp6 ) +is +.Qq snmp . +The default read community is +.Qq public +and the default write community +.Qq private . +.Pp +.Fn snmp_parse_server +recognizes path names, host names and numerical IPv4 and IPv6 addresses. +A string consisting of digits and periods is assumed to be an IPv4 address +and must be parseable by +.Fn inet_aton 3 . +An IPv6 address is any string enclosed in square brackets. +It must be parseable with +.Fn gethostinfo 3 . +.Pp +The port number for +.Fn snmp_parse_server +can be specified numerically or symbolically. +It is ignored for local sockets. .Sh DIAGNOSTICS -If an error occurs in any of the function an error indication as described +If an error occurs in any of the functions an error indication as described above is returned. -Additionally the function sets a printable error string -in the +Additionally the function sets a printable error string in the .Va error -filed of +field of .Va snmp_client . .Sh SEE ALSO .Xr gensnmptree 1 , Modified: head/contrib/bsnmp/lib/snmpclient.c ============================================================================== --- head/contrib/bsnmp/lib/snmpclient.c Wed Apr 1 15:12:51 2020 (r359511) +++ head/contrib/bsnmp/lib/snmpclient.c Wed Apr 1 15:25:16 2020 (r359512) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004-2005,2018 + * Copyright (c) 2004-2005,2018-2019 * Hartmut Brandt. * All rights reserved. * Copyright (c) 2001-2003 @@ -930,7 +930,7 @@ open_client_udp(const char *host, const char *port) /* open connection */ memset(&hints, 0, sizeof(hints)); hints.ai_flags = AI_CANONNAME; - hints.ai_family = snmp_client.trans == SNMP_TRANS_UDP ? AF_INET: + hints.ai_family = snmp_client.trans == SNMP_TRANS_UDP ? AF_INET : AF_INET6; hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = 0; @@ -1884,7 +1884,8 @@ static const char *const trans_list[] = { /** * Try to get a transport identifier which is a leading alphanumeric string * terminated by a double colon. The string may not be empty. The transport - * identifier is optional. + * identifier is optional. Unknown transport identifiers are reject. + * Be careful: a double colon can also occur in a numeric IPv6 address. * * \param sc client struct to set errors * \param strp possible start of transport; updated to point to @@ -1899,8 +1900,6 @@ get_transp(struct snmp_client *sc, const char **strp) size_t i; for (i = 0; i < nitems(trans_list); i++) { - if (trans_list[i] == NULL || *trans_list[i] == '\0') - continue; p = strstr(*strp, trans_list[i]); if (p == *strp) { *strp += strlen(trans_list[i]); @@ -1908,13 +1907,23 @@ get_transp(struct snmp_client *sc, const char **strp) } } - p = *strp; - if (p[0] == ':' && p[1] == ':') { + p = strstr(*strp, "::"); + if (p == *strp) { seterr(sc, "empty transport specifier"); return (-1); } - /* by default assume UDP */ - return (SNMP_TRANS_UDP); + if (p == NULL) + /* by default assume UDP */ + return (SNMP_TRANS_UDP); + + /* ignore :: after [ */ + const char *ob = strchr(*strp, '['); + if (ob != NULL && p > ob) + /* by default assume UDP */ + return (SNMP_TRANS_UDP); + + seterr(sc, "unknown transport specifier '%.*s'", p - *strp, *strp); + return (-1); } /** @@ -2153,12 +2162,14 @@ int snmp_parse_server(struct snmp_client *sc, const char *str) { const char *const orig = str; + /* parse input */ - int i, trans = get_transp(sc, &str); + int def_trans = 0, trans = get_transp(sc, &str); if (trans < 0) return (-1); /* choose automatically */ - i = orig == str ? -1: trans; + if (orig == str) + def_trans = 1; const char *const comm[2] = { str, @@ -2204,7 +2215,7 @@ snmp_parse_server(struct snmp_client *sc, const char * } #if DEBUG_PARSE - printf("transp: %u\n", trans); + printf("transp: %d (def=%d)\n", trans, def_trans); printf("comm: %zu %zu\n", comm[0] - orig, comm[1] - orig); printf("ipv6: %zu %zu\n", ipv6[0] - orig, ipv6[1] - orig); printf("ipv4: %zu %zu\n", ipv4[0] - orig, ipv4[1] - orig); @@ -2218,18 +2229,19 @@ snmp_parse_server(struct snmp_client *sc, const char * if (ipv6[0] != ipv6[1]) { if ((chost = save_str(sc, ipv6)) == NULL) return (-1); - if (i == -1 || trans == SNMP_TRANS_UDP) + if (def_trans || trans == SNMP_TRANS_UDP) + /* assume the user meant udp6:: */ trans = SNMP_TRANS_UDP6; } else if (ipv4[0] != ipv4[1]) { if ((chost = save_str(sc, ipv4)) == NULL) return (-1); - if (i == -1) + if (def_trans) trans = SNMP_TRANS_UDP; } else { if ((chost = save_str(sc, host)) == NULL) return (-1); - if (i == -1) { + if (def_trans) { /* * Default transport is UDP unless the host contains * a slash in which case we default to DGRAM. @@ -2258,6 +2270,7 @@ snmp_parse_server(struct snmp_client *sc, const char * /* commit */ sc->trans = trans; + /* * If community string was specified and it is empty, overwrite it. * If it was not specified, use default. @@ -2276,7 +2289,7 @@ snmp_parse_server(struct snmp_client *sc, const char * #if DEBUG_PARSE printf("Committed values:\n"); - printf("trans: %u\n", sc->trans); + printf("trans: %d\n", sc->trans); printf("comm: '%s'/'%s'\n", sc->read_community, sc->write_community); printf("host: '%s'\n", sc->chost); printf("port: '%s'\n", sc->cport); Modified: head/contrib/bsnmp/lib/snmpcrypto.c ============================================================================== --- head/contrib/bsnmp/lib/snmpcrypto.c Wed Apr 1 15:12:51 2020 (r359511) +++ head/contrib/bsnmp/lib/snmpcrypto.c Wed Apr 1 15:25:16 2020 (r359512) @@ -57,10 +57,10 @@ #define SNMP_AUTH_KEY_LOOPCNT 1048576 #define SNMP_AUTH_BUF_SIZE 72 +#ifdef HAVE_LIBCRYPTO + static const uint8_t ipad = 0x36; static const uint8_t opad = 0x5c; - -#ifdef HAVE_LIBCRYPTO static int32_t snmp_digest_init(const struct snmp_user *user, EVP_MD_CTX *ctx, Modified: head/contrib/bsnmp/snmp_mibII/mibII.c ============================================================================== --- head/contrib/bsnmp/snmp_mibII/mibII.c Wed Apr 1 15:12:51 2020 (r359511) +++ head/contrib/bsnmp/snmp_mibII/mibII.c Wed Apr 1 15:25:16 2020 (r359512) @@ -447,7 +447,7 @@ mib_fetch_ifmib(struct mibif *ifp) void *newmib; struct ifmibdata oldmib = ifp->mib; struct ifreq irr; - unsigned int alias_maxlen = MIBIF_ALIAS_SIZE_MAX; + u_int alias_maxlen = MIBIF_ALIAS_SIZE_MAX; if (fetch_generic_mib(ifp, &oldmib) == -1) return (-1); @@ -519,7 +519,6 @@ mib_fetch_ifmib(struct mibif *ifp) } out: - /* * Find sysctl mib for net.ifdescr_maxlen (one time). * kmib[0] == -1 at first call to mib_fetch_ifmib(). @@ -581,7 +580,7 @@ mib_fetch_ifmib(struct mibif *ifp) ifp->alias = realloc(ifp->alias, ifp->alias_size); } -fin: + fin: ifp->mibtick = get_ticks(); return (0); } Modified: head/contrib/bsnmp/snmp_mibII/mibII.h ============================================================================== --- head/contrib/bsnmp/snmp_mibII/mibII.h Wed Apr 1 15:12:51 2020 (r359511) +++ head/contrib/bsnmp/snmp_mibII/mibII.h Wed Apr 1 15:25:16 2020 (r359512) @@ -57,7 +57,7 @@ #include "snmp_mibII.h" #include "mibII_tree.h" -/* maximum size of the interface alias unless overridden with net.ifdescr_maxlen */ +/* maximum size of interface alias unless overridden with net.ifdescr_maxlen */ #define MIBIF_ALIAS_SIZE (64 + 1) #define MIBIF_ALIAS_SIZE_MAX 1024 @@ -81,7 +81,6 @@ struct mibif_private { uint64_t hc_opackets; uint64_t hc_imcasts; uint64_t hc_ipackets; - }; #define MIBIF_PRIV(IFP) ((struct mibif_private *)((IFP)->private)) Modified: head/contrib/bsnmp/snmp_usm/usm_snmp.c ============================================================================== --- head/contrib/bsnmp/snmp_usm/usm_snmp.c Wed Apr 1 15:12:51 2020 (r359511) +++ head/contrib/bsnmp/snmp_usm/usm_snmp.c Wed Apr 1 15:25:16 2020 (r359512) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2010 The FreeBSD Foundation + * Copyright (c) 2010,2018 The FreeBSD Foundation * All rights reserved. * * This software was developed by Shteryana Sotirova Shopova under @@ -605,7 +605,7 @@ usm_dump(void) privstr[uuser->suser.priv_proto]); } -static const char usm_comment[] = \ +static const char usm_comment[] = "This module implements SNMP User-based Security Model defined in RFC 3414."; extern const struct snmp_module config; Modified: head/contrib/bsnmp/snmp_vacm/vacm_snmp.c ============================================================================== --- head/contrib/bsnmp/snmp_vacm/vacm_snmp.c Wed Apr 1 15:12:51 2020 (r359511) +++ head/contrib/bsnmp/snmp_vacm/vacm_snmp.c Wed Apr 1 15:25:16 2020 (r359512) @@ -1013,7 +1013,7 @@ vacm_dump(void) "excluded":"included"); } -static const char vacm_comment[] = \ +static const char vacm_comment[] = "This module implements SNMP View-based Access Control Model defined in RFC 3415."; extern const struct snmp_module config; Modified: head/contrib/bsnmp/snmpd/snmpd.config ============================================================================== --- head/contrib/bsnmp/snmpd/snmpd.config Wed Apr 1 15:12:51 2020 (r359511) +++ head/contrib/bsnmp/snmpd/snmpd.config Wed Apr 1 15:25:16 2020 (r359512) @@ -28,7 +28,7 @@ # # $Begemot: bsnmp/snmpd/snmpd.config,v 1.16 2006/02/14 09:04:20 brandt_h Exp $ # -# Example configuration file. +# Example configuration file for testing. # # @@ -38,56 +38,80 @@ host := foo.bar.com location := "Room 200" contact := "sysmeister@bar.com" system := 1 # FreeBSD -traphost := noc.bar.com +traphost := localhost trapport := 162 read := "public" -# Uncomment the line below that sets the community string -# to enable write access. -write := "geheim" +write := "geheim" # take care - this allows writing trap := "mytrap" +securityModelSNMPv1 := 1 +securityModelSNMPv2c := 2 + +noAuthNoPriv := 1 + # # Configuration # %snmpd begemotSnmpdDebugDumpPdus = 2 begemotSnmpdDebugSyslogPri = 7 +begemotSnmpdDebugSnmpTrace = 0 # -# Set the read and write communities. +# Set community strings. # -# The default value of the community strings is NULL (note, that this is -# different from the empty string). This disables both read and write access. -# To enable read access only the read community string must be set. Setting -# the write community string enables both read and write access with that -# string. +# Each community string has a permission attached to it - 1 for read only +# and 2 for read/write. Default is 1. Community strings must be unique. # # Be sure to understand the security implications of SNMPv2 - the community # strings are readable on the wire! # begemotSnmpdCommunityString.0.1 = $(read) -# begemotSnmpdCommunityString.0.2 = $(write) -# begemotSnmpdCommunityString.0.3 = "otherPublic" +begemotSnmpdCommunityPermission.0.1 = 1 +#begemotSnmpdCommunityString.0.2 = $(write) +#begemotSnmpdCommunityPermission.0.2 = 2 +#begemotSnmpdCommunityString.0.3 = "otherPublic" begemotSnmpdCommunityDisable = 1 # open standard SNMP ports -# begemotSnmpdPortStatus.[$(host)].161 = 1 -# begemotSnmpdPortStatus.127.0.0.1.161 = 1 +# 0.0.0.0:161 +begemotSnmpdTransInetStatus.1.4.0.0.0.0.161.1 = 4 -# UDP over IPv4: 127.0.0.1:161 -begemotSnmpdTransInetStatus.1.4.127.0.0.1.161.1 = 4 +# test the port table; IPv4 address +# 127.0.0.1:10161 +begemotSnmpdTransInetStatus.1.4.127.0.0.1.10161.1 = 4 -# UDP over IPv6: ::1:161 -begemotSnmpdTransInetStatus.2.16.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.161.1 = 4 +# test the port table; IPv6 address +# ::1:10162 +begemotSnmpdTransInetStatus.2.16.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.10162.1 = 4 +# :::10163 +begemotSnmpdTransInetStatus.2.16.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.10163.1 = 4 +# fe80::1%1:10164 - requires inet fe80::1%em0/64 +begemotSnmpdTransInetStatus.4.20.254.128.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.0.0.1.10164.1 = 4 +# fe80::1%2:10164 - requires inet fe80::1%em1/64 +begemotSnmpdTransInetStatus.4.20.254.128.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.0.0.2.10164.1 = 4 +# fe80::1:10170 - should fail (no scope index) +# begemotSnmpdTransInetStatus.2.16.254.128.0.0.0.0.0.0.0.0.0.0.0.0.0.1.10170.1 = 4 +# fe80::1%0:10170 - should fail (default scope index for link local address) +# begemotSnmpdTransInetStatus.4.20.254.128.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.0.0.0.10170.1 = 4 -# Use domain name and IPv6 link-local address with scope zone id as address -# begemotSnmpdTransInetStatus.16."localhost".161.1 = 4 -# begemotSnmpdTransInetStatus.16."fe80::1%em0".161.1 = 4 +# test the port table; DNS address +# :10165 UDPv4 and UDPv6 +begemotSnmpdTransInetStatus.16.0.10165.1 = 4 +# 127.0.0.1:10166 +# ::1:10166 +begemotSnmpdTransInetStatus.16."localhost".10166.1 = 4 +# ::1:10167 +begemotSnmpdTransInetStatus.16."localhost6".10167.1 = 4 +# fe80::1%em0:10168 - requires inet fe80::$em0/64 +begemotSnmpdTransInetStatus.16."fe80::1%em0".10168.1 = 4 +# fe80::1%em1:10169 - requires inet fe80::$em1/64 +begemotSnmpdTransInetStatus.16."fe80::1%em1".10169.1 = 4 # open a unix domain socket -begemotSnmpdLocalPortStatus."/var/run/snmpd.sock" = 1 -begemotSnmpdLocalPortType."/var/run/snmpd.sock" = 4 +# begemotSnmpdLocalPortStatus."/var/run/snmpd.sock" = 1 +# begemotSnmpdLocalPortType."/var/run/snmpd.sock" = 4 # send traps to the traphost begemotTrapSinkStatus.[$(traphost)].$(trapport) = 4 @@ -103,12 +127,57 @@ snmpEnableAuthenTraps = 2 # # Load MIB-2 module # +#begemotSnmpdModulePath."mibII" = "../snmp_mibII/.libs/snmp_mibII.so" begemotSnmpdModulePath."mibII" = "/usr/local/lib/snmp_mibII.so" # +# SNMPv3 notification targets +# +#begemotSnmpdModulePath."target" = "../snmp_target/.libs/snmp_target.so" +begemotSnmpdModulePath."target" = "/usr/local/lib/snmp_target.so" + +# +# SNMPv3 user-based security module +# +#begemotSnmpdModulePath."usm" = "../snmp_usm/.libs/snmp_usm.so" +begemotSnmpdModulePath."usm" = "/usr/local/lib/snmp_usm.so" + +# +# SNMPv3 view-based access control module +# +#begemotSnmpdModulePath."vacm" = "../snmp_vacm/.libs/snmp_vacm.so" +begemotSnmpdModulePath."vacm" = "/usr/local/lib/snmp_vacm.so" + +# # Netgraph module # -begemotSnmpdModulePath."netgraph" = "/usr/local/lib/snmp_netgraph.so" +# begemotSnmpdModulePath."netgraph" = "/usr/local/lib/snmp_netgraph.so" +# %netgraph +# begemotNgControlNodeName = "snmpd" -%netgraph -begemotNgControlNodeName = "snmpd" +%vacm + +internetoid := 1.3.6.1 +internetoidlen := 4 + +vacmSecurityToGroupStatus.$(securityModelSNMPv1).$(read) = 4 +vacmGroupName.$(securityModelSNMPv1).$(read) = $(read) + +vacmSecurityToGroupStatus.$(securityModelSNMPv2c).$(read) = 4 +vacmGroupName.$(securityModelSNMPv2c).$(read) = $(read) + +vacmSecurityToGroupStatus.$(securityModelSNMPv2c).$(write) = 4 +vacmGroupName.$(securityModelSNMPv2c).$(write) = $(write) + +vacmViewTreeFamilyStatus."internet".$(internetoidlen).$(internetoid) = 4 + +vacmAccessStatus.$(read)."".$(securityModelSNMPv1).$(noAuthNoPriv) = 4 +vacmAccessReadViewName.$(read)."".$(securityModelSNMPv1).$(noAuthNoPriv) = "internet" + +vacmAccessStatus.$(write)."".$(securityModelSNMPv2c).$(noAuthNoPriv) = 4 +vacmAccessStatus.$(read)."".$(securityModelSNMPv2c).$(noAuthNoPriv) = 4 +vacmAccessReadViewName.$(write)."".$(securityModelSNMPv2c).$(noAuthNoPriv) = "internet" +vacmAccessReadViewName.$(read)."".$(securityModelSNMPv2c).$(noAuthNoPriv) = "internet" +vacmAccessWriteViewName.$(write)."".$(securityModelSNMPv2c).$(noAuthNoPriv) = "internet" +vacmAccessWriteViewName.$(read)."".$(securityModelSNMPv2c).$(noAuthNoPriv) = "internet" + Copied: head/contrib/bsnmp/snmpd/trans_inet.c (from r359490, vendor/bsnmp/dist/snmpd/trans_inet.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/contrib/bsnmp/snmpd/trans_inet.c Wed Apr 1 15:25:16 2020 (r359512, copy of r359490, vendor/bsnmp/dist/snmpd/trans_inet.c) @@ -0,0 +1,1341 @@ +/* + * Copyright (c) 2018 + * Hartmut Brandt. + * All rights reserved. + * + * Author: Harti Brandt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Begemot: bsnmp/snmpd/trans_udp.c,v 1.5 2005/10/04 08:46:56 brandt_h Exp $ + * + * Internet transport + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include "asn1.h" +#include "snmp.h" +#include "snmpmod.h" + +#include "snmpd.h" + +#define SNMPTREE_TYPES +#define SNMPENUM_FUNCS +#include "tree.h" +#include "oid.h" + +extern const struct transport_def inet_trans; + +struct inet_port; +struct inet_port_params; +struct port_sock; + +typedef int create_func(struct inet_port *, struct inet_port_params *); +typedef void input_func(int, void *); +typedef int activate_func(struct inet_port *); +typedef void deactivate_func(struct inet_port *); +typedef void parse_ctrl_func(struct port_sock *, const struct msghdr *); +typedef void setsrc_func(struct port_sock *, struct msghdr *); + +static create_func ipv4_create; +static input_func ipv4_input; +static activate_func ipv4_activate; +static deactivate_func ipv4_deactivate; +static parse_ctrl_func ipv4_parse_ctrl; +static setsrc_func ipv4_setsrc; + +static create_func ipv6_create; +static input_func ipv6_input; +static activate_func ipv6_activate; +static deactivate_func ipv6_deactivate; +static parse_ctrl_func ipv6_parse_ctrl; +static setsrc_func ipv6_setsrc; + +static create_func ipv6z_create; + +static create_func dns_create; +static activate_func dns_activate; +static deactivate_func dns_deactivate; + +struct port_sock { + /* common input stuff; must be first */ + struct port_input input; + + /** link field */ + TAILQ_ENTRY(port_sock) link; + + /** pointer to parent */ + struct inet_port *port; + + /** bind address */ + struct sockaddr_storage bind_addr; + + /** reply destination */ + struct sockaddr_storage ret_dest; + + /** need to set source address in reply; set for INADDR_ANY */ + bool set_ret_source; + + /** address of the receive interface */ + union { + /** IPv4 case */ + struct in_addr a4; + + /** IPv6 case */ + struct in6_pktinfo a6; + } ret_source; + + /** parse control message */ + parse_ctrl_func *parse_ctrl; + + /** set source address for a send() */ + setsrc_func *setsrc; +}; +static_assert(offsetof(struct port_sock, input) == 0, + "input not first in port_sock"); + +/** + * Table row for the inet ports. + * + * When actived each row can have one or several open sockets. For ipv6, + * ipv4 and ipv6z addresses it is always one, for dns addresses more than + * one socket can be open. + */ +struct inet_port { + /** common i/o port stuff (must be first) */ + struct tport tport; + + /** transport protocol */ + enum BegemotSnmpdTransportProto proto; + + /** row status */ + enum RowStatus row_status; + + /** socket list */ + TAILQ_HEAD(, port_sock) socks; + + /** value for InetAddressType::dns */ + char *dns_addr; + + /** port number in dns case; network byte order */ + uint16_t dns_port; + + /** create a port */ + create_func *create; + + /** activate a port */ + activate_func *activate; + + /** deactivate port */ + deactivate_func *deactivate; +}; +static_assert(offsetof(struct inet_port, tport) == 0, + "tport not first in inet_port"); + +/** to be used in bind_addr field */ +#define AF_DNS AF_VENDOR00 + +/** registered transport */ +static struct transport *my_trans; + +/** set operation */ +enum { + SET_CREATED, + SET_ACTIVATED, + SET_DEACTIVATE, + SET_DESTROY, +}; + +/** length of the control data buffer */ +static const size_t RECV_CBUF_SIZE = + MAX(CMSG_SPACE(SOCKCREDSIZE(CMGROUP_MAX)) + + CMSG_SPACE(sizeof(struct in_addr)), + CMSG_SPACE(SOCKCREDSIZE(CMGROUP_MAX)) + + CMSG_SPACE(sizeof(struct in6_pktinfo))); + +/** length of the control data buffer */ +static const size_t XMIT_CBUF_SIZE = + MAX(CMSG_SPACE(sizeof(struct in_addr)), + CMSG_SPACE(sizeof(struct in6_pktinfo))); + +/** + * Start the transport. This registers the transport with the + * transport table. + * + * \return SNMP error code + */ +static int +inet_start(void) +{ + return (trans_register(&inet_trans, &my_trans)); +} + +/** + * Stop the transport. This tries to unregister the transport which + * in turn fails if the list of ports is not empty. + * + * \return SNMP error code + */ +static int +inet_stop(int force __unused) +{ + if (my_trans != NULL) + if (trans_unregister(my_trans) != 0) + return (SNMP_ERR_GENERR); + return (SNMP_ERR_NOERROR); +} + +/** + * Deactivate SNMP port. + * + * \param tp port to close + */ +static void +deactivate_port(struct inet_port *p) +{ + p->deactivate(p); +} + +/* + * This function activates a port. For ports opened via the config files + * this is called just before entering the event loop. For ports create + * during runtime this is called when the RowStatus is set to Active or + * as second step for CreateAndGo. + * + * \param tp transport port + * + * \return SNMP error code + */ +static int +inet_activate(struct tport *tp) +{ + struct inet_port *port = (struct inet_port *)tp; + + return (port->activate(port)); +} + +/* + * Close the SNMP port if it is open and destroy it. + * + * \param tp port to close + */ +static void +inet_destroy_port(struct tport *tp) +{ + struct inet_port *port = (struct inet_port *)tp; + + deactivate_port(port); + + trans_remove_port(tp); + + free(port->dns_addr); + free(port); +} + +/** + * If the input struct has no buffer allocated yet, do it now. If allocation + * fails, read the data into a local buffer and drop it. + * + * \param pi input struct + * + * \return -1 if allocation fails, 0 otherwise + */ +static int +inet_alloc_buf(struct port_input *pi) +{ + char drop_buf[2000]; + + if (pi->buf == NULL) { + if ((pi->buf = buf_alloc(0)) == NULL) { + (void)recvfrom(pi->fd, drop_buf, sizeof(drop_buf), + 0, NULL, NULL); + return (-1); + } + pi->buflen = buf_size(0); + } + return (0); +} + +/** + * Read message into input buffer. Get also the source address and any + * control data that is available. If the message is truncated, increment + * corresponding statistics. + * + * \param pi input object + * \param msg message object to fill + * \param cbuf control data buffer + * + * \return -1 when something goes wrong, 0 othersise + */ +static int +inet_read_msg(struct port_input *pi, struct msghdr *msg, char *cbuf) +{ + struct iovec iov[1]; + + iov[0].iov_base = pi->buf; + iov[0].iov_len = pi->buflen; + + msg->msg_name = pi->peer; + msg->msg_namelen = pi->peerlen; + msg->msg_iov = iov; + msg->msg_iovlen = 1; + msg->msg_control = cbuf; + msg->msg_controllen = RECV_CBUF_SIZE; + msg->msg_flags = 0; + + memset(cbuf, 0, RECV_CBUF_SIZE); + + const ssize_t len = recvmsg(pi->fd, msg, 0); + + if (len == -1 || len == 0) + /* receive error */ + return (-1); + + if (msg->msg_flags & MSG_TRUNC) { + /* truncated - drop */ + snmpd_stats.silentDrops++; + snmpd_stats.inTooLong++; + return (-1); + } *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***