diff options
Diffstat (limited to 'obfs4proxy/pt_extra.go')
-rw-r--r-- | obfs4proxy/pt_extra.go | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/obfs4proxy/pt_extra.go b/obfs4proxy/pt_extra.go index 889c7bd..4d629e8 100644 --- a/obfs4proxy/pt_extra.go +++ b/obfs4proxy/pt_extra.go @@ -30,6 +30,7 @@ package main import ( "errors" "fmt" + "net/url" "os" "git.torproject.org/pluggable-transports/goptlib" @@ -44,6 +45,17 @@ func ptEnvError(msg string) error { return errors.New(msg) } +func ptProxyError(msg string) error { + line := []byte(fmt.Sprintf("PROXY-ERROR %s\n", msg)) + pt.Stdout.Write(line) + return errors.New(msg) +} + +func ptProxyDone() { + line := []byte("PROXY DONE\n") + pt.Stdout.Write(line) +} + func ptMakeStateDir() (string, error) { dir := os.Getenv("TOR_PT_STATE_LOCATION") if dir == "" { @@ -65,3 +77,59 @@ func ptIsClient() (bool, error) { } return false, errors.New("not launched as a managed transport") } + +func ptGetProxy() (*url.URL, error) { + specString := os.Getenv("TOR_PT_PROXY") + if specString == "" { + return nil, nil + } + spec, err := url.Parse(specString) + if err != nil { + return nil, ptProxyError(fmt.Sprintf("failed to parse proxy config: %s", err)) + } + + // Validate the TOR_PT_PROXY uri. + if !spec.IsAbs() { + return nil, ptProxyError("proxy URI is relative, must be absolute") + } + if spec.Path != "" { + return nil, ptProxyError("proxy URI has a path defined") + } + if spec.RawQuery != "" { + return nil, ptProxyError("proxy URI has a query defined") + } + if spec.Fragment != "" { + return nil, ptProxyError("proxy URI has a fragment defined") + } + + switch spec.Scheme { + case "http": + // The most forgiving of proxies. + + case "socks4a": + if spec.User != nil { + _, isSet := spec.User.Password() + if isSet { + return nil, ptProxyError("proxy URI specified SOCKS4a and a password") + } + } + + case "socks5": + if spec.User != nil { + // UNAME/PASSWD both must be between 1 and 255 bytes long. (RFC1929) + user := spec.User.Username() + passwd, isSet := spec.User.Password() + if len(user) < 1 || len(user) > 255 { + return nil, ptProxyError("proxy URI specified a invalid SOCKS5 username") + } + if !isSet || len(passwd) < 1 || len(passwd) > 255 { + return nil, ptProxyError("proxy URI specified a invalid SOCKS5 password") + } + } + + default: + return nil, ptProxyError(fmt.Sprintf("proxy URI has invalid scheme: %s", spec.Scheme)) + } + + return spec, nil +} |