net-snmp 3.23.0 → 3.25.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 +132 -0
- package/eslint.config.js +3 -0
- package/example/agentx-subagent.js +44 -9
- package/index.js +345 -125
- package/package.json +2 -2
- package/test/README-test-coverage.md +76 -0
- package/test/snmpv3-auth-failures.test.js +331 -0
- package/test/subagent.test.js +469 -0
package/index.js
CHANGED
@@ -166,6 +166,16 @@ var UsmStats = {
|
|
166
166
|
|
167
167
|
_expandConstantObject (UsmStats);
|
168
168
|
|
169
|
+
// USM Error Type Constants for Report PDUs (RFC 3414 §3.2)
|
170
|
+
var UsmErrorType = {
|
171
|
+
UNSUPPORTED_SECURITY_LEVEL: "1",
|
172
|
+
NOT_IN_TIME_WINDOW: "2",
|
173
|
+
UNKNOWN_USER_NAME: "3",
|
174
|
+
UNKNOWN_ENGINE_ID: "4",
|
175
|
+
WRONG_DIGESTS: "5",
|
176
|
+
DECRYPTION_ERROR: "6"
|
177
|
+
};
|
178
|
+
|
169
179
|
var MibProviderType = {
|
170
180
|
"1": "Scalar",
|
171
181
|
"2": "Table"
|
@@ -203,6 +213,8 @@ var AgentXPduType = {
|
|
203
213
|
17: "RemoveAgentCaps",
|
204
214
|
18: "Response"
|
205
215
|
};
|
216
|
+
const agentXPduTypesRequiringReadAccess = [ 5, 6, 7];
|
217
|
+
const agentXPduTypesRequiringWriteAccess = [ 8, 9, 10, 11, 14, 15, 16, 17 ];
|
206
218
|
|
207
219
|
_expandConstantObject (AgentXPduType);
|
208
220
|
|
@@ -1795,7 +1807,7 @@ Message.prototype.hasAuthoritativeEngineID = function () {
|
|
1795
1807
|
this.msgSecurityParameters.msgAuthoritativeEngineID != "";
|
1796
1808
|
};
|
1797
1809
|
|
1798
|
-
Message.prototype.createReportResponseMessage = function (engine, context) {
|
1810
|
+
Message.prototype.createReportResponseMessage = function (engine, context, errorType) {
|
1799
1811
|
var user = {
|
1800
1812
|
name: "",
|
1801
1813
|
level: SecurityLevel.noAuthNoPriv
|
@@ -1808,7 +1820,18 @@ Message.prototype.createReportResponseMessage = function (engine, context) {
|
|
1808
1820
|
msgAuthenticationParameters: "",
|
1809
1821
|
msgPrivacyParameters: ""
|
1810
1822
|
};
|
1811
|
-
|
1823
|
+
|
1824
|
+
// Create varbinds array with appropriate error
|
1825
|
+
var varbinds = [];
|
1826
|
+
if (errorType && UsmStats[errorType]) {
|
1827
|
+
varbinds.push ({
|
1828
|
+
oid: UsmStatsBase + "." + errorType + ".0",
|
1829
|
+
type: ObjectType.Counter32,
|
1830
|
+
value: 1
|
1831
|
+
});
|
1832
|
+
}
|
1833
|
+
|
1834
|
+
var reportPdu = ReportPdu.createFromVariables (this.pdu.id, varbinds, {});
|
1812
1835
|
reportPdu.contextName = context;
|
1813
1836
|
var responseMessage = Message.createRequestV3 (user, responseSecurityParameters, reportPdu);
|
1814
1837
|
responseMessage.msgGlobalData.msgID = this.msgGlobalData.msgID;
|
@@ -3110,10 +3133,24 @@ Listener.processIncoming = function (buffer, authorizer, callback) {
|
|
3110
3133
|
message.disableAuthentication = authorizer.disableAuthorization;
|
3111
3134
|
if ( ! message.user ) {
|
3112
3135
|
if ( message.msgSecurityParameters.msgUserName != "" && ! authorizer.disableAuthorization ) {
|
3136
|
+
if ( message.isReportable () ) {
|
3137
|
+
return {
|
3138
|
+
original: message,
|
3139
|
+
report: true,
|
3140
|
+
errorType: UsmErrorType.UNKNOWN_USER_NAME
|
3141
|
+
};
|
3142
|
+
}
|
3113
3143
|
callback (new RequestFailedError ("Local user not found for message with user " +
|
3114
3144
|
message.msgSecurityParameters.msgUserName));
|
3115
3145
|
return;
|
3116
3146
|
} else if ( message.hasAuthentication () ) {
|
3147
|
+
if ( message.isReportable () ) {
|
3148
|
+
return {
|
3149
|
+
original: message,
|
3150
|
+
report: true,
|
3151
|
+
errorType: UsmErrorType.UNKNOWN_USER_NAME
|
3152
|
+
};
|
3153
|
+
}
|
3117
3154
|
callback (new RequestFailedError ("Local user not found and message requires authentication with user " +
|
3118
3155
|
message.msgSecurityParameters.msgUserName));
|
3119
3156
|
return;
|
@@ -3125,11 +3162,25 @@ Listener.processIncoming = function (buffer, authorizer, callback) {
|
|
3125
3162
|
}
|
3126
3163
|
}
|
3127
3164
|
if ( (message.user.level == SecurityLevel.authNoPriv || message.user.level == SecurityLevel.authPriv) && ! message.hasAuthentication() ) {
|
3165
|
+
if ( message.isReportable () ) {
|
3166
|
+
return {
|
3167
|
+
original: message,
|
3168
|
+
report: true,
|
3169
|
+
errorType: UsmErrorType.WRONG_DIGESTS
|
3170
|
+
};
|
3171
|
+
}
|
3128
3172
|
callback (new RequestFailedError ("Local user " + message.msgSecurityParameters.msgUserName +
|
3129
3173
|
" requires authentication but message does not provide it"));
|
3130
3174
|
return;
|
3131
3175
|
}
|
3132
3176
|
if ( message.user.level == SecurityLevel.authPriv && ! message.hasPrivacy() ) {
|
3177
|
+
if ( message.isReportable () ) {
|
3178
|
+
return {
|
3179
|
+
original: message,
|
3180
|
+
report: true,
|
3181
|
+
errorType: UsmErrorType.WRONG_DIGESTS
|
3182
|
+
};
|
3183
|
+
}
|
3133
3184
|
callback (new RequestFailedError ("Local user " + message.msgSecurityParameters.msgUserName +
|
3134
3185
|
" requires privacy but message does not provide it"));
|
3135
3186
|
return;
|
@@ -3390,6 +3441,12 @@ Receiver.prototype.onMsg = function (socket, buffer, rinfo) {
|
|
3390
3441
|
return;
|
3391
3442
|
}
|
3392
3443
|
|
3444
|
+
if ( message.report && message.original ) {
|
3445
|
+
let reportMessage = message.original.createReportResponseMessage (this.engine, this.context, message.errorType);
|
3446
|
+
this.listener.send (reportMessage, rinfo, socket);
|
3447
|
+
return;
|
3448
|
+
}
|
3449
|
+
|
3393
3450
|
// The only GetRequest PDUs supported are those used for SNMPv3 discovery
|
3394
3451
|
if ( message.pdu.type == PduType.GetRequest ) {
|
3395
3452
|
if ( message.version != Version3 ) {
|
@@ -3402,7 +3459,7 @@ Receiver.prototype.onMsg = function (socket, buffer, rinfo) {
|
|
3402
3459
|
this.callback (new RequestInvalidError ("Only discovery GetRequests are supported and this message does not have the reportable flag set"));
|
3403
3460
|
return;
|
3404
3461
|
}
|
3405
|
-
let reportMessage = message.createReportResponseMessage (this.engine, this.context);
|
3462
|
+
let reportMessage = message.createReportResponseMessage (this.engine, this.context, UsmErrorType.UNKNOWN_ENGINE_ID);
|
3406
3463
|
this.listener.send (reportMessage, rinfo, socket);
|
3407
3464
|
return;
|
3408
3465
|
}
|
@@ -3928,17 +3985,9 @@ MibNode.prototype.getConstraintsFromProvider = function () {
|
|
3928
3985
|
}
|
3929
3986
|
};
|
3930
3987
|
|
3931
|
-
MibNode.prototype.
|
3988
|
+
MibNode.prototype.validateValue = function (typeFromSet, valueFromSet) {
|
3932
3989
|
const constraints = this.getConstraintsFromProvider ();
|
3933
|
-
|
3934
|
-
const castValue = ObjectTypeUtil.castSetValue (typeFromSet, valueFromSet, constraints);
|
3935
|
-
this.value = castValue;
|
3936
|
-
return true;
|
3937
|
-
} catch (error) {
|
3938
|
-
console.error ("Error setting value: " + error.message);
|
3939
|
-
return false;
|
3940
|
-
}
|
3941
|
-
|
3990
|
+
return ObjectTypeUtil.isValid (typeFromSet, valueFromSet, constraints);
|
3942
3991
|
};
|
3943
3992
|
|
3944
3993
|
MibNode.prototype.getInstanceNodeForTableRow = function () {
|
@@ -4982,10 +5031,16 @@ Agent.prototype.onMsg = function (socket, buffer, rinfo) {
|
|
4982
5031
|
return;
|
4983
5032
|
}
|
4984
5033
|
|
5034
|
+
if ( message.report && message.original ) {
|
5035
|
+
let reportMessage = message.original.createReportResponseMessage (this.engine, this.context, message.errorType);
|
5036
|
+
this.listener.send (reportMessage, rinfo, socket);
|
5037
|
+
return;
|
5038
|
+
}
|
5039
|
+
|
4985
5040
|
// SNMPv3 discovery
|
4986
5041
|
if ( message.version == Version3 && message.pdu.type == PduType.GetRequest &&
|
4987
5042
|
! message.hasAuthoritativeEngineID() && message.isReportable () ) {
|
4988
|
-
let reportMessage = message.createReportResponseMessage (this.engine, this.context);
|
5043
|
+
let reportMessage = message.createReportResponseMessage (this.engine, this.context, UsmErrorType.UNKNOWN_ENGINE_ID);
|
4989
5044
|
this.listener.send (reportMessage, rinfo, socket);
|
4990
5045
|
return;
|
4991
5046
|
}
|
@@ -5192,11 +5247,12 @@ Agent.prototype.request = function (socket, requestMessage, rinfo) {
|
|
5192
5247
|
var varbindsLength = requestPdu.varbinds.length;
|
5193
5248
|
var responsePdu = requestPdu.getResponsePduForRequest ();
|
5194
5249
|
var mibRequests = [];
|
5195
|
-
var handlers = [];
|
5196
5250
|
var createResult = [];
|
5197
5251
|
var oldValues = [];
|
5198
5252
|
var securityName = requestMessage.version == Version3 ? requestMessage.user.name : requestMessage.community;
|
5199
5253
|
|
5254
|
+
const isSetRequest = requestPdu.type === PduType.SetRequest;
|
5255
|
+
|
5200
5256
|
for ( let i = 0; i < requestPdu.varbinds.length; i++ ) {
|
5201
5257
|
let instanceNode = this.mib.lookup (requestPdu.varbinds[i].oid);
|
5202
5258
|
let providerNode;
|
@@ -5226,7 +5282,7 @@ Agent.prototype.request = function (socket, requestMessage, rinfo) {
|
|
5226
5282
|
});
|
5227
5283
|
const ancestorProvider = this.mib.getAncestorProviderFromOid(requestPdu.varbinds[i].oid);
|
5228
5284
|
if ( ancestorProvider ) {
|
5229
|
-
|
5285
|
+
mibRequests[i].handler = function getNsiHandler (mibRequestForNsi) {
|
5230
5286
|
mibRequestForNsi.done ({
|
5231
5287
|
errorStatus: ErrorStatus.NoError,
|
5232
5288
|
type: ObjectType.NoSuchInstance,
|
@@ -5234,7 +5290,7 @@ Agent.prototype.request = function (socket, requestMessage, rinfo) {
|
|
5234
5290
|
});
|
5235
5291
|
};
|
5236
5292
|
} else {
|
5237
|
-
|
5293
|
+
mibRequests[i].handler = function getNsoHandler (mibRequestForNso) {
|
5238
5294
|
mibRequestForNso.done ({
|
5239
5295
|
errorStatus: ErrorStatus.NoError,
|
5240
5296
|
type: ObjectType.NoSuchObject,
|
@@ -5249,7 +5305,7 @@ Agent.prototype.request = function (socket, requestMessage, rinfo) {
|
|
5249
5305
|
operation: requestPdu.type,
|
5250
5306
|
oid: requestPdu.varbinds[i].oid
|
5251
5307
|
});
|
5252
|
-
|
5308
|
+
mibRequests[i].handler = function getNsiHandler (mibRequestForNsi) {
|
5253
5309
|
mibRequestForNsi.done ({
|
5254
5310
|
errorStatus: ErrorStatus.NoError,
|
5255
5311
|
type: ObjectType.NoSuchInstance,
|
@@ -5262,7 +5318,7 @@ Agent.prototype.request = function (socket, requestMessage, rinfo) {
|
|
5262
5318
|
operation: requestPdu.type,
|
5263
5319
|
oid: requestPdu.varbinds[i].oid
|
5264
5320
|
});
|
5265
|
-
|
5321
|
+
mibRequests[i].handler = function getRanaHandler (mibRequestForRana) {
|
5266
5322
|
mibRequestForRana.done ({
|
5267
5323
|
errorStatus: ErrorStatus.NoAccess,
|
5268
5324
|
type: ObjectType.Null,
|
@@ -5276,14 +5332,14 @@ Agent.prototype.request = function (socket, requestMessage, rinfo) {
|
|
5276
5332
|
operation: requestPdu.type,
|
5277
5333
|
oid: requestPdu.varbinds[i].oid
|
5278
5334
|
});
|
5279
|
-
|
5335
|
+
mibRequests[i].handler = function getAccessDeniedHandler (mibRequestForAccessDenied) {
|
5280
5336
|
mibRequestForAccessDenied.done ({
|
5281
5337
|
errorStatus: ErrorStatus.NoAccess,
|
5282
5338
|
type: ObjectType.Null,
|
5283
5339
|
value: null
|
5284
5340
|
});
|
5285
5341
|
};
|
5286
|
-
} else if (
|
5342
|
+
} else if ( isSetRequest &&
|
5287
5343
|
providerNode.provider.type == MibProviderType.Table &&
|
5288
5344
|
typeof (rowStatusColumn = providerNode.provider.tableColumns.reduce(
|
5289
5345
|
(acc, current) => current.rowStatus ? current.number : acc, null )) == "number" &&
|
@@ -5319,7 +5375,7 @@ Agent.prototype.request = function (socket, requestMessage, rinfo) {
|
|
5319
5375
|
operation: requestPdu.type,
|
5320
5376
|
oid: requestPdu.varbinds[i].oid
|
5321
5377
|
});
|
5322
|
-
|
5378
|
+
mibRequests[i].handler = getIcsHandler;
|
5323
5379
|
}
|
5324
5380
|
break;
|
5325
5381
|
|
@@ -5333,7 +5389,7 @@ Agent.prototype.request = function (socket, requestMessage, rinfo) {
|
|
5333
5389
|
operation: requestPdu.type,
|
5334
5390
|
oid: requestPdu.varbinds[i].oid
|
5335
5391
|
});
|
5336
|
-
|
5392
|
+
mibRequests[i].handler = getIcsHandler;
|
5337
5393
|
}
|
5338
5394
|
break;
|
5339
5395
|
|
@@ -5354,16 +5410,16 @@ Agent.prototype.request = function (socket, requestMessage, rinfo) {
|
|
5354
5410
|
operation: requestPdu.type,
|
5355
5411
|
oid: requestPdu.varbinds[i].oid
|
5356
5412
|
});
|
5357
|
-
|
5413
|
+
mibRequests[i].handler = getIcsHandler;
|
5358
5414
|
break;
|
5359
5415
|
}
|
5360
5416
|
}
|
5361
5417
|
|
5362
|
-
if (
|
5418
|
+
if ( isSetRequest && ! createResult[i] ) {
|
5363
5419
|
oldValues[i] = instanceNode.value;
|
5364
5420
|
}
|
5365
5421
|
|
5366
|
-
if ( !
|
5422
|
+
if ( ! mibRequests[i] ) {
|
5367
5423
|
mibRequests[i] = new MibRequest ({
|
5368
5424
|
operation: requestPdu.type,
|
5369
5425
|
providerNode: providerNode,
|
@@ -5371,38 +5427,67 @@ Agent.prototype.request = function (socket, requestMessage, rinfo) {
|
|
5371
5427
|
oid: requestPdu.varbinds[i].oid
|
5372
5428
|
});
|
5373
5429
|
|
5374
|
-
|
5375
|
-
|
5376
|
-
|
5430
|
+
mibRequests[i].handler = providerNode.provider.handler;
|
5431
|
+
|
5432
|
+
if ( isSetRequest ) {
|
5433
|
+
mibRequests[i].setType = instanceNode.valueType;
|
5434
|
+
mibRequests[i].setValue = requestPdu.varbinds[i].requestValue ?? requestPdu.varbinds[i].value;
|
5435
|
+
try {
|
5436
|
+
mibRequests[i].setValue =
|
5437
|
+
ObjectTypeUtil.castSetValue (mibRequests[i].setType, mibRequests[i].setValue);
|
5438
|
+
|
5439
|
+
if ( ! mibRequests[i].instanceNode.validateValue (mibRequests[i].setType, mibRequests[i].setValue) ) {
|
5440
|
+
mibRequests[i].handler = function badValueHandler (request) {
|
5441
|
+
request.done ({
|
5442
|
+
errorStatus: ErrorStatus.BadValue,
|
5443
|
+
type: ObjectType.Null,
|
5444
|
+
value: null,
|
5445
|
+
});
|
5446
|
+
};
|
5447
|
+
}
|
5448
|
+
} catch (e) {
|
5449
|
+
debug('Invalid value for type', e, mibRequests[i]);
|
5450
|
+
mibRequests[i].handler = function wrongTypeHandler (request) {
|
5451
|
+
request.done ({
|
5452
|
+
errorStatus: ErrorStatus.WrongType,
|
5453
|
+
type: ObjectType.Null,
|
5454
|
+
value: null,
|
5455
|
+
});
|
5456
|
+
};
|
5457
|
+
}
|
5377
5458
|
}
|
5378
|
-
handlers[i] = providerNode.provider.handler;
|
5379
5459
|
}
|
5380
5460
|
}
|
5381
5461
|
|
5382
5462
|
(function (savedIndex) {
|
5383
|
-
|
5384
|
-
|
5463
|
+
const mibRequest = mibRequests[savedIndex];
|
5464
|
+
mibRequest.done = function (error) {
|
5465
|
+
mibRequest.error = error ?? { errorStatus: ErrorStatus.NoError };
|
5466
|
+
let responseVarbind;
|
5385
5467
|
let rowIndex = null;
|
5386
5468
|
let row = null;
|
5387
5469
|
let deleted = false;
|
5388
5470
|
let column = -1;
|
5389
5471
|
responseVarbind = {
|
5390
|
-
oid:
|
5472
|
+
oid: mibRequest.oid
|
5391
5473
|
};
|
5392
5474
|
if ( error ) {
|
5393
|
-
if ( (typeof responsePdu.errorStatus == "undefined" || responsePdu.errorStatus == ErrorStatus.NoError) &&
|
5475
|
+
if ( (typeof responsePdu.errorStatus == "undefined" || responsePdu.errorStatus == ErrorStatus.NoError) &&
|
5476
|
+
error.errorStatus != ErrorStatus.NoError ) {
|
5394
5477
|
responsePdu.errorStatus = error.errorStatus;
|
5395
5478
|
responsePdu.errorIndex = savedIndex + 1;
|
5396
5479
|
}
|
5397
5480
|
responseVarbind.type = error.type || ObjectType.Null;
|
5398
|
-
responseVarbind.value = error.value
|
5481
|
+
responseVarbind.value = error.value ?? null;
|
5399
5482
|
//responseVarbind.errorStatus: error.errorStatus
|
5400
5483
|
if ( error.errorStatus != ErrorStatus.NoError ) {
|
5401
5484
|
responseVarbind.errorStatus = error.errorStatus;
|
5402
5485
|
}
|
5403
5486
|
} else {
|
5404
|
-
|
5405
|
-
|
5487
|
+
const instanceNode = mibRequest.instanceNode;
|
5488
|
+
const providerNode = mibRequest.providerNode;
|
5489
|
+
const provider = providerNode ? providerNode.provider : null;
|
5490
|
+
const providerName = provider ? provider.name : null;
|
5406
5491
|
let subOid;
|
5407
5492
|
let subAddr;
|
5408
5493
|
if ( providerNode && providerNode.provider && providerNode.provider.type == MibProviderType.Table ) {
|
@@ -5413,7 +5498,7 @@ Agent.prototype.request = function (socket, requestMessage, rinfo) {
|
|
5413
5498
|
rowIndex = Mib.getRowIndexFromOid( subAddr.join("."), provider.tableIndex );
|
5414
5499
|
row = me.mib.getTableRowCells ( providerName, rowIndex );
|
5415
5500
|
}
|
5416
|
-
if (
|
5501
|
+
if ( isSetRequest && mibRequest.commitSet ) {
|
5417
5502
|
// Is this a RowStatus column with a value of 6 (delete)?
|
5418
5503
|
let rowStatusColumn = provider.type == MibProviderType.Table
|
5419
5504
|
? provider.tableColumns.reduce( (acc, current) => current.rowStatus ? current.number : acc, null )
|
@@ -5437,26 +5522,16 @@ Agent.prototype.request = function (socket, requestMessage, rinfo) {
|
|
5437
5522
|
|
5438
5523
|
} else {
|
5439
5524
|
// No special handling required. Just save the new value.
|
5440
|
-
|
5441
|
-
requestPdu.varbinds[savedIndex].type,
|
5442
|
-
requestPdu.varbinds[savedIndex].value
|
5443
|
-
);
|
5444
|
-
if ( ! setResult ) {
|
5445
|
-
if ( typeof responsePdu.errorStatus == "undefined" || responsePdu.errorStatus == ErrorStatus.NoError ) {
|
5446
|
-
responsePdu.errorStatus = ErrorStatus.WrongValue;
|
5447
|
-
responsePdu.errorIndex = savedIndex + 1;
|
5448
|
-
}
|
5449
|
-
responseVarbind.errorStatus = ErrorStatus.WrongValue;
|
5450
|
-
}
|
5525
|
+
mibRequest.instanceNode.value = mibRequest.setValue;
|
5451
5526
|
}
|
5452
5527
|
}
|
5453
5528
|
if ( ( requestPdu.type == PduType.GetNextRequest || requestPdu.type == PduType.GetBulkRequest ) &&
|
5454
5529
|
requestPdu.varbinds[savedIndex].type == ObjectType.EndOfMibView ) {
|
5455
5530
|
responseVarbind.type = ObjectType.EndOfMibView;
|
5456
5531
|
} else {
|
5457
|
-
responseVarbind.type =
|
5532
|
+
responseVarbind.type = mibRequest.instanceNode.valueType;
|
5458
5533
|
}
|
5459
|
-
responseVarbind.value =
|
5534
|
+
responseVarbind.value = mibRequest.instanceNode.value;
|
5460
5535
|
if ( responseVarbind.value === undefined || responseVarbind.value === null ) {
|
5461
5536
|
responseVarbind.type = ObjectType.NoSuchInstance;
|
5462
5537
|
}
|
@@ -5467,16 +5542,19 @@ Agent.prototype.request = function (socket, requestMessage, rinfo) {
|
|
5467
5542
|
if ( requestPdu.type == PduType.GetNextRequest || requestPdu.type == PduType.GetNextRequest ) {
|
5468
5543
|
responseVarbind.previousOid = requestPdu.varbinds[savedIndex].previousOid;
|
5469
5544
|
}
|
5470
|
-
|
5545
|
+
const isTestSet = mibRequest.testSet;
|
5546
|
+
if ( isSetRequest ) {
|
5547
|
+
if ( mibRequest.testSet ) {
|
5548
|
+
delete mibRequest.testSet;
|
5549
|
+
mibRequest.commitSet = true;
|
5550
|
+
if ( mibRequest.error.errorStatus === ErrorStatus.NoError )
|
5551
|
+
delete mibRequest.error;
|
5552
|
+
}
|
5471
5553
|
if ( oldValues[savedIndex] !== undefined ) {
|
5472
5554
|
responseVarbind.oldValue = oldValues[savedIndex];
|
5473
5555
|
}
|
5474
|
-
responseVarbind.requestType =
|
5475
|
-
|
5476
|
-
responseVarbind.requestValue = ObjectTypeUtil.castSetValue (requestPdu.varbinds[savedIndex].type, requestPdu.varbinds[savedIndex].requestValue);
|
5477
|
-
} else {
|
5478
|
-
responseVarbind.requestValue = ObjectTypeUtil.castSetValue (requestPdu.varbinds[savedIndex].type, requestPdu.varbinds[savedIndex].value);
|
5479
|
-
}
|
5556
|
+
responseVarbind.requestType = mibRequests[savedIndex].setType;
|
5557
|
+
responseVarbind.requestValue = mibRequests[savedIndex].setValue;
|
5480
5558
|
}
|
5481
5559
|
if ( createResult[savedIndex] ) {
|
5482
5560
|
responseVarbind.autoCreated = true;
|
@@ -5494,16 +5572,56 @@ Agent.prototype.request = function (socket, requestMessage, rinfo) {
|
|
5494
5572
|
}
|
5495
5573
|
me.setSingleVarbind (responsePdu, savedIndex, responseVarbind);
|
5496
5574
|
if ( ++varbindsCompleted == varbindsLength) {
|
5575
|
+
// If all varbind have been tested, apply
|
5576
|
+
// the handlers again in commit mode.
|
5577
|
+
if (isTestSet && !responsePdu.errorIndex) {
|
5578
|
+
varbindsCompleted = 0;
|
5579
|
+
setImmediate(() => applySetHandlers(/*testSet=*/false));
|
5580
|
+
return;
|
5581
|
+
}
|
5497
5582
|
me.sendResponse.call (me, socket, rinfo, requestMessage, responsePdu);
|
5498
5583
|
}
|
5499
5584
|
};
|
5585
|
+
if ( isSetRequest )
|
5586
|
+
mibRequest.testSet = true;
|
5500
5587
|
})(i);
|
5501
|
-
if ( handlers[i] ) {
|
5502
|
-
handlers[i] (mibRequests[i]);
|
5503
|
-
} else {
|
5504
|
-
mibRequests[i].done ();
|
5505
|
-
}
|
5506
5588
|
}
|
5589
|
+
const applyHandlers = testSet => {
|
5590
|
+
for ( const mibRequest of mibRequests ) {
|
5591
|
+
if ( mibRequest.error === undefined && testSet === !!mibRequest.testSet ) {
|
5592
|
+
if ( mibRequest.handler ) {
|
5593
|
+
mibRequest.handler (mibRequest);
|
5594
|
+
} else {
|
5595
|
+
mibRequest.done ();
|
5596
|
+
}
|
5597
|
+
}
|
5598
|
+
}
|
5599
|
+
};
|
5600
|
+
const applySetHandlers = testSet => {
|
5601
|
+
if ( this.bulkSetHandler ) {
|
5602
|
+
const errorStatus = this.bulkSetHandler( mibRequests, this.mib, testSet ) ?? ErrorStatus.NoError;
|
5603
|
+
if ( errorStatus !== ErrorStatus.NoError ) {
|
5604
|
+
for ( const mibRequest of mibRequests ) {
|
5605
|
+
if ( mibRequest.error === undefined ) {
|
5606
|
+
mibRequest.done ({
|
5607
|
+
errorStatus,
|
5608
|
+
type: ObjectType.Null,
|
5609
|
+
value: null
|
5610
|
+
});
|
5611
|
+
}
|
5612
|
+
}
|
5613
|
+
}
|
5614
|
+
}
|
5615
|
+
applyHandlers(testSet);
|
5616
|
+
};
|
5617
|
+
if ( isSetRequest )
|
5618
|
+
applySetHandlers(/*testSet=*/true);
|
5619
|
+
else
|
5620
|
+
applyHandlers(false);
|
5621
|
+
};
|
5622
|
+
|
5623
|
+
Agent.prototype.setBulkSetHandler = function setBulkSetHandler(cb) {
|
5624
|
+
this.bulkSetHandler = cb;
|
5507
5625
|
};
|
5508
5626
|
|
5509
5627
|
Agent.prototype.getRequest = function (socket, requestMessage, rinfo) {
|
@@ -5854,6 +5972,13 @@ AgentXPdu.createFromVariables = function (vars) {
|
|
5854
5972
|
pdu.index = vars.index || 0;
|
5855
5973
|
pdu.varbinds = vars.varbinds || null;
|
5856
5974
|
break;
|
5975
|
+
case AgentXPduType.TestSet:
|
5976
|
+
pdu.varbinds = vars.varbinds || null;
|
5977
|
+
break;
|
5978
|
+
case AgentXPduType.CommitSet:
|
5979
|
+
case AgentXPduType.UndoSet:
|
5980
|
+
case AgentXPduType.CleanupSet:
|
5981
|
+
break;
|
5857
5982
|
default:
|
5858
5983
|
// unsupported PDU type - should never happen as we control these
|
5859
5984
|
throw new RequestInvalidError ("Unknown PDU type '" + pdu.pduType
|
@@ -6278,35 +6403,39 @@ Subagent.prototype.onMsg = function (buffer, rinfo) {
|
|
6278
6403
|
debug ("Received AgentX " + AgentXPduType[pdu.pduType] + " PDU");
|
6279
6404
|
debug (pdu);
|
6280
6405
|
|
6281
|
-
|
6282
|
-
|
6283
|
-
|
6284
|
-
|
6285
|
-
|
6286
|
-
|
6287
|
-
|
6288
|
-
|
6289
|
-
|
6290
|
-
|
6291
|
-
|
6292
|
-
|
6293
|
-
|
6294
|
-
|
6295
|
-
|
6296
|
-
|
6297
|
-
|
6298
|
-
|
6299
|
-
|
6300
|
-
|
6301
|
-
|
6302
|
-
|
6303
|
-
|
6304
|
-
|
6305
|
-
|
6306
|
-
|
6307
|
-
|
6308
|
-
|
6309
|
-
|
6406
|
+
try {
|
6407
|
+
switch (pdu.pduType) {
|
6408
|
+
case AgentXPduType.Response:
|
6409
|
+
this.response (pdu);
|
6410
|
+
break;
|
6411
|
+
case AgentXPduType.Get:
|
6412
|
+
this.getRequest (pdu);
|
6413
|
+
break;
|
6414
|
+
case AgentXPduType.GetNext:
|
6415
|
+
this.getNextRequest (pdu);
|
6416
|
+
break;
|
6417
|
+
case AgentXPduType.GetBulk:
|
6418
|
+
this.getBulkRequest (pdu);
|
6419
|
+
break;
|
6420
|
+
case AgentXPduType.TestSet:
|
6421
|
+
this.testSet (pdu);
|
6422
|
+
break;
|
6423
|
+
case AgentXPduType.CommitSet:
|
6424
|
+
this.commitSet (pdu);
|
6425
|
+
break;
|
6426
|
+
case AgentXPduType.UndoSet:
|
6427
|
+
this.undoSet (pdu);
|
6428
|
+
break;
|
6429
|
+
case AgentXPduType.CleanupSet:
|
6430
|
+
this.cleanupSet (pdu);
|
6431
|
+
break;
|
6432
|
+
default:
|
6433
|
+
// Unknown PDU type - shouldn't happen as master agents shouldn't send administrative PDUs
|
6434
|
+
throw new RequestInvalidError ("Unknown PDU type '" + pdu.pduType
|
6435
|
+
+ "' in request");
|
6436
|
+
}
|
6437
|
+
} catch (e) {
|
6438
|
+
console.error(e);
|
6310
6439
|
}
|
6311
6440
|
};
|
6312
6441
|
|
@@ -6345,82 +6474,141 @@ Subagent.prototype.response = function (pdu) {
|
|
6345
6474
|
}
|
6346
6475
|
};
|
6347
6476
|
|
6477
|
+
Subagent.prototype.isAllowed = function (pduType, provider, instanceNode) {
|
6478
|
+
const requestedAccess =
|
6479
|
+
agentXPduTypesRequiringReadAccess.includes(pduType)? MaxAccess["read-only"] :
|
6480
|
+
agentXPduTypesRequiringWriteAccess.includes(pduType)? MaxAccess["read-write"] :
|
6481
|
+
undefined;
|
6482
|
+
|
6483
|
+
if (requestedAccess === undefined)
|
6484
|
+
return true;
|
6485
|
+
|
6486
|
+
if (provider.type === MibProviderType.Scalar)
|
6487
|
+
return provider.maxAccess >= requestedAccess;
|
6488
|
+
|
6489
|
+
// It's a table column. Use that column's maxAccess.
|
6490
|
+
const column = instanceNode.getTableColumnFromInstanceNode();
|
6491
|
+
|
6492
|
+
// In the typical case, we could use (column - 1) to index
|
6493
|
+
// into tableColumns to get to the correct entry. There is no
|
6494
|
+
// guarantee, however, that column numbers in the OID are
|
6495
|
+
// necessarily consecutive; theoretically some could be
|
6496
|
+
// missing. We'll therefore play it safe and search for the
|
6497
|
+
// specified column entry.
|
6498
|
+
|
6499
|
+
const columnEntry = provider.tableColumns.find(entry => entry.number === column);
|
6500
|
+
const maxAccess = columnEntry ? columnEntry.maxAccess || MaxAccess['not-accessible'] : MaxAccess['not-accessible'];
|
6501
|
+
return maxAccess >= requestedAccess;
|
6502
|
+
};
|
6503
|
+
|
6504
|
+
|
6348
6505
|
Subagent.prototype.request = function (pdu, requestVarbinds) {
|
6349
6506
|
const me = this;
|
6350
6507
|
const varbindsLength = requestVarbinds.length;
|
6351
6508
|
const responseVarbinds = [];
|
6352
6509
|
const responsePdu = pdu.getResponsePduForRequest ();
|
6510
|
+
const mibRequests = [];
|
6353
6511
|
let varbindsCompleted = 0;
|
6512
|
+
let firstVarbindError;
|
6513
|
+
const isTestSet = pdu.pduType == AgentXPduType.TestSet;
|
6514
|
+
const isSetRequest = isTestSet ||
|
6515
|
+
pdu.pduType == AgentXPduType.CommitSet ||
|
6516
|
+
pdu.pduType == AgentXPduType.UndoSet;
|
6354
6517
|
|
6355
6518
|
for ( let i = 0; i < varbindsLength; i++ ) {
|
6356
6519
|
const requestVarbind = requestVarbinds[i];
|
6357
|
-
|
6358
|
-
|
6359
|
-
|
6360
|
-
var handler;
|
6361
|
-
var responseVarbindType;
|
6520
|
+
const instanceNode = this.mib.lookup (requestVarbind.oid);
|
6521
|
+
let providerNode;
|
6522
|
+
let responseVarbindType;
|
6362
6523
|
|
6363
6524
|
if ( ! instanceNode ) {
|
6364
|
-
|
6525
|
+
mibRequests[i] = new MibRequest ({
|
6365
6526
|
operation: pdu.pduType,
|
6366
6527
|
oid: requestVarbind.oid
|
6367
6528
|
});
|
6368
|
-
|
6369
|
-
mibRequestForNso.done ({
|
6529
|
+
mibRequests[i].error = {
|
6370
6530
|
errorStatus: ErrorStatus.NoError,
|
6371
6531
|
errorIndex: 0,
|
6372
6532
|
type: ObjectType.NoSuchObject,
|
6373
6533
|
value: null
|
6374
|
-
});
|
6375
6534
|
};
|
6376
6535
|
} else {
|
6377
6536
|
providerNode = this.mib.getProviderNodeForInstance (instanceNode);
|
6378
6537
|
if ( ! providerNode ) {
|
6379
|
-
|
6538
|
+
mibRequests[i] = new MibRequest ({
|
6380
6539
|
operation: pdu.pduType,
|
6381
6540
|
oid: requestVarbind.oid
|
6382
6541
|
});
|
6383
|
-
|
6384
|
-
mibRequestForNsi.done ({
|
6542
|
+
mibRequests[i].error = {
|
6385
6543
|
errorStatus: ErrorStatus.NoError,
|
6386
6544
|
errorIndex: 0,
|
6387
6545
|
type: ObjectType.NoSuchInstance,
|
6388
6546
|
value: null
|
6389
|
-
});
|
6390
6547
|
};
|
6391
6548
|
} else {
|
6392
|
-
|
6549
|
+
mibRequests[i] = new MibRequest ({
|
6393
6550
|
operation: pdu.pduType,
|
6394
6551
|
providerNode: providerNode,
|
6395
6552
|
instanceNode: instanceNode,
|
6396
|
-
oid: requestVarbind.oid
|
6553
|
+
oid: requestVarbind.oid,
|
6397
6554
|
});
|
6398
|
-
|
6399
|
-
|
6400
|
-
|
6555
|
+
mibRequests[i].handler = providerNode.provider.handler;
|
6556
|
+
if ( ! me.isAllowed(pdu.pduType, mibRequests[i].providerNode?.provider, mibRequests[i].instanceNode) ) {
|
6557
|
+
mibRequests[i].error = {
|
6558
|
+
errorStatus: ErrorStatus.NoAccess,
|
6559
|
+
errorIndex: i + 1,
|
6560
|
+
type: ObjectType.Null,
|
6561
|
+
value: null
|
6562
|
+
};
|
6563
|
+
}
|
6564
|
+
if ( isSetRequest ) {
|
6565
|
+
mibRequests[i].setType = instanceNode.valueType;
|
6566
|
+
mibRequests[i].setValue = requestVarbind.requestValue ?? requestVarbind.value;
|
6567
|
+
mibRequests[i].requestIndex = i + 1;
|
6568
|
+
try {
|
6569
|
+
mibRequests[i].setValue =
|
6570
|
+
ObjectTypeUtil.castSetValue (mibRequests[i].setType, mibRequests[i].setValue);
|
6571
|
+
|
6572
|
+
if ( ! mibRequests[i].instanceNode.validateValue (mibRequests[i].setType, mibRequests[i].setValue) ) {
|
6573
|
+
mibRequests[i].error = {
|
6574
|
+
errorStatus: ErrorStatus.BadValue,
|
6575
|
+
errorIndex: i + 1,
|
6576
|
+
type: mibRequests[i].setType,
|
6577
|
+
value: mibRequests[i].setValue,
|
6578
|
+
};
|
6579
|
+
}
|
6580
|
+
} catch (e) {
|
6581
|
+
debug('Invalid value for type', e, mibRequests[i]);
|
6582
|
+
mibRequests[i].error = {
|
6583
|
+
errorStatus: ErrorStatus.WrongType,
|
6584
|
+
errorIndex: i + 1,
|
6585
|
+
type: mibRequests[i].setType,
|
6586
|
+
value: mibRequests[i].setValue,
|
6587
|
+
};
|
6588
|
+
}
|
6401
6589
|
}
|
6402
|
-
handler = providerNode.provider.handler;
|
6403
6590
|
}
|
6404
6591
|
}
|
6405
6592
|
|
6406
6593
|
(function (savedIndex) {
|
6594
|
+
const mibRequest = mibRequests[savedIndex];
|
6595
|
+
const requestVarbind = requestVarbinds[savedIndex];
|
6407
6596
|
mibRequest.done = function (error) {
|
6597
|
+
mibRequest.error = error ?? { errorStatus: ErrorStatus.NoError };
|
6408
6598
|
let responseVarbind;
|
6409
6599
|
if ( error ) {
|
6410
6600
|
responseVarbind = {
|
6411
6601
|
oid: mibRequest.oid,
|
6412
6602
|
type: error.type || ObjectType.Null,
|
6413
|
-
value: error.value
|
6603
|
+
value: error.value ?? null
|
6414
6604
|
};
|
6415
|
-
|
6416
|
-
|
6417
|
-
responsePdu.index = savedIndex + 1;
|
6418
|
-
}
|
6605
|
+
error.errorIndex = savedIndex + 1;
|
6606
|
+
firstVarbindError = firstVarbindError ?? error;
|
6419
6607
|
if ( error.errorStatus != ErrorStatus.NoError ) {
|
6420
6608
|
responseVarbind.errorStatus = error.errorStatus;
|
6421
6609
|
}
|
6422
6610
|
} else {
|
6423
|
-
if (
|
6611
|
+
if ( isTestSet ) {
|
6424
6612
|
// more tests?
|
6425
6613
|
} else if ( pdu.pduType == AgentXPduType.CommitSet ) {
|
6426
6614
|
me.setTransactions[pdu.transactionID].originalValue = mibRequest.instanceNode.value;
|
@@ -6440,25 +6628,56 @@ Subagent.prototype.request = function (pdu, requestVarbinds) {
|
|
6440
6628
|
value: mibRequest.instanceNode.value
|
6441
6629
|
};
|
6442
6630
|
}
|
6443
|
-
responseVarbinds[savedIndex] = responseVarbind;
|
6444
|
-
if ( ++varbindsCompleted == varbindsLength) {
|
6445
|
-
if (
|
6446
|
-
|
6631
|
+
responseVarbinds[savedIndex] = mibRequest.response = responseVarbind;
|
6632
|
+
if ( ++varbindsCompleted == varbindsLength ) {
|
6633
|
+
if ( isSetRequest ) {
|
6634
|
+
responsePdu.error = firstVarbindError?.errorStatus ?? 0;
|
6635
|
+
responsePdu.index = firstVarbindError?.errorIndex ?? 0;
|
6447
6636
|
me.sendResponse.call (me, responsePdu);
|
6448
6637
|
} else {
|
6449
6638
|
me.sendResponse.call (me, responsePdu, responseVarbinds);
|
6450
6639
|
}
|
6451
6640
|
}
|
6452
6641
|
};
|
6642
|
+
if ( isTestSet )
|
6643
|
+
mibRequests[i].testSet = true;
|
6644
|
+
else if ( pdu.pduType == AgentXPduType.CommitSet )
|
6645
|
+
mibRequests[i].commitSet = true;
|
6646
|
+
if ( mibRequest.error )
|
6647
|
+
mibRequest.done(mibRequest.error);
|
6453
6648
|
})(i);
|
6454
|
-
|
6455
|
-
|
6456
|
-
|
6457
|
-
|
6649
|
+
}
|
6650
|
+
if ( isSetRequest && this.bulkSetHandler ) {
|
6651
|
+
const errorStatus = this.bulkSetHandler( mibRequests, this.mib, isTestSet ) ?? ErrorStatus.NoError;
|
6652
|
+
if ( errorStatus !== ErrorStatus.NoError ) {
|
6653
|
+
for ( const mibRequest of mibRequests ) {
|
6654
|
+
if ( !mibRequest.response ) {
|
6655
|
+
mibRequest.done ({
|
6656
|
+
errorStatus,
|
6657
|
+
type: ObjectType.Null,
|
6658
|
+
value: null
|
6659
|
+
});
|
6660
|
+
}
|
6661
|
+
}
|
6662
|
+
return;
|
6663
|
+
}
|
6664
|
+
}
|
6665
|
+
for ( let i = 0; i < requestVarbinds.length; i++ ) {
|
6666
|
+
if ( !mibRequests[i].response ) {
|
6667
|
+
const handler = mibRequests[i].handler;
|
6668
|
+
if ( handler ) {
|
6669
|
+
handler (mibRequests[i]);
|
6670
|
+
} else {
|
6671
|
+
mibRequests[i].done ();
|
6672
|
+
}
|
6458
6673
|
}
|
6459
6674
|
}
|
6460
6675
|
};
|
6461
6676
|
|
6677
|
+
Subagent.prototype.setBulkSetHandler = function setBulkSetHandler(cb) {
|
6678
|
+
this.bulkSetHandler = cb;
|
6679
|
+
};
|
6680
|
+
|
6462
6681
|
Subagent.prototype.addGetNextVarbind = function (targetVarbinds, startOid) {
|
6463
6682
|
var startNode;
|
6464
6683
|
var getNextNode;
|
@@ -6619,6 +6838,7 @@ exports.ErrorStatus = ErrorStatus;
|
|
6619
6838
|
exports.TrapType = TrapType;
|
6620
6839
|
exports.ObjectType = ObjectType;
|
6621
6840
|
exports.PduType = PduType;
|
6841
|
+
exports.AgentXPdu = AgentXPdu;
|
6622
6842
|
exports.AgentXPduType = AgentXPduType;
|
6623
6843
|
exports.MibProviderType = MibProviderType;
|
6624
6844
|
exports.SecurityLevel = SecurityLevel;
|