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