Allow SNMPv3 authNoPriv and noAuthNoPriv protocols to discover snmpEngineTime

as discussed in RFC-5343

This fixes interoperability with net-snmp.

Tested with the following invocations of snmpwalk (from net-snmp):

- noAuthNoPriv:

  % snmpwalk -v 3 -n '' -u public localhost snmpEngineTime

- authNoPriv:

  % snmpwalk -v 3 -n '' -u bsnmp -A bsnmptest -l authNoPriv -a sha localhost \
    localhost snmpEngineTime

- authPriv:

  % snmpwalk -v 3 -n '' -u bsnmp -A bsnmptest -l authPriv -a sha -x des \
    -X bsnmptest localhost snmpEngineTime

MFC after:	1 week
Obtained from:	Isilon OneFS (5ec6d772cacbc, with minor tweaks)
Submitted by:	Austin Voecks <austin.voecks@isilon.com>
Sponsored by:	Dell EMC Isilon
This commit is contained in:
Enji Cooper 2016-12-24 11:23:18 +00:00
parent 7c933da6ed
commit 88cdfafad2
3 changed files with 22 additions and 12 deletions

View File

@ -40,6 +40,7 @@
#include <sys/utsname.h>
#include <ctype.h>
#include <errno.h>
#include <inttypes.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
@ -219,6 +220,21 @@ set_snmpd_engine(void)
return (0);
}
void
update_snmpd_engine_time(void)
{
uint64_t etime;
etime = (get_ticks() - start_tick) / 100ULL;
if (etime < INT32_MAX)
snmpd_engine.engine_time = etime;
else {
start_tick = get_ticks();
(void)set_snmpd_engine();
snmpd_engine.engine_time = start_tick;
}
}
/*************************************************************
*
* System group
@ -1118,7 +1134,7 @@ op_snmp_engine(struct snmp_context *ctx __unused, struct snmp_value *value,
value->v.integer = snmpd_engine.engine_boots;
break;
case LEAF_snmpEngineTime:
snmpd_engine.engine_time = (get_ticks() - start_tick) / 100ULL;
update_snmpd_engine_time();
value->v.integer = snmpd_engine.engine_time;
break;
case LEAF_snmpEngineMaxMessageSize:

View File

@ -53,7 +53,6 @@
#include <unistd.h>
#include <signal.h>
#include <dlfcn.h>
#include <inttypes.h>
#ifdef USE_TCPWRAPPERS
#include <arpa/inet.h>
@ -304,7 +303,6 @@ snmp_output(struct snmp_pdu *pdu, u_char *sndbuf, size_t *sndlen,
static enum snmp_code
snmp_pdu_auth_user(struct snmp_pdu *pdu)
{
uint64_t etime;
usm_user = NULL;
/* un-authenticated snmpEngineId discovery */
@ -312,6 +310,7 @@ snmp_pdu_auth_user(struct snmp_pdu *pdu)
pdu->engine.engine_len = snmpd_engine.engine_len;
memcpy(pdu->engine.engine_id, snmpd_engine.engine_id,
snmpd_engine.engine_len);
update_snmpd_engine_time();
pdu->engine.engine_boots = snmpd_engine.engine_boots;
pdu->engine.engine_time = snmpd_engine.engine_time;
pdu->flags |= SNMP_MSG_AUTODISCOVER;
@ -334,21 +333,14 @@ snmp_pdu_auth_user(struct snmp_pdu *pdu)
/* authenticated snmpEngineId discovery */
if ((pdu->flags & SNMP_MSG_AUTH_FLAG) != 0) {
etime = (get_ticks() - start_tick) / 100ULL;
if (etime < INT32_MAX)
snmpd_engine.engine_time = etime;
else {
start_tick = get_ticks();
set_snmpd_engine();
snmpd_engine.engine_time = start_tick;
}
update_snmpd_engine_time();
pdu->user.auth_proto = usm_user->suser.auth_proto;
memcpy(pdu->user.auth_key, usm_user->suser.auth_key,
sizeof(pdu->user.auth_key));
if (pdu->engine.engine_boots == 0 &&
pdu->engine.engine_time == 0) {
update_snmpd_engine_time();
pdu->flags |= SNMP_MSG_AUTODISCOVER;
return (SNMP_CODE_OK);
}
@ -643,6 +635,7 @@ snmp_input_start(const u_char *buf, size_t len, const char *source,
pdu->engine.engine_time == 0) {
asn_append_oid(&(pdu->bindings[pdu->nbindings++].var),
&oid_usmNotInTimeWindows);
update_snmpd_engine_time();
pdu->engine.engine_boots = snmpd_engine.engine_boots;
pdu->engine.engine_time = snmpd_engine.engine_time;
}

View File

@ -332,6 +332,7 @@ int init_actvals(void);
extern char engine_file[];
int init_snmpd_engine(void);
int set_snmpd_engine(void);
void update_snmpd_engine_time(void);
int read_config(const char *, struct lmodule *);
int define_macro(const char *name, const char *value);