net-snmp 3.5.8 → 3.6.2

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 CHANGED
@@ -243,8 +243,8 @@ This object contains constants to select a supported encryption algorithm for
243
243
  SNMPv3 messages that require privacy:
244
244
  * `des` - for DES encryption (CBC-DES)
245
245
  * `aes` - for 128-bit AES encryption (CFB-AES-128)
246
- * `aes256b` - for 256-bit AES encryption (CFB-AES-256) with "Blumenthal" key localiztaion
247
- * `aes256r` - for 256-bit AES encryption (CFB-AES-256) with "Reeder" key localiztaion
246
+ * `aes256b` - for 256-bit AES encryption (CFB-AES-256) with "Blumenthal" key localization
247
+ * `aes256r` - for 256-bit AES encryption (CFB-AES-256) with "Reeder" key localization
248
248
 
249
249
  DES is the sole encryption algorithm specified in the original SNMPv3 User-Based
250
250
  Security Model RFC (RFC 3414); 128-bit AES for SNMPv3 was added later in RFC 3826.
@@ -1062,7 +1062,7 @@ The `table()` method fetches the value for all OIDs lexicographically
1062
1062
  following a specified OID in the MIB tree which have the specified OID as
1063
1063
  their base, much like the `subtree()` method.
1064
1064
 
1065
- This method is designed to fetch conceptial tables, for example the ifTable
1065
+ This method is designed to fetch conceptual tables, for example the ifTable
1066
1066
  (`1.3.6.1.2.1.2.2`) table. The values for returned varbinds will be structured
1067
1067
  into objects to represent conceptual rows. Each row is then placed into an
1068
1068
  object with the rows index being the key, e.g.:
@@ -1171,7 +1171,7 @@ be in the resulting table.
1171
1171
 
1172
1172
  This method should be used when only selected columns are required, and
1173
1173
  will be many times faster than the `table()` method since a much smaller
1174
- amount of data will be fected.
1174
+ amount of data will be fetched.
1175
1175
 
1176
1176
  The following example fetches the ifTable (`1.3.6.1.2.1.2.2`) table, and
1177
1177
  specifies that only the ifDescr (`1.3.6.1.2.1.2.2.1.2`) and ifPhysAddress
@@ -1259,7 +1259,7 @@ returned by the `process.uptime ()` function multiplied by `100`.
1259
1259
  SNMP version 2c messages are quite different in comparison with version 1.
1260
1260
  The version 2c trap has a much simpler format, simply a sequence of varbinds.
1261
1261
  The first varbind to be placed in the trap message will be for the
1262
- `sysUptime.0` OID (`1.3.6.1.6.3.1.1.4.1.0`). The value for this varbind will
1262
+ `sysUptime.0` OID (`1.3.6.1.2.1.1.3.0`). The value for this varbind will
1263
1263
  be the value returned by the `process.uptime ()` function multiplied by 100
1264
1264
  (this can be overridden by providing `upTime` in the optional `options`
1265
1265
  parameter, as documented below).
@@ -1280,7 +1280,7 @@ following items:
1280
1280
 
1281
1281
  * `agentAddr` - IP address used to populate the agent-addr field for SNMP
1282
1282
  version 1 type traps, and defaults to `127.0.0.1`
1283
- * `upTime` - Value of the `sysUptime.0` OID (`1.3.6.1.6.3.1.1.4.1.0`) in the
1283
+ * `upTime` - Value of the `sysUptime.0` OID (`1.3.6.1.2.1.1.3.0`) in the
1284
1284
  trap, defaults to the value returned by the `process.uptime ()` function
1285
1285
  multiplied by 100
1286
1286
 
