Browse Source

Merge remote-tracking branch 'origin/master'

pull/192/head
xiaojunnuo 3 years ago
parent
commit
9a47914c57
  1. 7078
      package-lock.json
  2. 3
      package.json
  3. 5
      packages/core/src/config/index.js
  4. 21
      packages/core/src/shell/scripts/set-system-proxy/index.js
  5. 4
      packages/core/src/shell/scripts/setup-ca.js
  6. 25
      packages/core/src/shell/shell.js
  7. 12
      packages/core/start/mitmproxy.js
  8. 45
      packages/core/start/user_config.json5
  9. 8
      packages/core/yarn.lock
  10. 21
      packages/gui/package.json
  11. BIN
      packages/gui/public/setup-linux.png
  12. 20
      packages/gui/src/background.js
  13. 10
      packages/gui/src/view/components/setup-ca.vue
  14. 61
      packages/gui/src/view/pages/server.vue
  15. 85
      packages/gui/yarn.lock
  16. 4
      packages/mitmproxy/src/index.js
  17. 41
      packages/mitmproxy/src/lib/proxy/mitmproxy/createConnectHandler.js
  18. 25
      packages/mitmproxy/src/lib/proxy/mitmproxy/index.js
  19. 169
      packages/mitmproxy/src/lib/proxy/tls/sniUtil.js
  20. 32
      packages/mitmproxy/src/lib/proxy/tls/tlsUtils.js
  21. 9
      packages/mitmproxy/src/options.js
  22. 3
      packages/mitmproxy/src/utils/util.match.js
  23. 40
      packages/mitmproxy/yarn-error.log

7078
package-lock.json generated

File diff suppressed because it is too large Load Diff

3
package.json

@ -6,6 +6,5 @@
"devDependencies": {
"lerna": "^3.22.1"
},
"dependencies": {
}
"dependencies": {}
}

5
packages/core/src/config/index.js

