forked from openprivacy/libricochet-go
Compare commits
10 Commits
Author | SHA1 | Date |
---|---|---|
Sarah Jamie Lewis | f82c2f9da4 | |
Dan Ballard | 7c828d3916 | |
Dan Ballard | 79a1ff9161 | |
Sarah Jamie Lewis | 5a1fc1b94d | |
Dan Ballard | 9ba39b93b7 | |
Sarah Jamie Lewis | 29540dcf71 | |
Dan Ballard | 0fdcfd1553 | |
Dan Ballard | ac4993adb7 | |
Dan Ballard | 881ca5c6c2 | |
Dan Ballard | 61f89d7b2c |
14
.drone.yml
14
.drone.yml
|
@ -5,27 +5,35 @@ workspace:
|
|||
pipeline:
|
||||
fetch:
|
||||
image: golang
|
||||
environment:
|
||||
- GO111MODULE=on
|
||||
commands:
|
||||
- wget https://git.openprivacy.ca/openprivacy/buildfiles/raw/master/tor/tor
|
||||
- wget https://git.openprivacy.ca/openprivacy/buildfiles/raw/master/tor/torrc
|
||||
- chmod a+x tor
|
||||
- go list ./... | xargs go get
|
||||
- go get -u github.com/golang/lint/golint
|
||||
- go get -u golang.org/x/lint/golint
|
||||
- go mod download
|
||||
quality:
|
||||
image: golang
|
||||
environment:
|
||||
- GO111MODULE=on
|
||||
commands:
|
||||
- go list ./... | xargs go vet
|
||||
- go list ./... | grep -v "/wire/" | xargs golint -set_exit_status
|
||||
units-tests:
|
||||
image: golang
|
||||
environment:
|
||||
- GO111MODULE=on
|
||||
commands:
|
||||
- sh testing/tests.sh
|
||||
integ-test:
|
||||
image: golang
|
||||
environment:
|
||||
- GO111MODULE=on
|
||||
commands:
|
||||
- ./tor -f ./torrc
|
||||
- sleep 15
|
||||
- go test -v git.openprivacy.ca/openprivacy/libricochet-go/testing
|
||||
- go test -race -v git.openprivacy.ca/openprivacy/libricochet-go/testing
|
||||
notify-email:
|
||||
image: drillster/drone-email
|
||||
host: build.openprivacy.ca
|
||||
|
|
|
@ -144,7 +144,9 @@ func (ra *RicochetApplication) Run(ls connectivity.ListenService) {
|
|||
if !ra.v3identity.Initialized() || ra.contactManager == nil {
|
||||
return
|
||||
}
|
||||
ra.lock.Lock()
|
||||
ra.ls = ls
|
||||
ra.lock.Unlock()
|
||||
var err error
|
||||
for err == nil {
|
||||
conn, err := ra.ls.Accept()
|
||||
|
|
|
@ -32,8 +32,9 @@ type Connection struct {
|
|||
|
||||
messageBuilder utils.MessageBuilder
|
||||
|
||||
closed bool
|
||||
closing bool
|
||||
closed bool
|
||||
closingLock sync.Mutex
|
||||
closing bool
|
||||
// This mutex is exclusively for preventing races during blocking
|
||||
// interactions with Process; specifically Do and Break. Don't use
|
||||
// it for anything else. See those functions for an explanation.
|
||||
|
@ -311,6 +312,8 @@ func (rc *Connection) Process(handler Handler) error {
|
|||
go func() {
|
||||
rc.processBlockMutex.Lock()
|
||||
defer rc.processBlockMutex.Unlock()
|
||||
rc.closingLock.Lock()
|
||||
defer rc.closingLock.Unlock()
|
||||
rc.closed = true
|
||||
close(closedChan)
|
||||
}()
|
||||
|
@ -468,5 +471,7 @@ func (rc *Connection) Close() {
|
|||
// Kill the Ricochet Connection.
|
||||
log.Debugf("Closing Ricochet Connection for %v", rc.RemoteHostname)
|
||||
rc.conn.Close()
|
||||
rc.closingLock.Lock()
|
||||
rc.closed = true
|
||||
rc.closingLock.Unlock()
|
||||
}
|
||||
|
|
|
@ -53,6 +53,9 @@ func TestProcessAuthAs3DHServer(t *testing.T) {
|
|||
t.Errorf("Error while testing ProcessAuthAsServer: %v", err)
|
||||
}
|
||||
|
||||
// Wait for server to finish
|
||||
time.Sleep(time.Second * 2)
|
||||
|
||||
// Test Close
|
||||
rc.Close()
|
||||
}
|
||||
|
|
|
@ -28,6 +28,9 @@ type ACN interface {
|
|||
// Sets the calback function to be called when ACN status changes
|
||||
SetStatusCallback(callback func(int, string))
|
||||
|
||||
// Restarts the underlying connection
|
||||
Restart()
|
||||
|
||||
// Open takes a hostname and returns a net.conn to the derived endpoint
|
||||
// Open allows a client to resolve various hostnames to connections
|
||||
// The supported types are onions address are:
|
||||
|
|
|
@ -63,6 +63,10 @@ func (lp *localProvider) Open(hostname string) (net.Conn, string, error) {
|
|||
|
||||
}
|
||||
|
||||
func (lp *localProvider) Restart() {
|
||||
//noop
|
||||
}
|
||||
|
||||
func (lp *localProvider) Close() {
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
// +build !windows
|
||||
|
||||
package connectivity
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
var sysProcAttr = &syscall.SysProcAttr{}
|
|
@ -0,0 +1,9 @@
|
|||
// +build windows
|
||||
|
||||
package connectivity
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
var sysProcAttr = &syscall.SysProcAttr{HideWindow: true}
|
|
@ -1,10 +1,12 @@
|
|||
package connectivity
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"git.openprivacy.ca/openprivacy/libricochet-go/log"
|
||||
"git.openprivacy.ca/openprivacy/libricochet-go/utils"
|
||||
"github.com/cretz/bine/control"
|
||||
"github.com/cretz/bine/process"
|
||||
"github.com/cretz/bine/tor"
|
||||
bineed255192 "github.com/cretz/bine/torutil/ed25519"
|
||||
"golang.org/x/crypto/ed25519"
|
||||
|
@ -155,6 +157,13 @@ func (tp *torProvider) Listen(identity PrivateKey, port int) (ListenService, err
|
|||
return ols, nil
|
||||
}
|
||||
|
||||
func (tp *torProvider) Restart() {
|
||||
if tp.statusCallback != nil {
|
||||
tp.statusCallback(0, "rebooting")
|
||||
}
|
||||
tp.restart()
|
||||
}
|
||||
|
||||
func (tp *torProvider) Open(hostname string) (net.Conn, string, error) {
|
||||
tp.lock.Lock()
|
||||
|
||||
|
@ -206,6 +215,17 @@ func StartTor(appDirectory string, bundledTorPath string) (ACN, error) {
|
|||
return tp, err
|
||||
}
|
||||
|
||||
// newHideCmd creates a Creator function for bine which generates a cmd that one windows will hide the dosbox
|
||||
func newHideCmd(exePath string) process.Creator {
|
||||
return process.CmdCreatorFunc(func(ctx context.Context, args ...string) (*exec.Cmd, error) {
|
||||
cmd := exec.CommandContext(ctx, exePath, args...)
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
cmd.SysProcAttr = sysProcAttr
|
||||
return cmd, nil
|
||||
})
|
||||
}
|
||||
|
||||
func startTor(appDirectory string, bundledTorPath string) (*torProvider, error) {
|
||||
dataDir := path.Join(appDirectory, "tor")
|
||||
os.MkdirAll(dataDir, 0700)
|
||||
|
@ -232,7 +252,7 @@ func startTor(appDirectory string, bundledTorPath string) (*torProvider, error)
|
|||
|
||||
// if not, try running system tor
|
||||
if checkCmdlineTorVersion("tor") {
|
||||
t, err := tor.Start(nil, &tor.StartConf{EnableNetwork: true, DataDir: dataDir, DebugWriter: nil})
|
||||
t, err := tor.Start(nil, &tor.StartConf{EnableNetwork: true, DataDir: dataDir, DebugWriter: nil, ProcessCreator: newHideCmd("tor")})
|
||||
if err == nil {
|
||||
tp.t = t
|
||||
return tp, nil
|
||||
|
@ -243,7 +263,7 @@ func startTor(appDirectory string, bundledTorPath string) (*torProvider, error)
|
|||
// try running bundledTor
|
||||
if bundledTorPath != "" && checkCmdlineTorVersion(bundledTorPath) {
|
||||
log.Debugln("using bundled tor '" + bundledTorPath + "'")
|
||||
t, err := tor.Start(nil, &tor.StartConf{EnableNetwork: true, DataDir: dataDir, ExePath: bundledTorPath, DebugWriter: nil})
|
||||
t, err := tor.Start(nil, &tor.StartConf{EnableNetwork: true, DataDir: dataDir, ExePath: bundledTorPath, DebugWriter: nil, ProcessCreator: newHideCmd(bundledTorPath)})
|
||||
if err != nil {
|
||||
log.Debugf("Error running bundled tor: %v\n", err)
|
||||
}
|
||||
|
@ -334,6 +354,7 @@ func createFromExisting(controlport *control.Conn, datadir string) *tor.Tor {
|
|||
|
||||
func checkCmdlineTorVersion(torCmd string) bool {
|
||||
cmd := exec.Command(torCmd, "--version")
|
||||
cmd.SysProcAttr = sysProcAttr
|
||||
out, err := cmd.CombinedOutput()
|
||||
re := regexp.MustCompile("[0-1]\\.[0-9]\\.[0-9]\\.[0-9]")
|
||||
sysTorVersion := re.Find(out)
|
||||
|
|
|
@ -15,10 +15,11 @@ func getStatusCallback(progChan chan int) func(int, string) {
|
|||
func TestTorProvider(t *testing.T) {
|
||||
progChan := make(chan int)
|
||||
acn, err := StartTor(".", "")
|
||||
acn.SetStatusCallback(getStatusCallback(progChan))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
acn.SetStatusCallback(getStatusCallback(progChan))
|
||||
|
||||
progress := 0
|
||||
for progress < 100 {
|
||||
|
|
4
go.mod
4
go.mod
|
@ -2,10 +2,12 @@ module git.openprivacy.ca/openprivacy/libricochet-go
|
|||
|
||||
require (
|
||||
github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412
|
||||
github.com/cretz/bine v0.1.0
|
||||
github.com/cretz/bine v0.1.1-0.20200124154328-f9f678b84cca
|
||||
github.com/golang/protobuf v1.2.0
|
||||
github.com/stretchr/testify v1.3.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20190128193316-c7b33c32a30b
|
||||
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3 // indirect
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 // indirect
|
||||
)
|
||||
|
||||
go 1.13
|
||||
|
|
2
go.sum
2
go.sum
|
@ -2,6 +2,8 @@ github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412 h1:w1UutsfOrms1J05zt7I
|
|||
github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412/go.mod h1:WPjqKcmVOxf0XSf3YxCJs6N6AOSrOx3obionmG7T0y0=
|
||||
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/cretz/bine v0.1.1-0.20200124154328-f9f678b84cca h1:Q2r7AxHdJwWfLtBZwvW621M3sPqxPc6ITv2j1FGsYpw=
|
||||
github.com/cretz/bine v0.1.1-0.20200124154328-f9f678b84cca/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/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
||||
|
|
|
@ -4,13 +4,14 @@
|
|||
|
||||
set -e
|
||||
pwd
|
||||
go test ${1} -coverprofile=utils.cover.out -v ./utils
|
||||
go test ${1} -coverprofile=channels.cover.out -v ./channels
|
||||
go test ${1} -coverprofile=channels.v3.inbound.cover.out -v ./channels/v3/inbound
|
||||
go test ${1} -coverprofile=connection.cover.out -v ./connection
|
||||
go test ${1} -coverprofile=policies.cover.out -v ./policies
|
||||
go test ${1} -coverprofile=identity.cover.out -v ./identity
|
||||
go test ${1} -coverprofile=root.cover.out -v ./
|
||||
GORACE="haltonerror=1"
|
||||
go test -race ${1} -coverprofile=utils.cover.out -v ./utils
|
||||
go test -race ${1} -coverprofile=channels.cover.out -v ./channels
|
||||
go test -race ${1} -coverprofile=channels.v3.inbound.cover.out -v ./channels/v3/inbound
|
||||
go test -race ${1} -coverprofile=connection.cover.out -v ./connection
|
||||
go test -race ${1} -coverprofile=policies.cover.out -v ./policies
|
||||
go test -race ${1} -coverprofile=identity.cover.out -v ./identity
|
||||
go test -race ${1} -coverprofile=root.cover.out -v ./
|
||||
echo "mode: set" > coverage.out && cat *.cover.out | grep -v mode: | sort -r | \
|
||||
awk '{if($1 != last) {print $0;last=$1}}' >> coverage.out
|
||||
rm -rf *.cover.out
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"git.openprivacy.ca/openprivacy/libricochet-go/log"
|
||||
"golang.org/x/crypto/nacl/secretbox"
|
||||
"io"
|
||||
"sync"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -43,10 +44,13 @@ type RicochetNetwork struct {
|
|||
// Derived ephemeral session key for connection
|
||||
key [32]byte
|
||||
encrypt bool
|
||||
lock sync.Mutex
|
||||
}
|
||||
|
||||
// SetEncryptionKey sets the ephemeral encryption key for this session.
|
||||
func (rn *RicochetNetwork) SetEncryptionKey(key [32]byte) {
|
||||
rn.lock.Lock()
|
||||
defer rn.lock.Unlock()
|
||||
log.Debugf("turning on ephemeral session encryption for connection")
|
||||
copy(rn.key[:], key[:])
|
||||
|
||||
|
@ -67,6 +71,7 @@ func (rn *RicochetNetwork) SendRicochetPacket(dst io.Writer, channel int32, data
|
|||
binary.BigEndian.PutUint16(packet[2:4], uint16(channel))
|
||||
copy(packet[4:], data[:])
|
||||
|
||||
rn.lock.Lock()
|
||||
if rn.encrypt {
|
||||
var nonce [24]byte
|
||||
if _, err := io.ReadFull(rand.Reader, nonce[:]); err != nil {
|
||||
|
@ -77,6 +82,7 @@ func (rn *RicochetNetwork) SendRicochetPacket(dst io.Writer, channel int32, data
|
|||
binary.BigEndian.PutUint16(packet[0:2], uint16(len(encrypted)+2))
|
||||
packet = append(packet[0:2], encrypted...)
|
||||
}
|
||||
rn.lock.Unlock()
|
||||
|
||||
for pos := 0; pos < len(packet); {
|
||||
n, err := dst.Write(packet[pos:])
|
||||
|
@ -112,6 +118,7 @@ func (rn *RicochetNetwork) RecvRicochetPacket(reader io.Reader) (RicochetData, e
|
|||
return packet, err
|
||||
}
|
||||
|
||||
rn.lock.Lock()
|
||||
if rn.encrypt {
|
||||
var decryptNonce [24]byte
|
||||
if len(packetBytes) > 24 {
|
||||
|
@ -127,6 +134,7 @@ func (rn *RicochetNetwork) RecvRicochetPacket(reader io.Reader) (RicochetData, e
|
|||
return packet, errors.New("ciphertext length was too short")
|
||||
}
|
||||
}
|
||||
rn.lock.Unlock()
|
||||
|
||||
packet.Channel = int32(binary.BigEndian.Uint16(packetBytes[0:2]))
|
||||
packet.Data = make([]byte, len(packetBytes)-2)
|
||||
|
|
Loading…
Reference in New Issue