[tor-commits] [meek/master] Add meek-client-torbrowser program.

dcf at torproject.org dcf at torproject.org
Wed Apr 9 05:56:56 UTC 2014


commit 7cba0a659c3abd4b92eb289b20263726d1c6d610
Author: David Fifield <david at bamsoftware.com>
Date:   Sun Apr 6 10:07:33 2014 -0700

    Add meek-client-torbrowser program.
    
    This program starts firefox with the meek-http-helper profile and then
    starts meek-client set up to talk to it.
---
 .gitignore                        |    1 +
 meek-client-torbrowser/Makefile   |   18 +++++
 meek-client-torbrowser/linux.go   |   10 +++
 meek-client-torbrowser/mac.go     |   10 +++
 meek-client-torbrowser/main.go    |  160 +++++++++++++++++++++++++++++++++++++
 meek-client-torbrowser/windows.go |   10 +++
 6 files changed, 209 insertions(+)

diff --git a/.gitignore b/.gitignore
index e085380..3d5729c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
 /meek-client/meek-client
+/meek-client-torbrowser/meek-client-torbrowser
 /meek-server/meek-server
diff --git a/meek-client-torbrowser/Makefile b/meek-client-torbrowser/Makefile
new file mode 100644
index 0000000..7ce013b
--- /dev/null
+++ b/meek-client-torbrowser/Makefile
@@ -0,0 +1,18 @@
+DESTDIR =
+PREFIX = /usr/local
+BINDIR = $(PREFIX)/bin
+
+GOBUILDFLAGS =
+
+all: meek-client
+
+meek-client: *.go
+	go build $(GOBUILDFLAGS)
+
+clean:
+	rm -f meek-client-torbrowser
+
+fmt:
+	go fmt
+
+.PHONY: all install clean fmt
diff --git a/meek-client-torbrowser/linux.go b/meek-client-torbrowser/linux.go
new file mode 100644
index 0000000..73e363a
--- /dev/null
+++ b/meek-client-torbrowser/linux.go
@@ -0,0 +1,10 @@
+// +build linux
+// This file is compiled only on linux. It contains paths used by the linux
+// browser bundle.
+// http://golang.org/pkg/go/build/#hdr-Build_Constraints
+
+package main
+
+var firefoxPath = "Browser/firefox"
+var firefoxProfilePath = "Data/Browser/profile.meek-http-helper"
+var meekClientPath = "Tor/PluggableTransports/meek-client"
diff --git a/meek-client-torbrowser/mac.go b/meek-client-torbrowser/mac.go
new file mode 100644
index 0000000..6830da1
--- /dev/null
+++ b/meek-client-torbrowser/mac.go
@@ -0,0 +1,10 @@
+// +build darwin
+// This file is compiled only on mac. It contains paths used by the mac
+// browser bundle.
+// http://golang.org/pkg/go/build/#hdr-Build_Constraints
+
+package main
+
+var firefoxPath = "../Contents/MacOS/TorBrowser.app/Contents/MacOS/firefox"
+var firefoxProfilePath = "../Data/Browser/profile.meek-http-helper"
+var meekClientPath = "PluggableTransports/meek-client"
diff --git a/meek-client-torbrowser/main.go b/meek-client-torbrowser/main.go
new file mode 100644
index 0000000..8890f6d
--- /dev/null
+++ b/meek-client-torbrowser/main.go
@@ -0,0 +1,160 @@
+// The meek-client-torbrowser program starts a copy of Tor Browser running
+// meek-http-helper in a special profile, and then starts meek-client set up to
+// use the browser helper.
+//
+// Arguments to this program are passed unmodified to meek-client, with the
+// addition of a --helper option pointing to the browser helper.
+package main
+
+import (
+	"bufio"
+	"io"
+	"io/ioutil"
+	"log"
+	"os"
+	"os/exec"
+	"os/signal"
+	"path/filepath"
+	"regexp"
+	"syscall"
+)
+
+var helperAddrPattern *regexp.Regexp
+
+// Log a call to os.Process.Kill.
+func logKill(p *os.Process) error {
+	log.Printf("killing PID %d", p.Pid)
+	err := p.Kill()
+	if err != nil {
+		log.Print(err)
+	}
+	return err
+}
+
+// Log a call to os.Process.Signal.
+func logSignal(p *os.Process, sig os.Signal) error {
+	log.Printf("sending signal %s to PID %d", sig, p.Pid)
+	err := p.Signal(sig)
+	if err != nil {
+		log.Print(err)
+	}
+	return err
+}
+
+// Run firefox and return its exec.Cmd and stdout pipe.
+func runFirefox() (cmd *exec.Cmd, stdout io.Reader, err error) {
+	var profilePath string
+	// Mac OS X needs an absolute profile path.
+	profilePath, err = filepath.Abs(firefoxProfilePath)
+	if err != nil {
+		return
+	}
+	cmd = exec.Command(firefoxPath, "-no-remote", "-profile", profilePath)
+	cmd.Stderr = os.Stderr
+	stdout, err = cmd.StdoutPipe()
+	if err != nil {
+		return
+	}
+	log.Printf("running firefox command %q", cmd.Args)
+	err = cmd.Start()
+	if err != nil {
+		return
+	}
+	log.Printf("firefox started with pid %d", cmd.Process.Pid)
+	return cmd, stdout, nil
+}
+
+// Look for the magic meek-http-helper address string in the Reader, and return
+// the address it contains. Start a goroutine to continue reading and discarding
+// output of the Reader before returning.
+func grepHelperAddr(r io.Reader) (string, error) {
+	var helperAddr string
+	scanner := bufio.NewScanner(r)
+	for scanner.Scan() {
+		line := scanner.Text()
+		if m := helperAddrPattern.FindStringSubmatch(line); m != nil {
+			helperAddr = m[1]
+			break
+		}
+	}
+	err := scanner.Err()
+	if err != nil {
+		return "", err
+	}
+	// Ran out of input before finding the pattern.
+	if helperAddr == "" {
+		return "", io.EOF
+	}
+	// Keep reading from the browser to avoid its output buffer filling.
+	go io.Copy(ioutil.Discard, r)
+	return helperAddr, nil
+}
+
+// Run meek-client and return its exec.Cmd.
+func runMeekClient(helperAddr string) (cmd *exec.Cmd, err error) {
+	args := os.Args[1:]
+	args = append(args, []string{"--helper", helperAddr}...)
+	cmd = exec.Command(meekClientPath, args...)
+	cmd.Stdout = os.Stdout
+	cmd.Stderr = os.Stderr
+	log.Printf("running meek-client command %q", cmd.Args)
+	err = cmd.Start()
+	if err != nil {
+		return
+	}
+	log.Printf("meek-client started with pid %d", cmd.Process.Pid)
+	return cmd, nil
+}
+
+func main() {
+	var err error
+
+	sigChan := make(chan os.Signal, 1)
+	signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
+
+	// This magic string is emitted by meek-http-helper.
+	helperAddrPattern, err = regexp.Compile(`^meek-http-helper: listen (127\.0\.0\.1:\d+)$`)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	// Start firefox.
+	firefoxCmd, stdout, err := runFirefox()
+	if err != nil {
+		log.Print(err)
+		return
+	}
+	defer logKill(firefoxCmd.Process)
+
+	// Find out the helper's listening address.
+	helperAddr, err := grepHelperAddr(stdout)
+	if err != nil {
+		log.Print(err)
+		return
+	}
+
+	// Start meek-client with the helper address.
+	meekClientCmd, err := runMeekClient(helperAddr)
+	if err != nil {
+		log.Print(err)
+		return
+	}
+	defer logKill(meekClientCmd.Process)
+
+	sig := <-sigChan
+	log.Printf("sig %s", sig)
+	err = logSignal(meekClientCmd.Process, sig)
+	if err != nil {
+		log.Print(err)
+	}
+
+	// If SIGINT, wait for a second SIGINT.
+	if sig == syscall.SIGINT {
+		sig := <-sigChan
+		log.Printf("sig %s", sig)
+		err = logSignal(meekClientCmd.Process, sig)
+		if err != nil {
+			log.Print(err)
+		}
+	}
+}
diff --git a/meek-client-torbrowser/windows.go b/meek-client-torbrowser/windows.go
new file mode 100644
index 0000000..ed590d8
--- /dev/null
+++ b/meek-client-torbrowser/windows.go
@@ -0,0 +1,10 @@
+// +build windows
+// This file is compiled only on windows. It contains paths used by the windows
+// browser bundle.
+// http://golang.org/pkg/go/build/#hdr-Build_Constraints
+
+package main
+
+var firefoxPath string = "Browser/firefox.exe"
+var firefoxProfilePath = "Data/Browser/profile.meek-http-helper"
+var meekClientPath = "Tor/PluggableTransports/meek-client.exe"





More information about the tor-commits mailing list