summaryrefslogtreecommitdiff
path: root/obfs4proxy
diff options
context:
space:
mode:
authorYawning Angel <yawning@schwanenlied.me>2014-05-25 08:01:11 +0000
committerYawning Angel <yawning@schwanenlied.me>2014-05-25 08:01:11 +0000
commitd5c3a25dec7f235ce34890fcc0f9eb9e7933c2b0 (patch)
tree13bc70351698066c7e0464a4dbd442defdd18a32 /obfs4proxy
parentf04fd166ac0ff7cf362db2e1d1958a32b17be25f (diff)
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.
Diffstat (limited to 'obfs4proxy')
-rw-r--r--obfs4proxy/obfs4proxy.go10
-rw-r--r--obfs4proxy/pt_extra.go68
2 files changed, 78 insertions, 0 deletions
diff --git a/obfs4proxy/obfs4proxy.go b/obfs4proxy/obfs4proxy.go
index ae18c5d..2e8a011 100644
--- a/obfs4proxy/obfs4proxy.go
+++ b/obfs4proxy/obfs4proxy.go
@@ -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:
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
+}