]> git.stg.codes - ssmd.git/blob - 3rdparty/snmp++/include/snmp_pp/mp_v3.h
Initial adding
[ssmd.git] / 3rdparty / snmp++ / include / snmp_pp / mp_v3.h
1 /*_############################################################################
2   _## 
3   _##  mp_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
30 // $Id: mp_v3.h 320 2007-11-08 22:05:23Z katz $
31
32 #ifndef _MP_V3
33 #define _MP_V3
34
35 #include "snmp_pp/config_snmp_pp.h"
36
37 #ifdef _SNMPv3
38
39 #include "snmp_pp/reentrant.h"
40 #include "snmp_pp/target.h"
41
42 #ifdef SNMP_PP_NAMESPACE
43 namespace Snmp_pp {
44 #endif
45
46 class Pdu;
47 class OctetStr;
48
49 #define MAX_HOST_NAME_LENGTH     128
50
51 #define oidMPDGroup                  "1.3.6.1.6.3.11.2.1"
52 #define oidSnmpUnknownSecurityModels "1.3.6.1.6.3.11.2.1.1.0"
53 #define oidSnmpInvalidMsgs           "1.3.6.1.6.3.11.2.1.2.0"
54 #define oidSnmpUnknownPDUHandlers    "1.3.6.1.6.3.11.2.1.3.0"
55
56 /** @name Error codes of the v3MP */
57 //@{
58 #define SNMPv3_MP_ERROR                       -1400
59 #define SNMPv3_MP_OK                          -1401
60 #define SNMPv3_MP_UNSUPPORTED_SECURITY_MODEL  -1402
61 #define SNMPv3_MP_NOT_IN_TIME_WINDOW          -1403
62 #define SNMPv3_MP_DOUBLED_MESSAGE             -1404
63 #define SNMPv3_MP_INVALID_MESSAGE             -1405
64 #define SNMPv3_MP_INVALID_ENGINEID            -1406
65 #define SNMPv3_MP_NOT_INITIALIZED             -1407
66 #define SNMPv3_MP_PARSE_ERROR                 -1408
67 #define SNMPv3_MP_UNKNOWN_MSGID               -1409
68 #define SNMPv3_MP_MATCH_ERROR                 -1410
69 #define SNMPv3_MP_COMMUNITY_ERROR             -1411
70 #define SNMPv3_MP_WRONG_USER_NAME             -1412
71 #define SNMPv3_MP_BUILD_ERROR                 -1413
72 #define SNMPv3_MP_USM_ERROR                   -1414
73 #define SNMPv3_MP_UNKNOWN_PDU_HANDLERS        -1415
74 #define SNMPv3_MP_UNAVAILABLE_CONTEXT         -1416
75 #define SNMPv3_MP_UNKNOWN_CONTEXT             -1417
76 #define SNMPv3_MP_REPORT_SENT                 -1418
77 //@}
78
79 /** @name Statistics on error codes. */
80 //@{
81 #define SNMPv3_MP_MAX_ERROR           SNMPv3_MP_ERROR
82 #define SNMPv3_MP_MIN_ERROR           SNMPv3_MP_REPORT_SENT
83 #define SNMPv3_MP_ERRORCOUNT          SNMPv3_MP_MAX_ERROR - SNMPv3_MP_MIN_ERROR
84 //@}
85
86 class Snmp;
87 class USM;
88
89 /**
90  * The SNMPv3 Message Processing Model (v3MP).
91  *
92  * If SNMPv3 is used, the application needs to create _one_ object of
93  * this class. This object will automatically create an object of the
94  * USM class. A pointer to this object is returned from the get_usm()
95  * method. See the USM documentation for a description on how to create
96  * and delete users.
97  *
98  * The only thing that may be configured after creation of the v3MP is
99  * the engine id table of the v3MP. Entries for other SNMP entities
100  * can be added through add_to_engine_id_table(). It is only required
101  * to add entries to this table if you want to disable engine id
102  * discovery and/or you don't want the delay caused by the automatic
103  * engine id discovery of SNMPv3.
104  */
105 class DLLOPT v3MP
106 {
107   friend class SnmpMessage;
108   friend class CSNMPMessageQueue;
109  public:
110   /**
111    * Initialize the v3MP.
112    *
113    * Set the engineID of this SNMP entity and the Snmp object used to
114    * send reports. This function creates a new USM object that can
115    * be configured after getting a pointer to it through get_usm().
116    *
117    * The user is responsible to save and restore and increment the
118    * snmpEngineBoots counter (The functions getBootCounter() and
119    * saveBootCounter() can be used to do this.).
120    *
121    * @param engine_id    - The locale engine id
122    * @param engine_boots - The new value for the snmpEngineBoots counter
123    * @param construct_status - OUT: SNMPv3_MP_OK or SNMPv3_MP_ERROR
124    *
125    */
126   v3MP(const OctetStr& engine_id,
127        unsigned int engine_boots, int &construct_status);
128
129   /**
130    * Get the engine id of this SNMP entity.
131    *
132    * @param id - OUT: The engineID of this SNMP entity
133    *
134    * @return - SNMPv3_MP_OK or SNMPv3_MP_ERROR
135    */
136   void get_local_engine_id(OctetStr &id) { id = own_engine_id_oct; };
137
138   /**
139    * Get the engine id of this SNMP entity as a OctetStr reference.
140    *
141    * @return Local engine id.
142    */
143   const OctetStr& get_local_engine_id() const
144     { return own_engine_id_oct; };
145
146   /**
147    * Get a pointer to the USM object that is used by the v3MP.
148    */
149   USM *get_usm() { return usm; };
150
151   /**
152    * Free all allocated ressources of the v3MP and leave it in an
153    * uninitialized state. After a call to this function, you can use
154    * mpInit() to reinitialize the v3MP.
155    *
156    */
157   ~v3MP();
158
159   /**
160    * Add an entry to the engine id table.
161    *
162    * In this table all known engine ids are stored. If the discovery
163    * mode of the USM is enabled, snmp++ will add entries to this table
164    * whenever a new engine id is dicovered.
165    *
166    * @param engine_id - The engine id
167    * @param host      - The numerical IP address
168    * @param port      - The port
169    *
170    * @return - SNMPv3_MP_ERROR, SNMPv3_MP_OK
171    */
172   int add_to_engine_id_table(const OctetStr &engine_id,
173                              const OctetStr &host, int port)
174     { return engine_id_table.add_entry(engine_id, host, port); };
175
176   /**
177    * Remove an entry from the engine id table.
178    *
179    * @param host      - The numerical IP address
180    * @param port      - The port
181    *
182    * @return - SNMPv3_MP_ERROR, SNMPv3_MP_OK
183    */
184   int remove_from_engine_id_table(const OctetStr &host, int port)
185     { return engine_id_table.delete_entry(host, port); };
186
187   /**
188    * Remove an entry from the engine id table.
189    *
190    * @param engine_id - The engine id
191    *
192    * @return - SNMPv3_MP_ERROR, SNMPv3_MP_OK
193    */
194   int remove_from_engine_id_table(const OctetStr &engine_id)
195     { return engine_id_table.delete_entry(engine_id); };
196
197   /**
198    * Get the engine id of the SNMP entity at the given host/port.
199    *
200    * @param engine_id - OUT: The engine id
201    * @param hostport  - The numerical IP address and port
202    *                    (syntax: a.b.c.d/port)
203    *
204    * @return - SNMPv3_MP_NOT_INITIALIZED, SNMPv3_MP_ERROR,
205    *           SNMPv3_MP_OK
206    */
207   int get_from_engine_id_table(OctetStr &engine_id,
208                                const OctetStr &hostport) const
209     {  return engine_id_table.get_entry(engine_id, hostport); };
210
211   /**
212    * Get the engineID of the SNMP entity at the given host/port.
213    *
214    * @param engineID - OUT: The engineID
215    * @param host     - The numerical IP address
216    * @param port     - The port
217    *
218    * @return - SNMPv3_MP_NOT_INITIALIZED, SNMPv3_MP_ERROR,
219    *           SNMPv3_MP_OK
220    */
221   int get_from_engine_id_table(OctetStr &engineID,
222                                const OctetStr &host, int port) const
223     {  return engine_id_table.get_entry(engineID, host, port); };
224
225   /**
226    * Remove all entries from the engine id table.
227    *
228    * @return - SNMPv3_MP_NOT_INITIALIZED, SNMPv3_MP_ERROR,
229    *           SNMPv3_MP_OK
230    */
231   int reset_engine_id_table()
232     {  return engine_id_table.reset(); };
233
234   /**
235    * Remove all occurences of this engine id from v3MP and USM.
236    *
237    * @param engine_id - The engine id to remove
238    *
239    * @return - SNMPv3_MP_NOT_INITIALIZED, SNMPv3_MP_ERROR,
240    *           SNMPv3_MP_OK
241    */
242   int remove_engine_id(const OctetStr &engine_id);
243
244   // ----------[ Access to status counters for agent++ ]--------------
245
246   /**
247    * Get the value of the status counter snmpUnknownSecurityModels.
248    *
249    * @return - The status counter
250    */
251   unsigned long get_stats_unknown_security_models() const
252     { return snmpUnknownSecurityModels; };
253
254   /**
255    * Get the value of the status counter snmpInvalidMsgs.
256    *
257    * @return - The status counter
258    */
259   unsigned long get_stats_invalid_msgs() const
260     { return snmpInvalidMsgs; };
261
262   /**
263    * Get the value of the status counter snmpUnknownPDUHandlers.
264    *
265    * @return - The status counter
266    */
267   unsigned long get_stats_unknown_pdu_handlers() const
268     { return snmpUnknownPDUHandlers; };
269
270   /**
271    * Increment the value of the status counter snmpUnknownSecurityModels.
272    */
273   void inc_stats_unknown_security_models()
274     { snmpUnknownSecurityModels++; };
275
276   /**
277    * Increment the value of the status counter snmpInvalidMsgs.
278    */
279   void inc_stats_invalid_msgs() { snmpInvalidMsgs++; };
280
281   /**
282    * Increment the value of the status counter snmpUnknownPDUHandlers.
283    */
284   void inc_stats_unknown_pdu_handlers() { snmpUnknownPDUHandlers++; };
285
286   // temporary pointer will be removed...
287   static v3MP *I;
288
289  protected:
290
291   /**
292    * Parse the given buffer as a SNMPv3-Message.
293    *
294    * @param snmp_session     - IN: The session used to receive the msg
295    * @param pdu              - OUT: Parsed values are put into this struct
296    * @param inBuf            - The buffer to parse
297    * @param inBufLength      - The length of the buffer
298    * @param securityEngineID - OUT: The parsed securityEngineID
299    * @param securityName     - OUT: The parsed securityName
300    * @param contextEngineID  - OUT: The parsed contextEngineID
301    * @param contextName      - OUT: The parsed contextName
302    * @param securityLevel    - OUT: The parsed security level
303    * @param msgSecurityModel - OUT: The security model used
304    * @param spp_version      - OUT: SNMP version (SNMPv3)
305    * @param from_address     - Where the message came from (used to send
306    *                           a report if neccessary)
307    *
308    * @return - SNMPv3_MP_OK or any error listed in snmperr.h
309    */
310   int snmp_parse(Snmp *snmp_session,
311                  struct snmp_pdu *pdu,
312                  unsigned char *inBuf,
313                  int inBufLength,
314                  OctetStr &securityEngineID,
315                  OctetStr &securityName,
316                  OctetStr &contextEngineID,
317                  OctetStr &contextName,
318                  long     &securityLevel,
319                  long     &msgSecurityModel,
320                  snmp_version &spp_version,
321                  UdpAddress from_address);
322
323   /**
324    * Tests if the given buffer contains a SNMPv3-Message. The buffer is
325    * only parsed to extract the version of the message, no other checks
326    * are made.
327    *
328    * @param buffer - The message
329    * @param length - The length of the message
330    *
331    * @return - TRUE if the version could be extracted and it
332    *           is a SNMPv3 message. On any error: FALSE.
333    *
334    */
335   static bool is_v3_msg( unsigned char *buffer, int length);
336
337   /**
338    * Do the complete process of encoding the given values into the buffer
339    * ready to send to the target.
340    *
341    * @param pdu              - The pdu structure
342    * @param packet           - The buffer to store the serialized message
343    * @param out_length       - IN: Length of the buffer,
344    *                           OUT: Length of the message
345    * @param securityEngineID - The securityEngineID
346    * @param securityNameIn   - The securityName
347    * @param securityModel    - Use this security model
348    * @param securityLevel    - Use this security level
349    * @param contextEngineID  - The contextEngineID
350    * @param contextName      - The contextName
351    *
352    * @return - SNMPv3_MP_OK or any error listed in snmperr.h
353    */
354   int snmp_build(struct snmp_pdu *pdu,
355                  unsigned char *packet,
356                  int *out_length,           // maximum Bytes in packet
357                  const OctetStr &securityEngineID,
358                  const OctetStr &securityNameIn,
359                  int securityModel, int securityLevel,
360                  const OctetStr &contextEngineID,
361                  const OctetStr &contextName);
362
363   /**
364    * Delete the entry with the given request id from the cache.
365    * This function is used in eventlist.cpp when a request
366    * has timed out.
367    *
368    * @param requestID - The request id.
369    * @param local_request - Does the request id belong to a local or to
370    *                        a remote request?
371    */
372   void delete_from_cache(unsigned long requestID,
373                          const bool local_request = true)
374     { cache.delete_entry(requestID, local_request); };
375
376  public:
377
378   /**
379    * Delete the entry with the given request id from the cache.
380    * This function is used in agent++ RequestList.
381    *
382    * @param requestID - The request id.
383    * @param messageID - The message id.
384    * @param local_request - Does the request id belong to a local or to
385    *                        a remote request?
386    */
387   void delete_from_cache(unsigned long requestID,
388                          unsigned long messageID,
389                          const bool local_request)
390     { cache.delete_entry(requestID, messageID, local_request); };
391
392  private:
393
394   /**
395    * Send a report message.
396    *
397    * @param scopedPDU   - The scopedPDU as received. If the pdu is not
398    *                      encrypted, the request id is extracted
399    * @param scopedPDULength - The lkength of the scopedPDU
400    * @param pdu         - The pdu structure.
401    * @param errorCode   - The code of the error that occured.
402    * @param sLevel      - Send the report with this security level.
403    * @param sModel      - Use this security model.
404    * @param sName       - Use this security name
405    * @param destination - Send the report to this address.
406    * @param snmp_session - Snmp session to use for sending a report
407    *
408    * @return - SNMPv3_MP_ERROR, SNMPv3_MP_OK
409    */
410   int send_report(unsigned char* scopedPDU, int scopedPDULength,
411                   struct snmp_pdu *pdu, int errorCode, int sLevel,
412                   int sModel, OctetStr &sName,
413                   UdpAddress &destination, Snmp *snmp_session);
414
415
416
417   // =====================[ member classes ]==============================
418
419   /**
420    * The engine id table is used to store known engine ids with
421    * corresponding hostadress and port.
422    */
423   class DLLOPT EngineIdTable
424   {
425    public:
426
427     EngineIdTable(int initial_size = 10);
428     ~EngineIdTable();
429
430     /**
431      * Add an entry to the table.
432      *
433      * @param engine_id - The engineID
434      * @param host      - The numerical IP address
435      * @param port      - The port
436      *
437      * @return - SNMPv3_MP_ERROR, SNMPv3_MP_OK
438      */
439     int add_entry(const OctetStr &engine_id,
440                   const OctetStr &host, int port);
441
442     /**
443      * Get the engine_id of the SNMP entity at the given host/port.
444      *
445      * @param engine_id - OUT: The engineID
446      * @param hostport  - The numerical IP address and port
447      *                    (syntax: a.b.c.d/port)
448      *
449      * @return - SNMPv3_MP_NOT_INITIALIZED, SNMPv3_MP_ERROR,
450      *           SNMPv3_MP_OK
451      */
452     int get_entry(OctetStr &engine_id, const OctetStr &hostport) const;
453
454     /**
455      * Get the engineID of the SNMP entity at the given host/port.
456      *
457      * @param engine_id - OUT: The engineID
458      * @param host      - The numerical IP address
459      * @param port      - The port
460      *
461      * @return - SNMPv3_MP_NOT_INITIALIZED, SNMPv3_MP_ERROR,
462      *           SNMPv3_MP_OK
463      */
464     int get_entry(OctetStr &engine_id, const OctetStr &host, int port) const;
465
466     /**
467      * Remove all entries from the engine id table.
468      *
469      * @return - SNMPv3_MP_NOT_INITIALIZED, SNMPv3_MP_ERROR,
470      *           SNMPv3_MP_OK
471      */
472     int reset();
473
474     /**
475      * Remove the given engine id from the table.
476      *
477      * @param engine_id - The engine id to remove
478      *
479      * @return - SNMPv3_MP_NOT_INITIALIZED, SNMPv3_MP_ERROR,
480      *           SNMPv3_MP_OK
481      */
482     int delete_entry(const OctetStr &engine_id);
483
484     /**
485      * Remove the entry for the given address/port from the table.
486      *
487      * @param host - Numeric IP address
488      * @param port - listen port of the snmp entity
489      *
490      * @return - SNMPv3_MP_NOT_INITIALIZED, SNMPv3_MP_ERROR,
491      *           SNMPv3_MP_OK
492      */
493     int delete_entry(const OctetStr &host, int port);
494
495   private:
496     int initialize_table(const int size);
497
498     struct Entry_T
499     {
500       OctetStr engine_id;
501       OctetStr host;
502       int port;
503     };
504
505     struct Entry_T *table;
506     int max_entries;      ///< the maximum number of entries
507     int entries;          ///< the current amount of entries
508     SNMP_PP_MUTABLE SnmpSynchronized lock;
509   };
510
511
512   /**
513    * Holds cache entries for currently processed requests.
514    */
515   class DLLOPT Cache
516   {
517    public:
518     Cache();
519     ~Cache();
520
521     struct Entry_T
522     {
523       int msg_id;
524       unsigned long req_id;
525       OctetStr sec_engine_id;
526       int sec_model;
527       OctetStr sec_name;
528       int sec_level;
529       OctetStr context_engine_id;
530       OctetStr context_name;
531       struct SecurityStateReference *sec_state_ref;
532       int error_code;
533       bool local_request;
534     };
535
536     /**
537      * Add an entry to the cache.
538      *
539      * @param msg_id            - The message id of the message
540      * @param req_id        - The request id of the message
541      * @param sec_engine_id - The authoritative engineID
542      * @param sec_model    - The security model used for this message
543      * @param sec_name     - The name of the user
544      * @param sec_level    - The security level used for this message
545      * @param context_engine_id  - The context_engine_id
546      * @param context_name      - The context_name
547      * @param sec_state_ref - The reference of the USM
548      * @param error_code        - The code of the error that occured while
549      *                           parsing the received message
550      *
551      * @return - SNMPv3_MP_OK, SNMPv3_MP_ERROR or SNMPv3_DOUBLED_MESSAGE
552      *           (an entry with the given values is already in the cache)
553      */
554     int add_entry(int msg_id, unsigned long req_id,
555                   const OctetStr &sec_engine_id,
556                   int sec_model,
557                   const OctetStr &sec_name,
558                   int sec_level,
559                   const OctetStr &context_engine_id,
560                   const OctetStr &context_name,
561                   struct SecurityStateReference *sec_state_ref,
562                   int error_code, bool local_request);
563     /**
564      * Search the cache for a message id, return the error code and
565      * the sec_state_ref and delete the entry from the cache.
566      *
567      * @param msg_id     - Search for this message id
568      * @param error_code - OUT: The error code of the received message
569      * @param sec_state_ref - IN:  Pointer to a pointer of the structure
570      *                        OUT: The structure as received by the USM when
571      *                             the message was parsed.
572      *
573      * @return - SNMPv3_MP_ERROR, SNMPv3_MP_OK
574      */
575     int get_entry(int msg_id, bool local_request, int *error_code,
576                   struct SecurityStateReference **sec_state_ref);
577
578     /**
579      * Delete the entry with the given request id from the cache.
580      * This function is used in eventlist.cpp when a request
581      * has timed out.
582      *
583      * @param req_id - The request id.
584      */
585     void delete_entry(unsigned long req_id, bool local_request);
586
587     /**
588      * Delete the entry with the given request and message id from the cache.
589      *
590      * @param req_id - The request id.
591      * @param msg_id - The message id.
592      */
593     void delete_entry(unsigned long req_id, int msg_id,
594                       bool local_request);
595
596     /**
597      * Search the cache for a message id, return the whole entry and
598      * delete the entry from the cache.
599      *
600      * @param searchedID - Search for this message id
601      * @param res        - IN:  Pointer to an empy structure
602      *                     OUT: The filled structure
603      *
604      * @return - SNMPv3_MP_ERROR, SNMPv3_MP_OK
605      */
606     int get_entry(int searchedID, bool local_request,
607                   struct Cache::Entry_T *res);
608
609     void delete_content(struct Cache::Entry_T &ce);
610
611     void set_usm(USM *usm_to_use) { usm = usm_to_use; };
612
613    private:
614 #ifdef _THREADS
615     SNMP_PP_MUTABLE SnmpSynchronized lock;
616 #endif
617     struct Entry_T *table; ///< whole table
618     int max_entries;       ///< the maximum number of entries
619     int entries;           ///< the current amount of entries
620     USM *usm;
621   };
622
623
624   // =====================[ member variables ]==============================
625   EngineIdTable engine_id_table;
626   Cache cache;
627
628   // the engineID of this SNMP entity
629   unsigned char *own_engine_id;
630   int own_engine_id_len;
631   OctetStr own_engine_id_oct;
632
633   unsigned int cur_msg_id;   ///< msgID to use for next message
634   SNMP_PP_MUTABLE SnmpSynchronized cur_msg_id_lock;
635
636   USM *usm;  ///< the USM object used
637
638   // MIB Counters
639   unsigned int snmpUnknownSecurityModels;
640   unsigned int snmpInvalidMsgs;
641   unsigned int snmpUnknownPDUHandlers;
642 };
643
644 #ifdef SNMP_PP_NAMESPACE
645 } // end of namespace Snmp_pp
646 #endif 
647
648 #endif // _SNMPv3
649
650 #endif