From owner-svn-src-all@freebsd.org Fri Jan 19 08:48:16 2018 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 96837ECB3EF; Fri, 19 Jan 2018 08:48:16 +0000 (UTC) (envelope-from ae@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 580C1788F2; Fri, 19 Jan 2018 08:48:16 +0000 (UTC) (envelope-from ae@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 A148B2E4F; Fri, 19 Jan 2018 08:48:15 +0000 (UTC) (envelope-from ae@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w0J8mFEF091048; Fri, 19 Jan 2018 08:48:15 GMT (envelope-from ae@FreeBSD.org) Received: (from ae@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w0J8mEKg091042; Fri, 19 Jan 2018 08:48:14 GMT (envelope-from ae@FreeBSD.org) Message-Id: <201801190848.w0J8mEKg091042@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: ae set sender to ae@FreeBSD.org using -f From: "Andrey V. Elsukov" Date: Fri, 19 Jan 2018 08:48:14 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r328160 - head/contrib/bsnmp/snmpd X-SVN-Group: head X-SVN-Commit-Author: ae X-SVN-Commit-Paths: head/contrib/bsnmp/snmpd X-SVN-Commit-Revision: 328160 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 19 Jan 2018 08:48:16 -0000 Author: ae Date: Fri Jan 19 08:48:14 2018 New Revision: 328160 URL: https://svnweb.freebsd.org/changeset/base/328160 Log: Add to bsnmpd(1) ability to specify multiple community strings with different access rights. By default there are two community strings with index 1 and 2, one for read-only access and second for read-write access: begemotSnmpdCommunityString.0.1 = $(read) begemotSnmpdCommunityString.0.2 = $(write) Now it is possible to define additional community strings using different indexes: begemotSnmpdCommunityString.0.3 = "SomeString1" begemotSnmpdCommunityPermission.0.3 = 1 begemotSnmpdCommunityString.0.4 = "SomeString2" begemotSnmpdCommunityPermission.0.4 = 2 begemotSnmpdCommunityString.0.5 = "SomeString3" begemotSnmpdCommunityString.0.6 = "SomeString4" New attribute begemotSnmpdCommunityPermission can be used to specify access rights: 1 means "read-only" access, 2 means "read-write" access. If attribute is not specified for some index this means "read-only" rights. Community strings must be unique, i.e. must not be the same for different indexes. Obtained from: Yandex LLC MFC after: 2 weeks Sponsored by: Yandex LLC Differential Revision: https://reviews.freebsd.org/D13785 Modified: head/contrib/bsnmp/snmpd/BEGEMOT-SNMPD.txt head/contrib/bsnmp/snmpd/action.c head/contrib/bsnmp/snmpd/main.c head/contrib/bsnmp/snmpd/snmpd.config head/contrib/bsnmp/snmpd/snmpmod.h head/contrib/bsnmp/snmpd/tree.def Modified: head/contrib/bsnmp/snmpd/BEGEMOT-SNMPD.txt ============================================================================== --- head/contrib/bsnmp/snmpd/BEGEMOT-SNMPD.txt Fri Jan 19 04:34:06 2018 (r328159) +++ head/contrib/bsnmp/snmpd/BEGEMOT-SNMPD.txt Fri Jan 19 08:48:14 2018 (r328160) @@ -44,7 +44,7 @@ IMPORTS FROM BEGEMOT-MIB; begemotSnmpd MODULE-IDENTITY - LAST-UPDATED "200212040000Z" + LAST-UPDATED "201801190000Z" ORGANIZATION "Fraunhofer FOKUS, CATS" CONTACT-INFO " Hartmut Brandt @@ -274,7 +274,8 @@ BegemotSnmpdCommunityEntry ::= SEQUENCE { begemotSnmpdCommunityModule SectionName, begemotSnmpdCommunityIndex Unsigned32, begemotSnmpdCommunityString OCTET STRING, - begemotSnmpdCommunityDescr OCTET STRING + begemotSnmpdCommunityDescr OCTET STRING, + begemotSnmpdCommunityPermission INTEGER } begemotSnmpdCommunityModule OBJECT-TYPE @@ -309,6 +310,14 @@ begemotSnmpdCommunityDescr OBJECT-TYPE DESCRIPTION "A description what this community is good for." ::= { begemotSnmpdCommunityEntry 4 } + +begemotSnmpdCommunityPermission OBJECT-TYPE + SYNTAX INTEGER (1..4294967295) + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "The numerical value of access rights granted to the community." + ::= { begemotSnmpdCommunityEntry 5 } -- -- Module table Modified: head/contrib/bsnmp/snmpd/action.c ============================================================================== --- head/contrib/bsnmp/snmpd/action.c Fri Jan 19 04:34:06 2018 (r328159) +++ head/contrib/bsnmp/snmpd/action.c Fri Jan 19 08:48:14 2018 (r328160) @@ -751,8 +751,9 @@ int op_community(struct snmp_context *ctx, struct snmp_value *value, u_int sub, u_int iidx __unused, enum snmp_op op) { - asn_subid_t which = value->var.subs[sub - 1]; + struct asn_oid index; struct community *c; + asn_subid_t which = value->var.subs[sub - 1]; switch (op) { @@ -770,12 +771,47 @@ op_community(struct snmp_context *ctx, struct snmp_val break; case SNMP_OP_SET: - if ((community != COMM_INITIALIZE && snmpd.comm_dis) || - (c = FIND_OBJECT_OID(&community_list, &value->var, sub)) == NULL) - return (SNMP_ERR_NO_CREATION); - if (which != LEAF_begemotSnmpdCommunityString) + if (community != COMM_INITIALIZE && snmpd.comm_dis) return (SNMP_ERR_NOT_WRITEABLE); - return (string_save(value, ctx, -1, &c->string)); + index.len = 2; + index.subs[0] = 0; + index.subs[1] = value->var.subs[value->var.len - 1]; + switch (which) { + case LEAF_begemotSnmpdCommunityString: + /* check that given string is unique */ + TAILQ_FOREACH(c, &community_list, link) { + if (!asn_compare_oid(&index, &c->index)) + continue; + if (c->string != NULL && strcmp(c->string, + value->v.octetstring.octets) == 0) + return (SNMP_ERR_WRONG_VALUE); + } + case LEAF_begemotSnmpdCommunityPermission: + break; + default: + return (SNMP_ERR_NOT_WRITEABLE); + } + if ((c = FIND_OBJECT_OID(&community_list, &value->var, + sub)) == NULL) { + /* create new community and use user sepcified index */ + c = comm_define_ordered(COMM_READ, "SNMP Custom Community", + &index, NULL, NULL); + if (c == NULL) + return (SNMP_ERR_NO_CREATION); + } + switch (which) { + case LEAF_begemotSnmpdCommunityString: + return (string_save(value, ctx, -1, &c->string)); + case LEAF_begemotSnmpdCommunityPermission: + if (value->v.integer != COMM_READ && + value->v.integer != COMM_WRITE) + return (SNMP_ERR_WRONG_VALUE); + c->private = value->v.integer; + break; + default: + return (SNMP_ERR_NOT_WRITEABLE); + } + return (SNMP_ERR_NOERROR); case SNMP_OP_ROLLBACK: if (which == LEAF_begemotSnmpdCommunityString) { @@ -786,6 +822,8 @@ op_community(struct snmp_context *ctx, struct snmp_val string_rollback(ctx, &c->string); return (SNMP_ERR_NOERROR); } + if (which == LEAF_begemotSnmpdCommunityPermission) + return (SNMP_ERR_NOERROR); abort(); case SNMP_OP_COMMIT: @@ -797,6 +835,8 @@ op_community(struct snmp_context *ctx, struct snmp_val string_commit(ctx); return (SNMP_ERR_NOERROR); } + if (which == LEAF_begemotSnmpdCommunityPermission) + return (SNMP_ERR_NOERROR); abort(); default: @@ -810,6 +850,12 @@ op_community(struct snmp_context *ctx, struct snmp_val case LEAF_begemotSnmpdCommunityDescr: return (string_get(value, c->descr, -1)); + + case LEAF_begemotSnmpdCommunityPermission: + value->v.integer = c->private; + return (SNMP_ERR_NOERROR); + default: + return (SNMP_ERR_NOT_WRITEABLE); } abort(); } Modified: head/contrib/bsnmp/snmpd/main.c ============================================================================== --- head/contrib/bsnmp/snmpd/main.c Fri Jan 19 04:34:06 2018 (r328159) +++ head/contrib/bsnmp/snmpd/main.c Fri Jan 19 08:48:14 2018 (r328160) @@ -1160,8 +1160,8 @@ snmpd_input(struct port_input *pi, struct tport *tport */ if (pdu.version < SNMP_V3 && ((pi->cred && !pi->priv && pdu.type == SNMP_PDU_SET) || - (community != COMM_WRITE && - (pdu.type == SNMP_PDU_SET || community != COMM_READ)))) { + (comm != NULL && comm->private != COMM_WRITE && + (pdu.type == SNMP_PDU_SET || comm->private != COMM_READ)))) { snmpd_stats.inBadCommunityUses++; snmp_pdu_free(&pdu); snmp_input_consume(pi); @@ -1609,8 +1609,8 @@ main(int argc, char *argv[]) /* * Get standard communities */ - (void)comm_define(1, "SNMP read", NULL, NULL); - (void)comm_define(2, "SNMP write", NULL, NULL); + comm_define(COMM_READ, "SNMP read", NULL, NULL); + comm_define(COMM_WRITE, "SNMP write", NULL, NULL); community = COMM_INITIALIZE; trap_reqid = reqid_allocate(512, NULL); @@ -2027,25 +2027,23 @@ asn_error_func(const struct asn_buf *b, const char *er /* * Create a new community */ -u_int -comm_define(u_int priv, const char *descr, struct lmodule *owner, - const char *str) +struct community* +comm_define_ordered(u_int priv, const char *descr, struct asn_oid *index, + struct lmodule *owner, const char *str) { struct community *c, *p; u_int ncomm; - /* generate an identifier */ - do { - if ((ncomm = next_community_index++) == UINT_MAX) - next_community_index = 1; - TAILQ_FOREACH(c, &community_list, link) - if (c->value == ncomm) - break; - } while (c != NULL); + ncomm = index->subs[index->len - 1]; + /* check that community doesn't already exist */ + TAILQ_FOREACH(c, &community_list, link) + if (c->value == ncomm) + return (c); + if ((c = malloc(sizeof(struct community))) == NULL) { - syslog(LOG_ERR, "comm_define: %m"); - return (0); + syslog(LOG_ERR, "%s: %m", __func__); + return (NULL); } c->owner = owner; c->value = ncomm; @@ -2056,23 +2054,14 @@ comm_define(u_int priv, const char *descr, struct lmod if (str != NULL) { if((c->string = malloc(strlen(str)+1)) == NULL) { free(c); - return (0); + return (NULL); } strcpy(c->string, str); } - - /* make index */ - if (c->owner == NULL) { - c->index.len = 1; - c->index.subs[0] = 0; - } else { - c->index = c->owner->index; - } - c->index.subs[c->index.len++] = c->private; - /* * Insert ordered */ + c->index = *index; TAILQ_FOREACH(p, &community_list, link) { if (asn_compare_oid(&p->index, &c->index) > 0) { TAILQ_INSERT_BEFORE(p, c, link); @@ -2081,6 +2070,38 @@ comm_define(u_int priv, const char *descr, struct lmod } if (p == NULL) TAILQ_INSERT_TAIL(&community_list, c, link); + return (c); +} + +u_int +comm_define(u_int priv, const char *descr, struct lmodule *owner, + const char *str) +{ + struct asn_oid index, *p; + struct community *c; + u_int ncomm; + + /* generate an identifier */ + do { + if ((ncomm = next_community_index++) == UINT_MAX) + next_community_index = 1; + TAILQ_FOREACH(c, &community_list, link) + if (c->value == ncomm) + break; + } while (c != NULL); + + /* make index */ + if (owner != NULL) + p = &owner->index; + else { + p = &index; + p->len = 1; + p->subs[0] = 0; + } + p->subs[p->len++] = ncomm; + c = comm_define_ordered(priv, descr, p, owner, str); + if (c == NULL) + return (0); return (c->value); } Modified: head/contrib/bsnmp/snmpd/snmpd.config ============================================================================== --- head/contrib/bsnmp/snmpd/snmpd.config Fri Jan 19 04:34:06 2018 (r328159) +++ head/contrib/bsnmp/snmpd/snmpd.config Fri Jan 19 08:48:14 2018 (r328160) @@ -68,6 +68,7 @@ begemotSnmpdDebugSyslogPri = 7 # begemotSnmpdCommunityString.0.1 = $(read) # begemotSnmpdCommunityString.0.2 = $(write) +# begemotSnmpdCommunityString.0.3 = "otherPublic" begemotSnmpdCommunityDisable = 1 # open standard SNMP ports Modified: head/contrib/bsnmp/snmpd/snmpmod.h ============================================================================== --- head/contrib/bsnmp/snmpd/snmpmod.h Fri Jan 19 04:34:06 2018 (r328159) +++ head/contrib/bsnmp/snmpd/snmpmod.h Fri Jan 19 08:48:14 2018 (r328160) @@ -334,6 +334,8 @@ extern struct systemg systemg; #define COMM_WRITE 2 u_int comm_define(u_int, const char *descr, struct lmodule *, const char *str); +struct community *comm_define_ordered(u_int priv, const char *descr, + struct asn_oid *index, struct lmodule *owner, const char *str); const char * comm_string(u_int); /* community for current packet */ Modified: head/contrib/bsnmp/snmpd/tree.def ============================================================================== --- head/contrib/bsnmp/snmpd/tree.def Fri Jan 19 04:34:06 2018 (r328159) +++ head/contrib/bsnmp/snmpd/tree.def Fri Jan 19 08:48:14 2018 (r328160) @@ -135,6 +135,7 @@ typedef RowStatus ENUM ( (2 begemotSnmpdCommunityIndex UNSIGNED32) (3 begemotSnmpdCommunityString OCTETSTRING GET SET) (4 begemotSnmpdCommunityDescr OCTETSTRING GET) + (5 begemotSnmpdCommunityPermission INTEGER GET SET) )) # # Module table