372 lines
16 KiB
Swift
Executable File
372 lines
16 KiB
Swift
Executable File
//import Foundation
|
|
//
|
|
//extension ShadowsocksAdapter {
|
|
// public struct ProtocolObfuscater {
|
|
// public class Factory {
|
|
// public init() {}
|
|
//
|
|
// public func build() -> ProtocolObfuscaterBase {
|
|
// return ProtocolObfuscaterBase()
|
|
// }
|
|
// }
|
|
//
|
|
// public class ProtocolObfuscaterBase {
|
|
// public weak var inputStreamProcessor: CryptoStreamProcessor!
|
|
// public weak var outputStreamProcessor: ShadowsocksAdapter!
|
|
//
|
|
// public func start() {}
|
|
// public func input(data: Data) throws {}
|
|
// public func output(data: Data) {}
|
|
//
|
|
// public func didWrite() {}
|
|
// }
|
|
//
|
|
// public class OriginProtocolObfuscater: ProtocolObfuscaterBase {
|
|
//
|
|
// public class Factory: ProtocolObfuscater.Factory {
|
|
// public override init() {}
|
|
//
|
|
// public override func build() -> ShadowsocksAdapter.ProtocolObfuscater.ProtocolObfuscaterBase {
|
|
// return OriginProtocolObfuscater()
|
|
// }
|
|
// }
|
|
//
|
|
// public override func start() {
|
|
// outputStreamProcessor.becomeReadyToForward()
|
|
// }
|
|
//
|
|
// public override func input(data: Data) throws {
|
|
// try inputStreamProcessor.input(data: data)
|
|
// }
|
|
//
|
|
// public override func output(data: Data) {
|
|
// outputStreamProcessor.output(data: data)
|
|
// }
|
|
// }
|
|
//
|
|
// public class HTTPProtocolObfuscater: ProtocolObfuscaterBase {
|
|
//
|
|
// public class Factory: ProtocolObfuscater.Factory {
|
|
// let method: String
|
|
// let hosts: [String]
|
|
// let customHeader: String?
|
|
//
|
|
// public init(method: String = "GET", hosts: [String], customHeader: String?) {
|
|
// self.method = method
|
|
// self.hosts = hosts
|
|
// self.customHeader = customHeader
|
|
// }
|
|
//
|
|
// public override func build() -> ShadowsocksAdapter.ProtocolObfuscater.ProtocolObfuscaterBase {
|
|
// return HTTPProtocolObfuscater(method: method, hosts: hosts, customHeader: customHeader)
|
|
// }
|
|
// }
|
|
//
|
|
// static let headerLength = 30
|
|
// static let userAgent = ["Mozilla/5.0 (Windows NT 6.3; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0",
|
|
// "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:40.0) Gecko/20100101 Firefox/44.0",
|
|
// "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36",
|
|
// "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.11 (KHTML, like Gecko) Ubuntu/11.10 Chromium/27.0.1453.93 Chrome/27.0.1453.93 Safari/537.36",
|
|
// "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:35.0) Gecko/20100101 Firefox/35.0",
|
|
// "Mozilla/5.0 (compatible; WOW64; MSIE 10.0; Windows NT 6.2)",
|
|
// "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27",
|
|
// "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.3; Trident/7.0; .NET4.0E; .NET4.0C)",
|
|
// "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko",
|
|
// "Mozilla/5.0 (Linux; Android 4.4; Nexus 5 Build/BuildID) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Mobile Safari/537.36",
|
|
// "Mozilla/5.0 (iPad; CPU OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3",
|
|
// "Mozilla/5.0 (iPhone; CPU iPhone OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3"]
|
|
//
|
|
// let method: String
|
|
// let hosts: [String]
|
|
// let customHeader: String?
|
|
//
|
|
// var readingFakeHeader = false
|
|
// var sendHeader = false
|
|
// var remaining = false
|
|
//
|
|
// var buffer = Buffer(capacity: 8192)
|
|
//
|
|
// public init(method: String = "GET", hosts: [String], customHeader: String?) {
|
|
// self.method = method
|
|
// self.hosts = hosts
|
|
// self.customHeader = customHeader
|
|
// }
|
|
//
|
|
// private func generateHeader(encapsulating data: Data) -> String {
|
|
// let ind = Int(arc4random_uniform(UInt32(hosts.count)))
|
|
// let host = outputStreamProcessor.port == 80 ? hosts[ind] : "\(hosts[ind]):\(outputStreamProcessor.port)"
|
|
// var header = "\(method) /\(hexlify(data: data)) HTTP/1.1\r\nHost: \(host)\r\n"
|
|
// if let customHeader = customHeader {
|
|
// header += customHeader
|
|
// } else {
|
|
// let ind = Int(arc4random_uniform(UInt32(HTTPProtocolObfuscater.userAgent.count)))
|
|
// header += "User-Agent: \(HTTPProtocolObfuscater.userAgent[ind])\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nAccept-Language: en-US,en;q=0.8\r\nAccept-Encoding: gzip, deflate\r\nDNT: 1\r\nConnection: keep-alive"
|
|
// }
|
|
// header += "\r\n\r\n"
|
|
// return header
|
|
// }
|
|
//
|
|
// private func hexlify(data: Data) -> String {
|
|
// var result = ""
|
|
// for i in data {
|
|
// result = result.appendingFormat("%%%02x", i)
|
|
// }
|
|
// return result
|
|
// }
|
|
//
|
|
// public override func start() {
|
|
// readingFakeHeader = true
|
|
// outputStreamProcessor.becomeReadyToForward()
|
|
// }
|
|
//
|
|
// public override func input(data: Data) throws {
|
|
// if readingFakeHeader {
|
|
// buffer.append(data: data)
|
|
// if buffer.get(to: Utils.HTTPData.DoubleCRLF) != nil {
|
|
// readingFakeHeader = false
|
|
// if let remainData = buffer.get() {
|
|
// try inputStreamProcessor.input(data: remainData)
|
|
// return
|
|
// }
|
|
// }
|
|
// try inputStreamProcessor.input(data: Data())
|
|
// return
|
|
// }
|
|
//
|
|
// try inputStreamProcessor.input(data: data)
|
|
// }
|
|
//
|
|
// public override func output(data: Data) {
|
|
// if sendHeader {
|
|
// outputStreamProcessor.output(data: data)
|
|
// } else {
|
|
// var fakeRequestDataLength = inputStreamProcessor.key.count + HTTPProtocolObfuscater.headerLength
|
|
// if data.count - fakeRequestDataLength > 64 {
|
|
// fakeRequestDataLength += Int(arc4random_uniform(64))
|
|
// } else {
|
|
// fakeRequestDataLength = data.count
|
|
// }
|
|
//
|
|
// var outputData = generateHeader(encapsulating: data.subdata(in: 0 ..< fakeRequestDataLength)).data(using: .utf8)!
|
|
// outputData.append(data.subdata(in: fakeRequestDataLength ..< data.count))
|
|
// sendHeader = true
|
|
// outputStreamProcessor.output(data: outputData)
|
|
// }
|
|
// }
|
|
// }
|
|
//
|
|
// public class TLSProtocolObfuscater: ProtocolObfuscaterBase {
|
|
//
|
|
// public class Factory: ProtocolObfuscater.Factory {
|
|
// let hosts: [String]
|
|
//
|
|
// public init(hosts: [String]) {
|
|
// self.hosts = hosts
|
|
// }
|
|
//
|
|
// public override func build() -> ShadowsocksAdapter.ProtocolObfuscater.ProtocolObfuscaterBase {
|
|
// return TLSProtocolObfuscater(hosts: hosts)
|
|
// }
|
|
// }
|
|
//
|
|
// let hosts: [String]
|
|
// let clientID: Data = {
|
|
// var id = Data(count: 32)
|
|
// Utils.Random.fill(data: &id)
|
|
// return id
|
|
// }()
|
|
//
|
|
// private var status = 0
|
|
//
|
|
// private var buffer = Buffer(capacity: 1024)
|
|
//
|
|
// init(hosts: [String]) {
|
|
// self.hosts = hosts
|
|
// }
|
|
//
|
|
// public override func start() {
|
|
// handleStatus0()
|
|
// outputStreamProcessor.socket.readDataTo(length: 129)
|
|
// }
|
|
//
|
|
// public override func input(data: Data) throws {
|
|
// switch status {
|
|
// case 8:
|
|
// try handleInput(data: data)
|
|
// case 1:
|
|
// outputStreamProcessor.becomeReadyToForward()
|
|
// default:
|
|
// break
|
|
// }
|
|
// }
|
|
//
|
|
// public override func output(data: Data) {
|
|
// switch status {
|
|
// case 8:
|
|
// handleStatus8(data: data)
|
|
// return
|
|
// case 1:
|
|
// handleStatus1(data: data)
|
|
// return
|
|
// default:
|
|
// break
|
|
// }
|
|
// }
|
|
//
|
|
// private func authData() -> Data {
|
|
// var time = UInt32(Date.init().timeIntervalSince1970).bigEndian
|
|
// var output = Data(count: 32)
|
|
// var key = inputStreamProcessor.key
|
|
// key.append(clientID)
|
|
//
|
|
// withUnsafeBytes(of: &time) {
|
|
// output.replaceSubrange(0 ..< 4, with: $0)
|
|
// }
|
|
//
|
|
// Utils.Random.fill(data: &output, from: 4, length: 18)
|
|
// output.withUnsafeBytes {
|
|
// output.replaceSubrange(22 ..< 32, with: HMAC.final(value: $0.baseAddress!, length: 22, algorithm: .SHA1, key: key).subdata(in: 0..<10))
|
|
// }
|
|
// return output
|
|
// }
|
|
//
|
|
// private func pack(data: Data) -> Data {
|
|
// var output = Data()
|
|
// var left = data.count
|
|
// while left > 0 {
|
|
// let blockSize = UInt16(min(Int(arc4random_uniform(UInt32(UInt16.max))) % 4096 + 100, left))
|
|
// var blockSizeBE = blockSize.bigEndian
|
|
// output.append(contentsOf: [0x17, 0x03, 0x03])
|
|
// withUnsafeBytes(of: &blockSizeBE) {
|
|
// output.append($0.baseAddress!.assumingMemoryBound(to: UInt8.self), count: $0.count)
|
|
// }
|
|
// output.append(data.subdata(in: data.count - left ..< data.count - left + Int(blockSize)))
|
|
// left -= Int(blockSize)
|
|
// }
|
|
// return output
|
|
// }
|
|
//
|
|
// private func handleStatus8(data: Data) {
|
|
// outputStreamProcessor.output(data: pack(data: data))
|
|
// }
|
|
//
|
|
// private func handleStatus0() {
|
|
// status = 1
|
|
//
|
|
// var outData = Data()
|
|
// outData.append(contentsOf: [0x03, 0x03])
|
|
// outData.append(authData())
|
|
// outData.append(0x20)
|
|
// outData.append(clientID)
|
|
// outData.append(contentsOf: [0x00, 0x1c, 0xc0, 0x2b, 0xc0, 0x2f, 0xcc, 0xa9, 0xcc, 0xa8, 0xcc, 0x14, 0xcc, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0xc0, 0x09, 0xc0, 0x13, 0x00, 0x9c, 0x00, 0x35, 0x00, 0x2f, 0x00, 0x0a])
|
|
// outData.append("0100".data(using: .utf8)!)
|
|
//
|
|
// var extData = Data()
|
|
// extData.append(contentsOf: [0xff, 0x01, 0x00, 0x01, 0x00])
|
|
// let hostData = hosts[Int(arc4random_uniform(UInt32(hosts.count)))].data(using: .utf8)!
|
|
//
|
|
// var sniData = Data(capacity: hosts.count + 2 + 1 + 2 + 2 + 2)
|
|
//
|
|
// sniData.append(contentsOf: [0x00, 0x00])
|
|
//
|
|
// var _lenBE = UInt16(hostData.count + 5).bigEndian
|
|
// withUnsafeBytes(of: &_lenBE) {
|
|
// sniData.append($0.baseAddress!.assumingMemoryBound(to: UInt8.self), count: $0.count)
|
|
// }
|
|
//
|
|
// _lenBE = UInt16(hostData.count + 3).bigEndian
|
|
// withUnsafeBytes(of: &_lenBE) {
|
|
// sniData.append($0.baseAddress!.assumingMemoryBound(to: UInt8.self), count: $0.count)
|
|
// }
|
|
//
|
|
// sniData.append(0x00)
|
|
//
|
|
// _lenBE = UInt16(hostData.count).bigEndian
|
|
// withUnsafeBytes(of: &_lenBE) {
|
|
// sniData.append($0.baseAddress!.assumingMemoryBound(to: UInt8.self), count: $0.count)
|
|
// }
|
|
//
|
|
// sniData.append(hostData)
|
|
//
|
|
// extData.append(sniData)
|
|
//
|
|
// extData.append(contentsOf: [0x00, 0x17, 0x00, 0x00, 0x00, 0x23, 0x00, 0xd0])
|
|
//
|
|
// var randomData = Data(count: 208)
|
|
// Utils.Random.fill(data: &randomData)
|
|
// extData.append(randomData)
|
|
//
|
|
// extData.append(contentsOf: [0x00, 0x0d, 0x00, 0x16, 0x00, 0x14, 0x06, 0x01, 0x06, 0x03, 0x05, 0x01, 0x05, 0x03, 0x04, 0x01, 0x04, 0x03, 0x03, 0x01, 0x03, 0x03, 0x02, 0x01, 0x02, 0x03])
|
|
// extData.append(contentsOf: [0x00, 0x05, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00])
|
|
// extData.append(contentsOf: [0x00, 0x12, 0x00, 0x00])
|
|
// extData.append(contentsOf: [0x75, 0x50, 0x00, 0x00])
|
|
// extData.append(contentsOf: [0x00, 0x0b, 0x00, 0x02, 0x01, 0x00])
|
|
// extData.append(contentsOf: [0x00, 0x0a, 0x00, 0x06, 0x00, 0x04, 0x00, 0x17, 0x00, 0x18])
|
|
//
|
|
// _lenBE = UInt16(extData.count).bigEndian
|
|
// withUnsafeBytes(of: &_lenBE) {
|
|
// outData.append($0.baseAddress!.assumingMemoryBound(to: UInt8.self), count: $0.count)
|
|
// }
|
|
// outData.append(extData)
|
|
//
|
|
// var outputData = Data(capacity: outData.count + 9)
|
|
// outputData.append(contentsOf: [0x16, 0x03, 0x01])
|
|
// _lenBE = UInt16(outData.count + 4).bigEndian
|
|
// withUnsafeBytes(of: &_lenBE) {
|
|
// outputData.append($0.baseAddress!.assumingMemoryBound(to: UInt8.self), count: $0.count)
|
|
// }
|
|
// outputData.append(contentsOf: [0x01, 0x00])
|
|
// _lenBE = UInt16(outData.count).bigEndian
|
|
// withUnsafeBytes(of: &_lenBE) {
|
|
// outputData.append($0.baseAddress!.assumingMemoryBound(to: UInt8.self), count: $0.count)
|
|
// }
|
|
// outputData.append(outData)
|
|
// outputStreamProcessor.output(data: outputData)
|
|
// }
|
|
//
|
|
// private func handleStatus1(data: Data) {
|
|
// status = 8
|
|
//
|
|
// var outputData = Data()
|
|
// outputData.append(contentsOf: [0x14, 0x03, 0x03, 0x00, 0x01, 0x01, 0x16, 0x03, 0x03, 0x00, 0x20])
|
|
// var random = Data(count: 22)
|
|
// Utils.Random.fill(data: &random)
|
|
// outputData.append(random)
|
|
//
|
|
// var key = inputStreamProcessor.key
|
|
// key.append(clientID)
|
|
// outputData.withUnsafeBytes {
|
|
// outputData.append(HMAC.final(value: $0.baseAddress!, length: outputData.count, algorithm: .SHA1, key: key).subdata(in: 0..<10))
|
|
// }
|
|
//
|
|
// outputData.append(pack(data: data))
|
|
//
|
|
// outputStreamProcessor.output(data: outputData)
|
|
// }
|
|
//
|
|
// private func handleInput(data: Data) throws {
|
|
// buffer.append(data: data)
|
|
// var unpackedData = Data()
|
|
// while buffer.left > 5 {
|
|
// buffer.skip(3)
|
|
// var length: Int = 0
|
|
// buffer.withUnsafeBytes { (ptr: UnsafePointer<UInt16>) in
|
|
// length = Int(ptr.pointee.byteSwapped)
|
|
// }
|
|
// buffer.skip(2)
|
|
// if buffer.left >= length {
|
|
// unpackedData.append(buffer.get(length: length)!)
|
|
// continue
|
|
// } else {
|
|
// buffer.setBack(length: 5)
|
|
// break
|
|
// }
|
|
// }
|
|
// buffer.squeeze()
|
|
// try inputStreamProcessor.input(data: unpackedData)
|
|
// }
|
|
// }
|
|
//
|
|
// }
|
|
//}
|