@zero-transfer/ssh 0.4.6 → 0.4.8
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 +0 -2
- package/dist/index.cjs +405 -164
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +229 -25
- package/dist/index.d.ts +229 -25
- package/dist/index.mjs +402 -164
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,68 @@
|
|
|
1
1
|
// src/client/ZeroTransfer.ts
|
|
2
2
|
import { EventEmitter } from "events";
|
|
3
3
|
|
|
4
|
+
// src/logging/redaction.ts
|
|
5
|
+
var REDACTED = "[REDACTED]";
|
|
6
|
+
var SENSITIVE_KEY_PATTERN = /(?:password|passphrase|privatekey|token|secret|username|user)$/i;
|
|
7
|
+
var SECRET_COMMAND_PATTERN = /^(PASS|USER|ACCT)\s+(.+)$/i;
|
|
8
|
+
var URL_KEY_PATTERN = /(?:url|uri|href)$/i;
|
|
9
|
+
function isSensitiveKey(key) {
|
|
10
|
+
return SENSITIVE_KEY_PATTERN.test(key.replace(/[_-]/g, ""));
|
|
11
|
+
}
|
|
12
|
+
function redactCommand(command) {
|
|
13
|
+
return command.replace(SECRET_COMMAND_PATTERN, (_fullMatch, commandName) => {
|
|
14
|
+
return `${commandName.toUpperCase()} ${REDACTED}`;
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
function redactValue(value) {
|
|
18
|
+
if (typeof value === "string") {
|
|
19
|
+
return redactCommand(value);
|
|
20
|
+
}
|
|
21
|
+
if (Array.isArray(value)) {
|
|
22
|
+
return value.map((item) => redactValue(item));
|
|
23
|
+
}
|
|
24
|
+
if (value !== null && typeof value === "object") {
|
|
25
|
+
return redactObject(value);
|
|
26
|
+
}
|
|
27
|
+
return value;
|
|
28
|
+
}
|
|
29
|
+
function redactObject(input) {
|
|
30
|
+
return Object.fromEntries(
|
|
31
|
+
Object.entries(input).map(([key, value]) => {
|
|
32
|
+
if (isSensitiveKey(key)) {
|
|
33
|
+
return [key, REDACTED];
|
|
34
|
+
}
|
|
35
|
+
if (URL_KEY_PATTERN.test(key) && typeof value === "string") {
|
|
36
|
+
return [key, redactUrlForLogging(value)];
|
|
37
|
+
}
|
|
38
|
+
return [key, redactValue(value)];
|
|
39
|
+
})
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
function redactUrlForLogging(url) {
|
|
43
|
+
let parsed;
|
|
44
|
+
try {
|
|
45
|
+
parsed = typeof url === "string" ? new URL(url) : url;
|
|
46
|
+
} catch {
|
|
47
|
+
return REDACTED;
|
|
48
|
+
}
|
|
49
|
+
const origin = parsed.host.length > 0 ? `${parsed.protocol}//${parsed.host}` : parsed.protocol;
|
|
50
|
+
const query = parsed.search.length > 0 ? `?${REDACTED}` : "";
|
|
51
|
+
return `${origin}${parsed.pathname}${query}`;
|
|
52
|
+
}
|
|
53
|
+
function redactErrorForLogging(error) {
|
|
54
|
+
if (error !== null && typeof error === "object") {
|
|
55
|
+
const candidate = error;
|
|
56
|
+
if (typeof candidate.toJSON === "function") {
|
|
57
|
+
return redactObject(candidate.toJSON());
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (error instanceof Error) {
|
|
61
|
+
return redactObject({ message: error.message, name: error.name });
|
|
62
|
+
}
|
|
63
|
+
return { message: redactValue(typeof error === "string" ? error : String(error)) };
|
|
64
|
+
}
|
|
65
|
+
|
|
4
66
|
// src/errors/ZeroTransferError.ts
|
|
5
67
|
var ZeroTransferError = class extends Error {
|
|
6
68
|
/** Stable machine-readable error code. */
|
|
@@ -42,6 +104,11 @@ var ZeroTransferError = class extends Error {
|
|
|
42
104
|
/**
|
|
43
105
|
* Serializes the error into a plain object suitable for logs or API responses.
|
|
44
106
|
*
|
|
107
|
+
* `details` and `command` are passed through secret redaction so serialized
|
|
108
|
+
* errors never leak credentials, signed URLs, or raw protocol commands. The
|
|
109
|
+
* live {@link ZeroTransferError.details | details} property stays unredacted
|
|
110
|
+
* for programmatic consumers.
|
|
111
|
+
*
|
|
45
112
|
* @returns A JSON-safe object containing public structured error fields.
|
|
46
113
|
*/
|
|
47
114
|
toJSON() {
|
|
@@ -51,12 +118,12 @@ var ZeroTransferError = class extends Error {
|
|
|
51
118
|
message: this.message,
|
|
52
119
|
protocol: this.protocol,
|
|
53
120
|
host: this.host,
|
|
54
|
-
command: this.command,
|
|
121
|
+
command: this.command === void 0 ? void 0 : redactCommand(this.command),
|
|
55
122
|
ftpCode: this.ftpCode,
|
|
56
123
|
sftpCode: this.sftpCode,
|
|
57
124
|
path: this.path,
|
|
58
125
|
retryable: this.retryable,
|
|
59
|
-
details: this.details
|
|
126
|
+
details: this.details === void 0 ? void 0 : redactObject(this.details)
|
|
60
127
|
};
|
|
61
128
|
}
|
|
62
129
|
};
|
|
@@ -579,15 +646,20 @@ var ProviderRegistry = class {
|
|
|
579
646
|
var TransferClient = class {
|
|
580
647
|
/** Provider registry used by this client. */
|
|
581
648
|
registry;
|
|
649
|
+
/** Execution defaults applied when call sites omit their own values. */
|
|
650
|
+
defaults;
|
|
582
651
|
logger;
|
|
583
652
|
/**
|
|
584
653
|
* Creates a transfer client without opening any provider connections.
|
|
585
654
|
*
|
|
586
|
-
* @param options - Optional registry, provider factories, and
|
|
655
|
+
* @param options - Optional registry, provider factories, logger, and execution defaults.
|
|
587
656
|
*/
|
|
588
657
|
constructor(options = {}) {
|
|
589
658
|
this.registry = options.registry ?? new ProviderRegistry();
|
|
590
659
|
this.logger = options.logger ?? noopLogger;
|
|
660
|
+
if (options.defaults !== void 0) {
|
|
661
|
+
this.defaults = { ...options.defaults };
|
|
662
|
+
}
|
|
591
663
|
for (const provider of options.providers ?? []) {
|
|
592
664
|
this.registry.register(provider);
|
|
593
665
|
}
|
|
@@ -1160,18 +1232,25 @@ var TransferEngine = class {
|
|
|
1160
1232
|
for (let attemptNumber = 1; attemptNumber <= maxAttempts; attemptNumber += 1) {
|
|
1161
1233
|
this.throwIfAborted(abortScope.signal, job);
|
|
1162
1234
|
const attemptStartedAt = this.now();
|
|
1235
|
+
const attemptScope = createAttemptScope(
|
|
1236
|
+
abortScope.signal,
|
|
1237
|
+
options.timeout,
|
|
1238
|
+
job,
|
|
1239
|
+
attemptNumber
|
|
1240
|
+
);
|
|
1163
1241
|
const context = this.createExecutionContext(
|
|
1164
1242
|
job,
|
|
1165
1243
|
attemptNumber,
|
|
1166
1244
|
attemptStartedAt,
|
|
1167
1245
|
options,
|
|
1168
|
-
|
|
1246
|
+
attemptScope.signal,
|
|
1169
1247
|
(bytesTransferred) => {
|
|
1170
1248
|
latestBytesTransferred = bytesTransferred;
|
|
1171
|
-
}
|
|
1249
|
+
},
|
|
1250
|
+
attemptScope.notifyProgress
|
|
1172
1251
|
);
|
|
1173
1252
|
try {
|
|
1174
|
-
const result = await runExecutor(executor, context,
|
|
1253
|
+
const result = await runExecutor(executor, context, attemptScope.signal, job);
|
|
1175
1254
|
context.throwIfAborted();
|
|
1176
1255
|
latestBytesTransferred = result.bytesTransferred;
|
|
1177
1256
|
const completedAt = this.now();
|
|
@@ -1189,16 +1268,27 @@ var TransferEngine = class {
|
|
|
1189
1268
|
summarizeError(error)
|
|
1190
1269
|
);
|
|
1191
1270
|
attempts.push(attempt);
|
|
1192
|
-
if (error instanceof AbortError ||
|
|
1271
|
+
if (error instanceof AbortError || abortScope.signal?.aborted === true) {
|
|
1193
1272
|
throw error;
|
|
1194
1273
|
}
|
|
1195
|
-
const retryInput = {
|
|
1274
|
+
const retryInput = {
|
|
1275
|
+
attempt: attemptNumber,
|
|
1276
|
+
elapsedMs: Math.max(0, completedAt.getTime() - startedAt.getTime()),
|
|
1277
|
+
error,
|
|
1278
|
+
job
|
|
1279
|
+
};
|
|
1196
1280
|
const shouldRetry = attemptNumber < maxAttempts && (options.retry?.shouldRetry?.(retryInput) ?? isRetryable(error));
|
|
1197
1281
|
if (shouldRetry) {
|
|
1198
1282
|
options.retry?.onRetry?.(retryInput);
|
|
1283
|
+
const delayMs = normalizeDelayMs(options.retry?.getDelayMs?.(retryInput));
|
|
1284
|
+
if (delayMs > 0) {
|
|
1285
|
+
await sleepWithAbort(delayMs, abortScope.signal, job);
|
|
1286
|
+
}
|
|
1199
1287
|
continue;
|
|
1200
1288
|
}
|
|
1201
1289
|
throw createTransferFailure(job, error, attempts);
|
|
1290
|
+
} finally {
|
|
1291
|
+
attemptScope.dispose();
|
|
1202
1292
|
}
|
|
1203
1293
|
}
|
|
1204
1294
|
throw createTransferFailure(job, void 0, attempts);
|
|
@@ -1206,12 +1296,13 @@ var TransferEngine = class {
|
|
|
1206
1296
|
abortScope.dispose();
|
|
1207
1297
|
}
|
|
1208
1298
|
}
|
|
1209
|
-
createExecutionContext(job, attempt, startedAt, options, signal, updateBytesTransferred) {
|
|
1299
|
+
createExecutionContext(job, attempt, startedAt, options, signal, updateBytesTransferred, notifyProgress) {
|
|
1210
1300
|
const context = {
|
|
1211
1301
|
attempt,
|
|
1212
1302
|
job,
|
|
1213
1303
|
reportProgress: (bytesTransferred, totalBytes) => {
|
|
1214
1304
|
this.throwIfAborted(signal, job);
|
|
1305
|
+
notifyProgress();
|
|
1215
1306
|
updateBytesTransferred(bytesTransferred);
|
|
1216
1307
|
const progressInput = {
|
|
1217
1308
|
bytesTransferred,
|
|
@@ -1280,6 +1371,96 @@ function createAbortScope(parentSignal, timeout, job) {
|
|
|
1280
1371
|
signal: controller.signal
|
|
1281
1372
|
};
|
|
1282
1373
|
}
|
|
1374
|
+
function createAttemptScope(parentSignal, timeout, job, attempt) {
|
|
1375
|
+
const attemptTimeoutMs = normalizeTimeoutMs(timeout?.attemptTimeoutMs);
|
|
1376
|
+
const stallTimeoutMs = normalizeTimeoutMs(timeout?.stallTimeoutMs);
|
|
1377
|
+
if (attemptTimeoutMs === void 0 && stallTimeoutMs === void 0) {
|
|
1378
|
+
const scope = {
|
|
1379
|
+
dispose: () => void 0,
|
|
1380
|
+
notifyProgress: () => void 0
|
|
1381
|
+
};
|
|
1382
|
+
if (parentSignal !== void 0) scope.signal = parentSignal;
|
|
1383
|
+
return scope;
|
|
1384
|
+
}
|
|
1385
|
+
const controller = new AbortController();
|
|
1386
|
+
const retryable = timeout?.retryable ?? true;
|
|
1387
|
+
const abortFromParent = () => controller.abort(parentSignal?.reason);
|
|
1388
|
+
if (parentSignal?.aborted === true) {
|
|
1389
|
+
abortFromParent();
|
|
1390
|
+
} else {
|
|
1391
|
+
parentSignal?.addEventListener("abort", abortFromParent, { once: true });
|
|
1392
|
+
}
|
|
1393
|
+
const attemptTimer = attemptTimeoutMs === void 0 ? void 0 : setTimeout(() => {
|
|
1394
|
+
controller.abort(
|
|
1395
|
+
new TimeoutError({
|
|
1396
|
+
details: { attempt, attemptTimeoutMs, jobId: job.id, operation: job.operation },
|
|
1397
|
+
message: `Transfer attempt ${String(attempt)} timed out after ${String(attemptTimeoutMs)}ms: ${job.id}`,
|
|
1398
|
+
retryable
|
|
1399
|
+
})
|
|
1400
|
+
);
|
|
1401
|
+
}, attemptTimeoutMs);
|
|
1402
|
+
let stallTimer;
|
|
1403
|
+
const armStallWatchdog = () => {
|
|
1404
|
+
if (stallTimeoutMs === void 0 || controller.signal.aborted) return;
|
|
1405
|
+
if (stallTimer !== void 0) clearTimeout(stallTimer);
|
|
1406
|
+
stallTimer = setTimeout(() => {
|
|
1407
|
+
controller.abort(
|
|
1408
|
+
new TimeoutError({
|
|
1409
|
+
details: { attempt, jobId: job.id, operation: job.operation, stallTimeoutMs },
|
|
1410
|
+
message: `Transfer attempt ${String(attempt)} stalled (no progress for ${String(stallTimeoutMs)}ms): ${job.id}`,
|
|
1411
|
+
retryable
|
|
1412
|
+
})
|
|
1413
|
+
);
|
|
1414
|
+
}, stallTimeoutMs);
|
|
1415
|
+
};
|
|
1416
|
+
armStallWatchdog();
|
|
1417
|
+
return {
|
|
1418
|
+
dispose: () => {
|
|
1419
|
+
if (attemptTimer !== void 0) clearTimeout(attemptTimer);
|
|
1420
|
+
if (stallTimer !== void 0) clearTimeout(stallTimer);
|
|
1421
|
+
parentSignal?.removeEventListener("abort", abortFromParent);
|
|
1422
|
+
},
|
|
1423
|
+
notifyProgress: armStallWatchdog,
|
|
1424
|
+
signal: controller.signal
|
|
1425
|
+
};
|
|
1426
|
+
}
|
|
1427
|
+
function sleepWithAbort(delayMs, signal, job) {
|
|
1428
|
+
return new Promise((resolve, reject) => {
|
|
1429
|
+
if (signal === void 0) {
|
|
1430
|
+
setTimeout(resolve, delayMs);
|
|
1431
|
+
return;
|
|
1432
|
+
}
|
|
1433
|
+
if (signal.aborted) {
|
|
1434
|
+
reject(toAbortFailure(signal, job));
|
|
1435
|
+
return;
|
|
1436
|
+
}
|
|
1437
|
+
const rejectAbort = () => {
|
|
1438
|
+
clearTimeout(timer);
|
|
1439
|
+
reject(toAbortFailure(signal, job));
|
|
1440
|
+
};
|
|
1441
|
+
const timer = setTimeout(() => {
|
|
1442
|
+
signal.removeEventListener("abort", rejectAbort);
|
|
1443
|
+
resolve();
|
|
1444
|
+
}, delayMs);
|
|
1445
|
+
signal.addEventListener("abort", rejectAbort, { once: true });
|
|
1446
|
+
});
|
|
1447
|
+
}
|
|
1448
|
+
function toAbortFailure(signal, job) {
|
|
1449
|
+
if (signal.reason instanceof ZeroTransferError) {
|
|
1450
|
+
return signal.reason;
|
|
1451
|
+
}
|
|
1452
|
+
return new AbortError({
|
|
1453
|
+
details: { jobId: job.id, operation: job.operation },
|
|
1454
|
+
message: `Transfer job aborted: ${job.id}`,
|
|
1455
|
+
retryable: false
|
|
1456
|
+
});
|
|
1457
|
+
}
|
|
1458
|
+
function normalizeDelayMs(value) {
|
|
1459
|
+
if (value === void 0 || !Number.isFinite(value) || value <= 0) {
|
|
1460
|
+
return 0;
|
|
1461
|
+
}
|
|
1462
|
+
return Math.floor(value);
|
|
1463
|
+
}
|
|
1283
1464
|
function normalizeTimeoutMs(value) {
|
|
1284
1465
|
if (value === void 0 || !Number.isFinite(value) || value <= 0) {
|
|
1285
1466
|
return void 0;
|
|
@@ -1448,7 +1629,7 @@ async function runRoute(options) {
|
|
|
1448
1629
|
const executor = createProviderTransferExecutor({
|
|
1449
1630
|
resolveSession: ({ role }) => sessions.get(role)
|
|
1450
1631
|
});
|
|
1451
|
-
return await engine.execute(job, executor, buildExecuteOptions(options));
|
|
1632
|
+
return await engine.execute(job, executor, buildExecuteOptions(options, client));
|
|
1452
1633
|
} finally {
|
|
1453
1634
|
if (destinationSession !== void 0) {
|
|
1454
1635
|
await destinationSession.disconnect();
|
|
@@ -1485,12 +1666,14 @@ function defaultJobId(route, now) {
|
|
|
1485
1666
|
const timestamp = (now?.() ?? /* @__PURE__ */ new Date()).getTime();
|
|
1486
1667
|
return `route:${route.id}:${timestamp.toString(36)}`;
|
|
1487
1668
|
}
|
|
1488
|
-
function buildExecuteOptions(options) {
|
|
1669
|
+
function buildExecuteOptions(options, client) {
|
|
1489
1670
|
const execute = {};
|
|
1671
|
+
const retry = options.retry ?? client.defaults?.retry;
|
|
1672
|
+
const timeout = options.timeout ?? client.defaults?.timeout;
|
|
1490
1673
|
if (options.signal !== void 0) execute.signal = options.signal;
|
|
1491
|
-
if (
|
|
1674
|
+
if (retry !== void 0) execute.retry = retry;
|
|
1492
1675
|
if (options.onProgress !== void 0) execute.onProgress = options.onProgress;
|
|
1493
|
-
if (
|
|
1676
|
+
if (timeout !== void 0) execute.timeout = timeout;
|
|
1494
1677
|
if (options.bandwidthLimit !== void 0) execute.bandwidthLimit = options.bandwidthLimit;
|
|
1495
1678
|
return execute;
|
|
1496
1679
|
}
|
|
@@ -1547,41 +1730,6 @@ function defaultRouteSuffix(source, destination) {
|
|
|
1547
1730
|
return `${source}->${destination}`;
|
|
1548
1731
|
}
|
|
1549
1732
|
|
|
1550
|
-
// src/logging/redaction.ts
|
|
1551
|
-
var REDACTED = "[REDACTED]";
|
|
1552
|
-
var SENSITIVE_KEY_PATTERN = /(?:password|passphrase|privatekey|token|secret|username|user)$/i;
|
|
1553
|
-
var SECRET_COMMAND_PATTERN = /^(PASS|USER|ACCT)\s+(.+)$/i;
|
|
1554
|
-
function isSensitiveKey(key) {
|
|
1555
|
-
return SENSITIVE_KEY_PATTERN.test(key.replace(/[_-]/g, ""));
|
|
1556
|
-
}
|
|
1557
|
-
function redactCommand(command) {
|
|
1558
|
-
return command.replace(SECRET_COMMAND_PATTERN, (_fullMatch, commandName) => {
|
|
1559
|
-
return `${commandName.toUpperCase()} ${REDACTED}`;
|
|
1560
|
-
});
|
|
1561
|
-
}
|
|
1562
|
-
function redactValue(value) {
|
|
1563
|
-
if (typeof value === "string") {
|
|
1564
|
-
return redactCommand(value);
|
|
1565
|
-
}
|
|
1566
|
-
if (Array.isArray(value)) {
|
|
1567
|
-
return value.map((item) => redactValue(item));
|
|
1568
|
-
}
|
|
1569
|
-
if (value !== null && typeof value === "object") {
|
|
1570
|
-
return redactObject(value);
|
|
1571
|
-
}
|
|
1572
|
-
return value;
|
|
1573
|
-
}
|
|
1574
|
-
function redactObject(input) {
|
|
1575
|
-
return Object.fromEntries(
|
|
1576
|
-
Object.entries(input).map(([key, value]) => {
|
|
1577
|
-
if (isSensitiveKey(key)) {
|
|
1578
|
-
return [key, REDACTED];
|
|
1579
|
-
}
|
|
1580
|
-
return [key, redactValue(value)];
|
|
1581
|
-
})
|
|
1582
|
-
);
|
|
1583
|
-
}
|
|
1584
|
-
|
|
1585
1733
|
// src/profiles/SecretSource.ts
|
|
1586
1734
|
import { Buffer as Buffer3 } from "buffer";
|
|
1587
1735
|
import { readFile } from "fs/promises";
|
|
@@ -1963,11 +2111,11 @@ import {
|
|
|
1963
2111
|
import path from "path";
|
|
1964
2112
|
|
|
1965
2113
|
// src/utils/path.ts
|
|
1966
|
-
var UNSAFE_FTP_ARGUMENT_PATTERN = /[\r\n]/;
|
|
2114
|
+
var UNSAFE_FTP_ARGUMENT_PATTERN = /[\r\n\0]/;
|
|
1967
2115
|
function assertSafeFtpArgument(value, label = "path") {
|
|
1968
2116
|
if (UNSAFE_FTP_ARGUMENT_PATTERN.test(value)) {
|
|
1969
2117
|
throw new ConfigurationError({
|
|
1970
|
-
message: `Unsafe FTP ${label}: CR and
|
|
2118
|
+
message: `Unsafe FTP ${label}: CR, LF, and NUL characters are not allowed`,
|
|
1971
2119
|
retryable: false,
|
|
1972
2120
|
details: {
|
|
1973
2121
|
label
|
|
@@ -3269,7 +3417,6 @@ function expandAlgorithms(values) {
|
|
|
3269
3417
|
}
|
|
3270
3418
|
|
|
3271
3419
|
// src/profiles/importers/FileZillaImporter.ts
|
|
3272
|
-
import { Buffer as Buffer6 } from "buffer";
|
|
3273
3420
|
function importFileZillaSites(xml) {
|
|
3274
3421
|
const events = tokenizeXml(xml);
|
|
3275
3422
|
if (events.length === 0) {
|
|
@@ -3285,7 +3432,6 @@ function importFileZillaSites(xml) {
|
|
|
3285
3432
|
const folderNamePending = [];
|
|
3286
3433
|
let inServer = false;
|
|
3287
3434
|
let serverFields = {};
|
|
3288
|
-
let serverPasswordEncoding;
|
|
3289
3435
|
let activeTag;
|
|
3290
3436
|
let captureFolderName = false;
|
|
3291
3437
|
for (const event of events) {
|
|
@@ -3298,13 +3444,9 @@ function importFileZillaSites(xml) {
|
|
|
3298
3444
|
if (event.name === "Server") {
|
|
3299
3445
|
inServer = true;
|
|
3300
3446
|
serverFields = {};
|
|
3301
|
-
serverPasswordEncoding = void 0;
|
|
3302
3447
|
continue;
|
|
3303
3448
|
}
|
|
3304
3449
|
activeTag = event.name;
|
|
3305
|
-
if (event.name === "Pass" && inServer) {
|
|
3306
|
-
serverPasswordEncoding = event.attributes["encoding"];
|
|
3307
|
-
}
|
|
3308
3450
|
if (event.name === "Name" && !inServer && folderNamePending.length > 0) {
|
|
3309
3451
|
captureFolderName = true;
|
|
3310
3452
|
}
|
|
@@ -3330,7 +3472,7 @@ function importFileZillaSites(xml) {
|
|
|
3330
3472
|
}
|
|
3331
3473
|
if (event.name === "Server") {
|
|
3332
3474
|
const folder = folderStack.filter((segment) => segment !== "");
|
|
3333
|
-
const result = buildSiteFromFields(serverFields
|
|
3475
|
+
const result = buildSiteFromFields(serverFields);
|
|
3334
3476
|
if (result.kind === "site") {
|
|
3335
3477
|
sites.push({ ...result.site, folder });
|
|
3336
3478
|
} else {
|
|
@@ -3342,7 +3484,6 @@ function importFileZillaSites(xml) {
|
|
|
3342
3484
|
}
|
|
3343
3485
|
inServer = false;
|
|
3344
3486
|
serverFields = {};
|
|
3345
|
-
serverPasswordEncoding = void 0;
|
|
3346
3487
|
activeTag = void 0;
|
|
3347
3488
|
continue;
|
|
3348
3489
|
}
|
|
@@ -3351,7 +3492,7 @@ function importFileZillaSites(xml) {
|
|
|
3351
3492
|
}
|
|
3352
3493
|
return { sites, skipped };
|
|
3353
3494
|
}
|
|
3354
|
-
function buildSiteFromFields(fields
|
|
3495
|
+
function buildSiteFromFields(fields) {
|
|
3355
3496
|
const name = (fields["Name"] ?? fields["Host"] ?? "Untitled").trim();
|
|
3356
3497
|
const host = (fields["Host"] ?? "").trim();
|
|
3357
3498
|
if (host === "") return { kind: "skipped", name };
|
|
@@ -3370,18 +3511,9 @@ function buildSiteFromFields(fields, passwordEncoding) {
|
|
|
3370
3511
|
}
|
|
3371
3512
|
const user = fields["User"]?.trim();
|
|
3372
3513
|
if (user !== void 0 && user !== "") profile.username = { value: user };
|
|
3373
|
-
let password;
|
|
3374
3514
|
const rawPass = fields["Pass"];
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
password = Buffer6.from(rawPass, "base64").toString("utf8");
|
|
3378
|
-
} else {
|
|
3379
|
-
password = rawPass;
|
|
3380
|
-
}
|
|
3381
|
-
if (password !== void 0 && password !== "") profile.password = { value: password };
|
|
3382
|
-
}
|
|
3383
|
-
const site = { name, profile };
|
|
3384
|
-
if (password !== void 0) site.password = password;
|
|
3515
|
+
const hasStoredPassword = rawPass !== void 0 && rawPass !== "";
|
|
3516
|
+
const site = { hasStoredPassword, name, profile };
|
|
3385
3517
|
const logonText = fields["Logontype"];
|
|
3386
3518
|
if (logonText !== void 0) {
|
|
3387
3519
|
const logonType = Number.parseInt(logonText.trim(), 10);
|
|
@@ -3624,6 +3756,62 @@ function mapFtp550(details) {
|
|
|
3624
3756
|
return new PermissionDeniedError(details);
|
|
3625
3757
|
}
|
|
3626
3758
|
|
|
3759
|
+
// src/transfers/createDefaultRetryPolicy.ts
|
|
3760
|
+
var DEFAULT_MAX_ATTEMPTS = 4;
|
|
3761
|
+
var DEFAULT_BASE_DELAY_MS = 250;
|
|
3762
|
+
var DEFAULT_MAX_DELAY_MS = 3e4;
|
|
3763
|
+
var DEFAULT_MAX_ELAPSED_MS = 3e5;
|
|
3764
|
+
function createDefaultRetryPolicy(options = {}) {
|
|
3765
|
+
const maxAttempts = normalizePositiveInteger(options.maxAttempts, DEFAULT_MAX_ATTEMPTS);
|
|
3766
|
+
const baseDelayMs = normalizeNonNegative(options.baseDelayMs, DEFAULT_BASE_DELAY_MS);
|
|
3767
|
+
const maxDelayMs = normalizeNonNegative(options.maxDelayMs, DEFAULT_MAX_DELAY_MS);
|
|
3768
|
+
const maxElapsedMs = normalizeNonNegative(options.maxElapsedMs, DEFAULT_MAX_ELAPSED_MS);
|
|
3769
|
+
const random = options.random ?? Math.random;
|
|
3770
|
+
return {
|
|
3771
|
+
getDelayMs(input) {
|
|
3772
|
+
const retryAfterMs = readRetryAfterMs(input.error);
|
|
3773
|
+
if (retryAfterMs !== void 0) {
|
|
3774
|
+
return retryAfterMs;
|
|
3775
|
+
}
|
|
3776
|
+
const exponentialMs = baseDelayMs * 2 ** (input.attempt - 1);
|
|
3777
|
+
const cappedMs = Math.min(maxDelayMs, exponentialMs);
|
|
3778
|
+
return Math.floor(random() * cappedMs);
|
|
3779
|
+
},
|
|
3780
|
+
maxAttempts,
|
|
3781
|
+
shouldRetry(input) {
|
|
3782
|
+
if (!(input.error instanceof ZeroTransferError) || !input.error.retryable) {
|
|
3783
|
+
return false;
|
|
3784
|
+
}
|
|
3785
|
+
if (input.elapsedMs >= maxElapsedMs) {
|
|
3786
|
+
return false;
|
|
3787
|
+
}
|
|
3788
|
+
const retryAfterMs = readRetryAfterMs(input.error);
|
|
3789
|
+
if (retryAfterMs !== void 0 && input.elapsedMs + retryAfterMs > maxElapsedMs) {
|
|
3790
|
+
return false;
|
|
3791
|
+
}
|
|
3792
|
+
return true;
|
|
3793
|
+
}
|
|
3794
|
+
};
|
|
3795
|
+
}
|
|
3796
|
+
function readRetryAfterMs(error) {
|
|
3797
|
+
if (!(error instanceof ZeroTransferError)) return void 0;
|
|
3798
|
+
const value = error.details?.["retryAfterMs"];
|
|
3799
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value < 0) return void 0;
|
|
3800
|
+
return Math.floor(value);
|
|
3801
|
+
}
|
|
3802
|
+
function normalizePositiveInteger(value, fallback) {
|
|
3803
|
+
if (value === void 0 || !Number.isFinite(value) || value < 1) {
|
|
3804
|
+
return fallback;
|
|
3805
|
+
}
|
|
3806
|
+
return Math.floor(value);
|
|
3807
|
+
}
|
|
3808
|
+
function normalizeNonNegative(value, fallback) {
|
|
3809
|
+
if (value === void 0 || !Number.isFinite(value) || value < 0) {
|
|
3810
|
+
return fallback;
|
|
3811
|
+
}
|
|
3812
|
+
return Math.floor(value);
|
|
3813
|
+
}
|
|
3814
|
+
|
|
3627
3815
|
// src/transfers/TransferPlan.ts
|
|
3628
3816
|
function createTransferPlan(input) {
|
|
3629
3817
|
const plan = {
|
|
@@ -3721,8 +3909,8 @@ var TransferQueue = class {
|
|
|
3721
3909
|
this.concurrency = normalizeConcurrency(options.concurrency);
|
|
3722
3910
|
this.defaultExecutor = options.executor;
|
|
3723
3911
|
this.resolveExecutor = options.resolveExecutor;
|
|
3724
|
-
this.retry = options.retry;
|
|
3725
|
-
this.timeout = options.timeout;
|
|
3912
|
+
this.retry = options.retry ?? options.client?.defaults?.retry;
|
|
3913
|
+
this.timeout = options.timeout ?? options.client?.defaults?.timeout;
|
|
3726
3914
|
this.bandwidthLimit = options.bandwidthLimit;
|
|
3727
3915
|
this.onProgress = options.onProgress;
|
|
3728
3916
|
this.onReceipt = options.onReceipt;
|
|
@@ -4799,10 +4987,10 @@ function isMainModule(importMetaUrl) {
|
|
|
4799
4987
|
}
|
|
4800
4988
|
|
|
4801
4989
|
// src/protocols/ssh/transport/SshTransportConnection.ts
|
|
4802
|
-
import { Buffer as
|
|
4990
|
+
import { Buffer as Buffer15 } from "buffer";
|
|
4803
4991
|
|
|
4804
4992
|
// src/protocols/ssh/binary/SshDataReader.ts
|
|
4805
|
-
import { Buffer as
|
|
4993
|
+
import { Buffer as Buffer6 } from "buffer";
|
|
4806
4994
|
var SshDataReader = class {
|
|
4807
4995
|
constructor(source) {
|
|
4808
4996
|
this.source = source;
|
|
@@ -4828,18 +5016,18 @@ var SshDataReader = class {
|
|
|
4828
5016
|
this.ensureAvailable(length, "bytes");
|
|
4829
5017
|
const data = this.source.subarray(this.offset, this.offset + length);
|
|
4830
5018
|
this.offset += length;
|
|
4831
|
-
return
|
|
5019
|
+
return Buffer6.from(data);
|
|
4832
5020
|
}
|
|
4833
5021
|
readUint32() {
|
|
4834
5022
|
this.ensureAvailable(4, "uint32");
|
|
4835
|
-
const buffer =
|
|
5023
|
+
const buffer = Buffer6.from(this.source);
|
|
4836
5024
|
const value = buffer.readUInt32BE(this.offset);
|
|
4837
5025
|
this.offset += 4;
|
|
4838
5026
|
return value;
|
|
4839
5027
|
}
|
|
4840
5028
|
readUint64() {
|
|
4841
5029
|
this.ensureAvailable(8, "uint64");
|
|
4842
|
-
const buffer =
|
|
5030
|
+
const buffer = Buffer6.from(this.source);
|
|
4843
5031
|
const value = buffer.readBigUInt64BE(this.offset);
|
|
4844
5032
|
this.offset += 8;
|
|
4845
5033
|
return value;
|
|
@@ -4849,7 +5037,7 @@ var SshDataReader = class {
|
|
|
4849
5037
|
this.ensureAvailable(length, "string");
|
|
4850
5038
|
const data = this.source.subarray(this.offset, this.offset + length);
|
|
4851
5039
|
this.offset += length;
|
|
4852
|
-
return
|
|
5040
|
+
return Buffer6.from(data);
|
|
4853
5041
|
}
|
|
4854
5042
|
readUtf8String() {
|
|
4855
5043
|
return this.readString().toString("utf8");
|
|
@@ -4894,7 +5082,7 @@ var SshDataReader = class {
|
|
|
4894
5082
|
};
|
|
4895
5083
|
|
|
4896
5084
|
// src/protocols/ssh/binary/SshDataWriter.ts
|
|
4897
|
-
import { Buffer as
|
|
5085
|
+
import { Buffer as Buffer7 } from "buffer";
|
|
4898
5086
|
var MAX_UINT32 = 4294967295;
|
|
4899
5087
|
var MAX_UINT64 = (1n << 64n) - 1n;
|
|
4900
5088
|
var SshDataWriter = class {
|
|
@@ -4902,7 +5090,7 @@ var SshDataWriter = class {
|
|
|
4902
5090
|
length = 0;
|
|
4903
5091
|
writeByte(value) {
|
|
4904
5092
|
this.assertByte(value, "byte");
|
|
4905
|
-
const chunk =
|
|
5093
|
+
const chunk = Buffer7.alloc(1);
|
|
4906
5094
|
chunk.writeUInt8(value, 0);
|
|
4907
5095
|
return this.push(chunk);
|
|
4908
5096
|
}
|
|
@@ -4910,7 +5098,7 @@ var SshDataWriter = class {
|
|
|
4910
5098
|
return this.writeByte(value ? 1 : 0);
|
|
4911
5099
|
}
|
|
4912
5100
|
writeBytes(value) {
|
|
4913
|
-
return this.push(
|
|
5101
|
+
return this.push(Buffer7.from(value));
|
|
4914
5102
|
}
|
|
4915
5103
|
writeUint32(value) {
|
|
4916
5104
|
if (!Number.isInteger(value) || value < 0 || value > MAX_UINT32) {
|
|
@@ -4920,7 +5108,7 @@ var SshDataWriter = class {
|
|
|
4920
5108
|
retryable: false
|
|
4921
5109
|
});
|
|
4922
5110
|
}
|
|
4923
|
-
const chunk =
|
|
5111
|
+
const chunk = Buffer7.alloc(4);
|
|
4924
5112
|
chunk.writeUInt32BE(value, 0);
|
|
4925
5113
|
return this.push(chunk);
|
|
4926
5114
|
}
|
|
@@ -4932,12 +5120,12 @@ var SshDataWriter = class {
|
|
|
4932
5120
|
retryable: false
|
|
4933
5121
|
});
|
|
4934
5122
|
}
|
|
4935
|
-
const chunk =
|
|
5123
|
+
const chunk = Buffer7.alloc(8);
|
|
4936
5124
|
chunk.writeBigUInt64BE(value, 0);
|
|
4937
5125
|
return this.push(chunk);
|
|
4938
5126
|
}
|
|
4939
5127
|
writeString(value, encoding = "utf8") {
|
|
4940
|
-
const payload = typeof value === "string" ?
|
|
5128
|
+
const payload = typeof value === "string" ? Buffer7.from(value, encoding) : Buffer7.from(value);
|
|
4941
5129
|
this.writeUint32(payload.length);
|
|
4942
5130
|
return this.push(payload);
|
|
4943
5131
|
}
|
|
@@ -4959,7 +5147,7 @@ var SshDataWriter = class {
|
|
|
4959
5147
|
return this.writeString(values.join(","), "ascii");
|
|
4960
5148
|
}
|
|
4961
5149
|
toBuffer() {
|
|
4962
|
-
return
|
|
5150
|
+
return Buffer7.concat(this.chunks, this.length);
|
|
4963
5151
|
}
|
|
4964
5152
|
push(chunk) {
|
|
4965
5153
|
this.chunks.push(chunk);
|
|
@@ -4977,23 +5165,23 @@ var SshDataWriter = class {
|
|
|
4977
5165
|
}
|
|
4978
5166
|
};
|
|
4979
5167
|
function normalizePositiveMpint(value) {
|
|
4980
|
-
const input =
|
|
5168
|
+
const input = Buffer7.from(value);
|
|
4981
5169
|
let offset = 0;
|
|
4982
5170
|
while (offset < input.length && input[offset] === 0) {
|
|
4983
5171
|
offset += 1;
|
|
4984
5172
|
}
|
|
4985
5173
|
if (offset >= input.length) {
|
|
4986
|
-
return
|
|
5174
|
+
return Buffer7.alloc(0);
|
|
4987
5175
|
}
|
|
4988
5176
|
const stripped = input.subarray(offset);
|
|
4989
5177
|
if ((stripped[0] & 128) === 128) {
|
|
4990
|
-
return
|
|
5178
|
+
return Buffer7.concat([Buffer7.from([0]), stripped]);
|
|
4991
5179
|
}
|
|
4992
5180
|
return stripped;
|
|
4993
5181
|
}
|
|
4994
5182
|
|
|
4995
5183
|
// src/protocols/ssh/transport/SshTransportHandshake.ts
|
|
4996
|
-
import { Buffer as
|
|
5184
|
+
import { Buffer as Buffer13 } from "buffer";
|
|
4997
5185
|
|
|
4998
5186
|
// src/protocols/ssh/transport/SshAlgorithmNegotiation.ts
|
|
4999
5187
|
var DEFAULT_SSH_ALGORITHM_PREFERENCES = {
|
|
@@ -5155,12 +5343,12 @@ function parseSshIdentificationLine(line) {
|
|
|
5155
5343
|
}
|
|
5156
5344
|
|
|
5157
5345
|
// src/protocols/ssh/transport/SshKexInit.ts
|
|
5158
|
-
import { Buffer as
|
|
5346
|
+
import { Buffer as Buffer8 } from "buffer";
|
|
5159
5347
|
import { randomBytes } from "crypto";
|
|
5160
5348
|
var SSH_MSG_KEXINIT = 20;
|
|
5161
5349
|
var KEXINIT_COOKIE_LENGTH = 16;
|
|
5162
5350
|
function encodeSshKexInitMessage(options) {
|
|
5163
|
-
const cookie = options.cookie === void 0 ? randomBytes(KEXINIT_COOKIE_LENGTH) :
|
|
5351
|
+
const cookie = options.cookie === void 0 ? randomBytes(KEXINIT_COOKIE_LENGTH) : Buffer8.from(options.cookie);
|
|
5164
5352
|
if (cookie.length !== KEXINIT_COOKIE_LENGTH) {
|
|
5165
5353
|
throw new ConfigurationError({
|
|
5166
5354
|
details: { actualLength: cookie.length, expectedLength: KEXINIT_COOKIE_LENGTH },
|
|
@@ -5230,12 +5418,12 @@ function decodeSshKexInitMessage(payload) {
|
|
|
5230
5418
|
}
|
|
5231
5419
|
|
|
5232
5420
|
// src/protocols/ssh/transport/SshKexCurve25519.ts
|
|
5233
|
-
import { Buffer as
|
|
5421
|
+
import { Buffer as Buffer9 } from "buffer";
|
|
5234
5422
|
import { createPublicKey, diffieHellman, generateKeyPairSync } from "crypto";
|
|
5235
5423
|
var SSH_MSG_KEX_ECDH_INIT = 30;
|
|
5236
5424
|
var SSH_MSG_KEX_ECDH_REPLY = 31;
|
|
5237
5425
|
var X25519_PUBLIC_KEY_LENGTH = 32;
|
|
5238
|
-
var X25519_SPKI_PREFIX =
|
|
5426
|
+
var X25519_SPKI_PREFIX = Buffer9.from("302a300506032b656e032100", "hex");
|
|
5239
5427
|
function createCurve25519Ephemeral() {
|
|
5240
5428
|
const { privateKey, publicKey } = generateKeyPairSync("x25519");
|
|
5241
5429
|
const encodedPublicKey = exportX25519PublicKeyRaw(publicKey);
|
|
@@ -5280,7 +5468,7 @@ function exportX25519PublicKeyRaw(publicKey) {
|
|
|
5280
5468
|
}
|
|
5281
5469
|
function importX25519PublicKeyRaw(raw) {
|
|
5282
5470
|
const normalized = normalizeX25519PublicKey(raw, "server");
|
|
5283
|
-
const der =
|
|
5471
|
+
const der = Buffer9.concat([X25519_SPKI_PREFIX, normalized]);
|
|
5284
5472
|
return createPublicKey({
|
|
5285
5473
|
format: "der",
|
|
5286
5474
|
key: der,
|
|
@@ -5288,7 +5476,7 @@ function importX25519PublicKeyRaw(raw) {
|
|
|
5288
5476
|
});
|
|
5289
5477
|
}
|
|
5290
5478
|
function normalizeX25519PublicKey(value, label) {
|
|
5291
|
-
const key =
|
|
5479
|
+
const key = Buffer9.from(value);
|
|
5292
5480
|
if (key.length !== X25519_PUBLIC_KEY_LENGTH) {
|
|
5293
5481
|
throw new ConfigurationError({
|
|
5294
5482
|
details: { keyLength: key.length, label },
|
|
@@ -5301,7 +5489,7 @@ function normalizeX25519PublicKey(value, label) {
|
|
|
5301
5489
|
}
|
|
5302
5490
|
|
|
5303
5491
|
// src/protocols/ssh/transport/SshKeyDerivation.ts
|
|
5304
|
-
import { Buffer as
|
|
5492
|
+
import { Buffer as Buffer10 } from "buffer";
|
|
5305
5493
|
import { createHash } from "crypto";
|
|
5306
5494
|
function deriveSshSessionKeys(input) {
|
|
5307
5495
|
const hashAlgorithm = resolveKexHashAlgorithm(input.kexAlgorithm);
|
|
@@ -5323,7 +5511,7 @@ function deriveSshSessionKeys(input) {
|
|
|
5323
5511
|
input.negotiatedAlgorithms.encryptionServerToClient,
|
|
5324
5512
|
input.negotiatedAlgorithms.macServerToClient
|
|
5325
5513
|
);
|
|
5326
|
-
const sharedSecret =
|
|
5514
|
+
const sharedSecret = Buffer10.from(input.sharedSecret);
|
|
5327
5515
|
return {
|
|
5328
5516
|
clientToServer: {
|
|
5329
5517
|
encryptionKey: deriveMaterial(
|
|
@@ -5373,21 +5561,21 @@ function computeCurve25519ExchangeHash(input, hashAlgorithm) {
|
|
|
5373
5561
|
}
|
|
5374
5562
|
function deriveMaterial(sharedSecret, exchangeHash, sessionId, letter, length, hashAlgorithm) {
|
|
5375
5563
|
if (length <= 0) {
|
|
5376
|
-
return
|
|
5564
|
+
return Buffer10.alloc(0);
|
|
5377
5565
|
}
|
|
5378
5566
|
const result = [];
|
|
5379
5567
|
const first2 = createHash(hashAlgorithm).update(
|
|
5380
5568
|
new SshDataWriter().writeMpint(sharedSecret).writeBytes(exchangeHash).writeByte(letter.charCodeAt(0)).writeBytes(sessionId).toBuffer()
|
|
5381
5569
|
).digest();
|
|
5382
5570
|
result.push(first2);
|
|
5383
|
-
while (
|
|
5384
|
-
const previous =
|
|
5571
|
+
while (Buffer10.concat(result).length < length) {
|
|
5572
|
+
const previous = Buffer10.concat(result);
|
|
5385
5573
|
const next = createHash(hashAlgorithm).update(
|
|
5386
5574
|
new SshDataWriter().writeMpint(sharedSecret).writeBytes(exchangeHash).writeBytes(previous).toBuffer()
|
|
5387
5575
|
).digest();
|
|
5388
5576
|
result.push(next);
|
|
5389
5577
|
}
|
|
5390
|
-
return
|
|
5578
|
+
return Buffer10.concat(result).subarray(0, length);
|
|
5391
5579
|
}
|
|
5392
5580
|
function resolveKexHashAlgorithm(kexAlgorithm) {
|
|
5393
5581
|
if (kexAlgorithm === "curve25519-sha256" || kexAlgorithm === "curve25519-sha256@libssh.org") {
|
|
@@ -5475,20 +5663,21 @@ function decodeSshNewKeysMessage(payload) {
|
|
|
5475
5663
|
}
|
|
5476
5664
|
|
|
5477
5665
|
// src/protocols/ssh/transport/SshTransportPacket.ts
|
|
5478
|
-
import { Buffer as
|
|
5666
|
+
import { Buffer as Buffer11 } from "buffer";
|
|
5479
5667
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
5480
5668
|
var MIN_PADDING_LENGTH = 4;
|
|
5481
5669
|
var MIN_PACKET_LENGTH = 1 + MIN_PADDING_LENGTH;
|
|
5670
|
+
var MAX_SSH_PACKET_LENGTH = 256 * 1024;
|
|
5482
5671
|
function encodeSshTransportPacket(payload, options = {}) {
|
|
5483
|
-
const body =
|
|
5672
|
+
const body = Buffer11.from(payload);
|
|
5484
5673
|
const blockSize = normalizeBlockSize(options.blockSize ?? 8);
|
|
5485
5674
|
let paddingLength = MIN_PADDING_LENGTH;
|
|
5486
5675
|
while ((1 + body.length + paddingLength + 4) % blockSize !== 0) {
|
|
5487
5676
|
paddingLength += 1;
|
|
5488
5677
|
}
|
|
5489
|
-
const padding = options.randomPadding === false ?
|
|
5678
|
+
const padding = options.randomPadding === false ? Buffer11.alloc(paddingLength) : randomBytes2(paddingLength);
|
|
5490
5679
|
const packetLength = 1 + body.length + paddingLength;
|
|
5491
|
-
const frame =
|
|
5680
|
+
const frame = Buffer11.alloc(4 + packetLength);
|
|
5492
5681
|
frame.writeUInt32BE(packetLength, 0);
|
|
5493
5682
|
frame.writeUInt8(paddingLength, 4);
|
|
5494
5683
|
body.copy(frame, 5);
|
|
@@ -5496,7 +5685,7 @@ function encodeSshTransportPacket(payload, options = {}) {
|
|
|
5496
5685
|
return frame;
|
|
5497
5686
|
}
|
|
5498
5687
|
function decodeSshTransportPacket(frame) {
|
|
5499
|
-
const bytes =
|
|
5688
|
+
const bytes = Buffer11.from(frame);
|
|
5500
5689
|
if (bytes.length < 4 + MIN_PACKET_LENGTH) {
|
|
5501
5690
|
throw new ParseError({
|
|
5502
5691
|
details: { length: bytes.length },
|
|
@@ -5550,12 +5739,20 @@ function decodeSshTransportPacket(frame) {
|
|
|
5550
5739
|
};
|
|
5551
5740
|
}
|
|
5552
5741
|
var SshTransportPacketFramer = class {
|
|
5553
|
-
pending =
|
|
5742
|
+
pending = Buffer11.alloc(0);
|
|
5554
5743
|
push(chunk) {
|
|
5555
|
-
this.pending =
|
|
5744
|
+
this.pending = Buffer11.concat([this.pending, Buffer11.from(chunk)]);
|
|
5556
5745
|
const packets = [];
|
|
5557
5746
|
while (this.pending.length >= 4) {
|
|
5558
5747
|
const packetLength = this.pending.readUInt32BE(0);
|
|
5748
|
+
if (packetLength > MAX_SSH_PACKET_LENGTH) {
|
|
5749
|
+
throw new ParseError({
|
|
5750
|
+
details: { maxPacketLength: MAX_SSH_PACKET_LENGTH, packetLength },
|
|
5751
|
+
message: "SSH transport packet length exceeds the maximum accepted size",
|
|
5752
|
+
protocol: "sftp",
|
|
5753
|
+
retryable: false
|
|
5754
|
+
});
|
|
5755
|
+
}
|
|
5559
5756
|
const frameLength = 4 + packetLength;
|
|
5560
5757
|
if (this.pending.length < frameLength) {
|
|
5561
5758
|
break;
|
|
@@ -5571,8 +5768,8 @@ var SshTransportPacketFramer = class {
|
|
|
5571
5768
|
}
|
|
5572
5769
|
/** Returns and clears any bytes buffered but not yet part of a complete packet. */
|
|
5573
5770
|
takeRemainingBytes() {
|
|
5574
|
-
const remaining =
|
|
5575
|
-
this.pending =
|
|
5771
|
+
const remaining = Buffer11.from(this.pending);
|
|
5772
|
+
this.pending = Buffer11.alloc(0);
|
|
5576
5773
|
return remaining;
|
|
5577
5774
|
}
|
|
5578
5775
|
};
|
|
@@ -5589,10 +5786,10 @@ function normalizeBlockSize(blockSize) {
|
|
|
5589
5786
|
}
|
|
5590
5787
|
|
|
5591
5788
|
// src/protocols/ssh/transport/SshHostKeyVerification.ts
|
|
5592
|
-
import { Buffer as
|
|
5789
|
+
import { Buffer as Buffer12 } from "buffer";
|
|
5593
5790
|
import { createHash as createHash2, createPublicKey as createPublicKey2, verify as cryptoVerify } from "crypto";
|
|
5594
5791
|
var ED25519_RAW_KEY_LENGTH = 32;
|
|
5595
|
-
var ED25519_SPKI_PREFIX =
|
|
5792
|
+
var ED25519_SPKI_PREFIX = Buffer12.from("302a300506032b6570032100", "hex");
|
|
5596
5793
|
function verifySshHostKeySignature(input) {
|
|
5597
5794
|
const { algorithmName, publicKey } = parseHostKey(input.hostKeyBlob);
|
|
5598
5795
|
const { signatureAlgorithm, signatureBytes } = parseSignatureBlob(input.signatureBlob);
|
|
@@ -5605,9 +5802,9 @@ function verifySshHostKeySignature(input) {
|
|
|
5605
5802
|
});
|
|
5606
5803
|
}
|
|
5607
5804
|
const verified = verifySignature({
|
|
5608
|
-
data:
|
|
5805
|
+
data: Buffer12.from(input.exchangeHash),
|
|
5609
5806
|
publicKey,
|
|
5610
|
-
signature:
|
|
5807
|
+
signature: Buffer12.from(signatureBytes),
|
|
5611
5808
|
signatureAlgorithm
|
|
5612
5809
|
});
|
|
5613
5810
|
if (!verified) {
|
|
@@ -5636,7 +5833,7 @@ function parseHostKey(blob) {
|
|
|
5636
5833
|
retryable: false
|
|
5637
5834
|
});
|
|
5638
5835
|
}
|
|
5639
|
-
const spki =
|
|
5836
|
+
const spki = Buffer12.concat([ED25519_SPKI_PREFIX, raw]);
|
|
5640
5837
|
return {
|
|
5641
5838
|
algorithmName,
|
|
5642
5839
|
publicKey: createPublicKey2({ format: "der", key: spki, type: "spki" })
|
|
@@ -5742,37 +5939,37 @@ function verifySignature(input) {
|
|
|
5742
5939
|
function rsaPublicKeyFromComponents(e, n) {
|
|
5743
5940
|
const eDer = encodeAsn1Integer(e);
|
|
5744
5941
|
const nDer = encodeAsn1Integer(n);
|
|
5745
|
-
const rsaPublicKeyDer = encodeAsn1Sequence(
|
|
5746
|
-
const bitStringContent =
|
|
5747
|
-
const bitString =
|
|
5748
|
-
|
|
5942
|
+
const rsaPublicKeyDer = encodeAsn1Sequence(Buffer12.concat([nDer, eDer]));
|
|
5943
|
+
const bitStringContent = Buffer12.concat([Buffer12.from([0]), rsaPublicKeyDer]);
|
|
5944
|
+
const bitString = Buffer12.concat([
|
|
5945
|
+
Buffer12.from([3]),
|
|
5749
5946
|
encodeAsn1Length(bitStringContent.length),
|
|
5750
5947
|
bitStringContent
|
|
5751
5948
|
]);
|
|
5752
|
-
const algoId =
|
|
5753
|
-
const spki = encodeAsn1Sequence(
|
|
5949
|
+
const algoId = Buffer12.from("300d06092a864886f70d010101 0500".replace(/\s+/g, ""), "hex");
|
|
5950
|
+
const spki = encodeAsn1Sequence(Buffer12.concat([algoId, bitString]));
|
|
5754
5951
|
return createPublicKey2({ format: "der", key: spki, type: "spki" });
|
|
5755
5952
|
}
|
|
5756
5953
|
function encodeAsn1Integer(value) {
|
|
5757
5954
|
let body = value;
|
|
5758
5955
|
while (body.length > 1 && body[0] === 0) body = body.subarray(1);
|
|
5759
5956
|
if (body.length > 0 && (body[0] & 128) !== 0) {
|
|
5760
|
-
body =
|
|
5957
|
+
body = Buffer12.concat([Buffer12.from([0]), body]);
|
|
5761
5958
|
}
|
|
5762
|
-
return
|
|
5959
|
+
return Buffer12.concat([Buffer12.from([2]), encodeAsn1Length(body.length), body]);
|
|
5763
5960
|
}
|
|
5764
5961
|
function encodeAsn1Sequence(content) {
|
|
5765
|
-
return
|
|
5962
|
+
return Buffer12.concat([Buffer12.from([48]), encodeAsn1Length(content.length), content]);
|
|
5766
5963
|
}
|
|
5767
5964
|
function encodeAsn1Length(length) {
|
|
5768
|
-
if (length < 128) return
|
|
5965
|
+
if (length < 128) return Buffer12.from([length]);
|
|
5769
5966
|
const bytes = [];
|
|
5770
5967
|
let n = length;
|
|
5771
5968
|
while (n > 0) {
|
|
5772
5969
|
bytes.unshift(n & 255);
|
|
5773
5970
|
n >>>= 8;
|
|
5774
5971
|
}
|
|
5775
|
-
return
|
|
5972
|
+
return Buffer12.from([128 | bytes.length, ...bytes]);
|
|
5776
5973
|
}
|
|
5777
5974
|
var ECDSA_OID_BY_CURVE = {
|
|
5778
5975
|
nistp256: "06082a8648ce3d030107",
|
|
@@ -5793,15 +5990,15 @@ function ecdsaPublicKeyFromPoint(curveIdentifier, point) {
|
|
|
5793
5990
|
retryable: false
|
|
5794
5991
|
});
|
|
5795
5992
|
}
|
|
5796
|
-
const algoIdContent =
|
|
5993
|
+
const algoIdContent = Buffer12.from(ECDSA_ALGORITHM_OID_HEX + oidHex, "hex");
|
|
5797
5994
|
const algoId = encodeAsn1Sequence(algoIdContent);
|
|
5798
|
-
const bitStringContent =
|
|
5799
|
-
const bitString =
|
|
5800
|
-
|
|
5995
|
+
const bitStringContent = Buffer12.concat([Buffer12.from([0]), point]);
|
|
5996
|
+
const bitString = Buffer12.concat([
|
|
5997
|
+
Buffer12.from([3]),
|
|
5801
5998
|
encodeAsn1Length(bitStringContent.length),
|
|
5802
5999
|
bitStringContent
|
|
5803
6000
|
]);
|
|
5804
|
-
const spki = encodeAsn1Sequence(
|
|
6001
|
+
const spki = encodeAsn1Sequence(Buffer12.concat([algoId, bitString]));
|
|
5805
6002
|
return createPublicKey2({ format: "der", key: spki, type: "spki" });
|
|
5806
6003
|
}
|
|
5807
6004
|
function sshEcdsaSignatureToDer(sshSignature) {
|
|
@@ -5810,7 +6007,7 @@ function sshEcdsaSignatureToDer(sshSignature) {
|
|
|
5810
6007
|
const s = reader.readMpint();
|
|
5811
6008
|
const rDer = encodeAsn1Integer(r);
|
|
5812
6009
|
const sDer = encodeAsn1Integer(s);
|
|
5813
|
-
return encodeAsn1Sequence(
|
|
6010
|
+
return encodeAsn1Sequence(Buffer12.concat([rDer, sDer]));
|
|
5814
6011
|
}
|
|
5815
6012
|
|
|
5816
6013
|
// src/protocols/ssh/transport/SshTransportHandshake.ts
|
|
@@ -5842,7 +6039,7 @@ var SshTransportHandshake = class {
|
|
|
5842
6039
|
serverIdentification;
|
|
5843
6040
|
/** Creates the first outbound bytes (client identification line). */
|
|
5844
6041
|
createInitialClientBytes() {
|
|
5845
|
-
return
|
|
6042
|
+
return Buffer13.from(`${this.clientIdentificationLine}\r
|
|
5846
6043
|
`, "ascii");
|
|
5847
6044
|
}
|
|
5848
6045
|
/**
|
|
@@ -5866,7 +6063,7 @@ var SshTransportHandshake = class {
|
|
|
5866
6063
|
}
|
|
5867
6064
|
return { outbound };
|
|
5868
6065
|
}
|
|
5869
|
-
return this.pushServerBytesWithPhase(outbound,
|
|
6066
|
+
return this.pushServerBytesWithPhase(outbound, Buffer13.from(chunk));
|
|
5870
6067
|
}
|
|
5871
6068
|
getServerBannerLines() {
|
|
5872
6069
|
return this.identificationLines;
|
|
@@ -5920,12 +6117,12 @@ var SshTransportHandshake = class {
|
|
|
5920
6117
|
clientKexInitPayload: this.clientKexInitPayload,
|
|
5921
6118
|
clientPublicKey: this.pendingCurve25519.publicKey,
|
|
5922
6119
|
negotiatedAlgorithms,
|
|
5923
|
-
serverHostKey:
|
|
6120
|
+
serverHostKey: Buffer13.alloc(0),
|
|
5924
6121
|
serverIdentification: (this.serverIdentification ?? missingServerIdentificationError()).raw,
|
|
5925
|
-
serverKexInitPayload:
|
|
5926
|
-
serverPublicKey:
|
|
5927
|
-
serverSignature:
|
|
5928
|
-
sharedSecret:
|
|
6122
|
+
serverKexInitPayload: Buffer13.from(packet.payload),
|
|
6123
|
+
serverPublicKey: Buffer13.alloc(0),
|
|
6124
|
+
serverSignature: Buffer13.alloc(0),
|
|
6125
|
+
sharedSecret: Buffer13.alloc(0)
|
|
5929
6126
|
};
|
|
5930
6127
|
continue;
|
|
5931
6128
|
}
|
|
@@ -6033,24 +6230,54 @@ var SshTransportHandshake = class {
|
|
|
6033
6230
|
return { outbound };
|
|
6034
6231
|
}
|
|
6035
6232
|
};
|
|
6233
|
+
var MAX_IDENTIFICATION_LINE_BYTES = 8192;
|
|
6234
|
+
var MAX_PRE_IDENTIFICATION_LINES = 1024;
|
|
6036
6235
|
var SshIdentificationAccumulator = class {
|
|
6037
|
-
pending =
|
|
6236
|
+
pending = Buffer13.alloc(0);
|
|
6237
|
+
bannerLineCount = 0;
|
|
6038
6238
|
push(chunk) {
|
|
6039
|
-
this.pending =
|
|
6239
|
+
this.pending = Buffer13.concat([this.pending, Buffer13.from(chunk)]);
|
|
6040
6240
|
const bannerLines = [];
|
|
6041
6241
|
while (true) {
|
|
6042
6242
|
const lfIndex = this.pending.indexOf(10);
|
|
6043
|
-
if (lfIndex < 0)
|
|
6243
|
+
if (lfIndex < 0) {
|
|
6244
|
+
if (this.pending.length > MAX_IDENTIFICATION_LINE_BYTES) {
|
|
6245
|
+
throw new ProtocolError({
|
|
6246
|
+
details: { limitBytes: MAX_IDENTIFICATION_LINE_BYTES },
|
|
6247
|
+
message: "SSH identification line exceeds the maximum accepted length",
|
|
6248
|
+
protocol: "sftp",
|
|
6249
|
+
retryable: false
|
|
6250
|
+
});
|
|
6251
|
+
}
|
|
6252
|
+
break;
|
|
6253
|
+
}
|
|
6254
|
+
if (lfIndex > MAX_IDENTIFICATION_LINE_BYTES) {
|
|
6255
|
+
throw new ProtocolError({
|
|
6256
|
+
details: { limitBytes: MAX_IDENTIFICATION_LINE_BYTES },
|
|
6257
|
+
message: "SSH identification line exceeds the maximum accepted length",
|
|
6258
|
+
protocol: "sftp",
|
|
6259
|
+
retryable: false
|
|
6260
|
+
});
|
|
6261
|
+
}
|
|
6044
6262
|
const lineText = trimLineEndings(this.pending.subarray(0, lfIndex + 1).toString("ascii"));
|
|
6045
|
-
const remainder =
|
|
6263
|
+
const remainder = Buffer13.from(this.pending.subarray(lfIndex + 1));
|
|
6046
6264
|
this.pending = remainder;
|
|
6047
6265
|
if (lineText.startsWith("SSH-")) {
|
|
6048
|
-
this.pending =
|
|
6266
|
+
this.pending = Buffer13.alloc(0);
|
|
6049
6267
|
return { bannerLines, identLine: lineText, remainder };
|
|
6050
6268
|
}
|
|
6269
|
+
this.bannerLineCount += 1;
|
|
6270
|
+
if (this.bannerLineCount > MAX_PRE_IDENTIFICATION_LINES) {
|
|
6271
|
+
throw new ProtocolError({
|
|
6272
|
+
details: { limitLines: MAX_PRE_IDENTIFICATION_LINES },
|
|
6273
|
+
message: "SSH server sent too many pre-identification banner lines",
|
|
6274
|
+
protocol: "sftp",
|
|
6275
|
+
retryable: false
|
|
6276
|
+
});
|
|
6277
|
+
}
|
|
6051
6278
|
bannerLines.push(lineText);
|
|
6052
6279
|
}
|
|
6053
|
-
return { bannerLines, remainder:
|
|
6280
|
+
return { bannerLines, remainder: Buffer13.alloc(0) };
|
|
6054
6281
|
}
|
|
6055
6282
|
};
|
|
6056
6283
|
function trimLineEndings(value) {
|
|
@@ -6078,7 +6305,7 @@ function missingPendingKeyExchangeError() {
|
|
|
6078
6305
|
}
|
|
6079
6306
|
|
|
6080
6307
|
// src/protocols/ssh/transport/SshTransportProtection.ts
|
|
6081
|
-
import { Buffer as
|
|
6308
|
+
import { Buffer as Buffer14 } from "buffer";
|
|
6082
6309
|
import {
|
|
6083
6310
|
createCipheriv,
|
|
6084
6311
|
createDecipheriv,
|
|
@@ -6140,7 +6367,7 @@ var SshTransportPacketProtector = class {
|
|
|
6140
6367
|
);
|
|
6141
6368
|
const encrypted = this.cipher === void 0 ? clearPacket : this.cipher.update(clearPacket);
|
|
6142
6369
|
this.sequenceNumber = this.sequenceNumber + 1 >>> 0;
|
|
6143
|
-
return
|
|
6370
|
+
return Buffer14.concat([encrypted, mac]);
|
|
6144
6371
|
}
|
|
6145
6372
|
};
|
|
6146
6373
|
var SshTransportPacketUnprotector = class {
|
|
@@ -6166,7 +6393,7 @@ var SshTransportPacketUnprotector = class {
|
|
|
6166
6393
|
sequenceNumber;
|
|
6167
6394
|
// Streaming framing state for pushBytes()
|
|
6168
6395
|
framePartialDecrypted;
|
|
6169
|
-
framePendingRaw =
|
|
6396
|
+
framePendingRaw = Buffer14.alloc(0);
|
|
6170
6397
|
frameRemainingNeeded;
|
|
6171
6398
|
getSequenceNumber() {
|
|
6172
6399
|
return this.sequenceNumber;
|
|
@@ -6176,15 +6403,23 @@ var SshTransportPacketUnprotector = class {
|
|
|
6176
6403
|
* Maintains internal framing state across calls - pass each `data` event chunk directly.
|
|
6177
6404
|
*/
|
|
6178
6405
|
pushBytes(chunk) {
|
|
6179
|
-
this.framePendingRaw =
|
|
6406
|
+
this.framePendingRaw = Buffer14.concat([this.framePendingRaw, chunk]);
|
|
6180
6407
|
const results = [];
|
|
6181
6408
|
while (true) {
|
|
6182
6409
|
if (this.framePartialDecrypted === void 0) {
|
|
6183
6410
|
if (this.framePendingRaw.length < this.blockLength) break;
|
|
6184
6411
|
const firstBlock = this.framePendingRaw.subarray(0, this.blockLength);
|
|
6185
|
-
this.framePendingRaw =
|
|
6186
|
-
this.framePartialDecrypted = this.decipher ?
|
|
6412
|
+
this.framePendingRaw = Buffer14.from(this.framePendingRaw.subarray(this.blockLength));
|
|
6413
|
+
this.framePartialDecrypted = this.decipher ? Buffer14.from(this.decipher.update(firstBlock)) : Buffer14.from(firstBlock);
|
|
6187
6414
|
const packetLength = this.framePartialDecrypted.readUInt32BE(0);
|
|
6415
|
+
if (packetLength > MAX_SSH_PACKET_LENGTH) {
|
|
6416
|
+
throw new ProtocolError({
|
|
6417
|
+
details: { maxPacketLength: MAX_SSH_PACKET_LENGTH, packetLength },
|
|
6418
|
+
message: "SSH encrypted packet length exceeds the maximum accepted size",
|
|
6419
|
+
protocol: "sftp",
|
|
6420
|
+
retryable: false
|
|
6421
|
+
});
|
|
6422
|
+
}
|
|
6188
6423
|
const remaining = 4 + packetLength - this.blockLength + this.macLength;
|
|
6189
6424
|
if (remaining < 0) {
|
|
6190
6425
|
throw new ProtocolError({
|
|
@@ -6200,9 +6435,9 @@ var SshTransportPacketUnprotector = class {
|
|
|
6200
6435
|
if (this.framePendingRaw.length < needed) break;
|
|
6201
6436
|
const encryptedRest = this.framePendingRaw.subarray(0, needed - this.macLength);
|
|
6202
6437
|
const receivedMac = this.framePendingRaw.subarray(needed - this.macLength, needed);
|
|
6203
|
-
this.framePendingRaw =
|
|
6204
|
-
const decryptedRest = encryptedRest.length > 0 ? this.decipher ?
|
|
6205
|
-
const clearPacket =
|
|
6438
|
+
this.framePendingRaw = Buffer14.from(this.framePendingRaw.subarray(needed));
|
|
6439
|
+
const decryptedRest = encryptedRest.length > 0 ? this.decipher ? Buffer14.from(this.decipher.update(encryptedRest)) : Buffer14.from(encryptedRest) : Buffer14.alloc(0);
|
|
6440
|
+
const clearPacket = Buffer14.concat([this.framePartialDecrypted, decryptedRest]);
|
|
6206
6441
|
const expectedMac = computeMac(
|
|
6207
6442
|
this.macAlgorithm,
|
|
6208
6443
|
this.options.keys.macKey,
|
|
@@ -6225,7 +6460,7 @@ var SshTransportPacketUnprotector = class {
|
|
|
6225
6460
|
return results;
|
|
6226
6461
|
}
|
|
6227
6462
|
unprotectPayload(packet) {
|
|
6228
|
-
const frame =
|
|
6463
|
+
const frame = Buffer14.from(packet);
|
|
6229
6464
|
if (frame.length < this.macLength) {
|
|
6230
6465
|
throw new ProtocolError({
|
|
6231
6466
|
details: { length: frame.length, macLength: this.macLength },
|
|
@@ -6366,10 +6601,10 @@ function resolveMacLength(encryptionAlgorithm, macAlgorithm) {
|
|
|
6366
6601
|
}
|
|
6367
6602
|
function computeMac(macAlgorithm, macKey, sequence, packet, macLength) {
|
|
6368
6603
|
if (macLength === 0) {
|
|
6369
|
-
return
|
|
6604
|
+
return Buffer14.alloc(0);
|
|
6370
6605
|
}
|
|
6371
6606
|
const hashName = macAlgorithm === "hmac-sha2-512" ? "sha512" : "sha256";
|
|
6372
|
-
const sequenceBuffer =
|
|
6607
|
+
const sequenceBuffer = Buffer14.alloc(4);
|
|
6373
6608
|
sequenceBuffer.writeUInt32BE(sequence >>> 0, 0);
|
|
6374
6609
|
return createHmac2(hashName, macKey).update(sequenceBuffer).update(packet).digest().subarray(0, macLength);
|
|
6375
6610
|
}
|
|
@@ -6576,7 +6811,7 @@ var SshTransportConnection = class {
|
|
|
6576
6811
|
*/
|
|
6577
6812
|
sendPayload(payload) {
|
|
6578
6813
|
this.assertConnected();
|
|
6579
|
-
const frame = this.protector.protectPayload(
|
|
6814
|
+
const frame = this.protector.protectPayload(Buffer15.from(payload));
|
|
6580
6815
|
this.socket.write(frame);
|
|
6581
6816
|
this.resetKeepaliveTimer();
|
|
6582
6817
|
}
|
|
@@ -7044,7 +7279,7 @@ function buildKiRequest(args) {
|
|
|
7044
7279
|
}
|
|
7045
7280
|
|
|
7046
7281
|
// src/protocols/ssh/auth/SshPublickeyCredentialBuilder.ts
|
|
7047
|
-
import { Buffer as
|
|
7282
|
+
import { Buffer as Buffer16 } from "buffer";
|
|
7048
7283
|
import { createPublicKey as createPublicKey3, sign as cryptoSign } from "crypto";
|
|
7049
7284
|
var ED25519_RAW_KEY_LENGTH2 = 32;
|
|
7050
7285
|
var ED25519_SPKI_PREFIX_LENGTH = 12;
|
|
@@ -7062,7 +7297,7 @@ function buildPublickeyCredential(options) {
|
|
|
7062
7297
|
return {
|
|
7063
7298
|
algorithmName: "ssh-ed25519",
|
|
7064
7299
|
publicKeyBlob,
|
|
7065
|
-
sign: (data) => cryptoSign(null,
|
|
7300
|
+
sign: (data) => cryptoSign(null, Buffer16.from(data), privateKey),
|
|
7066
7301
|
type: "publickey",
|
|
7067
7302
|
username
|
|
7068
7303
|
};
|
|
@@ -7080,7 +7315,7 @@ function buildPublickeyCredential(options) {
|
|
|
7080
7315
|
return {
|
|
7081
7316
|
algorithmName,
|
|
7082
7317
|
publicKeyBlob,
|
|
7083
|
-
sign: (data) => cryptoSign(hash,
|
|
7318
|
+
sign: (data) => cryptoSign(hash, Buffer16.from(data), privateKey),
|
|
7084
7319
|
type: "publickey",
|
|
7085
7320
|
username
|
|
7086
7321
|
};
|
|
@@ -7093,7 +7328,7 @@ function buildPublickeyCredential(options) {
|
|
|
7093
7328
|
}
|
|
7094
7329
|
function base64UrlToMpint(value) {
|
|
7095
7330
|
const padded = value.replace(/-/g, "+").replace(/_/g, "/");
|
|
7096
|
-
const buffer =
|
|
7331
|
+
const buffer = Buffer16.from(padded, "base64");
|
|
7097
7332
|
return buffer;
|
|
7098
7333
|
}
|
|
7099
7334
|
function createInvalidKeyError(message) {
|
|
@@ -7219,7 +7454,7 @@ function encodeSshChannelClose(recipientChannel) {
|
|
|
7219
7454
|
}
|
|
7220
7455
|
|
|
7221
7456
|
// src/protocols/ssh/connection/SshSessionChannel.ts
|
|
7222
|
-
import { Buffer as
|
|
7457
|
+
import { Buffer as Buffer17 } from "buffer";
|
|
7223
7458
|
var INITIAL_WINDOW_SIZE = 256 * 1024;
|
|
7224
7459
|
var MAX_PACKET_SIZE = 32 * 1024;
|
|
7225
7460
|
var WINDOW_REFILL_THRESHOLD = 64 * 1024;
|
|
@@ -7377,7 +7612,7 @@ var SshSessionChannel = class {
|
|
|
7377
7612
|
this.remoteWindowRemaining,
|
|
7378
7613
|
this.remoteMaxPacketSize
|
|
7379
7614
|
);
|
|
7380
|
-
const chunk =
|
|
7615
|
+
const chunk = Buffer17.from(data.subarray(offset, offset + chunkSize));
|
|
7381
7616
|
this.transport.sendPayload(
|
|
7382
7617
|
encodeSshChannelData({ data: chunk, recipientChannel: this.remoteChannelId })
|
|
7383
7618
|
);
|
|
@@ -7756,6 +7991,7 @@ export {
|
|
|
7756
7991
|
copyBetween,
|
|
7757
7992
|
createAtomicDeployPlan,
|
|
7758
7993
|
createBandwidthThrottle,
|
|
7994
|
+
createDefaultRetryPolicy,
|
|
7759
7995
|
createLocalProviderFactory,
|
|
7760
7996
|
createMemoryProviderFactory,
|
|
7761
7997
|
createOAuthTokenSecretSource,
|
|
@@ -7792,8 +8028,10 @@ export {
|
|
|
7792
8028
|
parseRemoteManifest,
|
|
7793
8029
|
redactCommand,
|
|
7794
8030
|
redactConnectionProfile,
|
|
8031
|
+
redactErrorForLogging,
|
|
7795
8032
|
redactObject,
|
|
7796
8033
|
redactSecretSource,
|
|
8034
|
+
redactUrlForLogging,
|
|
7797
8035
|
redactValue,
|
|
7798
8036
|
resolveConnectionProfileSecrets,
|
|
7799
8037
|
resolveOpenSshHost,
|