diff --git a/TransX.exe b/TransX.exe new file mode 100644 index 0000000..e576389 Binary files /dev/null and b/TransX.exe differ diff --git a/log/logger.go b/log/logger.go new file mode 100644 index 0000000..be8da39 --- /dev/null +++ b/log/logger.go @@ -0,0 +1,121 @@ +package log + +import ( + log "github.com/alecthomas/log4go" + "fmt" +) + +var root log.Logger = make(log.Logger) + +func LogTo(target string, level_name string) { + var writer log.LogWriter = nil + + switch target { + case "stdout": + writer = log.NewConsoleLogWriter() + case "none": + // no logging + default: + writer = log.NewFileLogWriter(target, true) + } + + if writer != nil { + var level = log.DEBUG + + switch level_name { + case "FINEST": + level = log.FINEST + case "FINE": + level = log.FINE + case "DEBUG": + level = log.DEBUG + case "TRACE": + level = log.TRACE + case "INFO": + level = log.INFO + case "WARNING": + level = log.WARNING + case "ERROR": + level = log.ERROR + case "CRITICAL": + level = log.CRITICAL + default: + level = log.DEBUG + } + + root.AddFilter("log", level, writer) + } +} + +type Logger interface { + AddLogPrefix(string) + ClearLogPrefixes() + Debug(string, ...interface{}) + Info(string, ...interface{}) + Warn(string, ...interface{}) error + Error(string, ...interface{}) error +} + +type PrefixLogger struct { + *log.Logger + prefix string +} + +func NewPrefixLogger(prefixes ...string) Logger { + logger := &PrefixLogger{Logger: &root} + + for _, p := range prefixes { + logger.AddLogPrefix(p) + } + + return logger +} + +func (pl *PrefixLogger) pfx(fmtstr string) interface{} { + return fmt.Sprintf("%s %s", pl.prefix, fmtstr) +} + +func (pl *PrefixLogger) Debug(arg0 string, args ...interface{}) { + pl.Logger.Debug(pl.pfx(arg0), args...) +} + +func (pl *PrefixLogger) Info(arg0 string, args ...interface{}) { + pl.Logger.Info(pl.pfx(arg0), args...) +} + +func (pl *PrefixLogger) Warn(arg0 string, args ...interface{}) error { + return pl.Logger.Warn(pl.pfx(arg0), args...) +} + +func (pl *PrefixLogger) Error(arg0 string, args ...interface{}) error { + return pl.Logger.Error(pl.pfx(arg0), args...) +} + +func (pl *PrefixLogger) AddLogPrefix(prefix string) { + if len(pl.prefix) > 0 { + pl.prefix += " " + } + + pl.prefix += "[" + prefix + "]" +} + +func (pl *PrefixLogger) ClearLogPrefixes() { + pl.prefix = "" +} + +// we should never really use these . . . always prefer logging through a prefix logger +func Debug(arg0 string, args ...interface{}) { + root.Debug(arg0, args...) +} + +func Info(arg0 string, args ...interface{}) { + root.Info(arg0, args...) +} + +func Warn(arg0 string, args ...interface{}) error { + return root.Warn(arg0, args...) +} + +func Error(arg0 string, args ...interface{}) error { + return root.Error(arg0, args...) +} \ No newline at end of file diff --git a/main.go b/main.go index 271b75b..1f207a4 100644 --- a/main.go +++ b/main.go @@ -3,11 +3,12 @@ package main import ( "fmt" + // "github.com/TransX/log" ) func Tunnel() { trans := NewTransTCP() - trans.Start("1200", "127.0.0.1", "8118") + trans.Start("1200", "192.168.0.120", "8118") } func main() { diff --git a/main_test.go b/main_test.go index 7bf84ce..12ffe24 100644 --- a/main_test.go +++ b/main_test.go @@ -1,8 +1,10 @@ package main import ( - "fmt" + "github.com/TransX/tscipher" + "log" "net" + "os" "testing" "time" ) @@ -14,20 +16,24 @@ func server(t *testing.T) { } for { conn, err := listener.Accept() - fmt.Println("Test Server Incoming", conn.RemoteAddr().String()) + log.Println("Test Server Incoming", conn.RemoteAddr().String()) if err != nil { t.Fatal(err) } bytes := make([]byte, 32) + XOR := tscipher.NewXOR([]byte("fasdfasdf")) n, err := conn.Read(bytes) - fmt.Println("Test Server Receive ", string(bytes[:n])) - _, err = conn.Write([]byte("OK")) - fmt.Println("Test Server write") + decryped, _ := XOR.Decrypt(bytes[:n]) + copy(bytes, decryped[:n]) + log.Println("Test Server Receive ", string(bytes[:n])) + encrypted, _ := XOR.Encrypt([]byte("OK")) + _, err = conn.Write(encrypted) + log.Println("Test Server write") if err != nil { t.Fatal(err) } conn.Close() - fmt.Println("Test Server closed") + log.Println("Test Server closed") } } @@ -37,25 +43,31 @@ func client(t *testing.T) { if err != nil { t.Fatal(err) } - conn.Write([]byte("Client")) - fmt.Println("Test Client write") + XOR := tscipher.NewXOR([]byte("fasdfasdf")) + encrypted, _ := XOR.Encrypt([]byte("Client")) + conn.Write(encrypted) + log.Println("Test Client write") bytes := make([]byte, 32) n, err := conn.Read(bytes) - fmt.Println("Test Client read") + decryped, _ := XOR.Decrypt(bytes[:n]) + copy(bytes, decryped[:n]) + log.Println("Test Client read") if err != nil { t.Fatal(err) } - fmt.Println("Test Client Receive ", string(bytes[:n])) + log.Println("Test Client Receive ", string(bytes[:n])) time.Sleep(time.Second * 2) conn.Close() - fmt.Println("Test Client closed") + log.Println("Test Client closed") } } func TestTunnel(t *testing.T) { + file, _ := os.Create("log.txt") + log.SetOutput(file) // t.Log("Start testing.") - fmt.Println("Test Start testing.") + log.Println("Test Start testing.") go server(t) go client(t) trans := NewTransTCP() diff --git a/tcp.go b/tcp.go index b4ed3a9..3ab7dad 100644 --- a/tcp.go +++ b/tcp.go @@ -63,18 +63,18 @@ func (this *TransTCP) tunnel(src, dest net.Conn, id string) { //构建Carrier revCarrier := &tscipher.Carrier{ src, - tscipher.NewCipher("default"), + tscipher.NewCipher("XOR"), cache, } nByte, err := tscipher.ReceiveData(revCarrier) if err != nil { log.Panicln("Read panic", id, err, src.RemoteAddr().String()) } - log.Println("Reived ", id, string(cache[:nByte])) + log.Println("Reived ", nByte, "bytes:", id, string(cache[:nByte])) sendCarrier := &tscipher.Carrier{ dest, - tscipher.NewCipher("default"), - cache, + tscipher.NewCipher("XOR"), + cache, //TODO:危险,cache的容量容易被不小心修改 } _, err = tscipher.SendData(sendCarrier, nByte) log.Println("Write") diff --git a/tscipher/aes.go b/tscipher/aes.go new file mode 100644 index 0000000..8d3fb68 --- /dev/null +++ b/tscipher/aes.go @@ -0,0 +1,79 @@ +package tscipher + +import ( + "crypto/aes" + "crypto/cipher" + crtrand "crypto/rand" + // "errors" + "io" + "log" +) + +type AES struct { + key []byte +} + +func (this *AES) aesEncrypt(key, text []byte) (ciphertext []byte) { + ciphertext = make([]byte, aes.BlockSize+len(string(text))) + // iv = initialization vector + iv := ciphertext[:aes.BlockSize] + + io.ReadFull(crtrand.Reader, iv) + + // var block cipher.Block + block, err := aes.NewCipher(key) + if err != nil { + ciphertext = nil + log.Println("encrypt err", err) + } + + cfb := cipher.NewCFBEncrypter(block, iv) + cfb.XORKeyStream(ciphertext[aes.BlockSize:], text) + return +} + +func (this *AES) aesDecrypt(key, ciphertext []byte) (plaintext []byte) { + + // var block cipher.Block + // if len(ciphertext) < aes.BlockSize { + // err := errors.New("ciphertext too short") + // plaintext = nil + // log.Println("decrypt err", err) + // } + + iv := ciphertext[:aes.BlockSize] + ciphertext = ciphertext[aes.BlockSize:] + block, err := aes.NewCipher(key) + if err != nil { + plaintext = nil + log.Println("decrypt err", err) + } + cfb := cipher.NewCFBDecrypter(block, iv) + cfb.XORKeyStream(ciphertext, ciphertext) + + plaintext = ciphertext + + return +} + +func (this *AES) Decrypt(data []byte) (decrypted []byte, err error) { + data = this.aesDecrypt(this.key, data) + decrypted = data + err = nil + return +} + +func (this *AES) Encrypt(data []byte) (encryped []byte, err error) { + this.aesEncrypt(this.key, data) + encryped = data + err = nil + return +} + +func NewAES() (cipher Cipher) { + key := make([]byte, 32) + io.ReadFull(crtrand.Reader, key) + return &AES{ + key: key, + } +} diff --git a/tscipher/chacha.go b/tscipher/chacha.go index f809c26..84a466f 100644 --- a/tscipher/chacha.go +++ b/tscipher/chacha.go @@ -1,20 +1,40 @@ package tscipher +import ( + chacha "github.com/codahale/chacha20" + "log" +) + type ChaCha struct { + key []byte + nonce []byte } -func (*ChaCha) Decrypt(data []byte) (decrypted []byte, err error) { +func (this *ChaCha) Decrypt(data []byte) (decrypted []byte, err error) { + // xor, err := chacha.NewXChaCha(this.key, this.nonce) + if err != nil { + log.Fatalln("Decrypt", err) + } + // xor.XORKeyStream(data, data) decrypted = data err = nil return } -func (*ChaCha) Encrypt(data []byte) (encryped []byte, err error) { +func (this *ChaCha) Encrypt(data []byte) (encryped []byte, err error) { + xor, err := chacha.NewXChaCha(this.key, this.nonce) + if err != nil { + log.Fatalln("Chacha Encrypt", err) + } + xor.XORKeyStream(data, data) encryped = data err = nil return } func NewChaCha() (cipher Cipher) { - return &ChaCha{} + return &ChaCha{ + key: make([]byte, 256), + nonce: make([]byte, 64), + } } diff --git a/tscipher/cipher.go b/tscipher/cipher.go index f4eea9e..3222dbc 100644 --- a/tscipher/cipher.go +++ b/tscipher/cipher.go @@ -19,15 +19,38 @@ func NewCipher(cipherName string) (cipher Cipher) { if cipherName == "default" { return NewChaCha() } + if cipherName == "AES" { + return NewAES() + } + if cipherName == "XOR" { + return NewXOR([]byte("fasdfasdf")) + } return nil //TODO:临时这样处理 } func SendData(carrier *Carrier, nByte int) (n int, err error) { - n, err = carrier.Conn.Write(carrier.Cache[:nByte]) + encrypedByte, err := carrier.Cipher.Encrypt(carrier.Cache[:nByte]) + if err != nil { + n = 0 + return + } + n, err = carrier.Conn.Write(encrypedByte[:nByte]) return } func ReceiveData(carrier *Carrier) (n int, err error) { n, err = carrier.Conn.Read(carrier.Cache) + if err != nil { + n = 0 + return + } + //TODO:err + decrypted, err := carrier.Cipher.Decrypt(carrier.Cache[:n]) + copy(carrier.Cache, decrypted[:n]) + + if err != nil { + n = 0 + return + } return } diff --git a/tscipher/xor.go b/tscipher/xor.go new file mode 100644 index 0000000..19e9dcb --- /dev/null +++ b/tscipher/xor.go @@ -0,0 +1,31 @@ +package tscipher + +import () + +type XOR struct { + key []byte +} + +func (this *XOR) Decrypt(data []byte) (decrypted []byte, err error) { + decrypted = make([]byte, len(data)) + for i := 0; i < len(data); i++ { + decrypted[i] = data[i] ^ this.key[i%len(this.key)] + } + err = nil + return +} + +func (this *XOR) Encrypt(data []byte) (encryped []byte, err error) { + encryped = make([]byte, len(data)) + for i := 0; i < len(data); i++ { + encryped[i] = data[i] ^ this.key[i%len(this.key)] + } + err = nil + return +} + +func NewXOR(key []byte) (cipher Cipher) { + return &XOR{ + key: key, + } +} diff --git a/tunnel.go b/tunnel.go deleted file mode 100644 index 42ee016..0000000 --- a/tunnel.go +++ /dev/null @@ -1,18 +0,0 @@ -package main - -//func StartTunnel(sourceIP, desIP, desPort string) { -// remoteAddr := make(chan net.Addr) -// transSrcToDes := NewTransTCP() -// transSrcToDes.CreateTCPListener("0.0.0.0", desPort) -// transSrcToDes.CreateTCPClient(desIP, desPort) -// go transSrcToDes.Start(remoteAddr) -// sourcePort := <-remoteAddr -// transDesToSrc := NewTransTCP() -// transDesToSrc.CreateTCPListener("0.0.0.0", sourcePort) -// transSrcToDes.CreateTCPClient(sourceIP, sourcePort) - -// go transDesToSrc.Start() -// c := make(chan byte) -// <-c - -//}