Skip to content

Commit

Permalink
Merge pull request #3 from vigo5190/auth
Browse files Browse the repository at this point in the history
add auth
  • Loading branch information
Stanislav Gumeniuk authored May 28, 2018
2 parents b812839 + e91d5f4 commit af1b8ce
Show file tree
Hide file tree
Showing 35 changed files with 5,832 additions and 62 deletions.
41 changes: 41 additions & 0 deletions .gometalinter.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"Vendor": true,
"Deadline": "2m",
"Sort": [
"linter",
"severity",
"path",
"line"
],
"Exclude": [
"vendor"
],
"EnableGC": true,
"Linters": {
"nakedret": {
"Command": "nakedret",
"Pattern": "^(?P<path>.*?\\.go):(?P<line>\\d+)\\s*(?P<message>.*)$"
}
},
"WarnUnmatchedDirective": true,
"DisableAll": true,
"Enable": [
"deadcode",
"gocyclo",
"gofmt",
"goimports",
"golint",
"gosimple",
"ineffassign",
"interfacer",
"lll",
"misspell",
"nakedret",
"unconvert",
"unparam",
"unused",
"vet"
],
"Cyclo": 16,
"LineLength": 100
}
10 changes: 10 additions & 0 deletions BENCHMARKS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
```bash
go test -bench=. -benchmem `go list ./... | grep -v vendor`
? github.com/vigo5190/go-socks5 [no test files]
goos: darwin
goarch: amd64
pkg: github.com/vigo5190/go-socks5/proxy
BenchmarkProxy_Start-8 10000 145070 ns/op 5130 B/op 66 allocs/op
BenchmarkAuth_Auth-8 3000000 499 ns/op 96 B/op 3 allocs/op
PASS
```
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ vet:
lint:
golint $(GOFILES)

metalint:
gometalinter ./...

docker:
docker build -t $(IMAGE) .

Expand All @@ -36,4 +39,4 @@ docker-push:
travis: lint vet test
echo "done all"

pre: fmt lint vet test bench
pre: fmt lint vet metalint test bench
30 changes: 24 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,35 @@ How to use
docker run -d -p 5190:8008 vigo5190/gosocks5
```

How to use (not docker)
------------------------

Build:
How to build (local)
----

```bash
make
```

Run:

Configuration
--------------

By default your app run on `0.0.0.0:8008` without auth

How to get password :
```bash
./go-socks5 -port=8009 -addr=0.0.0.0
htpasswd -nbs yourUsername yourPassword
```

You will get something like : `yourUsername:{SHA}pNvEyEKjh5XJ9cGgtK0l0WiuwmM=`
You need part after `:{SHA}`. for this example its `pNvEyEKjh5XJ9cGgtK0l0WiuwmM=
`

Example:

```toml
listen ="0.0.0.0:8008"

