@blamejs/core 0.18.54 → 0.18.55
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/CHANGELOG.md +110 -0
- package/NOTICE +1 -1
- package/README.md +3 -3
- package/lib/agent-audit.js +27 -2
- package/lib/audit-sign.js +24 -5
- package/lib/auth/passkey.js +4 -1
- package/lib/db-file-lifecycle.js +14 -3
- package/lib/db.js +505 -49
- package/lib/guard-filename.js +8 -1
- package/lib/guard-html.js +10 -2
- package/lib/guard-list-unsubscribe.js +6 -1
- package/lib/guard-managesieve-command.js +24 -3
- package/lib/guard-smtp-command.js +20 -4
- package/lib/guard-svg.js +6 -1
- package/lib/http-client.js +17 -3
- package/lib/mail-agent.js +6 -4
- package/lib/mail-auth.js +59 -2
- package/lib/mail-server-imap.js +65 -34
- package/lib/mail-server-managesieve.js +50 -37
- package/lib/mail-server-mx.js +115 -34
- package/lib/mail-server-net.js +155 -1
- package/lib/mail-server-pop3.js +16 -19
- package/lib/mail-server-rate-limit.js +104 -6
- package/lib/mail-server-submission.js +162 -33
- package/lib/mail-server-tls.js +48 -3
- package/lib/mcp.js +11 -3
- package/lib/middleware/require-mtls.js +8 -1
- package/lib/network-tls.js +18 -0
- package/lib/safe-mount-info.js +39 -6
- package/lib/safe-smtp.js +96 -1
- package/lib/safe-url.js +8 -2
- package/lib/self-update.js +4 -1
- package/lib/vendor/MANIFEST.json +12 -12
- package/lib/vendor/blamejs-pki.cjs +396 -37
- package/lib/watcher.js +31 -6
- package/lib/ws-client.js +17 -2
- package/package.json +1 -1
- package/sbom.cdx.json +6 -6
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// @blamejs/pki v0.5.
|
|
1
|
+
// @blamejs/pki v0.5.31 — vendored (Apache-2.0). Zero-dep pure CJS.
|
|
2
2
|
// https://github.com/blamejs/pki Exports: x509, crl, pkcs12, key, webcrypto, schema, csr, cms, ...
|
|
3
3
|
// Backs lib/mtls-engine-default.js (PQC-capable CA + PKCS#12 engine).
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
@@ -141,7 +141,7 @@ var require_package = __commonJS({
|
|
|
141
141
|
"node_modules/@blamejs/pki/package.json"(exports2, module2) {
|
|
142
142
|
module2.exports = {
|
|
143
143
|
name: "@blamejs/pki",
|
|
144
|
-
version: "0.5.
|
|
144
|
+
version: "0.5.31",
|
|
145
145
|
description: "Pure-JavaScript PKI toolkit that owns its stack \u2014 X.509, ASN.1/DER, CMS, PQC-first.",
|
|
146
146
|
license: "Apache-2.0",
|
|
147
147
|
author: "blamejs contributors",
|
|
@@ -5756,6 +5756,7 @@ var require_asn1_der = __commonJS({
|
|
|
5756
5756
|
return _asBuffer(buf, "build.raw");
|
|
5757
5757
|
}
|
|
5758
5758
|
};
|
|
5759
|
+
intrinsic.freeze(build);
|
|
5759
5760
|
function _intContent(v, who) {
|
|
5760
5761
|
if (Buffer.isBuffer(v)) {
|
|
5761
5762
|
if (v.length === 0) throw new Asn1Error("asn1/bad-integer", who + ": INTEGER content is empty");
|
|
@@ -18413,7 +18414,10 @@ var require_sign_scheme = __commonJS({
|
|
|
18413
18414
|
}
|
|
18414
18415
|
function _assertKeyMatchesScheme(key, imp, E) {
|
|
18415
18416
|
var ka = key.algorithm || {};
|
|
18416
|
-
if (_toUpperCase(_String(ka.name)) !== _toUpperCase(_String(imp.name)))
|
|
18417
|
+
if (_toUpperCase(_String(ka.name)) !== _toUpperCase(_String(imp.name))) {
|
|
18418
|
+
var hint = _toUpperCase(_String(ka.name)) === "RSA-PSS" && _toUpperCase(_String(imp.name)) === "RSASSA-PKCS1-V1_5" ? "; this CryptoKey is bound to RSASSA-PSS -- pass opts.pss to sign with RSASSA-PSS" : "";
|
|
18419
|
+
throw E("bad-input", "the signer CryptoKey algorithm (" + ka.name + ") does not match the certificate's key algorithm (" + imp.name + ")" + hint);
|
|
18420
|
+
}
|
|
18417
18421
|
if (imp.hash && (!ka.hash || ka.hash.name !== imp.hash)) throw E("bad-input", "the signer CryptoKey hash (" + (ka.hash && ka.hash.name) + ") does not match the signing digest (" + imp.hash + ")");
|
|
18418
18422
|
if (imp.namedCurve && ka.namedCurve !== imp.namedCurve) throw E("bad-input", "the signer CryptoKey curve (" + ka.namedCurve + ") does not match the certificate curve (" + imp.namedCurve + ")");
|
|
18419
18423
|
}
|
|
@@ -18436,7 +18440,10 @@ var require_sign_scheme = __commonJS({
|
|
|
18436
18440
|
return { mldsa: _normPkcs8(key.mldsa, "the composite ML-DSA component key", E), trad: _normPkcs8(key.trad, "the composite traditional component key", E) };
|
|
18437
18441
|
}
|
|
18438
18442
|
function _importKey(key, imp, E) {
|
|
18439
|
-
if (key && typeof key === "object" && !_isBuffer(key) && !_isU8(key) && key.type === "
|
|
18443
|
+
if (key && typeof key === "object" && !_isBuffer(key) && !_isU8(key) && typeof key.type === "string" && key.algorithm != null) {
|
|
18444
|
+
if (key.type !== "private") {
|
|
18445
|
+
throw E("bad-input", "the signing key is a WebCrypto CryptoKey of type " + _stringify(key.type) + '; a signing key must be a private key (type "private")');
|
|
18446
|
+
}
|
|
18440
18447
|
_assertKeyMatchesScheme(key, imp, E);
|
|
18441
18448
|
return webcrypto.adoptKey(key, imp, ["sign"], E, "bad-input");
|
|
18442
18449
|
}
|
|
@@ -18452,7 +18459,9 @@ var require_sign_scheme = __commonJS({
|
|
|
18452
18459
|
throw E("bad-input", "the signer PEM private key could not be decoded", e);
|
|
18453
18460
|
}
|
|
18454
18461
|
owned = true;
|
|
18455
|
-
} else
|
|
18462
|
+
} else if (intrinsic.types.isKeyObject(key)) {
|
|
18463
|
+
throw E("bad-input", "the signing key is a node:crypto KeyObject, not a WebCrypto CryptoKey; pass a CryptoKey (e.g. from pki.key.generate) or export it to a PKCS#8 DER Buffer or PEM string");
|
|
18464
|
+
} else throw E("bad-input", "a signer key must be a WebCrypto CryptoKey, a PKCS#8 DER Buffer, or a PKCS#8 PEM string");
|
|
18456
18465
|
var imported = subtle.importKey("pkcs8", der, imp, false, ["sign"]);
|
|
18457
18466
|
if (!owned) return imported;
|
|
18458
18467
|
return imported.then(function(k) {
|
|
@@ -18492,35 +18501,101 @@ var require_sign_scheme = __commonJS({
|
|
|
18492
18501
|
var require_ip_utils = __commonJS({
|
|
18493
18502
|
"node_modules/@blamejs/pki/lib/ip-utils.js"(exports2, module2) {
|
|
18494
18503
|
"use strict";
|
|
18495
|
-
var
|
|
18504
|
+
var intrinsic = require_guard_intrinsic();
|
|
18505
|
+
var _slice = intrinsic.uncurry(String.prototype.slice);
|
|
18506
|
+
var _padStart = intrinsic.uncurry(String.prototype.padStart);
|
|
18507
|
+
var _charCodeAt = intrinsic.uncurry(String.prototype.charCodeAt);
|
|
18508
|
+
var _lastIndexOf = intrinsic.uncurry(String.prototype.lastIndexOf);
|
|
18509
|
+
var _toLowerCase = intrinsic.toLowerCase;
|
|
18510
|
+
var _indexOf = intrinsic.stringIndexOf;
|
|
18511
|
+
var _numToString = intrinsic.numberToString;
|
|
18512
|
+
var _bufferFrom = intrinsic.bufferFrom;
|
|
18513
|
+
var _bufferAlloc = intrinsic.bufferAlloc;
|
|
18514
|
+
var _defineProperty = intrinsic.defineProperty;
|
|
18515
|
+
var _Number = intrinsic.Number;
|
|
18516
|
+
function _push(arr, v) {
|
|
18517
|
+
_defineProperty(arr, arr.length, { value: v, writable: true, enumerable: true, configurable: true });
|
|
18518
|
+
}
|
|
18519
|
+
function _splitOn(str, sep) {
|
|
18520
|
+
var out = [], from = 0, at;
|
|
18521
|
+
while ((at = _indexOf(str, sep, from)) !== -1) {
|
|
18522
|
+
_push(out, _slice(str, from, at));
|
|
18523
|
+
from = at + sep.length;
|
|
18524
|
+
}
|
|
18525
|
+
_push(out, _slice(str, from));
|
|
18526
|
+
return out;
|
|
18527
|
+
}
|
|
18528
|
+
function _isDigitCode(c) {
|
|
18529
|
+
return c >= 48 && c <= 57;
|
|
18530
|
+
}
|
|
18531
|
+
function _isHexCode(c) {
|
|
18532
|
+
return c >= 48 && c <= 57 || c >= 97 && c <= 102 || c >= 65 && c <= 70;
|
|
18533
|
+
}
|
|
18534
|
+
function _isOctet(p) {
|
|
18535
|
+
var n = p.length, i, c;
|
|
18536
|
+
if (n < 1 || n > 3) return false;
|
|
18537
|
+
for (i = 0; i < n; i += 1) {
|
|
18538
|
+
c = _charCodeAt(p, i);
|
|
18539
|
+
if (!_isDigitCode(c)) return false;
|
|
18540
|
+
}
|
|
18541
|
+
if (n > 1 && _charCodeAt(p, 0) === 48) return false;
|
|
18542
|
+
return _Number(p) <= 255;
|
|
18543
|
+
}
|
|
18496
18544
|
function isIPv4(s) {
|
|
18497
|
-
|
|
18545
|
+
if (typeof s !== "string") return false;
|
|
18546
|
+
var parts = _splitOn(s, ".");
|
|
18547
|
+
if (parts.length !== 4) return false;
|
|
18548
|
+
for (var i = 0; i < 4; i += 1) {
|
|
18549
|
+
if (!_isOctet(parts[i])) return false;
|
|
18550
|
+
}
|
|
18551
|
+
return true;
|
|
18552
|
+
}
|
|
18553
|
+
function _isHexGroup(g) {
|
|
18554
|
+
var n = g.length, i;
|
|
18555
|
+
if (n < 1 || n > 4) return false;
|
|
18556
|
+
for (i = 0; i < n; i += 1) {
|
|
18557
|
+
if (!_isHexCode(_charCodeAt(g, i))) return false;
|
|
18558
|
+
}
|
|
18559
|
+
return true;
|
|
18560
|
+
}
|
|
18561
|
+
function _isDottedQuadShape(t) {
|
|
18562
|
+
var q = _splitOn(t, "."), i, p, j;
|
|
18563
|
+
if (q.length !== 4) return false;
|
|
18564
|
+
for (i = 0; i < 4; i += 1) {
|
|
18565
|
+
p = q[i];
|
|
18566
|
+
if (p.length < 1 || p.length > 3) return false;
|
|
18567
|
+
for (j = 0; j < p.length; j += 1) {
|
|
18568
|
+
if (!_isDigitCode(_charCodeAt(p, j))) return false;
|
|
18569
|
+
}
|
|
18570
|
+
}
|
|
18571
|
+
return true;
|
|
18498
18572
|
}
|
|
18499
18573
|
var IPV6_TEXT_MAX_LEN = 45;
|
|
18500
18574
|
function expandIpv6Hex(ip) {
|
|
18501
|
-
if (typeof ip !== "string" || ip.length > IPV6_TEXT_MAX_LEN || ip
|
|
18502
|
-
var
|
|
18503
|
-
|
|
18504
|
-
|
|
18505
|
-
|
|
18506
|
-
|
|
18507
|
-
|
|
18508
|
-
|
|
18575
|
+
if (typeof ip !== "string" || ip.length > IPV6_TEXT_MAX_LEN || _indexOf(ip, ":") === -1) return null;
|
|
18576
|
+
var lastColon = _lastIndexOf(ip, ":");
|
|
18577
|
+
var tail = _slice(ip, lastColon + 1);
|
|
18578
|
+
if (_indexOf(tail, ".") !== -1) {
|
|
18579
|
+
if (!_isDottedQuadShape(tail) || !isIPv4(tail)) return null;
|
|
18580
|
+
var q = _splitOn(tail, "."), o0 = _Number(q[0]), o1 = _Number(q[1]), o2 = _Number(q[2]), o3 = _Number(q[3]);
|
|
18581
|
+
ip = _slice(ip, 0, lastColon) + ":" + _numToString(o0 << 8 | o1, 16) + ":" + _numToString(o2 << 8 | o3, 16);
|
|
18582
|
+
}
|
|
18583
|
+
var dbl = _splitOn(ip, "::");
|
|
18509
18584
|
if (dbl.length > 2) return null;
|
|
18510
|
-
var left = dbl[0] === "" ? [] : dbl[0]
|
|
18511
|
-
var right = dbl.length === 2 ? dbl[1] === "" ? [] : dbl[1]
|
|
18585
|
+
var left = dbl[0] === "" ? [] : _splitOn(dbl[0], ":");
|
|
18586
|
+
var right = dbl.length === 2 ? dbl[1] === "" ? [] : _splitOn(dbl[1], ":") : [];
|
|
18512
18587
|
if (dbl.length === 1 && left.length !== 8) return null;
|
|
18513
18588
|
var fill = 8 - left.length - right.length;
|
|
18514
18589
|
if (dbl.length === 2 ? fill < 1 : fill !== 0) return null;
|
|
18515
18590
|
var groups = left, i;
|
|
18516
|
-
for (i = 0; i < fill; i += 1) groups
|
|
18517
|
-
|
|
18591
|
+
for (i = 0; i < fill; i += 1) _push(groups, "0");
|
|
18592
|
+
for (i = 0; i < right.length; i += 1) _push(groups, right[i]);
|
|
18518
18593
|
if (groups.length !== 8) return null;
|
|
18519
18594
|
var hex = "";
|
|
18520
18595
|
for (i = 0; i < 8; i += 1) {
|
|
18521
18596
|
var g = groups[i];
|
|
18522
|
-
if (
|
|
18523
|
-
hex += g
|
|
18597
|
+
if (!_isHexGroup(g)) return null;
|
|
18598
|
+
hex += _padStart(_toLowerCase(g), 4, "0");
|
|
18524
18599
|
}
|
|
18525
18600
|
return hex;
|
|
18526
18601
|
}
|
|
@@ -18528,11 +18603,15 @@ var require_ip_utils = __commonJS({
|
|
|
18528
18603
|
return isIPv4(s) || expandIpv6Hex(s) !== null;
|
|
18529
18604
|
}
|
|
18530
18605
|
function packIpLiteral(s) {
|
|
18531
|
-
if (isIPv4(s))
|
|
18606
|
+
if (isIPv4(s)) {
|
|
18607
|
+
var parts = _splitOn(s, "."), buf = _bufferAlloc(4), i;
|
|
18608
|
+
for (i = 0; i < 4; i += 1) buf[i] = _Number(parts[i]);
|
|
18609
|
+
return buf;
|
|
18610
|
+
}
|
|
18532
18611
|
var hex = expandIpv6Hex(s);
|
|
18533
|
-
return hex === null ? null :
|
|
18612
|
+
return hex === null ? null : _bufferFrom(hex, "hex");
|
|
18534
18613
|
}
|
|
18535
|
-
module2.exports = { isIPv4, expandIpv6Hex, isIpLiteral, packIpLiteral
|
|
18614
|
+
module2.exports = { isIPv4, expandIpv6Hex, isIpLiteral, packIpLiteral };
|
|
18536
18615
|
}
|
|
18537
18616
|
});
|
|
18538
18617
|
|
|
@@ -18550,10 +18629,275 @@ var require_pki_build = __commonJS({
|
|
|
18550
18629
|
var _bufferEquals = intrinsic.bufferEquals;
|
|
18551
18630
|
var oid = require_oid();
|
|
18552
18631
|
var ipUtils = require_ip_utils();
|
|
18632
|
+
var _packIpLiteral = ipUtils.packIpLiteral;
|
|
18553
18633
|
var nodeCrypto = require("crypto");
|
|
18554
18634
|
var _keyEquals = intrinsic.uncurry(nodeCrypto.KeyObject.prototype.equals);
|
|
18635
|
+
var _charCodeAt = intrinsic.uncurry(String.prototype.charCodeAt);
|
|
18636
|
+
var _stringIndexOf = intrinsic.stringIndexOf;
|
|
18637
|
+
var _stringLastIndexOf = intrinsic.uncurry(String.prototype.lastIndexOf);
|
|
18638
|
+
var _sliceStr = intrinsic.uncurry(String.prototype.slice);
|
|
18639
|
+
var _String = intrinsic.String;
|
|
18640
|
+
var _objectKeys = intrinsic.keys;
|
|
18641
|
+
var _isBufferChk = intrinsic.isBuffer;
|
|
18642
|
+
var _stringify = intrinsic.stringify;
|
|
18643
|
+
function _isAlphaCode(c) {
|
|
18644
|
+
return c >= 65 && c <= 90 || c >= 97 && c <= 122;
|
|
18645
|
+
}
|
|
18646
|
+
function _isDigitCode(c) {
|
|
18647
|
+
return c >= 48 && c <= 57;
|
|
18648
|
+
}
|
|
18649
|
+
function _isHexCode(c) {
|
|
18650
|
+
return c >= 48 && c <= 57 || c >= 97 && c <= 102 || c >= 65 && c <= 70;
|
|
18651
|
+
}
|
|
18652
|
+
function _isUnreserved(c) {
|
|
18653
|
+
return _isAlphaCode(c) || _isDigitCode(c) || c === 45 || c === 46 || c === 95 || c === 126;
|
|
18654
|
+
}
|
|
18655
|
+
function _isSubDelim(c) {
|
|
18656
|
+
switch (c) {
|
|
18657
|
+
case 33:
|
|
18658
|
+
case 36:
|
|
18659
|
+
case 38:
|
|
18660
|
+
case 39:
|
|
18661
|
+
case 40:
|
|
18662
|
+
case 41:
|
|
18663
|
+
case 42:
|
|
18664
|
+
case 43:
|
|
18665
|
+
case 44:
|
|
18666
|
+
case 59:
|
|
18667
|
+
case 61:
|
|
18668
|
+
return true;
|
|
18669
|
+
default:
|
|
18670
|
+
return false;
|
|
18671
|
+
}
|
|
18672
|
+
}
|
|
18673
|
+
function _isUserinfoByte(c) {
|
|
18674
|
+
return _isUnreserved(c) || _isSubDelim(c) || c === 58;
|
|
18675
|
+
}
|
|
18676
|
+
function _isUriByte(c) {
|
|
18677
|
+
return _isUnreserved(c) || _isSubDelim(c) || c === 58 || c === 47 || c === 63 || c === 35 || c === 64;
|
|
18678
|
+
}
|
|
18679
|
+
function _isAtextByte(c) {
|
|
18680
|
+
if (_isAlphaCode(c) || _isDigitCode(c)) return true;
|
|
18681
|
+
switch (c) {
|
|
18682
|
+
case 33:
|
|
18683
|
+
case 35:
|
|
18684
|
+
case 36:
|
|
18685
|
+
case 37:
|
|
18686
|
+
case 38:
|
|
18687
|
+
case 39:
|
|
18688
|
+
// ! # $ % & '
|
|
18689
|
+
case 42:
|
|
18690
|
+
case 43:
|
|
18691
|
+
case 45:
|
|
18692
|
+
case 47:
|
|
18693
|
+
case 61:
|
|
18694
|
+
case 63:
|
|
18695
|
+
// * + - / = ?
|
|
18696
|
+
case 94:
|
|
18697
|
+
case 95:
|
|
18698
|
+
case 96:
|
|
18699
|
+
case 123:
|
|
18700
|
+
case 124:
|
|
18701
|
+
case 125:
|
|
18702
|
+
case 126:
|
|
18703
|
+
return true;
|
|
18704
|
+
default:
|
|
18705
|
+
return false;
|
|
18706
|
+
}
|
|
18707
|
+
}
|
|
18708
|
+
function _looksLikeIPv4Shape(s) {
|
|
18709
|
+
var n = s.length, i, c, sawDot = false, atomEmpty = true;
|
|
18710
|
+
if (n === 0) return false;
|
|
18711
|
+
for (i = 0; i < n; i += 1) {
|
|
18712
|
+
c = _charCodeAt(s, i);
|
|
18713
|
+
if (c === 46) {
|
|
18714
|
+
if (atomEmpty) return false;
|
|
18715
|
+
sawDot = true;
|
|
18716
|
+
atomEmpty = true;
|
|
18717
|
+
} else if (_isDigitCode(c)) {
|
|
18718
|
+
atomEmpty = false;
|
|
18719
|
+
} else return false;
|
|
18720
|
+
}
|
|
18721
|
+
return sawDot && !atomEmpty;
|
|
18722
|
+
}
|
|
18723
|
+
function _componentBytesOk(s, from, to, byteOk) {
|
|
18724
|
+
var i = from, c;
|
|
18725
|
+
while (i < to) {
|
|
18726
|
+
c = _charCodeAt(s, i);
|
|
18727
|
+
if (c === 37) {
|
|
18728
|
+
if (i + 2 >= to || !_isHexCode(_charCodeAt(s, i + 1)) || !_isHexCode(_charCodeAt(s, i + 2))) return false;
|
|
18729
|
+
i += 3;
|
|
18730
|
+
} else if (byteOk(c)) {
|
|
18731
|
+
i += 1;
|
|
18732
|
+
} else return false;
|
|
18733
|
+
}
|
|
18734
|
+
return true;
|
|
18735
|
+
}
|
|
18736
|
+
function _validUriHost(s, from, to) {
|
|
18737
|
+
if (to <= from) return false;
|
|
18738
|
+
var host = _sliceStr(s, from, to), len = host.length;
|
|
18739
|
+
if (_looksLikeIPv4Shape(host)) return _packIpLiteral(host) !== null;
|
|
18740
|
+
var end = _charCodeAt(host, len - 1) === 46 ? len - 1 : len;
|
|
18741
|
+
if (end > 253) return false;
|
|
18742
|
+
var firstDot = _stringIndexOf(host, ".", 0);
|
|
18743
|
+
if (firstDot === -1 || firstDot >= end) return false;
|
|
18744
|
+
return _labelsValid(host, 0, len, _isHostLabelRange, true);
|
|
18745
|
+
}
|
|
18746
|
+
function _validUriAuthority(s, from, to) {
|
|
18747
|
+
var i, c, at = -1;
|
|
18748
|
+
for (i = from; i < to; i += 1) {
|
|
18749
|
+
c = _charCodeAt(s, i);
|
|
18750
|
+
if (c === 64) {
|
|
18751
|
+
if (at !== -1) return false;
|
|
18752
|
+
at = i;
|
|
18753
|
+
}
|
|
18754
|
+
}
|
|
18755
|
+
var hostStart = at === -1 ? from : at + 1;
|
|
18756
|
+
if (at !== -1 && !_componentBytesOk(s, from, at, _isUserinfoByte)) return false;
|
|
18757
|
+
var colon = -1;
|
|
18758
|
+
for (i = hostStart; i < to; i += 1) {
|
|
18759
|
+
if (_charCodeAt(s, i) === 58) {
|
|
18760
|
+
colon = i;
|
|
18761
|
+
break;
|
|
18762
|
+
}
|
|
18763
|
+
}
|
|
18764
|
+
var hostEnd = colon === -1 ? to : colon;
|
|
18765
|
+
if (!_validUriHost(s, hostStart, hostEnd)) return false;
|
|
18766
|
+
if (colon !== -1) {
|
|
18767
|
+
for (i = colon + 1; i < to; i += 1) {
|
|
18768
|
+
if (!_isDigitCode(_charCodeAt(s, i))) return false;
|
|
18769
|
+
}
|
|
18770
|
+
}
|
|
18771
|
+
return true;
|
|
18772
|
+
}
|
|
18773
|
+
function _looksLikeUri(s) {
|
|
18774
|
+
var n = s.length, i, c;
|
|
18775
|
+
if (n === 0 || !_isAlphaCode(_charCodeAt(s, 0))) return false;
|
|
18776
|
+
i = 1;
|
|
18777
|
+
while (i < n) {
|
|
18778
|
+
c = _charCodeAt(s, i);
|
|
18779
|
+
if (_isAlphaCode(c) || _isDigitCode(c) || c === 43 || c === 45 || c === 46) i += 1;
|
|
18780
|
+
else break;
|
|
18781
|
+
}
|
|
18782
|
+
if (i + 3 > n || _charCodeAt(s, i) !== 58 || _charCodeAt(s, i + 1) !== 47 || _charCodeAt(s, i + 2) !== 47) return false;
|
|
18783
|
+
i += 3;
|
|
18784
|
+
var authStart = i, authEnd = n;
|
|
18785
|
+
for (; i < n; i += 1) {
|
|
18786
|
+
c = _charCodeAt(s, i);
|
|
18787
|
+
if (c === 47 || c === 63 || c === 35) {
|
|
18788
|
+
authEnd = i;
|
|
18789
|
+
break;
|
|
18790
|
+
}
|
|
18791
|
+
}
|
|
18792
|
+
if (authEnd === authStart) return false;
|
|
18793
|
+
if (!_validUriAuthority(s, authStart, authEnd)) return false;
|
|
18794
|
+
var sawHash = false;
|
|
18795
|
+
i = authEnd;
|
|
18796
|
+
while (i < n) {
|
|
18797
|
+
c = _charCodeAt(s, i);
|
|
18798
|
+
if (c === 37) {
|
|
18799
|
+
if (i + 2 >= n || !_isHexCode(_charCodeAt(s, i + 1)) || !_isHexCode(_charCodeAt(s, i + 2))) return false;
|
|
18800
|
+
i += 3;
|
|
18801
|
+
continue;
|
|
18802
|
+
}
|
|
18803
|
+
if (c === 35) {
|
|
18804
|
+
if (sawHash) return false;
|
|
18805
|
+
sawHash = true;
|
|
18806
|
+
}
|
|
18807
|
+
if (!_isUriByte(c)) return false;
|
|
18808
|
+
i += 1;
|
|
18809
|
+
}
|
|
18810
|
+
return true;
|
|
18811
|
+
}
|
|
18812
|
+
function _isDnsLabelRange(s, from, to) {
|
|
18813
|
+
var len = to - from, i, c;
|
|
18814
|
+
if (len < 1 || len > 63) return false;
|
|
18815
|
+
for (i = from; i < to; i += 1) {
|
|
18816
|
+
c = _charCodeAt(s, i);
|
|
18817
|
+
if (_isAlphaCode(c) || _isDigitCode(c)) continue;
|
|
18818
|
+
if (i === to - 1) return false;
|
|
18819
|
+
if (c === 95) continue;
|
|
18820
|
+
if (c === 45 && i !== from) continue;
|
|
18821
|
+
return false;
|
|
18822
|
+
}
|
|
18823
|
+
return true;
|
|
18824
|
+
}
|
|
18825
|
+
function _isHostLabelRange(s, from, to) {
|
|
18826
|
+
var len = to - from, i, c, edge;
|
|
18827
|
+
if (len < 1 || len > 63) return false;
|
|
18828
|
+
for (i = from; i < to; i += 1) {
|
|
18829
|
+
c = _charCodeAt(s, i);
|
|
18830
|
+
edge = i === from || i === to - 1;
|
|
18831
|
+
if (_isAlphaCode(c) || _isDigitCode(c)) continue;
|
|
18832
|
+
if (c === 45 && !edge) continue;
|
|
18833
|
+
return false;
|
|
18834
|
+
}
|
|
18835
|
+
return true;
|
|
18836
|
+
}
|
|
18837
|
+
function _labelsValid(s, from, to, labelFn, allowRootDot) {
|
|
18838
|
+
if (allowRootDot && to - from >= 1 && _charCodeAt(s, to - 1) === 46) to -= 1;
|
|
18839
|
+
if (to <= from) return false;
|
|
18840
|
+
var start = from, dot;
|
|
18841
|
+
for (; ; ) {
|
|
18842
|
+
dot = _stringIndexOf(s, ".", start);
|
|
18843
|
+
var end = dot === -1 || dot >= to ? to : dot;
|
|
18844
|
+
if (!labelFn(s, start, end)) return false;
|
|
18845
|
+
if (end === to) return true;
|
|
18846
|
+
start = end + 1;
|
|
18847
|
+
}
|
|
18848
|
+
}
|
|
18849
|
+
function _looksLikeDnsName(s) {
|
|
18850
|
+
var n = s.length, start = 0;
|
|
18851
|
+
if (n < 1) return false;
|
|
18852
|
+
var end = _charCodeAt(s, n - 1) === 46 ? n - 1 : n;
|
|
18853
|
+
if (end < 1 || end > 253) return false;
|
|
18854
|
+
if (end >= 2 && _charCodeAt(s, 0) === 42 && _charCodeAt(s, 1) === 46) start = 2;
|
|
18855
|
+
if (start >= end) return false;
|
|
18856
|
+
return _labelsValid(s, start, n, _isDnsLabelRange, true);
|
|
18857
|
+
}
|
|
18858
|
+
function _looksLikeEmail(s) {
|
|
18859
|
+
if (s.length > 254) return false;
|
|
18860
|
+
var at = _stringIndexOf(s, "@", 0);
|
|
18861
|
+
if (at < 1 || at > 64 || _stringLastIndexOf(s, "@") !== at) return false;
|
|
18862
|
+
var i, c, atomEmpty = true;
|
|
18863
|
+
for (i = 0; i < at; i += 1) {
|
|
18864
|
+
c = _charCodeAt(s, i);
|
|
18865
|
+
if (c === 46) {
|
|
18866
|
+
if (atomEmpty) return false;
|
|
18867
|
+
atomEmpty = true;
|
|
18868
|
+
} else if (_isAtextByte(c)) {
|
|
18869
|
+
atomEmpty = false;
|
|
18870
|
+
} else return false;
|
|
18871
|
+
}
|
|
18872
|
+
if (atomEmpty) return false;
|
|
18873
|
+
var dStart = at + 1, dLen = s.length - dStart;
|
|
18874
|
+
if (dLen < 1 || dLen > 253 || _stringIndexOf(s, ".", dStart) === -1) return false;
|
|
18875
|
+
return _labelsValid(s, dStart, s.length, _isHostLabelRange, false);
|
|
18876
|
+
}
|
|
18877
|
+
function _isDottedOid(s) {
|
|
18878
|
+
var n = s.length, i, c, d0, arcs = 0;
|
|
18879
|
+
if (n < 3) return false;
|
|
18880
|
+
c = _charCodeAt(s, 0);
|
|
18881
|
+
if (c < 48 || c > 50) return false;
|
|
18882
|
+
i = 1;
|
|
18883
|
+
while (i < n) {
|
|
18884
|
+
if (_charCodeAt(s, i) !== 46) return false;
|
|
18885
|
+
i += 1;
|
|
18886
|
+
if (i >= n) return false;
|
|
18887
|
+
d0 = _charCodeAt(s, i);
|
|
18888
|
+
if (d0 === 48) {
|
|
18889
|
+
i += 1;
|
|
18890
|
+
} else if (d0 >= 49 && d0 <= 57) {
|
|
18891
|
+
i += 1;
|
|
18892
|
+
while (i < n && _isDigitCode(_charCodeAt(s, i))) i += 1;
|
|
18893
|
+
} else {
|
|
18894
|
+
return false;
|
|
18895
|
+
}
|
|
18896
|
+
arcs += 1;
|
|
18897
|
+
}
|
|
18898
|
+
return arcs >= 1;
|
|
18899
|
+
}
|
|
18555
18900
|
var b = asn1.build;
|
|
18556
|
-
var DOTTED_OID_RE = /^[0-2](?:\.(?:0|[1-9]\d*))+$/;
|
|
18557
18901
|
var KU_BIT = {
|
|
18558
18902
|
digitalSignature: 0,
|
|
18559
18903
|
nonRepudiation: 1,
|
|
@@ -18639,15 +18983,30 @@ var require_pki_build = __commonJS({
|
|
|
18639
18983
|
return asn1.decode(nameDer).children.length === 0;
|
|
18640
18984
|
}
|
|
18641
18985
|
function ia5Content(s) {
|
|
18642
|
-
s =
|
|
18986
|
+
s = _String(s);
|
|
18643
18987
|
for (var i = 0; i < s.length; i++) {
|
|
18644
|
-
if (s
|
|
18988
|
+
if (_charCodeAt(s, i) > 127) throw E("bad-input", "value requires 7-bit ASCII (IA5String): " + _stringify(s));
|
|
18645
18989
|
}
|
|
18646
|
-
return
|
|
18990
|
+
return _bufferFrom(s, "latin1");
|
|
18991
|
+
}
|
|
18992
|
+
function _classifyBareGeneralName(s) {
|
|
18993
|
+
if (_packIpLiteral(s) !== null) return { iPAddress: s };
|
|
18994
|
+
if (_looksLikeIPv4Shape(s)) {
|
|
18995
|
+
throw E("bad-input", "the bare GeneralName string " + _stringify(s) + " looks like an IPv4 address but is not a valid one; pass { iPAddress: ... } for an address or { dNSName: ... } for a name");
|
|
18996
|
+
}
|
|
18997
|
+
if (_looksLikeUri(s)) return { uniformResourceIdentifier: s };
|
|
18998
|
+
if (_looksLikeEmail(s)) return { rfc822Name: s };
|
|
18999
|
+
if (_looksLikeDnsName(s)) return { dNSName: s };
|
|
19000
|
+
var _qs = _stringify(s);
|
|
19001
|
+
throw E("bad-input", "cannot classify the bare GeneralName string " + _qs + " as a dNSName, rfc822Name, iPAddress, or URI; pass an explicit form object, e.g. { dNSName: " + _qs + " }");
|
|
18647
19002
|
}
|
|
18648
19003
|
function encodeGeneralName(entry) {
|
|
18649
|
-
if (
|
|
18650
|
-
|
|
19004
|
+
if (typeof entry === "string") {
|
|
19005
|
+
if (entry === "") throw E("bad-input", "an empty GeneralName value is not permitted (RFC 5280 sec. 4.2.1.6)");
|
|
19006
|
+
entry = _classifyBareGeneralName(entry);
|
|
19007
|
+
}
|
|
19008
|
+
if (!entry || typeof entry !== "object" || _isBufferChk(entry)) throw E("bad-input", "a GeneralName must be an object with exactly one name form");
|
|
19009
|
+
var keys = _objectKeys(entry);
|
|
18651
19010
|
if (keys.length !== 1) throw E("bad-input", "a GeneralName entry must have exactly one form, got " + keys.length);
|
|
18652
19011
|
var k = keys[0], v = entry[k];
|
|
18653
19012
|
if (v == null || v === "") throw E("bad-input", "an empty GeneralName value is not permitted (RFC 5280 sec. 4.2.1.6)");
|
|
@@ -18662,10 +19021,10 @@ var require_pki_build = __commonJS({
|
|
|
18662
19021
|
case "iPAddress":
|
|
18663
19022
|
var ipBuf = v;
|
|
18664
19023
|
if (typeof v === "string") {
|
|
18665
|
-
ipBuf =
|
|
18666
|
-
if (ipBuf === null) throw E("bad-input", "iPAddress string is not a valid IPv4 or IPv6 literal: " +
|
|
19024
|
+
ipBuf = _packIpLiteral(v);
|
|
19025
|
+
if (ipBuf === null) throw E("bad-input", "iPAddress string is not a valid IPv4 or IPv6 literal: " + _stringify(v));
|
|
18667
19026
|
}
|
|
18668
|
-
if (!
|
|
19027
|
+
if (!_isBufferChk(ipBuf) || ipBuf.length !== 4 && ipBuf.length !== 16) throw E("bad-input", "iPAddress must be a 4- or 16-octet Buffer or an IPv4/IPv6 string");
|
|
18669
19028
|
return b.contextPrimitive(7, ipBuf);
|
|
18670
19029
|
case "directoryName":
|
|
18671
19030
|
return b.explicit(4, encodeName(v));
|
|
@@ -18700,7 +19059,7 @@ var require_pki_build = __commonJS({
|
|
|
18700
19059
|
function _resolveOid(n, label) {
|
|
18701
19060
|
var dotted = O(n);
|
|
18702
19061
|
if (dotted != null) return dotted;
|
|
18703
|
-
if (typeof n === "string" &&
|
|
19062
|
+
if (typeof n === "string" && _isDottedOid(n)) {
|
|
18704
19063
|
try {
|
|
18705
19064
|
b.oid(n);
|
|
18706
19065
|
} catch (e) {
|
|
@@ -30696,7 +31055,7 @@ var require_x509_sign = __commonJS({
|
|
|
30696
31055
|
}
|
|
30697
31056
|
);
|
|
30698
31057
|
guard.identifier.assertKnownKeys(opts, KNOWN_SIGN_OPTS, _err, "x509/bad-input", "pki.x509.sign has an unknown option ");
|
|
30699
|
-
if (issuer.key == null) throw _err("x509/bad-input", "a signing key (issuer.key, a PKCS#8 private key) is required");
|
|
31058
|
+
if (issuer.key == null) throw _err("x509/bad-input", "a signing key (issuer.key, a WebCrypto CryptoKey or a PKCS#8 private key DER/PEM) is required");
|
|
30700
31059
|
var spki = _reqDer(spec.subjectPublicKey, "spec.subjectPublicKey (the SPKI DER of the certified key)");
|
|
30701
31060
|
_assertValidSpki(spki, "spec.subjectPublicKey");
|
|
30702
31061
|
var subjectDer = _encodeName(spec.subject == null ? [] : spec.subject);
|
|
@@ -31308,7 +31667,7 @@ var require_attrcert_sign = __commonJS({
|
|
|
31308
31667
|
if (!spec || typeof spec !== "object" || Buffer.isBuffer(spec)) throw _err("attrcert/bad-input", "the attribute-certificate spec must be an object");
|
|
31309
31668
|
guard.identifier.assertKnownKeys(spec, KNOWN_SPEC_KEYS, _err, "attrcert/bad-input", "unknown spec field ");
|
|
31310
31669
|
issuer = issuer || {};
|
|
31311
|
-
if (issuer.key == null) throw _err("attrcert/bad-input", "a signing key (issuer.key, the AA's PKCS#8 private key) is required");
|
|
31670
|
+
if (issuer.key == null) throw _err("attrcert/bad-input", "a signing key (issuer.key, the AA's WebCrypto CryptoKey or PKCS#8 private key DER/PEM) is required");
|
|
31312
31671
|
var issuerDnSpec, aaSpki;
|
|
31313
31672
|
if (issuer.cert != null) {
|
|
31314
31673
|
var aaCert = _parseCert(issuer.cert, "issuer.cert");
|
|
@@ -32026,7 +32385,7 @@ var require_crl_sign = __commonJS({
|
|
|
32026
32385
|
}
|
|
32027
32386
|
);
|
|
32028
32387
|
guard.identifier.assertKnownKeys(opts, KNOWN_SIGN_OPTS, _err, "crl/bad-input", "pki.crl.sign has an unknown option ");
|
|
32029
|
-
if (issuer.key == null) throw _err("crl/bad-input", "a signing key (issuer.key, a PKCS#8 private key) is required");
|
|
32388
|
+
if (issuer.key == null) throw _err("crl/bad-input", "a signing key (issuer.key, a WebCrypto CryptoKey or a PKCS#8 private key DER/PEM) is required");
|
|
32030
32389
|
var issuerDer, issuerSpki, issuerCert = null;
|
|
32031
32390
|
if (byCert) {
|
|
32032
32391
|
issuerCert = _parseIssuerCert(issuer.cert);
|
package/lib/watcher.js
CHANGED
|
@@ -231,7 +231,7 @@ var AUTO_PROBE_POLL_FSTYPES = new Set([
|
|
|
231
231
|
"vboxsf",
|
|
232
232
|
]);
|
|
233
233
|
|
|
234
|
-
function _detectAutoMode(rootPath) {
|
|
234
|
+
function _detectAutoMode(rootPath, probe) {
|
|
235
235
|
// Sync probe — looks at the kernel's view of the mount carrying the
|
|
236
236
|
// watcher's root and decides whether fs.watch will deliver events.
|
|
237
237
|
// Three signals contribute, in priority order:
|
|
@@ -246,7 +246,21 @@ function _detectAutoMode(rootPath) {
|
|
|
246
246
|
// 3. Otherwise — fs.
|
|
247
247
|
//
|
|
248
248
|
// Returns { mode, reason, fsType, inContainer }.
|
|
249
|
-
|
|
249
|
+
// Injectable so the branches that only exist on a restricted Linux can be
|
|
250
|
+
// driven from any host. A rule about what happens when mountinfo cannot be
|
|
251
|
+
// read is untestable while reaching it requires unmounting /proc.
|
|
252
|
+
var platform = (probe && probe.platform) || process.platform;
|
|
253
|
+
var readEntries = (probe && probe.readEntries) ||
|
|
254
|
+
function () { return safeMountInfo.read(); };
|
|
255
|
+
// Injected for the same reason as readEntries, and for one more: "/.dockerenv"
|
|
256
|
+
// is drive-relative on Windows, so a direct probe there asks about C:\.dockerenv
|
|
257
|
+
// rather than about being in a container. It is only reached below the
|
|
258
|
+
// non-Linux return, but reaching a POSIX path through the injected reader is
|
|
259
|
+
// what keeps that ordering from being the only thing holding it up.
|
|
260
|
+
var exists = (probe && probe.exists) ||
|
|
261
|
+
function (p) { return nodeFs.existsSync(p); };
|
|
262
|
+
|
|
263
|
+
if (platform !== "linux") {
|
|
250
264
|
// macOS + Windows fs.watch backends use FSEvents + ReadDirectoryChangesW
|
|
251
265
|
// respectively, which DO deliver recursive events natively for
|
|
252
266
|
// operator-owned local filesystems. Containerized Linux is the
|
|
@@ -255,7 +269,7 @@ function _detectAutoMode(rootPath) {
|
|
|
255
269
|
}
|
|
256
270
|
|
|
257
271
|
var inContainer = false;
|
|
258
|
-
try { inContainer =
|
|
272
|
+
try { inContainer = exists("/.dockerenv"); }
|
|
259
273
|
catch (_e) { inContainer = false; }
|
|
260
274
|
|
|
261
275
|
// Route through b.safeMountInfo — single canonical parser that
|
|
@@ -263,13 +277,23 @@ function _detectAutoMode(rootPath) {
|
|
|
263
277
|
// mount check below. Pre-v0.11.6 this parsed inline; centralizing
|
|
264
278
|
// it means future container-escape / sealed-store / sandbox call
|
|
265
279
|
// sites inherit the discipline.
|
|
266
|
-
var entries =
|
|
280
|
+
var entries = readEntries();
|
|
281
|
+
// Not knowing which filesystem this is resolves toward polling, not toward
|
|
282
|
+
// fs.watch. On Linux mountinfo is always there, so failing to read it means
|
|
283
|
+
// /proc is unmounted or restricted — which is the containerized case this
|
|
284
|
+
// probe exists for, and the one where inotify is least likely to deliver.
|
|
285
|
+
// The two answers are not symmetric: polling costs stat calls the operator
|
|
286
|
+
// can see, while fs.watch on a filesystem that does not chain inotify drops
|
|
287
|
+
// events silently and nothing downstream can tell that it did.
|
|
267
288
|
if (entries === null || entries.length === 0) {
|
|
268
|
-
return { mode: "
|
|
289
|
+
return { mode: "poll", reason: "no-mountinfo", fsType: null, inContainer: inContainer };
|
|
269
290
|
}
|
|
270
291
|
var bestMatch = safeMountInfo.bestMatch(entries, rootPath);
|
|
271
292
|
if (!bestMatch) {
|
|
272
|
-
|
|
293
|
+
// Same reasoning: "/" matches every path on a healthy Linux, so no match
|
|
294
|
+
// means the mount table did not describe this root and its fstype is
|
|
295
|
+
// unknown rather than known-good.
|
|
296
|
+
return { mode: "poll", reason: "no-mount-match", fsType: null, inContainer: inContainer };
|
|
273
297
|
}
|
|
274
298
|
if (AUTO_PROBE_POLL_FSTYPES.has(bestMatch.fstype)) {
|
|
275
299
|
return {
|
|
@@ -687,4 +711,5 @@ module.exports = {
|
|
|
687
711
|
// create() enforces, instead of pinning hand-copied mirror constants.
|
|
688
712
|
MAX_IGNORE_PATTERN_LEN: MAX_IGNORE_PATTERN_LEN,
|
|
689
713
|
MAX_IGNORE_STAR_COUNT: MAX_IGNORE_STAR_COUNT,
|
|
714
|
+
_detectAutoModeForTest: _detectAutoMode,
|
|
690
715
|
};
|
package/lib/ws-client.js
CHANGED
|
@@ -361,7 +361,12 @@ class WsClient extends EventEmitter {
|
|
|
361
361
|
allowInternal: opts.allowInternal,
|
|
362
362
|
errorClass: WsClientError,
|
|
363
363
|
});
|
|
364
|
-
|
|
364
|
+
// `null` when the gate produced no pin at all, the array when it did —
|
|
365
|
+
// including an EMPTY one. An empty pin means the gate admitted no address,
|
|
366
|
+
// so there is nothing to connect to; treating it as "no pin" would hand the
|
|
367
|
+
// connect back to the ordinary resolver and re-open the rebinding window
|
|
368
|
+
// the pin exists to close.
|
|
369
|
+
this._ssrfPinnedIps = probe && Array.isArray(probe.ips) ? probe.ips : null;
|
|
365
370
|
this._dialParsed = dialParsed;
|
|
366
371
|
this._dialTlsOpts = dialTlsOpts;
|
|
367
372
|
}
|
|
@@ -405,12 +410,22 @@ class WsClient extends EventEmitter {
|
|
|
405
410
|
// private one between the check and the connect.
|
|
406
411
|
var pinnedIps = self._ssrfPinnedIps || null;
|
|
407
412
|
var lookup = null;
|
|
408
|
-
if (pinnedIps
|
|
413
|
+
if (pinnedIps) {
|
|
409
414
|
lookup = function (h, lookupOpts, cb) {
|
|
410
415
|
// Node's lookup callback signatures:
|
|
411
416
|
// (err, address, family) for legacy { all: false } (default)
|
|
412
417
|
// (err, addresses) for { all: true }
|
|
413
418
|
if (typeof lookupOpts === "function") { cb = lookupOpts; lookupOpts = {}; }
|
|
419
|
+
// An empty pin admits no address, so there is nothing to connect to.
|
|
420
|
+
// Answer the lookup with an error, which fails the dial through the
|
|
421
|
+
// socket's ordinary error path — reading `pinnedIps[0].address` here
|
|
422
|
+
// would throw a TypeError out of a lookup callback instead, which is a
|
|
423
|
+
// crash rather than a refusal.
|
|
424
|
+
if (pinnedIps.length === 0) {
|
|
425
|
+
var noneErr = new Error("ws.connect: the SSRF gate admitted no address for " + h);
|
|
426
|
+
noneErr.code = "ENOTFOUND";
|
|
427
|
+
return cb(noneErr);
|
|
428
|
+
}
|
|
414
429
|
var first = pinnedIps[0];
|
|
415
430
|
if (lookupOpts && lookupOpts.all) {
|
|
416
431
|
return cb(null, pinnedIps.map(function (ip) {
|