/contrib/bsnmp/snmp_usm/usm_snmp.c

https://bitbucket.org/freebsd/freebsd-head/ · C · 614 lines · 507 code · 64 blank · 43 comment · 119 complexity · 4bce9de80f8bd9500b58dce3eeb06a1d MD5 · raw file

  1. /*-
  2. * Copyright (c) 2010 The FreeBSD Foundation
  3. * All rights reserved.
  4. *
  5. * This software was developed by Shteryana Sotirova Shopova under
  6. * sponsorship from the FreeBSD Foundation.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in the
  15. * documentation and/or other materials provided with the distribution.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  18. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  21. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  23. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  24. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  25. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  26. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27. * SUCH DAMAGE.
  28. *
  29. * $FreeBSD$
  30. */
  31. #include <sys/queue.h>
  32. #include <sys/types.h>
  33. #include <errno.h>
  34. #include <stdarg.h>
  35. #include <stdlib.h>
  36. #include <stdio.h>
  37. #include <stdint.h>
  38. #include <string.h>
  39. #include <syslog.h>
  40. #include "asn1.h"
  41. #include "snmp.h"
  42. #include "snmpmod.h"
  43. #include "usm_tree.h"
  44. #include "usm_oid.h"
  45. static struct lmodule *usm_module;
  46. /* For the registration. */
  47. static const struct asn_oid oid_usm = OIDX_snmpUsmMIB;
  48. static const struct asn_oid oid_usmNoAuthProtocol = OIDX_usmNoAuthProtocol;
  49. static const struct asn_oid oid_usmHMACMD5AuthProtocol = \
  50. OIDX_usmHMACMD5AuthProtocol;
  51. static const struct asn_oid oid_usmHMACSHAAuthProtocol = \
  52. OIDX_usmHMACSHAAuthProtocol;
  53. static const struct asn_oid oid_usmNoPrivProtocol = OIDX_usmNoPrivProtocol;
  54. static const struct asn_oid oid_usmDESPrivProtocol = OIDX_usmDESPrivProtocol;
  55. static const struct asn_oid oid_usmAesCfb128Protocol = OIDX_usmAesCfb128Protocol;
  56. static const struct asn_oid oid_usmUserSecurityName = OIDX_usmUserSecurityName;
  57. /* The registration. */
  58. static uint reg_usm;
  59. static int32_t usm_lock;
  60. static struct usm_user * usm_get_user(const struct asn_oid *, uint);
  61. static struct usm_user * usm_get_next_user(const struct asn_oid *, uint);
  62. static void usm_append_userindex(struct asn_oid *, uint,
  63. const struct usm_user *);
  64. static int usm_user_index_decode(const struct asn_oid *, uint, uint8_t *,
  65. uint32_t *, char *);
  66. int
  67. op_usm_stats(struct snmp_context *ctx __unused, struct snmp_value *val,
  68. uint32_t sub __unused, uint32_t iidx __unused, enum snmp_op op)
  69. {
  70. struct snmpd_usmstat *usmstats;
  71. if (op == SNMP_OP_SET)
  72. return (SNMP_ERR_NOT_WRITEABLE);
  73. if ((usmstats = bsnmpd_get_usm_stats()) == NULL)
  74. return (SNMP_ERR_GENERR);
  75. if (op == SNMP_OP_GET) {
  76. switch (val->var.subs[sub - 1]) {
  77. case LEAF_usmStatsUnsupportedSecLevels:
  78. val->v.uint32 = usmstats->unsupported_seclevels;
  79. break;
  80. case LEAF_usmStatsNotInTimeWindows:
  81. val->v.uint32 = usmstats->not_in_time_windows;
  82. break;
  83. case LEAF_usmStatsUnknownUserNames:
  84. val->v.uint32 = usmstats->unknown_users;
  85. break;
  86. case LEAF_usmStatsUnknownEngineIDs:
  87. val->v.uint32 = usmstats->unknown_engine_ids;
  88. break;
  89. case LEAF_usmStatsWrongDigests:
  90. val->v.uint32 = usmstats->wrong_digests;
  91. break;
  92. case LEAF_usmStatsDecryptionErrors:
  93. val->v.uint32 = usmstats->decrypt_errors;
  94. break;
  95. default:
  96. return (SNMP_ERR_NOSUCHNAME);
  97. }
  98. return (SNMP_ERR_NOERROR);
  99. }
  100. abort();
  101. }
  102. int
  103. op_usm_lock(struct snmp_context *ctx __unused, struct snmp_value *val,
  104. uint32_t sub, uint32_t iidx __unused, enum snmp_op op)
  105. {
  106. if (val->var.subs[sub - 1] != LEAF_usmUserSpinLock)
  107. return (SNMP_ERR_NOSUCHNAME);
  108. switch (op) {
  109. case SNMP_OP_GET:
  110. if (++usm_lock == INT32_MAX)
  111. usm_lock = 0;
  112. val->v.integer = usm_lock;
  113. break;
  114. case SNMP_OP_GETNEXT:
  115. abort();
  116. case SNMP_OP_SET:
  117. if (val->v.integer != usm_lock)
  118. return (SNMP_ERR_INCONS_VALUE);
  119. break;
  120. case SNMP_OP_ROLLBACK:
  121. /* FALLTHROUGH */
  122. case SNMP_OP_COMMIT:
  123. break;
  124. }
  125. return (SNMP_ERR_NOERROR);
  126. }
  127. int
  128. op_usm_users(struct snmp_context *ctx, struct snmp_value *val,
  129. uint32_t sub, uint32_t iidx __unused, enum snmp_op op)
  130. {
  131. uint32_t elen;
  132. struct usm_user *uuser, *clone;
  133. char uname[SNMP_ADM_STR32_SIZ];
  134. uint8_t eid[SNMP_ENGINE_ID_SIZ];
  135. switch (op) {
  136. case SNMP_OP_GET:
  137. if ((uuser = usm_get_user(&val->var, sub)) == NULL)
  138. return (SNMP_ERR_NOSUCHNAME);
  139. break;
  140. case SNMP_OP_GETNEXT:
  141. if ((uuser = usm_get_next_user(&val->var, sub)) == NULL)
  142. return (SNMP_ERR_NOSUCHNAME);
  143. usm_append_userindex(&val->var, sub, uuser);
  144. break;
  145. case SNMP_OP_SET:
  146. if ((uuser = usm_get_user(&val->var, sub)) == NULL &&
  147. val->var.subs[sub - 1] != LEAF_usmUserStatus &&
  148. val->var.subs[sub - 1] != LEAF_usmUserCloneFrom)
  149. return (SNMP_ERR_NOSUCHNAME);
  150. if (community != COMM_INITIALIZE &&
  151. uuser->type == StorageType_readOnly)
  152. return (SNMP_ERR_NOT_WRITEABLE);
  153. switch (val->var.subs[sub - 1]) {
  154. case LEAF_usmUserSecurityName:
  155. return (SNMP_ERR_NOT_WRITEABLE);
  156. case LEAF_usmUserCloneFrom:
  157. if (uuser != NULL || usm_user_index_decode(&val->var,
  158. sub, eid, &elen, uname) < 0 ||
  159. !(asn_is_suboid(&oid_usmUserSecurityName, &val->v.oid)))
  160. return (SNMP_ERR_WRONG_VALUE);
  161. if ((clone = usm_get_user(&val->v.oid, sub)) == NULL)
  162. return (SNMP_ERR_INCONS_VALUE);
  163. if ((uuser = usm_new_user(eid, elen, uname)) == NULL)
  164. return (SNMP_ERR_GENERR);
  165. uuser->status = RowStatus_notReady;
  166. if (community != COMM_INITIALIZE)
  167. uuser->type = StorageType_volatile;
  168. else
  169. uuser->type = StorageType_readOnly;
  170. uuser->suser.auth_proto = clone->suser.auth_proto;
  171. uuser->suser.priv_proto = clone->suser.priv_proto;
  172. memcpy(uuser->suser.auth_key, clone->suser.auth_key,
  173. sizeof(uuser->suser.auth_key));
  174. memcpy(uuser->suser.priv_key, clone->suser.priv_key,
  175. sizeof(uuser->suser.priv_key));
  176. ctx->scratch->int1 = RowStatus_createAndWait;
  177. break;
  178. case LEAF_usmUserAuthProtocol:
  179. ctx->scratch->int1 = uuser->suser.auth_proto;
  180. if (asn_compare_oid(&oid_usmNoAuthProtocol,
  181. &val->v.oid) == 0)
  182. uuser->suser.auth_proto = SNMP_AUTH_NOAUTH;
  183. else if (asn_compare_oid(&oid_usmHMACMD5AuthProtocol,
  184. &val->v.oid) == 0)
  185. uuser->suser.auth_proto = SNMP_AUTH_HMAC_MD5;
  186. else if (asn_compare_oid(&oid_usmHMACSHAAuthProtocol,
  187. &val->v.oid) == 0)
  188. uuser->suser.auth_proto = SNMP_AUTH_HMAC_SHA;
  189. else
  190. return (SNMP_ERR_WRONG_VALUE);
  191. break;
  192. case LEAF_usmUserAuthKeyChange:
  193. case LEAF_usmUserOwnAuthKeyChange:
  194. if (val->var.subs[sub - 1] ==
  195. LEAF_usmUserOwnAuthKeyChange &&
  196. (usm_user == NULL || strcmp(uuser->suser.sec_name,
  197. usm_user->suser.sec_name) != 0))
  198. return (SNMP_ERR_NO_ACCESS);
  199. if (val->v.octetstring.len > SNMP_AUTH_KEY_SIZ)
  200. return (SNMP_ERR_INCONS_VALUE);
  201. ctx->scratch->ptr1 = malloc(SNMP_AUTH_KEY_SIZ);
  202. if (ctx->scratch->ptr1 == NULL)
  203. return (SNMP_ERR_GENERR);
  204. memcpy(ctx->scratch->ptr1, uuser->suser.auth_key,
  205. SNMP_AUTH_KEY_SIZ);
  206. memcpy(uuser->suser.auth_key, val->v.octetstring.octets,
  207. val->v.octetstring.len);
  208. break;
  209. case LEAF_usmUserPrivProtocol:
  210. ctx->scratch->int1 = uuser->suser.priv_proto;
  211. if (asn_compare_oid(&oid_usmNoPrivProtocol,
  212. &val->v.oid) == 0)
  213. uuser->suser.priv_proto = SNMP_PRIV_NOPRIV;
  214. else if (asn_compare_oid(&oid_usmDESPrivProtocol,
  215. &val->v.oid) == 0)
  216. uuser->suser.priv_proto = SNMP_PRIV_DES;
  217. else if (asn_compare_oid(&oid_usmAesCfb128Protocol,
  218. &val->v.oid) == 0)
  219. uuser->suser.priv_proto = SNMP_PRIV_AES;
  220. else
  221. return (SNMP_ERR_WRONG_VALUE);
  222. break;
  223. case LEAF_usmUserPrivKeyChange:
  224. case LEAF_usmUserOwnPrivKeyChange:
  225. if (val->var.subs[sub - 1] ==
  226. LEAF_usmUserOwnPrivKeyChange &&
  227. (usm_user == NULL || strcmp(uuser->suser.sec_name,
  228. usm_user->suser.sec_name) != 0))
  229. return (SNMP_ERR_NO_ACCESS);
  230. if (val->v.octetstring.len > SNMP_PRIV_KEY_SIZ)
  231. return (SNMP_ERR_INCONS_VALUE);
  232. ctx->scratch->ptr1 = malloc(SNMP_PRIV_KEY_SIZ);
  233. if (ctx->scratch->ptr1 == NULL)
  234. return (SNMP_ERR_GENERR);
  235. memcpy(ctx->scratch->ptr1, uuser->suser.priv_key,
  236. SNMP_PRIV_KEY_SIZ);
  237. memcpy(uuser->suser.priv_key, val->v.octetstring.octets,
  238. val->v.octetstring.len);
  239. break;
  240. case LEAF_usmUserPublic:
  241. if (val->v.octetstring.len > SNMP_ADM_STR32_SIZ)
  242. return (SNMP_ERR_INCONS_VALUE);
  243. if (uuser->user_public_len > 0) {
  244. ctx->scratch->ptr2 =
  245. malloc(uuser->user_public_len);
  246. if (ctx->scratch->ptr2 == NULL)
  247. return (SNMP_ERR_GENERR);
  248. memcpy(ctx->scratch->ptr2, uuser->user_public,
  249. uuser->user_public_len);
  250. ctx->scratch->int2 = uuser->user_public_len;
  251. }
  252. if (val->v.octetstring.len > 0) {
  253. memcpy(uuser->user_public,
  254. val->v.octetstring.octets,
  255. val->v.octetstring.len);
  256. uuser->user_public_len = val->v.octetstring.len;
  257. } else {
  258. memset(uuser->user_public, 0,
  259. SNMP_ADM_STR32_SIZ);
  260. uuser->user_public_len = 0;
  261. }
  262. break;
  263. case LEAF_usmUserStorageType:
  264. return (SNMP_ERR_INCONS_VALUE);
  265. case LEAF_usmUserStatus:
  266. if (uuser == NULL) {
  267. if (val->v.integer != RowStatus_createAndWait ||
  268. usm_user_index_decode(&val->var, sub, eid,
  269. &elen, uname) < 0)
  270. return (SNMP_ERR_INCONS_VALUE);
  271. uuser = usm_new_user(eid, elen, uname);
  272. if (uuser == NULL)
  273. return (SNMP_ERR_GENERR);
  274. uuser->status = RowStatus_notReady;
  275. if (community != COMM_INITIALIZE)
  276. uuser->type = StorageType_volatile;
  277. else
  278. uuser->type = StorageType_readOnly;
  279. } else if (val->v.integer != RowStatus_active &&
  280. val->v.integer != RowStatus_destroy)
  281. return (SNMP_ERR_INCONS_VALUE);
  282. uuser->status = val->v.integer;
  283. break;
  284. }
  285. return (SNMP_ERR_NOERROR);
  286. case SNMP_OP_COMMIT:
  287. switch (val->var.subs[sub - 1]) {
  288. case LEAF_usmUserAuthKeyChange:
  289. case LEAF_usmUserOwnAuthKeyChange:
  290. case LEAF_usmUserPrivKeyChange:
  291. case LEAF_usmUserOwnPrivKeyChange:
  292. free(ctx->scratch->ptr1);
  293. break;
  294. case LEAF_usmUserPublic:
  295. if (ctx->scratch->ptr2 != NULL)
  296. free(ctx->scratch->ptr2);
  297. break;
  298. case LEAF_usmUserStatus:
  299. if (val->v.integer != RowStatus_destroy)
  300. break;
  301. if ((uuser = usm_get_user(&val->var, sub)) == NULL)
  302. return (SNMP_ERR_GENERR);
  303. usm_delete_user(uuser);
  304. break;
  305. default:
  306. break;
  307. }
  308. return (SNMP_ERR_NOERROR);
  309. case SNMP_OP_ROLLBACK:
  310. if ((uuser = usm_get_user(&val->var, sub)) == NULL)
  311. return (SNMP_ERR_GENERR);
  312. switch (val->var.subs[sub - 1]) {
  313. case LEAF_usmUserAuthProtocol:
  314. uuser->suser.auth_proto = ctx->scratch->int1;
  315. break;
  316. case LEAF_usmUserAuthKeyChange:
  317. case LEAF_usmUserOwnAuthKeyChange:
  318. memcpy(uuser->suser.auth_key, ctx->scratch->ptr1,
  319. SNMP_AUTH_KEY_SIZ);
  320. free(ctx->scratch->ptr1);
  321. break;
  322. case LEAF_usmUserPrivProtocol:
  323. uuser->suser.priv_proto = ctx->scratch->int1;
  324. break;
  325. case LEAF_usmUserPrivKeyChange:
  326. case LEAF_usmUserOwnPrivKeyChange:
  327. memcpy(uuser->suser.priv_key, ctx->scratch->ptr1,
  328. SNMP_AUTH_KEY_SIZ);
  329. free(ctx->scratch->ptr1);
  330. break;
  331. case LEAF_usmUserPublic:
  332. if (ctx->scratch->ptr2 != NULL) {
  333. memcpy(uuser->user_public, ctx->scratch->ptr2,
  334. ctx->scratch->int2);
  335. uuser->user_public_len = ctx->scratch->int2;
  336. free(ctx->scratch->ptr2);
  337. } else {
  338. memset(uuser->user_public, 0,
  339. SNMP_ADM_STR32_SIZ);
  340. uuser->user_public_len = 0;
  341. }
  342. break;
  343. case LEAF_usmUserCloneFrom:
  344. case LEAF_usmUserStatus:
  345. if (ctx->scratch->int1 == RowStatus_createAndWait)
  346. usm_delete_user(uuser);
  347. break;
  348. default:
  349. break;
  350. }
  351. return (SNMP_ERR_NOERROR);
  352. default:
  353. abort();
  354. }
  355. switch (val->var.subs[sub - 1]) {
  356. case LEAF_usmUserSecurityName:
  357. return (string_get(val, uuser->suser.sec_name, -1));
  358. case LEAF_usmUserCloneFrom:
  359. memcpy(&val->v.oid, &oid_zeroDotZero, sizeof(oid_zeroDotZero));
  360. break;
  361. case LEAF_usmUserAuthProtocol:
  362. switch (uuser->suser.auth_proto) {
  363. case SNMP_AUTH_HMAC_MD5:
  364. memcpy(&val->v.oid, &oid_usmHMACMD5AuthProtocol,
  365. sizeof(oid_usmHMACMD5AuthProtocol));
  366. break;
  367. case SNMP_AUTH_HMAC_SHA:
  368. memcpy(&val->v.oid, &oid_usmHMACSHAAuthProtocol,
  369. sizeof(oid_usmHMACSHAAuthProtocol));
  370. break;
  371. default:
  372. memcpy(&val->v.oid, &oid_usmNoAuthProtocol,
  373. sizeof(oid_usmNoAuthProtocol));
  374. break;
  375. }
  376. break;
  377. case LEAF_usmUserAuthKeyChange:
  378. case LEAF_usmUserOwnAuthKeyChange:
  379. return (string_get(val, (char *)uuser->suser.auth_key, 0));
  380. case LEAF_usmUserPrivProtocol:
  381. switch (uuser->suser.priv_proto) {
  382. case SNMP_PRIV_DES:
  383. memcpy(&val->v.oid, &oid_usmDESPrivProtocol,
  384. sizeof(oid_usmDESPrivProtocol));
  385. break;
  386. case SNMP_PRIV_AES:
  387. memcpy(&val->v.oid, &oid_usmAesCfb128Protocol,
  388. sizeof(oid_usmAesCfb128Protocol));
  389. break;
  390. default:
  391. memcpy(&val->v.oid, &oid_usmNoPrivProtocol,
  392. sizeof(oid_usmNoPrivProtocol));
  393. break;
  394. }
  395. break;
  396. case LEAF_usmUserPrivKeyChange:
  397. case LEAF_usmUserOwnPrivKeyChange:
  398. return (string_get(val, (char *)uuser->suser.priv_key, 0));
  399. case LEAF_usmUserPublic:
  400. return (string_get(val, uuser->user_public,
  401. uuser->user_public_len));
  402. case LEAF_usmUserStorageType:
  403. val->v.integer = uuser->type;
  404. break;
  405. case LEAF_usmUserStatus:
  406. val->v.integer = uuser->status;
  407. break;
  408. }
  409. return (SNMP_ERR_NOERROR);
  410. }
  411. static int
  412. usm_user_index_decode(const struct asn_oid *oid, uint sub, uint8_t *engine,
  413. uint32_t *elen, char *uname)
  414. {
  415. uint32_t i, nlen;
  416. int uname_off;
  417. if (oid->subs[sub] > SNMP_ENGINE_ID_SIZ)
  418. return (-1);
  419. for (i = 0; i < oid->subs[sub]; i++)
  420. engine[i] = oid->subs[sub + i + 1];
  421. *elen = i;
  422. uname_off = sub + oid->subs[sub] + 1;
  423. if ((nlen = oid->subs[uname_off]) >= SNMP_ADM_STR32_SIZ)
  424. return (-1);
  425. for (i = 0; i < nlen; i++)
  426. uname[i] = oid->subs[uname_off + i + 1];
  427. uname[nlen] = '\0';
  428. return (0);
  429. }
  430. static void
  431. usm_append_userindex(struct asn_oid *oid, uint sub,
  432. const struct usm_user *uuser)
  433. {
  434. uint32_t i;
  435. oid->len = sub + uuser->user_engine_len + strlen(uuser->suser.sec_name);
  436. oid->len += 2;
  437. oid->subs[sub] = uuser->user_engine_len;
  438. for (i = 1; i < uuser->user_engine_len + 1; i++)
  439. oid->subs[sub + i] = uuser->user_engine_id[i - 1];
  440. sub += uuser->user_engine_len + 1;
  441. oid->subs[sub] = strlen(uuser->suser.sec_name);
  442. for (i = 1; i <= oid->subs[sub]; i++)
  443. oid->subs[sub + i] = uuser->suser.sec_name[i - 1];
  444. }
  445. static struct usm_user *
  446. usm_get_user(const struct asn_oid *oid, uint sub)
  447. {
  448. uint32_t enginelen;
  449. char username[SNMP_ADM_STR32_SIZ];
  450. uint8_t engineid[SNMP_ENGINE_ID_SIZ];
  451. if (usm_user_index_decode(oid, sub, engineid, &enginelen, username) < 0)
  452. return (NULL);
  453. return (usm_find_user(engineid, enginelen, username));
  454. }
  455. static struct usm_user *
  456. usm_get_next_user(const struct asn_oid *oid, uint sub)
  457. {
  458. uint32_t enginelen;
  459. char username[SNMP_ADM_STR32_SIZ];
  460. uint8_t engineid[SNMP_ENGINE_ID_SIZ];
  461. struct usm_user *uuser;
  462. if (oid->len - sub == 0)
  463. return (usm_first_user());
  464. if (usm_user_index_decode(oid, sub, engineid, &enginelen, username) < 0)
  465. return (NULL);
  466. if ((uuser = usm_find_user(engineid, enginelen, username)) != NULL)
  467. return (usm_next_user(uuser));
  468. return (NULL);
  469. }
  470. /*
  471. * USM snmp module initialization hook.
  472. * Returns 0 on success, < 0 on error.
  473. */
  474. static int
  475. usm_init(struct lmodule * mod, int argc __unused, char *argv[] __unused)
  476. {
  477. usm_module = mod;
  478. usm_lock = random();
  479. bsnmpd_reset_usm_stats();
  480. return (0);
  481. }
  482. /*
  483. * USM snmp module finalization hook.
  484. */
  485. static int
  486. usm_fini(void)
  487. {
  488. usm_flush_users();
  489. or_unregister(reg_usm);
  490. return (0);
  491. }
  492. /*
  493. * USM snmp module start operation.
  494. */
  495. static void
  496. usm_start(void)
  497. {
  498. reg_usm = or_register(&oid_usm,
  499. "The MIB module for managing SNMP User-Based Security Model.",
  500. usm_module);
  501. }
  502. static void
  503. usm_dump(void)
  504. {
  505. struct usm_user *uuser;
  506. struct snmpd_usmstat *usmstats;
  507. const char *const authstr[] = {
  508. "noauth",
  509. "md5",
  510. "sha",
  511. NULL
  512. };
  513. const char *const privstr[] = {
  514. "nopriv",
  515. "des",
  516. "aes",
  517. NULL
  518. };
  519. if ((usmstats = bsnmpd_get_usm_stats()) != NULL) {
  520. syslog(LOG_ERR, "UnsupportedSecLevels\t\t%u",
  521. usmstats->unsupported_seclevels);
  522. syslog(LOG_ERR, "NotInTimeWindows\t\t%u",
  523. usmstats->not_in_time_windows);
  524. syslog(LOG_ERR, "UnknownUserNames\t\t%u",
  525. usmstats->unknown_users);
  526. syslog(LOG_ERR, "UnknownEngineIDs\t\t%u",
  527. usmstats->unknown_engine_ids);
  528. syslog(LOG_ERR, "WrongDigests\t\t%u",
  529. usmstats->wrong_digests);
  530. syslog(LOG_ERR, "DecryptionErrors\t\t%u",
  531. usmstats->decrypt_errors);
  532. }
  533. syslog(LOG_ERR, "USM users");
  534. for (uuser = usm_first_user(); uuser != NULL;
  535. (uuser = usm_next_user(uuser)))
  536. syslog(LOG_ERR, "user %s\t\t%s, %s", uuser->suser.sec_name,
  537. authstr[uuser->suser.auth_proto],
  538. privstr[uuser->suser.priv_proto]);
  539. }
  540. const char usm_comment[] = \
  541. "This module implements SNMP User-based Security Model defined in RFC 3414.";
  542. const struct snmp_module config = {
  543. .comment = usm_comment,
  544. .init = usm_init,
  545. .fini = usm_fini,
  546. .start = usm_start,
  547. .tree = usm_ctree,
  548. .dump = usm_dump,
  549. .tree_size = usm_CTREE_SIZE,
  550. };