From fb9226cf6956926473b412b172c04ae591e073a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Wed, 16 Oct 2024 16:46:00 +0800 Subject: [PATCH] =?UTF-8?q?bugfix:=20=E4=BF=AE=E5=A4=8D=E5=90=8C=E4=B8=80?= =?UTF-8?q?=E5=9F=9F=E5=90=8D=E4=B8=8D=E5=90=8C=E7=AB=AF=E5=8F=A3=E5=85=B1?= =?UTF-8?q?=E7=94=A8fakeServer=E7=9A=84Promise=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/lib/proxy/tls/CertAndKeyContainer.js | 106 ++++++++++-------- .../src/lib/proxy/tls/FakeServersCenter.js | 44 ++++++-- 2 files changed, 97 insertions(+), 53 deletions(-) diff --git a/packages/mitmproxy/src/lib/proxy/tls/CertAndKeyContainer.js b/packages/mitmproxy/src/lib/proxy/tls/CertAndKeyContainer.js index 036442b60a..ccaa00d9f9 100644 --- a/packages/mitmproxy/src/lib/proxy/tls/CertAndKeyContainer.js +++ b/packages/mitmproxy/src/lib/proxy/tls/CertAndKeyContainer.js @@ -1,5 +1,15 @@ const tlsUtils = require('./tlsUtils') -const https = require('https') +// const https = require('https') +const log = require('../../../utils/util.log') + +function arraysHaveSameElements (arr1, arr2) { + if (arr1.length !== arr2.length) { + return false + } + const sortedArr1 = [...arr1].sort() + const sortedArr2 = [...arr2].sort() + return sortedArr1.every((value, index) => value === sortedArr2[index]) +} module.exports = class CertAndKeyContainer { constructor ({ @@ -26,17 +36,20 @@ module.exports = class CertAndKeyContainer { getCertPromise (hostname, port) { for (let i = 0; i < this.queue.length; i++) { const _certPromiseObj = this.queue[i] - const mappingHostNames = _certPromiseObj.mappingHostNames - for (let j = 0; j < mappingHostNames.length; j++) { - const DNSName = mappingHostNames[j] - if (tlsUtils.isMappingHostName(DNSName, hostname)) { - this.reRankCert(i) - return _certPromiseObj.promise + if (_certPromiseObj.port === port) { + const mappingHostNames = _certPromiseObj.mappingHostNames + for (let j = 0; j < mappingHostNames.length; j++) { + const DNSName = mappingHostNames[j] + if (tlsUtils.isMappingHostName(DNSName, hostname)) { + this.reRankCert(i) + return _certPromiseObj.promise + } } } } const certPromiseObj = { + port, mappingHostNames: [hostname] // temporary hostname } @@ -45,8 +58,13 @@ module.exports = class CertAndKeyContainer { const _resolve = (_certObj) => { if (once) { once = false - const mappingHostNames = tlsUtils.getMappingHostNamesFromCert(_certObj.cert) - certPromiseObj.mappingHostNames = mappingHostNames // change + let newMappingHostNames = tlsUtils.getMappingHostNamesFromCert(_certObj.cert) + newMappingHostNames = [...new Set(newMappingHostNames)] + + if (!arraysHaveSameElements(newMappingHostNames, certPromiseObj.mappingHostNames)) { + log.info(`【getCertPromise - ${hostname}:${port}】Reset mappingHostNames: `, certPromiseObj.mappingHostNames, '变更为', newMappingHostNames) + certPromiseObj.mappingHostNames = newMappingHostNames // change + } resolve(_certObj) } } @@ -57,41 +75,41 @@ module.exports = class CertAndKeyContainer { _resolve(certObj) } else { // 这个太慢了 - const preReq = https.request({ - port: port, - hostname: hostname, - path: '/', - method: 'HEAD' - }, (preRes) => { - try { - const realCert = preRes.socket.getPeerCertificate() - if (realCert) { - try { - certObj = tlsUtils.createFakeCertificateByCA(this.caKey, this.caCert, realCert) - } catch (error) { - certObj = tlsUtils.createFakeCertificateByDomain(this.caKey, this.caCert, hostname) - } - } else { - certObj = tlsUtils.createFakeCertificateByDomain(this.caKey, this.caCert, hostname) - } - _resolve(certObj) - } catch (e) { - reject(e) - } - }) - preReq.setTimeout(~~this.getCertSocketTimeout, () => { - if (!certObj) { - certObj = tlsUtils.createFakeCertificateByDomain(this.caKey, this.caCert, hostname) - _resolve(certObj) - } - }) - preReq.on('error', (e) => { - if (!certObj) { - certObj = tlsUtils.createFakeCertificateByDomain(this.caKey, this.caCert, hostname) - _resolve(certObj) - } - }) - preReq.end() + // const preReq = https.request({ + // port: port, + // hostname: hostname, + // path: '/', + // method: 'HEAD' + // }, (preRes) => { + // try { + // const realCert = preRes.socket.getPeerCertificate() + // if (realCert) { + // try { + // certObj = tlsUtils.createFakeCertificateByCA(this.caKey, this.caCert, realCert) + // } catch (error) { + // certObj = tlsUtils.createFakeCertificateByDomain(this.caKey, this.caCert, hostname) + // } + // } else { + // certObj = tlsUtils.createFakeCertificateByDomain(this.caKey, this.caCert, hostname) + // } + // _resolve(certObj) + // } catch (e) { + // reject(e) + // } + // }) + // preReq.setTimeout(~~this.getCertSocketTimeout, () => { + // if (!certObj) { + // certObj = tlsUtils.createFakeCertificateByDomain(this.caKey, this.caCert, hostname) + // _resolve(certObj) + // } + // }) + // preReq.on('error', (e) => { + // if (!certObj) { + // certObj = tlsUtils.createFakeCertificateByDomain(this.caKey, this.caCert, hostname) + // _resolve(certObj) + // } + // }) + // preReq.end() } }) diff --git a/packages/mitmproxy/src/lib/proxy/tls/FakeServersCenter.js b/packages/mitmproxy/src/lib/proxy/tls/FakeServersCenter.js index c4aef53b9f..51dc2b356b 100644 --- a/packages/mitmproxy/src/lib/proxy/tls/FakeServersCenter.js +++ b/packages/mitmproxy/src/lib/proxy/tls/FakeServersCenter.js @@ -6,6 +6,16 @@ const pki = forge.pki // const colors = require('colors') const tls = require('tls') const log = require('../../../utils/util.log') + +function arraysHaveSameElements (arr1, arr2) { + if (arr1.length !== arr2.length) { + return false + } + const sortedArr1 = [...arr1].sort() + const sortedArr2 = [...arr2].sort() + return sortedArr1.every((value, index) => value === sortedArr2[index]) +} + module.exports = class FakeServersCenter { constructor ({ maxLength = 256, requestHandler, upgradeHandler, caCert, caKey, getCertSocketTimeout }) { this.queue = [] @@ -36,17 +46,20 @@ module.exports = class FakeServersCenter { getServerPromise (hostname, port) { for (let i = 0; i < this.queue.length; i++) { const serverPromiseObj = this.queue[i] - const mappingHostNames = serverPromiseObj.mappingHostNames - for (let j = 0; j < mappingHostNames.length; j++) { - const DNSName = mappingHostNames[j] - if (tlsUtils.isMappingHostName(DNSName, hostname)) { - this.reRankServer(i) - return serverPromiseObj.promise + if (serverPromiseObj.port === port) { + const mappingHostNames = serverPromiseObj.mappingHostNames + for (let j = 0; j < mappingHostNames.length; j++) { + const DNSName = mappingHostNames[j] + if (tlsUtils.isMappingHostName(DNSName, hostname)) { + this.reRankServer(i) + return serverPromiseObj.promise + } } } } const serverPromiseObj = { + port, mappingHostNames: [hostname] // temporary hostname } @@ -75,7 +88,7 @@ module.exports = class FakeServersCenter { cert, key, server: fakeServer, - port: 0 // if prot === 0 ,should listen server's `listening` event. + port: 0 // if port === 0 ,should listen server's `listening` event. } serverPromiseObj.serverObj = serverObj @@ -88,14 +101,27 @@ module.exports = class FakeServersCenter { log.debug(`【fakeServer request - ${hostname}:${port}】\r\n----- req -----\r\n`, req, '\r\n----- res -----\r\n', res) this.requestHandler(req, res, ssl) }) + let once = true fakeServer.on('listening', () => { log.debug(`【fakeServer listening - ${hostname}:${port}】no arguments...`) - serverPromiseObj.mappingHostNames = tlsUtils.getMappingHostNamesFromCert(certObj.cert) + if (cert && once) { + once = false + let newMappingHostNames = tlsUtils.getMappingHostNamesFromCert(cert) + newMappingHostNames = [...new Set(newMappingHostNames)] + if (!arraysHaveSameElements(serverPromiseObj.mappingHostNames, newMappingHostNames)) { + log.info(`【fakeServer listening - ${hostname}:${port}】Reset mappingHostNames: `, serverPromiseObj.mappingHostNames, '变更为', newMappingHostNames) + serverPromiseObj.mappingHostNames = newMappingHostNames + } + } resolve(serverObj) }) fakeServer.on('upgrade', (req, socket, head) => { const ssl = true - log.debug(`【fakeServer upgrade - ${hostname}:${port}】\r\n----- req -----\r\n`, req, '\r\n----- socket -----\r\n', socket, '\r\n----- head -----\r\n', head) + if (process.env.NODE_ENV === 'development') { + log.debug(`【fakeServer upgrade - ${hostname}:${port}】\r\n----- req -----\r\n`, req, '\r\n----- socket -----\r\n', socket, '\r\n----- head -----\r\n', head) + } else { + log.info(`【fakeServer upgrade - ${hostname}:${port}】`, req.url) + } this.upgradeHandler(req, socket, head, ssl) })