@@ -1452,6 +1452,7 @@ class:
1452
1452
  var options = {
1453
1453
  port: 162,
1454
1454
  disableAuthorization: false,
1455
+ includeAuthentication: false,
1455
1456
  accessControlModelType: snmp.AccessControlModelType.None,
1456
1457
  engineID: "8000B98380XXXXXXXXXXXXXXXXXXXXXXXX", // where the X's are random hex digits
1457
1458
  address: null,
@@ -1483,6 +1484,8 @@ an object, possibly empty, and can contain the following fields:
1483
1484
  * `transport` - the transport family to use - defaults to `udp4`
1484
1485
  * `address` - the IP address to bind to - default to `null`, which means bind to all IP
1485
1486
  addresses
1487
+ * `includeAuthentication` - adds the community (v1/2c) or user name (v3) information
1488
+ to the notification callback - defaults to `false`
1486
1489
 
1487
1490
  The `callback` parameter is a callback function of the form
1488
1491
  `function (error, notification)`. On an error condition, the `notification`
@@ -3166,6 +3169,18 @@ Example programs are included under the module's `example` directory.
3166
3169
 
3167
3170
  * Fix processing of negative integers larger than 32 bits
3168
3171
 
3172
+ ## Version 3.6.0 - 18/02/2022
3173
+
3174
+ * Add calculated key cache to remove authNoPriv and authPriv performance bottleneck
3175
+
3176
+ ## Version 3.6.1 - 21/03/2022
3177
+
3178
+ * Add v3 context to non-initial PDUs
3179
+
3180
+ ## Version 3.6.2 - 07/04/2022
3181
+
3182
+ * Add option for receiver to receive client authentication identity
3183
+
3169
3184
  # License
3170
3185
 
3171
3186
  Copyright (c) 2020 Mark Abrahams <mark@abrahams.co.nz>
@@ -7,7 +7,8 @@ var snmpOptions = {
7
7
  disableAuthorization: options.n,
8
8
  port: options.p,
9
9
  transport: options.t,
10
- engineID: options.e
10
+ engineID: options.e,
11
+ includeAuthentication: options.a
11
12
  };
12
13
 
13
14
  var cb = function(error, trap) {
package/index.js CHANGED
@@ -427,16 +427,16 @@ function readUint (buffer, isSigned) {
427
427
  value *= 256;
428
428
  value += buffer.readByte ();
429
429
 
430
- if (isSigned && i <= 0) {
431
- if ((value & 0x80) == 0x80) {
432
- signedBitSet = true;
433
- }
434
- }
430
+ if (isSigned && i <= 0) {
431
+ if ((value & 0x80) == 0x80) {
432
+ signedBitSet = true;
433
+ }
434
+ }
435
435
  }
436
436
 
437
- if (signedBitSet) {
438
- value -= 2 ** (i * 8);
439
- }
437
+ if (signedBitSet) {
438
+ value -= 2 ** (i * 8);
439
+ }
440
440
 
441
441
  return value;
442
442
  }
@@ -934,17 +934,32 @@ Authentication.algorithms[AuthProtocols.sha] = {
934
934
  CRYPTO_ALGORITHM: 'sha1'
935
935
  };
936
936
 
937
+ Authentication.authToKeyCache = {};
938
+
939
+ Authentication.computeCacheKey = function (authProtocol, authPasswordString, engineID) {
940
+ var engineIDString = engineID.toString('base64');
941
+ return authProtocol + authPasswordString + engineIDString;
942
+ };
943
+
937
944
  // Adapted from RFC3414 Appendix A.2.1. Password to Key Sample Code for MD5
938
945
  Authentication.passwordToKey = function (authProtocol, authPasswordString, engineID) {
939
946
  var hashAlgorithm;
940
947
  var firstDigest;
941
948
  var finalDigest;
942
- var buf = Buffer.alloc (Authentication.HMAC_BUFFER_SIZE);
949
+ var buf;
943
950
  var bufOffset = 0;
944
951
  var passwordIndex = 0;
945
952
  var count = 0;
946
- var password = Buffer.from (authPasswordString);
953
+ var password;
947
954
  var cryptoAlgorithm = Authentication.algorithms[authProtocol].CRYPTO_ALGORITHM;
955
+
956
+ var cacheKey = Authentication.computeCacheKey(authProtocol, authPasswordString, engineID);
957
+ if (Authentication.authToKeyCache[cacheKey] !== undefined) {
958
+ return Authentication.authToKeyCache[cacheKey];
959
+ }
960
+
961
+ buf = Buffer.alloc (Authentication.HMAC_BUFFER_SIZE);
962
+ password = Buffer.from (authPasswordString);
948
963
 
949
964
  while (count < Authentication.HMAC_BUFFER_SIZE) {
950
965
  for (var i = 0; i < Authentication.HMAC_BLOCK_SIZE; i++) {
@@ -964,6 +979,7 @@ Authentication.passwordToKey = function (authProtocol, authPasswordString, engin
964
979
  finalDigest = hashAlgorithm.digest();
965
980
  // debug ("Localized key: " + finalDigest.toString('hex'));
966
981
 
982
+ Authentication.authToKeyCache[cacheKey] = finalDigest;
967
983
  return finalDigest;
968
984
  };
969
985
 
@@ -2322,6 +2338,7 @@ Session.prototype.set = function (varbinds, responseCb) {
2322
2338
  Session.prototype.simpleGet = function (pduClass, feedCb, varbinds,
2323
2339
  responseCb, options) {
2324
2340
  var id = _generateId (this.idBitsSize);
2341
+ options = Object.assign({}, options, { context: this.context });
2325
2342
  var pdu = SimplePdu.createFromVariables (pduClass, id, varbinds, options);
2326
2343
  var message;
2327
2344
  var req;
@@ -3109,6 +3126,7 @@ var Receiver = function (options, callback) {
3109
3126
  this.port = options.port || 162;
3110
3127
  options.port = this.port;
3111
3128
  this.disableAuthorization = options.disableAuthorization || false;
3129
+ this.includeAuthentication = options.includeAuthentication || false;
3112
3130
  this.context = (options && options.context) ? options.context : "";
3113
3131
  this.listener = new Listener (options, this);
3114
3132
  };
@@ -3145,29 +3163,38 @@ Receiver.prototype.onMsg = function (buffer, rinfo) {
3145
3163
  // Inform/trap processing
3146
3164
  // debug (JSON.stringify (message.pdu, null, 2));
3147
3165
  if ( message.pdu.type == PduType.Trap || message.pdu.type == PduType.TrapV2 ) {
3148
- this.callback (null, this.formatCallbackData (message.pdu, rinfo) );
3166
+ this.callback (null, this.formatCallbackData (message, rinfo) );
3149
3167
  } else if ( message.pdu.type == PduType.InformRequest ) {
3150
3168
  message.pdu.type = PduType.GetResponse;
3151
3169
  message.buffer = null;
3152
3170
  message.setReportable (false);
3153
3171
  this.listener.send (message, rinfo);
3154
3172
  message.pdu.type = PduType.InformRequest;
3155
- this.callback (null, this.formatCallbackData (message.pdu, rinfo) );
3173
+ this.callback (null, this.formatCallbackData (message, rinfo) );
3156
3174
  } else {
3157
3175
  this.callback (new RequestInvalidError ("Unexpected PDU type " + message.pdu.type + " (" + PduType[message.pdu.type] + ")"));
3158
3176
  }
3159
3177
  };
3160
3178
 
3161
- Receiver.prototype.formatCallbackData = function (pdu, rinfo) {
3162
- if ( pdu.contextEngineID ) {
3163
- pdu.contextEngineID = pdu.contextEngineID.toString('hex');
3179
+ Receiver.prototype.formatCallbackData = function (message, rinfo) {
3180
+ if ( message.pdu.contextEngineID ) {
3181
+ message.pdu.contextEngineID = message.pdu.contextEngineID.toString('hex');
3164
3182
  }
3165
- delete pdu.nonRepeaters;
3166
- delete pdu.maxRepetitions;
3167
- return {
3168
- pdu: pdu,
3169
- rinfo: rinfo
3183
+ delete message.pdu.nonRepeaters;
3184
+ delete message.pdu.maxRepetitions;
3185
+ const formattedData = {
3186
+ pdu: message.pdu,
3187
+ rinfo: rinfo
3170
3188
  };
3189
+ if (this.includeAuthentication) {
3190
+ if (message.community) {
3191
+ formattedData.pdu.community = message.community;
3192
+ } else if (message.user) {
3193
+ formattedData.pdu.user = message.user.name;
3194
+ }
3195
+ }
3196
+
3197
+ return formattedData;
3171
3198
  };
3172
3199
 
3173
3200
  Receiver.prototype.close = function() {
@@ -3546,11 +3573,11 @@ MibNode.prototype.getConstraintsFromProvider = function () {
3546
3573
  };
3547
3574
 
3548
3575
  MibNode.prototype.setValue = function (newValue) {
3549
- var len;
3550
- var min;
3551
- var max;
3552
- var range;
3553
- var found = false;
3576
+ var len;
3577
+ var min;
3578
+ var max;
3579
+ var range;
3580
+ var found = false;
3554
3581
  var constraints = this.getConstraintsFromProvider ();
3555
3582
  if ( ! constraints ) {
3556
3583
  this.value = newValue;
@@ -3561,35 +3588,35 @@ MibNode.prototype.setValue = function (newValue) {
3561
3588
  return false;
3562
3589
  }
3563
3590
  } else if ( constraints.ranges ) {
3564
- for ( range of constraints.ranges ) {
3565
- min = "min" in range ? range.min : Number.MIN_SAFE_INTEGER;
3566
- max = "max" in range ? range.max : Number.MAX_SAFE_INTEGER;
3567
- if ( newValue >= min && newValue <= max ) {
3568
- found = true;
3569
- break;
3570
- }
3571
- }
3572
- if ( ! found ) {
3573
- return false;
3574
- }
3575
- } else if ( constraints.sizes ) {
3576
- // if size is constrained, value must have a length property
3577
- if ( ! ( "length" in newValue ) ) {
3578
- return false;
3579
- }
3580
- len = newValue.length;
3581
- for ( range of constraints.sizes ) {
3582
- min = "min" in range ? range.min : Number.MIN_SAFE_INTEGER;
3583
- max = "max" in range ? range.max : Number.MAX_SAFE_INTEGER;
3584
- if ( len >= min && len <= max ) {
3585
- found = true;
3586
- break;
3587
- }
3588
- }
3589
- if ( ! found ) {
3590
- return false;
3591
- }
3592
- }
3591
+ for ( range of constraints.ranges ) {
3592
+ min = "min" in range ? range.min : Number.MIN_SAFE_INTEGER;
3593
+ max = "max" in range ? range.max : Number.MAX_SAFE_INTEGER;
3594
+ if ( newValue >= min && newValue <= max ) {
3595
+ found = true;
3596
+ break;
3597
+ }
3598
+ }
3599
+ if ( ! found ) {
3600
+ return false;
3601
+ }
3602
+ } else if ( constraints.sizes ) {
3603
+ // if size is constrained, value must have a length property
3604
+ if ( ! ( "length" in newValue ) ) {
3605
+ return false;
3606
+ }
3607
+ len = newValue.length;
3608
+ for ( range of constraints.sizes ) {
3609
+ min = "min" in range ? range.min : Number.MIN_SAFE_INTEGER;
3610
+ max = "max" in range ? range.max : Number.MAX_SAFE_INTEGER;
3611
+ if ( len >= min && len <= max ) {
3612
+ found = true;
3613
+ break;
3614
+ }
3615
+ }
3616
+ if ( ! found ) {
3617
+ return false;
3618
+ }
3619
+ }
3593
3620
  this.value = newValue;
3594
3621
  return true;
3595
3622
  };
@@ -3977,25 +4004,25 @@ Mib.prototype.setTableRowDefaultValues = function (name, values) {
3977
4004
  };
3978
4005
 
3979
4006
  Mib.prototype.setScalarRanges = function (name, ranges ) {
3980
- let provider = this.getProvider(name);
3981
- provider.constraints = { ranges };
4007
+ let provider = this.getProvider(name);
4008
+ provider.constraints = { ranges };
3982
4009
  };
3983
4010
 
3984
4011
  Mib.prototype.setTableColumnRanges = function(name, column, ranges ) {
3985
- let provider = this.getProvider(name);
3986
- let tc = provider.tableColumns;
3987
- tc[column].constraints = { ranges };
4012
+ let provider = this.getProvider(name);
4013
+ let tc = provider.tableColumns;
4014
+ tc[column].constraints = { ranges };
3988
4015
  };
3989
4016
 
3990
4017
  Mib.prototype.setScalarSizes = function (name, sizes ) {
3991
- let provider = this.getProvider(name);
3992
- provider.constraints = { sizes };
4018
+ let provider = this.getProvider(name);
4019
+ provider.constraints = { sizes };
3993
4020
  };
3994
4021
 
3995
4022
  Mib.prototype.setTableColumnSizes = function(name, column, sizes ) {
3996
- let provider = this.getProvider(name);
3997
- let tc = provider.tableColumns;
3998
- tc[column].constraints = { sizes };
4023
+ let provider = this.getProvider(name);
4024
+ let tc = provider.tableColumns;
4025
+ tc[column].constraints = { sizes };
3999
4026
  };
4000
4027
 
4001
4028
  Mib.prototype.registerProviders = function (providers) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "net-snmp",
3
- "version": "3.5.8",
3
+ "version": "3.6.2",
4
4
  "description": "JavaScript implementation of the Simple Network Management Protocol (SNMP)",
5
5
  "main": "index.js",
6
6
  "directories": {
@@ -61,8 +61,8 @@ node ${HOME_DIR}/example/snmp-trap.js -v 3 -l authNoPriv -u ${USER_AUTH} -a ${AU
61
61
  node ${HOME_DIR}/example/snmp-trap.js -v 3 -l authPriv -u ${USER_PRIV} -a ${AUTH_PROTOCOL} -A ${AUTH_KEY} -x ${PRIV_PROTOCOL} -X ${PRIV_KEY} ${PARAMS} ${HOST} ${TRAP_OID}
62
62
  node ${HOME_DIR}/example/snmp-inform.js -v 2c -c ${COMMUNITY} ${PARAMS} ${HOST} ${TRAP_OID}
63
63
  node ${HOME_DIR}/example/snmp-inform.js -v 3 -l noAuthNoPriv -u ${USER_NONE} ${PARAMS} ${HOST} ${TRAP_OID}
64
- node ${HOME_DIR}/example/snmp-inform.js -v 3 -u ${USER_AUTH} -a ${AUTH_PROTOCOL} -A ${AUTH_KEY} ${PARAMS} ${HOST} ${TRAP_OID}
65
- node ${HOME_DIR}/example/snmp-inform.js -v 3 -u ${USER_PRIV} -a ${AUTH_PROTOCOL} -A ${AUTH_KEY} -x ${PRIV_PROTOCOL} -X ${PRIV_KEY} ${PARAMS} ${HOST} ${TRAP_OID}
64
+ node ${HOME_DIR}/example/snmp-inform.js -v 3 -l authNoPriv -u ${USER_AUTH} -a ${AUTH_PROTOCOL} -A ${AUTH_KEY} ${PARAMS} ${HOST} ${TRAP_OID}
65
+ node ${HOME_DIR}/example/snmp-inform.js -v 3 -l authPriv -u ${USER_PRIV} -a ${AUTH_PROTOCOL} -A ${AUTH_KEY} -x ${PRIV_PROTOCOL} -X ${PRIV_KEY} ${PARAMS} ${HOST} ${TRAP_OID}
66
66
  ENDOFCMDS
67
67
 
68
68
  COUNT=1
@@ -81,4 +81,3 @@ while read CMD ; do
81
81
  done <${CMDS}
82
82
 
83
83
  rm -f ${CMDS}
84
-