From bbe4198a414afad5ef3a91e8ac7fda63f2f32400 Mon Sep 17 00:00:00 2001 From: Dan Ballard Date: Sat, 8 Oct 2022 11:58:42 -0700 Subject: [PATCH 1/2] add TakeOwnership call once tor started to help ensure tor ends; add support for __OwningControllerProcess --- tor/torProvider.go | 2 ++ tor/torrcBuilder.go | 23 +++++++++++++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/tor/torProvider.go b/tor/torProvider.go index d1050ce..69f32c7 100644 --- a/tor/torProvider.go +++ b/tor/torProvider.go @@ -335,6 +335,7 @@ func (tp *torProvider) restart() { } tp.lastRestartTime = time.Now() tp.isClosed = false + tp.t.Control.TakeOwnership() go tp.monitorRestart() } else { log.Errorf("Error restarting Tor process: %v", err) @@ -431,6 +432,7 @@ func NewTorACNWithAuth(appDirectory string, bundledTorPath string, dataDir strin tp, err := startTor(appDirectory, bundledTorPath, dataDir, controlPort, authenticator) if err == nil { tp.isClosed = false + tp.t.Control.TakeOwnership() go tp.monitorRestart() } return tp, err diff --git a/tor/torrcBuilder.go b/tor/torrcBuilder.go index dc04c04..8a49114 100644 --- a/tor/torrcBuilder.go +++ b/tor/torrcBuilder.go @@ -42,15 +42,28 @@ func (tb *TorrcBuilder) WithControlPort(port int) *TorrcBuilder { return tb } -// WithLog sets the Log to file directive to the specified with with the specified log level +// WithLog sets the Log to file directive to the specified file with the specified log level func (tb *TorrcBuilder) WithLog(logfile string, level TorLogLevel) *TorrcBuilder { tb.lines = append(tb.lines, fmt.Sprintf("Log %v file %v", level, logfile)) return tb } -// WithCustom clobbers the torrc builder and allows the client to set any option they want, while benefiting +// WithSocksTimeout adjusts how long before a timeout error is generated trying to connect to the SOCKS port +func (tb *TorrcBuilder) WithSocksTimeout(timeOutSecs int) *TorrcBuilder { + tb.lines = append(tb.lines, fmt.Sprintf("SocksTimeout %v", timeOutSecs)) + return tb +} + +// WithCustom appends to the torrc builder and allows the client to set any option they want, while benefiting // from other configuration options. func (tb *TorrcBuilder) WithCustom(lines []string) *TorrcBuilder { + tb.lines = append(tb.lines, lines...) + return tb +} + +// UseCustom clobbers the torrc builder and allows the client to set any option they want, while benefiting +// from other configuration options. +func (tb *TorrcBuilder) UseCustom(lines []string) *TorrcBuilder { tb.lines = lines return tb } @@ -66,6 +79,12 @@ func (tb *TorrcBuilder) WithOnionTrafficOnly() *TorrcBuilder { return tb } +// WithOwningPid adds a __OwningControllerProcess line to the config that will attempt to have tor monitor parent PID health and die when parent dies +func (tb *TorrcBuilder) WithOwningPid(pid int) *TorrcBuilder { + tb.lines = append(tb.lines, fmt.Sprintf("__OwningControllerProcess %v", pid)) + return tb +} + // WithHashedPassword sets a password for the control port. func (tb *TorrcBuilder) WithHashedPassword(password string) *TorrcBuilder { var salt [8]byte From 2f3860eb89668484ceda3d69545c1006a59d4698 Mon Sep 17 00:00:00 2001 From: Dan Ballard Date: Sat, 8 Oct 2022 11:59:51 -0700 Subject: [PATCH 2/2] drone use go 1.19.1 --- .drone.yml | 8 ++++---- testing/launch_tor_integration_test.go | 3 +-- tor/torProvider.go | 7 +++---- tor/torProvider_test.go | 3 +-- tor/torrcBuilder.go | 4 ++-- 5 files changed, 11 insertions(+), 14 deletions(-) diff --git a/.drone.yml b/.drone.yml index 79c5d40..19513fe 100644 --- a/.drone.yml +++ b/.drone.yml @@ -5,7 +5,7 @@ name: linux-test steps: - name: fetch - image: golang:1.17.5 + image: golang:1.19.1 volumes: - name: deps path: /go @@ -15,14 +15,14 @@ steps: - chmod a+x tmp/tor - go mod download - name: quality - image: golang:1.17.5 + image: golang:1.19.1 volumes: - name: deps path: /go commands: - staticcheck ./... - name: units-tests - image: golang:1.17.5 + image: golang:1.19.1 volumes: - name: deps path: /go @@ -33,7 +33,7 @@ steps: - sh testing/tests.sh - pkill -9 tor - name: integration-tests - image: golang:1.17.5 + image: golang:1.19.1 volumes: - name: deps path: /go diff --git a/testing/launch_tor_integration_test.go b/testing/launch_tor_integration_test.go index 73c7329..8b58106 100644 --- a/testing/launch_tor_integration_test.go +++ b/testing/launch_tor_integration_test.go @@ -3,7 +3,6 @@ package testing import ( "git.openprivacy.ca/openprivacy/connectivity/tor" "git.openprivacy.ca/openprivacy/log" - "io/ioutil" "math/rand" "os" path "path/filepath" @@ -30,7 +29,7 @@ func TestLaunchTor(t *testing.T) { } dataDir := "" - if dataDir, err = ioutil.TempDir(path.Join("..", "testing"), "data-dir-"); err != nil { + if dataDir, err = os.MkdirTemp(path.Join("..", "testing"), "data-dir-"); err != nil { t.Fatalf("could not create data dir") } diff --git a/tor/torProvider.go b/tor/torProvider.go index 69f32c7..24f649c 100644 --- a/tor/torProvider.go +++ b/tor/torProvider.go @@ -335,7 +335,6 @@ func (tp *torProvider) restart() { } tp.lastRestartTime = time.Now() tp.isClosed = false - tp.t.Control.TakeOwnership() go tp.monitorRestart() } else { log.Errorf("Error restarting Tor process: %v", err) @@ -432,7 +431,6 @@ func NewTorACNWithAuth(appDirectory string, bundledTorPath string, dataDir strin tp, err := startTor(appDirectory, bundledTorPath, dataDir, controlPort, authenticator) if err == nil { tp.isClosed = false - tp.t.Control.TakeOwnership() go tp.monitorRestart() } return tp, err @@ -488,9 +486,9 @@ func startTor(appDirectory string, bundledTorPath string, dataDir string, contro if err == nil { log.Debugf("creating tor handler from system tor") tp.t = createFromExisting(controlport, dataDir) + tp.dialer, err = tp.t.Dialer(context.TODO(), &tor.DialConf{Authenticator: tp.authenticator}) + return tp, err } - tp.dialer, err = tp.t.Dialer(context.TODO(), &tor.DialConf{Authenticator: tp.authenticator}) - return tp, err } // check if the torrc file is present where expected @@ -529,6 +527,7 @@ func startTor(appDirectory string, bundledTorPath string, dataDir string, contro tp.t.DeleteDataDirOnClose = false // caller is responsible for dealing with cached information... tp.dialer, err = tp.t.Dialer(context.TODO(), &tor.DialConf{Authenticator: tp.authenticator}) tp.version = version + tp.t.Control.TakeOwnership() return tp, err } return nil, fmt.Errorf("could not connect to running tor: %v", err) diff --git a/tor/torProvider_test.go b/tor/torProvider_test.go index 9967c4e..2ed6171 100644 --- a/tor/torProvider_test.go +++ b/tor/torProvider_test.go @@ -3,7 +3,6 @@ package tor import ( "fmt" "git.openprivacy.ca/openprivacy/log" - "io/ioutil" "os" path "path/filepath" "runtime" @@ -41,7 +40,7 @@ func TestTorProvider(t *testing.T) { dataDir := "" var err error - if dataDir, err = ioutil.TempDir(path.Join("..", "testing"), "data-dir-"); err != nil { + if dataDir, err = os.MkdirTemp(path.Join("..", "testing"), "data-dir-"); err != nil { t.Fatalf("could not create data dir") } diff --git a/tor/torrcBuilder.go b/tor/torrcBuilder.go index 8a49114..960ce3b 100644 --- a/tor/torrcBuilder.go +++ b/tor/torrcBuilder.go @@ -6,7 +6,7 @@ import ( "encoding/hex" "fmt" "io" - "io/ioutil" + "os" "strings" ) @@ -98,7 +98,7 @@ func (tb *TorrcBuilder) WithHashedPassword(password string) *TorrcBuilder { // Build finalizes the torrc contents and write a file func (tb *TorrcBuilder) Build(path string) error { - return ioutil.WriteFile(path, []byte(strings.Join(tb.lines, "\n")), 0600) + return os.WriteFile(path, []byte(strings.Join(tb.lines, "\n")), 0600) } // Preview provides a string representation of the torrc file without writing it to a file location.