@ -157,6 +157,9 @@ module.exports = {
'pay.weixin.qq.com': true,
'www.baidu.com': true
},
// sniList: {
// 'github.com': 'abaidu.com'
// },
dns: {
providers: {
aliyun: {
@ -212,7 +215,7 @@ module.exports = {
},
speedTest: {
enabled: true,
interval: 60000,
interval: 160000,
hostnameList: ['github.com'],
dnsProviders: ['usa', 'quad9', 'rubyfish']
}

21
packages/core/src/shell/scripts/set-system-proxy/index.js

@ -122,7 +122,26 @@ const executor = {
}
},
async linux (exec, params) {
throw Error('暂未实现此功能')
if (params != null) {
const { ip, port } = params
// const local = 'localhost, 127.0.0.0/8, ::1'
const setProxyCmd = [
'gsettings set org.gnome.system.proxy mode manual',
`gsettings set org.gnome.system.proxy.https port ${port}`,
`gsettings set org.gnome.system.proxy.https host ${ip}`,
`gsettings set org.gnome.system.proxy.http port ${port}`,
`gsettings set org.gnome.system.proxy.http host ${ip}`
// `gsettings set org.gnome.system.proxy ignore-hosts "${local}"`
]
await exec(setProxyCmd)
} else {
const setProxyCmd = [
'gsettings set org.gnome.system.proxy mode none'
]
await exec(setProxyCmd)
}
},
async mac (exec, params) {
// exec = _exec

4
packages/core/src/shell/scripts/setup-ca.js

@ -8,9 +8,9 @@ const executor = {
return true
},
async linux (exec, { certPath }) {
const cmds = ['open "' + certPath + '"']
const cmds = [`sudo cp ${certPath} /usr/local/share/ca-certificates`, 'sudo update-ca-certificates ']
// eslint-disable-next-line no-unused-vars
const ret = await exec(cmds, { type: 'cmd' })
const ret = await exec(cmds)
return true
},
async mac (exec, { certPath }) {

25
packages/core/src/shell/shell.js

@ -21,7 +21,7 @@ class LinuxSystemShell extends SystemShell {
cmds = [cmds]
}
for (const cmd of cmds) {
await childExec(cmd)
await _childExec(cmd, { shell: '/bin/bash' })
}
}
}
@ -33,7 +33,7 @@ class DarwinSystemShell extends SystemShell {
}
let ret
for (const cmd of cmds) {
ret = await childExec(cmd)
ret = await _childExec(cmd)
}
return ret
}
@ -76,13 +76,31 @@ class WindowsSystemShell extends SystemShell {
}
}
function childExec (composeCmds) {
function _childExec (composeCmds, options = {}) {
return new Promise((resolve, reject) => {
const childProcess = require('child_process')
log.info('shell:', composeCmds)
childProcess.exec(composeCmds, options, function (error, stdout, stderr) {
if (error) {
log.error('cmd 命令执行错误:', composeCmds, stderr)
reject(new Error(stderr))
} else {
// log.info('cmd 命令完成:', stdout)
resolve(stdout)
}
// log.info('关闭 cmd')
// ps.kill('SIGINT')
})
})
}
function childExec (composeCmds) {
return new Promise((resolve, reject) => {
var encoding = 'cp936'
var binaryEncoding = 'binary'
const childProcess = require('child_process')
log.info('shell:', composeCmds)
childProcess.exec(composeCmds, { encoding: binaryEncoding }, function (error, stdout, stderr) {
if (error) {
// console.log('------', decoder.decode(stderr))
@ -120,6 +138,7 @@ function getSystemPlatform () {
case 'linux':
return 'linux'
case 'win32':
return 'windows'
case 'win64':
return 'windows'
case 'unknown os':

12
packages/core/start/mitmproxy.js

@ -2,7 +2,7 @@
const server = require('@docmirror/mitmproxy')
const JSON5 = require('json5')
const path = require('path')
const home = process.env.HOME
const home = process.env.USER_HOME || process.env.HOME || 'C:/Users/xiaoj/'
let configPath = path.join(home, '.dev-sidecar/running.json')
if (process.argv && process.argv.length > 3) {
configPath = process.argv[2]
@ -11,9 +11,9 @@ if (process.argv && process.argv.length > 3) {
const fs = require('fs')
const configJson = fs.readFileSync(configPath)
const config = JSON5.parse(configJson)
const scriptDir = '../../gui/extra/scripts/'
config.setting.script.defaultDir = path.join(__dirname, scriptDir)
const pacFilePath = '../../gui/extra/pac/pac.txt'
config.plugin.overwall.pac.customPacFilePath = path.join(__dirname, pacFilePath)
// const scriptDir = '../../gui/extra/scripts/'
// config.setting.script.defaultDir = path.join(__dirname, scriptDir)
// const pacFilePath = '../../gui/extra/pac/pac.txt'
// config.plugin.overwall.pac.customPacFilePath = path.join(__dirname, pacFilePath)
config.setting.rootDir = path.join(__dirname, '../../gui/')
server.start(config)

45
packages/core/start/user_config.json5

@ -1,24 +1,31 @@
{
server: {
intercepts: {
'github1.githubassets.com': {
'.*': {
redirect: 'assets.fastgit.org',
test: 'https://github.githubassets.com/favicons/favicon.svg',
desc: '静态资源加速'
}
},
'github.githubassets.com': null,
'notify3.note.youdao.com': {
'/pushserver3/.*': {
abort: true
},
}
app: {
autoStart: {
enabled: true,
},
mode: 'safe',
},
plugin: {
node: {
enabled: true
}
}
}
setting: {
yarnRegistry: null,
},
},
git: {
enabled: true,
},
overwall: {
targets: {
'*yonsz.net': true,
'*bootstrapcdn.com': true,
'*cloudflare.com': true,
'help.yonsz.net': true,
},
},
},
server: {
intercept: {
enabled: false,
},
},
}

8
packages/core/yarn.lock

@ -93,10 +93,10 @@
lodash "^4.17.19"
to-fast-properties "^2.0.0"
"@docmirror/mitmproxy@^1.5.0":
version "1.5.0"
resolved "https://registry.npmjs.org/@docmirror/mitmproxy/-/mitmproxy-1.5.0.tgz#16b9a956542a56f9889cd0c69c08a33d06d77ab8"
integrity sha512-H17TAqKmvzCMSTO6VGTC6kKQskjk1gEJZYsU2ijziZU0XEC96ObG0TWOnsdKh2PhmwDLwxS9cUyb1hpYilLreQ==
"@docmirror/mitmproxy@^1.5.1":
version "1.5.1"
resolved "https://registry.nlark.com/@docmirror/mitmproxy/download/@docmirror/mitmproxy-1.5.1.tgz#357142a41b89266491c3519a7528b9b83dc30c85"
integrity sha1-NXFCpBuJJmSRw1GadSi5uD3DDIU=
dependencies:
agentkeepalive "^2.1.1"
axios "^0.21.1"

21
packages/gui/package.json

@ -40,22 +40,23 @@
"vue-router": "^3.4.8"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"@vue/eslint-config-standard": "^5.1.2",
"babel-eslint": "^10.1.0",
"electron": "10.4.2",
"electron-devtools-installer": "^3.1.0",
"electron-icon-builder": "^1.0.2",
"eslint": "^6.7.2",
"eslint-plugin-import": "^2.20.2",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.0.0",
"eslint-plugin-vue": "^6.2.2",
"json5-loader": "^4.0.1",
"vue-cli-plugin-electron-builder": "^2.0.0-rc.4",
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"babel-eslint": "^10.1.0",
"electron": "^13.0.0",
"electron-devtools-installer": "^3.1.0",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^6.2.2",
"vue-cli-plugin-electron-builder": "~2.1.1",
"vue-template-compiler": "^2.6.11"
},
"eslintConfig": {
@ -79,4 +80,4 @@
],
"__npminstall_done": false,
"gitHead": "3566cd6d33cbe782d91e408d6f174dd826b2790f"
}
}

BIN
packages/gui/public/setup-linux.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 KiB

20
packages/gui/src/background.js

@ -75,6 +75,21 @@ function setTray (app) {
return appTray
}
function isLinux () {
const platform = DevSidecar.api.shell.getSystemPlatform()
return platform === 'linux'
}
function hideWin () {
if (win) {
if (isLinux()) {
win.minimize()
} else {
win.hide()
}
}
}
function createWindow () {
// Create the browser window.
@ -92,6 +107,7 @@ function createWindow () {
title: 'DevSidecar',
webPreferences: {
enableRemoteModule: true,
contextIsolation: false,
// preload: path.join(__dirname, 'preload.js'),
// Use pluginOptions.nodeIntegration, leave this alone
// See nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration for more info
@ -113,7 +129,7 @@ function createWindow () {
}
if (startHideWindow) {
win.hide()
hideWin()
}
win.on('closed', async (e) => {
@ -124,7 +140,7 @@ function createWindow () {
win.on('close', (e) => {
if (!forceClose) {
e.preventDefault()
win.hide()
hideWin()
}
})
}

10
packages/gui/src/view/components/setup-ca.vue

@ -21,13 +21,16 @@
2然后按如下图步骤将随机生成的根证书设置为始终信任<br/>
3可能需要重新启动应用和浏览器才能生效<br/>
</template>
<template v-else-if="this.systemPlatform === 'linux'">
1点击右上角点此去安装按钮,将自动安装到系统证书库中<br/>
2火狐chrome等浏览器不走系统证书需要手动安装(下图以chrome为例安装根证书)<br/>
</template>
<template v-else>
1点击右上角点此去安装按钮打开证书<br/>
2然后按如下图步骤将根证书添加到<b>信任的根证书颁发机构</b><br/>
</template>
</div>
<img width="100%" :src="setupImage" />
</a-drawer>
</template>
@ -59,6 +62,8 @@ export default {
setupImage () {
if (this.systemPlatform === 'mac') {
return '/setup-mac.png'
} else if (this.systemPlatform === 'linux') {
return '/setup-linux.png'
} else {
return '/setup.png'
}
@ -75,6 +80,9 @@ export default {
},
async doSetup () {
this.$emit('setup')
if (this.systemPlatform === 'linux') {
this.$message.success('根证书已成功安装到系统证书库(注意:浏览器仍然需要手动安装)')
}
}
}
}

61
packages/gui/src/view/pages/server.vue

@ -80,11 +80,9 @@
<a-button v-if="item.value!==false" type="danger" icon="minus" @click="deleteWhiteList(item,index)"/>
</a-col>
</a-row>
</a-tab-pane>
<a-tab-pane tab="DNS设置" key="4">
<div>
<a-row style="margin-top:10px">
<a-col span="19">
<div>这里配置哪些域名需要通过国外DNS服务器获取IP进行访问</div>
@ -110,10 +108,31 @@
@click="restoreDefDnsMapping(item,index)"></a-button>
</a-col>
</a-row>
</div>
</a-tab-pane>
<a-tab-pane tab="IP测速" key="5">
<!-- <a-tab-pane tab="SNI" key="5">-->
<!-- <a-row style="margin-top:10px">-->
<!-- <a-col span="19">-->
<!-- <div>这里配置哪些域名要修改sni</div>-->
<!-- </a-col>-->
<!-- <a-col span="3">-->
<!-- <a-button style="margin-left:8px" type="primary" icon="plus" @click="addSniList()"/>-->
<!-- </a-col>-->
<!-- </a-row>-->
<!-- <a-row :gutter="10" style="margin-top: 10px" v-for="(item,index) of sniList" :key='index'>-->
<!-- <a-col :span="14">-->
<!-- <a-input v-model="item.key"></a-input>-->
<!-- </a-col>-->
<!-- <a-col :span="5">-->
<!-- <a-input v-model="item.value"></a-input>-->
<!-- </a-col>-->
<!-- <a-col :span="3">-->
<!-- <a-button type="danger" icon="minus" @click="deleteSniList(item,index)"/>-->
<!-- </a-col>-->
<!-- </a-row>-->
<!-- </a-tab-pane>-->
<a-tab-pane tab="IP测速" key="6">
<div>
<a-alert type="info" message="对从dns获取到的ip进行测速,使用速度最快的ip进行访问。(对使用增强功能的域名没啥用)"></a-alert>
<a-form-item label="开启dns测速" :label-col="labelCol" :wrapper-col="wrapperCol">
@ -207,7 +226,8 @@ export default {
wrapperCol: { span: 20 },
dnsMappings: [],
speedTestList: [],
whiteList: []
whiteList: [],
sniList: []
}
},
created () {
@ -249,6 +269,7 @@ export default {
ready () {
this.initDnsMapping()
this.initWhiteList()
this.initSniList()
if (this.config.server.dns.speedTest.dnsProviders) {
this.speedDns = this.config.server.dns.speedTest.dnsProviders
}
@ -256,6 +277,7 @@ export default {
async applyBefore () {
this.submitDnsMapping()
this.submitWhiteList()
this.submitSniList()
},
async applyAfter () {
if (this.status.server.enabled) {
@ -320,6 +342,35 @@ export default {
this.whiteList.unshift({ key: '', value: true })
},
// sniList
initSniList () {
this.sniList = []
for (const key in this.config.server.sniList) {
const value = this.config.server.sniList[key]
this.sniList.push({
key, value
})
}
},
submitSniList () {
const sniList = {}
for (const item of this.sniList) {
if (item.key) {
sniList[item.key] = item.value
}
}
this.config.server.sniList = sniList
},
deleteSniList (item, index) {
this.sniList.splice(index, 1)
},
restoreDefSniList (item, index) {
},
addSniList () {
this.sniList.unshift({ key: '', value: true })
},
async openLog () {
const dir = await this.$api.info.getConfigDir()
this.$api.ipc.openPath(dir + '/logs/')

85
packages/gui/yarn.lock

@ -1507,10 +1507,10 @@
resolved "https://registry.npm.taobao.org/@types/node/download/@types/node-14.11.8.tgz"
integrity sha1-/iAS8jVeTOCLykSus6u7Ic+I0z8=
"@types/node@^12.0.12":
version "12.20.6"
resolved "https://registry.npmjs.org/@types/node/-/node-12.20.6.tgz"
integrity sha512-sRVq8d+ApGslmkE9e3i+D3gFGk7aZHAT+G4cIpIEdLJYPsWiSPwcAnJEjddLQQDqV3Ra2jOclX/Sv6YrvGYiWA==
"@types/node@^14.6.2":
version "14.17.9"
resolved "https://registry.nlark.com/@types/node/download/@types/node-14.17.9.tgz#b97c057e6138adb7b720df2bd0264b03c9f504fd"
integrity sha1-uXwFfmE4rbe3IN8r0CZLA8n1BP0=
"@types/normalize-package-data@^2.4.0":
version "2.4.0"
@ -1823,6 +1823,24 @@
optionalDependencies:
vue-loader-v16 "npm:vue-loader@^16.0.0-beta.7"
"@vue/cli-shared-utils@^4.5.6":
version "4.5.13"
resolved "https://registry.nlark.com/@vue/cli-shared-utils/download/@vue/cli-shared-utils-4.5.13.tgz?cache=0&sync_timestamp=1628579241293&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40vue%2Fcli-shared-utils%2Fdownload%2F%40vue%2Fcli-shared-utils-4.5.13.tgz#acd40f31b4790f1634292bdaa5fca95dc1e0ff50"
integrity sha1-rNQPMbR5DxY0KSvapfypXcHg/1A=
dependencies:
"@hapi/joi" "^15.0.1"
chalk "^2.4.2"
execa "^1.0.0"
launch-editor "^2.2.1"
lru-cache "^5.1.1"
node-ipc "^9.1.1"
open "^6.3.0"
ora "^3.4.0"
read-pkg "^5.1.1"
request "^2.88.2"
semver "^6.1.0"
strip-ansi "^6.0.0"
"@vue/cli-shared-utils@^4.5.7":
version "4.5.7"
resolved "https://registry.npm.taobao.org/@vue/cli-shared-utils/download/@vue/cli-shared-utils-4.5.7.tgz?cache=0&sync_timestamp=1602060136132&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fcli-shared-utils%2Fdownload%2F%40vue%2Fcli-shared-utils-4.5.7.tgz"
@ -3876,7 +3894,7 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5:
shebang-command "^1.2.0"
which "^1.2.9"
cross-spawn@^7.0.0:
cross-spawn@^7.0.0, cross-spawn@^7.0.3:
version "7.0.3"
resolved "https://registry.npm.taobao.org/cross-spawn/download/cross-spawn-7.0.3.tgz"
integrity sha1-9zqFudXUHQRVUcF34ogtSshXKKY=
@ -4651,13 +4669,13 @@ electron-updater@^4.3.5:
lodash.isequal "^4.5.0"
semver "^7.3.2"
electron@10.4.2:
version "10.4.2"
resolved "https://registry.nlark.com/electron/download/electron-10.4.2.tgz?cache=0&sync_timestamp=1620442447118&other_urls=https%3A%2F%2Fregistry.nlark.com%2Felectron%2Fdownload%2Felectron-10.4.2.tgz#2322a72f1e653e023250be91f3dd8d27662e3805"
integrity sha1-IyKnLx5lPgIyUL6R892NJ2YuOAU=
electron@^13.0.0:
version "13.1.9"
resolved "https://registry.nlark.com/electron/download/electron-13.1.9.tgz#668e2632b81e9fa21edfd32876282d3e2ff7fd76"
integrity sha1-Zo4mMrgen6Ie39ModigtPi/3/XY=
dependencies:
"@electron/get" "^1.0.1"
"@types/node" "^12.0.12"
"@types/node" "^14.6.2"
extract-zip "^1.0.3"
elliptic@^6.5.3:
@ -5160,19 +5178,19 @@ execa@^3.3.0:
signal-exit "^3.0.2"
strip-final-newline "^2.0.0"
execa@^4.0.0:
version "4.0.3"
resolved "https://registry.npm.taobao.org/execa/download/execa-4.0.3.tgz"
integrity sha1-CjTau61tZhAL1vLFdshmlAPzF/I=
execa@^5.0.0:
version "5.1.1"
resolved "https://registry.nlark.com/execa/download/execa-5.1.1.tgz?cache=0&sync_timestamp=1622825396605&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fexeca%2Fdownload%2Fexeca-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd"
integrity sha1-+ArZy/Qpj3vR1MlVXCHpN0HEEd0=
dependencies:
cross-spawn "^7.0.0"
get-stream "^5.0.0"
human-signals "^1.1.1"
cross-spawn "^7.0.3"
get-stream "^6.0.0"
human-signals "^2.1.0"
is-stream "^2.0.0"
merge-stream "^2.0.0"
npm-run-path "^4.0.0"
onetime "^5.1.0"
signal-exit "^3.0.2"
npm-run-path "^4.0.1"
onetime "^5.1.2"
signal-exit "^3.0.3"
strip-final-newline "^2.0.0"
exif-parser@^0.1.12:
@ -5752,6 +5770,11 @@ get-stream@^5.0.0, get-stream@^5.1.0:
dependencies:
pump "^3.0.0"
get-stream@^6.0.0:
version "6.0.1"
resolved "https://registry.npm.taobao.org/get-stream/download/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7"
integrity sha1-omLY7vZ6ztV8KFKtYWdSakPL97c=
get-value@^2.0.3, get-value@^2.0.6:
version "2.0.6"
resolved "https://registry.npm.taobao.org/get-value/download/get-value-2.0.6.tgz"
@ -6252,6 +6275,11 @@ human-signals@^1.1.1:
resolved "https://registry.npm.taobao.org/human-signals/download/human-signals-1.1.1.tgz"
integrity sha1-xbHNFPUK6uCatsWf5jujOV/k36M=
human-signals@^2.1.0:
version "2.1.0"
resolved "https://registry.nlark.com/human-signals/download/human-signals-2.1.0.tgz?cache=0&sync_timestamp=1624364695595&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fhuman-signals%2Fdownload%2Fhuman-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0"
integrity sha1-3JH8ukLk0G5Kuu0zs+ejwC9RTqA=
icon-gen@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/icon-gen/-/icon-gen-2.0.0.tgz"
@ -8028,7 +8056,7 @@ npm-run-path@^2.0.0:
dependencies:
path-key "^2.0.0"
npm-run-path@^4.0.0:
npm-run-path@^4.0.0, npm-run-path@^4.0.1:
version "4.0.1"
resolved "https://registry.npm.taobao.org/npm-run-path/download/npm-run-path-4.0.1.tgz"
integrity sha1-t+zR5e1T2o43pV4cImnguX7XSOo=
@ -8179,7 +8207,7 @@ onetime@^2.0.0:
dependencies:
mimic-fn "^1.0.0"
onetime@^5.1.0:
onetime@^5.1.0, onetime@^5.1.2:
version "5.1.2"
resolved "https://registry.npm.taobao.org/onetime/download/onetime-5.1.2.tgz?cache=0&sync_timestamp=1597005345612&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fonetime%2Fdownload%2Fonetime-5.1.2.tgz"
integrity sha1-0Oluu1awdHbfHdnEgG5SN5hcpF4=
@ -10001,7 +10029,7 @@ shortid@^2.2.14:
dependencies:
nanoid "^2.1.0"
signal-exit@^3.0.0, signal-exit@^3.0.2:
signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3:
version "3.0.3"
resolved "https://registry.npm.taobao.org/signal-exit/download/signal-exit-3.0.3.tgz"
integrity sha1-oUEMLt2PB3sItOJTyOrPyvBXRhw=
@ -11267,14 +11295,15 @@ vm-browserify@^1.0.1:
resolved "https://registry.npm.taobao.org/vm-browserify/download/vm-browserify-1.1.2.tgz?cache=0&sync_timestamp=1589682787766&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvm-browserify%2Fdownload%2Fvm-browserify-1.1.2.tgz"
integrity sha1-eGQcSIuObKkadfUR56OzKobl3aA=
vue-cli-plugin-electron-builder@^2.0.0-rc.4:
version "2.0.0-rc.4"
resolved "https://registry.npm.taobao.org/vue-cli-plugin-electron-builder/download/vue-cli-plugin-electron-builder-2.0.0-rc.4.tgz"
integrity sha1-yBknngD+Z3GRL18EaO4m8nl1Cls=
vue-cli-plugin-electron-builder@~2.1.1:
version "2.1.1"
resolved "https://registry.nlark.com/vue-cli-plugin-electron-builder/download/vue-cli-plugin-electron-builder-2.1.1.tgz#de8bed25b32e73e28dd08061dd2a3c6bfff73227"
integrity sha1-3ovtJbMuc+KN0IBh3So8a//3Mic=
dependencies:
"@vue/cli-shared-utils" "^4.5.6"
chokidar "^3.0.2"
electron-builder "^22.2.0"
execa "^4.0.0"
execa "^5.0.0"
friendly-errors-webpack-plugin "^1.7.0"
fs-extra "^9.0.1"
lodash.merge "^4.6.1"

4
packages/mitmproxy/src/index.js

@ -34,6 +34,10 @@ function registerProcessListener () {
log.info('Unhandled Rejection at: Promise', p, 'err:', err)
// application specific logging, throwing an error, or other logic here
})
process.on('exit', function (code) {
log.info('代理服务进程被关闭:', code)
})
}
const api = {

41
packages/mitmproxy/src/lib/proxy/mitmproxy/createConnectHandler.js

@ -5,9 +5,9 @@ const log = require('../../../utils/util.log')
const DnsUtil = require('../../dns/index')
const localIP = '127.0.0.1'
const defaultDns = require('dns')
const matchUtil = require('../../../utils/util.match')
const speedTest = require('../../speed/index.js')
const sniExtract = require('../tls/sniUtil.js')
function isSslConnect (sslConnectInterceptors, req, cltSocket, head) {
for (const intercept of sslConnectInterceptors) {
const ret = intercept(req, cltSocket, head)
@ -19,7 +19,7 @@ function isSslConnect (sslConnectInterceptors, req, cltSocket, head) {
}
// create connectHandler function
module.exports = function createConnectHandler (sslConnectInterceptor, middlewares, fakeServerCenter, dnsConfig) {
module.exports = function createConnectHandler (sslConnectInterceptor, middlewares, fakeServerCenter, dnsConfig, sniConfig) {
// return
const sslConnectInterceptors = []
sslConnectInterceptors.push(sslConnectInterceptor)
@ -28,6 +28,9 @@ module.exports = function createConnectHandler (sslConnectInterceptor, middlewar
sslConnectInterceptors.push(middleware.sslConnectInterceptor)
}
}
console.log('sni config', sniConfig)
const sniRegexpMap = matchUtil.domainMapRegexply(sniConfig)
return function connectHandler (req, cltSocket, head) {
// eslint-disable-next-line node/no-deprecated-api
const srvUrl = url.parse(`https://${req.url}`)
@ -40,16 +43,17 @@ module.exports = function createConnectHandler (sslConnectInterceptor, middlewar
log.error('getServerPromise', e)
})
} else {
connect(req, cltSocket, head, hostname, srvUrl.port, dnsConfig)
connect(req, cltSocket, head, hostname, srvUrl.port, dnsConfig, sniRegexpMap)
}
}
}
function connect (req, cltSocket, head, hostname, port, dnsConfig) {
function connect (req, cltSocket, head, hostname, port, dnsConfig, sniRegexpMap) {
// tunneling https
// log.info('connect:', hostname, port)
const start = new Date().getTime()
let isDnsIntercept = null
const replaceSni = matchUtil.matchHostname(sniRegexpMap, hostname)
try {
const options = {
port,
@ -90,6 +94,33 @@ function connect (req, cltSocket, head, hostname, port, dnsConfig) {
proxySocket.pipe(cltSocket)
cltSocket.pipe(proxySocket)
// let sniReplaced = false
// cltSocket.on('data', (chunk) => {
// // if (replaceSni && sniReplaced === false) {
// // const sniPackage = sniExtract(chunk)
// // if (sniPackage != null) {
// // sniReplaced = true
// // const bytes = Buffer.from(replaceSni)
// // const start = sniPackage.start
// // const length = sniPackage.length
// // for (let i = 0; i < length; i++) {
// // let char = 97 // a 的ascii
// // if (bytes.length > i) {
// // char = bytes[i]
// // }
// // chunk[start + i] = char
// // }
// // }
// // }
// if (sniReplaced === false) {
// sniReplaced = true
// chunk[chunk.length - 1] = 1
// }
// proxySocket.write(chunk)
// })
// cltSocket.on('end', () => {
// proxySocket.end()
// })
})
cltSocket.on('error', (e) => {

25
packages/mitmproxy/src/lib/proxy/mitmproxy/index.js

@ -21,7 +21,8 @@ module.exports = {
middlewares = [],
externalProxy,
dnsConfig,
setting
setting,
sniConfig
}, callback) {
// Don't reject unauthorized
// process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'
@ -39,25 +40,6 @@ module.exports = {
log.info(`CA private key saved in: ${caKeyPath}`)
}
// function lookup (hostname, options, callback) {
// const dns = DnsUtil.hasDnsLookup(dnsConfig, hostname)
// if (dns) {
// dns.lookup(hostname).then(ip => {
// // isDnsIntercept = { dns, hostname, ip }
// if (ip !== hostname) {
// log.info(`-----${hostname} use ip:${ip}-----`)
// callback(null, ip, 4)
// } else {
// defaultDns.lookup(hostname, options, callback)
// }
// })
// } else {
// defaultDns.lookup(hostname, options, callback)
// }
// }
//
// https.globalAgent.lookup = lookup
port = ~~port
const speedTestConfig = dnsConfig.speedTest
@ -95,7 +77,8 @@ module.exports = {
sslConnectInterceptor,
middlewares,
fakeServersCenter,
dnsConfig
dnsConfig,
sniConfig
)
const server = new http.Server()

169
packages/mitmproxy/src/lib/proxy/tls/sniUtil.js

@ -0,0 +1,169 @@
module.exports = function extractSNI (data) {
/*
From https://tools.ietf.org/html/rfc5246:
enum {
hello_request(0), client_hello(1), server_hello(2),
certificate(11), server_key_exchange (12),
certificate_request(13), server_hello_done(14),
certificate_verify(15), client_key_exchange(16),
finished(20)
(255)
} HandshakeType;
struct {
HandshakeType msg_type;
uint24 length;
select (HandshakeType) {
case hello_request: HelloRequest;
case client_hello: ClientHello;
case server_hello: ServerHello;
case certificate: Certificate;
case server_key_exchange: ServerKeyExchange;
case certificate_request: CertificateRequest;
case server_hello_done: ServerHelloDone;
case certificate_verify: CertificateVerify;
case client_key_exchange: ClientKeyExchange;
case finished: Finished;
} body;
} Handshake;
struct {
uint8 major;
uint8 minor;
} ProtocolVersion;
struct {
uint32 gmt_unix_time;
opaque random_bytes[28];
} Random;
opaque SessionID<0..32>;
uint8 CipherSuite[2];
enum { null(0), (255) } CompressionMethod;
struct {
ProtocolVersion client_version;
Random random;
SessionID session_id;
CipherSuite cipher_suites<2..2^16-2>;
CompressionMethod compression_methods<1..2^8-1>;
select (extensions_present) {
case false:
struct {};
case true:
Extension extensions<0..2^16-1>;
};
} ClientHello;
*/
var end = data.length
// skip the record header
var pos = 5
// skip HandshakeType (you should already have verified this)
pos += 1
// skip handshake length
pos += 3
// skip protocol version (you should already have verified this)
pos += 2
// skip Random
pos += 32
// skip SessionID
if (pos > end - 1) return null
var sessionIdLength = data[pos]
pos += 1 + sessionIdLength
// skip CipherSuite
if (pos > end - 2) return null
var cipherSuiteLength = data[pos] << 8 | data[pos + 1]
pos += 2 + cipherSuiteLength
// skip CompressionMethod
if (pos > end - 1) return null
var compressionMethodLength = data[pos]
pos += 1 + compressionMethodLength
// verify extensions exist
if (pos > end - 2) return null
var extensionsLength = data[pos] << 8 | data[pos + 1]
pos += 2
// verify the extensions fit
var extensionsEnd = pos + extensionsLength
if (extensionsEnd > end) return null
end = extensionsEnd
/*
From https://tools.ietf.org/html/rfc5246
and http://tools.ietf.org/html/rfc6066:
struct {
ExtensionType extension_type;
opaque extension_data<0..2^16-1>;
} Extension;
enum {
signature_algorithms(13), (65535)
} ExtensionType;
enum {
server_name(0), max_fragment_length(1),
client_certificate_url(2), trusted_ca_keys(3),
truncated_hmac(4), status_request(5), (65535)
} ExtensionType;
struct {
NameType name_type;
select (name_type) {
case host_name: HostName;
} name;
} ServerName;
enum {
host_name(0), (255)
} NameType;
opaque HostName<1..2^16-1>;
struct {
ServerName server_name_list<1..2^16-1>
} ServerNameList;
*/
while (pos <= end - 4) {
var extensionType = data[pos] << 8 | data[pos + 1]
var extensionSize = data[pos + 2] << 8 | data[pos + 3]
pos += 4
if (extensionType === 0) { // ExtensionType was server_name(0)
// read ServerNameList length
if (pos > end - 2) return null
var nameListLength = data[pos] << 8 | data[pos + 1]
pos += 2
// verify we have enough bytes and loop over SeverNameList
var n = pos
pos += nameListLength
if (pos > end) return null
while (n < pos - 3) {
var nameType = data[n]
var nameLength = data[n + 1] << 8 | data[n + 2]
n += 3
// check if NameType is host_name(0)
if (nameType === 0) {
// verify we have enough bytes
if (n > end - nameLength) return null
// decode as ascii and return
const sniName = data.toString('ascii', n, n + nameLength)
return {
sniName,
start: n,
end: n + nameLength,
length: nameLength
}
} else {
n += nameLength
}
}
} else { // ExtensionType was something we are not interested in
pos += extensionSize
}
}
return null
}

32
packages/mitmproxy/src/lib/proxy/tls/tlsUtils.js

@ -51,11 +51,13 @@ utils.createCA = function (CN) {
name: 'basicConstraints',
critical: true,
cA: true
}, {
},
{
name: 'keyUsage',
critical: true,
keyCertSign: true
}, {
},
{
name: 'subjectKeyIdentifier'
}])
@ -111,19 +113,19 @@ utils.createFakeCertificateByDomain = function (caKey, caCert, domain) {
critical: true,
cA: false
},
{
name: 'keyUsage',
critical: true,
digitalSignature: true,
contentCommitment: true,
keyEncipherment: true,
dataEncipherment: true,
keyAgreement: true,
keyCertSign: true,
cRLSign: true,
encipherOnly: true,
decipherOnly: true
},
// {
// name: 'keyUsage',
// critical: true,
// digitalSignature: true,
// contentCommitment: true,
// keyEncipherment: true,
// dataEncipherment: true,
// keyAgreement: true,
// keyCertSign: true,
// cRLSign: true,
// encipherOnly: true,
// decipherOnly: true
// },
{
name: 'subjectAltName',
altNames: [{

9
packages/mitmproxy/src/options.js

@ -13,10 +13,14 @@ module.exports = (config) => {
const serverConfig = config
const setting = serverConfig.setting
setting.script.dirAbsolutePath = path.join(setting.rootDir, setting.script.defaultDir)
if (!setting.script.dirAbsolutePath) {
setting.script.dirAbsolutePath = path.join(setting.rootDir, setting.script.defaultDir)
}
const overwallConfig = serverConfig.plugin.overwall
overwallConfig.pac.pacFileAbsolutePath = path.join(setting.rootDir, overwallConfig.pac.pacFilePath)
if (!overwallConfig.pac.pacFileAbsolutePath) {
overwallConfig.pac.pacFileAbsolutePath = path.join(setting.rootDir, overwallConfig.pac.pacFilePath)
}
const overwallMiddleware = createOverwallMiddleware(overwallConfig)
const middlewares = []
if (overwallMiddleware) {
@ -30,6 +34,7 @@ module.exports = (config) => {
speedTest: config.dns.speedTest
},
setting,
sniConfig: serverConfig.sniList,
middlewares,
sslConnectInterceptor: (req, cltSocket, head) => {
const hostname = req.url.split(':')[0]

3
packages/mitmproxy/src/utils/util.match.js

@ -24,6 +24,9 @@ function domainMapRegexply (hostMap) {
}
function matchHostname (hostMap, hostname) {
if (hostMap == null) {
return null
}
const value = hostMap[hostname]
if (value) {
return value

40
packages/mitmproxy/yarn-error.log

@ -1,33 +1,25 @@
Arguments:
/usr/local/bin/node /usr/local/bin/yarn install
/usr/bin/node /usr/local/bin/yarn install
PATH:
/usr/local/lib/ruby/gems/3.0.0/bin:/usr/local/opt/ruby/bin:/usr/local/opt/openssl@1.1/bin:/usr/local/sbin:/usr/local/bin:/usr/local/sbin:/usr/local/bin:/Users/daiboning/.npm-global/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin:/Users/daiboning/Desktop/codes/dev-sidecar/node_modules/.bin
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
Yarn version:
1.22.10
1.22.11
Node version:
14.15.4
14.17.5
Platform:
darwin x64
linux x64
Trace:
Error: https://registry.npm.taobao.org/string.prototype.trimend/download/string.prototype.trimend-1.0.2.tgz?cache=0&sync_timestamp=1603219618123&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstring.prototype.trimend%2Fdownload%2Fstring.prototype.trimend-1.0.2.tgz: tunneling socket could not be established, cause=connect ECONNREFUSED 127.0.0.1:1181
at ClientRequest.onError (/usr/local/lib/node_modules/yarn/lib/cli.js:152235:17)
at Object.onceWrapper (events.js:422:26)
at ClientRequest.emit (events.js:315:20)
at Socket.socketErrorListener (_http_client.js:469:9)
at Socket.emit (events.js:315:20)
at emitErrorNT (internal/streams/destroy.js:106:8)
at emitErrorCloseNT (internal/streams/destroy.js:74:3)
at processTicksAndRejections (internal/process/task_queues.js:80:21)
Error: ENOENT: no such file or directory, copyfile '/home/xiaojunnuo/.cache/yarn/v6/npm-webpack-4.44.2-6bfe2b0af055c8b2d1e90ed2cd9363f841266b72-integrity/node_modules/webpack/declarations/plugins/BannerPlugin.d.ts' -> '/home/xiaojunnuo/Codes/dev-sidecar/packages/mitmproxy/node_modules/webpack/declarations/plugins/BannerPlugin.d.ts'
npm manifest:
{
"name": "@docmirror/mitmproxy",
"version": "1.4.0",
"version": "1.5.1",
"description": "",
"main": "src/index.js",
"keywords": [
@ -56,6 +48,7 @@ npm manifest:
"node-cmd": "^3.0.0",
"node-forge": "^0.8.2",
"require-context": "^1.1.0",
"stream-throttle": "^0.1.3",
"through2": "^2.0.1",
"tunnel-agent": "^0.4.3",
"util": "^0.12.3",
@ -92,7 +85,7 @@ npm manifest:
"last 2 versions",
"not dead"
],
"gitHead": "660c77e4279c1499f771270941526614f927bdf1"
"gitHead": "3566cd6d33cbe782d91e408d6f174dd826b2790f"
}
yarn manifest:
@ -2104,7 +2097,7 @@ Lockfile:
dependencies:
delayed-stream "~1.0.0"
commander@^2.20.0, commander@^2.9.0:
commander@^2.2.0, commander@^2.20.0, commander@^2.9.0:
version "2.20.3"
resolved "https://registry.npm.taobao.org/commander/download/commander-2.20.3.tgz?cache=0&sync_timestamp=1603599636161&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcommander%2Fdownload%2Fcommander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
integrity sha1-/UhehMA+tIgcIHIrpIA16FMa6zM=
@ -3898,6 +3891,11 @@ Lockfile:
prelude-ls "~1.1.2"
type-check "~0.3.2"
limiter@^1.0.5:
version "1.1.5"
resolved "https://registry.npm.taobao.org/limiter/download/limiter-1.1.5.tgz#8f92a25b3b16c6131293a0cc834b4a838a2aa7c2"
integrity sha1-j5KiWzsWxhMSk6DMg0tKg4oqp8I=
lines-and-columns@^1.1.6:
version "1.1.6"
resolved "https://registry.npm.taobao.org/lines-and-columns/download/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00"
@ -5387,6 +5385,14 @@ Lockfile:
resolved "https://registry.npm.taobao.org/stream-shift/download/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d"
integrity sha1-1wiCgVWasneEJCebCHfaPDktWj0=
stream-throttle@^0.1.3:
version "0.1.3"
resolved "https://registry.npm.taobao.org/stream-throttle/download/stream-throttle-0.1.3.tgz#add57c8d7cc73a81630d31cd55d3961cfafba9c3"
integrity sha1-rdV8jXzHOoFjDTHNVdOWHPr7qcM=
dependencies:
commander "^2.2.0"
limiter "^1.0.5"
streamroller@^2.2.4:
version "2.2.4"
resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-2.2.4.tgz#c198ced42db94086a6193608187ce80a5f2b0e53"

Loading…
Cancel
Save