license changed to LGPL for libnxcl, libnxsnmp, libnxlp, libnxsl, and libnxmap
[public/netxms.git] / src / snmp / libnxsnmp / security.cpp
1 /*
2 ** NetXMS - Network Management System
3 ** SNMP support library
4 ** Copyright (C) 2003-2010 Victor Kirhenshtein
5 **
6 ** This program is free software; you can redistribute it and/or modify
7 ** it under the terms of the GNU Lesser General Public License as published by
8 ** the Free Software Foundation; either version 3 of the License, or
9 ** (at your option) any later version.
10 **
11 ** This program is distributed in the hope that it will be useful,
12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ** GNU General Public License for more details.
15 **
16 ** You should have received a copy of the GNU Lesser General Public License
17 ** along with this program; if not, write to the Free Software
18 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 **
20 ** File: security.cpp
21 **
22 **/
23
24 #include "libnxsnmp.h"
25
26
27 //
28 // Constructors for SNMP_SecurityContext
29 //
30
31 SNMP_SecurityContext::SNMP_SecurityContext()
32 {
33 m_securityModel = 0;
34 m_authName = NULL;
35 m_authPassword = NULL;
36 m_privPassword = NULL;
37 m_authMethod = SNMP_AUTH_NONE;
38 m_privMethod = SNMP_ENCRYPT_NONE;
39 memset(m_authKeyMD5, 0, 16);
40 memset(m_authKeySHA1, 0, 20);
41 memset(m_privKey, 0, 20);
42 }
43
44 SNMP_SecurityContext::SNMP_SecurityContext(SNMP_SecurityContext *src)
45 {
46 m_securityModel = src->m_securityModel;
47 m_authName = (src->m_authName != NULL) ? strdup(src->m_authName) : NULL;
48 m_authPassword = (src->m_authPassword != NULL) ? strdup(src->m_authPassword) : NULL;
49 m_privPassword = (src->m_privPassword != NULL) ? strdup(src->m_privPassword) : NULL;
50 m_authMethod = src->m_authMethod;
51 m_privMethod = src->m_privMethod;
52 memcpy(m_authKeyMD5, src->m_authKeyMD5, 16);
53 memcpy(m_authKeySHA1, src->m_authKeySHA1, 20);
54 memcpy(m_privKey, src->m_privKey, 20);
55 m_authoritativeEngine = src->m_authoritativeEngine;
56 }
57
58 SNMP_SecurityContext::SNMP_SecurityContext(const char *community)
59 {
60 m_securityModel = SNMP_SECURITY_MODEL_V2C;
61 m_authName = strdup(CHECK_NULL_EX_A(community));
62 m_authPassword = NULL;
63 m_privPassword = NULL;
64 m_authMethod = SNMP_AUTH_NONE;
65 m_privMethod = SNMP_ENCRYPT_NONE;
66 memset(m_authKeyMD5, 0, 16);
67 memset(m_authKeySHA1, 0, 20);
68 memset(m_privKey, 0, 20);
69 }
70
71 SNMP_SecurityContext::SNMP_SecurityContext(const char *user, const char *authPassword, int authMethod)
72 {
73 m_securityModel = SNMP_SECURITY_MODEL_USM;
74 m_authName = strdup(CHECK_NULL_EX_A(user));
75 m_authPassword = strdup(CHECK_NULL_EX_A(authPassword));
76 m_privPassword = NULL;
77 m_authMethod = authMethod;
78 m_privMethod = SNMP_ENCRYPT_NONE;
79 recalculateKeys();
80 }
81
82 SNMP_SecurityContext::SNMP_SecurityContext(const char *user, const char *authPassword, const char *encryptionPassword,
83 int authMethod, int encryptionMethod)
84 {
85 m_securityModel = SNMP_SECURITY_MODEL_USM;
86 m_authName = strdup(CHECK_NULL_EX_A(user));
87 m_authPassword = strdup(CHECK_NULL_EX_A(authPassword));
88 m_privPassword = strdup(CHECK_NULL_EX_A(encryptionPassword));
89 m_authMethod = authMethod;
90 m_privMethod = encryptionMethod;
91 recalculateKeys();
92 }
93
94
95 //
96 // Destructor for security context
97 //
98
99 SNMP_SecurityContext::~SNMP_SecurityContext()
100 {
101 safe_free(m_authName);
102 safe_free(m_authPassword);
103 safe_free(m_privPassword);
104 }
105
106
107 //
108 // Set authentication name
109 //
110
111 void SNMP_SecurityContext::setAuthName(const char *name)
112 {
113 safe_free(m_authName);
114 m_authName = strdup(CHECK_NULL_EX_A(name));
115 }
116
117
118 //
119 // Set authentication password
120 //
121
122 void SNMP_SecurityContext::setAuthPassword(const char *password)
123 {
124 safe_free(m_authPassword);
125 m_authPassword = strdup(CHECK_NULL_EX_A(password));
126 recalculateKeys();
127 }
128
129
130 //
131 // Set encryption password
132 //
133
134 void SNMP_SecurityContext::setPrivPassword(const char *password)
135 {
136 safe_free(m_privPassword);
137 m_privPassword = strdup(CHECK_NULL_EX_A(password));
138 recalculateKeys();
139 }
140
141
142 //
143 // Set authoritative engine ID
144 //
145
146 void SNMP_SecurityContext::setAuthoritativeEngine(SNMP_Engine &engine)
147 {
148 m_authoritativeEngine = engine;
149 recalculateKeys();
150 }
151
152
153 //
154 // Recalculate keys
155 //
156
157 void SNMP_SecurityContext::recalculateKeys()
158 {
159 BYTE buffer[256];
160 const char *authPassword = (m_authPassword != NULL) ? m_authPassword : "";
161 const char *privPassword = (m_privPassword != NULL) ? m_privPassword : "";
162
163 // MD5 auth key
164 MD5HashForPattern((const BYTE *)authPassword, strlen(authPassword), 1048576, buffer);
165 memcpy(&buffer[16], m_authoritativeEngine.getId(), m_authoritativeEngine.getIdLen());
166 memcpy(&buffer[16 + m_authoritativeEngine.getIdLen()], buffer, 16);
167 CalculateMD5Hash(buffer, m_authoritativeEngine.getIdLen() + 32, m_authKeyMD5);
168
169 // SHA1 auth key
170 SHA1HashForPattern((BYTE *)authPassword, strlen(authPassword), 1048576, buffer);
171 memcpy(&buffer[20], m_authoritativeEngine.getId(), m_authoritativeEngine.getIdLen());
172 memcpy(&buffer[20 + m_authoritativeEngine.getIdLen()], buffer, 20);
173 CalculateSHA1Hash(buffer, m_authoritativeEngine.getIdLen() + 40, m_authKeySHA1);
174
175 // Priv key
176 if (m_authMethod == SNMP_AUTH_MD5)
177 {
178 MD5HashForPattern((const BYTE *)privPassword, strlen(privPassword), 1048576, buffer);
179 memcpy(&buffer[16], m_authoritativeEngine.getId(), m_authoritativeEngine.getIdLen());
180 memcpy(&buffer[16 + m_authoritativeEngine.getIdLen()], buffer, 16);
181 CalculateMD5Hash(buffer, m_authoritativeEngine.getIdLen() + 32, m_privKey);
182 }
183 else
184 {
185 SHA1HashForPattern((BYTE *)privPassword, strlen(privPassword), 1048576, buffer);
186 memcpy(&buffer[20], m_authoritativeEngine.getId(), m_authoritativeEngine.getIdLen());
187 memcpy(&buffer[20 + m_authoritativeEngine.getIdLen()], buffer, 20);
188 CalculateSHA1Hash(buffer, m_authoritativeEngine.getIdLen() + 40, m_privKey);
189 }
190 }