[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [fog/master] Added a loading configuration file on the server side. The format is identical to the client configuration file except ClientTransportationPlugin is ServerTransportationPlugin. Uses go-shellwords to parse the config files.
commit 58858475e5ba737ca0e7e271b7604fe1ac06bf75
Author: Quinn Jarrell <qjarrell@xxxxxxxxxxxxxxx>
Date: Mon Jun 23 16:15:18 2014 -0400
Added a loading configuration file on the server side. The format is identical to the client configuration file except ClientTransportationPlugin is ServerTransportationPlugin. Uses go-shellwords to parse the config files.
---
fog-server/Makefile | 2 +-
fog-server/config.go | 145 ++++++++++++++++++++++++++++++++++++++++++++++
fog-server/fog-server.go | 80 ++++---------------------
fog-server/fogrc | 13 +++++
fog-server/torrc | 2 +-
5 files changed, 171 insertions(+), 71 deletions(-)
diff --git a/fog-server/Makefile b/fog-server/Makefile
index c7d474b..1a153a6 100644
--- a/fog-server/Makefile
+++ b/fog-server/Makefile
@@ -1,6 +1,6 @@
GOBUILDFLAGS =
-./fog-server: ./fog-server.go ./stack.go
+./fog-server: ./fog-server.go ./stack.go ./config.go
go build $(GOBUILDFLAGS) -o "$@" $^
test:
diff --git a/fog-server/config.go b/fog-server/config.go
new file mode 100644
index 0000000..615ea47
--- /dev/null
+++ b/fog-server/config.go
@@ -0,0 +1,145 @@
+package main
+
+import (
+ "errors"
+ "fmt"
+ "io/ioutil"
+ "strings"
+)
+
+import "git.torproject.org/pluggable-transports/goptlib.git"
+import "github.com/mattn/go-shellwords"
+
+// Represents a server transport plugin configuration like:
+// ServerTransportPlugin MethodName exec Command
+type ServerTransportPlugin struct {
+ MethodName string
+ Command []string
+ Options pt.Args
+}
+
+type Configuration struct {
+ // Map from method names to command strings.
+ Transports map[string][]string
+ // Map from method names to ServerTransportOptions.
+ Options map[string]pt.Args
+ // Map from tor-friendly names like "obfs3_websocket" to systematic
+ // names like "obfs3|websocket".
+ Aliases map[string]string
+}
+
+func (conf *Configuration) MethodNames() []string {
+ result := make([]string, 0)
+ // We understand all the single transports
+ for k, _ := range conf.Transports {
+ result = append(result, k)
+ }
+ // and aliases.
+ for k, _ := range conf.Aliases {
+ result = append(result, k)
+ }
+ return result
+}
+
+// Parse a (possibly composed) method name into a slice of single method names.
+func (conf *Configuration) ParseMethodName(methodName string) []string {
+ if name, ok := conf.Aliases[methodName]; ok {
+ methodName = name
+ }
+ return strings.Split(methodName, "|")
+}
+
+func (conf *Configuration) PluginList(methodName string) ([]ServerTransportPlugin, error) {
+ names := conf.ParseMethodName(methodName)
+ stp := make([]ServerTransportPlugin, 0)
+ for _, name := range names {
+ command, ok := conf.Transports[name]
+ if !ok {
+ return nil, errors.New(fmt.Sprintf("no transport named %q", name))
+ }
+ options := conf.Options[name]
+ stp = append(stp, ServerTransportPlugin{name, command, options})
+ }
+ return stp, nil
+}
+
+// Initialize a configuration object
+func getConfiguration() (conf *Configuration) {
+ conf = new(Configuration)
+ conf.Transports = make(map[string][]string)
+ conf.Aliases = make(map[string]string)
+ conf.Options = make(map[string]pt.Args)
+ return conf
+}
+
+// Reads a configuration file and returns the contents
+func ReadConfigFile(fileName string) (*Configuration, error) {
+ var contents []byte
+ contents, err := ioutil.ReadFile(fileName)
+ if err != nil {
+ return nil, errors.New(fmt.Sprintf("Error reading configuration file %s contents.", fileName))
+ }
+ return ParseConfiguration(string(contents), getConfiguration())
+}
+
+// Parses a configuration string and fills the config object's fields with the requested Aliases and ServerTransportPlugins
+func ParseConfiguration(configString string, config *Configuration) (*Configuration, error) {
+ lines := strings.Split(configString, "\n")
+ for lineCounter, line := range lines {
+ if len(line) > 0 && line[0] != '#' { // Check for empty lines and comment tags on the first
+ line = strings.TrimSpace(line)
+ delimitedTokens, err := shellwords.Parse(line)
+ if err != nil {
+ return nil, errors.New(fmt.Sprintf("Line %v: \"%v\" was split incorrectly by shellwords. Error: %v", lineCounter, line, err))
+ }
+ if len(delimitedTokens) > 1 {
+ configLineType := delimitedTokens[0] // This can be either Alias or ServerTransportPlugin
+ if configLineType == "ServerTransportPlugin" {
+ err = parseTransportLine(config, delimitedTokens, lineCounter)
+ if err != nil {
+ return nil, err
+ }
+ } else if configLineType == "Alias" {
+ err = parseAliasLine(config, delimitedTokens, lineCounter)
+ if err != nil {
+ return nil, err
+ }
+ } else {
+ log("Configuration file has unknown line %s: %s", lineCounter, line)
+ }
+ }
+ }
+ }
+ return config, nil
+}
+
+// Parses a ServerTransportPlugin line.
+// Ex: ServerTransportPlugin dummy obfsproxy --client T managed
+func parseTransportLine(config *Configuration, tokens []string, lineCounter int) error {
+ transportName := tokens[1]
+ transportCmdLine := tokens[2:]
+ if _, ok := config.Transports[transportName]; ok {
+ return errors.New(fmt.Sprintf("Configuration file has duplicate ServerTransportPlugin lines. Duplicate line is at line number %s", lineCounter))
+ }
+ config.Transports[transportName] = transportCmdLine
+ return nil
+}
+
+// Parses an alias line
+// Ex: Alias b64_b64 b64|b64
+func parseAliasLine(config *Configuration, tokens []string, lineCounter int) error {
+ var aliasName string
+ var aliasPath []string
+ aliasName = tokens[1]
+ aliasPath = strings.Split(tokens[2], "|")
+ if _, hashed := config.Aliases[aliasName]; hashed {
+ return errors.New(fmt.Sprintf("Configuration file has duplicate Alias lines. Duplicate line is at line number %s", lineCounter))
+ }
+ for _, ptName := range aliasPath {
+ if _, hashed := config.Transports[ptName]; !hashed {
+ log("Transport map is missing pluggable transport %s needed for chain %s. Check your configuration file for a ServerTransportPlugin line can launch %s", ptName, aliasName, ptName)
+ }
+ }
+ config.Aliases[aliasName] = tokens[2]
+ return nil
+}
\ No newline at end of file
diff --git a/fog-server/fog-server.go b/fog-server/fog-server.go
index cf77a6a..9ee2703 100644
--- a/fog-server/fog-server.go
+++ b/fog-server/fog-server.go
@@ -39,6 +39,7 @@ func usage() {
fmt.Printf(" -h, --help show this help.\n")
fmt.Printf(" --log FILE log messages to FILE (default stderr).\n")
fmt.Printf(" --port PORT listen on PORT (overrides Tor's requested port).\n")
+ fmt.Printf(" -f, --file FILE Loads and runs configuration FILE.\n")
}
var logMutex sync.Mutex
@@ -174,14 +175,6 @@ func encodeServerTransportOptions(methodName string, opts pt.Args) string {
return strings.Join(parts, ";")
}
-// Represents a server transport plugin configuration like:
-// ServerTransportPlugin MethodName exec Command
-type ServerTransportPlugin struct {
- MethodName string
- Command []string
- Options pt.Args
-}
-
func startProcesses(connectBackAddr net.Addr, plugins []ServerTransportPlugin) (bindAddr *net.TCPAddr, procs ProcList, err error) {
var stdout io.ReadCloser
@@ -393,72 +386,17 @@ func startChain(methodName string, bindaddr *net.TCPAddr, plugins []ServerTransp
return chain, nil
}
-type Configuration struct {
- // Map from method names to command strings.
- Transports map[string][]string
- // Map from method names to ServerTransportOptions.
- Options map[string]pt.Args
- // Map from tor-friendly names like "obfs3_websocket" to systematic
- // names like "obfs3|websocket".
- Aliases map[string]string
-}
-
-func (conf *Configuration) MethodNames() []string {
- result := make([]string, 0)
- // We understand all the single transports
- for k, _ := range conf.Transports {
- result = append(result, k)
- }
- // and aliases.
- for k, _ := range conf.Aliases {
- result = append(result, k)
- }
- return result
-}
-
-// Parse a (possibly composed) method name into a slice of single method names.
-func (conf *Configuration) ParseMethodName(methodName string) []string {
- if name, ok := conf.Aliases[methodName]; ok {
- methodName = name
- }
- return strings.Split(methodName, "|")
-}
-
-func (conf *Configuration) PluginList(methodName string) ([]ServerTransportPlugin, error) {
- names := conf.ParseMethodName(methodName)
- stp := make([]ServerTransportPlugin, 0)
- for _, name := range names {
- command, ok := conf.Transports[name]
- if !ok {
- return nil, errors.New(fmt.Sprintf("no transport named %q", name))
- }
- options := conf.Options[name]
- stp = append(stp, ServerTransportPlugin{name, command, options})
- }
- return stp, nil
-}
-
-// Simulate loading a configuration file.
-func getConfiguration() (conf *Configuration) {
- conf = new(Configuration)
- conf.Transports = make(map[string][]string)
- conf.Aliases = make(map[string]string)
- conf.Options = make(map[string]pt.Args)
- conf.Transports["obfs3"] = []string{"obfsproxy", "managed"}
- conf.Transports["websocket"] = []string{"pt-websocket-server"}
- // conf.Options["obfs3"] = make(pt.Args)
- // conf.Options["obfs3"]["secret"] = []string{"foo"}
- conf.Aliases["obfs3_websocket"] = "obfs3|websocket"
- return conf
-}
-
func main() {
var logFilename string
var port int
+ var configFilename string
+ var conf *Configuration
flag.Usage = usage
flag.StringVar(&logFilename, "log", "", "log file to write to")
flag.IntVar(&port, "port", 0, "port to listen on if unspecified by Tor")
+ flag.StringVar(&configFilename, "file", "fogrc", "The fog file to read the configuration from.")
+ flag.StringVar(&configFilename, "f", "fogrc", "The fog file to read the configuration from.")
flag.Parse()
if logFilename != "" {
@@ -469,11 +407,15 @@ func main() {
}
logFile = f
}
+ var err error
+ conf, err = ReadConfigFile(configFilename)
+ if err != nil {
+ log("Error in reading configuration file: %s", err)
+ os.Exit(1)
+ }
log("Starting.")
- var err error
- conf := getConfiguration()
ptInfo, err = pt.ServerSetup(conf.MethodNames())
if err != nil {
log("Error in ServerSetup: %s", err)
diff --git a/fog-server/fogrc b/fog-server/fogrc
new file mode 100644
index 0000000..870d8b6
--- /dev/null
+++ b/fog-server/fogrc
@@ -0,0 +1,13 @@
+#Based off of ticket #9744
+#Server transports are setup like so:
+#ServerTransportPlugin name commandline
+#For instance to launch obfs3, the server transport line should be this
+#ServerTransportPlugin obfs3 obfsproxy managed
+#
+#For chaining transports together, an alias line is used.
+#Alias chainname firsttransportname|secondtransportname
+#tor expects alias to use underscores instead of pipes. So an alias links the tor version of a plugin chain to the actual plugins. See ticket #9580
+
+ServerTransportPlugin obfs3 obfsproxy managed
+ServerTransportPlugin websocket pt-websocket-server
+Alias obfs3_websocket obfs3|websocket
\ No newline at end of file
diff --git a/fog-server/torrc b/fog-server/torrc
index f103ddc..88258fa 100644
--- a/fog-server/torrc
+++ b/fog-server/torrc
@@ -2,4 +2,4 @@ ORPort 9999
ExtORPort 5555
BridgeRelay 1
SocksPort 0
-ServerTransportPlugin obfs3_websocket exec ./bin/fog-server
+ServerTransportPlugin obfs3_websocket exec ./fog-server
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits