• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 Generated by LwipMibCompiler
3 */
4 
5 #include "lwip/apps/snmp_opts.h"
6 #if LWIP_SNMP && LWIP_SNMP_V3
7 
8 #include "lwip/apps/snmp_snmpv2_usm.h"
9 #include "lwip/apps/snmp.h"
10 #include "lwip/apps/snmp_core.h"
11 #include "lwip/apps/snmp_scalar.h"
12 #include "lwip/apps/snmp_table.h"
13 #include "lwip/apps/snmpv3.h"
14 #include "snmpv3_priv.h"
15 
16 #include "lwip/apps/snmp_snmpv2_framework.h"
17 
18 #include <string.h>
19 
20 /* --- usmUser 1.3.6.1.6.3.15.1.2 ----------------------------------------------------- */
21 
22 static const struct snmp_oid_range usmUserTable_oid_ranges[] = {
23   { 0, 0xff }, { 0, 0xff }, { 0, 0xff }, { 0, 0xff },
24   { 0, 0xff }, { 0, 0xff }, { 0, 0xff }, { 0, 0xff },
25   { 0, 0xff }, { 0, 0xff }, { 0, 0xff }, { 0, 0xff },
26   { 0, 0xff }, { 0, 0xff }, { 0, 0xff }, { 0, 0xff },
27   { 0, 0xff }, { 0, 0xff }, { 0, 0xff }, { 0, 0xff },
28   { 0, 0xff }, { 0, 0xff }, { 0, 0xff }, { 0, 0xff },
29   { 0, 0xff }, { 0, 0xff }, { 0, 0xff }, { 0, 0xff },
30   { 0, 0xff }, { 0, 0xff }, { 0, 0xff }, { 0, 0xff }
31 };
32 
snmp_engineid_to_oid(const char * engineid,u32_t * oid,u32_t len)33 static void snmp_engineid_to_oid(const char *engineid, u32_t *oid, u32_t len)
34 {
35   u8_t i;
36 
37   for (i = 0; i < len; i++) {
38     oid[i] = engineid[i];
39   }
40 }
41 
snmp_oid_to_name(char * name,const u32_t * oid,size_t len)42 static void snmp_oid_to_name(char *name, const u32_t *oid, size_t len)
43 {
44   u8_t i;
45 
46   for (i = 0; i < len; i++) {
47     name[i] = (char)oid[i];
48   }
49 }
50 
snmp_name_to_oid(const char * name,u32_t * oid,size_t len)51 static void snmp_name_to_oid(const char *name, u32_t *oid, size_t len)
52 {
53   u8_t i;
54 
55   for (i = 0; i < len; i++) {
56     oid[i] = name[i];
57   }
58 }
59 
snmp_auth_algo_to_oid(snmpv3_auth_algo_t algo)60 static const struct snmp_obj_id *snmp_auth_algo_to_oid(snmpv3_auth_algo_t algo)
61 {
62   if (algo == SNMP_V3_AUTH_ALGO_MD5) {
63     return &usmHMACMD5AuthProtocol;
64   } else if (algo ==  SNMP_V3_AUTH_ALGO_SHA) {
65     return &usmHMACMD5AuthProtocol;
66   }
67 
68   return &usmNoAuthProtocol;
69 }
70 
snmp_priv_algo_to_oid(snmpv3_priv_algo_t algo)71 static const struct snmp_obj_id *snmp_priv_algo_to_oid(snmpv3_priv_algo_t algo)
72 {
73   if (algo == SNMP_V3_PRIV_ALGO_DES) {
74     return &usmDESPrivProtocol;
75   } else if (algo == SNMP_V3_PRIV_ALGO_AES) {
76     return &usmAESPrivProtocol;
77   }
78 
79   return &usmNoPrivProtocol;
80 }
81 
82 char username[32];
83 
usmusertable_get_instance(const u32_t * column,const u32_t * row_oid,u8_t row_oid_len,struct snmp_node_instance * cell_instance)84 static snmp_err_t usmusertable_get_instance(const u32_t *column, const u32_t *row_oid, u8_t row_oid_len, struct snmp_node_instance *cell_instance)
85 {
86   const char *engineid;
87   u8_t eid_len;
88 
89   u32_t engineid_oid[SNMP_V3_MAX_ENGINE_ID_LENGTH];
90 
91   u8_t name_len;
92   u8_t engineid_len;
93 
94   u8_t name_start;
95   u8_t engineid_start;
96 
97   LWIP_UNUSED_ARG(column);
98 
99   snmpv3_get_engine_id(&engineid, &eid_len);
100 
101   engineid_len = (u8_t)row_oid[0];
102   engineid_start = 1;
103 
104   if (engineid_len != eid_len) {
105     /* EngineID length does not match! */
106     return SNMP_ERR_NOSUCHINSTANCE;
107   }
108 
109   if (engineid_len > row_oid_len) {
110     /* row OID doesn't contain enough data according to engineid_len.*/
111     return SNMP_ERR_NOSUCHINSTANCE;
112   }
113 
114   /* check if incoming OID length and if values are in plausible range */
115   if (!snmp_oid_in_range(&row_oid[engineid_start], engineid_len, usmUserTable_oid_ranges, engineid_len)) {
116     return SNMP_ERR_NOSUCHINSTANCE;
117   }
118 
119   snmp_engineid_to_oid(engineid, engineid_oid, engineid_len);
120 
121   /* Verify EngineID */
122   if (snmp_oid_equal(&row_oid[engineid_start], engineid_len, engineid_oid, engineid_len)) {
123     return SNMP_ERR_NOSUCHINSTANCE;
124   }
125 
126   name_len = (u8_t)row_oid[engineid_start + engineid_len];
127   name_start = engineid_start + engineid_len + 1;
128 
129   if (name_len > SNMP_V3_MAX_USER_LENGTH) {
130     /* specified name is too long */
131     return SNMP_ERR_NOSUCHINSTANCE;
132   }
133 
134   if (1 + engineid_len + 1 + name_len != row_oid_len) {
135     /* Length of EngineID and name does not match row oid length. (+2 for length fields)*/
136     return SNMP_ERR_NOSUCHINSTANCE;
137   }
138 
139   /* check if incoming OID length and if values are in plausible range */
140   if (!snmp_oid_in_range(&row_oid[name_start], name_len, usmUserTable_oid_ranges, name_len)) {
141     return SNMP_ERR_NOSUCHINSTANCE;
142   }
143 
144   /* Verify if user exists */
145   memset(username, 0, sizeof(username));
146   snmp_oid_to_name(username, &row_oid[name_start], name_len);
147   if (snmpv3_get_user(username, NULL, NULL, NULL, NULL) != ERR_OK) {
148     return SNMP_ERR_NOSUCHINSTANCE;
149   }
150 
151   /* Save name in reference pointer to make it easier to handle later on */
152   cell_instance->reference.ptr = username;
153   cell_instance->reference_len = name_len;
154 
155   /* user was found */
156   return SNMP_ERR_NOERROR;
157 }
158 
159 /*
160  * valid oid options
161  * <oid>
162  * <oid>.<EngineID length>
163  * <oid>.<EngineID length>.<partial EngineID>
164  * <oid>.<EngineID length>.<EngineID>
165  * <oid>.<EngineID length>.<EngineID>.<UserName length>
166  * <oid>.<EngineID length>.<EngineID>.<UserName length>.<partial UserName>
167  * <oid>.<EngineID length>.<EngineID>.<UserName length>.<UserName>
168  *
169  */
usmusertable_get_next_instance(const u32_t * column,struct snmp_obj_id * row_oid,struct snmp_node_instance * cell_instance)170 static snmp_err_t usmusertable_get_next_instance(const u32_t *column, struct snmp_obj_id *row_oid, struct snmp_node_instance *cell_instance)
171 {
172   const char *engineid;
173   u8_t eid_len;
174 
175   u32_t engineid_oid[SNMP_V3_MAX_ENGINE_ID_LENGTH];
176 
177   u8_t name_len;
178   u8_t engineid_len;
179 
180   u8_t name_start;
181   u8_t engineid_start = 1;
182   u8_t i;
183 
184   struct snmp_next_oid_state state;
185 
186   u32_t result_temp[LWIP_ARRAYSIZE(usmUserTable_oid_ranges)];
187 
188   LWIP_UNUSED_ARG(column);
189 
190   snmpv3_get_engine_id(&engineid, &eid_len);
191 
192   /* If EngineID might be given */
193   if (row_oid->len > 0) {
194     engineid_len = (u8_t)row_oid->id[0];
195     engineid_start = 1;
196 
197     if (engineid_len != eid_len) {
198       /* EngineID length does not match! */
199       return SNMP_ERR_NOSUCHINSTANCE;
200     }
201 
202     if (engineid_len > row_oid->len) {
203       /* Verify partial EngineID */
204       snmp_engineid_to_oid(engineid, engineid_oid, row_oid->len - 1);
205       if (!snmp_oid_equal(&row_oid->id[engineid_start], row_oid->len - 1, engineid_oid, row_oid->len - 1)) {
206         return SNMP_ERR_NOSUCHINSTANCE;
207       }
208     } else {
209       /* Verify complete EngineID */
210       snmp_engineid_to_oid(engineid, engineid_oid, engineid_len);
211       if (!snmp_oid_equal(&row_oid->id[engineid_start], engineid_len, engineid_oid, engineid_len)) {
212         return SNMP_ERR_NOSUCHINSTANCE;
213       }
214     }
215 
216     /* At this point, the given EngineID (partially) matches the local EngineID.*/
217 
218     /* If name might also be given */
219     if (row_oid->len > engineid_start + engineid_len) {
220       name_len = (u8_t)row_oid->id[engineid_start + engineid_len];
221       name_start = engineid_start + engineid_len + 1;
222 
223       if (name_len > SNMP_V3_MAX_USER_LENGTH) {
224         /* specified name is too long, max length is 32 according to mib file.*/
225         return SNMP_ERR_NOSUCHINSTANCE;
226       }
227 
228       if (row_oid->len < engineid_len + name_len + 2) {
229         /* Partial name given according to oid.*/
230         u8_t tmplen = row_oid->len - engineid_len - 2;
231         if (!snmp_oid_in_range(&row_oid->id[name_start], tmplen, usmUserTable_oid_ranges, tmplen)) {
232           return SNMP_ERR_NOSUCHINSTANCE;
233         }
234       } else {
235         /* Full name given according to oid. Also test for too much data.*/
236         u8_t tmplen = row_oid->len - engineid_len - 2;
237         if (!snmp_oid_in_range(&row_oid->id[name_start], name_len, usmUserTable_oid_ranges, tmplen)) {
238           return SNMP_ERR_NOSUCHINSTANCE;
239         }
240       }
241 
242       /* At this point the EngineID and (partial) UserName match the local EngineID and UserName.*/
243     }
244   }
245 
246   /* init struct to search next oid */
247   snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(usmUserTable_oid_ranges));
248 
249   for (i = 0; i < snmpv3_get_amount_of_users(); i++) {
250     u32_t test_oid[LWIP_ARRAYSIZE(usmUserTable_oid_ranges)];
251 
252     test_oid[0] = eid_len;
253     snmp_engineid_to_oid(engineid, &test_oid[1], eid_len);
254 
255     snmpv3_get_username(username, i);
256 
257     test_oid[1 + eid_len] = strlen(username);
258     snmp_name_to_oid(username, &test_oid[2 + eid_len], strlen(username));
259 
260     /* check generated OID: is it a candidate for the next one? */
261     snmp_next_oid_check(&state, test_oid, (u8_t)(1 + eid_len + 1 + strlen(username)), LWIP_PTR_NUMERIC_CAST(void *, i));
262   }
263 
264   /* did we find a next one? */
265   if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) {
266     snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len);
267     /* store username for subsequent operations (get/test/set) */
268     memset(username, 0, sizeof(username));
269     snmpv3_get_username(username, LWIP_PTR_NUMERIC_CAST(u8_t, state.reference));
270     cell_instance->reference.ptr = username;
271     cell_instance->reference_len = strlen(username);
272     return SNMP_ERR_NOERROR;
273   }
274 
275   /* not found */
276   return SNMP_ERR_NOSUCHINSTANCE;
277 }
278 
usmusertable_get_value(struct snmp_node_instance * cell_instance,void * value)279 static s16_t usmusertable_get_value(struct snmp_node_instance *cell_instance, void *value)
280 {
281   snmpv3_user_storagetype_t storage_type;
282 
283   switch (SNMP_TABLE_GET_COLUMN_FROM_OID(cell_instance->instance_oid.id)) {
284     case 3: /* usmUserSecurityName */
285       MEMCPY(value, cell_instance->reference.ptr, cell_instance->reference_len);
286       return (s16_t)cell_instance->reference_len;
287     case 4: /* usmUserCloneFrom */
288       MEMCPY(value, snmp_zero_dot_zero.id, snmp_zero_dot_zero.len * sizeof(u32_t));
289       return snmp_zero_dot_zero.len * sizeof(u32_t);
290     case 5: { /* usmUserAuthProtocol */
291       const struct snmp_obj_id *auth_algo;
292       snmpv3_auth_algo_t auth_algo_val;
293       snmpv3_get_user((const char *)cell_instance->reference.ptr, &auth_algo_val, NULL, NULL, NULL);
294       auth_algo = snmp_auth_algo_to_oid(auth_algo_val);
295       MEMCPY(value, auth_algo->id, auth_algo->len * sizeof(u32_t));
296       return auth_algo->len * sizeof(u32_t);
297     }
298     case 6: /* usmUserAuthKeyChange */
299       return 0;
300     case 7: /* usmUserOwnAuthKeyChange */
301       return 0;
302     case 8: { /* usmUserPrivProtocol */
303       const struct snmp_obj_id *priv_algo;
304       snmpv3_priv_algo_t priv_algo_val;
305       snmpv3_get_user((const char *)cell_instance->reference.ptr, NULL, NULL, &priv_algo_val, NULL);
306       priv_algo = snmp_priv_algo_to_oid(priv_algo_val);
307       MEMCPY(value, priv_algo->id, priv_algo->len * sizeof(u32_t));
308       return priv_algo->len * sizeof(u32_t);
309     }
310     case 9: /* usmUserPrivKeyChange */
311       return 0;
312     case 10: /* usmUserOwnPrivKeyChange */
313       return 0;
314     case 11: /* usmUserPublic */
315       /* TODO: Implement usmUserPublic */
316       return 0;
317     case 12: /* usmUserStorageType */
318       snmpv3_get_user_storagetype((const char *)cell_instance->reference.ptr, &storage_type);
319       *(s32_t *)value = storage_type;
320       return sizeof(s32_t);
321     case 13: /* usmUserStatus */
322       *(s32_t *)value = 1; /* active */
323       return sizeof(s32_t);
324     default:
325       LWIP_DEBUGF(SNMP_MIB_DEBUG, ("usmusertable_get_value(): unknown id: %"S32_F"\n", SNMP_TABLE_GET_COLUMN_FROM_OID(cell_instance->instance_oid.id)));
326       return 0;
327   }
328 }
329 
330 /* --- usmMIBObjects 1.3.6.1.6.3.15.1 ----------------------------------------------------- */
usmstats_scalars_get_value(const struct snmp_scalar_array_node_def * node,void * value)331 static s16_t usmstats_scalars_get_value(const struct snmp_scalar_array_node_def *node, void *value)
332 {
333   u32_t *uint_ptr = (u32_t *)value;
334   switch (node->oid) {
335     case 1: /* usmStatsUnsupportedSecLevels */
336       *uint_ptr = snmp_stats.unsupportedseclevels;
337       break;
338     case 2: /* usmStatsNotInTimeWindows */
339       *uint_ptr = snmp_stats.notintimewindows;
340       break;
341     case 3: /* usmStatsUnknownUserNames */
342       *uint_ptr = snmp_stats.unknownusernames;
343       break;
344     case 4: /* usmStatsUnknownEngineIDs */
345       *uint_ptr = snmp_stats.unknownengineids;
346       break;
347     case 5: /* usmStatsWrongDigests */
348       *uint_ptr = snmp_stats.wrongdigests;
349       break;
350     case 6: /* usmStatsDecryptionErrors */
351       *uint_ptr = snmp_stats.decryptionerrors;
352       break;
353     default:
354       LWIP_DEBUGF(SNMP_MIB_DEBUG, ("usmstats_scalars_get_value(): unknown id: %"S32_F"\n", node->oid));
355       return 0;
356   }
357 
358   return sizeof(*uint_ptr);
359 }
360 
361 /* --- snmpUsmMIB  ----------------------------------------------------- */
362 
363 /* --- usmUser 1.3.6.1.6.3.15.1.2 ----------------------------------------------------- */
364 
365 static const struct snmp_table_col_def usmusertable_columns[] = {
366   {3,  SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY}, /* usmUserSecurityName */
367   {4,  SNMP_ASN1_TYPE_OBJECT_ID,    SNMP_NODE_INSTANCE_READ_ONLY}, /* usmUserCloneFrom */
368   {5,  SNMP_ASN1_TYPE_OBJECT_ID,    SNMP_NODE_INSTANCE_READ_ONLY}, /* usmUserAuthProtocol */
369   {6,  SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY}, /* usmUserAuthKeyChange */
370   {7,  SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY}, /* usmUserOwnAuthKeyChange */
371   {8,  SNMP_ASN1_TYPE_OBJECT_ID,    SNMP_NODE_INSTANCE_READ_ONLY}, /* usmUserPrivProtocol */
372   {9,  SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY}, /* usmUserPrivKeyChange */
373   {10, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY}, /* usmUserOwnPrivKeyChange */
374   {11, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY}, /* usmUserPublic */
375   {12, SNMP_ASN1_TYPE_INTEGER,      SNMP_NODE_INSTANCE_READ_ONLY}, /* usmUserStorageType */
376   {13, SNMP_ASN1_TYPE_INTEGER,      SNMP_NODE_INSTANCE_READ_ONLY}, /* usmUserStatus */
377 };
378 static const struct snmp_table_node usmusertable = SNMP_TABLE_CREATE(2, usmusertable_columns, usmusertable_get_instance, usmusertable_get_next_instance, usmusertable_get_value, NULL, NULL);
379 
380 static const struct snmp_node *const usmuser_subnodes[] = {
381   &usmusertable.node.node
382 };
383 static const struct snmp_tree_node usmuser_treenode = SNMP_CREATE_TREE_NODE(2, usmuser_subnodes);
384 
385 /* --- usmMIBObjects 1.3.6.1.6.3.15.1 ----------------------------------------------------- */
386 static const struct snmp_scalar_array_node_def usmstats_scalars_nodes[] = {
387   {1, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* usmStatsUnsupportedSecLevels */
388   {2, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* usmStatsNotInTimeWindows */
389   {3, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* usmStatsUnknownUserNames */
390   {4, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* usmStatsUnknownEngineIDs */
391   {5, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* usmStatsWrongDigests */
392   {6, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* usmStatsDecryptionErrors */
393 };
394 static const struct snmp_scalar_array_node usmstats_scalars = SNMP_SCALAR_CREATE_ARRAY_NODE(1, usmstats_scalars_nodes, usmstats_scalars_get_value, NULL, NULL);
395 
396 static const struct snmp_node *const usmmibobjects_subnodes[] = {
397   &usmstats_scalars.node.node,
398   &usmuser_treenode.node
399 };
400 static const struct snmp_tree_node usmmibobjects_treenode = SNMP_CREATE_TREE_NODE(1, usmmibobjects_subnodes);
401 
402 /* --- snmpUsmMIB  ----------------------------------------------------- */
403 static const struct snmp_node *const snmpusmmib_subnodes[] = {
404   &usmmibobjects_treenode.node
405 };
406 static const struct snmp_tree_node snmpusmmib_root = SNMP_CREATE_TREE_NODE(15, snmpusmmib_subnodes);
407 static const u32_t snmpusmmib_base_oid[] = {1, 3, 6, 1, 6, 3, 15};
408 const struct snmp_mib snmpusmmib = {snmpusmmib_base_oid, LWIP_ARRAYSIZE(snmpusmmib_base_oid), &snmpusmmib_root.node};
409 
410 #endif /* LWIP_SNMP */
411