-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit e8457cc
Showing
17 changed files
with
789 additions
and
0 deletions.
There are no files selected for viewing
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# Auto detect text files and perform LF normalization | ||
* text=auto |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2018 Yrr0r | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
//CLIENT | ||
|
||
package main | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
"net" | ||
|
||
"./cmd" | ||
"./core" | ||
"./local" | ||
) | ||
|
||
var version = "master" | ||
|
||
func main() { | ||
fmt.Print("Ich*Liebe*Dich~ \n", "CLIENT\n") | ||
log.SetFlags(log.Lshortfile) | ||
|
||
// 默认配置 | ||
config := &cmd.Config{ | ||
ListenAddr: ":7448", | ||
} | ||
config.ReadConfig() | ||
|
||
// 解析配置 | ||
password, err := core.ParsePassword(config.Password) | ||
if err != nil { | ||
log.Fatalln(err) | ||
} | ||
listenAddr, err := net.ResolveTCPAddr("tcp", config.ListenAddr) | ||
if err != nil { | ||
log.Fatalln(err) | ||
} | ||
remoteAddr, err := net.ResolveTCPAddr("tcp", config.RemoteAddr) | ||
if err != nil { | ||
log.Fatalln(err) | ||
} | ||
|
||
// 启动 local 端并监听 | ||
lsLocal := local.New(password, listenAddr, remoteAddr) | ||
log.Fatalln(lsLocal.Listen(func(listenAddr net.Addr) { | ||
log.Println("使用配置:", fmt.Sprintf(` | ||
本地监听地址 listen: | ||
%s | ||
远程服务地址 remote: | ||
%s | ||
密码 password: | ||
%s | ||
`, listenAddr, remoteAddr, password)) | ||
log.Printf("lightsocks-local:%s 启动成功 监听在 %s\n", version, listenAddr.String()) | ||
})) | ||
} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
package cmd | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"io/ioutil" | ||
"log" | ||
"os" | ||
"path" | ||
|
||
"flag" | ||
|
||
"../core" | ||
) | ||
|
||
var ( | ||
// 配置文件路径 | ||
configPath string | ||
) | ||
|
||
var listen string | ||
var passwd string | ||
var remote string | ||
|
||
//Config temporary structure | ||
type Config struct { | ||
ListenAddr string `json:"listen"` | ||
RemoteAddr string `json:"remote"` | ||
Password string `json:"password"` | ||
} | ||
|
||
func init() { | ||
|
||
flag.StringVar(&configPath, "conf", "NO", "配置文件路径") | ||
|
||
flag.StringVar(&listen, "port", "EMPTY", "服务器端口") | ||
flag.StringVar(&passwd, "pass", "EMPTY", "密码") | ||
flag.StringVar(&remote, "remote", "EMPTY", "remote") | ||
|
||
var confgen = flag.String("gconf", "NO", "用此命令生成配置文件然后手动填入参数。") | ||
|
||
flag.Usage = func() { | ||
flag.PrintDefaults() | ||
} | ||
|
||
flag.Parse() | ||
|
||
if *confgen != "NO" { | ||
configPath = *confgen | ||
content := Config{ | ||
ListenAddr: ":7448", | ||
// 密码随机生成 | ||
Password: core.RandPassword().String(), | ||
} | ||
configJson, _ := json.MarshalIndent(content, "", " ") | ||
err := ioutil.WriteFile(configPath, configJson, 0644) | ||
if err != nil { | ||
fmt.Errorf("保存配置到文件出错: ", configPath, err) | ||
} | ||
log.Printf("保存配置到文件成功", configPath, "\n") | ||
os.Exit(0) | ||
} | ||
if configPath == "NO" { | ||
file, err := os.Getwd() | ||
configPath = path.Join(file, "conf.json") | ||
fmt.Println(configPath) | ||
if err != nil { | ||
fmt.Println(err) | ||
os.Exit(1) | ||
} | ||
} | ||
|
||
} | ||
|
||
func (config *Config) ReadConfig() { | ||
// 如果配置文件存在,就读取配置文件中的配置 assign 到 config | ||
if _, err := os.Stat(configPath); !os.IsNotExist(err) { | ||
log.Printf("读取配置:", configPath, "\n") | ||
file, err := os.Open(configPath) | ||
if err != nil { | ||
log.Fatalf("打开配置文件 %s 出错:%s", configPath, err) | ||
} | ||
defer file.Close() | ||
|
||
err = json.NewDecoder(file).Decode(config) | ||
if err != nil { | ||
log.Fatalf("格式不合法的 JSON 配置文件:\n%s", file) | ||
} | ||
} | ||
if listen != "EMPTY" { | ||
config.ListenAddr = ":" + listen | ||
fmt.Println("端口:命令行参数先于配置文件") | ||
} | ||
if passwd != "EMPTY" { | ||
config.Password = passwd | ||
fmt.Println("密码:命令行参数先于配置文件") | ||
} | ||
if remote != "EMPTY" { | ||
config.RemoteAddr = remote | ||
fmt.Println("Remote:命令行参数先于配置文件") | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package core | ||
|
||
type Cipher struct { | ||
// 编码用的密码 | ||
encodePassword *Password | ||
// 解码用的密码 | ||
decodePassword *Password | ||
} | ||
|
||
// 加密原数据 | ||
func (cipher *Cipher) encode(bs []byte) { | ||
for i, v := range bs { | ||
bs[i] = cipher.encodePassword[v] | ||
} | ||
} | ||
|
||
// 解码加密后的数据到原数据 | ||
func (cipher *Cipher) decode(bs []byte) { | ||
for i, v := range bs { | ||
bs[i] = cipher.decodePassword[v] | ||
} | ||
} | ||
|
||
// 新建一个编码解码器 | ||
func NewCipher(encodePassword *Password) *Cipher { | ||
decodePassword := &Password{} | ||
for i, v := range encodePassword { | ||
encodePassword[i] = v | ||
decodePassword[v] = byte(i) | ||
} | ||
return &Cipher{ | ||
encodePassword: encodePassword, | ||
decodePassword: decodePassword, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package core | ||
|
||
import ( | ||
"crypto/rand" | ||
"reflect" | ||
"testing" | ||
) | ||
|
||
const ( | ||
MB = 1024 * 1024 | ||
) | ||
|
||
// 测试 Cipher 加密解密 | ||
func TestCipher(t *testing.T) { | ||
password := RandPassword() | ||
t.Log(password) | ||
cipher := NewCipher(password) | ||
// 原数据 | ||
org := make([]byte, PasswordLength) | ||
for i := 0; i < PasswordLength; i++ { | ||
org[i] = byte(i) | ||
} | ||
// 复制一份原数据到 tmp | ||
tmp := make([]byte, PasswordLength) | ||
copy(tmp, org) | ||
t.Log(tmp) | ||
// 加密 tmp | ||
cipher.encode(tmp) | ||
t.Log(tmp) | ||
// 解密 tmp | ||
cipher.decode(tmp) | ||
t.Log(tmp) | ||
if !reflect.DeepEqual(org, tmp) { | ||
t.Error("解码编码数据后无法还原数据,数据不对应") | ||
} | ||
} | ||
|
||
func BenchmarkEncode(b *testing.B) { | ||
password := RandPassword() | ||
cipher := NewCipher(password) | ||
bs := make([]byte, MB) | ||
b.ResetTimer() | ||
rand.Read(bs) | ||
cipher.encode(bs) | ||
} | ||
|
||
func BenchmarkDecode(b *testing.B) { | ||
password := RandPassword() | ||
cipher := NewCipher(password) | ||
bs := make([]byte, MB) | ||
b.ResetTimer() | ||
rand.Read(bs) | ||
cipher.decode(bs) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package core | ||
|
||
import ( | ||
"encoding/base64" | ||
"errors" | ||
"math/rand" | ||
"strings" | ||
"time" | ||
) | ||
|
||
const PasswordLength = 256 | ||
|
||
var ErrInvalidPassword = errors.New("不合法的密码") | ||
|
||
type Password [PasswordLength]byte | ||
|
||
func init() { | ||
// 更新随机种子,防止生成一样的随机密码 | ||
rand.Seed(time.Now().Unix()) | ||
} | ||
|
||
// 采用base64编码把密码转换为字符串 | ||
func (password *Password) String() string { | ||
return base64.StdEncoding.EncodeToString(password[:]) | ||
} | ||
|
||
// 解析采用base64编码的字符串获取密码 | ||
func ParsePassword(passwordString string) (*Password, error) { | ||
bs, err := base64.StdEncoding.DecodeString(strings.TrimSpace(passwordString)) | ||
if err != nil || len(bs) != PasswordLength { | ||
return nil, ErrInvalidPassword | ||
} | ||
password := Password{} | ||
copy(password[:], bs) | ||
bs = nil | ||
return &password, nil | ||
} | ||
|
||
// 产生 256个byte随机组合的 密码,最后会使用base64编码为字符串存储在配置文件中 | ||
// 不能出现任何一个重复的byte位,必须又 0-255 组成,并且都需要包含 | ||
func RandPassword() *Password { | ||
// 随机生成一个由 0~255 组成的 byte 数组 | ||
intArr := rand.Perm(PasswordLength) | ||
password := &Password{} | ||
for i, v := range intArr { | ||
password[i] = byte(v) | ||
if i == v { | ||
// 确保不会出现如何一个byte位出现重复 | ||
return RandPassword() | ||
} | ||
} | ||
return password | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package core | ||
|
||
import ( | ||
"reflect" | ||
"sort" | ||
"testing" | ||
) | ||
|
||
func (password *Password) Len() int { | ||
return PasswordLength | ||
} | ||
|
||
func (password *Password) Less(i, j int) bool { | ||
return password[i] < password[j] | ||
} | ||
|
||
func (password *Password) Swap(i, j int) { | ||
password[i], password[j] = password[j], password[i] | ||
} | ||
|
||
func TestRandPassword(t *testing.T) { | ||
password := RandPassword() | ||
t.Log(password) | ||
sort.Sort(password) | ||
for i := 0; i < PasswordLength; i++ { | ||
if password[i] != byte(i) { | ||
t.Error("不能出现任何一个重复的byte位,必须由 0-255 组成,并且都需要包含") | ||
} | ||
} | ||
} | ||
|
||
func TestPasswordString(t *testing.T) { | ||
password := RandPassword() | ||
passwordStr := password.String() | ||
decodePassword, err := ParsePassword(passwordStr) | ||
if err != nil { | ||
t.Error(err) | ||
} else { | ||
if !reflect.DeepEqual(password, decodePassword) { | ||
t.Error("密码转化成字符串后反解后数据不对应") | ||
} | ||
} | ||
} |
Oops, something went wrong.