Parse TOR_PT_PROXY and support sending DONE/PROXY-ERROR.

Currently obfs4proxy is hardcoded to always PROXY-ERROR, despite a
valid proxy uri being passed in the env var.  Once the dialer portion
of the code is done, this will be changed.

Part of issue #7.
merge-requests/3/head
Yawning Angel 10 years ago
parent f04fd166ac
commit d5c3a25dec

@ -299,6 +299,16 @@ func clientSetup() (launched bool) {
return
}
ptClientProxy, err := ptGetProxy()
if err != nil {
log.Fatal(err)
return
}
if ptClientProxy != nil {
// XXX: Remove this once done.
ptProxyError("proxy are not supported yet")
}
for _, methodName := range ptClientInfo.MethodNames {
switch methodName {
case obfs4Method:

@ -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
}

Loading…
Cancel
Save