UNPKG

pure-js-sftp

Version:

A pure JavaScript SFTP client with revolutionary RSA-SHA2 compatibility fixes. Zero native dependencies, built on ssh2-streams with 100% SSH key support.

73 lines 4.05 kB
"use strict"; /** * Revolutionary Proxy Fix for ssh2-streams RSA Authentication * * This module uses JavaScript Proxy to intercept ssh2-streams method calls * and modify RSA key algorithm names from "ssh-rsa" to "rsa-sha2-256" at runtime. * This enables RSA key authentication with modern SSH servers without modifying * the ssh2-streams library. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.applyRevolutionaryProxyFix = applyRevolutionaryProxyFix; function applyRevolutionaryProxyFix(ssh2Stream, debugFn) { const debug = debugFn || (() => { }); debug('Applying RSA-SHA2 proxy fix to ssh2-streams'); // Create a Proxy that intercepts method calls return new Proxy(ssh2Stream, { get(target, prop, receiver) { const originalValue = Reflect.get(target, prop, receiver); // Intercept the authPK method which handles public key authentication if (prop === 'authPK' && typeof originalValue === 'function') { debug('Intercepting authPK method for RSA-SHA2 fix'); return function (username, pubKey, cbSign) { let modifiedPubKey = pubKey; if (pubKey && pubKey.type === 'ssh-rsa') { // Case 1: Key object with .type property - modify the type debug('Modifying RSA key object: ssh-rsa -> rsa-sha2-256'); modifiedPubKey = { ...pubKey, type: 'rsa-sha2-256', getPublicSSH: pubKey.getPublicSSH?.bind(pubKey) || function () { return pubKey; }, sign: pubKey.sign?.bind(pubKey) || function () { throw new Error('Sign method not available'); } }; } else if (Buffer.isBuffer(pubKey)) { // Case 2: Buffer containing SSH public key - check if it's RSA const keyTypeStart = 4; // Skip length prefix const keyTypeLen = pubKey.readUInt32BE(0); const keyType = pubKey.toString('ascii', keyTypeStart, keyTypeStart + keyTypeLen); if (keyType === 'ssh-rsa') { debug('Modifying RSA key buffer: ssh-rsa -> rsa-sha2-256'); // Create a new buffer with rsa-sha2-256 instead of ssh-rsa const newKeyType = 'rsa-sha2-256'; const newKeyTypeBuffer = Buffer.from(newKeyType, 'ascii'); const newKeyTypeLen = Buffer.alloc(4); newKeyTypeLen.writeUInt32BE(newKeyTypeBuffer.length, 0); // Reconstruct the buffer: [new_length][new_type][rest_of_key] const restOfKey = pubKey.slice(keyTypeStart + keyTypeLen); modifiedPubKey = Buffer.concat([newKeyTypeLen, newKeyTypeBuffer, restOfKey]); } } // Create signature callback that passes through to the original const signatureCallback = (buf, cb) => { cbSign(buf, (signature) => { debug('RSA-SHA2 authentication complete'); cb(signature); }); }; // Call the original authPK method with our modified key return originalValue.call(target, username, modifiedPubKey, signatureCallback); }; } // For all other properties, return as-is if (typeof originalValue === 'function') { return originalValue.bind(target); } return originalValue; }, set(target, prop, value, receiver) { return Reflect.set(target, prop, value, receiver); } }); } //# sourceMappingURL=revolutionary-proxy-fix.js.map