Download raw body.
snmpd: Use a proper engine context
This diff adds support for persistent engine information.
Having persistent engine support allows us to properly increment our
engineBoots on every restart as per RFC. We currently violate the RFC
in 2 ways:
- We have engineBoots set to 0, while engineBoots needs to be 1+
- We use the unix timestamp as our engineTime. This means we don't
start at 0 as per the RFC, and we're vulnerable for the 2038 unix
timestamp overflow (engineBoots is a 32 bit integer).
I'm storing the information in a local/remote agnostic way (simply based
on engineid), so that if we want to properly support remote engines over
SNMPv3 the fundamentals are there (trap receiving, inform sending,
proxy, ...)
This diff only contains the snmpd bits. To test this diff
/var/db/snmpd needs to be manually created. I want to create the
directory as _snmpd:_snmpd/755. Right now everything is relatively
open since the data stored there are public secrets. I am not
expecting us to support creating users via snmp set, or store anything
else that needs to be a secret, and even if we would I think those
permissions should be easy enough to fix with a current.html entry.
However, I'm not attached to the colour of this bikeshed.
Thoughts? Ok?
martijn@
diff 033841d6245fb04a471b798741c0003f8568f241 5e087a57dbc4d05b0a2844969c879a87775b3ab0
commit - 033841d6245fb04a471b798741c0003f8568f241
commit + 5e087a57dbc4d05b0a2844969c879a87775b3ab0
blob - d3b17ba026afe2cb332d3ab85da99b5445e141c6
blob + 38e3a120ff14245f93d06c25edcfa4efd0c9d267
--- usr.sbin/snmpd/application_internal.c
+++ usr.sbin/snmpd/application_internal.c
@@ -530,14 +530,16 @@ struct ber_element *
appl_internal_engine(struct ber_oid *oid)
{
if (ober_oid_cmp(&OID(MIB_snmpEngineID, 0), oid) == 0)
- return ober_add_nstring(NULL, snmpd_env->sc_engineid.value,
- snmpd_env->sc_engineid.length);
+ return ober_add_nstring(NULL, snmpd_env->sc_engine.id.value,
+ snmpd_env->sc_engine.id.length);
else if (ober_oid_cmp(&OID(MIB_snmpEngineBoots, 0), oid) == 0)
- return ober_add_integer(NULL, snmpd_env->sc_engine_boots);
+ return ober_add_integer(NULL, snmpd_env->sc_engine.boots);
else if (ober_oid_cmp(&OID(MIB_snmpEngineTime, 0), oid) == 0)
- return ober_add_integer(NULL, snmpd_engine_time());
+ return ober_add_integer(
+ NULL, engine_time(&snmpd_env->sc_engine));
else if (ober_oid_cmp(&OID(MIB_snmpEngineMaxMsgSize, 0), oid) == 0)
- return ober_add_integer(NULL, READ_BUF_SIZE);
+ return ober_add_integer(NULL,
+ snmpd_env->sc_engine.msg_max_size);
return NULL;
}
blob - 7a6d4fe36f628994247b05825f9572c556859d9d
blob + a417b679f7102c52c6eebe79cdb5c617ca328ee9
--- usr.sbin/snmpd/engine.c
+++ usr.sbin/snmpd/engine.c
@@ -16,11 +16,202 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
+#include "log.h"
#include "snmpd.h"
+#include "snmp.h"
+int engine_cmp(struct engine *, struct engine *);
+
+RB_HEAD(engines, engine) engines = RB_INITIALIZER(&engines);
+RB_PROTOTYPE_STATIC(engines, engine, entry, engine_cmp);
+
+void
+engine_load(void)
+{
+ struct engine buf, *engine;
+ struct timespec mnow, rnow, rmeasure, diff;
+ char path[PATH_MAX];
+ DIR *d;
+ struct dirent *entry;
+ FILE *f;
+ int fd;
+
+ RB_INSERT(engines, &engines, &snmpd_env->sc_engine);
+
+ snprintf(path, sizeof(path), "%s/%s", SNMPD_DB, "engines");
+ if ((d = opendir(path)) == NULL) {
+ if (errno != ENOENT)
+ log_warn("Failed to open %s", path);
+ return;
+ }
+
+ while ((entry = readdir(d)) != NULL) {
+ if (entry->d_name[0] == '.')
+ continue;
+ if (entry->d_namlen / 2 > sizeof(buf.id.value))
+ continue;
+ if (fromhexstr(buf.id.value,
+ entry->d_name, entry->d_namlen) == NULL)
+ continue;
+ buf.id.length = entry->d_namlen / 2;
+
+ if ((fd = openat(dirfd(d), entry->d_name, O_RDONLY)) == -1) {
+ log_warn("Failed to open db for engine %s",
+ entry->d_name);
+ continue;
+ }
+ if ((f = fdopen(fd, "r")) == NULL) {
+ log_warn("Failed to open db for engine %s",
+ entry->d_name);
+ close(fd);
+ continue;
+ }
+
+ if (fscanf(f, "%lld.%09ld\n%d\n%d\n%d\n",
+ &rmeasure.tv_sec, &rmeasure.tv_nsec,
+ &buf.boots, &buf.time, &buf.msg_max_size) != 5 ||
+ fgetc(f) != EOF || !feof(f)) {
+ fclose(f);
+ continue;
+ }
+ fclose(f);
+
+ if ((engine = RB_FIND(engines, &engines, &buf)) == NULL) {
+ if ((engine = calloc(1, sizeof(*engine))) == NULL)
+ fatal("malloc");
+ engine->id = buf.id;
+ RB_INSERT(engines, &engines, engine);
+ }
+
+ if (clock_gettime(CLOCK_MONOTONIC, &mnow) == -1 ||
+ clock_gettime(CLOCK_REALTIME, &rnow) == -1)
+ fatal("clock_gettime");
+
+ timespecsub(&rnow, &rmeasure, &diff);
+
+ engine->boots = buf.boots;
+ engine->time = buf.time;
+ timespecsub(&mnow, &diff, &engine->measure);
+ engine->msg_max_size = buf.msg_max_size;
+ }
+ closedir(d);
+}
+
+void
+engine_store(struct engine *engine)
+{
+ if (proc_compose(&snmpd_env->sc_ps, PROC_PARENT, IMSG_DB_ENGINE,
+ engine, sizeof(*engine)) == -1)
+ fatal("Failed to store engine");
+}
+
+void
+engine_do_store(struct engine *engine)
+{
+ char path[PATH_MAX], tmppath[PATH_MAX], dbpath[PATH_MAX];
+ struct timespec rnow, mnow, rmeasure, diff;
+ FILE *f;
+
+ snprintf(path, sizeof(path), "%s/engines/%s", SNMPD_DB,
+ tohexstr(engine->id.value, engine->id.length));
+ snprintf(tmppath, sizeof(tmppath), "%s/engines/.%s", SNMPD_DB,
+ tohexstr(engine->id.value, engine->id.length));
+
+ if ((f = fopen(tmppath, "w")) == NULL) {
+ if (errno != ENOENT)
+ fatal("Failed to open db for engine %s",
+ tohexstr(engine->id.value, engine->id.length));
+ snprintf(dbpath, sizeof(dbpath), "%s/engines", SNMPD_DB);
+ if (mkdir(dbpath, 0755) == -1)
+ fatal("Failed to create db directory %s", dbpath);
+ if ((f = fopen(tmppath, "w")) == NULL)
+ fatal("Failed to open db for engine %s",
+ tohexstr(engine->id.value, engine->id.length));
+ }
+
+ /*
+ * Use real time
+ * It's less consistent, but it survives across reboots
+ */
+ if (clock_gettime(CLOCK_MONOTONIC, &mnow) == -1 ||
+ clock_gettime(CLOCK_REALTIME, &rnow) == -1)
+ fatal("clock_gettime");
+ timespecsub(&mnow, &engine->measure, &diff);
+ timespecsub(&rnow, &diff, &rmeasure);
+
+ if (fprintf(f, "%lld.%09ld\n%d\n%d\n%d\n",
+ rmeasure.tv_sec, rmeasure.tv_nsec,
+ engine->boots, engine->time, engine->msg_max_size) < 0 ||
+ fclose(f) != 0)
+ fatal("Failed to write db for engine %s",
+ tohexstr(engine->id.value, engine->id.length));
+
+ if (rename(tmppath, path) == -1)
+ fatal("Failed to save db for engine %s",
+ tohexstr(engine->id.value, engine->id.length));
+}
+
int
+engine_in_window(struct engine *engine, int boots, int time)
+{
+ struct timespec now, diff;
+ int min, max, etime;
+
+ if (boots < 0 || /* Should be 1, but we previously used 0 */
+ time < 0)
+ return 0;
+ if (engine->boots > boots)
+ return 0;
+ if (engine->boots == boots) {
+ etime = engine_time(engine);
+ min = etime - SNMP_MAX_TIMEWINDOW >= 0 ?
+ etime - SNMP_MAX_TIMEWINDOW : 0;
+ max = INT_MAX - etime < SNMP_MAX_TIMEWINDOW ?
+ etime + SNMP_MAX_TIMEWINDOW : INT_MAX;
+ return time > min || time < max ? 1 : 0;
+ }
+
+ if (clock_gettime(CLOCK_MONOTONIC, &now) == -1)
+ fatal("clock_gettime");
+ timespecsub(&now, &engine->measure, &diff);
+
+ /* Assume no more than 1 restart per second */
+ if ((boots - engine->boots) + time > diff.tv_sec + SNMP_MAX_TIMEWINDOW)
+ return 0;
+ return 1;
+}
+
+int32_t
+engine_time(struct engine *engine)
+{
+ struct timespec now, diff;
+
+ if (clock_gettime(CLOCK_MONOTONIC, &now) == -1)
+ fatal("clock_gettime");
+ timespecsub(&now, &engine->measure, &diff);
+
+ return engine->time + diff.tv_sec;
+}
+
+int
+engine_cmp(struct engine *e1, struct engine *e2)
+{
+ return engineid_cmp(&e1->id, &e2->id);
+}
+
+int
engineid_cmp(struct engineid *e1, struct engineid *e2)
{
size_t min;
@@ -33,3 +224,5 @@ engineid_cmp(struct engineid *e1, struct engineid *e2)
return 0;
return e1->length < e2->length ? -1 : 1;
}
+
+RB_GENERATE_STATIC(engines, engine, entry, engine_cmp);
blob - 555bc4050d03fd1f3b54d4ea4a745cb9fa3cfc21
blob + c4aff3b132d1e6c7f7374dc4db4ef6a0e2069a94
--- usr.sbin/snmpd/parse.y
+++ usr.sbin/snmpd/parse.y
@@ -308,11 +308,11 @@ main : LISTEN ON listen_udptcp
axm_entry);
}
| engineid_local {
- if (conf->sc_engineid.length != 0) {
+ if (conf->sc_engine.id.length != 0) {
yyerror("Redefinition of engineid");
YYERROR;
}
- conf->sc_engineid = $1;
+ conf->sc_engine.id = $1;
}
| READONLY COMMUNITY STRING {
if (strlcpy(conf->sc_rdcommunity, $3,
@@ -1875,18 +1875,19 @@ parse_config(const char *filename, u_int flags)
/* Must be identical to enginefmt_local:HOSTHASH */
- if (conf->sc_engineid.length == 0) {
+ if (conf->sc_engine.id.length == 0) {
if (gethostname(hostname, sizeof(hostname)) == -1)
fatal("gethostname");
- memcpy(conf->sc_engineid.value, &npen, sizeof(npen));
- conf->sc_engineid.length += sizeof(npen);
- conf->sc_engineid.value[conf->sc_engineid.length++] =
+ memcpy(conf->sc_engine.id.value, &npen, sizeof(npen));
+ conf->sc_engine.id.length += sizeof(npen);
+ conf->sc_engine.id.value[conf->sc_engine.id.length++] =
SNMP_ENGINEID_FMT_HH;
- memcpy(conf->sc_engineid.value + conf->sc_engineid.length,
+ memcpy(conf->sc_engine.id.value + conf->sc_engine.id.length,
SHA256(hostname, strlen(hostname), sha256),
- sizeof(conf->sc_engineid.value) - conf->sc_engineid.length);
- conf->sc_engineid.length = sizeof(conf->sc_engineid.value);
- conf->sc_engineid.value[0] |= SNMP_ENGINEID_NEW;
+ sizeof(conf->sc_engine.id.value) -
+ conf->sc_engine.id.length);
+ conf->sc_engine.id.length = sizeof(conf->sc_engine.id.value);
+ conf->sc_engine.id.value[0] |= SNMP_ENGINEID_NEW;
}
/* Setup default listen addresses */
blob - 85581e7ee9b020d658101571df8bf8a761d7b5f6
blob + a03638609ecb51531e7722614db3cbb505817be1
--- usr.sbin/snmpd/snmpd.c
+++ usr.sbin/snmpd/snmpd.c
@@ -218,8 +218,6 @@ main(int argc, char *argv[])
log_init(debug, LOG_DAEMON);
log_setverbose(verbose);
- env->sc_engine_boots = 0;
-
proc_init(ps, procs, nitems(procs), debug, argc0, argv0, proc_id);
log_procinit("parent");
@@ -244,7 +242,10 @@ main(int argc, char *argv[])
proc_connect(ps);
snmpd_backend(env);
- if (pledge("stdio dns sendfd proc exec id", NULL) == -1)
+ if (unveil("/", "x") == -1 ||
+ unveil(SNMPD_DB, "rwc") == -1)
+ fatal("unveil");
+ if (pledge("stdio dns sendfd proc exec id rpath wpath cpath", NULL) == -1)
fatal("pledge");
event_dispatch();
@@ -288,9 +289,16 @@ check_child(pid_t pid, const char *pname)
int
snmpd_dispatch_snmpe(int fd, struct privsep_proc *p, struct imsg *imsg)
{
+ struct engine *engine;
+
switch (imsg->hdr.type) {
case IMSG_TRAP_EXEC:
return (traphandler_priv_recvmsg(p, imsg));
+ case IMSG_DB_ENGINE:
+ IMSG_SIZE_CHECK(imsg, engine);
+ engine = imsg->data;
+ engine_do_store(engine);
+ return 0;
default:
break;
}
@@ -319,24 +327,6 @@ snmpd_socket_af(struct sockaddr_storage *ss, int type)
return fd;
}
-u_long
-snmpd_engine_time(void)
-{
- struct timeval now;
-
- /*
- * snmpEngineBoots should be stored in a non-volatile storage.
- * snmpEngineTime is the number of seconds since snmpEngineBoots
- * was last incremented. We don't rely on non-volatile storage.
- * snmpEngineBoots is set to zero and snmpEngineTime to the system
- * clock. Hence, the tuple (snmpEngineBoots, snmpEngineTime) is
- * still unique and protects us against replay attacks. It only
- * 'expires' a little bit sooner than the RFC3414 method.
- */
- gettimeofday(&now, NULL);
- return now.tv_sec;
-}
-
void
snmpd_backend(struct snmpd *env)
{
blob - 5fefd671b71a9cea26758de538109e8e871cb2e1
blob + 14f17359358d8f3673d358db35da6f34fc44bd3e
--- usr.sbin/snmpd/snmpd.h
+++ usr.sbin/snmpd/snmpd.h
@@ -49,6 +49,7 @@
#define CONF_FILE "/etc/snmpd.conf"
#define SNMPD_BACKEND "/usr/libexec/snmpd"
#define SNMPD_USER "_snmpd"
+#define SNMPD_DB "/var/db/snmpd"
#define SNMP_PORT "161"
#define SNMPTRAP_PORT "162"
@@ -68,10 +69,7 @@
#define SNMP_USM_KEYLEN 64
#define SNMP_CIPHER_KEYLEN 16
-#define SMALL_READ_BUF_SIZE 1024
#define READ_BUF_SIZE 65535
-#define RT_BUF_SIZE 16384
-#define MAX_RTSOCK_BUF (2 * 1024 * 1024)
#define SNMP_ENGINEID_OLD 0x00
#define SNMP_ENGINEID_NEW 0x80 /* RFC3411 */
@@ -90,7 +88,8 @@ enum imsg_type {
IMSG_CTL_VERBOSE,
IMSG_CTL_PROCFD,
IMSG_TRAP_EXEC,
- IMSG_AX_FD
+ IMSG_AX_FD,
+ IMSG_DB_ENGINE
};
struct imsgev {
@@ -184,6 +183,15 @@ struct engineid {
size_t length;
};
+struct engine {
+ struct engineid id;
+ int32_t boots;
+ int32_t time;
+ struct timespec measure;
+ int msg_max_size;
+ RB_ENTRY(engine) entry;
+};
+
#define MSG_HAS_AUTH(m) (((m)->sm_flags & SNMP_MSGFLAG_AUTH) != 0)
#define MSG_HAS_PRIV(m) (((m)->sm_flags & SNMP_MSGFLAG_PRIV) != 0)
#define MSG_SECLEVEL(m) ((m)->sm_flags & SNMP_MSGFLAG_SECMASK)
@@ -405,13 +413,12 @@ struct snmpd {
const char *sc_confpath;
struct addresslist sc_addresses;
struct axmasterlist sc_agentx_masters;
- u_int32_t sc_engine_boots;
char sc_rdcommunity[SNMPD_MAXCOMMUNITYLEN];
char sc_rwcommunity[SNMPD_MAXCOMMUNITYLEN];
char sc_trcommunity[SNMPD_MAXCOMMUNITYLEN];
- struct engineid sc_engineid;
+ struct engine sc_engine;
struct snmp_stats sc_stats;
struct snmp_system sc_system;
@@ -448,6 +455,11 @@ struct snmpd *parse_config(const char *, u_int);
int cmdline_symset(char *);
/* engine.c */
+void engine_load(void);
+void engine_store(struct engine *);
+void engine_do_store(struct engine *);
+int32_t engine_time(struct engine *);
+int engine_in_window(struct engine *, int, int);
int engineid_cmp(struct engineid *, struct engineid *);
/* snmpe.c */
@@ -471,7 +483,6 @@ void smi_debug_elements(struct ber_element *);
/* snmpd.c */
int snmpd_socket_af(struct sockaddr_storage *, int);
-u_long snmpd_engine_time(void);
/* usm.c */
void usm_generate_keys(void);
blob - 67dcfc523ad4171ad87ab71a2c21aca7cc639187
blob + 1c61ba3db3a24540ffed4d8352db4b6330bb4333
--- usr.sbin/snmpd/snmpe.c
+++ usr.sbin/snmpd/snmpe.c
@@ -74,6 +74,7 @@ snmpe(struct privsep *ps, struct privsep_proc *p)
if ((setlocale(LC_CTYPE, "en_US.UTF-8")) == NULL)
fatal("setlocale(LC_CTYPE, \"en_US.UTF-8\")");
+ engine_load();
appl();
/* bind SNMP UDP/TCP sockets */
@@ -90,6 +91,13 @@ snmpe_init(struct privsep *ps, struct privsep_proc *p,
struct snmpd *env = ps->ps_env;
struct address *h;
+ if (clock_gettime(CLOCK_MONOTONIC, &env->sc_engine.measure) == -1)
+ fatal("clock_gettime");
+ env->sc_engine.boots++;
+ env->sc_engine.time = 0;
+ env->sc_engine.msg_max_size = READ_BUF_SIZE;
+ engine_store(&env->sc_engine);
+
usm_generate_keys();
appl_init();
@@ -114,7 +122,7 @@ snmpe_init(struct privsep *ps, struct privsep_proc *p,
fatal("pledge");
log_info("snmpe %s: ready",
- tohexstr(env->sc_engineid.value, env->sc_engineid.length));
+ tohexstr(env->sc_engine.id.value, env->sc_engine.id.length));
trap_init();
}
@@ -851,7 +859,8 @@ snmpe_encode(struct snmp_message *msg)
pdu = epdu = ober_add_sequence(NULL);
if (msg->sm_version == SNMP_V3) {
if ((epdu = ober_printf_elements(epdu, "xs{",
- snmpd_env->sc_engineid.value, snmpd_env->sc_engineid.length,
+ snmpd_env->sc_engine.id.value,
+ snmpd_env->sc_engine.id.length,
msg->sm_ctxname)) == NULL) {
ober_free_elements(pdu);
return -1;
blob - 11446e02974afa4f87a43e7a8454f110a749b015
blob + 614c15f37a0c6c0dd879e31e8536610480371903
--- usr.sbin/snmpd/trap.c
+++ usr.sbin/snmpd/trap.c
@@ -107,9 +107,9 @@ trap_send(struct ber_oid *oid, struct ber_element *elm
msg->sm_flags = tr->ta_seclevel != -1 ?
tr->ta_seclevel : snmpd_env->sc_min_seclevel;
msg->sm_secmodel = SNMP_SEC_USM;
- msg->sm_engine_time = snmpd_engine_time();
- msg->sm_engine_boots = snmpd_env->sc_engine_boots;
- msg->sm_ctxengineid = snmpd_env->sc_engineid;
+ msg->sm_engine_time = engine_time(&snmpd_env->sc_engine);
+ msg->sm_engine_boots = snmpd_env->sc_engine.boots;
+ msg->sm_ctxengineid = snmpd_env->sc_engine.id;
(void)strlcpy(msg->sm_username, tr->ta_usmusername,
sizeof(msg->sm_username));
msg->sm_user = tr->ta_usmuser;
blob - b38eaa9d4b02a389eae9ea5f7c8808e4c32cf9e5
blob + 6a5feaab219a1c1d3d35c020662096686513b2fe
--- usr.sbin/snmpd/usm.c
+++ usr.sbin/snmpd/usm.c
@@ -273,8 +273,7 @@ usm_decode(struct snmp_message *msg, struct ber_elemen
char *engineidv;
char *user;
char *digest, *salt;
- u_long now;
- long long engine_boots, engine_time;
+ long long boots, time;
bzero(&ber, sizeof(ber));
offs = ober_getpos(elm);
@@ -299,7 +298,7 @@ usm_decode(struct snmp_message *msg, struct ber_elemen
#endif
if (ober_scanf_elements(usm, "{xiixpxx$", &engineidv, &engineid.length,
- &engine_boots, &engine_time, &user, &userlen, &offs2,
+ &boots, &time, &user, &userlen, &offs2,
&digest, &digestlen, &salt, &saltlen) != 0) {
*errp = "cannot decode USM params";
msg->sm_flags &= SNMP_MSGFLAG_REPORT;
@@ -307,8 +306,8 @@ usm_decode(struct snmp_message *msg, struct ber_elemen
}
log_debug("USM: engineid '%s', engine boots %lld, engine time %lld, "
- "user '%s'", tohexstr(engineidv, engineid.length), engine_boots,
- engine_time, user);
+ "user '%s'", tohexstr(engineidv, engineid.length), boots,
+ time, user);
if (engineid.length > sizeof(engineid.value) ||
userlen > SNMPD_MAXUSERNAMELEN ||
@@ -320,7 +319,7 @@ usm_decode(struct snmp_message *msg, struct ber_elemen
}
memcpy(engineid.value, engineidv, engineid.length);
- if (engineid_cmp(&snmpd_env->sc_engineid, &engineid) != 0) {
+ if (engineid_cmp(&snmpd_env->sc_engine.id, &engineid) != 0) {
*errp = "unknown engine id";
msg->sm_usmerr = OIDVAL_usmErrEngineId;
stats->snmp_usmnosuchengine++;
@@ -328,8 +327,8 @@ usm_decode(struct snmp_message *msg, struct ber_elemen
goto done;
}
- msg->sm_engine_boots = (u_int32_t)engine_boots;
- msg->sm_engine_time = (u_int32_t)engine_time;
+ msg->sm_engine_boots = boots;
+ msg->sm_engine_time = time;
memcpy(msg->sm_username, user, userlen);
msg->sm_username[userlen] = '\0';
@@ -374,11 +373,7 @@ usm_decode(struct snmp_message *msg, struct ber_elemen
}
if (MSG_HAS_AUTH(msg)) {
- now = snmpd_engine_time();
- if (engine_boots != snmpd_env->sc_engine_boots ||
- engine_time < (long long)(now - SNMP_MAX_TIMEWINDOW) ||
- engine_time > (long long)(now + SNMP_MAX_TIMEWINDOW)) {
- *errp = "out of time window";
+ if (!engine_in_window(&snmpd_env->sc_engine, boots, time)) {
msg->sm_usmerr = OIDVAL_usmErrTimeWindow;
stats->snmp_usmtimewindow++;
goto done;
@@ -434,10 +429,10 @@ usm_encode(struct snmp_message *msg, struct ber_elemen
} else
saltlen = 0;
- msg->sm_engine_boots = (u_int32_t)snmpd_env->sc_engine_boots;
- msg->sm_engine_time = (u_int32_t)snmpd_engine_time();
+ msg->sm_engine_boots = snmpd_env->sc_engine.boots;
+ msg->sm_engine_time = engine_time(&snmpd_env->sc_engine);
if ((a = ober_printf_elements(usm, "xdds",
- snmpd_env->sc_engineid.value, snmpd_env->sc_engineid.length,
+ snmpd_env->sc_engine.id.value, snmpd_env->sc_engine.id.length,
msg->sm_engine_boots, msg->sm_engine_time,
msg->sm_username)) == NULL)
goto done;
@@ -718,16 +713,16 @@ usm_passwd2key(const EVP_MD *md, char *passwd, int *ma
/* Localize the key */
#ifdef DEBUG
- assert(snmpd_env->sc_engineid_len <= SNMPD_MAXENGINEIDLEN);
+ assert(snmpd_env->sc_engine.id.length <= SNMPD_MAXENGINEIDLEN);
#endif
memcpy(pwbuf, keybuf, dlen);
- memcpy(pwbuf + dlen, snmpd_env->sc_engineid.value,
- snmpd_env->sc_engineid.length);
- memcpy(pwbuf + dlen + snmpd_env->sc_engineid.length, keybuf, dlen);
+ memcpy(pwbuf + dlen, snmpd_env->sc_engine.id.value,
+ snmpd_env->sc_engine.id.length);
+ memcpy(pwbuf + dlen + snmpd_env->sc_engine.id.length, keybuf, dlen);
if (!EVP_DigestInit_ex(ctx, md, NULL) ||
!EVP_DigestUpdate(ctx, pwbuf,
- 2 * dlen + snmpd_env->sc_engineid.length) ||
+ 2 * dlen + snmpd_env->sc_engine.id.length) ||
!EVP_DigestFinal_ex(ctx, keybuf, &dlen)) {
EVP_MD_CTX_free(ctx);
return NULL;
snmpd: Use a proper engine context