SNMP++  3.3.4
usm_v3.h
Go to the documentation of this file.
1 /*_############################################################################
2  _##
3  _## usm_v3.h
4  _##
5  _## SNMP++ v3.3
6  _## -----------------------------------------------
7  _## Copyright (c) 2001-2013 Jochen Katz, Frank Fock
8  _##
9  _## This software is based on SNMP++2.6 from Hewlett Packard:
10  _##
11  _## Copyright (c) 1996
12  _## Hewlett-Packard Company
13  _##
14  _## ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
15  _## Permission to use, copy, modify, distribute and/or sell this software
16  _## and/or its documentation is hereby granted without fee. User agrees
17  _## to display the above copyright notice and this license notice in all
18  _## copies of the software and any documentation of the software. User
19  _## agrees to assume all liability for the use of the software;
20  _## Hewlett-Packard and Jochen Katz make no representations about the
21  _## suitability of this software for any purpose. It is provided
22  _## "AS-IS" without warranty of any kind, either express or implied. User
23  _## hereby grants a royalty-free license to any and all derivatives based
24  _## upon this software code base.
25  _##
26  _##########################################################################*/
27 // $Id: usm_v3.h 2359 2013-05-09 20:07:01Z fock $
28 
29 #ifndef _USM_V3
30 #define _USM_V3
31 
32 #include "snmp_pp/config_snmp_pp.h"
33 
34 #ifdef _SNMPv3
35 
36 #include "snmp_pp/smi.h"
37 #include "snmp_pp/octet.h"
38 #include "snmp_pp/address.h"
39 
40 #ifdef SNMP_PP_NAMESPACE
41 namespace Snmp_pp {
42 #endif
43 
44 #ifndef MAXUINT32
45 #define MAXUINT32 4294967295u
46 #endif
47 
48 // the maximum allowed length of the username
49 #define MAXLEN_USMUSERNAME 32
50 #define MAXLEN_USMSECURITYNAME MAXLEN_USMUSERNAME
51 
52 #define SNMPv3_AUTHFLAG 0x01
53 #define SNMPv3_PRIVFLAG 0x02
54 #define SNMPv3_REPORTABLEFLAG 0x04
55 
56 #define NOKEY 0
57 #define AUTHKEY 1
58 #define PRIVKEY 2
59 #define OWNAUTHKEY 3
60 #define OWNPRIVKEY 4
61 
62 /** @name SecurityLevels
63  *
64  * When sending a SNMPv3 message, one of these security levels can be
65  * set on the Pdu object.
66  */
67 //@{
68 #define SNMP_SECURITY_LEVEL_NOAUTH_NOPRIV 1 ///< noAuthNoPriv
69 #define SNMP_SECURITY_LEVEL_AUTH_NOPRIV 2 ///< authNoPriv
70 #define SNMP_SECURITY_LEVEL_AUTH_PRIV 3 ///< authPriv
71 //@}
72 
73 /** @name AuthProtocols
74  *
75  * Each user of the USM must use one authentication protocol (which
76  * may be none.
77  */
78 //@{
79 #define SNMP_AUTHPROTOCOL_NONE 1 ///< None
80 #define SNMP_AUTHPROTOCOL_HMACMD5 2 ///< HMAC-MD5
81 #define SNMP_AUTHPROTOCOL_HMACSHA 3 ///< HMAC-SHA
82 //@}
83 
84 /** @name PrivProtocols
85  *
86  * Each user of the USM must use one privacy protocol (which may be
87  * none.
88  */
89 //@{
90 #define SNMP_PRIVPROTOCOL_NONE 1 ///< None
91 #define SNMP_PRIVPROTOCOL_DES 2 ///< DES
92 #define SNMP_PRIVPROTOCOL_AES128 4 ///< AES128 (RFC 3826)
93 
94 #define SNMP_PRIVPROTOCOL_IDEA 9 ///< IDEA (non standard)
95 #define SNMP_PRIVPROTOCOL_AES192 20 ///< AES192 (non standard)
96 #define SNMP_PRIVPROTOCOL_AES256 21 ///< AES256 (non standard)
97 #define SNMP_PRIVPROTOCOL_3DESEDE 3 ///< 3DES (expired draft standard)
98 //@}
99 
100 /** @name USM-ErrorCodes
101  *
102  * Each method of the class USM may return one of the following
103  * error codes.
104  */
105 //@{
106 #define SNMPv3_USM_OK 1400
107 #define SNMPv3_USM_ERROR 1401
108 #define SNMPv3_USM_ERROR_CONFIGFILE 1402
109 #define SNMPv3_USM_UNSUPPORTED_SECURITY_LEVEL 1403
110 #define SNMPv3_USM_UNKNOWN_SECURITY_NAME 1404
111 #define SNMPv3_USM_ENCRYPTION_ERROR 1405
112 #define SNMPv3_USM_DECRYPTION_ERROR 1406
113 #define SNMPv3_USM_AUTHENTICATION_ERROR 1407
114 #define SNMPv3_USM_AUTHENTICATION_FAILURE 1408
115 #define SNMPv3_USM_PARSE_ERROR 1409
116 #define SNMPv3_USM_UNKNOWN_ENGINEID 1410
117 #define SNMPv3_USM_NOT_IN_TIME_WINDOW 1411
118 #define SNMPv3_USM_UNSUPPORTED_AUTHPROTOCOL 1412
119 #define SNMPv3_USM_UNSUPPORTED_PRIVPROTOCOL 1413
120 #define SNMPv3_USM_ADDRESS_ERROR 1414
121 #define SNMPv3_USM_FILECREATE_ERROR 1415
122 #define SNMPv3_USM_FILEOPEN_ERROR 1416
123 #define SNMPv3_USM_FILERENAME_ERROR 1417
124 #define SNMPv3_USM_FILEDELETE_ERROR 1418
125 #define SNMPv3_USM_FILEWRITE_ERROR 1419
126 #define SNMPv3_USM_FILEREAD_ERROR 1420
127 //@}
128 
129 /** @name Statistics on error codes. */
130 //@{
131 #define SNMPv3_USM_MAX_ERROR SNMPv3_USM_FILEREAD_ERROR
132 #define SNMPv3_USM_MIN_ERROR SNMPv3_USM_OK
133 #define SNMPv3_USM_ERRORCOUNT SNMPv3_USM_MAX_ERROR - SNMPv3_USM_MIN_ERROR
134 //@}
135 
136 #define oidUsmStats "1.3.6.1.6.3.15.1.1"
137 #define oidUsmStatsUnsupportedSecLevels "1.3.6.1.6.3.15.1.1.1.0"
138 #define oidUsmStatsNotInTimeWindows "1.3.6.1.6.3.15.1.1.2.0"
139 #define oidUsmStatsUnknownUserNames "1.3.6.1.6.3.15.1.1.3.0"
140 #define oidUsmStatsUnknownEngineIDs "1.3.6.1.6.3.15.1.1.4.0"
141 #define oidUsmStatsWrongDigests "1.3.6.1.6.3.15.1.1.5.0"
142 #define oidUsmStatsDecryptionErrors "1.3.6.1.6.3.15.1.1.6.0"
143 
144 #define oidUsmUserTable "1.3.6.1.6.3.15.1.2.2"
145 #define oidUsmUserEntry "1.3.6.1.6.3.15.1.2.2.1"
146 
147 #define oidUsmAuthProtocolBase "1.3.6.1.6.3.10.1.1"
148 #define oidUsmNoAuthProtocol "1.3.6.1.6.3.10.1.1.1"
149 #define oidUsmHMACMD5AuthProtocol "1.3.6.1.6.3.10.1.1.2"
150 #define oidUsmHMACSHAAuthProtocol "1.3.6.1.6.3.10.1.1.3"
151 
152 #define oidUsmPrivProtocolBase "1.3.6.1.6.3.10.1.2"
153 #define oidUsmNoPrivProtocol "1.3.6.1.6.3.10.1.2.1"
154 #define oidUsmDESPrivProtocol "1.3.6.1.6.3.10.1.2.2"
155 #define oidUsmIDEAPrivProtocol "1.3.6.1.6.3.10.1.2.9"
156 #define oidUsmAES128PrivProtocol "1.3.6.1.6.3.10.1.2.4"
157 #define oidUsmAES192PrivProtocol "1.3.6.1.6.3.10.1.2.20"
158 #define oidUsmAES256PrivProtocol "1.3.6.1.6.3.10.1.2.21"
159 #define oidUsm3DESEDEPrivProtocol "1.3.6.1.6.3.10.1.2.3"
160 
161 
162 #define USM_KeyUpdate 1
163 #define USM_PasswordUpdate 2
164 #define USM_PasswordKeyUpdate 3
165 #define USM_PasswordAllKeyUpdate 4
166 
167 class SnmpTarget;
168 class Pdu;
169 
170 struct UsmKeyUpdate;
171 
173  unsigned char *usmUserEngineID; long int usmUserEngineIDLength;
174  unsigned char *usmUserName; long int usmUserNameLength;
175  unsigned char *usmUserSecurityName; long int usmUserSecurityNameLength;
177  unsigned char *usmUserAuthKey; long int usmUserAuthKeyLength;
179  unsigned char *usmUserPrivKey; long int usmUserPrivKeyLength;
180 };
181 
182 struct UsmUser {
183  unsigned char *engineID; long int engineIDLength;
184  unsigned char *usmUserName; long int usmUserNameLength;
185  unsigned char *securityName; long int securityNameLength;
186  long int authProtocol;
187  unsigned char *authKey; long int authKeyLength;
188  long int privProtocol;
189  unsigned char *privKey; long int privKeyLength;
190 };
191 
197  unsigned char *authPassword; long int authPasswordLength;
198  unsigned char *privPassword; long int privPasswordLength;
199 };
200 
201 //-----------[ async methods callback ]-----------------------------------
202 typedef void (*usm_add_user_callback)(const OctetStr &engine_id,
203  const OctetStr &usm_user_name,
204  const OctetStr &usm_user_security_name,
205  const int auth_protocol,
206  const OctetStr &auth_key,
207  const int priv_protocol,
208  const OctetStr &priv_key);
209 
210 struct SecurityStateReference;
211 
212 class AuthPriv;
213 class USMTimeTable;
214 class USMUserNameTable;
215 class USMUserTable;
216 class v3MP;
217 
218 /**
219  * This is the class for the User Based Security Model.
220  *
221  * To add or delete users, the methods add_usm_user() and delete_usm_user()
222  * should be used.
223  *
224  * USM distinguishes between userName and securityName. The following is
225  * from section 2.1 of RFC3414:
226  *
227  * "userName: A string representing the name of the user.
228  *
229  * securityName: A human-readable string representing the user in a format
230  * that is Security Model independent. There is a one-to-one relationship *
231  * between userName and securityName."
232  */
233 class DLLOPT USM
234 {
235  friend class v3MP;
236 
237 public:
238 
239  /**
240  * Create an instance of the USM.
241  *
242  * @param engine_boots - The new value for the snmpEngineBoots counter
243  * @param engine_id - The local snmp engine id
244  * @param v3_mp - Pointer to the parent v3MP object.
245  * @param msg_id - OUT: The initial value for the msgID
246  * @param result - OUT: construct status, should be SNMPv3_USM_OK
247  */
248  USM(unsigned int engine_boots, const OctetStr &engine_id, const v3MP *v3_mp,
249  unsigned int *msg_id, int &result);
250 
251  /**
252  * Destructor.
253  */
254  ~USM();
255 
256  /**
257  * Enables the discovery mode of the USM, i.e. the USM accepts all messages
258  * with unknown engine ids and adds these engine ids to its tables.
259  */
260  void set_discovery_mode() { discovery_mode = true; };
261 
262  /**
263  * Disables the discovery mode of the USM, i.e. the USM will not accept any
264  * message with an unknown engine id.
265  */
266  void unset_discovery_mode() { discovery_mode = false; };
267 
268  /**
269  * Return TRUE if the USM discovery mode is enabled, FALSE else.
270  */
271  bool is_discovery_enabled() const { return discovery_mode; };
272 
273  /**
274  * Add a new user to the usmUserNameTable. If the User is already known
275  * to the USM, the old entry is replaced.
276  * The USM will compute a userName for the given securityName, which
277  * will be the same as securityName (recommended).
278  *
279  * If discovery mode is enabled, localized user entries are
280  * automatically created for new engine ids.
281  *
282  * @param security_name - Unique securityName
283  * @param auth_protocol - Possible values are:
284  * SNMP_AUTHPROTOCOL_NONE,
285  * SNMP_AUTHPROTOCOL_HMACMD5,
286  * SNMP_AUTHPROTOCOL_HMACSHA
287  * @param priv_protocol - Possible values are:
288  * SNMP_PRIVPROTOCOL_NONE,
289  * SNMP_PRIVPROTOCOL_DES,
290  * SNMP_PRIVPROTOCOL_IDEA
291  * @param auth_password - Secret password for authentication
292  * @param priv_password - Secret password for privacy
293  *
294  * @return - SNMPv3_USM_OK or
295  * SNMP_v3_USM_ERROR (memory error, not initialized)
296  */
297  int add_usm_user(const OctetStr& security_name,
298  const long int auth_protocol,
299  const long int priv_protocol,
300  const OctetStr& auth_password,
301  const OctetStr& priv_password);
302 
303  /**
304  * Add a new user to the usmUserNameTable. If the userName is already known
305  * to the USM, the old entry is replaced.
306  *
307  * It is not recommended to add users with userName != securityName.
308  *
309  * @param user_name - Unique userName
310  * @param security_name - Unique securityName
311  * @param auth_protocol - Possible values are:
312  * SNMP_AUTHPROTOCOL_NONE,
313  * SNMP_AUTHPROTOCOL_HMACMD5,
314  * SNMP_AUTHPROTOCOL_HMACSHA
315  * @param priv_protocol - Possible values are:
316  * SNMP_PRIVPROTOCOL_NONE,
317  * SNMP_PRIVPROTOCOL_DES,
318  * SNMP_PRIVPROTOCOL_IDEA
319  * @param auth_password - Secret password for authentication
320  * @param priv_password - Secret password for privacy
321  *
322  * @return - SNMPv3_USM_OK or
323  * SNMP_v3_USM_ERROR (memory error, not initialized)
324  */
325  int add_usm_user(const OctetStr& user_name,
326  const OctetStr& security_name,
327  const long int auth_protocol,
328  const long int priv_protocol,
329  const OctetStr& auth_password,
330  const OctetStr& priv_password);
331 
332 
333  /**
334  * Add or replace a localized user in the USM table.
335  *
336  * This function uses build_localized_keys() to generate localized
337  * keys for the given passwords. Then it calls add_localized_user()
338  * to add/replace the localized entry for the user.
339  *
340  * The passwords are not stored, so no additonal engine id discovery
341  * is possible.
342  *
343  * @param user_name - The name of the user (in the USM)
344  * @param security_name - The securityName of the user, this name
345  * is the same for all securityModels
346  * @param auth_protocol - Possible values are:
347  * SNMP_AUTHPROTOCOL_NONE,
348  * SNMP_AUTHPROTOCOL_HMACMD5,
349  * SNMP_AUTHPROTOCOL_HMACSHA,...
350  * @param priv_protocol - Possible values are:
351  * SNMP_PRIVPROTOCOL_NONE,
352  * SNMP_PRIVPROTOCOL_DES,
353  * SNMP_PRIVPROTOCOL_IDEA,...
354  * @param auth_password - Secret password for authentication
355  * @param priv_password - Secret password for privacy
356  * @param engine_id - The engineID, the key was localized with
357  *
358  * @return - SNMPv3_USM_OK
359  * SNMP_v3_USM_ERROR (not initialized, no memory)
360  */
361  int add_usm_user(const OctetStr& user_name,
362  const OctetStr& security_name,
363  const long int auth_protocol,
364  const long int priv_protocol,
365  const OctetStr& auth_password,
366  const OctetStr& priv_password,
367  const OctetStr& engine_id);
368 
369  int add_usm_user(const OctetStr& security_name,
370  const long int auth_protocol,
371  const long int priv_protocol,
372  const OctetStr& auth_password,
373  const OctetStr& priv_password,
374  const OctetStr& engine_id)
375  { return add_usm_user(security_name, security_name, auth_protocol,
376  priv_protocol, auth_password, priv_password,
377  engine_id); };
378 
379 
380  /**
381  * Delete all occurences of the user with the given security name
382  * from the USM.
383  *
384  * @param security_name - the securityName of the user
385  */
386  void delete_usm_user(const OctetStr& security_name);
387 
388 
389  /**
390  * Save all localized users into a file.
391  *
392  * @param file - filename including path
393  *
394  * @return SNMPv3_USM_ERROR, SNMPv3_USM_FILECREATE_ERROR,
395  * SNMPv3_USM_FILERENAME_ERROR or SNMPv3_USM_OK
396  */
397  int save_localized_users(const char *file);
398 
399  /**
400  * Load localized users from a file.
401  *
402  * @param file - filename including path
403  *
404  * @return SNMPv3_USM_ERROR, SNMPv3_USM_FILEOPEN_ERROR,
405  * SNMPv3_USM_FILEREAD_ERROR or SNMPv3_USM_OK
406  */
407  int load_localized_users(const char *file);
408 
409  /**
410  * Save all users with their passwords into a file.
411  *
412  * @param file - filename including path
413  *
414  * @return SNMPv3_USM_ERROR, SNMPv3_USM_FILECREATE_ERROR,
415  * SNMPv3_USM_FILERENAME_ERROR or SNMPv3_USM_OK
416  */
417  int save_users(const char *file);
418 
419  /**
420  * Load users with their passwords from a file.
421  *
422  * @param file - filename including path
423  *
424  * @return SNMPv3_USM_ERROR, SNMPv3_USM_FILEOPEN_ERROR,
425  * SNMPv3_USM_FILEREAD_ERROR or SNMPv3_USM_OK
426  */
427  int load_users(const char *file);
428 
429  /**
430  * Add or replace a localized user in the USM table. Use this method
431  * only, if you know what you are doing.
432  *
433  * @param engine_id - The engineID, the key was localized with
434  * @param user_name - The name of the user (in the USM)
435  * @param security_name - The securityName of the user, this name
436  * is the same for all securityModels
437  * @param auth_protocol - Possible values are:
438  * SNMP_AUTHPROTOCOL_NONE,
439  * SNMP_AUTHPROTOCOL_HMACMD5,
440  * SNMP_AUTHPROTOCOL_HMACSHA,...
441  * @param auth_key - The key used for authentications
442  * @param priv_protocol - Possible values are:
443  * SNMP_PRIVPROTOCOL_NONE,
444  * SNMP_PRIVPROTOCOL_DES,
445  * SNMP_PRIVPROTOCOL_IDEA,...
446  * @param priv_key - The key used for privacy
447  *
448  * @return - SNMPv3_USM_OK
449  * SNMP_v3_USM_ERROR (not initialized, no memory)
450  */
451  int add_localized_user(const OctetStr &engine_id,
452  const OctetStr &user_name,
453  const OctetStr &security_name,
454  const long auth_protocol,
455  const OctetStr &auth_key,
456  const long priv_protocol,
457  const OctetStr &priv_key);
458 
459  /**
460  * Generate localized keys for the given params.
461  *
462  * The buffers for the keys should be of size SNMPv3_USM_MAX_KEY_LEN.
463  *
464  * @param engine_id -
465  * @param auth_prot -
466  * @param priv_prot -
467  * @param auth_password -
468  * @param auth_password_len -
469  * @param priv_password -
470  * @param priv_password_len -
471  * @param auth_key - allocated space for the authentication key
472  * @param auth_key_len - IN: length of the buffer, OUT: key length
473  * @param priv_key - allocated space for the privacy key
474  * @param priv_key_len - IN: length of the buffer, OUT: key length
475  * @return SNMPv3_USM_OK, or USM error codes
476  */
477  int build_localized_keys(const OctetStr &engine_id,
478  const int auth_prot,
479  const int priv_prot,
480  const unsigned char *auth_password,
481  const unsigned int auth_password_len,
482  const unsigned char *priv_password,
483  const unsigned int priv_password_len,
484  unsigned char *auth_key,
485  unsigned int *auth_key_len,
486  unsigned char *priv_key,
487  unsigned int *priv_key_len);
488 
489  /**
490  * Delete all localized entries of this user from the usmUserTable.
491  *
492  * @param user_name - The userName that should be deleted
493  *
494  * @return - SNMPv3_USM_ERROR (not initialized),
495  * SNMPv3_USM_OK (user deleted or not in table)
496  */
497  int delete_localized_user(const OctetStr& user_name);
498 
499 
500  /**
501  * Delete the entry with the given userName and engineID
502  * from the usmUserTable
503  *
504  * @param engine_id - The engineID
505  * @param user_name - The userName that should be deleted
506  *
507  * @return - SNMPv3_USM_ERROR (not initialized),
508  * SNMPv3_USM_OK (user deleted or not in table)
509  */
510  int delete_localized_user(const OctetStr& engine_id,
511  const OctetStr& user_name);
512 
513 
514  /**
515  * Delete this engine id form all USM tables (users and engine time).
516  *
517  * @param engine_id - the engine id
518  *
519  * @return - SNMPv3_USM_ERROR (not initialized),
520  * SNMPv3_USM_OK (entries deleted or not in table)
521  */
522  int remove_engine_id(const OctetStr &engine_id);
523 
524  /**
525  * Delete the time information for the given engine id.
526  *
527  * @param engine_id - the engine id
528  *
529  * @return - SNMPv3_USM_ERROR (not initialized),
530  * SNMPv3_USM_OK (entry deleted or not in table)
531  */
532  int remove_time_information(const OctetStr &engine_id);
533 
534  /**
535  * Replace a localized key of the user and engineID in the
536  * usmUserTable.
537  *
538  * @param user_name - The name of the user in the USM
539  * @param user_name_len - The length of the user name
540  * @param engine_id - Change the localized key for the SNMP
541  * entity with this engine id
542  * @param engine_id_len - The length of the engine id
543  * @param new_key - The new key
544  * @param new_key_len - The length of the new key
545  * @param type_of_key - AUTHKEY, OWNAUTHKEY, PRIVKEY or OWNPRIVKEY
546  *
547  * @return - SNMPv3_USM_ERROR (no such entry or not initialized),
548  * SNMPv3_USM_OK
549  */
550  int update_key(const unsigned char* user_name, const long user_name_len,
551  const unsigned char* engine_id, const long engine_id_len,
552  const unsigned char* new_key, const long new_key_len,
553  const int type_of_key);
554 
555  /**
556  * Search for a user with the given securityName and engineID
557  * in the usmUserTable and return the entry. If no entry
558  * could be found, the usmUserNameTable is searched for the given
559  * securityName. If this table has an entry of this user, a
560  * localized entry is generated, added to the usmUserTable and
561  * returned to the caller.
562  *
563  * The caller has to call free_user() with the returned struct.
564  *
565  * @param engine_id -
566  * @param security_name -
567  *
568  * @return - a pointer to the structure if an entry could be found
569  * or was generated, NULL for all errors
570  */
571  struct UsmUser *get_user(const OctetStr &engine_id,
572  const OctetStr &security_name);
573 
574  /**
575  * Free the structure returned from get_user(OctetStr,OctetStr).
576  */
577  void free_user(struct UsmUser *&user);
578 
579  /**
580  * Get the security name from a user name.
581  *
582  * @param user_name -
583  * @param user_name_len -
584  * @param security_name - Buffer for the securityName
585  *
586  * @return - SNMPv3_USM_ERROR (not initialized, not found, buffer too small),
587  * SNMPv3_USM_OK
588  */
589  int get_security_name(const unsigned char *user_name,
590  const long int user_name_len,
591  OctetStr &security_name);
592 
593  /**
594  * Get the user name from a security name.
595  *
596  * @param user_name - Buffer for the userName
597  * @param user_name_len - Has to be set to the max length of the
598  * buffer. Is set to the length of the found
599  * securityName or to 0 if not found.
600  * @param security_name -
601  * @param security_name_len -
602  *
603  * @return - SNMPv3_USM_ERROR (not initialized, not found, buffer too small),
604  * SNMPv3_USM_OK
605  */
606  int get_user_name(unsigned char *user_name,
607  long int *user_name_len,
608  const unsigned char *security_name,
609  const long int security_name_len);
610 
611 
612  /**
613  * Prepare a key update in the USM. The following procedure is used: To
614  * prepare the key update, this function adds the neccessary variable
615  * bindings to the Pdu to do the key update on the target SNMP entity.
616  * The Pdu has to be sent to the target. If the key update on the target
617  * is successful, usmCommitKeyUpdate() has to be called to do the local key
618  * update. On failure usmAbortKeyUpdate() has to be called to free
619  * temporary ressources.
620  *
621  * @param securityName - The name of the user
622  * @param target - A target to identify the SNMP entity on which the
623  * key will be updated
624  * @param newPassword - The new password for the user
625  * @param pdu - A PDU into which this funktion adds the VBs needed
626  * to change the keys on the target
627  * @param type - Indicates how and which key should be chaned:
628  * possilbe values are: AUTHKEY, PRIVKEY and
629  * OWNAUTHKEY, OWNPRIVKEY.
630  * @param status - The return status: SNMPv3_USM_OK or one of the
631  * error codes
632  *
633  * @return - A structure, that is needed to commit/abort the key update.
634  * If an error occurs, the return value is NULL
635  */
636  struct UsmKeyUpdate* key_update_prepare(const OctetStr& securityName,
637  SnmpTarget& target,
638  const OctetStr& newPassword,
639  Pdu& pdu, int type,
640  int &status,
641  const OctetStr& oldpass = "",
642  const OctetStr& oldengid= "",
643  const OctetStr& newengid= "");
644 
645  /**
646  * Abort the local key update.
647  *
648  * @param uku - The pointer returned by usmPrepareKeyUpdate()
649  */
650  void key_update_abort(struct UsmKeyUpdate *uku);
651 
652 
653  /**
654  * Commit the local key update.
655  *
656  * @param uku - The pointer returned by usmPrepareKeyUpdate()
657  * @param update_type - One of USM_KeyUpdate, USM_PasswordKeyUpdate,
658  * USM_PasswordAllKeyUpdate
659  *
660  * @return - SNMPv3_USM_ERROR, SNMPv3_USM_OK
661  */
662  int key_update_commit(struct UsmKeyUpdate *uku, int update_type);
663 
664 
665  /**
666  * Get a pointer to the AuthPriv object used by the USM.
667  *
668  */
669  AuthPriv *get_auth_priv();
670 
671 
672  /**
673  * Return engineBoots and engineTime for a given engineID
674  *
675  * @param engine_id - The engineID of the SNMP entity
676  * @param engine_boots - OUT: boot counter (0 if not found)
677  * @param engine_time - OUT: engine time (0 if not found)
678  *
679  * @return - SNMPv3_USM_ERROR (not initialized),
680  * SNMPv3_USM_OK (entry found, values are filled)
681  * SNMPv3_USM_UNKNOWN_ENGINEID ( not found)
682  */
683  int get_time(const OctetStr &engine_id,
684  long int *engine_boots, long int *engine_time);
685 
686 
687 
688  /**
689  * Return engineBoots and engineTime of the local snmp entity
690  *
691  * @param engine_boots - OUT: boot counter (0 if not found)
692  * @param engine_time - OUT: engine time (0 if not found)
693  *
694  * @return - SNMPv3_USM_ERROR (not initialized),
695  * SNMPv3_USM_OK (entry found, values are filled)
696  */
697  int get_local_time(long int *engine_boots, long int *engine_time) const;
698 
699 
700  /**
701  * Return the local snmp engine id.
702  */
703  const OctetStr& get_local_engine_id() const { return local_snmp_engine_id; };
704 
705  /**
706  * Get the number of received messages with an unsupported securityLevel
707  *
708  * @return - usmStatsUnsupportedSecLevels
709  */
710  unsigned long get_stats_unsupported_sec_levels() const
711  { return usmStatsUnsupportedSecLevels; };
712 
713  /**
714  * Get the number of received messages outside time window
715  *
716  * @return - usmStatsNotInTimeWindows
717  */
718  unsigned long get_stats_not_in_time_windows() const
719  { return usmStatsNotInTimeWindows; };
720 
721  /**
722  * Get the number of received messages with a unknown userName
723  *
724  * @return - usmStatsUnknownUserNames
725  */
726  unsigned long get_stats_unknown_user_names() const
727  { return usmStatsUnknownUserNames; };
728 
729  /**
730  * Get the number of received messages with a unknown engineID
731  *
732  * @return - usmStatsUnknownEngineIDs
733  */
734  unsigned long get_stats_unknown_engine_ids() const
735  { return usmStatsUnknownEngineIDs; };
736 
737  /**
738  * Get the number of received messages with a wrong digest
739  *
740  * @return - usmStatsWrongDigests
741  */
742  unsigned long get_stats_wrong_digests() const
743  { return usmStatsWrongDigests; };
744 
745  /**
746  * Get the number of received messages with decryption errors
747  *
748  * @return - usmStatsDecryptionErrors
749  */
750  unsigned long get_stats_decryption_errors() const
751  { return usmStatsDecryptionErrors; };
752 
753  //@{
754  /**
755  * Increase the stats counter. Should only be used by agent++.
756  */
757  void inc_stats_unsupported_sec_levels();
758  void inc_stats_not_in_time_windows();
759  void inc_stats_unknown_user_names();
760  void inc_stats_unknown_engine_ids();
761  void inc_stats_wrong_digests();
762  void inc_stats_decryption_errors();
763  //@}
764 
765  /**
766  * Lock the UsmUserNameTable for access through peek_first_user()
767  * and peek_next_user().
768  */
769  void lock_user_name_table();
770 
771  /**
772  * Get a const pointer to the first entry of the UsmUserNameTable.
773  *
774  * @note Use lock_user_name_table() and unlock_user_name_table()
775  * for thread safety.
776  */
777  const UsmUserNameTableEntry *peek_first_user();
778 
779  /**
780  * Get a const pointer to the next entry of the UsmUserNameTable.
781  *
782  * @note Use lock_user_name_table() and unlock_user_name_table()
783  * for thread safety.
784  */
785  const UsmUserNameTableEntry *peek_next_user(const UsmUserNameTableEntry *e);
786 
787  /**
788  * Unlock the UsmUserNameTable after access through peek_first_user()
789  * and peek_next_user().
790  */
791  void unlock_user_name_table();
792 
793  /**
794  * Lock the UsmUserTable for access through peek_first_luser()
795  * and peek_next_luser().
796  */
797  void lock_user_table();
798 
799  /**
800  * Get a const pointer to the first entry of the UsmUserTable.
801  *
802  * @note Use lock_user_table() and unlock_user_table()
803  * for thread safety.
804  */
805  const UsmUserTableEntry *peek_first_luser();
806 
807  /**
808  * Get a const pointer to the next entry of the UsmUserTable.
809  *
810  * @note Use lock_user_table() and unlock_user_table()
811  * for thread safety.
812  */
813  const UsmUserTableEntry *peek_next_luser(const UsmUserTableEntry *e);
814 
815  /**
816  * Unlock the UsmUserTable after access through peek_first_luser()
817  * and peek_next_luser().
818  */
819  void unlock_user_table();
820 
821  /**
822  * for v3MP:
823  *
824  * Delete the pointers within the structure and the structure
825  * itself.
826  *
827  * @param ssr - The structure that should be deleted.
828  */
829  void delete_sec_state_reference(struct SecurityStateReference *ssr);
830 
831  /**
832  * Protected (for agent++):
833  *
834  * Get the user at the specified position of the usmUserTable.
835  *
836  * The returned pointer must NOT be deleted!
837  *
838  * @note lock_user_table() and unlock_user_table() must be used
839  * for thread synchronization.
840  *
841  * @param number - get the entry at position number (1...)
842  *
843  * @return - a pointer to the structure or NULL if number is out
844  * of range
845  */
846  const struct UsmUserTableEntry *get_user(int number);
847 
848  /**
849  * Get the properties of the specified user.
850  *
851  * The returned pointer must NOT be deleted!
852  *
853  * @note lock_user_table() and unlock_user_table() must be used
854  * for thread synchronization.
855  *
856  * @param security_name - The security name of the user
857  *
858  * @return - a pointer to the structure or NULL if number is out
859  * of range
860  */
861  const struct UsmUserNameTableEntry *get_user(const OctetStr &security_name);
862 
863  /**
864  * Protected (for agent++):
865  *
866  * Get the number of elements in the usmUserTable
867  *
868  * @note lock_user_table() and unlock_user_table() must be used
869  * for thread synchronization.
870  *
871  * @return - number of elements
872  */
873  int get_user_count() const;
874 
875 
876  /**
877  * Protected (for agent++)
878  *
879  * Register a callback function that is called if a new localized user
880  * has been added to the usm user table
881  */
882  void add_user_added_callback(const usm_add_user_callback cb);
883 
884  /**
885  * Clear all user configuration from this USM instance. This method is
886  * not synchronized. Do not use it while the USM is being used by other
887  * threads.
888  * @return
889  * SNMPv3_USM_OK on success.
890  */
891  int remove_all_users();
892 
893  protected:
894 
895  /**
896  * Get a new security state reference (for v3MP).
897  *
898  * @return - A newly created security state reference.
899  */
900  struct SecurityStateReference *get_new_sec_state_reference();
901 
902  /**
903  * Generate a complete message that is ready to send to the target.
904  *
905  * @param globalData - Buffer containing the serialized globalData,
906  * ready to be copied into the wholeMsg
907  * @param globalDataLength - The length of this buffer
908  * @param maxMessageSize - The maximum message size
909  * @param securityEngineID - The engineID of the authoritative SNMP entity
910  * @param securityName - The name of the user
911  * @param securityLevel - The security Level for this Message
912  * @param scopedPDU - Buffer containing the serialized scopedPDU,
913  * ready to be copied into the wholeMsg
914  * @param scopedPDULength - The length of this Buffer
915  * @param securityStateReference - The reference that was generated when
916  * the request was parsed. For request, this
917  * param has to be NULL. The reference
918  * is deleted by this function.
919  * @param wholeMsg - OUT: the buffer for the whole message
920  * @param wholeMsgLength - IN: lenght of the buffer.
921  * OUT: length of the generated message
922  *
923  * @return - SNMPv3_USM_OK on success. See snmperrs.h for the error codes
924  * of the USM.
925  */
926  int generate_msg(
927  unsigned char *globalData, // message header, admin data
928  int globalDataLength,
929  int maxMessageSize, // of the sending SNMP entity
930  const OctetStr &securityEngineID,// authoritative SNMP entity
931  const OctetStr &securityName, // on behalf of this principal
932  int securityLevel, // Level of Security requested
933  unsigned char *scopedPDU, // message (plaintext) payload
934  int scopedPDULength,
935  struct SecurityStateReference *securityStateReference,
936  unsigned char *wholeMsg, // OUT complete generated message
937  int *wholeMsgLength); // OUT length of generated message
938 
939 
940 
941  /**
942  * Parse a received message.
943  *
944  * @param maxMessageSize - The maximum message size of the snding
945  * SNMP entity.
946  * @param securityParameters - The security parameters as received
947  * @param securityParametersLength - The length of the security parameters
948  * @param securityParametersPosition - The position of the security
949  * parameters in the message
950  * @param securityLevel - The securityLevel of the message
951  * @param wholeMsg - The buffer with the whole message
952  * @param wholeMsgLength - The length of the whole message
953  * @param msgData - The buffer with the messageData
954  * @param msgDataLength - The length of the messageData buffer
955  * @param security_engine_id - OUT: the authoritative engineID
956  * @param security_name - OUT: the name of the user
957  * @param scopedPDU - OUT: buffer containing the scopedPDU
958  * @param scopedPDULength - IN: length of the buffer
959  * OUT: length of the scopedPDU
960  * @param maxSizeResponseScopedPDU - OUT: maximum size for a scopedPDU in a
961  * response message
962  * @param securityStateReference - OUT: the securityStateReference
963  * @param fromAddress - IN: Address of the sender
964  *
965  * @return - SNMPv3_USM_OK on success. See snmperrs.h for the error codes
966  * of the USM.
967  */
968  int process_msg(
969  int maxMessageSize, // of the sending SNMP entity
970  unsigned char *securityParameters, // for the received message
971  int securityParametersLength,
972  int securityParametersPosition,
973  long int securityLevel, // Level of Security
974  unsigned char *wholeMsg, // as received on the wire
975  int wholeMsgLength, // length as received on the wire
976  unsigned char *msgData,
977  int msgDataLength,
978  OctetStr &security_engine_id, // authoritative SNMP entity
979  OctetStr &security_name, //identification of the principal
980  unsigned char *scopedPDU, // message (plaintext) payload
981  int *scopedPDULength,
982  long *maxSizeResponseScopedPDU,// maximum size of the Response PDU
983  struct SecurityStateReference *securityStateReference,
984  // reference to security state
985  // information, needed for response
986  const UdpAddress &fromAddress); // Address of the sender
987 
988 private:
989 
990  /**
991  * Delete the pointers in the structure and set all values to 0/NULL.
992  *
993  * @param usp - The structure that should be deleted
994  */
995  void delete_sec_parameters( struct UsmSecurityParameters *usp);
996 
997 
998  /**
999  * Serialize the given values into the buffer according to the BER.
1000  *
1001  * UsmSecurityParameters ::=
1002  * SEQUENCE {
1003  * -- global User-based security parameters
1004  * msgAuthoritativeEngineID OCTET STRING (5..32)
1005  * msgAuthoritativeEngineBoots INTEGER (0..2147483647),
1006  * msgAuthoritativeEngineTime INTEGER (0..2147483647),
1007  * msgUserName OCTET STRING (SIZE(0..32)),
1008  * -- authentication protocol specific parameters
1009  * msgAuthenticationParameters OCTET STRING,
1010  * -- privacy protocol specific parameters
1011  * msgPrivacyParameters OCTET STRING
1012  * }
1013  *
1014  * @param outBuf - buffer for the serialized values
1015  * @param maxLength - before call: length of the buffer
1016  * after call: bytes left in the buffer
1017  * @param sp - the values to serialize
1018  * @param position - after call: points to the first byte of the
1019  * field for the authentication parameter
1020  *
1021  * @return - a pointer to the first free byte in the buffer,
1022  * NULL on error
1023  */
1024  unsigned char *build_sec_params(unsigned char *outBuf, int *maxLength,
1025  struct UsmSecurityParameters sp,
1026  int *position);
1027 
1028  /**
1029  * Serialize the given values acording to the BER into the
1030  * buffer. On success, the buffer contains a valid SNMPv3 message.
1031  *
1032  * @param outBuf - buffer for the serialized values
1033  * @param maxLength - before call: length of the buffer
1034  * after call: bytes left in the buffer
1035  * @param globalData - Buffer that contains the serialized globalData
1036  * @param globalDataLength - The length of this buffer
1037  * @param positionAuthPar - after call: points to the first byte of the
1038  * field for the authentication parameter
1039  * @param securityParameters - The security parameters
1040  * @param msgData - Buffer that contains the serialized msgData
1041  * @param msgDataLength - The length of this buffer
1042  *
1043  * @return - a pointer to the first free byte in the buffer,
1044  * NULL on error
1045  */
1046  unsigned char *build_whole_msg(
1047  unsigned char *outBuf, int *maxLength,
1048  unsigned char *globalData, long int globalDataLength,
1049  int *positionAuthPar,
1050  struct UsmSecurityParameters securityParameters,
1051  unsigned char *msgData, long int msgDataLength);
1052 
1053 
1054  /**
1055  * Delete the pointers in the structure
1056  *
1057  * @param user - The structure that should be deleted
1058  */
1059  inline void delete_user_ptr(struct UsmUser *user);
1060 
1061 
1062  private:
1063 
1064  OctetStr local_snmp_engine_id; ///< local snmp engine id
1065  const v3MP *v3mp; ///< Pointer to the v3MP that created this object
1066 
1067  // 0: don't accept messages from hosts with a unknown engine id
1069 
1070  // MIB Counters
1075  unsigned int usmStatsWrongDigests;
1077 
1078  // the instance of AuthPriv
1080 
1081  // this table contains time values of contacted snmp entities
1082  USMTimeTable *usm_time_table;
1083 
1084  // Users that are known but not localized to a engine ID
1085  USMUserNameTable *usm_user_name_table;
1086 
1087  // Table containing localized Users ready to use
1088  USMUserTable *usm_user_table;
1089 
1090  // Callback for agent++ to indicate new users in usm tables
1092 
1093 };
1094 
1095 
1096 // only for compatibility do not use these values and functions:
1097 // =============================================================
1098 
1099 #define SecurityLevel_noAuthNoPriv SNMP_SECURITY_LEVEL_NOAUTH_NOPRIV
1100 #define SecurityLevel_authNoPriv SNMP_SECURITY_LEVEL_AUTH_NOPRIV
1101 #define SecurityLevel_authPriv SNMP_SECURITY_LEVEL_AUTH_PRIV
1102 
1103 #define SNMPv3_usmNoAuthProtocol SNMP_AUTHPROTOCOL_NONE
1104 #define SNMPv3_usmHMACMD5AuthProtocol SNMP_AUTHPROTOCOL_HMACMD5
1105 #define SNMPv3_usmHMACSHAAuthProtocol SNMP_AUTHPROTOCOL_HMACSHA
1106 
1107 #define SNMPv3_usmNoPrivProtocol SNMP_PRIVPROTOCOL_NONE
1108 #define SNMPv3_usmDESPrivProtocol SNMP_PRIVPROTOCOL_DES
1109 #define SNMPv3_usmIDEAPrivProtocol SNMP_PRIVPROTOCOL_IDEA
1110 #define SNMPv3_usmAES128PrivProtocol SNMP_PRIVPROTOCOL_AES128
1111 #define SNMPv3_usmAES192PrivProtocol SNMP_PRIVPROTOCOL_AES192
1112 #define SNMPv3_usmAES256PrivProtocol SNMP_PRIVPROTOCOL_AES256
1113 
1114 #ifdef SNMP_PP_NAMESPACE
1115 } // end of namespace Snmp_pp
1116 #endif
1117 
1118 #endif // _SNMPv3
1119 
1120 #endif
long int privKeyLength
Definition: usm_v3.h:189
long int authPasswordLength
Definition: usm_v3.h:197
Class that holds all authentication and privacy protocols for a snmp entity.
Definition: auth_priv.h:336
unsigned long get_stats_unknown_user_names() const
Get the number of received messages with a unknown userName.
Definition: usm_v3.h:726
unsigned int usmStatsWrongDigests
Definition: usm_v3.h:1075
unsigned int usmStatsUnknownUserNames
Definition: usm_v3.h:1073
long int usmUserAuthProtocol
Definition: usm_v3.h:195
long int usmUserAuthProtocol
Definition: usm_v3.h:176
USMUserTable * usm_user_table
Definition: usm_v3.h:1088
long int usmUserEngineIDLength
Definition: usm_v3.h:173
bool discovery_mode
Definition: usm_v3.h:1068
long int authProtocol
Definition: usm_v3.h:186
OctetStr local_snmp_engine_id
local snmp engine id
Definition: usm_v3.h:1064
long int usmUserSecurityNameLength
Definition: usm_v3.h:175
unsigned long get_stats_decryption_errors() const
Get the number of received messages with decryption errors.
Definition: usm_v3.h:750
long int usmUserPrivKeyLength
Definition: usm_v3.h:179
long int usmUserAuthKeyLength
Definition: usm_v3.h:177
long int engineIDLength
Definition: usm_v3.h:183
long int privPasswordLength
Definition: usm_v3.h:198
unsigned int usmStatsNotInTimeWindows
Definition: usm_v3.h:1072
unsigned long get_stats_unknown_engine_ids() const
Get the number of received messages with a unknown engineID.
Definition: usm_v3.h:734
#define DLLOPT
long int usmUserNameLength
Definition: usm_v3.h:184
unsigned int usmStatsDecryptionErrors
Definition: usm_v3.h:1076
OctetStr usmUserName
Definition: usm_v3.h:193
unsigned long get_stats_not_in_time_windows() const
Get the number of received messages outside time window.
Definition: usm_v3.h:718
The SNMPv3 Message Processing Model (v3MP).
Definition: mp_v3.h:103
unsigned long get_stats_wrong_digests() const
Get the number of received messages with a wrong digest.
Definition: usm_v3.h:742
USMUserNameTable * usm_user_name_table
Definition: usm_v3.h:1085
long int authKeyLength
Definition: usm_v3.h:187
unsigned int usmStatsUnknownEngineIDs
Definition: usm_v3.h:1074
long int usmUserPrivProtocol
Definition: usm_v3.h:178
int add_usm_user(const OctetStr &security_name, const long int auth_protocol, const long int priv_protocol, const OctetStr &auth_password, const OctetStr &priv_password, const OctetStr &engine_id)
Definition: usm_v3.h:369
Definition: octet.h:67
long int usmUserNameLength
Definition: usm_v3.h:174
unsigned int usmStatsUnsupportedSecLevels
Definition: usm_v3.h:1071
int remove_engine_id(const OctetStr &engine_id)
Remove all occurences of this engine id from v3MP and USM.
OctetStr usmUserSecurityName
Definition: usm_v3.h:194
const OctetStr & get_local_engine_id() const
Return the local snmp engine id.
Definition: usm_v3.h:703
USMTimeTable * usm_time_table
Definition: usm_v3.h:1082
void set_discovery_mode()
Enables the discovery mode of the USM, i.e.
Definition: usm_v3.h:260
void(* usm_add_user_callback)(const OctetStr &engine_id, const OctetStr &usm_user_name, const OctetStr &usm_user_security_name, const int auth_protocol, const OctetStr &auth_key, const int priv_protocol, const OctetStr &priv_key)
Definition: usm_v3.h:202
void unset_discovery_mode()
Disables the discovery mode of the USM, i.e.
Definition: usm_v3.h:266
This is the class for the User Based Security Model.
Definition: usm_v3.h:233
long int usmUserPrivProtocol
Definition: usm_v3.h:196
long int securityNameLength
Definition: usm_v3.h:185
Pdu class...
Definition: pdu.h:81
long int privProtocol
Definition: usm_v3.h:188
bool is_discovery_enabled() const
Return TRUE if the USM discovery mode is enabled, FALSE else.
Definition: usm_v3.h:271
AuthPriv * auth_priv
Definition: usm_v3.h:1079
Abstract class used to provide a virtual interface into Targets.
Definition: target.h:92
usm_add_user_callback usm_add_user_cb
Definition: usm_v3.h:1091
const v3MP * v3mp
Pointer to the v3MP that created this object.
Definition: usm_v3.h:1065
unsigned long get_stats_unsupported_sec_levels() const
Get the number of received messages with an unsupported securityLevel.
Definition: usm_v3.h:710