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