add ca helper when run anyproxy -i

check and help to generate the root CA when run in https interception mode, and install the CA after user's confirmation (Mac only for now)
This commit is contained in:
砚然
2018-06-30 18:01:53 +08:00
parent 71477d5aae
commit 0241b90e4d
7 changed files with 202 additions and 99 deletions

View File

@@ -1,11 +1,16 @@
'use strict'
const util = require('./util');
const EasyCert = require('node-easy-cert');
const co = require('co');
const os = require('os');
const inquirer = require('inquirer');
const util = require('./util');
const logUtil = require('./log');
const options = {
rootDirPath: util.getAnyProxyPath('certificates'),
inMemory: false,
defaultCertAttrs: [
{ name: 'countryName', value: 'CN' },
{ name: 'organizationName', value: 'AnyProxy' },
@@ -54,4 +59,43 @@ crtMgr.getCAStatus = function *() {
});
}
/**
* trust the root ca by command
*/
crtMgr.trustRootCA = function *() {
const platform = os.platform();
const rootCAPath = crtMgr.getRootCAFilePath();
const trustInquiry = [
{
type: 'list',
name: 'trustCA',
message: 'The rootCA is not trusted yet, install it to the trust store now?',
choices: ['Yes', "No, I'll do it myself"]
}
];
if (platform === 'darwin') {
const answer = yield inquirer.prompt(trustInquiry);
if (answer.trustCA === 'Yes') {
logUtil.info('About to trust the root CA, this may requires your password');
// https://ss64.com/osx/security-cert.html
const result = util.execScriptSync(`sudo security add-trusted-cert -d -k /Library/Keychains/System.keychain ${rootCAPath}`);
if (result.status === 0) {
logUtil.info('Root CA install, you are ready to intercept the https now');
} else {
console.error(result);
logUtil.info('Failed to trust the root CA, please trust it manually');
}
} else {
logUtil.info('Please trust the root CA manually so https interception works');
}
}
if (/^win/.test(process.platform)) {
logUtil.info('You can install the root CA manually.');
}
logUtil.info('The root CA file path is: ' + crtMgr.getRootCAFilePath());
}
module.exports = crtMgr;

View File

@@ -58,7 +58,7 @@ function printLog(content, type) {
return;
}
console.error(color.magenta(`[AnyProxy WARN][${timeString}]: ` + content));
console.error(color.yellow(`[AnyProxy WARN][${timeString}]: ` + content));
break;
}
@@ -89,7 +89,7 @@ module.exports.warn = (content) => {
};
module.exports.error = (content) => {
printLog(content, LogLevelMap.error);
printLog(content, LogLevelMap.system_error);
};
module.exports.ruleError = (content) => {

View File

@@ -4,7 +4,7 @@ const fs = require('fs'),
path = require('path'),
mime = require('mime-types'),
color = require('colorful'),
crypto = require('crypto'),
child_process = require('child_process'),
Buffer = require('buffer').Buffer,
logUtil = require('./log');
const networkInterfaces = require('os').networkInterfaces();
@@ -216,6 +216,8 @@ function deleteFolderContentsRecursive(dirPath, ifClearFolderItself) {
throw new Error('can_not_delete_this_dir');
}
console.info('==>>> delete cache ', dirPath);
if (fs.existsSync(dirPath)) {
fs.readdirSync(dirPath).forEach((file) => {
const curPath = path.join(dirPath, file);
@@ -307,17 +309,18 @@ module.exports.isIpDomain = function (domain) {
return ipReg.test(domain);
};
/**
* To generic a Sec-WebSocket-Accept value
* 1. append the `Sec-WebSocket-Key` request header with `matic string`
* 2. get sha1 hash of the string
* 3. get base64 of the sha1 hash
*/
module.exports.genericWsSecAccept = function (wsSecKey) {
// the string to generate the Sec-WebSocket-Accept
const magicString = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
const targetString = `${wsSecKey}${magicString}`;
const shasum = crypto.createHash('sha1');
shasum.update(targetString);
return shasum.digest('base64');
}
module.exports.execScriptSync = function (cmd) {
let stdout,
status = 0;
try {
stdout = child_process.execSync(cmd);
} catch (err) {
stdout = err.stdout;
status = err.status;
}
return {
stdout: stdout.toString(),
status
};
};