source: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/snmp/snmp_v3/snmpv3_dummy.c@ 457

Last change on this file since 457 was 457, checked in by coas-nagasima, 4 years ago

ファイルを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 10.1 KB
Line 
1/**
2 * @file
3 * Dummy SNMPv3 functions.
4 */
5
6/*
7 * Copyright (c) 2016 Elias Oenal.
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without modification,
11 * are permitted provided that the following conditions are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright notice,
14 * this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright notice,
16 * this list of conditions and the following disclaimer in the documentation
17 * and/or other materials provided with the distribution.
18 * 3. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
22 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
23 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
24 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
26 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
29 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
30 * OF SUCH DAMAGE.
31 *
32 * Author: Elias Oenal <lwip@eliasoenal.com>
33 * Dirk Ziegelmeier <dirk@ziegelmeier.net>
34 */
35
36#include "lwip/apps/snmpv3.h"
37#include "snmpv3_dummy.h"
38#include <string.h>
39#include "lwip/err.h"
40#include "lwip/def.h"
41#include "lwip/timeouts.h"
42
43#if LWIP_SNMP && LWIP_SNMP_V3
44
45struct user_table_entry {
46 char username[32];
47 snmpv3_auth_algo_t auth_algo;
48 u8_t auth_key[20];
49 snmpv3_priv_algo_t priv_algo;
50 u8_t priv_key[20];
51};
52
53static struct user_table_entry user_table[] = {
54 { "lwip", SNMP_V3_AUTH_ALGO_INVAL, "" , SNMP_V3_PRIV_ALGO_INVAL, "" },
55 { "piwl", SNMP_V3_AUTH_ALGO_INVAL, "" , SNMP_V3_PRIV_ALGO_INVAL, "" },
56 { "test", SNMP_V3_AUTH_ALGO_INVAL, "" , SNMP_V3_PRIV_ALGO_INVAL, "" }
57};
58
59static char snmpv3_engineid[32];
60static u8_t snmpv3_engineid_len;
61
62static u32_t enginetime = 0;
63
64/* In this implementation engineboots is volatile. In a real world application this value should be stored in non-volatile memory.*/
65static u32_t engineboots = 0;
66
67/**
68 * @brief Get the user table entry for the given username.
69 *
70 * @param[in] username pointer to the username
71 *
72 * @return pointer to the user table entry or NULL if not found.
73 */
74static struct user_table_entry*
75get_user(const char *username)
76{
77 size_t i;
78
79 for (i = 0; i < LWIP_ARRAYSIZE(user_table); i++) {
80 if (strnlen(username, 32) != strnlen(user_table[i].username, 32)) {
81 continue;
82 }
83
84 if (memcmp(username, user_table[i].username, strnlen(username, 32)) == 0) {
85 return &user_table[i];
86 }
87 }
88
89 return NULL;
90}
91
92u8_t
93snmpv3_get_amount_of_users(void)
94{
95 return LWIP_ARRAYSIZE(user_table);
96}
97
98/**
99 * @brief Get the username of a user number (index)
100 * @param username is a pointer to a string.
101 * @param index is the user index.
102 * @return ERR_OK if user is found, ERR_VAL is user is not found.
103 */
104err_t
105snmpv3_get_username(char *username, u8_t index)
106{
107 if (index < LWIP_ARRAYSIZE(user_table)) {
108 MEMCPY(username, user_table[index].username, sizeof(user_table[0].username));
109 return ERR_OK;
110 }
111
112 return ERR_VAL;
113}
114
115/**
116 * Timer callback function that increments enginetime and reschedules itself.
117 *
118 * @param arg unused argument
119 */
120static void
121snmpv3_enginetime_timer(void *arg)
122{
123 LWIP_UNUSED_ARG(arg);
124
125 enginetime++;
126
127 /* This handles the engine time reset */
128 snmpv3_get_engine_time_internal();
129
130 /* restart timer */
131 sys_timeout(1000, snmpv3_enginetime_timer, NULL);
132}
133
134err_t
135snmpv3_set_user_auth_algo(const char *username, snmpv3_auth_algo_t algo)
136{
137 struct user_table_entry *p = get_user(username);
138
139 if (p) {
140 switch (algo) {
141 case SNMP_V3_AUTH_ALGO_INVAL:
142 if (p->priv_algo != SNMP_V3_PRIV_ALGO_INVAL) {
143 /* Privacy MUST be disabled before configuring authentication */
144 break;
145 } else {
146 p->auth_algo = algo;
147 return ERR_OK;
148 }
149#if LWIP_SNMP_V3_CRYPTO
150 case SNMP_V3_AUTH_ALGO_MD5:
151 case SNMP_V3_AUTH_ALGO_SHA:
152#endif
153 p->auth_algo = algo;
154 return ERR_OK;
155 default:
156 break;
157 }
158 }
159
160 return ERR_VAL;
161}
162
163err_t
164snmpv3_set_user_priv_algo(const char *username, snmpv3_priv_algo_t algo)
165{
166 struct user_table_entry *p = get_user(username);
167
168 if (p) {
169 switch (algo) {
170#if LWIP_SNMP_V3_CRYPTO
171 case SNMP_V3_PRIV_ALGO_AES:
172 case SNMP_V3_PRIV_ALGO_DES:
173 if (p->auth_algo == SNMP_V3_AUTH_ALGO_INVAL) {
174 /* Authentication MUST be enabled before configuring privacy */
175 break;
176 } else {
177 p->priv_algo = algo;
178 return ERR_OK;
179 }
180#endif
181 case SNMP_V3_PRIV_ALGO_INVAL:
182 p->priv_algo = algo;
183 return ERR_OK;
184 default:
185 break;
186 }
187 }
188
189 return ERR_VAL;
190}
191
192err_t
193snmpv3_set_user_auth_key(const char *username, const char *password)
194{
195 struct user_table_entry *p = get_user(username);
196 const char *engineid;
197 u8_t engineid_len;
198
199 if (p) {
200 /* password should be at least 8 characters long */
201 if (strlen(password) >= 8) {
202 memset(p->auth_key, 0, sizeof(p->auth_key));
203 snmpv3_get_engine_id(&engineid, &engineid_len);
204 switch (p->auth_algo) {
205 case SNMP_V3_AUTH_ALGO_INVAL:
206 return ERR_OK;
207#if LWIP_SNMP_V3_CRYPTO
208 case SNMP_V3_AUTH_ALGO_MD5:
209 snmpv3_password_to_key_md5((const u8_t*)password, strlen(password), (const u8_t*)engineid, engineid_len, p->auth_key);
210 return ERR_OK;
211 case SNMP_V3_AUTH_ALGO_SHA:
212 snmpv3_password_to_key_sha((const u8_t*)password, strlen(password), (const u8_t*)engineid, engineid_len, p->auth_key);
213 return ERR_OK;
214#endif
215 default:
216 return ERR_VAL;
217 }
218 }
219 }
220
221 return ERR_VAL;
222}
223
224err_t
225snmpv3_set_user_priv_key(const char *username, const char *password)
226{
227 struct user_table_entry *p = get_user(username);
228 const char *engineid;
229 u8_t engineid_len;
230
231 if (p) {
232 /* password should be at least 8 characters long */
233 if (strlen(password) >= 8) {
234 memset(p->priv_key, 0, sizeof(p->priv_key));
235 snmpv3_get_engine_id(&engineid, &engineid_len);
236 switch (p->auth_algo) {
237 case SNMP_V3_AUTH_ALGO_INVAL:
238 return ERR_OK;
239#if LWIP_SNMP_V3_CRYPTO
240 case SNMP_V3_AUTH_ALGO_MD5:
241 snmpv3_password_to_key_md5((const u8_t*)password, strlen(password), (const u8_t*)engineid, engineid_len, p->priv_key);
242 return ERR_OK;
243 case SNMP_V3_AUTH_ALGO_SHA:
244 snmpv3_password_to_key_sha((const u8_t*)password, strlen(password), (const u8_t*)engineid, engineid_len, p->priv_key);
245 return ERR_OK;
246#endif
247 default:
248 return ERR_VAL;
249 }
250 }
251 }
252
253 return ERR_VAL;
254}
255
256/**
257 * @brief Get the storage type of the given username.
258 *
259 * @param[in] username pointer to the username
260 * @param[out] type the storage type
261 *
262 * @return ERR_OK if the user was found, ERR_VAL if not.
263 */
264err_t
265snmpv3_get_user_storagetype(const char *username, snmpv3_user_storagetype_t *type)
266{
267 if (get_user(username) != NULL) {
268 /* Found user in user table
269 * In this dummy implementation, storage is permanent because no user can be deleted.
270 * All changes to users are lost after a reboot.*/
271 *type = SNMP_V3_USER_STORAGETYPE_PERMANENT;
272 return ERR_OK;
273 }
274
275 return ERR_VAL;
276}
277
278/**
279 * @param username is a pointer to a string.
280 * @param auth_algo is a pointer to u8_t. The implementation has to set this if user was found.
281 * @param auth_key is a pointer to a pointer to a string. Implementation has to set this if user was found.
282 * @param priv_algo is a pointer to u8_t. The implementation has to set this if user was found.
283 * @param priv_key is a pointer to a pointer to a string. Implementation has to set this if user was found.
284 */
285err_t
286snmpv3_get_user(const char* username, snmpv3_auth_algo_t *auth_algo, u8_t *auth_key, snmpv3_priv_algo_t *priv_algo, u8_t *priv_key)
287{
288 const struct user_table_entry *p;
289
290 /* The msgUserName specifies the user (principal) on whose behalf the
291 message is being exchanged. Note that a zero-length userName will
292 not match any user, but it can be used for snmpEngineID discovery. */
293 if(strlen(username) == 0) {
294 return ERR_OK;
295 }
296
297 p = get_user(username);
298
299 if (!p) {
300 return ERR_VAL;
301 }
302
303 if (auth_algo != NULL) {
304 *auth_algo = p->auth_algo;
305 }
306 if(auth_key != NULL) {
307 MEMCPY(auth_key, p->auth_key, sizeof(p->auth_key));
308 }
309 if (priv_algo != NULL) {
310 *priv_algo = p->priv_algo;
311 }
312 if(priv_key != NULL) {
313 MEMCPY(priv_key, p->priv_key, sizeof(p->priv_key));
314 }
315 return ERR_OK;
316}
317
318/**
319 * Get engine ID from persistence
320 */
321void
322snmpv3_get_engine_id(const char **id, u8_t *len)
323{
324 *id = snmpv3_engineid;
325 *len = snmpv3_engineid_len;
326}
327
328/**
329 * Store engine ID in persistence
330 */
331err_t
332snmpv3_set_engine_id(const char *id, u8_t len)
333{
334 MEMCPY(snmpv3_engineid, id, len);
335 snmpv3_engineid_len = len;
336 return ERR_OK;
337}
338
339/**
340 * Get engine boots from persistence. Must be increased on each boot.
341 */
342u32_t
343snmpv3_get_engine_boots(void)
344{
345 return engineboots;
346}
347
348/**
349 * Store engine boots in persistence
350 */
351void
352snmpv3_set_engine_boots(u32_t boots)
353{
354 engineboots = boots;
355}
356
357/**
358 * RFC3414 2.2.2.
359 * Once the timer reaches 2147483647 it gets reset to zero and the
360 * engine boot ups get incremented.
361 */
362u32_t
363snmpv3_get_engine_time(void)
364{
365 return enginetime;
366}
367
368/**
369 * Reset current engine time to 0
370 */
371void
372snmpv3_reset_engine_time(void)
373{
374 enginetime = 0;
375}
376
377/**
378 * Initialize dummy SNMPv3 implementation
379 */
380void
381snmpv3_dummy_init(void)
382{
383 snmpv3_set_engine_id("FOO", 3);
384
385 snmpv3_set_user_auth_algo("lwip", SNMP_V3_AUTH_ALGO_SHA);
386 snmpv3_set_user_auth_key("lwip", "maplesyrup");
387
388 snmpv3_set_user_priv_algo("lwip", SNMP_V3_PRIV_ALGO_DES);
389 snmpv3_set_user_priv_key("lwip", "maplesyrup");
390
391 /* Start the engine time timer */
392 snmpv3_enginetime_timer(NULL);
393}
394
395#endif /* LWIP_SNMP && LWIP_SNMP_V3 */
Note: See TracBrowser for help on using the repository browser.