Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 1 Apr 2020 15:25:16 +0000 (UTC)
From:      Hartmut Brandt <harti@FreeBSD.org>
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
Message-ID:  <202004011525.031FPGKm079714@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 <harti@freebsd.org>
+ *
+ * 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 <sys/param.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <netdb.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+
+#include <stdio.h>
+
+#include <arpa/inet.h>
+
+#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 ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202004011525.031FPGKm079714>