@zero-transfer/ssh 0.4.7 → 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/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.cjs
CHANGED
|
@@ -70,6 +70,7 @@ __export(ssh_exports, {
|
|
|
70
70
|
copyBetween: () => copyBetween,
|
|
71
71
|
createAtomicDeployPlan: () => createAtomicDeployPlan,
|
|
72
72
|
createBandwidthThrottle: () => createBandwidthThrottle,
|
|
73
|
+
createDefaultRetryPolicy: () => createDefaultRetryPolicy,
|
|
73
74
|
createLocalProviderFactory: () => createLocalProviderFactory,
|
|
74
75
|
createMemoryProviderFactory: () => createMemoryProviderFactory,
|
|
75
76
|
createOAuthTokenSecretSource: () => createOAuthTokenSecretSource,
|
|
@@ -106,8 +107,10 @@ __export(ssh_exports, {
|
|
|
106
107
|
parseRemoteManifest: () => parseRemoteManifest,
|
|
107
108
|
redactCommand: () => redactCommand,
|
|
108
109
|
redactConnectionProfile: () => redactConnectionProfile,
|
|
110
|
+
redactErrorForLogging: () => redactErrorForLogging,
|
|
109
111
|
redactObject: () => redactObject,
|
|
110
112
|
redactSecretSource: () => redactSecretSource,
|
|
113
|
+
redactUrlForLogging: () => redactUrlForLogging,
|
|
111
114
|
redactValue: () => redactValue,
|
|
112
115
|
resolveConnectionProfileSecrets: () => resolveConnectionProfileSecrets,
|
|
113
116
|
resolveOpenSshHost: () => resolveOpenSshHost,
|
|
@@ -129,6 +132,68 @@ module.exports = __toCommonJS(ssh_exports);
|
|
|
129
132
|
// src/client/ZeroTransfer.ts
|
|
130
133
|
var import_node_events = require("events");
|
|
131
134
|
|
|
135
|
+
// src/logging/redaction.ts
|
|
136
|
+
var REDACTED = "[REDACTED]";
|
|
137
|
+
var SENSITIVE_KEY_PATTERN = /(?:password|passphrase|privatekey|token|secret|username|user)$/i;
|
|
138
|
+
var SECRET_COMMAND_PATTERN = /^(PASS|USER|ACCT)\s+(.+)$/i;
|
|
139
|
+
var URL_KEY_PATTERN = /(?:url|uri|href)$/i;
|
|
140
|
+
function isSensitiveKey(key) {
|
|
141
|
+
return SENSITIVE_KEY_PATTERN.test(key.replace(/[_-]/g, ""));
|
|
142
|
+
}
|
|
143
|
+
function redactCommand(command) {
|
|
144
|
+
return command.replace(SECRET_COMMAND_PATTERN, (_fullMatch, commandName) => {
|
|
145
|
+
return `${commandName.toUpperCase()} ${REDACTED}`;
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
function redactValue(value) {
|
|
149
|
+
if (typeof value === "string") {
|
|
150
|
+
return redactCommand(value);
|
|
151
|
+
}
|
|
152
|
+
if (Array.isArray(value)) {
|
|
153
|
+
return value.map((item) => redactValue(item));
|
|
154
|
+
}
|
|
155
|
+
if (value !== null && typeof value === "object") {
|
|
156
|
+
return redactObject(value);
|
|
157
|
+
}
|
|
158
|
+
return value;
|
|
159
|
+
}
|
|
160
|
+
function redactObject(input) {
|
|
161
|
+
return Object.fromEntries(
|
|
162
|
+
Object.entries(input).map(([key, value]) => {
|
|
163
|
+
if (isSensitiveKey(key)) {
|
|
164
|
+
return [key, REDACTED];
|
|
165
|
+
}
|
|
166
|
+
if (URL_KEY_PATTERN.test(key) && typeof value === "string") {
|
|
167
|
+
return [key, redactUrlForLogging(value)];
|
|
168
|
+
}
|
|
169
|
+
return [key, redactValue(value)];
|
|
170
|
+
})
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
function redactUrlForLogging(url) {
|
|
174
|
+
let parsed;
|
|
175
|
+
try {
|
|
176
|
+
parsed = typeof url === "string" ? new URL(url) : url;
|
|
177
|
+
} catch {
|
|
178
|
+
return REDACTED;
|
|
179
|
+
}
|
|
180
|
+
const origin = parsed.host.length > 0 ? `${parsed.protocol}//${parsed.host}` : parsed.protocol;
|
|
181
|
+
const query = parsed.search.length > 0 ? `?${REDACTED}` : "";
|
|
182
|
+
return `${origin}${parsed.pathname}${query}`;
|
|
183
|
+
}
|
|
184
|
+
function redactErrorForLogging(error) {
|
|
185
|
+
if (error !== null && typeof error === "object") {
|
|
186
|
+
const candidate = error;
|
|
187
|
+
if (typeof candidate.toJSON === "function") {
|
|
188
|
+
return redactObject(candidate.toJSON());
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
if (error instanceof Error) {
|
|
192
|
+
return redactObject({ message: error.message, name: error.name });
|
|
193
|
+
}
|
|
194
|
+
return { message: redactValue(typeof error === "string" ? error : String(error)) };
|
|
195
|
+
}
|
|
196
|
+
|
|
132
197
|
// src/errors/ZeroTransferError.ts
|
|
133
198
|
var ZeroTransferError = class extends Error {
|
|
134
199
|
/** Stable machine-readable error code. */
|
|
@@ -170,6 +235,11 @@ var ZeroTransferError = class extends Error {
|
|
|
170
235
|
/**
|
|
171
236
|
* Serializes the error into a plain object suitable for logs or API responses.
|
|
172
237
|
*
|
|
238
|
+
* `details` and `command` are passed through secret redaction so serialized
|
|
239
|
+
* errors never leak credentials, signed URLs, or raw protocol commands. The
|
|
240
|
+
* live {@link ZeroTransferError.details | details} property stays unredacted
|
|
241
|
+
* for programmatic consumers.
|
|
242
|
+
*
|
|
173
243
|
* @returns A JSON-safe object containing public structured error fields.
|
|
174
244
|
*/
|
|
175
245
|
toJSON() {
|
|
@@ -179,12 +249,12 @@ var ZeroTransferError = class extends Error {
|
|
|
179
249
|
message: this.message,
|
|
180
250
|
protocol: this.protocol,
|
|
181
251
|
host: this.host,
|
|
182
|
-
command: this.command,
|
|
252
|
+
command: this.command === void 0 ? void 0 : redactCommand(this.command),
|
|
183
253
|
ftpCode: this.ftpCode,
|
|
184
254
|
sftpCode: this.sftpCode,
|
|
185
255
|
path: this.path,
|
|
186
256
|
retryable: this.retryable,
|
|
187
|
-
details: this.details
|
|
257
|
+
details: this.details === void 0 ? void 0 : redactObject(this.details)
|
|
188
258
|
};
|
|
189
259
|
}
|
|
190
260
|
};
|
|
@@ -707,15 +777,20 @@ var ProviderRegistry = class {
|
|
|
707
777
|
var TransferClient = class {
|
|
708
778
|
/** Provider registry used by this client. */
|
|
709
779
|
registry;
|
|
780
|
+
/** Execution defaults applied when call sites omit their own values. */
|
|
781
|
+
defaults;
|
|
710
782
|
logger;
|
|
711
783
|
/**
|
|
712
784
|
* Creates a transfer client without opening any provider connections.
|
|
713
785
|
*
|
|
714
|
-
* @param options - Optional registry, provider factories, and
|
|
786
|
+
* @param options - Optional registry, provider factories, logger, and execution defaults.
|
|
715
787
|
*/
|
|
716
788
|
constructor(options = {}) {
|
|
717
789
|
this.registry = options.registry ?? new ProviderRegistry();
|
|
718
790
|
this.logger = options.logger ?? noopLogger;
|
|
791
|
+
if (options.defaults !== void 0) {
|
|
792
|
+
this.defaults = { ...options.defaults };
|
|
793
|
+
}
|
|
719
794
|
for (const provider of options.providers ?? []) {
|
|
720
795
|
this.registry.register(provider);
|
|
721
796
|
}
|
|
@@ -1288,18 +1363,25 @@ var TransferEngine = class {
|
|
|
1288
1363
|
for (let attemptNumber = 1; attemptNumber <= maxAttempts; attemptNumber += 1) {
|
|
1289
1364
|
this.throwIfAborted(abortScope.signal, job);
|
|
1290
1365
|
const attemptStartedAt = this.now();
|
|
1366
|
+
const attemptScope = createAttemptScope(
|
|
1367
|
+
abortScope.signal,
|
|
1368
|
+
options.timeout,
|
|
1369
|
+
job,
|
|
1370
|
+
attemptNumber
|
|
1371
|
+
);
|
|
1291
1372
|
const context = this.createExecutionContext(
|
|
1292
1373
|
job,
|
|
1293
1374
|
attemptNumber,
|
|
1294
1375
|
attemptStartedAt,
|
|
1295
1376
|
options,
|
|
1296
|
-
|
|
1377
|
+
attemptScope.signal,
|
|
1297
1378
|
(bytesTransferred) => {
|
|
1298
1379
|
latestBytesTransferred = bytesTransferred;
|
|
1299
|
-
}
|
|
1380
|
+
},
|
|
1381
|
+
attemptScope.notifyProgress
|
|
1300
1382
|
);
|
|
1301
1383
|
try {
|
|
1302
|
-
const result = await runExecutor(executor, context,
|
|
1384
|
+
const result = await runExecutor(executor, context, attemptScope.signal, job);
|
|
1303
1385
|
context.throwIfAborted();
|
|
1304
1386
|
latestBytesTransferred = result.bytesTransferred;
|
|
1305
1387
|
const completedAt = this.now();
|
|
@@ -1317,16 +1399,27 @@ var TransferEngine = class {
|
|
|
1317
1399
|
summarizeError(error)
|
|
1318
1400
|
);
|
|
1319
1401
|
attempts.push(attempt);
|
|
1320
|
-
if (error instanceof AbortError ||
|
|
1402
|
+
if (error instanceof AbortError || abortScope.signal?.aborted === true) {
|
|
1321
1403
|
throw error;
|
|
1322
1404
|
}
|
|
1323
|
-
const retryInput = {
|
|
1405
|
+
const retryInput = {
|
|
1406
|
+
attempt: attemptNumber,
|
|
1407
|
+
elapsedMs: Math.max(0, completedAt.getTime() - startedAt.getTime()),
|
|
1408
|
+
error,
|
|
1409
|
+
job
|
|
1410
|
+
};
|
|
1324
1411
|
const shouldRetry = attemptNumber < maxAttempts && (options.retry?.shouldRetry?.(retryInput) ?? isRetryable(error));
|
|
1325
1412
|
if (shouldRetry) {
|
|
1326
1413
|
options.retry?.onRetry?.(retryInput);
|
|
1414
|
+
const delayMs = normalizeDelayMs(options.retry?.getDelayMs?.(retryInput));
|
|
1415
|
+
if (delayMs > 0) {
|
|
1416
|
+
await sleepWithAbort(delayMs, abortScope.signal, job);
|
|
1417
|
+
}
|
|
1327
1418
|
continue;
|
|
1328
1419
|
}
|
|
1329
1420
|
throw createTransferFailure(job, error, attempts);
|
|
1421
|
+
} finally {
|
|
1422
|
+
attemptScope.dispose();
|
|
1330
1423
|
}
|
|
1331
1424
|
}
|
|
1332
1425
|
throw createTransferFailure(job, void 0, attempts);
|
|
@@ -1334,12 +1427,13 @@ var TransferEngine = class {
|
|
|
1334
1427
|
abortScope.dispose();
|
|
1335
1428
|
}
|
|
1336
1429
|
}
|
|
1337
|
-
createExecutionContext(job, attempt, startedAt, options, signal, updateBytesTransferred) {
|
|
1430
|
+
createExecutionContext(job, attempt, startedAt, options, signal, updateBytesTransferred, notifyProgress) {
|
|
1338
1431
|
const context = {
|
|
1339
1432
|
attempt,
|
|
1340
1433
|
job,
|
|
1341
1434
|
reportProgress: (bytesTransferred, totalBytes) => {
|
|
1342
1435
|
this.throwIfAborted(signal, job);
|
|
1436
|
+
notifyProgress();
|
|
1343
1437
|
updateBytesTransferred(bytesTransferred);
|
|
1344
1438
|
const progressInput = {
|
|
1345
1439
|
bytesTransferred,
|
|
@@ -1408,6 +1502,96 @@ function createAbortScope(parentSignal, timeout, job) {
|
|
|
1408
1502
|
signal: controller.signal
|
|
1409
1503
|
};
|
|
1410
1504
|
}
|
|
1505
|
+
function createAttemptScope(parentSignal, timeout, job, attempt) {
|
|
1506
|
+
const attemptTimeoutMs = normalizeTimeoutMs(timeout?.attemptTimeoutMs);
|
|
1507
|
+
const stallTimeoutMs = normalizeTimeoutMs(timeout?.stallTimeoutMs);
|
|
1508
|
+
if (attemptTimeoutMs === void 0 && stallTimeoutMs === void 0) {
|
|
1509
|
+
const scope = {
|
|
1510
|
+
dispose: () => void 0,
|
|
1511
|
+
notifyProgress: () => void 0
|
|
1512
|
+
};
|
|
1513
|
+
if (parentSignal !== void 0) scope.signal = parentSignal;
|
|
1514
|
+
return scope;
|
|
1515
|
+
}
|
|
1516
|
+
const controller = new AbortController();
|
|
1517
|
+
const retryable = timeout?.retryable ?? true;
|
|
1518
|
+
const abortFromParent = () => controller.abort(parentSignal?.reason);
|
|
1519
|
+
if (parentSignal?.aborted === true) {
|
|
1520
|
+
abortFromParent();
|
|
1521
|
+
} else {
|
|
1522
|
+
parentSignal?.addEventListener("abort", abortFromParent, { once: true });
|
|
1523
|
+
}
|
|
1524
|
+
const attemptTimer = attemptTimeoutMs === void 0 ? void 0 : setTimeout(() => {
|
|
1525
|
+
controller.abort(
|
|
1526
|
+
new TimeoutError({
|
|
1527
|
+
details: { attempt, attemptTimeoutMs, jobId: job.id, operation: job.operation },
|
|
1528
|
+
message: `Transfer attempt ${String(attempt)} timed out after ${String(attemptTimeoutMs)}ms: ${job.id}`,
|
|
1529
|
+
retryable
|
|
1530
|
+
})
|
|
1531
|
+
);
|
|
1532
|
+
}, attemptTimeoutMs);
|
|
1533
|
+
let stallTimer;
|
|
1534
|
+
const armStallWatchdog = () => {
|
|
1535
|
+
if (stallTimeoutMs === void 0 || controller.signal.aborted) return;
|
|
1536
|
+
if (stallTimer !== void 0) clearTimeout(stallTimer);
|
|
1537
|
+
stallTimer = setTimeout(() => {
|
|
1538
|
+
controller.abort(
|
|
1539
|
+
new TimeoutError({
|
|
1540
|
+
details: { attempt, jobId: job.id, operation: job.operation, stallTimeoutMs },
|
|
1541
|
+
message: `Transfer attempt ${String(attempt)} stalled (no progress for ${String(stallTimeoutMs)}ms): ${job.id}`,
|
|
1542
|
+
retryable
|
|
1543
|
+
})
|
|
1544
|
+
);
|
|
1545
|
+
}, stallTimeoutMs);
|
|
1546
|
+
};
|
|
1547
|
+
armStallWatchdog();
|
|
1548
|
+
return {
|
|
1549
|
+
dispose: () => {
|
|
1550
|
+
if (attemptTimer !== void 0) clearTimeout(attemptTimer);
|
|
1551
|
+
if (stallTimer !== void 0) clearTimeout(stallTimer);
|
|
1552
|
+
parentSignal?.removeEventListener("abort", abortFromParent);
|
|
1553
|
+
},
|
|
1554
|
+
notifyProgress: armStallWatchdog,
|
|
1555
|
+
signal: controller.signal
|
|
1556
|
+
};
|
|
1557
|
+
}
|
|
1558
|
+
function sleepWithAbort(delayMs, signal, job) {
|
|
1559
|
+
return new Promise((resolve, reject) => {
|
|
1560
|
+
if (signal === void 0) {
|
|
1561
|
+
setTimeout(resolve, delayMs);
|
|
1562
|
+
return;
|
|
1563
|
+
}
|
|
1564
|
+
if (signal.aborted) {
|
|
1565
|
+
reject(toAbortFailure(signal, job));
|
|
1566
|
+
return;
|
|
1567
|
+
}
|
|
1568
|
+
const rejectAbort = () => {
|
|
1569
|
+
clearTimeout(timer);
|
|
1570
|
+
reject(toAbortFailure(signal, job));
|
|
1571
|
+
};
|
|
1572
|
+
const timer = setTimeout(() => {
|
|
1573
|
+
signal.removeEventListener("abort", rejectAbort);
|
|
1574
|
+
resolve();
|
|
1575
|
+
}, delayMs);
|
|
1576
|
+
signal.addEventListener("abort", rejectAbort, { once: true });
|
|
1577
|
+
});
|
|
1578
|
+
}
|
|
1579
|
+
function toAbortFailure(signal, job) {
|
|
1580
|
+
if (signal.reason instanceof ZeroTransferError) {
|
|
1581
|
+
return signal.reason;
|
|
1582
|
+
}
|
|
1583
|
+
return new AbortError({
|
|
1584
|
+
details: { jobId: job.id, operation: job.operation },
|
|
1585
|
+
message: `Transfer job aborted: ${job.id}`,
|
|
1586
|
+
retryable: false
|
|
1587
|
+
});
|
|
1588
|
+
}
|
|
1589
|
+
function normalizeDelayMs(value) {
|
|
1590
|
+
if (value === void 0 || !Number.isFinite(value) || value <= 0) {
|
|
1591
|
+
return 0;
|
|
1592
|
+
}
|
|
1593
|
+
return Math.floor(value);
|
|
1594
|
+
}
|
|
1411
1595
|
function normalizeTimeoutMs(value) {
|
|
1412
1596
|
if (value === void 0 || !Number.isFinite(value) || value <= 0) {
|
|
1413
1597
|
return void 0;
|
|
@@ -1576,7 +1760,7 @@ async function runRoute(options) {
|
|
|
1576
1760
|
const executor = createProviderTransferExecutor({
|
|
1577
1761
|
resolveSession: ({ role }) => sessions.get(role)
|
|
1578
1762
|
});
|
|
1579
|
-
return await engine.execute(job, executor, buildExecuteOptions(options));
|
|
1763
|
+
return await engine.execute(job, executor, buildExecuteOptions(options, client));
|
|
1580
1764
|
} finally {
|
|
1581
1765
|
if (destinationSession !== void 0) {
|
|
1582
1766
|
await destinationSession.disconnect();
|
|
@@ -1613,12 +1797,14 @@ function defaultJobId(route, now) {
|
|
|
1613
1797
|
const timestamp = (now?.() ?? /* @__PURE__ */ new Date()).getTime();
|
|
1614
1798
|
return `route:${route.id}:${timestamp.toString(36)}`;
|
|
1615
1799
|
}
|
|
1616
|
-
function buildExecuteOptions(options) {
|
|
1800
|
+
function buildExecuteOptions(options, client) {
|
|
1617
1801
|
const execute = {};
|
|
1802
|
+
const retry = options.retry ?? client.defaults?.retry;
|
|
1803
|
+
const timeout = options.timeout ?? client.defaults?.timeout;
|
|
1618
1804
|
if (options.signal !== void 0) execute.signal = options.signal;
|
|
1619
|
-
if (
|
|
1805
|
+
if (retry !== void 0) execute.retry = retry;
|
|
1620
1806
|
if (options.onProgress !== void 0) execute.onProgress = options.onProgress;
|
|
1621
|
-
if (
|
|
1807
|
+
if (timeout !== void 0) execute.timeout = timeout;
|
|
1622
1808
|
if (options.bandwidthLimit !== void 0) execute.bandwidthLimit = options.bandwidthLimit;
|
|
1623
1809
|
return execute;
|
|
1624
1810
|
}
|
|
@@ -1675,41 +1861,6 @@ function defaultRouteSuffix(source, destination) {
|
|
|
1675
1861
|
return `${source}->${destination}`;
|
|
1676
1862
|
}
|
|
1677
1863
|
|
|
1678
|
-
// src/logging/redaction.ts
|
|
1679
|
-
var REDACTED = "[REDACTED]";
|
|
1680
|
-
var SENSITIVE_KEY_PATTERN = /(?:password|passphrase|privatekey|token|secret|username|user)$/i;
|
|
1681
|
-
var SECRET_COMMAND_PATTERN = /^(PASS|USER|ACCT)\s+(.+)$/i;
|
|
1682
|
-
function isSensitiveKey(key) {
|
|
1683
|
-
return SENSITIVE_KEY_PATTERN.test(key.replace(/[_-]/g, ""));
|
|
1684
|
-
}
|
|
1685
|
-
function redactCommand(command) {
|
|
1686
|
-
return command.replace(SECRET_COMMAND_PATTERN, (_fullMatch, commandName) => {
|
|
1687
|
-
return `${commandName.toUpperCase()} ${REDACTED}`;
|
|
1688
|
-
});
|
|
1689
|
-
}
|
|
1690
|
-
function redactValue(value) {
|
|
1691
|
-
if (typeof value === "string") {
|
|
1692
|
-
return redactCommand(value);
|
|
1693
|
-
}
|
|
1694
|
-
if (Array.isArray(value)) {
|
|
1695
|
-
return value.map((item) => redactValue(item));
|
|
1696
|
-
}
|
|
1697
|
-
if (value !== null && typeof value === "object") {
|
|
1698
|
-
return redactObject(value);
|
|
1699
|
-
}
|
|
1700
|
-
return value;
|
|
1701
|
-
}
|
|
1702
|
-
function redactObject(input) {
|
|
1703
|
-
return Object.fromEntries(
|
|
1704
|
-
Object.entries(input).map(([key, value]) => {
|
|
1705
|
-
if (isSensitiveKey(key)) {
|
|
1706
|
-
return [key, REDACTED];
|
|
1707
|
-
}
|
|
1708
|
-
return [key, redactValue(value)];
|
|
1709
|
-
})
|
|
1710
|
-
);
|
|
1711
|
-
}
|
|
1712
|
-
|
|
1713
1864
|
// src/profiles/SecretSource.ts
|
|
1714
1865
|
var import_node_buffer2 = require("buffer");
|
|
1715
1866
|
var import_promises = require("fs/promises");
|
|
@@ -2081,11 +2232,11 @@ var import_promises2 = require("fs/promises");
|
|
|
2081
2232
|
var import_node_path2 = __toESM(require("path"));
|
|
2082
2233
|
|
|
2083
2234
|
// src/utils/path.ts
|
|
2084
|
-
var UNSAFE_FTP_ARGUMENT_PATTERN = /[\r\n]/;
|
|
2235
|
+
var UNSAFE_FTP_ARGUMENT_PATTERN = /[\r\n\0]/;
|
|
2085
2236
|
function assertSafeFtpArgument(value, label = "path") {
|
|
2086
2237
|
if (UNSAFE_FTP_ARGUMENT_PATTERN.test(value)) {
|
|
2087
2238
|
throw new ConfigurationError({
|
|
2088
|
-
message: `Unsafe FTP ${label}: CR and
|
|
2239
|
+
message: `Unsafe FTP ${label}: CR, LF, and NUL characters are not allowed`,
|
|
2089
2240
|
retryable: false,
|
|
2090
2241
|
details: {
|
|
2091
2242
|
label
|
|
@@ -3387,7 +3538,6 @@ function expandAlgorithms(values) {
|
|
|
3387
3538
|
}
|
|
3388
3539
|
|
|
3389
3540
|
// src/profiles/importers/FileZillaImporter.ts
|
|
3390
|
-
var import_node_buffer5 = require("buffer");
|
|
3391
3541
|
function importFileZillaSites(xml) {
|
|
3392
3542
|
const events = tokenizeXml(xml);
|
|
3393
3543
|
if (events.length === 0) {
|
|
@@ -3403,7 +3553,6 @@ function importFileZillaSites(xml) {
|
|
|
3403
3553
|
const folderNamePending = [];
|
|
3404
3554
|
let inServer = false;
|
|
3405
3555
|
let serverFields = {};
|
|
3406
|
-
let serverPasswordEncoding;
|
|
3407
3556
|
let activeTag;
|
|
3408
3557
|
let captureFolderName = false;
|
|
3409
3558
|
for (const event of events) {
|
|
@@ -3416,13 +3565,9 @@ function importFileZillaSites(xml) {
|
|
|
3416
3565
|
if (event.name === "Server") {
|
|
3417
3566
|
inServer = true;
|
|
3418
3567
|
serverFields = {};
|
|
3419
|
-
serverPasswordEncoding = void 0;
|
|
3420
3568
|
continue;
|
|
3421
3569
|
}
|
|
3422
3570
|
activeTag = event.name;
|
|
3423
|
-
if (event.name === "Pass" && inServer) {
|
|
3424
|
-
serverPasswordEncoding = event.attributes["encoding"];
|
|
3425
|
-
}
|
|
3426
3571
|
if (event.name === "Name" && !inServer && folderNamePending.length > 0) {
|
|
3427
3572
|
captureFolderName = true;
|
|
3428
3573
|
}
|
|
@@ -3448,7 +3593,7 @@ function importFileZillaSites(xml) {
|
|
|
3448
3593
|
}
|
|
3449
3594
|
if (event.name === "Server") {
|
|
3450
3595
|
const folder = folderStack.filter((segment) => segment !== "");
|
|
3451
|
-
const result = buildSiteFromFields(serverFields
|
|
3596
|
+
const result = buildSiteFromFields(serverFields);
|
|
3452
3597
|
if (result.kind === "site") {
|
|
3453
3598
|
sites.push({ ...result.site, folder });
|
|
3454
3599
|
} else {
|
|
@@ -3460,7 +3605,6 @@ function importFileZillaSites(xml) {
|
|
|
3460
3605
|
}
|
|
3461
3606
|
inServer = false;
|
|
3462
3607
|
serverFields = {};
|
|
3463
|
-
serverPasswordEncoding = void 0;
|
|
3464
3608
|
activeTag = void 0;
|
|
3465
3609
|
continue;
|
|
3466
3610
|
}
|
|
@@ -3469,7 +3613,7 @@ function importFileZillaSites(xml) {
|
|
|
3469
3613
|
}
|
|
3470
3614
|
return { sites, skipped };
|
|
3471
3615
|
}
|
|
3472
|
-
function buildSiteFromFields(fields
|
|
3616
|
+
function buildSiteFromFields(fields) {
|
|
3473
3617
|
const name = (fields["Name"] ?? fields["Host"] ?? "Untitled").trim();
|
|
3474
3618
|
const host = (fields["Host"] ?? "").trim();
|
|
3475
3619
|
if (host === "") return { kind: "skipped", name };
|
|
@@ -3488,18 +3632,9 @@ function buildSiteFromFields(fields, passwordEncoding) {
|
|
|
3488
3632
|
}
|
|
3489
3633
|
const user = fields["User"]?.trim();
|
|
3490
3634
|
if (user !== void 0 && user !== "") profile.username = { value: user };
|
|
3491
|
-
let password;
|
|
3492
3635
|
const rawPass = fields["Pass"];
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
password = import_node_buffer5.Buffer.from(rawPass, "base64").toString("utf8");
|
|
3496
|
-
} else {
|
|
3497
|
-
password = rawPass;
|
|
3498
|
-
}
|
|
3499
|
-
if (password !== void 0 && password !== "") profile.password = { value: password };
|
|
3500
|
-
}
|
|
3501
|
-
const site = { name, profile };
|
|
3502
|
-
if (password !== void 0) site.password = password;
|
|
3636
|
+
const hasStoredPassword = rawPass !== void 0 && rawPass !== "";
|
|
3637
|
+
const site = { hasStoredPassword, name, profile };
|
|
3503
3638
|
const logonText = fields["Logontype"];
|
|
3504
3639
|
if (logonText !== void 0) {
|
|
3505
3640
|
const logonType = Number.parseInt(logonText.trim(), 10);
|
|
@@ -3742,6 +3877,62 @@ function mapFtp550(details) {
|
|
|
3742
3877
|
return new PermissionDeniedError(details);
|
|
3743
3878
|
}
|
|
3744
3879
|
|
|
3880
|
+
// src/transfers/createDefaultRetryPolicy.ts
|
|
3881
|
+
var DEFAULT_MAX_ATTEMPTS = 4;
|
|
3882
|
+
var DEFAULT_BASE_DELAY_MS = 250;
|
|
3883
|
+
var DEFAULT_MAX_DELAY_MS = 3e4;
|
|
3884
|
+
var DEFAULT_MAX_ELAPSED_MS = 3e5;
|
|
3885
|
+
function createDefaultRetryPolicy(options = {}) {
|
|
3886
|
+
const maxAttempts = normalizePositiveInteger(options.maxAttempts, DEFAULT_MAX_ATTEMPTS);
|
|
3887
|
+
const baseDelayMs = normalizeNonNegative(options.baseDelayMs, DEFAULT_BASE_DELAY_MS);
|
|
3888
|
+
const maxDelayMs = normalizeNonNegative(options.maxDelayMs, DEFAULT_MAX_DELAY_MS);
|
|
3889
|
+
const maxElapsedMs = normalizeNonNegative(options.maxElapsedMs, DEFAULT_MAX_ELAPSED_MS);
|
|
3890
|
+
const random = options.random ?? Math.random;
|
|
3891
|
+
return {
|
|
3892
|
+
getDelayMs(input) {
|
|
3893
|
+
const retryAfterMs = readRetryAfterMs(input.error);
|
|
3894
|
+
if (retryAfterMs !== void 0) {
|
|
3895
|
+
return retryAfterMs;
|
|
3896
|
+
}
|
|
3897
|
+
const exponentialMs = baseDelayMs * 2 ** (input.attempt - 1);
|
|
3898
|
+
const cappedMs = Math.min(maxDelayMs, exponentialMs);
|
|
3899
|
+
return Math.floor(random() * cappedMs);
|
|
3900
|
+
},
|
|
3901
|
+
maxAttempts,
|
|
3902
|
+
shouldRetry(input) {
|
|
3903
|
+
if (!(input.error instanceof ZeroTransferError) || !input.error.retryable) {
|
|
3904
|
+
return false;
|
|
3905
|
+
}
|
|
3906
|
+
if (input.elapsedMs >= maxElapsedMs) {
|
|
3907
|
+
return false;
|
|
3908
|
+
}
|
|
3909
|
+
const retryAfterMs = readRetryAfterMs(input.error);
|
|
3910
|
+
if (retryAfterMs !== void 0 && input.elapsedMs + retryAfterMs > maxElapsedMs) {
|
|
3911
|
+
return false;
|
|
3912
|
+
}
|
|
3913
|
+
return true;
|
|
3914
|
+
}
|
|
3915
|
+
};
|
|
3916
|
+
}
|
|
3917
|
+
function readRetryAfterMs(error) {
|
|
3918
|
+
if (!(error instanceof ZeroTransferError)) return void 0;
|
|
3919
|
+
const value = error.details?.["retryAfterMs"];
|
|
3920
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value < 0) return void 0;
|
|
3921
|
+
return Math.floor(value);
|
|
3922
|
+
}
|
|
3923
|
+
function normalizePositiveInteger(value, fallback) {
|
|
3924
|
+
if (value === void 0 || !Number.isFinite(value) || value < 1) {
|
|
3925
|
+
return fallback;
|
|
3926
|
+
}
|
|
3927
|
+
return Math.floor(value);
|
|
3928
|
+
}
|
|
3929
|
+
function normalizeNonNegative(value, fallback) {
|
|
3930
|
+
if (value === void 0 || !Number.isFinite(value) || value < 0) {
|
|
3931
|
+
return fallback;
|
|
3932
|
+
}
|
|
3933
|
+
return Math.floor(value);
|
|
3934
|
+
}
|
|
3935
|
+
|
|
3745
3936
|
// src/transfers/TransferPlan.ts
|
|
3746
3937
|
function createTransferPlan(input) {
|
|
3747
3938
|
const plan = {
|
|
@@ -3839,8 +4030,8 @@ var TransferQueue = class {
|
|
|
3839
4030
|
this.concurrency = normalizeConcurrency(options.concurrency);
|
|
3840
4031
|
this.defaultExecutor = options.executor;
|
|
3841
4032
|
this.resolveExecutor = options.resolveExecutor;
|
|
3842
|
-
this.retry = options.retry;
|
|
3843
|
-
this.timeout = options.timeout;
|
|
4033
|
+
this.retry = options.retry ?? options.client?.defaults?.retry;
|
|
4034
|
+
this.timeout = options.timeout ?? options.client?.defaults?.timeout;
|
|
3844
4035
|
this.bandwidthLimit = options.bandwidthLimit;
|
|
3845
4036
|
this.onProgress = options.onProgress;
|
|
3846
4037
|
this.onReceipt = options.onReceipt;
|
|
@@ -4917,10 +5108,10 @@ function isMainModule(importMetaUrl) {
|
|
|
4917
5108
|
}
|
|
4918
5109
|
|
|
4919
5110
|
// src/protocols/ssh/transport/SshTransportConnection.ts
|
|
4920
|
-
var
|
|
5111
|
+
var import_node_buffer14 = require("buffer");
|
|
4921
5112
|
|
|
4922
5113
|
// src/protocols/ssh/binary/SshDataReader.ts
|
|
4923
|
-
var
|
|
5114
|
+
var import_node_buffer5 = require("buffer");
|
|
4924
5115
|
var SshDataReader = class {
|
|
4925
5116
|
constructor(source) {
|
|
4926
5117
|
this.source = source;
|
|
@@ -4946,18 +5137,18 @@ var SshDataReader = class {
|
|
|
4946
5137
|
this.ensureAvailable(length, "bytes");
|
|
4947
5138
|
const data = this.source.subarray(this.offset, this.offset + length);
|
|
4948
5139
|
this.offset += length;
|
|
4949
|
-
return
|
|
5140
|
+
return import_node_buffer5.Buffer.from(data);
|
|
4950
5141
|
}
|
|
4951
5142
|
readUint32() {
|
|
4952
5143
|
this.ensureAvailable(4, "uint32");
|
|
4953
|
-
const buffer =
|
|
5144
|
+
const buffer = import_node_buffer5.Buffer.from(this.source);
|
|
4954
5145
|
const value = buffer.readUInt32BE(this.offset);
|
|
4955
5146
|
this.offset += 4;
|
|
4956
5147
|
return value;
|
|
4957
5148
|
}
|
|
4958
5149
|
readUint64() {
|
|
4959
5150
|
this.ensureAvailable(8, "uint64");
|
|
4960
|
-
const buffer =
|
|
5151
|
+
const buffer = import_node_buffer5.Buffer.from(this.source);
|
|
4961
5152
|
const value = buffer.readBigUInt64BE(this.offset);
|
|
4962
5153
|
this.offset += 8;
|
|
4963
5154
|
return value;
|
|
@@ -4967,7 +5158,7 @@ var SshDataReader = class {
|
|
|
4967
5158
|
this.ensureAvailable(length, "string");
|
|
4968
5159
|
const data = this.source.subarray(this.offset, this.offset + length);
|
|
4969
5160
|
this.offset += length;
|
|
4970
|
-
return
|
|
5161
|
+
return import_node_buffer5.Buffer.from(data);
|
|
4971
5162
|
}
|
|
4972
5163
|
readUtf8String() {
|
|
4973
5164
|
return this.readString().toString("utf8");
|
|
@@ -5012,7 +5203,7 @@ var SshDataReader = class {
|
|
|
5012
5203
|
};
|
|
5013
5204
|
|
|
5014
5205
|
// src/protocols/ssh/binary/SshDataWriter.ts
|
|
5015
|
-
var
|
|
5206
|
+
var import_node_buffer6 = require("buffer");
|
|
5016
5207
|
var MAX_UINT32 = 4294967295;
|
|
5017
5208
|
var MAX_UINT64 = (1n << 64n) - 1n;
|
|
5018
5209
|
var SshDataWriter = class {
|
|
@@ -5020,7 +5211,7 @@ var SshDataWriter = class {
|
|
|
5020
5211
|
length = 0;
|
|
5021
5212
|
writeByte(value) {
|
|
5022
5213
|
this.assertByte(value, "byte");
|
|
5023
|
-
const chunk =
|
|
5214
|
+
const chunk = import_node_buffer6.Buffer.alloc(1);
|
|
5024
5215
|
chunk.writeUInt8(value, 0);
|
|
5025
5216
|
return this.push(chunk);
|
|
5026
5217
|
}
|
|
@@ -5028,7 +5219,7 @@ var SshDataWriter = class {
|
|
|
5028
5219
|
return this.writeByte(value ? 1 : 0);
|
|
5029
5220
|
}
|
|
5030
5221
|
writeBytes(value) {
|
|
5031
|
-
return this.push(
|
|
5222
|
+
return this.push(import_node_buffer6.Buffer.from(value));
|
|
5032
5223
|
}
|
|
5033
5224
|
writeUint32(value) {
|
|
5034
5225
|
if (!Number.isInteger(value) || value < 0 || value > MAX_UINT32) {
|
|
@@ -5038,7 +5229,7 @@ var SshDataWriter = class {
|
|
|
5038
5229
|
retryable: false
|
|
5039
5230
|
});
|
|
5040
5231
|
}
|
|
5041
|
-
const chunk =
|
|
5232
|
+
const chunk = import_node_buffer6.Buffer.alloc(4);
|
|
5042
5233
|
chunk.writeUInt32BE(value, 0);
|
|
5043
5234
|
return this.push(chunk);
|
|
5044
5235
|
}
|
|
@@ -5050,12 +5241,12 @@ var SshDataWriter = class {
|
|
|
5050
5241
|
retryable: false
|
|
5051
5242
|
});
|
|
5052
5243
|
}
|
|
5053
|
-
const chunk =
|
|
5244
|
+
const chunk = import_node_buffer6.Buffer.alloc(8);
|
|
5054
5245
|
chunk.writeBigUInt64BE(value, 0);
|
|
5055
5246
|
return this.push(chunk);
|
|
5056
5247
|
}
|
|
5057
5248
|
writeString(value, encoding = "utf8") {
|
|
5058
|
-
const payload = typeof value === "string" ?
|
|
5249
|
+
const payload = typeof value === "string" ? import_node_buffer6.Buffer.from(value, encoding) : import_node_buffer6.Buffer.from(value);
|
|
5059
5250
|
this.writeUint32(payload.length);
|
|
5060
5251
|
return this.push(payload);
|
|
5061
5252
|
}
|
|
@@ -5077,7 +5268,7 @@ var SshDataWriter = class {
|
|
|
5077
5268
|
return this.writeString(values.join(","), "ascii");
|
|
5078
5269
|
}
|
|
5079
5270
|
toBuffer() {
|
|
5080
|
-
return
|
|
5271
|
+
return import_node_buffer6.Buffer.concat(this.chunks, this.length);
|
|
5081
5272
|
}
|
|
5082
5273
|
push(chunk) {
|
|
5083
5274
|
this.chunks.push(chunk);
|
|
@@ -5095,23 +5286,23 @@ var SshDataWriter = class {
|
|
|
5095
5286
|
}
|
|
5096
5287
|
};
|
|
5097
5288
|
function normalizePositiveMpint(value) {
|
|
5098
|
-
const input =
|
|
5289
|
+
const input = import_node_buffer6.Buffer.from(value);
|
|
5099
5290
|
let offset = 0;
|
|
5100
5291
|
while (offset < input.length && input[offset] === 0) {
|
|
5101
5292
|
offset += 1;
|
|
5102
5293
|
}
|
|
5103
5294
|
if (offset >= input.length) {
|
|
5104
|
-
return
|
|
5295
|
+
return import_node_buffer6.Buffer.alloc(0);
|
|
5105
5296
|
}
|
|
5106
5297
|
const stripped = input.subarray(offset);
|
|
5107
5298
|
if ((stripped[0] & 128) === 128) {
|
|
5108
|
-
return
|
|
5299
|
+
return import_node_buffer6.Buffer.concat([import_node_buffer6.Buffer.from([0]), stripped]);
|
|
5109
5300
|
}
|
|
5110
5301
|
return stripped;
|
|
5111
5302
|
}
|
|
5112
5303
|
|
|
5113
5304
|
// src/protocols/ssh/transport/SshTransportHandshake.ts
|
|
5114
|
-
var
|
|
5305
|
+
var import_node_buffer12 = require("buffer");
|
|
5115
5306
|
|
|
5116
5307
|
// src/protocols/ssh/transport/SshAlgorithmNegotiation.ts
|
|
5117
5308
|
var DEFAULT_SSH_ALGORITHM_PREFERENCES = {
|
|
@@ -5273,12 +5464,12 @@ function parseSshIdentificationLine(line) {
|
|
|
5273
5464
|
}
|
|
5274
5465
|
|
|
5275
5466
|
// src/protocols/ssh/transport/SshKexInit.ts
|
|
5276
|
-
var
|
|
5467
|
+
var import_node_buffer7 = require("buffer");
|
|
5277
5468
|
var import_node_crypto2 = require("crypto");
|
|
5278
5469
|
var SSH_MSG_KEXINIT = 20;
|
|
5279
5470
|
var KEXINIT_COOKIE_LENGTH = 16;
|
|
5280
5471
|
function encodeSshKexInitMessage(options) {
|
|
5281
|
-
const cookie = options.cookie === void 0 ? (0, import_node_crypto2.randomBytes)(KEXINIT_COOKIE_LENGTH) :
|
|
5472
|
+
const cookie = options.cookie === void 0 ? (0, import_node_crypto2.randomBytes)(KEXINIT_COOKIE_LENGTH) : import_node_buffer7.Buffer.from(options.cookie);
|
|
5282
5473
|
if (cookie.length !== KEXINIT_COOKIE_LENGTH) {
|
|
5283
5474
|
throw new ConfigurationError({
|
|
5284
5475
|
details: { actualLength: cookie.length, expectedLength: KEXINIT_COOKIE_LENGTH },
|
|
@@ -5348,12 +5539,12 @@ function decodeSshKexInitMessage(payload) {
|
|
|
5348
5539
|
}
|
|
5349
5540
|
|
|
5350
5541
|
// src/protocols/ssh/transport/SshKexCurve25519.ts
|
|
5351
|
-
var
|
|
5542
|
+
var import_node_buffer8 = require("buffer");
|
|
5352
5543
|
var import_node_crypto3 = require("crypto");
|
|
5353
5544
|
var SSH_MSG_KEX_ECDH_INIT = 30;
|
|
5354
5545
|
var SSH_MSG_KEX_ECDH_REPLY = 31;
|
|
5355
5546
|
var X25519_PUBLIC_KEY_LENGTH = 32;
|
|
5356
|
-
var X25519_SPKI_PREFIX =
|
|
5547
|
+
var X25519_SPKI_PREFIX = import_node_buffer8.Buffer.from("302a300506032b656e032100", "hex");
|
|
5357
5548
|
function createCurve25519Ephemeral() {
|
|
5358
5549
|
const { privateKey, publicKey } = (0, import_node_crypto3.generateKeyPairSync)("x25519");
|
|
5359
5550
|
const encodedPublicKey = exportX25519PublicKeyRaw(publicKey);
|
|
@@ -5398,7 +5589,7 @@ function exportX25519PublicKeyRaw(publicKey) {
|
|
|
5398
5589
|
}
|
|
5399
5590
|
function importX25519PublicKeyRaw(raw) {
|
|
5400
5591
|
const normalized = normalizeX25519PublicKey(raw, "server");
|
|
5401
|
-
const der =
|
|
5592
|
+
const der = import_node_buffer8.Buffer.concat([X25519_SPKI_PREFIX, normalized]);
|
|
5402
5593
|
return (0, import_node_crypto3.createPublicKey)({
|
|
5403
5594
|
format: "der",
|
|
5404
5595
|
key: der,
|
|
@@ -5406,7 +5597,7 @@ function importX25519PublicKeyRaw(raw) {
|
|
|
5406
5597
|
});
|
|
5407
5598
|
}
|
|
5408
5599
|
function normalizeX25519PublicKey(value, label) {
|
|
5409
|
-
const key =
|
|
5600
|
+
const key = import_node_buffer8.Buffer.from(value);
|
|
5410
5601
|
if (key.length !== X25519_PUBLIC_KEY_LENGTH) {
|
|
5411
5602
|
throw new ConfigurationError({
|
|
5412
5603
|
details: { keyLength: key.length, label },
|
|
@@ -5419,7 +5610,7 @@ function normalizeX25519PublicKey(value, label) {
|
|
|
5419
5610
|
}
|
|
5420
5611
|
|
|
5421
5612
|
// src/protocols/ssh/transport/SshKeyDerivation.ts
|
|
5422
|
-
var
|
|
5613
|
+
var import_node_buffer9 = require("buffer");
|
|
5423
5614
|
var import_node_crypto4 = require("crypto");
|
|
5424
5615
|
function deriveSshSessionKeys(input) {
|
|
5425
5616
|
const hashAlgorithm = resolveKexHashAlgorithm(input.kexAlgorithm);
|
|
@@ -5441,7 +5632,7 @@ function deriveSshSessionKeys(input) {
|
|
|
5441
5632
|
input.negotiatedAlgorithms.encryptionServerToClient,
|
|
5442
5633
|
input.negotiatedAlgorithms.macServerToClient
|
|
5443
5634
|
);
|
|
5444
|
-
const sharedSecret =
|
|
5635
|
+
const sharedSecret = import_node_buffer9.Buffer.from(input.sharedSecret);
|
|
5445
5636
|
return {
|
|
5446
5637
|
clientToServer: {
|
|
5447
5638
|
encryptionKey: deriveMaterial(
|
|
@@ -5491,21 +5682,21 @@ function computeCurve25519ExchangeHash(input, hashAlgorithm) {
|
|
|
5491
5682
|
}
|
|
5492
5683
|
function deriveMaterial(sharedSecret, exchangeHash, sessionId, letter, length, hashAlgorithm) {
|
|
5493
5684
|
if (length <= 0) {
|
|
5494
|
-
return
|
|
5685
|
+
return import_node_buffer9.Buffer.alloc(0);
|
|
5495
5686
|
}
|
|
5496
5687
|
const result = [];
|
|
5497
5688
|
const first2 = (0, import_node_crypto4.createHash)(hashAlgorithm).update(
|
|
5498
5689
|
new SshDataWriter().writeMpint(sharedSecret).writeBytes(exchangeHash).writeByte(letter.charCodeAt(0)).writeBytes(sessionId).toBuffer()
|
|
5499
5690
|
).digest();
|
|
5500
5691
|
result.push(first2);
|
|
5501
|
-
while (
|
|
5502
|
-
const previous =
|
|
5692
|
+
while (import_node_buffer9.Buffer.concat(result).length < length) {
|
|
5693
|
+
const previous = import_node_buffer9.Buffer.concat(result);
|
|
5503
5694
|
const next = (0, import_node_crypto4.createHash)(hashAlgorithm).update(
|
|
5504
5695
|
new SshDataWriter().writeMpint(sharedSecret).writeBytes(exchangeHash).writeBytes(previous).toBuffer()
|
|
5505
5696
|
).digest();
|
|
5506
5697
|
result.push(next);
|
|
5507
5698
|
}
|
|
5508
|
-
return
|
|
5699
|
+
return import_node_buffer9.Buffer.concat(result).subarray(0, length);
|
|
5509
5700
|
}
|
|
5510
5701
|
function resolveKexHashAlgorithm(kexAlgorithm) {
|
|
5511
5702
|
if (kexAlgorithm === "curve25519-sha256" || kexAlgorithm === "curve25519-sha256@libssh.org") {
|
|
@@ -5593,20 +5784,21 @@ function decodeSshNewKeysMessage(payload) {
|
|
|
5593
5784
|
}
|
|
5594
5785
|
|
|
5595
5786
|
// src/protocols/ssh/transport/SshTransportPacket.ts
|
|
5596
|
-
var
|
|
5787
|
+
var import_node_buffer10 = require("buffer");
|
|
5597
5788
|
var import_node_crypto5 = require("crypto");
|
|
5598
5789
|
var MIN_PADDING_LENGTH = 4;
|
|
5599
5790
|
var MIN_PACKET_LENGTH = 1 + MIN_PADDING_LENGTH;
|
|
5791
|
+
var MAX_SSH_PACKET_LENGTH = 256 * 1024;
|
|
5600
5792
|
function encodeSshTransportPacket(payload, options = {}) {
|
|
5601
|
-
const body =
|
|
5793
|
+
const body = import_node_buffer10.Buffer.from(payload);
|
|
5602
5794
|
const blockSize = normalizeBlockSize(options.blockSize ?? 8);
|
|
5603
5795
|
let paddingLength = MIN_PADDING_LENGTH;
|
|
5604
5796
|
while ((1 + body.length + paddingLength + 4) % blockSize !== 0) {
|
|
5605
5797
|
paddingLength += 1;
|
|
5606
5798
|
}
|
|
5607
|
-
const padding = options.randomPadding === false ?
|
|
5799
|
+
const padding = options.randomPadding === false ? import_node_buffer10.Buffer.alloc(paddingLength) : (0, import_node_crypto5.randomBytes)(paddingLength);
|
|
5608
5800
|
const packetLength = 1 + body.length + paddingLength;
|
|
5609
|
-
const frame =
|
|
5801
|
+
const frame = import_node_buffer10.Buffer.alloc(4 + packetLength);
|
|
5610
5802
|
frame.writeUInt32BE(packetLength, 0);
|
|
5611
5803
|
frame.writeUInt8(paddingLength, 4);
|
|
5612
5804
|
body.copy(frame, 5);
|
|
@@ -5614,7 +5806,7 @@ function encodeSshTransportPacket(payload, options = {}) {
|
|
|
5614
5806
|
return frame;
|
|
5615
5807
|
}
|
|
5616
5808
|
function decodeSshTransportPacket(frame) {
|
|
5617
|
-
const bytes =
|
|
5809
|
+
const bytes = import_node_buffer10.Buffer.from(frame);
|
|
5618
5810
|
if (bytes.length < 4 + MIN_PACKET_LENGTH) {
|
|
5619
5811
|
throw new ParseError({
|
|
5620
5812
|
details: { length: bytes.length },
|
|
@@ -5668,12 +5860,20 @@ function decodeSshTransportPacket(frame) {
|
|
|
5668
5860
|
};
|
|
5669
5861
|
}
|
|
5670
5862
|
var SshTransportPacketFramer = class {
|
|
5671
|
-
pending =
|
|
5863
|
+
pending = import_node_buffer10.Buffer.alloc(0);
|
|
5672
5864
|
push(chunk) {
|
|
5673
|
-
this.pending =
|
|
5865
|
+
this.pending = import_node_buffer10.Buffer.concat([this.pending, import_node_buffer10.Buffer.from(chunk)]);
|
|
5674
5866
|
const packets = [];
|
|
5675
5867
|
while (this.pending.length >= 4) {
|
|
5676
5868
|
const packetLength = this.pending.readUInt32BE(0);
|
|
5869
|
+
if (packetLength > MAX_SSH_PACKET_LENGTH) {
|
|
5870
|
+
throw new ParseError({
|
|
5871
|
+
details: { maxPacketLength: MAX_SSH_PACKET_LENGTH, packetLength },
|
|
5872
|
+
message: "SSH transport packet length exceeds the maximum accepted size",
|
|
5873
|
+
protocol: "sftp",
|
|
5874
|
+
retryable: false
|
|
5875
|
+
});
|
|
5876
|
+
}
|
|
5677
5877
|
const frameLength = 4 + packetLength;
|
|
5678
5878
|
if (this.pending.length < frameLength) {
|
|
5679
5879
|
break;
|
|
@@ -5689,8 +5889,8 @@ var SshTransportPacketFramer = class {
|
|
|
5689
5889
|
}
|
|
5690
5890
|
/** Returns and clears any bytes buffered but not yet part of a complete packet. */
|
|
5691
5891
|
takeRemainingBytes() {
|
|
5692
|
-
const remaining =
|
|
5693
|
-
this.pending =
|
|
5892
|
+
const remaining = import_node_buffer10.Buffer.from(this.pending);
|
|
5893
|
+
this.pending = import_node_buffer10.Buffer.alloc(0);
|
|
5694
5894
|
return remaining;
|
|
5695
5895
|
}
|
|
5696
5896
|
};
|
|
@@ -5707,10 +5907,10 @@ function normalizeBlockSize(blockSize) {
|
|
|
5707
5907
|
}
|
|
5708
5908
|
|
|
5709
5909
|
// src/protocols/ssh/transport/SshHostKeyVerification.ts
|
|
5710
|
-
var
|
|
5910
|
+
var import_node_buffer11 = require("buffer");
|
|
5711
5911
|
var import_node_crypto6 = require("crypto");
|
|
5712
5912
|
var ED25519_RAW_KEY_LENGTH = 32;
|
|
5713
|
-
var ED25519_SPKI_PREFIX =
|
|
5913
|
+
var ED25519_SPKI_PREFIX = import_node_buffer11.Buffer.from("302a300506032b6570032100", "hex");
|
|
5714
5914
|
function verifySshHostKeySignature(input) {
|
|
5715
5915
|
const { algorithmName, publicKey } = parseHostKey(input.hostKeyBlob);
|
|
5716
5916
|
const { signatureAlgorithm, signatureBytes } = parseSignatureBlob(input.signatureBlob);
|
|
@@ -5723,9 +5923,9 @@ function verifySshHostKeySignature(input) {
|
|
|
5723
5923
|
});
|
|
5724
5924
|
}
|
|
5725
5925
|
const verified = verifySignature({
|
|
5726
|
-
data:
|
|
5926
|
+
data: import_node_buffer11.Buffer.from(input.exchangeHash),
|
|
5727
5927
|
publicKey,
|
|
5728
|
-
signature:
|
|
5928
|
+
signature: import_node_buffer11.Buffer.from(signatureBytes),
|
|
5729
5929
|
signatureAlgorithm
|
|
5730
5930
|
});
|
|
5731
5931
|
if (!verified) {
|
|
@@ -5754,7 +5954,7 @@ function parseHostKey(blob) {
|
|
|
5754
5954
|
retryable: false
|
|
5755
5955
|
});
|
|
5756
5956
|
}
|
|
5757
|
-
const spki =
|
|
5957
|
+
const spki = import_node_buffer11.Buffer.concat([ED25519_SPKI_PREFIX, raw]);
|
|
5758
5958
|
return {
|
|
5759
5959
|
algorithmName,
|
|
5760
5960
|
publicKey: (0, import_node_crypto6.createPublicKey)({ format: "der", key: spki, type: "spki" })
|
|
@@ -5860,37 +6060,37 @@ function verifySignature(input) {
|
|
|
5860
6060
|
function rsaPublicKeyFromComponents(e, n) {
|
|
5861
6061
|
const eDer = encodeAsn1Integer(e);
|
|
5862
6062
|
const nDer = encodeAsn1Integer(n);
|
|
5863
|
-
const rsaPublicKeyDer = encodeAsn1Sequence(
|
|
5864
|
-
const bitStringContent =
|
|
5865
|
-
const bitString =
|
|
5866
|
-
|
|
6063
|
+
const rsaPublicKeyDer = encodeAsn1Sequence(import_node_buffer11.Buffer.concat([nDer, eDer]));
|
|
6064
|
+
const bitStringContent = import_node_buffer11.Buffer.concat([import_node_buffer11.Buffer.from([0]), rsaPublicKeyDer]);
|
|
6065
|
+
const bitString = import_node_buffer11.Buffer.concat([
|
|
6066
|
+
import_node_buffer11.Buffer.from([3]),
|
|
5867
6067
|
encodeAsn1Length(bitStringContent.length),
|
|
5868
6068
|
bitStringContent
|
|
5869
6069
|
]);
|
|
5870
|
-
const algoId =
|
|
5871
|
-
const spki = encodeAsn1Sequence(
|
|
6070
|
+
const algoId = import_node_buffer11.Buffer.from("300d06092a864886f70d010101 0500".replace(/\s+/g, ""), "hex");
|
|
6071
|
+
const spki = encodeAsn1Sequence(import_node_buffer11.Buffer.concat([algoId, bitString]));
|
|
5872
6072
|
return (0, import_node_crypto6.createPublicKey)({ format: "der", key: spki, type: "spki" });
|
|
5873
6073
|
}
|
|
5874
6074
|
function encodeAsn1Integer(value) {
|
|
5875
6075
|
let body = value;
|
|
5876
6076
|
while (body.length > 1 && body[0] === 0) body = body.subarray(1);
|
|
5877
6077
|
if (body.length > 0 && (body[0] & 128) !== 0) {
|
|
5878
|
-
body =
|
|
6078
|
+
body = import_node_buffer11.Buffer.concat([import_node_buffer11.Buffer.from([0]), body]);
|
|
5879
6079
|
}
|
|
5880
|
-
return
|
|
6080
|
+
return import_node_buffer11.Buffer.concat([import_node_buffer11.Buffer.from([2]), encodeAsn1Length(body.length), body]);
|
|
5881
6081
|
}
|
|
5882
6082
|
function encodeAsn1Sequence(content) {
|
|
5883
|
-
return
|
|
6083
|
+
return import_node_buffer11.Buffer.concat([import_node_buffer11.Buffer.from([48]), encodeAsn1Length(content.length), content]);
|
|
5884
6084
|
}
|
|
5885
6085
|
function encodeAsn1Length(length) {
|
|
5886
|
-
if (length < 128) return
|
|
6086
|
+
if (length < 128) return import_node_buffer11.Buffer.from([length]);
|
|
5887
6087
|
const bytes = [];
|
|
5888
6088
|
let n = length;
|
|
5889
6089
|
while (n > 0) {
|
|
5890
6090
|
bytes.unshift(n & 255);
|
|
5891
6091
|
n >>>= 8;
|
|
5892
6092
|
}
|
|
5893
|
-
return
|
|
6093
|
+
return import_node_buffer11.Buffer.from([128 | bytes.length, ...bytes]);
|
|
5894
6094
|
}
|
|
5895
6095
|
var ECDSA_OID_BY_CURVE = {
|
|
5896
6096
|
nistp256: "06082a8648ce3d030107",
|
|
@@ -5911,15 +6111,15 @@ function ecdsaPublicKeyFromPoint(curveIdentifier, point) {
|
|
|
5911
6111
|
retryable: false
|
|
5912
6112
|
});
|
|
5913
6113
|
}
|
|
5914
|
-
const algoIdContent =
|
|
6114
|
+
const algoIdContent = import_node_buffer11.Buffer.from(ECDSA_ALGORITHM_OID_HEX + oidHex, "hex");
|
|
5915
6115
|
const algoId = encodeAsn1Sequence(algoIdContent);
|
|
5916
|
-
const bitStringContent =
|
|
5917
|
-
const bitString =
|
|
5918
|
-
|
|
6116
|
+
const bitStringContent = import_node_buffer11.Buffer.concat([import_node_buffer11.Buffer.from([0]), point]);
|
|
6117
|
+
const bitString = import_node_buffer11.Buffer.concat([
|
|
6118
|
+
import_node_buffer11.Buffer.from([3]),
|
|
5919
6119
|
encodeAsn1Length(bitStringContent.length),
|
|
5920
6120
|
bitStringContent
|
|
5921
6121
|
]);
|
|
5922
|
-
const spki = encodeAsn1Sequence(
|
|
6122
|
+
const spki = encodeAsn1Sequence(import_node_buffer11.Buffer.concat([algoId, bitString]));
|
|
5923
6123
|
return (0, import_node_crypto6.createPublicKey)({ format: "der", key: spki, type: "spki" });
|
|
5924
6124
|
}
|
|
5925
6125
|
function sshEcdsaSignatureToDer(sshSignature) {
|
|
@@ -5928,7 +6128,7 @@ function sshEcdsaSignatureToDer(sshSignature) {
|
|
|
5928
6128
|
const s = reader.readMpint();
|
|
5929
6129
|
const rDer = encodeAsn1Integer(r);
|
|
5930
6130
|
const sDer = encodeAsn1Integer(s);
|
|
5931
|
-
return encodeAsn1Sequence(
|
|
6131
|
+
return encodeAsn1Sequence(import_node_buffer11.Buffer.concat([rDer, sDer]));
|
|
5932
6132
|
}
|
|
5933
6133
|
|
|
5934
6134
|
// src/protocols/ssh/transport/SshTransportHandshake.ts
|
|
@@ -5960,7 +6160,7 @@ var SshTransportHandshake = class {
|
|
|
5960
6160
|
serverIdentification;
|
|
5961
6161
|
/** Creates the first outbound bytes (client identification line). */
|
|
5962
6162
|
createInitialClientBytes() {
|
|
5963
|
-
return
|
|
6163
|
+
return import_node_buffer12.Buffer.from(`${this.clientIdentificationLine}\r
|
|
5964
6164
|
`, "ascii");
|
|
5965
6165
|
}
|
|
5966
6166
|
/**
|
|
@@ -5984,7 +6184,7 @@ var SshTransportHandshake = class {
|
|
|
5984
6184
|
}
|
|
5985
6185
|
return { outbound };
|
|
5986
6186
|
}
|
|
5987
|
-
return this.pushServerBytesWithPhase(outbound,
|
|
6187
|
+
return this.pushServerBytesWithPhase(outbound, import_node_buffer12.Buffer.from(chunk));
|
|
5988
6188
|
}
|
|
5989
6189
|
getServerBannerLines() {
|
|
5990
6190
|
return this.identificationLines;
|
|
@@ -6038,12 +6238,12 @@ var SshTransportHandshake = class {
|
|
|
6038
6238
|
clientKexInitPayload: this.clientKexInitPayload,
|
|
6039
6239
|
clientPublicKey: this.pendingCurve25519.publicKey,
|
|
6040
6240
|
negotiatedAlgorithms,
|
|
6041
|
-
serverHostKey:
|
|
6241
|
+
serverHostKey: import_node_buffer12.Buffer.alloc(0),
|
|
6042
6242
|
serverIdentification: (this.serverIdentification ?? missingServerIdentificationError()).raw,
|
|
6043
|
-
serverKexInitPayload:
|
|
6044
|
-
serverPublicKey:
|
|
6045
|
-
serverSignature:
|
|
6046
|
-
sharedSecret:
|
|
6243
|
+
serverKexInitPayload: import_node_buffer12.Buffer.from(packet.payload),
|
|
6244
|
+
serverPublicKey: import_node_buffer12.Buffer.alloc(0),
|
|
6245
|
+
serverSignature: import_node_buffer12.Buffer.alloc(0),
|
|
6246
|
+
sharedSecret: import_node_buffer12.Buffer.alloc(0)
|
|
6047
6247
|
};
|
|
6048
6248
|
continue;
|
|
6049
6249
|
}
|
|
@@ -6151,24 +6351,54 @@ var SshTransportHandshake = class {
|
|
|
6151
6351
|
return { outbound };
|
|
6152
6352
|
}
|
|
6153
6353
|
};
|
|
6354
|
+
var MAX_IDENTIFICATION_LINE_BYTES = 8192;
|
|
6355
|
+
var MAX_PRE_IDENTIFICATION_LINES = 1024;
|
|
6154
6356
|
var SshIdentificationAccumulator = class {
|
|
6155
|
-
pending =
|
|
6357
|
+
pending = import_node_buffer12.Buffer.alloc(0);
|
|
6358
|
+
bannerLineCount = 0;
|
|
6156
6359
|
push(chunk) {
|
|
6157
|
-
this.pending =
|
|
6360
|
+
this.pending = import_node_buffer12.Buffer.concat([this.pending, import_node_buffer12.Buffer.from(chunk)]);
|
|
6158
6361
|
const bannerLines = [];
|
|
6159
6362
|
while (true) {
|
|
6160
6363
|
const lfIndex = this.pending.indexOf(10);
|
|
6161
|
-
if (lfIndex < 0)
|
|
6364
|
+
if (lfIndex < 0) {
|
|
6365
|
+
if (this.pending.length > MAX_IDENTIFICATION_LINE_BYTES) {
|
|
6366
|
+
throw new ProtocolError({
|
|
6367
|
+
details: { limitBytes: MAX_IDENTIFICATION_LINE_BYTES },
|
|
6368
|
+
message: "SSH identification line exceeds the maximum accepted length",
|
|
6369
|
+
protocol: "sftp",
|
|
6370
|
+
retryable: false
|
|
6371
|
+
});
|
|
6372
|
+
}
|
|
6373
|
+
break;
|
|
6374
|
+
}
|
|
6375
|
+
if (lfIndex > MAX_IDENTIFICATION_LINE_BYTES) {
|
|
6376
|
+
throw new ProtocolError({
|
|
6377
|
+
details: { limitBytes: MAX_IDENTIFICATION_LINE_BYTES },
|
|
6378
|
+
message: "SSH identification line exceeds the maximum accepted length",
|
|
6379
|
+
protocol: "sftp",
|
|
6380
|
+
retryable: false
|
|
6381
|
+
});
|
|
6382
|
+
}
|
|
6162
6383
|
const lineText = trimLineEndings(this.pending.subarray(0, lfIndex + 1).toString("ascii"));
|
|
6163
|
-
const remainder =
|
|
6384
|
+
const remainder = import_node_buffer12.Buffer.from(this.pending.subarray(lfIndex + 1));
|
|
6164
6385
|
this.pending = remainder;
|
|
6165
6386
|
if (lineText.startsWith("SSH-")) {
|
|
6166
|
-
this.pending =
|
|
6387
|
+
this.pending = import_node_buffer12.Buffer.alloc(0);
|
|
6167
6388
|
return { bannerLines, identLine: lineText, remainder };
|
|
6168
6389
|
}
|
|
6390
|
+
this.bannerLineCount += 1;
|
|
6391
|
+
if (this.bannerLineCount > MAX_PRE_IDENTIFICATION_LINES) {
|
|
6392
|
+
throw new ProtocolError({
|
|
6393
|
+
details: { limitLines: MAX_PRE_IDENTIFICATION_LINES },
|
|
6394
|
+
message: "SSH server sent too many pre-identification banner lines",
|
|
6395
|
+
protocol: "sftp",
|
|
6396
|
+
retryable: false
|
|
6397
|
+
});
|
|
6398
|
+
}
|
|
6169
6399
|
bannerLines.push(lineText);
|
|
6170
6400
|
}
|
|
6171
|
-
return { bannerLines, remainder:
|
|
6401
|
+
return { bannerLines, remainder: import_node_buffer12.Buffer.alloc(0) };
|
|
6172
6402
|
}
|
|
6173
6403
|
};
|
|
6174
6404
|
function trimLineEndings(value) {
|
|
@@ -6196,7 +6426,7 @@ function missingPendingKeyExchangeError() {
|
|
|
6196
6426
|
}
|
|
6197
6427
|
|
|
6198
6428
|
// src/protocols/ssh/transport/SshTransportProtection.ts
|
|
6199
|
-
var
|
|
6429
|
+
var import_node_buffer13 = require("buffer");
|
|
6200
6430
|
var import_node_crypto7 = require("crypto");
|
|
6201
6431
|
function createSshTransportProtectionContext(input) {
|
|
6202
6432
|
return {
|
|
@@ -6253,7 +6483,7 @@ var SshTransportPacketProtector = class {
|
|
|
6253
6483
|
);
|
|
6254
6484
|
const encrypted = this.cipher === void 0 ? clearPacket : this.cipher.update(clearPacket);
|
|
6255
6485
|
this.sequenceNumber = this.sequenceNumber + 1 >>> 0;
|
|
6256
|
-
return
|
|
6486
|
+
return import_node_buffer13.Buffer.concat([encrypted, mac]);
|
|
6257
6487
|
}
|
|
6258
6488
|
};
|
|
6259
6489
|
var SshTransportPacketUnprotector = class {
|
|
@@ -6279,7 +6509,7 @@ var SshTransportPacketUnprotector = class {
|
|
|
6279
6509
|
sequenceNumber;
|
|
6280
6510
|
// Streaming framing state for pushBytes()
|
|
6281
6511
|
framePartialDecrypted;
|
|
6282
|
-
framePendingRaw =
|
|
6512
|
+
framePendingRaw = import_node_buffer13.Buffer.alloc(0);
|
|
6283
6513
|
frameRemainingNeeded;
|
|
6284
6514
|
getSequenceNumber() {
|
|
6285
6515
|
return this.sequenceNumber;
|
|
@@ -6289,15 +6519,23 @@ var SshTransportPacketUnprotector = class {
|
|
|
6289
6519
|
* Maintains internal framing state across calls - pass each `data` event chunk directly.
|
|
6290
6520
|
*/
|
|
6291
6521
|
pushBytes(chunk) {
|
|
6292
|
-
this.framePendingRaw =
|
|
6522
|
+
this.framePendingRaw = import_node_buffer13.Buffer.concat([this.framePendingRaw, chunk]);
|
|
6293
6523
|
const results = [];
|
|
6294
6524
|
while (true) {
|
|
6295
6525
|
if (this.framePartialDecrypted === void 0) {
|
|
6296
6526
|
if (this.framePendingRaw.length < this.blockLength) break;
|
|
6297
6527
|
const firstBlock = this.framePendingRaw.subarray(0, this.blockLength);
|
|
6298
|
-
this.framePendingRaw =
|
|
6299
|
-
this.framePartialDecrypted = this.decipher ?
|
|
6528
|
+
this.framePendingRaw = import_node_buffer13.Buffer.from(this.framePendingRaw.subarray(this.blockLength));
|
|
6529
|
+
this.framePartialDecrypted = this.decipher ? import_node_buffer13.Buffer.from(this.decipher.update(firstBlock)) : import_node_buffer13.Buffer.from(firstBlock);
|
|
6300
6530
|
const packetLength = this.framePartialDecrypted.readUInt32BE(0);
|
|
6531
|
+
if (packetLength > MAX_SSH_PACKET_LENGTH) {
|
|
6532
|
+
throw new ProtocolError({
|
|
6533
|
+
details: { maxPacketLength: MAX_SSH_PACKET_LENGTH, packetLength },
|
|
6534
|
+
message: "SSH encrypted packet length exceeds the maximum accepted size",
|
|
6535
|
+
protocol: "sftp",
|
|
6536
|
+
retryable: false
|
|
6537
|
+
});
|
|
6538
|
+
}
|
|
6301
6539
|
const remaining = 4 + packetLength - this.blockLength + this.macLength;
|
|
6302
6540
|
if (remaining < 0) {
|
|
6303
6541
|
throw new ProtocolError({
|
|
@@ -6313,9 +6551,9 @@ var SshTransportPacketUnprotector = class {
|
|
|
6313
6551
|
if (this.framePendingRaw.length < needed) break;
|
|
6314
6552
|
const encryptedRest = this.framePendingRaw.subarray(0, needed - this.macLength);
|
|
6315
6553
|
const receivedMac = this.framePendingRaw.subarray(needed - this.macLength, needed);
|
|
6316
|
-
this.framePendingRaw =
|
|
6317
|
-
const decryptedRest = encryptedRest.length > 0 ? this.decipher ?
|
|
6318
|
-
const clearPacket =
|
|
6554
|
+
this.framePendingRaw = import_node_buffer13.Buffer.from(this.framePendingRaw.subarray(needed));
|
|
6555
|
+
const decryptedRest = encryptedRest.length > 0 ? this.decipher ? import_node_buffer13.Buffer.from(this.decipher.update(encryptedRest)) : import_node_buffer13.Buffer.from(encryptedRest) : import_node_buffer13.Buffer.alloc(0);
|
|
6556
|
+
const clearPacket = import_node_buffer13.Buffer.concat([this.framePartialDecrypted, decryptedRest]);
|
|
6319
6557
|
const expectedMac = computeMac(
|
|
6320
6558
|
this.macAlgorithm,
|
|
6321
6559
|
this.options.keys.macKey,
|
|
@@ -6338,7 +6576,7 @@ var SshTransportPacketUnprotector = class {
|
|
|
6338
6576
|
return results;
|
|
6339
6577
|
}
|
|
6340
6578
|
unprotectPayload(packet) {
|
|
6341
|
-
const frame =
|
|
6579
|
+
const frame = import_node_buffer13.Buffer.from(packet);
|
|
6342
6580
|
if (frame.length < this.macLength) {
|
|
6343
6581
|
throw new ProtocolError({
|
|
6344
6582
|
details: { length: frame.length, macLength: this.macLength },
|
|
@@ -6479,10 +6717,10 @@ function resolveMacLength(encryptionAlgorithm, macAlgorithm) {
|
|
|
6479
6717
|
}
|
|
6480
6718
|
function computeMac(macAlgorithm, macKey, sequence, packet, macLength) {
|
|
6481
6719
|
if (macLength === 0) {
|
|
6482
|
-
return
|
|
6720
|
+
return import_node_buffer13.Buffer.alloc(0);
|
|
6483
6721
|
}
|
|
6484
6722
|
const hashName = macAlgorithm === "hmac-sha2-512" ? "sha512" : "sha256";
|
|
6485
|
-
const sequenceBuffer =
|
|
6723
|
+
const sequenceBuffer = import_node_buffer13.Buffer.alloc(4);
|
|
6486
6724
|
sequenceBuffer.writeUInt32BE(sequence >>> 0, 0);
|
|
6487
6725
|
return (0, import_node_crypto7.createHmac)(hashName, macKey).update(sequenceBuffer).update(packet).digest().subarray(0, macLength);
|
|
6488
6726
|
}
|
|
@@ -6689,7 +6927,7 @@ var SshTransportConnection = class {
|
|
|
6689
6927
|
*/
|
|
6690
6928
|
sendPayload(payload) {
|
|
6691
6929
|
this.assertConnected();
|
|
6692
|
-
const frame = this.protector.protectPayload(
|
|
6930
|
+
const frame = this.protector.protectPayload(import_node_buffer14.Buffer.from(payload));
|
|
6693
6931
|
this.socket.write(frame);
|
|
6694
6932
|
this.resetKeepaliveTimer();
|
|
6695
6933
|
}
|
|
@@ -7157,7 +7395,7 @@ function buildKiRequest(args) {
|
|
|
7157
7395
|
}
|
|
7158
7396
|
|
|
7159
7397
|
// src/protocols/ssh/auth/SshPublickeyCredentialBuilder.ts
|
|
7160
|
-
var
|
|
7398
|
+
var import_node_buffer15 = require("buffer");
|
|
7161
7399
|
var import_node_crypto8 = require("crypto");
|
|
7162
7400
|
var ED25519_RAW_KEY_LENGTH2 = 32;
|
|
7163
7401
|
var ED25519_SPKI_PREFIX_LENGTH = 12;
|
|
@@ -7175,7 +7413,7 @@ function buildPublickeyCredential(options) {
|
|
|
7175
7413
|
return {
|
|
7176
7414
|
algorithmName: "ssh-ed25519",
|
|
7177
7415
|
publicKeyBlob,
|
|
7178
|
-
sign: (data) => (0, import_node_crypto8.sign)(null,
|
|
7416
|
+
sign: (data) => (0, import_node_crypto8.sign)(null, import_node_buffer15.Buffer.from(data), privateKey),
|
|
7179
7417
|
type: "publickey",
|
|
7180
7418
|
username
|
|
7181
7419
|
};
|
|
@@ -7193,7 +7431,7 @@ function buildPublickeyCredential(options) {
|
|
|
7193
7431
|
return {
|
|
7194
7432
|
algorithmName,
|
|
7195
7433
|
publicKeyBlob,
|
|
7196
|
-
sign: (data) => (0, import_node_crypto8.sign)(hash,
|
|
7434
|
+
sign: (data) => (0, import_node_crypto8.sign)(hash, import_node_buffer15.Buffer.from(data), privateKey),
|
|
7197
7435
|
type: "publickey",
|
|
7198
7436
|
username
|
|
7199
7437
|
};
|
|
@@ -7206,7 +7444,7 @@ function buildPublickeyCredential(options) {
|
|
|
7206
7444
|
}
|
|
7207
7445
|
function base64UrlToMpint(value) {
|
|
7208
7446
|
const padded = value.replace(/-/g, "+").replace(/_/g, "/");
|
|
7209
|
-
const buffer =
|
|
7447
|
+
const buffer = import_node_buffer15.Buffer.from(padded, "base64");
|
|
7210
7448
|
return buffer;
|
|
7211
7449
|
}
|
|
7212
7450
|
function createInvalidKeyError(message) {
|
|
@@ -7332,7 +7570,7 @@ function encodeSshChannelClose(recipientChannel) {
|
|
|
7332
7570
|
}
|
|
7333
7571
|
|
|
7334
7572
|
// src/protocols/ssh/connection/SshSessionChannel.ts
|
|
7335
|
-
var
|
|
7573
|
+
var import_node_buffer16 = require("buffer");
|
|
7336
7574
|
var INITIAL_WINDOW_SIZE = 256 * 1024;
|
|
7337
7575
|
var MAX_PACKET_SIZE = 32 * 1024;
|
|
7338
7576
|
var WINDOW_REFILL_THRESHOLD = 64 * 1024;
|
|
@@ -7490,7 +7728,7 @@ var SshSessionChannel = class {
|
|
|
7490
7728
|
this.remoteWindowRemaining,
|
|
7491
7729
|
this.remoteMaxPacketSize
|
|
7492
7730
|
);
|
|
7493
|
-
const chunk =
|
|
7731
|
+
const chunk = import_node_buffer16.Buffer.from(data.subarray(offset, offset + chunkSize));
|
|
7494
7732
|
this.transport.sendPayload(
|
|
7495
7733
|
encodeSshChannelData({ data: chunk, recipientChannel: this.remoteChannelId })
|
|
7496
7734
|
);
|
|
@@ -7870,6 +8108,7 @@ function openTcpSocket(host, port, timeoutMs) {
|
|
|
7870
8108
|
copyBetween,
|
|
7871
8109
|
createAtomicDeployPlan,
|
|
7872
8110
|
createBandwidthThrottle,
|
|
8111
|
+
createDefaultRetryPolicy,
|
|
7873
8112
|
createLocalProviderFactory,
|
|
7874
8113
|
createMemoryProviderFactory,
|
|
7875
8114
|
createOAuthTokenSecretSource,
|
|
@@ -7906,8 +8145,10 @@ function openTcpSocket(host, port, timeoutMs) {
|
|
|
7906
8145
|
parseRemoteManifest,
|
|
7907
8146
|
redactCommand,
|
|
7908
8147
|
redactConnectionProfile,
|
|
8148
|
+
redactErrorForLogging,
|
|
7909
8149
|
redactObject,
|
|
7910
8150
|
redactSecretSource,
|
|
8151
|
+
redactUrlForLogging,
|
|
7911
8152
|
redactValue,
|
|
7912
8153
|
resolveConnectionProfileSecrets,
|
|
7913
8154
|
resolveOpenSshHost,
|