net-snmp 3.27.0 → 3.28.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.
@@ -1,331 +0,0 @@
1
- const assert = require('assert');
2
- const snmp = require('../');
3
- const {
4
- SecurityLevel,
5
- AuthProtocols,
6
- PduType,
7
- ObjectType,
8
- } = snmp;
9
-
10
- // Access internal constants and classes for testing
11
- // These are not exported but are part of PR #289 implementation
12
- const UsmErrorType = {
13
- UNSUPPORTED_SECURITY_LEVEL: "1",
14
- NOT_IN_TIME_WINDOW: "2",
15
- UNKNOWN_USER_NAME: "3",
16
- UNKNOWN_ENGINE_ID: "4",
17
- WRONG_DIGESTS: "5",
18
- DECRYPTION_ERROR: "6"
19
- };
20
-
21
- describe('SNMPv3 Authentication Failure Handling (RFC 3414 §3.2)', function () {
22
-
23
- // Test constants
24
- const testEngineID = '8000B98380ABCDEF12345678';
25
- const testContext = 'testContext';
26
- const unknownUser = 'unknownUser';
27
- const knownUser = 'knownUser';
28
- const authPassword = 'testAuthPassword';
29
-
30
- // Create test engine configuration
31
- const testEngine = {
32
- engineID: testEngineID,
33
- engineBoots: 1,
34
- engineTime: 12345
35
- };
36
-
37
- // Create test receiver with known users for integration testing
38
- const createTestReceiver = () => {
39
- const receiver = snmp.createReceiver({
40
- port: 16200,
41
- disableAuthorization: false
42
- }, function(error, data) {
43
- // Simple callback for test receiver
44
- if (error) {
45
- console.log('Test receiver error:', error);
46
- }
47
- });
48
-
49
- // Add a user requiring authentication
50
- receiver.getAuthorizer().addUser({
51
- name: knownUser,
52
- level: SecurityLevel.authNoPriv,
53
- authProtocol: AuthProtocols.sha,
54
- authKey: authPassword
55
- });
56
-
57
- return receiver;
58
- };
59
-
60
- // Helper function to create test message buffers that would trigger authentication failures
61
- const createTestMessageBuffer = (userName, hasAuth = false, hasPriv = false, reportable = true) => {
62
- // Create a basic SNMP v3 message buffer structure
63
- // This is a simplified approach - in reality we'd need proper BER encoding
64
- const msgFlags = (reportable ? 4 : 0) | (hasPriv ? 2 : 0) | (hasAuth ? 1 : 0);
65
-
66
- // Return a mock message that would be created by Message.createFromBuffer
67
- return {
68
- version: 3,
69
- msgGlobalData: {
70
- msgID: 12345,
71
- msgMaxSize: 65507,
72
- msgFlags: msgFlags,
73
- msgSecurityModel: 3
74
- },
75
- msgSecurityParameters: {
76
- msgAuthoritativeEngineID: hasAuth ? testEngineID : '',
77
- msgAuthoritativeEngineBoots: hasAuth ? 1 : 0,
78
- msgAuthoritativeEngineTime: hasAuth ? 12345 : 0,
79
- msgUserName: userName,
80
- msgAuthenticationParameters: hasAuth ? Buffer.alloc(12) : '',
81
- msgPrivacyParameters: hasPriv ? Buffer.alloc(8) : ''
82
- },
83
- pdu: {
84
- type: PduType.GetRequest,
85
- id: 67890
86
- },
87
- hasAuthentication: () => hasAuth,
88
- hasPrivacy: () => hasPriv,
89
- hasAuthoritativeEngineID: () => hasAuth && testEngineID !== '',
90
- isReportable: () => reportable,
91
- // Add the createReportResponseMessage method that's part of PR #289
92
- createReportResponseMessage: function(engine, context, errorType) {
93
- const usmStatsBase = '1.3.6.1.6.3.15.1.1';
94
- const usmStats = {
95
- "1": "Unsupported Security Level",
96
- "2": "Not In Time Window",
97
- "3": "Unknown User Name",
98
- "4": "Unknown Engine ID",
99
- "5": "Wrong Digest (incorrect password, community or key)",
100
- "6": "Decryption Error"
101
- };
102
-
103
- const varbinds = [];
104
- if (errorType && usmStats[errorType]) {
105
- varbinds.push({
106
- oid: usmStatsBase + "." + errorType + ".0",
107
- type: ObjectType.Counter32,
108
- value: 1
109
- });
110
- }
111
-
112
- return {
113
- version: 3,
114
- msgGlobalData: {
115
- msgID: this.msgGlobalData.msgID,
116
- msgMaxSize: 65507,
117
- msgFlags: 0, // Report PDU is not reportable
118
- msgSecurityModel: 3
119
- },
120
- msgSecurityParameters: {
121
- msgAuthoritativeEngineID: engine.engineID,
122
- msgAuthoritativeEngineBoots: engine.engineBoots,
123
- msgAuthoritativeEngineTime: engine.engineTime,
124
- msgUserName: '',
125
- msgAuthenticationParameters: '',
126
- msgPrivacyParameters: ''
127
- },
128
- pdu: {
129
- type: PduType.Report,
130
- id: this.pdu.id,
131
- contextName: context,
132
- varbinds: varbinds
133
- },
134
- user: {
135
- name: '',
136
- level: SecurityLevel.noAuthNoPriv
137
- }
138
- };
139
- }
140
- };
141
- };
142
-
143
- describe('Report PDU Generation', function () {
144
-
145
- it('should create Report PDU with UNKNOWN_USER_NAME for unknown users', function () {
146
- const message = createTestMessageBuffer(unknownUser, false, false, true);
147
- const reportMessage = message.createReportResponseMessage(testEngine, testContext, UsmErrorType.UNKNOWN_USER_NAME);
148
-
149
- // Verify the report message structure
150
- assert.strictEqual(reportMessage.version, 3);
151
- assert.strictEqual(reportMessage.msgGlobalData.msgID, message.msgGlobalData.msgID);
152
- assert.strictEqual(reportMessage.pdu.type, PduType.Report);
153
- assert.strictEqual(reportMessage.pdu.contextName, testContext);
154
-
155
- // Verify USM statistics OID is correct
156
- assert.strictEqual(reportMessage.pdu.varbinds.length, 1);
157
- const varbind = reportMessage.pdu.varbinds[0];
158
- assert.strictEqual(varbind.oid, '1.3.6.1.6.3.15.1.1.3.0'); // usmStatsUnknownUserNames
159
- assert.strictEqual(varbind.type, ObjectType.Counter32);
160
- assert.strictEqual(varbind.value, 1);
161
- });
162
-
163
- it('should create Report PDU with WRONG_DIGESTS for authentication level mismatches', function () {
164
- const message = createTestMessageBuffer(knownUser, false, false, true);
165
- const reportMessage = message.createReportResponseMessage(testEngine, testContext, UsmErrorType.WRONG_DIGESTS);
166
-
167
- // Verify the report message structure
168
- assert.strictEqual(reportMessage.version, 3);
169
- assert.strictEqual(reportMessage.pdu.type, PduType.Report);
170
-
171
- // Verify USM statistics OID is correct
172
- const varbind = reportMessage.pdu.varbinds[0];
173
- assert.strictEqual(varbind.oid, '1.3.6.1.6.3.15.1.1.5.0'); // usmStatsWrongDigests
174
- assert.strictEqual(varbind.type, ObjectType.Counter32);
175
- assert.strictEqual(varbind.value, 1);
176
- });
177
-
178
- it('should create Report PDU with UNKNOWN_ENGINE_ID for discovery requests', function () {
179
- const message = createTestMessageBuffer('', false, false, true);
180
- const reportMessage = message.createReportResponseMessage(testEngine, testContext, UsmErrorType.UNKNOWN_ENGINE_ID);
181
-
182
- // Verify the report message structure
183
- assert.strictEqual(reportMessage.version, 3);
184
- assert.strictEqual(reportMessage.pdu.type, PduType.Report);
185
-
186
- // Verify USM statistics OID is correct
187
- const varbind = reportMessage.pdu.varbinds[0];
188
- assert.strictEqual(varbind.oid, '1.3.6.1.6.3.15.1.1.4.0'); // usmStatsUnknownEngineIDs
189
- assert.strictEqual(varbind.type, ObjectType.Counter32);
190
- assert.strictEqual(varbind.value, 1);
191
- });
192
-
193
- it('should preserve original message ID in Report PDU', function () {
194
- const originalMsgID = 98765;
195
- const message = createTestMessageBuffer(unknownUser, false, false, true);
196
- message.msgGlobalData.msgID = originalMsgID;
197
-
198
- const reportMessage = message.createReportResponseMessage(testEngine, testContext, UsmErrorType.UNKNOWN_USER_NAME);
199
-
200
- assert.strictEqual(reportMessage.msgGlobalData.msgID, originalMsgID);
201
- });
202
-
203
- it('should create Report PDU with correct security parameters', function () {
204
- const message = createTestMessageBuffer(unknownUser, false, false, true);
205
- const reportMessage = message.createReportResponseMessage(testEngine, testContext, UsmErrorType.UNKNOWN_USER_NAME);
206
-
207
- // Verify security parameters match engine configuration
208
- assert.strictEqual(reportMessage.msgSecurityParameters.msgAuthoritativeEngineID, testEngineID);
209
- assert.strictEqual(reportMessage.msgSecurityParameters.msgAuthoritativeEngineBoots, testEngine.engineBoots);
210
- assert.strictEqual(reportMessage.msgSecurityParameters.msgAuthoritativeEngineTime, testEngine.engineTime);
211
- assert.strictEqual(reportMessage.msgSecurityParameters.msgUserName, '');
212
- assert.strictEqual(reportMessage.msgSecurityParameters.msgAuthenticationParameters, '');
213
- assert.strictEqual(reportMessage.msgSecurityParameters.msgPrivacyParameters, '');
214
- });
215
-
216
- it('should handle missing error type gracefully', function () {
217
- const message = createTestMessageBuffer(unknownUser, false, false, true);
218
- const reportMessage = message.createReportResponseMessage(testEngine, testContext, null);
219
-
220
- // Should create report with empty varbinds when no error type
221
- assert.strictEqual(reportMessage.pdu.varbinds.length, 0);
222
- });
223
-
224
- it('should handle invalid error type gracefully', function () {
225
- const message = createTestMessageBuffer(unknownUser, false, false, true);
226
- const reportMessage = message.createReportResponseMessage(testEngine, testContext, 'invalid_error_type');
227
-
228
- // Should create report with empty varbinds when invalid error type
229
- assert.strictEqual(reportMessage.pdu.varbinds.length, 0);
230
- });
231
- });
232
-
233
- describe('Integration with Receiver/Agent', function () {
234
-
235
- it('should demonstrate Report PDU generation flow for unknown users', function () {
236
- // This test demonstrates the integration flow but doesn't test internal implementation
237
- // Since we cannot directly test Listener.processIncoming without proper message parsing
238
- const receiver = createTestReceiver();
239
-
240
- // Verify that receiver has the expected authorizer setup
241
- const authorizer = receiver.getAuthorizer();
242
- assert(authorizer);
243
- assert.strictEqual(authorizer.users.length, 1);
244
- assert.strictEqual(authorizer.users[0].name, knownUser);
245
-
246
- // Close receiver to clean up
247
- receiver.close();
248
- });
249
-
250
- it('should handle reportable flag correctly in message creation', function () {
251
- // Test the reportable flag handling which is part of the RFC 3414 compliance
252
- const message1 = createTestMessageBuffer(knownUser, true, false, true);
253
- assert.strictEqual(message1.isReportable(), true);
254
- assert.strictEqual((message1.msgGlobalData.msgFlags & 4), 4); // reportable bit set
255
-
256
- const message2 = createTestMessageBuffer(knownUser, true, false, false);
257
- assert.strictEqual(message2.isReportable(), false);
258
- assert.strictEqual((message2.msgGlobalData.msgFlags & 4), 0); // reportable bit clear
259
- });
260
- });
261
-
262
- describe('USM Error Type Constants', function () {
263
-
264
- it('should define all required USM error type constants', function () {
265
- assert.strictEqual(UsmErrorType.UNSUPPORTED_SECURITY_LEVEL, '1');
266
- assert.strictEqual(UsmErrorType.NOT_IN_TIME_WINDOW, '2');
267
- assert.strictEqual(UsmErrorType.UNKNOWN_USER_NAME, '3');
268
- assert.strictEqual(UsmErrorType.UNKNOWN_ENGINE_ID, '4');
269
- assert.strictEqual(UsmErrorType.WRONG_DIGESTS, '5');
270
- assert.strictEqual(UsmErrorType.DECRYPTION_ERROR, '6');
271
- });
272
-
273
- it('should map error type constants to correct USM statistics OIDs', function () {
274
- const usmStatsBase = '1.3.6.1.6.3.15.1.1';
275
-
276
- assert.strictEqual(`${usmStatsBase}.${UsmErrorType.UNSUPPORTED_SECURITY_LEVEL}.0`, '1.3.6.1.6.3.15.1.1.1.0');
277
- assert.strictEqual(`${usmStatsBase}.${UsmErrorType.NOT_IN_TIME_WINDOW}.0`, '1.3.6.1.6.3.15.1.1.2.0');
278
- assert.strictEqual(`${usmStatsBase}.${UsmErrorType.UNKNOWN_USER_NAME}.0`, '1.3.6.1.6.3.15.1.1.3.0');
279
- assert.strictEqual(`${usmStatsBase}.${UsmErrorType.UNKNOWN_ENGINE_ID}.0`, '1.3.6.1.6.3.15.1.1.4.0');
280
- assert.strictEqual(`${usmStatsBase}.${UsmErrorType.WRONG_DIGESTS}.0`, '1.3.6.1.6.3.15.1.1.5.0');
281
- assert.strictEqual(`${usmStatsBase}.${UsmErrorType.DECRYPTION_ERROR}.0`, '1.3.6.1.6.3.15.1.1.6.0');
282
- });
283
- });
284
-
285
- describe('Reportable Flag Handling', function () {
286
-
287
- it('should respect reportable flag in message creation', function () {
288
- // Test reportable message (typical for requests)
289
- const reportableMessage = createTestMessageBuffer(knownUser, true, false, true);
290
- assert.strictEqual(reportableMessage.isReportable(), true);
291
- assert.strictEqual((reportableMessage.msgGlobalData.msgFlags & 4), 4); // reportable bit set
292
-
293
- // Test non-reportable message (typical for responses)
294
- const nonReportableMessage = createTestMessageBuffer(knownUser, true, false, false);
295
- assert.strictEqual(nonReportableMessage.isReportable(), false);
296
- assert.strictEqual((nonReportableMessage.msgGlobalData.msgFlags & 4), 0); // reportable bit clear
297
- });
298
- });
299
-
300
- describe('Edge Cases and Error Handling', function () {
301
-
302
- it('should handle empty user name correctly', function () {
303
- const message = createTestMessageBuffer('', false, false, true);
304
- const reportMessage = message.createReportResponseMessage(testEngine, testContext, UsmErrorType.UNKNOWN_ENGINE_ID);
305
-
306
- assert.strictEqual(reportMessage.msgSecurityParameters.msgUserName, '');
307
- assert.strictEqual(reportMessage.user.name, '');
308
- assert.strictEqual(reportMessage.user.level, SecurityLevel.noAuthNoPriv);
309
- });
310
-
311
- it('should handle messages with authentication parameters correctly', function () {
312
- const message = createTestMessageBuffer(knownUser, true, false, true);
313
- message.msgSecurityParameters.msgAuthenticationParameters = Buffer.from('1234567890abcdef', 'hex');
314
-
315
- const reportMessage = message.createReportResponseMessage(testEngine, testContext, UsmErrorType.WRONG_DIGESTS);
316
-
317
- // Report should not include original auth parameters
318
- assert.strictEqual(reportMessage.msgSecurityParameters.msgAuthenticationParameters, '');
319
- });
320
-
321
- it('should handle messages with privacy parameters correctly', function () {
322
- const message = createTestMessageBuffer(knownUser, true, true, true);
323
- message.msgSecurityParameters.msgPrivacyParameters = Buffer.from('12345678', 'hex');
324
-
325
- const reportMessage = message.createReportResponseMessage(testEngine, testContext, UsmErrorType.DECRYPTION_ERROR);
326
-
327
- // Report should not include original privacy parameters
328
- assert.strictEqual(reportMessage.msgSecurityParameters.msgPrivacyParameters, '');
329
- });
330
- });
331
- });