Skip to content

Commit

Permalink
libsnmp, USM: Introduce a reference count in struct usmStateReference
Browse files Browse the repository at this point in the history
  • Loading branch information
bvanassche committed Jul 30, 2019
1 parent cae2cb0 commit 5f881d3
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 42 deletions.
22 changes: 5 additions & 17 deletions snmplib/snmp_client.c
Expand Up @@ -405,28 +405,16 @@ _clone_pdu_header(netsnmp_pdu *pdu)
return NULL;
}

if (pdu->securityStateRef &&
pdu->command == SNMP_MSG_TRAP2) {

netsnmp_assert(pdu->securityModel == SNMP_DEFAULT_SECMODEL);
ret = usm_clone_usmStateReference((struct usmStateReference *) pdu->securityStateRef,
(struct usmStateReference **) &newpdu->securityStateRef );

if (ret)
{
sptr = find_sec_mod(newpdu->securityModel);
if (sptr && sptr->pdu_clone) {
/* call security model if it needs to know about this */
ret = sptr->pdu_clone(pdu, newpdu);
if (ret) {
snmp_free_pdu(newpdu);
return NULL;
}
}

if ((sptr = find_sec_mod(newpdu->securityModel)) != NULL &&
sptr->pdu_clone != NULL) {
/*
* call security model if it needs to know about this
*/
(*sptr->pdu_clone) (pdu, newpdu);
}

return newpdu;
}

Expand Down
73 changes: 48 additions & 25 deletions snmplib/snmpusm.c
Expand Up @@ -85,6 +85,7 @@ netsnmp_feature_child_of(usm_support, usm_all)
netsnmp_feature_require(usm_support)

struct usmStateReference {
int refcnt;
char *usr_name;
size_t usr_name_length;
u_char *usr_engine_id;
Expand Down Expand Up @@ -280,42 +281,63 @@ free_enginetime_on_shutdown(int majorid, int minorid, void *serverarg,
static struct usmStateReference *
usm_malloc_usmStateReference(void)
{
struct usmStateReference *retval = (struct usmStateReference *)
calloc(1, sizeof(struct usmStateReference));
struct usmStateReference *retval;

retval = calloc(1, sizeof(struct usmStateReference));
if (retval)
retval->refcnt = 1;

return retval;
} /* end usm_malloc_usmStateReference() */

static int
usm_clone(netsnmp_pdu *pdu, netsnmp_pdu *new_pdu)
{
struct usmStateReference *ref = pdu->securityStateRef;
struct usmStateReference **new_ref =
(struct usmStateReference **)&new_pdu->securityStateRef;
int ret = 0;

if (!ref)
return ret;

if (pdu->command == SNMP_MSG_TRAP2) {
netsnmp_assert(pdu->securityModel == SNMP_DEFAULT_SECMODEL);
ret = usm_clone_usmStateReference(ref, new_ref);
} else {
netsnmp_assert(ref == *new_ref);
ref->refcnt++;
}

return ret;
}

static void
usm_free_usmStateReference(void *old)
{
struct usmStateReference *old_ref = (struct usmStateReference *) old;

if (old_ref) {

if (old_ref->usr_name_length)
SNMP_FREE(old_ref->usr_name);
if (old_ref->usr_engine_id_length)
SNMP_FREE(old_ref->usr_engine_id);
if (old_ref->usr_auth_protocol_length)
SNMP_FREE(old_ref->usr_auth_protocol);
if (old_ref->usr_priv_protocol_length)
SNMP_FREE(old_ref->usr_priv_protocol);

if (old_ref->usr_auth_key_length && old_ref->usr_auth_key) {
SNMP_ZERO(old_ref->usr_auth_key, old_ref->usr_auth_key_length);
SNMP_FREE(old_ref->usr_auth_key);
}
if (old_ref->usr_priv_key_length && old_ref->usr_priv_key) {
SNMP_ZERO(old_ref->usr_priv_key, old_ref->usr_priv_key_length);
SNMP_FREE(old_ref->usr_priv_key);
}
struct usmStateReference *ref = old;

if (!ref)
return;

if (--ref->refcnt > 0)
return;

SNMP_ZERO(old_ref, sizeof(*old_ref));
SNMP_FREE(old_ref);
SNMP_FREE(ref->usr_name);
SNMP_FREE(ref->usr_engine_id);
SNMP_FREE(ref->usr_auth_protocol);
SNMP_FREE(ref->usr_priv_protocol);

if (ref->usr_auth_key_length && ref->usr_auth_key) {
SNMP_ZERO(ref->usr_auth_key, ref->usr_auth_key_length);
SNMP_FREE(ref->usr_auth_key);
}
if (ref->usr_priv_key_length && ref->usr_priv_key) {
SNMP_ZERO(ref->usr_priv_key, ref->usr_priv_key_length);
SNMP_FREE(ref->usr_priv_key);
}

SNMP_FREE(ref);
} /* end usm_free_usmStateReference() */

struct usmUser *
Expand Down Expand Up @@ -4916,6 +4938,7 @@ init_usm(void)
def->encode_reverse = usm_secmod_rgenerate_out_msg;
def->encode_forward = usm_secmod_generate_out_msg;
def->decode = usm_secmod_process_in_msg;
def->pdu_clone = usm_clone;
def->pdu_free_state_ref = usm_free_usmStateReference;
def->session_setup = usm_session_init;
def->handle_report = usm_handle_report;
Expand Down

0 comments on commit 5f881d3

Please sign in to comment.