auth = true
[[users]]
login = "vigo5190"
pass = "Ys23Ag/5IOWqZCw9QGaVDdHwH00="
```
3 changes: 3 additions & 0 deletions config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
listen ="0.0.0.0:8008"

auth = false
5 changes: 4 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
module github.com/vigo5190/go-socks5

require github.com/rs/zerolog v1.7.0
require (
github.com/BurntSushi/toml v0.3.0
github.com/rs/zerolog v1.7.0
)
24 changes: 11 additions & 13 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,26 @@ package main
import (
"flag"

"github.com/BurntSushi/toml"
"github.com/rs/zerolog/log"

proxy2 "github.com/vigo5190/go-socks5/proxy"
)

func main() {
log.Info().Msg("vigo5190/go-socks5 Started")
defer log.Info().Msg("vigo5190/go-socks5 Stop")

port := flag.String("port", "8008", "listen port")
listenAddr := flag.String("addr", "0.0.0.0", "listen addr")
flag.Parse()

//customFormatter := new(log.TextFormatter)
//customFormatter.TimestampFormat = "2006-01-02 15:04:05"
//customFormatter.FullTimestamp = true
cfgFile := flag.String("c", "config.toml", "config file")

//lg := log.New()
//lg.Formatter = customFormatter
flag.Parse()

log.Info().Msg("vigo5190/go-socks5 Started")
defer log.Info().Msg("vigo5190/go-socks5 Stop")
proxy := proxy2.Proxy{}

proxy := proxy2.Proxy{
Listen: *listenAddr + ":" + *port,
if _, err := toml.DecodeFile(*cfgFile, &proxy); err != nil {
log.Error().Err(err)
panic(err)
}

proxy.Start()
}
25 changes: 23 additions & 2 deletions proxy/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,34 @@ import (

//Proxy is main struct for all magic
type Proxy struct {
Listen string
Listen string `toml:"listen"`
AuthEnable bool `toml:"auth"`
Users []user `toml:"users"`
}

type user struct {
Login string `toml:"login"`
Pass string `toml:"pass"`
}

//Start method for start proxy
func (p *Proxy) Start() {
server := &Server{}

server := &Server{
auth: p.authorizer(),
}

log.Info().Msgf("start %s", p.Listen)
server.ListenAndServe("tcp", p.Listen)
}

func (p *Proxy) authorizer() Authorizer {
upmap := map[string]string{}
for _, u := range p.Users {
upmap[u.Login] = u.Pass
}
return &Auth{
Users: upmap,
AuthEnable: p.AuthEnable,
}
}
59 changes: 59 additions & 0 deletions proxy/auth.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package proxy

import (
"crypto/sha1"
"encoding/base64"
"hash"
"sync"
)

//Authorizer interface for auth
type Authorizer interface {
AuthLoginPassword(login string, pass []byte) bool
ShouldAuth() bool
}

//Auth container for auth info
type Auth struct {
AuthEnable bool
Users map[string]string
shapool sync.Pool
}

//ShouldAuth return true if aith enable
func (p *Auth) ShouldAuth() bool {
return p.AuthEnable
}

//AuthLoginPassword return true if auth enable and login/password corrected
func (p *Auth) AuthLoginPassword(login string, pass []byte) bool {
if !p.AuthEnable {
return true
}

spass, ok := p.Users[login]

if !ok {
return false
}

hashedPass := p.hashSha(pass)

return hashedPass == spass
}

func (p *Auth) hashSha(password []byte) string {
s := p.shapool.Get()
if s == nil {
s = sha1.New()
}

ss := s.(hash.Hash)
defer ss.Reset()
defer p.shapool.Put(ss)

ss.Write(password)
passwordSum := ss.Sum(nil)

return base64.StdEncoding.EncodeToString(passwordSum)
}
74 changes: 74 additions & 0 deletions proxy/auth_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package proxy

import "testing"

func TestProxy_Auth(t *testing.T) {
p := Auth{
AuthEnable: true,
Users: map[string]string{
"foo": "Ys23Ag/5IOWqZCw9QGaVDdHwH00=",
},
}

if !p.AuthLoginPassword("foo", []byte("bar")) {
t.Error("expected auth true, got false")
}

if p.AuthLoginPassword("foo", []byte("bar1")) {
t.Error("expected auth false, got true")
}

if p.AuthLoginPassword("fooq", []byte("bar")) {
t.Error("expected auth false, got true")
}
}

func TestProxy_Auth2(t *testing.T) {
p := Auth{
AuthEnable: true,
Users: map[string]string{
"foo": "Ys23Ag/5IOWqZCw9QGaVDdHwH00=",
"bar": "C+7Hteo/D9vJXQ3UfzxbwnXaijM=",
},
}

if !p.AuthLoginPassword("foo", []byte("bar")) {
t.Error("expected auth true, got false")
}

if p.AuthLoginPassword("foo", []byte("bar1")) {
t.Error("expected auth false, got true")
}

if p.AuthLoginPassword("fooq", []byte("bar")) {
t.Error("expected auth false, got true")
}

if !p.AuthLoginPassword("bar", []byte("foo")) {
t.Error("expected auth true, got false")
}

if p.AuthLoginPassword("bar", []byte("foo1")) {
t.Error("expected auth false, got true")
}

if p.AuthLoginPassword("bar1", []byte("foo")) {
t.Error("expected auth false, got true")
}
}

func BenchmarkAuth_Auth(b *testing.B) {
p := Auth{
AuthEnable: true,
Users: map[string]string{
"foo": "Ys23Ag/5IOWqZCw9QGaVDdHwH00=",
},
}
pass := []byte("bar")
for n := 0; n < b.N; n++ {
if !p.AuthLoginPassword("foo", pass) {
b.Error("expected auth true, got false")
}
}

}
2 changes: 1 addition & 1 deletion proxy/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func (c *Command) connect() (rsp byte, err error) {

c.proxy()

return
return rspSuccess, nil
}

func (c *Command) proxy() {
Expand Down
Loading

0 comments on commit af1b8ce

Please sign in to comment.