|
|
|
@ -16,7 +16,7 @@ import (
|
|
|
|
|
gmux "github.com/gorilla/mux"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type rawConfig struct {
|
|
|
|
|
type RawConfig struct {
|
|
|
|
|
ProxyBook map[string][]string
|
|
|
|
|
BindAddr []string
|
|
|
|
|
BypassUID [][]byte
|
|
|
|
@ -31,7 +31,6 @@ type rawConfig struct {
|
|
|
|
|
|
|
|
|
|
// State type stores the global state of the program
|
|
|
|
|
type State struct {
|
|
|
|
|
BindAddr []net.Addr
|
|
|
|
|
ProxyBook map[string]net.Addr
|
|
|
|
|
ProxyDialer common.Dialer
|
|
|
|
|
|
|
|
|
@ -55,17 +54,6 @@ type State struct {
|
|
|
|
|
LocalAPIRouter *gmux.Router
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func InitState(nowFunc func() time.Time) (*State, error) {
|
|
|
|
|
ret := &State{
|
|
|
|
|
Now: nowFunc,
|
|
|
|
|
BypassUID: make(map[[16]byte]struct{}),
|
|
|
|
|
ProxyBook: map[string]net.Addr{},
|
|
|
|
|
usedRandom: map[[32]byte]int64{},
|
|
|
|
|
}
|
|
|
|
|
go ret.UsedRandomCleaner()
|
|
|
|
|
return ret, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func parseRedirAddr(redirAddr string) (net.Addr, string, error) {
|
|
|
|
|
var host string
|
|
|
|
|
var port string
|
|
|
|
@ -109,18 +97,6 @@ func parseLocalPanel(databasePath string) (*userPanel, *gmux.Router, error) {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func parseBindAddr(bindAddrs []string) ([]net.Addr, error) {
|
|
|
|
|
var addrs []net.Addr
|
|
|
|
|
for _, addr := range bindAddrs {
|
|
|
|
|
bindAddr, err := net.ResolveTCPAddr("tcp", addr)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
addrs = append(addrs, bindAddr)
|
|
|
|
|
}
|
|
|
|
|
return addrs, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func parseProxyBook(bookEntries map[string][]string) (map[string]net.Addr, error) {
|
|
|
|
|
proxyBook := map[string]net.Addr{}
|
|
|
|
|
for name, pair := range bookEntries {
|
|
|
|
@ -149,28 +125,40 @@ func parseProxyBook(bookEntries map[string][]string) (map[string]net.Addr, error
|
|
|
|
|
return proxyBook, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ParseConfig parses the config (either a path to json or the json itself as argument) into a State variable
|
|
|
|
|
func (sta *State) ParseConfig(conf string) (err error) {
|
|
|
|
|
var content []byte
|
|
|
|
|
var preParse rawConfig
|
|
|
|
|
|
|
|
|
|
func ParseConfig(conf string) (raw RawConfig, err error) {
|
|
|
|
|
content, errPath := ioutil.ReadFile(conf)
|
|
|
|
|
if errPath != nil {
|
|
|
|
|
errJson := json.Unmarshal(content, &preParse)
|
|
|
|
|
errJson := json.Unmarshal(content, &raw)
|
|
|
|
|
if errJson != nil {
|
|
|
|
|
return errors.New("Failed to read/unmarshal configuration, path is invalid or " + errJson.Error())
|
|
|
|
|
err = fmt.Errorf("failed to read/unmarshal configuration, path is invalid or %v", errJson)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
errJson := json.Unmarshal(content, &preParse)
|
|
|
|
|
errJson := json.Unmarshal(content, &raw)
|
|
|
|
|
if errJson != nil {
|
|
|
|
|
return errors.New("Failed to read configuration file: " + errJson.Error())
|
|
|
|
|
err = fmt.Errorf("failed to read configuration file: %v", errJson)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ParseConfig parses the config (either a path to json or the json itself as argument) into a State variable
|
|
|
|
|
func InitState(preParse RawConfig, nowFunc func() time.Time) (sta *State, err error) {
|
|
|
|
|
sta = &State{
|
|
|
|
|
Now: nowFunc,
|
|
|
|
|
BypassUID: make(map[[16]byte]struct{}),
|
|
|
|
|
ProxyBook: map[string]net.Addr{},
|
|
|
|
|
usedRandom: map[[32]byte]int64{},
|
|
|
|
|
}
|
|
|
|
|
if preParse.CncMode {
|
|
|
|
|
return errors.New("command & control mode not implemented")
|
|
|
|
|
err = errors.New("command & control mode not implemented")
|
|
|
|
|
return
|
|
|
|
|
} else {
|
|
|
|
|
sta.Panel, sta.LocalAPIRouter, err = parseLocalPanel(preParse.DatabasePath)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if preParse.StreamTimeout == 0 {
|
|
|
|
@ -187,17 +175,14 @@ func (sta *State) ParseConfig(conf string) (err error) {
|
|
|
|
|
|
|
|
|
|
sta.RedirHost, sta.RedirPort, err = parseRedirAddr(preParse.RedirAddr)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("unable to parse RedirAddr: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sta.BindAddr, err = parseBindAddr(preParse.BindAddr)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("unable to parse BindAddr: %v", err)
|
|
|
|
|
err = fmt.Errorf("unable to parse RedirAddr: %v", err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sta.ProxyBook, err = parseProxyBook(preParse.ProxyBook)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("unable to parse ProxyBook: %v", err)
|
|
|
|
|
err = fmt.Errorf("unable to parse ProxyBook: %v", err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var pv [32]byte
|
|
|
|
@ -214,7 +199,8 @@ func (sta *State) ParseConfig(conf string) (err error) {
|
|
|
|
|
copy(arrUID[:], sta.AdminUID)
|
|
|
|
|
sta.BypassUID[arrUID] = struct{}{}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
go sta.UsedRandomCleaner()
|
|
|
|
|
return sta, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// IsBypass checks if a UID is a bypass user
|
|
|
|
|