Skip to content

Commit

Permalink
Breaking change - fix: address failing tests and remove Version3 opt-…
Browse files Browse the repository at this point in the history
…in since it's required now (#61)
  • Loading branch information
cmars authored Feb 11, 2022
1 parent 9267b2d commit 874b17b
Show file tree
Hide file tree
Showing 7 changed files with 28 additions and 171 deletions.
20 changes: 4 additions & 16 deletions control/cmd_onion.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,8 @@ type AddOnionRequest struct {
// Ports are ADD_ONION Port values. Key is virtual port, Val is target
// port (or can be empty to use virtual port).
Ports []*KeyVal
// ClientAuths are ADD_ONION ClientAuth values. If value is empty string,
// Tor will generate the password.
ClientAuths map[string]string
// ClientAuths are ADD_ONION V3Key values.
ClientAuths []string
}

// AddOnionResponse is the response for AddOnion.
Expand All @@ -138,8 +137,6 @@ type AddOnionResponse struct {
ServiceID string
// Key is the ADD_ONION response PrivateKey value.
Key Key
// ClientAuths are the ADD_ONION response ClientAuth values.
ClientAuths map[string]string
// RawResponse is the raw ADD_ONION response.
RawResponse *Response
}
Expand All @@ -163,11 +160,8 @@ func (c *Conn) AddOnion(req *AddOnionRequest) (*AddOnionResponse, error) {
cmd += "," + port.Val
}
}
for name, blob := range req.ClientAuths {
cmd += " ClientAuth=" + name
if blob != "" {
cmd += ":" + blob
}
for _, blob := range req.ClientAuths {
cmd += " ClientAuthV3=" + blob
}
// Invoke and read response
resp, err := c.SendRequest(cmd)
Expand All @@ -184,12 +178,6 @@ func (c *Conn) AddOnion(req *AddOnionRequest) (*AddOnionResponse, error) {
if ret.Key, err = KeyFromString(val); err != nil {
return nil, err
}
case "ClientAuth":
name, pass, _ := torutil.PartitionString(val, ':')
if ret.ClientAuths == nil {
ret.ClientAuths = map[string]string{}
}
ret.ClientAuths[name] = pass
}
}
return ret, nil
Expand Down
8 changes: 4 additions & 4 deletions tests/control_cmd_hiddenservice_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ package tests

import (
"context"
"strings"
"testing"
"time"

"github.com/cretz/bine/control"
)

const hsFetchOnion = "2gzyxa5ihm7nsggfxnu52rck2vv4rvmdlkiu3zzui5du4xyclen53wid"

