summaryrefslogtreecommitdiffstats
path: root/contrib/bsnmp/lib/snmpagent.c
diff options
context:
space:
mode:
authorsyrinx <syrinx@FreeBSD.org>2013-10-17 11:49:46 +0000
committersyrinx <syrinx@FreeBSD.org>2013-10-17 11:49:46 +0000
commitf7282ff245e4c8ffa3c6689fc2714d94bdf5863e (patch)
tree78b203f49281a1f8b30ef14d14de7ea0fafb6aa6 /contrib/bsnmp/lib/snmpagent.c
parentb7fd4846e58549b232ed7e909aafea11ca0ec2a6 (diff)
downloadFreeBSD-src-f7282ff245e4c8ffa3c6689fc2714d94bdf5863e.zip
FreeBSD-src-f7282ff245e4c8ffa3c6689fc2714d94bdf5863e.tar.gz
Fix SNMP Error response PDUs and properly encode them when using v3 auth/encryption.
Reported by: harti@
Diffstat (limited to 'contrib/bsnmp/lib/snmpagent.c')
-rw-r--r--contrib/bsnmp/lib/snmpagent.c47
1 files changed, 43 insertions, 4 deletions
diff --git a/contrib/bsnmp/lib/snmpagent.c b/contrib/bsnmp/lib/snmpagent.c
index 888d622..ee92420 100644
--- a/contrib/bsnmp/lib/snmpagent.c
+++ b/contrib/bsnmp/lib/snmpagent.c
@@ -166,7 +166,7 @@ find_subnode(const struct snmp_value *value)
}
static void
-snmp_pdu_create_response(struct snmp_pdu *pdu, struct snmp_pdu *resp)
+snmp_pdu_create_response(const struct snmp_pdu *pdu, struct snmp_pdu *resp)
{
memset(resp, 0, sizeof(*resp));
strcpy(resp->community, pdu->community);
@@ -952,18 +952,57 @@ enum snmp_ret
snmp_make_errresp(const struct snmp_pdu *pdu, struct asn_buf *pdu_b,
struct asn_buf *resp_b)
{
+ u_char type;
asn_len_t len;
struct snmp_pdu resp;
enum asn_err err;
enum snmp_code code;
- memset(&resp, 0, sizeof(resp));
+ snmp_pdu_create_response(pdu, &resp);
+
if ((code = snmp_pdu_decode_header(pdu_b, &resp)) != SNMP_CODE_OK)
return (SNMP_RET_IGN);
- if (pdu_b->asn_len < len)
+ if (pdu->version == SNMP_V3) {
+ if (resp.user.priv_proto != SNMP_PRIV_NOPRIV &&
+ (asn_get_header(pdu_b, &type, &resp.scoped_len) != ASN_ERR_OK
+ || type != ASN_TYPE_OCTETSTRING)) {
+ snmp_error("cannot decode encrypted pdu");
+ return (SNMP_RET_IGN);
+ }
+
+ if (asn_get_sequence(pdu_b, &len) != ASN_ERR_OK) {
+ snmp_error("cannot decode scoped pdu header");
+ return (SNMP_RET_IGN);
+ }
+
+ len = SNMP_ENGINE_ID_SIZ;
+ if (asn_get_octetstring(pdu_b, (u_char *)resp.context_engine,
+ &len) != ASN_ERR_OK) {
+ snmp_error("cannot decode msg context engine");
+ return (SNMP_RET_IGN);
+ }
+ resp.context_engine_len = len;
+ len = SNMP_CONTEXT_NAME_SIZ;
+ if (asn_get_octetstring(pdu_b, (u_char *)resp.context_name,
+ &len) != ASN_ERR_OK) {
+ snmp_error("cannot decode msg context name");
+ return (SNMP_RET_IGN);
+ }
+ resp.context_name[len] = '\0';
+ }
+
+
+ if (asn_get_header(pdu_b, &type, &len) != ASN_ERR_OK) {
+ snmp_error("cannot get pdu header");
return (SNMP_RET_IGN);
- pdu_b->asn_len = len;
+ }
+
+ if ((type & ~ASN_TYPE_MASK) !=
+ (ASN_TYPE_CONSTRUCTED | ASN_CLASS_CONTEXT)) {
+ snmp_error("bad pdu header tag");
+ return (SNMP_RET_IGN);
+ }
err = snmp_parse_pdus_hdr(pdu_b, &resp, &len);
if (ASN_ERR_STOPPED(err))
OpenPOWER on IntegriCloud