AUTH-2394 added socks5 proxy

This commit is contained in:
Dalton
2020-03-31 09:56:22 -05:00
parent 710f66b0bb
commit a37da2b165
54 changed files with 2509 additions and 593 deletions

87
socks/authenticator.go Normal file
View File

@@ -0,0 +1,87 @@
package socks
import (
"fmt"
"io"
)
// Authenticator is the connection passed in as a reader/writer to support different authentication types
type Authenticator interface {
Handle(io.Reader, io.Writer) error
}
// NoAuthAuthenticator is used to handle the No Authentication mode
type NoAuthAuthenticator struct{}
// NewNoAuthAuthenticator creates a authless Authenticator
func NewNoAuthAuthenticator() Authenticator {
return &NoAuthAuthenticator{}
}
// Handle writes back the version and NoAuth
func (a *NoAuthAuthenticator) Handle(reader io.Reader, writer io.Writer) error {
_, err := writer.Write([]byte{socks5Version, NoAuth})
return err
}
// UserPassAuthAuthenticator is used to handle the user/password mode
type UserPassAuthAuthenticator struct {
IsValid func(string, string) bool
}
// NewUserPassAuthAuthenticator creates a new username/password validator Authenticator
func NewUserPassAuthAuthenticator(isValid func(string, string) bool) Authenticator {
return &UserPassAuthAuthenticator{
IsValid: isValid,
}
}
// Handle writes back the version and NoAuth
func (a *UserPassAuthAuthenticator) Handle(reader io.Reader, writer io.Writer) error {
if _, err := writer.Write([]byte{socks5Version, UserPassAuth}); err != nil {
return err
}
// Get the version and username length
header := []byte{0, 0}
if _, err := io.ReadAtLeast(reader, header, 2); err != nil {
return err
}
// Ensure compatibility. Someone call E-harmony
if header[0] != userAuthVersion {
return fmt.Errorf("Unsupported auth version: %v", header[0])
}
// Get the user name
userLen := int(header[1])
user := make([]byte, userLen)
if _, err := io.ReadAtLeast(reader, user, userLen); err != nil {
return err
}
// Get the password length
if _, err := reader.Read(header[:1]); err != nil {
return err
}
// Get the password
passLen := int(header[0])
pass := make([]byte, passLen)
if _, err := io.ReadAtLeast(reader, pass, passLen); err != nil {
return err
}
// Verify the password
if a.IsValid(string(user), string(pass)) {
_, err := writer.Write([]byte{userAuthVersion, authSuccess})
return err
}
// password failed. Write back failure
if _, err := writer.Write([]byte{userAuthVersion, authFailure}); err != nil {
return err
}
return fmt.Errorf("User authentication failed")
}