func TestHSFetch(t *testing.T) {
ctx := GlobalEnabledNetworkContext(t)
// Add listener
Expand All @@ -18,7 +19,7 @@ func TestHSFetch(t *testing.T) {
ctx.Require.NoError(err)
defer ctx.Control.RemoveEventListener(eventCh, control.EventCodeHSDescContent)
// Lookup HS
err = ctx.Control.GetHiddenServiceDescriptorAsync("facebookcorewwwi", "")
err = ctx.Control.GetHiddenServiceDescriptorAsync(hsFetchOnion, "")
ctx.Require.NoError(err)
// Grab events
eventCtx, eventCancel := context.WithTimeout(ctx, 45*time.Second)
Expand All @@ -32,7 +33,6 @@ func TestHSFetch(t *testing.T) {
ctx.Require.NoError(err)
case event := <-eventCh:
hsEvent := event.(*control.HSDescContentEvent)
ctx.Require.Equal("facebookcorewwwi", hsEvent.Address)
ctx.Require.True(strings.HasPrefix(hsEvent.Descriptor, "rendezvous-service-descriptor "+hsEvent.DescID))
ctx.Require.Equal(hsFetchOnion, hsEvent.Address)
}
}
2 changes: 1 addition & 1 deletion tests/control_cmd_protocolinfo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ func TestProtocolInfo(t *testing.T) {
info, err := ctx.Control.ProtocolInfo()
ctx.Require.NoError(err)
ctx.Require.Contains(info.AuthMethods, "SAFECOOKIE")
ctx.Require.True(strings.HasPrefix(info.TorVersion, "0.3"))
ctx.Require.True(strings.HasPrefix(info.TorVersion, "0.4"))
}
1 change: 0 additions & 1 deletion tests/tor_forward_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ func TestForwardSimpleHTTP(t *testing.T) {

// Forward as an onion service on test ports
conf := &tor.ForwardConf{
Version3: true,
PortForwards: map[string][]int{
server.Listener.Addr().String(): remotePorts,
},
Expand Down
18 changes: 1 addition & 17 deletions tests/tor_listen_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,10 @@ import (
"github.com/cretz/bine/torutil"
)

func TestListenSimpleHTTPV2(t *testing.T) {
ctx := GlobalEnabledNetworkContext(t)
// Create an onion service to listen on random port but show as 80
conf := &tor.ListenConf{RemotePorts: []int{80}}
client, server, onion := startHTTPServer(ctx, conf, "/test", func(w http.ResponseWriter, r *http.Request) {
_, err := w.Write([]byte("Test Content"))
ctx.Require.NoError(err)
})
// Check the service ID
ctx.Require.Equal(torutil.OnionServiceIDFromPrivateKey(onion.Key), onion.ID)
defer server.Shutdown(ctx)
// Call /test
byts := httpGet(ctx, client, "http://"+onion.ID+".onion/test")
ctx.Require.Equal("Test Content", string(byts))
}

func TestListenSimpleHTTPV3(t *testing.T) {
ctx := GlobalEnabledNetworkContext(t)
// Create an onion service to listen on random port but show as 80
conf := &tor.ListenConf{RemotePorts: []int{80}, Version3: true}
conf := &tor.ListenConf{RemotePorts: []int{80}}
// _, conf.Key, _ = ed25519.GenerateKey(nil)
client, server, onion := startHTTPServer(ctx, conf, "/test", func(w http.ResponseWriter, r *http.Request) {
_, err := w.Write([]byte("Test Content"))
Expand Down
75 changes: 9 additions & 66 deletions tor/forward.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package tor
import (
"context"
"crypto"
"crypto/rsa"
"fmt"
"strconv"

Expand All @@ -18,19 +17,10 @@ type OnionForward struct {
ID string

// 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.
// generated key, or nil if asked to discard the key. If present, it is an
// instance of github.com/cretz/bine/torutil/ed25519.KeyPair.
Key crypto.PrivateKey

// Version3 says whether or not this service is a V3 service.
Version3 bool

// ClientAuths is the credential set for clients. The keys are username and
// the values are credentials. The credentials will always be present even
// if Tor had to generate them.
ClientAuths map[string]string

// PortForwards defines the ports that will be forwarded to the onion
// service.
PortForwards map[string][]int
Expand All @@ -45,26 +35,16 @@ type ForwardConf struct {
// service.
PortForwards map[string][]int

// 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
// Key is the private key to use. If not present, a key is generated. If
// present, it must be an instance of
// github.com/cretz/bine/torutil/ed25519.KeyPair, a
// golang.org/x/crypto/ed25519.PrivateKey, or a
// github.com/cretz/bine/control.Key.
Key crypto.PrivateKey

// Version3 determines whether, when Key is nil, a version 2 or version 3
// service/key will be generated. If true it is version 3 (an ed25519 key
// and v3 onion service) and if false it is version 2 (a RSA-1024 key and v2
// onion service). If Key is not nil, this value is ignored.
Version3 bool

// ClientAuths is the set of usernames and credentials for client
// authentication. The keys are usernames and the values are credentials. If
// a username is present but the credential is empty, a credential is
// generated by Tor for that user. If this is empty there is no
// authentication.
ClientAuths map[string]string
// ClientAuths is the credential set for clients. The values are
// base32-encoded ed25519 public keys.
ClientAuths []string

// MaxStreams is the maximum number of streams the service will accept. 0
// means unlimited.
Expand Down Expand Up @@ -116,7 +96,7 @@ func (t *Tor) Forward(ctx context.Context, conf *ForwardConf) (*OnionForward, er
req.Flags = append(req.Flags, "Detach")
}
if len(conf.ClientAuths) > 0 {
req.Flags = append(req.Flags, "BasicAuth")
req.Flags = append(req.Flags, "V3Auth")
}
if conf.NonAnonymous {
req.Flags = append(req.Flags, "NonAnonymous")
Expand All @@ -127,43 +107,18 @@ func (t *Tor) Forward(ctx context.Context, conf *ForwardConf) (*OnionForward, er
// Set the key
switch key := conf.Key.(type) {
case nil:
fwd.Version3 = conf.Version3
if conf.Version3 {
req.Key = control.GenKey(control.KeyAlgoED25519V3)
} else {
req.Key = control.GenKey(control.KeyAlgoRSA1024)
}
req.Key = control.GenKey(control.KeyAlgoED25519V3)
case control.GenKey:
fwd.Version3 = conf.Version3
req.Key = key
case *rsa.PrivateKey:
fwd.Key = key
fwd.Version3 = false
if key.N == nil || key.N.BitLen() != 1024 {
err = fmt.Errorf("RSA key must be 1024 bits")
} else {
req.Key = &control.RSAKey{PrivateKey: key}
}
case *control.RSAKey:
fwd.Key = key.PrivateKey
fwd.Version3 = false
if key.N == nil || key.N.BitLen() != 1024 {
err = fmt.Errorf("RSA key must be 1024 bits")
} else {
req.Key = key
}
case ed25519.KeyPair:
fwd.Key = key
fwd.Version3 = true
req.Key = &control.ED25519Key{key}
case othered25519.PrivateKey:
properKey := ed25519.FromCryptoPrivateKey(key)
fwd.Key = properKey
fwd.Version3 = true
req.Key = &control.ED25519Key{properKey}
case *control.ED25519Key:
fwd.Key = key.KeyPair
fwd.Version3 = true
req.Key = key
default:
err = fmt.Errorf("Unrecognized key type: %T", key)
Expand Down Expand Up @@ -195,23 +150,11 @@ func (t *Tor) Forward(ctx context.Context, conf *ForwardConf) (*OnionForward, er
switch key := resp.Key.(type) {
case nil:
// Do nothing
case *control.RSAKey:
fwd.Key = key.PrivateKey
case *control.ED25519Key:
fwd.Key = key.KeyPair
default:
err = fmt.Errorf("Unrecognized result key type: %T", key)
}
// Client auths are the conf and then overridden by results
if len(conf.ClientAuths) > 0 {
fwd.ClientAuths = make(map[string]string, len(conf.ClientAuths))
for k, v := range conf.ClientAuths {
fwd.ClientAuths[k] = v
}
for k, v := range resp.ClientAuths {
fwd.ClientAuths[k] = v
}
}
}

// Wait if necessary
Expand Down
Loading

0 comments on commit 874b17b

Please sign in to comment.