Compare commits
6 Commits
Author | SHA1 | Date |
---|---|---|
Sarah Jamie Lewis | e2dda25e37 | |
Sarah Jamie Lewis | a68c0fd160 | |
Dan Ballard | 5996d426c1 | |
Sarah Jamie Lewis | e353e4c70d | |
Sarah Jamie Lewis | 5b9bdf108a | |
Sarah Jamie Lewis | 4bf58a3c21 |
|
@ -30,7 +30,7 @@ import (
|
|||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/cretz/bine/tor"
|
||||
"git.openprivacy.ca/openprivacy/bine/tor"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
@ -67,9 +67,9 @@ func main() {
|
|||
```
|
||||
|
||||
If in `main.go` it can simply be run with `go run main.go`. Of course this uses a separate `tor` process. To embed Tor
|
||||
statically in the binary, follow the [embedded package docs](https://godoc.org/github.com/cretz/bine/process/embedded)
|
||||
statically in the binary, follow the [embedded package docs](https://godoc.org/git.openprivacy.ca/openprivacy/bine/process/embedded)
|
||||
which will require [building Tor statically](https://github.com/cretz/tor-static). Then with
|
||||
`github.com/cretz/bine/process/embedded` imported, change the start line above to:
|
||||
`git.openprivacy.ca/openprivacy/bine/process/embedded` imported, change the start line above to:
|
||||
|
||||
```go
|
||||
t, err := tor.Start(nil, &tor.StartConf{ProcessCreator: embedded.NewCreator()})
|
||||
|
|
|
@ -3,7 +3,7 @@ package control
|
|||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/cretz/bine/torutil"
|
||||
"git.openprivacy.ca/openprivacy/bine/torutil"
|
||||
)
|
||||
|
||||
// SetConf invokes SETCONF.
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/cretz/bine/torutil"
|
||||
"git.openprivacy.ca/openprivacy/bine/torutil"
|
||||
)
|
||||
|
||||
// EventCode represents an asynchronous event code (ref control spec 4.1).
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
package control
|
||||
|
||||
import (
|
||||
"git.openprivacy.ca/openprivacy/bine/torutil"
|
||||
"strings"
|
||||
|
||||
"github.com/cretz/bine/torutil"
|
||||
)
|
||||
|
||||
// Signal invokes SIGNAL.
|
||||
|
|
|
@ -8,8 +8,8 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/cretz/bine/torutil"
|
||||
"github.com/cretz/bine/torutil/ed25519"
|
||||
"git.openprivacy.ca/openprivacy/bine/torutil"
|
||||
"git.openprivacy.ca/openprivacy/bine/torutil/ed25519"
|
||||
)
|
||||
|
||||
// KeyType is a key type for Key in AddOnion.
|
||||
|
|
|
@ -3,7 +3,7 @@ package control
|
|||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/cretz/bine/torutil"
|
||||
"git.openprivacy.ca/openprivacy/bine/torutil"
|
||||
)
|
||||
|
||||
// ProtocolInfo is the protocol info result of Conn.ProtocolInfo.
|
||||
|
|
|
@ -10,8 +10,8 @@ import (
|
|||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/cretz/bine/process/embedded"
|
||||
"github.com/cretz/bine/tor"
|
||||
"git.openprivacy.ca/openprivacy/bine/process/embedded"
|
||||
"git.openprivacy.ca/openprivacy/bine/tor"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/cretz/bine/process/embedded"
|
||||
"git.openprivacy.ca/openprivacy/bine/process/embedded"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
|
|
@ -14,8 +14,8 @@ import (
|
|||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/cretz/bine/tor"
|
||||
"github.com/cretz/bine/torutil"
|
||||
"git.openprivacy.ca/openprivacy/bine/tor"
|
||||
"git.openprivacy.ca/openprivacy/bine/torutil"
|
||||
)
|
||||
|
||||
var verbose bool
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/cretz/bine/tor"
|
||||
"git.openprivacy.ca/openprivacy/bine/tor"
|
||||
"golang.org/x/net/html"
|
||||
)
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/cretz/bine/tor"
|
||||
"git.openprivacy.ca/openprivacy/bine/tor"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
|
2
go.mod
2
go.mod
|
@ -3,7 +3,7 @@ module git.openprivacy.ca/openprivacy/bine
|
|||
go 1.14
|
||||
|
||||
require (
|
||||
github.com/cretz/bine v0.1.0
|
||||
git.openprivacy.ca/openprivacy/log v1.0.3
|
||||
github.com/stretchr/testify v1.6.1
|
||||
golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee
|
||||
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb
|
||||
|
|
2
go.sum
2
go.sum
|
@ -1,5 +1,3 @@
|
|||
github.com/cretz/bine v0.1.0 h1:1/fvhLE+fk0bPzjdO5Ci+0ComYxEMuB1JhM4X5skT3g=
|
||||
github.com/cretz/bine v0.1.0/go.mod h1:6PF6fWAvYtwjRGkAuDEJeWNOv3a2hUouSP/yRYXmvHw=
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
|
|
|
@ -21,9 +21,9 @@
|
|||
package embedded
|
||||
|
||||
import (
|
||||
"github.com/cretz/bine/process"
|
||||
"git.openprivacy.ca/openprivacy/bine/process"
|
||||
|
||||
tor035 "github.com/cretz/bine/process/embedded/tor-0.3.5"
|
||||
tor035 "git.openprivacy.ca/openprivacy/bine/process/embedded/tor-0.3.5"
|
||||
)
|
||||
|
||||
// NewCreator creates a process.Creator for statically-linked Tor embedded in
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"log"
|
||||
"os"
|
||||
|
||||
tor033 "github.com/cretz/bine/process/embedded/tor-0.3.3"
|
||||
tor033 "git.openprivacy.ca/openprivacy/bine/process/embedded/tor-0.3.3"
|
||||
)
|
||||
|
||||
// Simply calls Tor will the same parameters
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/cretz/bine/process"
|
||||
"git.openprivacy.ca/openprivacy/bine/process"
|
||||
)
|
||||
|
||||
/*
|
||||
|
|
|
@ -7,8 +7,8 @@ import (
|
|||
"net/textproto"
|
||||
"os"
|
||||
|
||||
"github.com/cretz/bine/control"
|
||||
tor035 "github.com/cretz/bine/process/embedded/tor-0.3.5"
|
||||
"git.openprivacy.ca/openprivacy/bine/control"
|
||||
tor035 "git.openprivacy.ca/openprivacy/bine/process/embedded/tor-0.3.5"
|
||||
)
|
||||
|
||||
// Simply calls Tor will the same parameters, unless "embedconn" is the arg
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"net"
|
||||
"os"
|
||||
|
||||
"github.com/cretz/bine/process"
|
||||
"git.openprivacy.ca/openprivacy/bine/process"
|
||||
)
|
||||
|
||||
/*
|
||||
|
|
|
@ -16,7 +16,7 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/cretz/bine/torutil"
|
||||
"git.openprivacy.ca/openprivacy/bine/torutil"
|
||||
)
|
||||
|
||||
// Process is the interface implemented by Tor processes.
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cretz/bine/tor"
|
||||
"git.openprivacy.ca/openprivacy/bine/tor"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ package tests
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/cretz/bine/tor"
|
||||
"git.openprivacy.ca/openprivacy/bine/tor"
|
||||
)
|
||||
|
||||
func TestAuthenticateNull(t *testing.T) {
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
"github.com/cretz/bine/control"
|
||||
"git.openprivacy.ca/openprivacy/bine/control"
|
||||
)
|
||||
|
||||
func TestGetSetAndResetConf(t *testing.T) {
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cretz/bine/control"
|
||||
"git.openprivacy.ca/openprivacy/bine/control"
|
||||
)
|
||||
|
||||
func TestHSFetch(t *testing.T) {
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cretz/bine/tor"
|
||||
"git.openprivacy.ca/openprivacy/bine/tor"
|
||||
"golang.org/x/net/context/ctxhttp"
|
||||
)
|
||||
|
||||
|
|
|
@ -3,8 +3,8 @@ package tests
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/cretz/bine/tor"
|
||||
"github.com/cretz/bine/torutil/geoipembed"
|
||||
"git.openprivacy.ca/openprivacy/bine/tor"
|
||||
"git.openprivacy.ca/openprivacy/bine/torutil/geoipembed"
|
||||
)
|
||||
|
||||
func TestEmbeddedGeoIPFile(t *testing.T) {
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cretz/bine/tor"
|
||||
"git.openprivacy.ca/openprivacy/bine/tor"
|
||||
"golang.org/x/net/proxy"
|
||||
)
|
||||
|
||||
|
|
|
@ -6,8 +6,8 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cretz/bine/tor"
|
||||
"github.com/cretz/bine/torutil"
|
||||
"git.openprivacy.ca/openprivacy/bine/tor"
|
||||
"git.openprivacy.ca/openprivacy/bine/torutil"
|
||||
)
|
||||
|
||||
func TestListenSimpleHTTPV2(t *testing.T) {
|
||||
|
|
|
@ -3,6 +3,7 @@ package tor
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"git.openprivacy.ca/openprivacy/bine/control"
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
|
@ -14,6 +15,11 @@ type Dialer struct {
|
|||
proxy.Dialer
|
||||
}
|
||||
|
||||
// Authenticator provides a facade over various Tor control port authentication methods.
|
||||
type Authenticator interface {
|
||||
Authenticate(controlport *control.Conn) error
|
||||
}
|
||||
|
||||
// DialConf is the configuration used for Dialer.
|
||||
type DialConf struct {
|
||||
// ProxyAddress is the address for the SOCKS5 proxy. If empty, it is looked
|
||||
|
@ -39,6 +45,8 @@ type DialConf struct {
|
|||
|
||||
// Forward is the dialer to forward to. If nil, just uses normal net dialer.
|
||||
Forward proxy.Dialer
|
||||
|
||||
Authenticator Authenticator
|
||||
}
|
||||
|
||||
// Dialer creates a new Dialer for the given configuration. Context can be nil.
|
||||
|
@ -50,6 +58,9 @@ func (t *Tor) Dialer(ctx context.Context, conf *DialConf) (*Dialer, error) {
|
|||
if conf == nil {
|
||||
conf = &DialConf{}
|
||||
}
|
||||
|
||||
conf.Authenticator.Authenticate(t.Control)
|
||||
|
||||
// Enable the network if requested
|
||||
if !conf.SkipEnableNetwork {
|
||||
if err := t.EnableNetwork(ctx, true); err != nil {
|
||||
|
@ -67,12 +78,23 @@ func (t *Tor) Dialer(ctx context.Context, conf *DialConf) (*Dialer, error) {
|
|||
if len(info) != 1 || info[0].Key != "net/listeners/socks" {
|
||||
return nil, fmt.Errorf("Unable to get socks proxy address")
|
||||
}
|
||||
proxyAddress = info[0].Val
|
||||
if strings.HasPrefix(proxyAddress, "unix:") {
|
||||
proxyAddress = proxyAddress[5:]
|
||||
proxyNetwork = "unix"
|
||||
} else {
|
||||
|
||||
if strings.HasPrefix(info[0].Val, "\"") {
|
||||
options := strings.Split(info[0].Val, " ")
|
||||
// we get this kind of response from Tails / OnionGrater, multiple potential listeners
|
||||
// formatted. Simply choose the first one.
|
||||
// NOTE: This logic is probably not the best...
|
||||
proxyAddress = options[0][1 : len(options[0])-1]
|
||||
proxyNetwork = "tcp"
|
||||
} else {
|
||||
|
||||
proxyAddress = info[0].Val
|
||||
if strings.HasPrefix(proxyAddress, "unix:") {
|
||||
proxyAddress = proxyAddress[5:]
|
||||
proxyNetwork = "unix"
|
||||
} else {
|
||||
proxyNetwork = "tcp"
|
||||
}
|
||||
}
|
||||
} else if proxyNetwork == "" {
|
||||
proxyNetwork = "tcp"
|
||||
|
|
|
@ -21,7 +21,7 @@ type OnionService struct {
|
|||
// Key is the private key for this service. It is either the set key, the
|
||||
// generated key, or nil if asked to discard the key. If present, it is
|
||||
// *crypto/rsa.PrivateKey (1024 bit) when Version3 is false or
|
||||
// github.com/cretz/bine/torutil/ed25519.KeyPair when Version3 is true.
|
||||
// git.openprivacy.ca/openprivacy/bine/torutil/ed25519.KeyPair when Version3 is true.
|
||||
Key crypto.PrivateKey
|
||||
|
||||
// Version3 says whether or not this service is a V3 service.
|
||||
|
@ -66,9 +66,9 @@ type ListenConf struct {
|
|||
// Key is the private key to use. If not present, a key is generated based
|
||||
// on whether Version3 is true or false. If present, it must be a
|
||||
// *crypto/rsa.PrivateKey (1024 bit), a
|
||||
// github.com/cretz/bine/torutil/ed25519.KeyPair, a
|
||||
// git.openprivacy.ca/openprivacy/bine/torutil/ed25519.KeyPair, a
|
||||
// golang.org/x/crypto/ed25519.PrivateKey, or a
|
||||
// github.com/cretz/bine/control.Key.
|
||||
// git.openprivacy.ca/openprivacy/bine/control.Key.
|
||||
Key crypto.PrivateKey
|
||||
|
||||
// Version3 determines whether, when Key is nil, a version 2 or version 3
|
||||
|
|
19
tor/tor.go
19
tor/tor.go
|
@ -173,11 +173,25 @@ func Start(ctx context.Context, conf *StartConf) (*Tor, error) {
|
|||
if err == nil {
|
||||
err = tor.startProcess(ctx, conf)
|
||||
}
|
||||
time.Sleep(time.Second)
|
||||
|
||||
|
||||
// Connect the controller
|
||||
if err == nil {
|
||||
err = tor.connectController(ctx, conf)
|
||||
for attempts := 0; attempts < 10; attempts++ {
|
||||
err = tor.connectController(ctx, conf)
|
||||
if err == nil {
|
||||
break
|
||||
} else {
|
||||
// backoff and retry
|
||||
// max is 1 + 2 + 3 + 4 + 5...+10 = ~55 seconds
|
||||
// After which point there is probably something else very wrong
|
||||
// TODO: It might be worth breaking out the error here so that we can distinguish a
|
||||
// slow socket (on e.g. Android) with a failed setup.
|
||||
time.Sleep(time.Duration(int(time.Second) * attempts))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Attempt eager auth w/ no password
|
||||
if err == nil && !conf.DisableEagerAuth {
|
||||
err = tor.Control.Authenticate("")
|
||||
|
@ -364,6 +378,7 @@ func (t *Tor) EnableNetwork(ctx context.Context, wait bool) error {
|
|||
if ctx == nil {
|
||||
ctx = context.Background()
|
||||
}
|
||||
|
||||
// Only enable if DisableNetwork is 1
|
||||
if vals, err := t.Control.GetConf("DisableNetwork"); err != nil {
|
||||
return err
|
||||
|
|
|
@ -12,7 +12,7 @@ import (
|
|||
"errors"
|
||||
"io"
|
||||
|
||||
"github.com/cretz/bine/torutil/ed25519/internal/edwards25519"
|
||||
"git.openprivacy.ca/openprivacy/bine/torutil/ed25519/internal/edwards25519"
|
||||
"golang.org/x/crypto/ed25519"
|
||||
)
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/cretz/bine/torutil/ed25519/internal/edwards25519"
|
||||
"git.openprivacy.ca/openprivacy/bine/torutil/ed25519/internal/edwards25519"
|
||||
)
|
||||
|
||||
// Taken from https://github.com/golang/crypto/blob/1a580b3eff7814fc9b40602fd35256c63b50f491/ed25519/ed25519_test.go
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/cretz/bine/torutil/ed25519"
|
||||
"git.openprivacy.ca/openprivacy/bine/torutil/ed25519"
|
||||
"golang.org/x/crypto/sha3"
|
||||
)
|
||||
|
||||
|
@ -17,7 +17,7 @@ var serviceIDEncoding = base32.StdEncoding.WithPadding(base32.NoPadding)
|
|||
|
||||
// OnionServiceIDFromPrivateKey generates the onion service ID from the given
|
||||
// private key. This panics if the private key is not a 1024-bit
|
||||
// crypto/*rsa.PrivateKey or github.com/cretz/bine/torutil/ed25519.KeyPair.
|
||||
// crypto/*rsa.PrivateKey or git.openprivacy.ca/openprivacy/bine/torutil/ed25519.KeyPair.
|
||||
func OnionServiceIDFromPrivateKey(key crypto.PrivateKey) string {
|
||||
switch k := key.(type) {
|
||||
case *rsa.PrivateKey:
|
||||
|
@ -30,7 +30,7 @@ func OnionServiceIDFromPrivateKey(key crypto.PrivateKey) string {
|
|||
|
||||
// OnionServiceIDFromPublicKey generates the onion service ID from the given
|
||||
// public key. This panics if the public key is not a 1024-bit
|
||||
// crypto/*rsa.PublicKey or github.com/cretz/bine/torutil/ed25519.PublicKey.
|
||||
// crypto/*rsa.PublicKey or git.openprivacy.ca/openprivacy/bine/torutil/ed25519.PublicKey.
|
||||
func OnionServiceIDFromPublicKey(key crypto.PublicKey) string {
|
||||
switch k := key.(type) {
|
||||
case *rsa.PublicKey:
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"math/big"
|
||||
"testing"
|
||||
|
||||
"github.com/cretz/bine/torutil/ed25519"
|
||||
"git.openprivacy.ca/openprivacy/bine/torutil/ed25519"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
|
|
|
@ -70,7 +70,11 @@ func UnescapeSimpleQuotedString(str string) (string, error) {
|
|||
if len(str) < 2 || str[0] != '"' || str[len(str)-1] != '"' {
|
||||
return "", fmt.Errorf("Missing quotes")
|
||||
}
|
||||
return UnescapeSimpleQuotedStringContents(str[1 : len(str)-1])
|
||||
if str, err := UnescapeSimpleQuotedStringContents(str[1 : len(str)-1]); err == nil {
|
||||
return str, nil
|
||||
}
|
||||
// Assume this wasn't quoted
|
||||
return str, nil
|
||||
}
|
||||
|
||||
// UnescapeSimpleQuotedStringContents unescapes backslashes, double quotes,
|
||||
|
|
Loading…
Reference in New Issue