Fix SNMP Error response PDUs and properly encode them when using v3 auth/encryption.
Reported by: harti@
This commit is contained in:
parent
a1739e7e15
commit
0698344859
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=256678
@ -288,11 +288,13 @@ parse_secparams(struct asn_buf *b, struct snmp_pdu *pdu)
|
|||||||
memset(buf, 0, 256);
|
memset(buf, 0, 256);
|
||||||
tb.asn_ptr = buf;
|
tb.asn_ptr = buf;
|
||||||
tb.asn_len = 256;
|
tb.asn_len = 256;
|
||||||
|
u_int len;
|
||||||
|
|
||||||
if (asn_get_octetstring(b, buf, &tb.asn_len) != ASN_ERR_OK) {
|
if (asn_get_octetstring(b, buf, &len) != ASN_ERR_OK) {
|
||||||
snmp_error("cannot parse usm header");
|
snmp_error("cannot parse usm header");
|
||||||
return (ASN_ERR_FAILED);
|
return (ASN_ERR_FAILED);
|
||||||
}
|
}
|
||||||
|
tb.asn_len = len;
|
||||||
|
|
||||||
if (asn_get_sequence(&tb, &octs_len) != ASN_ERR_OK) {
|
if (asn_get_sequence(&tb, &octs_len) != ASN_ERR_OK) {
|
||||||
snmp_error("cannot decode usm header");
|
snmp_error("cannot decode usm header");
|
||||||
@ -864,7 +866,7 @@ snmp_fix_encoding(struct asn_buf *b, struct snmp_pdu *pdu)
|
|||||||
return (SNMP_CODE_FAILED);
|
return (SNMP_CODE_FAILED);
|
||||||
|
|
||||||
pdu->scoped_len = b->asn_ptr - pdu->scoped_ptr;
|
pdu->scoped_len = b->asn_ptr - pdu->scoped_ptr;
|
||||||
if ((code = snmp_pdu_fix_padd(b, pdu))!= ASN_ERR_OK)
|
if (snmp_pdu_fix_padd(b, pdu) != ASN_ERR_OK)
|
||||||
return (SNMP_CODE_FAILED);
|
return (SNMP_CODE_FAILED);
|
||||||
|
|
||||||
if (pdu->security_model != SNMP_SECMODEL_USM)
|
if (pdu->security_model != SNMP_SECMODEL_USM)
|
||||||
@ -997,7 +999,7 @@ snmp_pdu_encode(struct snmp_pdu *pdu, struct asn_buf *resp_b)
|
|||||||
if ((err = snmp_pdu_encode_header(resp_b, pdu)) != SNMP_CODE_OK)
|
if ((err = snmp_pdu_encode_header(resp_b, pdu)) != SNMP_CODE_OK)
|
||||||
return (err);
|
return (err);
|
||||||
for (idx = 0; idx < pdu->nbindings; idx++)
|
for (idx = 0; idx < pdu->nbindings; idx++)
|
||||||
if ((err = snmp_binding_encode(resp_b, &pdu->bindings[idx]))
|
if (snmp_binding_encode(resp_b, &pdu->bindings[idx])
|
||||||
!= ASN_ERR_OK)
|
!= ASN_ERR_OK)
|
||||||
return (SNMP_CODE_FAILED);
|
return (SNMP_CODE_FAILED);
|
||||||
|
|
||||||
|
@ -182,7 +182,7 @@ struct snmp_pdu {
|
|||||||
|
|
||||||
/* fixes for encoding */
|
/* fixes for encoding */
|
||||||
size_t outer_len;
|
size_t outer_len;
|
||||||
size_t scoped_len;
|
asn_len_t scoped_len;
|
||||||
u_char *outer_ptr;
|
u_char *outer_ptr;
|
||||||
u_char *digest_ptr;
|
u_char *digest_ptr;
|
||||||
u_char *encrypted_ptr;
|
u_char *encrypted_ptr;
|
||||||
|
@ -166,7 +166,7 @@ find_subnode(const struct snmp_value *value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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));
|
memset(resp, 0, sizeof(*resp));
|
||||||
strcpy(resp->community, pdu->community);
|
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,
|
snmp_make_errresp(const struct snmp_pdu *pdu, struct asn_buf *pdu_b,
|
||||||
struct asn_buf *resp_b)
|
struct asn_buf *resp_b)
|
||||||
{
|
{
|
||||||
|
u_char type;
|
||||||
asn_len_t len;
|
asn_len_t len;
|
||||||
struct snmp_pdu resp;
|
struct snmp_pdu resp;
|
||||||
enum asn_err err;
|
enum asn_err err;
|
||||||
enum snmp_code code;
|
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)
|
if ((code = snmp_pdu_decode_header(pdu_b, &resp)) != SNMP_CODE_OK)
|
||||||
return (SNMP_RET_IGN);
|
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);
|
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);
|
err = snmp_parse_pdus_hdr(pdu_b, &resp, &len);
|
||||||
if (ASN_ERR_STOPPED(err))
|
if (ASN_ERR_STOPPED(err))
|
||||||
|
Loading…
Reference in New Issue
Block a user