Skip to content

Commit

Permalink
mistake header
Browse files Browse the repository at this point in the history
  • Loading branch information
Peter Xie authored and Peter Xie committed Oct 26, 2017
1 parent 0977914 commit 2c5d41b
Show file tree
Hide file tree
Showing 12 changed files with 189 additions and 177 deletions.
72 changes: 44 additions & 28 deletions app/compress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@
* limitations under the License.
*/

import * as crypto from 'crypto'
import * as Crypto from 'crypto'
import * as Async from 'async'
import * as Stream from 'stream'
import * as Net from 'net'
import HttpHeader from './httpProxy'
const EOF = Buffer.from ( '\r\n\r\n', 'utf8' )
import * as fs from 'fs'
export interface packetBuffer {
Expand All @@ -36,20 +37,20 @@ export interface pairConnect {
export const encrypt = ( text: Buffer, masterkey: string, CallBack ) => {
let salt = null
Async.waterfall ([
next => crypto.randomBytes ( 64, next ),
next => Crypto.randomBytes ( 64, next ),
( _salt, next ) => {
salt = _salt
crypto.pbkdf2 ( masterkey, salt, 2145, 32, 'sha512', next )
Crypto.pbkdf2 ( masterkey, salt, 2145, 32, 'sha512', next )
}
], ( err, derivedKey ) => {
if ( err )
return CallBack ( err )

crypto.randomBytes ( 12, ( err1, iv ) => {
Crypto.randomBytes ( 12, ( err1, iv ) => {
if ( err1 )
return CallBack ( err1 )

const cipher = crypto.createCipheriv ( 'aes-256-gcm', derivedKey, iv );
const cipher = Crypto.createCipheriv ( 'aes-256-gcm', derivedKey, iv );

let _text = Buffer.concat ([ Buffer.alloc ( 4, 0 ) , text ])
_text.writeUInt32BE ( text.length, 0 )
Expand Down Expand Up @@ -82,13 +83,13 @@ export const decrypt = ( data: Buffer, masterkey, CallBack ) => {
const tag = data.slice ( 76, 92 );
const text = data.slice ( 92 );
// derive key using; 32 byte key length
crypto.pbkdf2 ( masterkey, salt , 2145, 32, 'sha512', ( err, derivedKey ) => {
Crypto.pbkdf2 ( masterkey, salt , 2145, 32, 'sha512', ( err, derivedKey ) => {

if ( err )
return CallBack ( err )
// AES 256 GCM Mode
try {
const decipher = crypto.createDecipheriv ( 'aes-256-gcm', derivedKey, iv )
const decipher = Crypto.createDecipheriv ( 'aes-256-gcm', derivedKey, iv )
decipher.setAuthTag ( tag )
const decrypted = Buffer.concat([decipher.update ( text ), decipher.final ( )])
const leng = decrypted.slice( 4, 4 + decrypted.readUInt32BE(0))
Expand Down Expand Up @@ -134,6 +135,27 @@ const HTTP_HEADER = Buffer.from (
`HTTP/1.1 200 OK\r\nDate: ${ new Date ().toUTCString ()}\r\nContent-Type: text/html\r\nTransfer-Encoding: chunked\r\nConnection: keep-alive\r\nVary: Accept-Encoding\r\n\r\n`, 'utf8')
const HTTP_EOF = Buffer.from ( '\r\n\r\n', 'utf8' )

const getHeaderString = ( headers, host: string, port: number ) => {
//console.trace (`getHeaderString header[${ !headers ? 'null': Object.keys ( headers ).forEach ( n => { return `${ n }: [${ + headers [ n ]}] ` }) }]`)
const ret = `Host: ${ host }${ port !== 80 ? ':' + port : '' }\r\n` +
( headers && headers['accept'] ? headers['accept'] : 'Accept: */*') + '\r\n' +
( headers && headers['accept-language'] ? headers['accept-language'] : 'Accept-Language: en-ca' ) + '\r\n' +
( headers && headers['connection'] ? headers['Connection'] : 'Connection: keep-alive' ) + '\r\n' +
( headers && headers['accept-encoding'] ? headers['accept-encoding'] : 'Accept-Encoding: gzip, deflate' ) + '\r\n' +
( headers && headers['user-agent'] ? headers[ 'user-agent'] : 'User-Agent: Mozilla/5.0' ) + '\r\n'
return ret
}

export const otherRequestForNet = ( path: string, host: string, port: number, headers: HttpHeader ) => {

if ( path.length < 2048 )
return `GET /${ path } HTTP/1.1\r\n` + getHeaderString ( headers && headers.headers ? headers: null, host, port ) + '\r\n'

return `POST /${ Crypto.randomBytes ( 4 + Math.random () * 100 ).toString ('base64') } HTTP/1.1\r\n` +
getHeaderString ( headers && headers.headers ? headers.headers: null, host, port ) + `Content-Length: ${ path.length }\r\n\r\n` + path + '\r\n\r\n'
}


export class encryptStream extends Stream.Transform {
private salt: Buffer
private iv: Buffer
Expand All @@ -143,16 +165,17 @@ export class encryptStream extends Stream.Transform {
private BlockBuffer ( _buf: Buffer ) {
return Buffer.from( _buf.length.toString( 16 ).toUpperCase() + '\r\n', 'utf8' )
}

private init ( callback ) {
return Async.waterfall ([
next => crypto.randomBytes ( 64, next ),
next => Crypto.randomBytes ( 64, next ),
( _salt, next ) => {
this.salt = _salt
crypto.randomBytes ( 12, next )
Crypto.randomBytes ( 12, next )
},
( _iv, next ) => {
this.iv = _iv
crypto.pbkdf2 ( this.password, this.salt, 2145, 32, 'sha512', next )
Crypto.pbkdf2 ( this.password, this.salt, 2145, 32, 'sha512', next )
}
], ( err, derivedKey ) => {

Expand All @@ -161,8 +184,10 @@ export class encryptStream extends Stream.Transform {
})
}

constructor ( private password: string, private random: number, private httpHeader : ( str: string ) => Buffer ) {
constructor ( private password: string, private random: number, private host: string, private port: number, private httpRequest: HttpHeader ) {

super ()
console.trace (`new encryptStream get httpRequest [${ httpRequest && httpRequest.headers ? JSON.stringify ( httpRequest.headers ): 'null'}]`)
}

public _transform ( chunk: Buffer, encode, cb ) {
Expand All @@ -171,7 +196,7 @@ export class encryptStream extends Stream.Transform {
return this._transform ( chunk, encode, cb )
})
}
const cipher = crypto.createCipheriv ( 'aes-256-gcm', this.derivedKey, this.iv )
const cipher = Crypto.createCipheriv ( 'aes-256-gcm', this.derivedKey, this.iv )

let _text = Buffer.concat ([ Buffer.alloc ( 4, 0 ) , chunk ])

Expand All @@ -186,22 +211,13 @@ export class encryptStream extends Stream.Transform {
if ( this.first ) {
this.first = false
const black = Buffer.concat ([ this.salt, this.iv, _buf1 ]).toString ( 'base64' )
if ( ! this.httpHeader ) {
const _buf4 = Buffer.from ( black, 'base64')
return cb ( null, Buffer.concat ([ HTTP_HEADER, this.BlockBuffer ( _buf4 ), _buf4, EOF ]))
}
const _buf2 = this.httpHeader ( black )

return cb ( null, _buf2 )

otherRequestForNet ( black, this.host, this.port, this.httpRequest )
return cb ( null, otherRequestForNet ( black, this.host, this.port, this.httpRequest ))
}

const _buf2 = _buf1.toString( 'base64' )

if ( this.httpHeader ) {
return cb ( null, this.httpHeader ( _buf2 ))
}
const _buf3 = Buffer.from ( _buf2, 'base64' )
return cb ( null, Buffer.concat ([ this.BlockBuffer ( _buf3 ), _buf3, EOF ]))
const _buf2 = _buf1.toString ( 'base64' )
return cb ( null, otherRequestForNet ( _buf2, this.host, this.port, this.httpRequest ))
}
}

Expand All @@ -213,7 +229,7 @@ export class decryptStream extends Stream.Transform {
private derivedKey: Buffer = null
private _decrypt ( _text: Buffer ) {

const decipher = crypto.createDecipheriv ( 'aes-256-gcm', this.derivedKey, this.iv )
const decipher = Crypto.createDecipheriv ( 'aes-256-gcm', this.derivedKey, this.iv )
decipher.setAuthTag ( _text.slice ( 0, 16 ))
try {
const _buf = Buffer.concat ([ decipher.update ( _text.slice ( 16 )), decipher.final () ])
Expand All @@ -233,7 +249,7 @@ export class decryptStream extends Stream.Transform {
public _First ( chunk: Buffer, CallBack: ( err?: Error, text?: Buffer ) => void ) {
this.salt = chunk.slice ( 0, 64 );
this.iv = chunk.slice ( 64, 76 );
return crypto.pbkdf2 ( this.password, this.salt , 2145, 32, 'sha512', ( err, derivedKey ) => {
return Crypto.pbkdf2 ( this.password, this.salt , 2145, 32, 'sha512', ( err, derivedKey ) => {
if ( err ) {
console.log ( `decryptStream crypto.pbkdf2 ERROR: ${ err.message }` )
return CallBack ( err )
Expand Down
46 changes: 13 additions & 33 deletions app/gateway.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,12 @@ import * as Dns from 'dns'
import * as Net from 'net'
import * as res from './res'
import * as Stream from 'stream'
import * as Crypto from 'crypto'
import { homedir } from 'os'
import HttpHeader from './httpProxy'

const Day = 1000 * 60 * 60 * 24

const otherRequestForNet = ( path: string, host: string, port: number, UserAgent: string ) => {
if ( path.length < 2048)
return `GET /${ path } HTTP/1.1\r\n` +
`Host: ${ host }:${ port }\r\n` +
`Accept: */*\r\n` +
`Accept-Language: en-ca\r\n` +
`Connection: keep-alive\r\n` +
`Accept-Encoding: gzip, deflate\r\n` +
`User-Agent: ${ UserAgent ? UserAgent : 'Mozilla/5.0' }\r\n\r\n`
return `POST /${ Buffer.allocUnsafe ( 10 + Math.random()).toString('base64') } HTTP/1.1\r\n` +
`Host: ${ host }:${ port }\r\n` +
`Content-Length: ${ path.length }\r\n\r\n` +
path + '\r\n\r\n'
}

class hostLookupResponse extends Stream.Writable {
constructor ( private CallBack: ( err?: Error, dns?: domainData ) => void ) { super ()}
public _write ( chunk: Buffer, enc, next ) {
Expand All @@ -59,24 +47,18 @@ class hostLookupResponse extends Stream.Writable {
}

export default class gateWay {

private userAgent = null

private request ( str: string ) {
return Buffer.from ( otherRequestForNet ( str, this.serverIp, this.serverPort, this.userAgent ), 'utf8' )
}
private httpHeader: HttpHeader = null

constructor ( public serverIp: string, public serverPort: number, private password: string ) {
}

public hostLookup ( hostName: string, userAgent: string, CallBack: ( err?: Error, hostIp?: domainData ) => void ) {
public hostLookup ( hostName: string, CallBack: ( err?: Error, hostIp?: domainData ) => void ) {


const _data = new Buffer ( JSON.stringify ({ hostName: hostName }), 'utf8' )

const encrypt = new Compress.encryptStream ( this.password, 0, ( str: string ) => {
return this.request ( str )
})
const encrypt = new Compress.encryptStream ( this.password, 1 + Math.random() * 1000, this.serverIp, this.serverPort, this.httpHeader )

const finish = new hostLookupResponse ( CallBack )
const httpBlock = new Compress.getDecryptClientStreamFromHttp ()
Expand Down Expand Up @@ -104,12 +86,12 @@ export default class gateWay {

}

public requestGetWay ( id: string, uuuu: VE_IPptpStream, userAgent: string, socket: Net.Socket ) {
this.userAgent = userAgent
public requestGetWay ( id: string, uuuu: VE_IPptpStream, httpHeader: HttpHeader, socket: Net.Socket ) {
if ( httpHeader )
this.httpHeader = httpHeader
console.trace ( 'requestGetWay',JSON.stringify ( this.httpHeader.headers ))
const decrypt = new Compress.decryptStream ( this.password )
const encrypt = new Compress.encryptStream ( this.password, 0, ( str: string ) => {
return this.request ( str )
})
const encrypt = new Compress.encryptStream ( this.password, 0, this.serverIp, this.serverPort, this.httpHeader )
const httpBlock = new Compress.getDecryptClientStreamFromHttp ()
httpBlock.once ( 'error', err => {
socket.end ( res._HTTP_404 )
Expand All @@ -123,14 +105,12 @@ export default class gateWay {
}

public requestGetWayTest ( id: string, uuuu: VE_IPptpStream, userAgent: string, socket: Net.Socket ) {
console.log ('connect to test port!')
console.log ( 'connect to test port!' )
const _socket = Net.createConnection ({ port: this.serverPort + 1, host: this.serverIp })

_socket.on ( 'connect', () => {
const ls = new Compress.printStream ('>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
const ls1 = new Compress.printStream ('<<<<<<<<<<<<<<<<<<<<<<<<<<<<')
_socket.pipe ( socket ).pipe ( _socket )
const _buf = Buffer.from ( otherRequestForNet ( Buffer.from ( JSON.stringify ( uuuu ), 'utf8' ).toString ( 'base64' ), this.serverIp, this.serverPort, this.userAgent ), 'utf8' )
const _buf = Buffer.from ( Compress.otherRequestForNet ( Buffer.from ( JSON.stringify ( uuuu ), 'utf8' ).toString ( 'base64' ), this.serverIp, this.serverPort, this.httpHeader ), 'utf8' )
_socket.write ( _buf )

})
Expand Down
43 changes: 21 additions & 22 deletions app/proxyServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import * as Net from 'net'
import * as Http from 'http'
import * as Dns from 'dns'
import HttpProxyHeader from './httpProxy'
import HttpHeader from './httpProxy'
import * as Async from 'async'
import * as Compress from './compress'
import * as util from 'util'
Expand All @@ -32,7 +32,8 @@ import * as Path from 'path'
import * as Socks from './socket5ForiOpn'
import gateWay from './gateway'
import * as Os from 'os'
const { remote } = require ( "electron" )

const { remote } = require ( 'electron' )

const whiteIpFile = 'whiteIpList.json'
Http.globalAgent.maxSockets = 1024
Expand Down Expand Up @@ -99,7 +100,7 @@ const otherRespon = ( path: string, host: string, port: number, UserAgent: strin

const testLogin = ( req: Buffer, loginUserList: string ) => {

const header = new HttpProxyHeader ( req )
const header = new HttpHeader ( req )
if ( header.isGet && header.Url.path === loginUserList )
return true

Expand Down Expand Up @@ -255,13 +256,13 @@ export const tryConnectHost = ( hostname: string, hostIp: domainData, port: numb

}

export const isAllBlackedByFireWall = ( hostName: string, ip6: boolean, gatway: gateWay, userAgent: string, domainListPool: Map < string, domainData >,
export const isAllBlackedByFireWall = ( hostName: string, ip6: boolean, gatway: gateWay, httpHead: HttpHeader, domainListPool: Map < string, domainData >,
CallBack: ( err?: Error, hostIp?: domainData ) => void ) => {

const hostIp = domainListPool.get ( hostName )
const now = new Date ().getTime ()
if ( ! hostIp || hostIp.expire < now )
return gatway.hostLookup ( hostName, userAgent, ( err, ipadd ) => {
return gatway.hostLookup ( hostName, ( err, ipadd ) => {
return CallBack ( err, ipadd )
})
return CallBack ( null, hostIp )
Expand All @@ -276,9 +277,8 @@ const isSslFromBuffer = ( buffer ) => {
const httpProxy = ( clientSocket: Net.Socket, buffer: Buffer, useGatWay: boolean, ip6: boolean, connectTimeOut: number,
domainListPool: Map < string, domainData >, gatway: gateWay, checkAgainTime: number, blackDomainList: string[] ) => {

const httpHead = new HttpProxyHeader ( buffer )
const httpHead = new HttpHeader ( buffer )
const hostName = httpHead.Url.hostname
const userAgent = httpHead.headers [ 'user-agent' ]

const CallBack = ( err?: Error, _data?: Buffer ) => {

Expand All @@ -296,7 +296,7 @@ const httpProxy = ( clientSocket: Net.Socket, buffer: Buffer, useGatWay: boolean
}

const id = `[${ clientSocket.remoteAddress.split(':')[3] }:${ clientSocket.remotePort }][${ uuuu.uuid }] `
return gatway.requestGetWay ( id, uuuu, userAgent, clientSocket )
return gatway.requestGetWay ( id, uuuu, httpHead, clientSocket )

}

Expand All @@ -318,7 +318,7 @@ const httpProxy = ( clientSocket: Net.Socket, buffer: Buffer, useGatWay: boolean

if ( ! hostIp ) {

return isAllBlackedByFireWall ( hostName, ip6, gatway, userAgent, domainListPool, ( err, _hostIp ) => {
return isAllBlackedByFireWall ( hostName, ip6, gatway, null, domainListPool, ( err, _hostIp ) => {
if ( err ) {
console.log ( `[${ hostName }] Blocked!`)
return closeClientSocket ( clientSocket, 504, null )
Expand Down Expand Up @@ -375,7 +375,7 @@ const getPac = ( hostIp: string, port: number, http: boolean, sock5: boolean ) =


export class proxyServer {
public UdpServer = new Socks.UdpDgram ()
//public UdpServer = new Socks.UdpDgram ()
private hostLocalIpv4: { network: string, address: string } []= []
private hostLocalIpv6: string = null
private hostGlobalIpV4: string = null
Expand All @@ -397,7 +397,7 @@ export class proxyServer {
return
this.getGlobalIpRunning = true

gateWay.hostLookup ( testGatewayDomainName, null, ( err, data ) => {
gateWay.hostLookup ( testGatewayDomainName, ( err, data ) => {
if ( err )
return console.log ( 'getGlobalIp ERROR:', err.message )
console.log ( data )
Expand Down Expand Up @@ -427,31 +427,30 @@ export class proxyServer {
public connectHostTimeOut: number, public useGatWay: boolean, public domainBlackList: string[] ) {
this.getGlobalIp ( this.gateway )
let socks = null
let httpHead: HttpHeader = null
const server = Net.createServer ( socket => {
const ip = socket.remoteAddress
const isWhiteIp = this.whiteIpList.find ( n => { return n === ip }) ? true : false
let agent = 'Mozilla/5.0'
console.log (`new socket!`)

socket.once ( 'data', ( data: Buffer ) => {
const dataStr = data.toString()
if ( /^GET \/pac/.test ( dataStr )) {
const httpHead = new HttpProxyHeader ( data )
agent = httpHead.headers['user-agent']
const sock5 = /Windows NT|Darwin/i.test ( agent ) && ! /CFNetwork/i.test (agent)

httpHead = new HttpHeader ( data )
const agent = httpHead.headers [ 'user-agent']

const sock5 = /Windows NT|Darwin/i.test ( agent ) && ! /CFNetwork/i.test ( agent )
console.log (`new GET /pac\n headers[${ JSON.stringify ( httpHead.headers )}]\n sock5=[${ sock5 }]\n`)
let ret = getPac ( this.localProxyServerIP, this.port, false, sock5 )
if ( /pacHttp/.test( dataStr ))
ret = getPac ( this.localProxyServerIP, this.port, true, sock5 )
console.log ( `/GET \/pac from :[${ socket.remoteAddress }] sock5 [${ sock5 }] agent [${ agent }] httpHead.headers [${ Object.keys(httpHead.headers)}]`)
console.log ( dataStr )
return socket.end ( ret )
}

console.log (`new socket!\n headers [${ httpHead && httpHead.headers ? JSON.stringify ( httpHead.headers) : 'null' }]`, )
switch ( data.readUInt8 ( 0 )) {
case 0x4:
return socks = new Socks.sockt4 ( socket, data, agent, this )
return socks = new Socks.sockt4 ( socket, data, httpHead, this )
case 0x5:
return socks = new Socks.socks5 ( socket, agent, this )
return socks = new Socks.socks5 ( socket, httpHead, this )
default:
return httpProxy ( socket, data, useGatWay, this.hostGlobalIpV6 ? true : false, connectHostTimeOut, domainListPool, this.gateway, checkAgainTimeOut, domainBlackList )
}
Expand Down
Loading

0 comments on commit 2c5d41b

Please sign in to comment.