net-snmp 3.21.1 → 3.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -0
- package/index.js +11 -11
- package/package.json +14 -14
- package/test/crypto.test.js +384 -0
package/README.md
CHANGED
@@ -2493,6 +2493,27 @@ pre-loaded "base" modules is:
|
|
2493
2493
|
* SNMPv2-TC
|
2494
2494
|
* SNMPv2-MIB
|
2495
2495
|
|
2496
|
+
By default, the `createModuleStore()` function creates a new `ModuleStore` instance with all the base modules pre-loaded.
|
2497
|
+
However, you can now customize which base modules are loaded by passing an options object:
|
2498
|
+
|
2499
|
+
```js
|
2500
|
+
// Example of selecting only SNMPv2 MIBs
|
2501
|
+
const store = snmp.createModuleStore({
|
2502
|
+
baseModules: [
|
2503
|
+
'SNMPv2-SMI',
|
2504
|
+
'SNMPv2-CONF',
|
2505
|
+
'SNMPv2-TC',
|
2506
|
+
'SNMPv2-MIB',
|
2507
|
+
],
|
2508
|
+
});
|
2509
|
+
```
|
2510
|
+
|
2511
|
+
The `options` object can contain:
|
2512
|
+
|
2513
|
+
* `baseModules` - An array of module names to use as the base modules. This allows you to explicitly control which MIBs are loaded, which can be useful to avoid unexpected type overrides that might occur with the full set of base modules.
|
2514
|
+
|
2515
|
+
This feature is helpful when dealing with constraints for SNMPv2-TC defined textual conventions like DisplayString that might get preempted by subsequent definitions as plain OCTET STRING in RFC MIBs.
|
2516
|
+
|
2496
2517
|
## store.loadFromFile (fileName)
|
2497
2518
|
|
2498
2519
|
Loads all MIB modules in the given file into the module store. By convention, there is
|
@@ -3525,6 +3546,16 @@ Example programs are included under the module's `example` directory.
|
|
3525
3546
|
|
3526
3547
|
* Add better defval type handling, improved debug handling and simple agent example
|
3527
3548
|
|
3549
|
+
# Version 3.21.2 - 27/04/2025
|
3550
|
+
|
3551
|
+
* Add custom base module list
|
3552
|
+
|
3553
|
+
# Version 3.22.0 - 27/04/2025
|
3554
|
+
|
3555
|
+
* Fix incorrect SNMPv3 engineID handling
|
3556
|
+
|
3557
|
+
* Add custom base module list
|
3558
|
+
|
3528
3559
|
# License
|
3529
3560
|
|
3530
3561
|
Copyright (c) 2020 Mark Abrahams <mark@abrahams.co.nz>
|
package/index.js
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
// Copyright 2013 Stephen Vickers <stephen.vickers.sv@gmail.com>
|
3
2
|
|
4
3
|
const ber = require ("asn1-ber").Ber;
|
@@ -2038,7 +2037,7 @@ var Session = function (target, authenticator, options) {
|
|
2038
2037
|
DEBUG |= options.debug;
|
2039
2038
|
|
2040
2039
|
this.engine = new Engine ({
|
2041
|
-
|
2040
|
+
engineID: options.engineID
|
2042
2041
|
});
|
2043
2042
|
this.reqs = {};
|
2044
2043
|
this.reqCount = 0;
|
@@ -3009,7 +3008,7 @@ Session.createV3 = function (target, user, options) {
|
|
3009
3008
|
};
|
3010
3009
|
|
3011
3010
|
var Engine = function (engineOptions) {
|
3012
|
-
|
3011
|
+
let { engineID } = engineOptions;
|
3013
3012
|
if ( engineID ) {
|
3014
3013
|
if ( ! (engineID instanceof Buffer) ) {
|
3015
3014
|
engineID = engineID.replace('0x', '');
|
@@ -3355,7 +3354,7 @@ var Receiver = function (options, callback) {
|
|
3355
3354
|
DEBUG |= options.debug;
|
3356
3355
|
this.authorizer = new Authorizer (options);
|
3357
3356
|
this.engine = new Engine ({
|
3358
|
-
|
3357
|
+
engineID: options.engineID
|
3359
3358
|
});
|
3360
3359
|
|
3361
3360
|
this.engineBoots = 0;
|
@@ -3455,7 +3454,8 @@ Receiver.create = function (options, callback) {
|
|
3455
3454
|
return receiver;
|
3456
3455
|
};
|
3457
3456
|
|
3458
|
-
var ModuleStore = function () {
|
3457
|
+
var ModuleStore = function (baseModules) {
|
3458
|
+
this.baseModules = baseModules ?? ModuleStore.BASE_MODULES;
|
3459
3459
|
this.parser = mibparser ();
|
3460
3460
|
this.translations = {
|
3461
3461
|
oidToPath: {},
|
@@ -3545,7 +3545,7 @@ ModuleStore.prototype.getModule = function (moduleName) {
|
|
3545
3545
|
ModuleStore.prototype.getModules = function (includeBase) {
|
3546
3546
|
var modules = {};
|
3547
3547
|
for ( var moduleName of Object.keys(this.parser.Modules) ) {
|
3548
|
-
if ( includeBase ||
|
3548
|
+
if ( includeBase || this.baseModules.indexOf (moduleName) == -1 ) {
|
3549
3549
|
modules[moduleName] = this.parser.Modules[moduleName];
|
3550
3550
|
}
|
3551
3551
|
}
|
@@ -3555,7 +3555,7 @@ ModuleStore.prototype.getModules = function (includeBase) {
|
|
3555
3555
|
ModuleStore.prototype.getModuleNames = function (includeBase) {
|
3556
3556
|
var modules = [];
|
3557
3557
|
for ( var moduleName of Object.keys(this.parser.Modules) ) {
|
3558
|
-
if ( includeBase ||
|
3558
|
+
if ( includeBase || this.baseModules.indexOf (moduleName) == -1 ) {
|
3559
3559
|
modules.push (moduleName);
|
3560
3560
|
}
|
3561
3561
|
}
|
@@ -3729,7 +3729,7 @@ ModuleStore.prototype.getProvidersForModule = function (moduleName) {
|
|
3729
3729
|
};
|
3730
3730
|
|
3731
3731
|
ModuleStore.prototype.loadBaseModules = function () {
|
3732
|
-
for ( var mibModule of
|
3732
|
+
for ( var mibModule of this.baseModules ) {
|
3733
3733
|
this.parser.Import (__dirname + "/lib/mibs/" + mibModule + ".mib");
|
3734
3734
|
}
|
3735
3735
|
this.parser.Serialize ();
|
@@ -3813,8 +3813,8 @@ ModuleStore.prototype.translate = function (name, destinationFormat) {
|
|
3813
3813
|
}
|
3814
3814
|
};
|
3815
3815
|
|
3816
|
-
ModuleStore.create = function () {
|
3817
|
-
|
3816
|
+
ModuleStore.create = function (options) {
|
3817
|
+
const store = new ModuleStore (options?.baseModules ?? ModuleStore.BASE_MODULES);
|
3818
3818
|
store.loadBaseModules ();
|
3819
3819
|
return store;
|
3820
3820
|
};
|
@@ -4873,7 +4873,7 @@ var Agent = function (options, callback, mib) {
|
|
4873
4873
|
DEBUG |= options.debug;
|
4874
4874
|
this.listener = new Listener (options, this);
|
4875
4875
|
this.engine = new Engine ({
|
4876
|
-
|
4876
|
+
engineID: options.engineID
|
4877
4877
|
});
|
4878
4878
|
this.authorizer = new Authorizer (options);
|
4879
4879
|
this.callback = callback || function () {};
|
package/package.json
CHANGED
@@ -1,19 +1,16 @@
|
|
1
1
|
{
|
2
2
|
"name": "net-snmp",
|
3
|
-
"version": "3.
|
3
|
+
"version": "3.22.0",
|
4
4
|
"description": "JavaScript implementation of the Simple Network Management Protocol (SNMP)",
|
5
|
+
"author": "Mark Abrahams <mark@abrahams.co.nz>",
|
6
|
+
"license": "MIT",
|
5
7
|
"main": "index.js",
|
6
8
|
"directories": {
|
7
9
|
"example": "example"
|
8
10
|
},
|
9
|
-
"
|
10
|
-
"
|
11
|
-
"
|
12
|
-
},
|
13
|
-
"devDependencies": {
|
14
|
-
"eslint": "^9.9.1",
|
15
|
-
"getopts": "^2.3.0",
|
16
|
-
"mocha": "^11.0.1"
|
11
|
+
"scripts": {
|
12
|
+
"lint": "eslint . ./**/*.js",
|
13
|
+
"test": "node --openssl-legacy-provider ./node_modules/mocha/bin/mocha.js"
|
17
14
|
},
|
18
15
|
"contributors": [
|
19
16
|
{
|
@@ -45,10 +42,13 @@
|
|
45
42
|
"monitor",
|
46
43
|
"monitoring"
|
47
44
|
],
|
48
|
-
"
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
45
|
+
"dependencies": {
|
46
|
+
"asn1-ber": "^1.2.1",
|
47
|
+
"smart-buffer": "^4.1.0"
|
48
|
+
},
|
49
|
+
"devDependencies": {
|
50
|
+
"eslint": "^9.9.1",
|
51
|
+
"getopts": "^2.3.0",
|
52
|
+
"mocha": "^11.0.1"
|
53
53
|
}
|
54
54
|
}
|
@@ -0,0 +1,384 @@
|
|
1
|
+
const assert = require('assert');
|
2
|
+
// crypto is used indirectly by Authentication and Encryption modules
|
3
|
+
const snmp = require('../');
|
4
|
+
const { SecurityLevel, AuthProtocols, PrivProtocols, Authentication, Encryption } = snmp;
|
5
|
+
|
6
|
+
describe('SNMPv3 Authentication and Encryption', function () {
|
7
|
+
// Sample data for tests
|
8
|
+
const authPassword = 'test_auth_password';
|
9
|
+
const privPassword = 'test_priv_password';
|
10
|
+
const engineID = Buffer.from('8000B98380ABCDEF', 'hex');
|
11
|
+
|
12
|
+
// Test data that will be encrypted/authenticated
|
13
|
+
const testData = Buffer.from('Test data for SNMP authentication and privacy tests', 'utf8');
|
14
|
+
|
15
|
+
describe('Authentication', function () {
|
16
|
+
it('should support noAuthNoPriv security level', function () {
|
17
|
+
// noAuthNoPriv doesn't use authentication, verify this is handled appropriately
|
18
|
+
const user = {
|
19
|
+
name: 'noAuthUser',
|
20
|
+
level: SecurityLevel.noAuthNoPriv,
|
21
|
+
};
|
22
|
+
|
23
|
+
// No authentication should be required for this user
|
24
|
+
assert.strictEqual(user.level, SecurityLevel.noAuthNoPriv);
|
25
|
+
assert.strictEqual(user.authProtocol, undefined);
|
26
|
+
assert.strictEqual(user.authKey, undefined);
|
27
|
+
});
|
28
|
+
|
29
|
+
it('should support MD5 authentication protocol', function () {
|
30
|
+
// Generate authentication key using MD5
|
31
|
+
const authKey = Authentication.passwordToKey(AuthProtocols.md5, authPassword, engineID);
|
32
|
+
|
33
|
+
// Verify key length matches expected MD5 output length
|
34
|
+
assert.strictEqual(authKey.length, Authentication.algorithms[AuthProtocols.md5].KEY_LENGTH);
|
35
|
+
|
36
|
+
// Create a test digest
|
37
|
+
const digest = Authentication.calculateDigest(testData, AuthProtocols.md5, authPassword, engineID);
|
38
|
+
|
39
|
+
// Verify digest length
|
40
|
+
assert.strictEqual(digest.length, Authentication.algorithms[AuthProtocols.md5].AUTHENTICATION_CODE_LENGTH);
|
41
|
+
|
42
|
+
// Verify authentication works
|
43
|
+
const testBuffer = Buffer.concat([testData]);
|
44
|
+
const digestInMessage = Buffer.alloc(
|
45
|
+
Authentication.algorithms[AuthProtocols.md5].AUTHENTICATION_CODE_LENGTH
|
46
|
+
);
|
47
|
+
Authentication.writeParameters(testBuffer, AuthProtocols.md5, authPassword, engineID, digestInMessage);
|
48
|
+
|
49
|
+
assert.strictEqual(
|
50
|
+
Authentication.isAuthentic(testBuffer, AuthProtocols.md5, authPassword, engineID, digestInMessage),
|
51
|
+
true
|
52
|
+
);
|
53
|
+
});
|
54
|
+
|
55
|
+
it('should support SHA authentication protocol', function () {
|
56
|
+
// Generate authentication key using SHA
|
57
|
+
const authKey = Authentication.passwordToKey(AuthProtocols.sha, authPassword, engineID);
|
58
|
+
|
59
|
+
// Verify key length matches expected SHA output length
|
60
|
+
assert.strictEqual(authKey.length, Authentication.algorithms[AuthProtocols.sha].KEY_LENGTH);
|
61
|
+
|
62
|
+
// Create a test digest
|
63
|
+
const digest = Authentication.calculateDigest(testData, AuthProtocols.sha, authPassword, engineID);
|
64
|
+
|
65
|
+
// Verify digest length
|
66
|
+
assert.strictEqual(digest.length, Authentication.algorithms[AuthProtocols.sha].AUTHENTICATION_CODE_LENGTH);
|
67
|
+
|
68
|
+
// Verify authentication works
|
69
|
+
const testBuffer = Buffer.concat([testData]);
|
70
|
+
const digestInMessage = Buffer.alloc(
|
71
|
+
Authentication.algorithms[AuthProtocols.sha].AUTHENTICATION_CODE_LENGTH
|
72
|
+
);
|
73
|
+
Authentication.writeParameters(testBuffer, AuthProtocols.sha, authPassword, engineID, digestInMessage);
|
74
|
+
|
75
|
+
assert.strictEqual(
|
76
|
+
Authentication.isAuthentic(testBuffer, AuthProtocols.sha, authPassword, engineID, digestInMessage),
|
77
|
+
true
|
78
|
+
);
|
79
|
+
});
|
80
|
+
|
81
|
+
it('should support SHA-256 authentication protocol', function () {
|
82
|
+
// Generate authentication key using SHA-256
|
83
|
+
const authKey = Authentication.passwordToKey(AuthProtocols.sha256, authPassword, engineID);
|
84
|
+
|
85
|
+
// Verify key length matches expected SHA-256 output length
|
86
|
+
assert.strictEqual(authKey.length, Authentication.algorithms[AuthProtocols.sha256].KEY_LENGTH);
|
87
|
+
|
88
|
+
// Create a test digest
|
89
|
+
const digest = Authentication.calculateDigest(testData, AuthProtocols.sha256, authPassword, engineID);
|
90
|
+
|
91
|
+
// Verify digest length
|
92
|
+
assert.strictEqual(
|
93
|
+
digest.length,
|
94
|
+
Authentication.algorithms[AuthProtocols.sha256].AUTHENTICATION_CODE_LENGTH
|
95
|
+
);
|
96
|
+
|
97
|
+
// Verify authentication works
|
98
|
+
const testBuffer = Buffer.concat([testData]);
|
99
|
+
const digestInMessage = Buffer.alloc(
|
100
|
+
Authentication.algorithms[AuthProtocols.sha256].AUTHENTICATION_CODE_LENGTH
|
101
|
+
);
|
102
|
+
Authentication.writeParameters(testBuffer, AuthProtocols.sha256, authPassword, engineID, digestInMessage);
|
103
|
+
|
104
|
+
assert.strictEqual(
|
105
|
+
Authentication.isAuthentic(testBuffer, AuthProtocols.sha256, authPassword, engineID, digestInMessage),
|
106
|
+
true
|
107
|
+
);
|
108
|
+
});
|
109
|
+
|
110
|
+
it('should support SHA-512 authentication protocol', function () {
|
111
|
+
// Generate authentication key using SHA-512
|
112
|
+
const authKey = Authentication.passwordToKey(AuthProtocols.sha512, authPassword, engineID);
|
113
|
+
|
114
|
+
// Verify key length matches expected SHA-512 output length
|
115
|
+
assert.strictEqual(authKey.length, Authentication.algorithms[AuthProtocols.sha512].KEY_LENGTH);
|
116
|
+
|
117
|
+
// Create a test digest
|
118
|
+
const digest = Authentication.calculateDigest(testData, AuthProtocols.sha512, authPassword, engineID);
|
119
|
+
|
120
|
+
// Verify digest length
|
121
|
+
assert.strictEqual(
|
122
|
+
digest.length,
|
123
|
+
Authentication.algorithms[AuthProtocols.sha512].AUTHENTICATION_CODE_LENGTH
|
124
|
+
);
|
125
|
+
|
126
|
+
// Verify authentication works
|
127
|
+
const testBuffer = Buffer.concat([testData]);
|
128
|
+
const digestInMessage = Buffer.alloc(
|
129
|
+
Authentication.algorithms[AuthProtocols.sha512].AUTHENTICATION_CODE_LENGTH
|
130
|
+
);
|
131
|
+
Authentication.writeParameters(testBuffer, AuthProtocols.sha512, authPassword, engineID, digestInMessage);
|
132
|
+
|
133
|
+
assert.strictEqual(
|
134
|
+
Authentication.isAuthentic(testBuffer, AuthProtocols.sha512, authPassword, engineID, digestInMessage),
|
135
|
+
true
|
136
|
+
);
|
137
|
+
});
|
138
|
+
});
|
139
|
+
|
140
|
+
describe('Encryption', function () {
|
141
|
+
// Create a mock engine for encryption tests
|
142
|
+
const engine = {
|
143
|
+
engineID: engineID,
|
144
|
+
engineBoots: 1,
|
145
|
+
engineTime: 123,
|
146
|
+
};
|
147
|
+
|
148
|
+
it('should support DES encryption protocol', function () {
|
149
|
+
// Test DES encryption/decryption with SHA authentication
|
150
|
+
const authProtocol = AuthProtocols.sha;
|
151
|
+
const privProtocol = PrivProtocols.des;
|
152
|
+
|
153
|
+
// Encrypt the test data
|
154
|
+
const { encryptedPdu, msgPrivacyParameters } = Encryption.encryptPdu(
|
155
|
+
privProtocol,
|
156
|
+
testData,
|
157
|
+
privPassword,
|
158
|
+
authProtocol,
|
159
|
+
engine
|
160
|
+
);
|
161
|
+
|
162
|
+
// Verify encryption was done (output should be different from input)
|
163
|
+
assert.notDeepStrictEqual(encryptedPdu, testData);
|
164
|
+
|
165
|
+
// Decrypt the data
|
166
|
+
const decryptedPdu = Encryption.decryptPdu(
|
167
|
+
privProtocol,
|
168
|
+
encryptedPdu,
|
169
|
+
msgPrivacyParameters,
|
170
|
+
privPassword,
|
171
|
+
authProtocol,
|
172
|
+
engine
|
173
|
+
);
|
174
|
+
|
175
|
+
// Verify decryption works
|
176
|
+
assert.deepStrictEqual(decryptedPdu.slice(0, testData.length), testData);
|
177
|
+
});
|
178
|
+
|
179
|
+
it('should support AES encryption protocol', function () {
|
180
|
+
// Test AES encryption/decryption with SHA authentication
|
181
|
+
const authProtocol = AuthProtocols.sha;
|
182
|
+
const privProtocol = PrivProtocols.aes;
|
183
|
+
|
184
|
+
// Encrypt the test data
|
185
|
+
const { encryptedPdu, msgPrivacyParameters } = Encryption.encryptPdu(
|
186
|
+
privProtocol,
|
187
|
+
testData,
|
188
|
+
privPassword,
|
189
|
+
authProtocol,
|
190
|
+
engine
|
191
|
+
);
|
192
|
+
|
193
|
+
// Verify encryption was done (output should be different from input)
|
194
|
+
assert.notDeepStrictEqual(encryptedPdu, testData);
|
195
|
+
|
196
|
+
// Decrypt the data
|
197
|
+
const decryptedPdu = Encryption.decryptPdu(
|
198
|
+
privProtocol,
|
199
|
+
encryptedPdu,
|
200
|
+
msgPrivacyParameters,
|
201
|
+
privPassword,
|
202
|
+
authProtocol,
|
203
|
+
engine
|
204
|
+
);
|
205
|
+
|
206
|
+
// Verify decryption works
|
207
|
+
assert.deepStrictEqual(decryptedPdu.slice(0, testData.length), testData);
|
208
|
+
});
|
209
|
+
|
210
|
+
it('should support AES-256b (Blumenthal) encryption protocol', function () {
|
211
|
+
// Test AES-256 Blumenthal encryption/decryption with SHA authentication
|
212
|
+
const authProtocol = AuthProtocols.sha;
|
213
|
+
const privProtocol = PrivProtocols.aes256b;
|
214
|
+
|
215
|
+
// Encrypt the test data
|
216
|
+
const { encryptedPdu, msgPrivacyParameters } = Encryption.encryptPdu(
|
217
|
+
privProtocol,
|
218
|
+
testData,
|
219
|
+
privPassword,
|
220
|
+
authProtocol,
|
221
|
+
engine
|
222
|
+
);
|
223
|
+
|
224
|
+
// Verify encryption was done (output should be different from input)
|
225
|
+
assert.notDeepStrictEqual(encryptedPdu, testData);
|
226
|
+
|
227
|
+
// Decrypt the data
|
228
|
+
const decryptedPdu = Encryption.decryptPdu(
|
229
|
+
privProtocol,
|
230
|
+
encryptedPdu,
|
231
|
+
msgPrivacyParameters,
|
232
|
+
privPassword,
|
233
|
+
authProtocol,
|
234
|
+
engine
|
235
|
+
);
|
236
|
+
|
237
|
+
// Verify decryption works
|
238
|
+
assert.deepStrictEqual(decryptedPdu.slice(0, testData.length), testData);
|
239
|
+
});
|
240
|
+
|
241
|
+
it('should support AES-256r (Reeder) encryption protocol', function () {
|
242
|
+
// Test AES-256 Reeder encryption/decryption with SHA authentication
|
243
|
+
const authProtocol = AuthProtocols.sha;
|
244
|
+
const privProtocol = PrivProtocols.aes256r;
|
245
|
+
|
246
|
+
// Encrypt the test data
|
247
|
+
const { encryptedPdu, msgPrivacyParameters } = Encryption.encryptPdu(
|
248
|
+
privProtocol,
|
249
|
+
testData,
|
250
|
+
privPassword,
|
251
|
+
authProtocol,
|
252
|
+
engine
|
253
|
+
);
|
254
|
+
|
255
|
+
// Verify encryption was done (output should be different from input)
|
256
|
+
assert.notDeepStrictEqual(encryptedPdu, testData);
|
257
|
+
|
258
|
+
// Decrypt the data
|
259
|
+
const decryptedPdu = Encryption.decryptPdu(
|
260
|
+
privProtocol,
|
261
|
+
encryptedPdu,
|
262
|
+
msgPrivacyParameters,
|
263
|
+
privPassword,
|
264
|
+
authProtocol,
|
265
|
+
engine
|
266
|
+
);
|
267
|
+
|
268
|
+
// Verify decryption works
|
269
|
+
assert.deepStrictEqual(decryptedPdu.slice(0, testData.length), testData);
|
270
|
+
});
|
271
|
+
});
|
272
|
+
|
273
|
+
describe('SecurityLevel combinations', function () {
|
274
|
+
it('should support authNoPriv security level', function () {
|
275
|
+
// Create a user with authentication but no privacy
|
276
|
+
const user = {
|
277
|
+
name: 'authNoPrivUser',
|
278
|
+
level: SecurityLevel.authNoPriv,
|
279
|
+
authProtocol: AuthProtocols.sha,
|
280
|
+
authKey: 'authPassword',
|
281
|
+
};
|
282
|
+
|
283
|
+
assert.strictEqual(user.level, SecurityLevel.authNoPriv);
|
284
|
+
assert.strictEqual(user.authProtocol, AuthProtocols.sha);
|
285
|
+
assert.strictEqual(user.authKey, 'authPassword');
|
286
|
+
assert.strictEqual(user.privProtocol, undefined);
|
287
|
+
assert.strictEqual(user.privKey, undefined);
|
288
|
+
});
|
289
|
+
|
290
|
+
it('should support authPriv security level', function () {
|
291
|
+
// Create a user with authentication and privacy
|
292
|
+
const user = {
|
293
|
+
name: 'authPrivUser',
|
294
|
+
level: SecurityLevel.authPriv,
|
295
|
+
authProtocol: AuthProtocols.sha256,
|
296
|
+
authKey: 'authPassword',
|
297
|
+
privProtocol: PrivProtocols.aes,
|
298
|
+
privKey: 'privPassword',
|
299
|
+
};
|
300
|
+
|
301
|
+
assert.strictEqual(user.level, SecurityLevel.authPriv);
|
302
|
+
assert.strictEqual(user.authProtocol, AuthProtocols.sha256);
|
303
|
+
assert.strictEqual(user.authKey, 'authPassword');
|
304
|
+
assert.strictEqual(user.privProtocol, PrivProtocols.aes);
|
305
|
+
assert.strictEqual(user.privKey, 'privPassword');
|
306
|
+
});
|
307
|
+
|
308
|
+
it('should validate all required parameters are provided for each security level', function () {
|
309
|
+
// noAuthNoPriv only requires username and level
|
310
|
+
const user1 = {
|
311
|
+
name: 'user1',
|
312
|
+
level: SecurityLevel.noAuthNoPriv,
|
313
|
+
};
|
314
|
+
|
315
|
+
// authNoPriv requires authentication parameters
|
316
|
+
const user2 = {
|
317
|
+
name: 'user2',
|
318
|
+
level: SecurityLevel.authNoPriv,
|
319
|
+
authProtocol: AuthProtocols.sha,
|
320
|
+
authKey: 'authPassword',
|
321
|
+
};
|
322
|
+
|
323
|
+
// authPriv requires both authentication and privacy parameters
|
324
|
+
const user3 = {
|
325
|
+
name: 'user3',
|
326
|
+
level: SecurityLevel.authPriv,
|
327
|
+
authProtocol: AuthProtocols.sha,
|
328
|
+
authKey: 'authPassword',
|
329
|
+
privProtocol: PrivProtocols.aes,
|
330
|
+
privKey: 'privPassword',
|
331
|
+
};
|
332
|
+
|
333
|
+
// This function would typically be part of parameter validation
|
334
|
+
function validateUser(user) {
|
335
|
+
if (user.level === SecurityLevel.authNoPriv || user.level === SecurityLevel.authPriv) {
|
336
|
+
assert.ok(user.authProtocol, 'authProtocol required for this security level');
|
337
|
+
assert.ok(user.authKey, 'authKey required for this security level');
|
338
|
+
}
|
339
|
+
|
340
|
+
if (user.level === SecurityLevel.authPriv) {
|
341
|
+
assert.ok(user.privProtocol, 'privProtocol required for this security level');
|
342
|
+
assert.ok(user.privKey, 'privKey required for this security level');
|
343
|
+
}
|
344
|
+
|
345
|
+
return true;
|
346
|
+
}
|
347
|
+
|
348
|
+
assert.strictEqual(validateUser(user1), true);
|
349
|
+
assert.strictEqual(validateUser(user2), true);
|
350
|
+
assert.strictEqual(validateUser(user3), true);
|
351
|
+
});
|
352
|
+
});
|
353
|
+
|
354
|
+
describe('Custom engineID handling', function () {
|
355
|
+
it('should correctly use engineID parameter', function () {
|
356
|
+
// This test verifies the fix for issue #283
|
357
|
+
// Create a session with default settings (no engineID)
|
358
|
+
const defaultSession = new snmp.Session({
|
359
|
+
host: 'example.org',
|
360
|
+
version: snmp.Version3
|
361
|
+
});
|
362
|
+
|
363
|
+
// Default session should have an engineID of expected format (17 bytes)
|
364
|
+
assert.strictEqual(defaultSession.engine.engineID.length, 17);
|
365
|
+
|
366
|
+
// Convert to hex string for easier inspection
|
367
|
+
const defaultEngineIDHex = defaultSession.engine.engineID.toString('hex');
|
368
|
+
// First 5 bytes should match the standard format 8000B98380
|
369
|
+
assert.strictEqual(defaultEngineIDHex.substring(0, 10), '8000b98380');
|
370
|
+
|
371
|
+
// Create a second session - should generate a different random engineID
|
372
|
+
const anotherDefaultSession = new snmp.Session({
|
373
|
+
host: 'example.org',
|
374
|
+
version: snmp.Version3
|
375
|
+
});
|
376
|
+
|
377
|
+
// The two sessions should have different engineIDs (random part differs)
|
378
|
+
assert.notStrictEqual(
|
379
|
+
defaultSession.engine.engineID.toString('hex'),
|
380
|
+
anotherDefaultSession.engine.engineID.toString('hex')
|
381
|
+
);
|
382
|
+
});
|
383
|
+
});
|
384
|
+
});
|