Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add client version to the client app and send it to the management service #222

Merged
merged 9 commits into from
Feb 8, 2022
9 changes: 6 additions & 3 deletions client/cmd/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,21 @@ import (
"bufio"
"context"
"fmt"
"os"
"time"

"github.com/cenkalti/backoff/v4"
"github.com/google/uuid"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/wiretrustee/wiretrustee/client/internal"
"github.com/wiretrustee/wiretrustee/client/system"
mgm "github.com/wiretrustee/wiretrustee/management/client"
mgmProto "github.com/wiretrustee/wiretrustee/management/proto"
"github.com/wiretrustee/wiretrustee/util"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"os"
"time"
)

var (
Expand Down Expand Up @@ -143,7 +145,8 @@ func registerPeer(serverPublicKey wgtypes.Key, client *mgm.GrpcClient, setupKey
}

log.Debugf("sending peer registration request to Management Service")
loginResp, err := client.Register(serverPublicKey, validSetupKey.String())
info := system.GetInfo()
loginResp, err := client.Register(serverPublicKey, validSetupKey.String(), info)
if err != nil {
log.Errorf("failed registering peer %v", err)
return nil, err
Expand Down
4 changes: 2 additions & 2 deletions client/cmd/up.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package cmd

import (
"context"
"time"

"github.com/cenkalti/backoff/v4"
"github.com/kardianos/service"
log "github.com/sirupsen/logrus"
Expand All @@ -13,7 +15,6 @@ import (
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"time"
)

var (
Expand Down Expand Up @@ -186,7 +187,6 @@ func runClient() error {
return err
}

// create start the Wiretrustee Engine that will connect to the Signal and Management streams and manage connections to remote peers.
engine := internal.NewEngine(signalClient, mgmClient, engineConfig, cancel, ctx)
err = engine.Start()
if err != nil {
Expand Down
9 changes: 5 additions & 4 deletions client/internal/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ package internal
import (
"context"
"fmt"
"math/rand"
"strings"
"sync"
"time"

"github.com/pion/ice/v2"
log "github.com/sirupsen/logrus"
"github.com/wiretrustee/wiretrustee/client/internal/peer"
Expand All @@ -14,10 +19,6 @@ import (
sProto "github.com/wiretrustee/wiretrustee/signal/proto"
"github.com/wiretrustee/wiretrustee/util"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
"math/rand"
"strings"
"sync"
"time"
)

// PeerConnectionTimeoutMax is a timeout of an initial connection attempt to a remote peer.
Expand Down
19 changes: 11 additions & 8 deletions client/internal/engine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,16 @@ package internal
import (
"context"
"fmt"
"net"
"os"
"path/filepath"
"runtime"
"sync"
"testing"
"time"

log "github.com/sirupsen/logrus"
"github.com/wiretrustee/wiretrustee/client/system"
mgmt "github.com/wiretrustee/wiretrustee/management/client"
mgmtProto "github.com/wiretrustee/wiretrustee/management/proto"
"github.com/wiretrustee/wiretrustee/management/server"
Expand All @@ -14,13 +23,6 @@ import (
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
"google.golang.org/grpc"
"google.golang.org/grpc/keepalive"
"net"
"os"
"path/filepath"
"runtime"
"sync"
"testing"
"time"
)

var (
Expand Down Expand Up @@ -382,7 +384,8 @@ func createEngine(ctx context.Context, cancel context.CancelFunc, setupKey strin
return nil, err
}

resp, err := mgmtClient.Register(*publicKey, setupKey)
info := system.GetInfo()
resp, err := mgmtClient.Register(*publicKey, setupKey, info)
if err != nil {
return nil, err
}
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ require (
require (
github.com/cakturk/go-netstat v0.0.0-20200220111822-e5b49efee7a5
github.com/magiconair/properties v1.8.5
github.com/pion/logging v0.2.2
github.com/pion/turn/v2 v2.0.5
github.com/rs/xid v1.3.0
github.com/stretchr/testify v1.7.0
)
Expand All @@ -46,12 +48,10 @@ require (
github.com/mdlayher/socket v0.0.0-20211102153432-57e3fa563ecb // indirect
github.com/nxadm/tail v1.4.8 // indirect
github.com/pion/dtls/v2 v2.0.12 // indirect
github.com/pion/logging v0.2.2 // indirect
github.com/pion/mdns v0.0.5 // indirect
github.com/pion/randutil v0.1.0 // indirect
github.com/pion/stun v0.3.5 // indirect
github.com/pion/transport v0.12.3 // indirect
github.com/pion/turn/v2 v2.0.5 // indirect
github.com/pion/udp v0.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df // indirect
Expand Down
6 changes: 4 additions & 2 deletions management/client/client.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
package client

import (
"io"

"github.com/wiretrustee/wiretrustee/client/system"
"github.com/wiretrustee/wiretrustee/management/proto"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
"io"
)

type Client interface {
io.Closer
Sync(msgHandler func(msg *proto.SyncResponse) error) error
GetServerPublicKey() (*wgtypes.Key, error)
Register(serverKey wgtypes.Key, setupKey string) (*proto.LoginResponse, error)
Register(serverKey wgtypes.Key, setupKey string, info *system.Info) (*proto.LoginResponse, error)
Login(serverKey wgtypes.Key) (*proto.LoginResponse, error)
}
139 changes: 132 additions & 7 deletions management/client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,31 @@ package client

import (
"context"
"net"
"path/filepath"
"sync"
"testing"
"time"

"github.com/wiretrustee/wiretrustee/client/system"

log "github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
"github.com/wiretrustee/wiretrustee/encryption"
"github.com/wiretrustee/wiretrustee/management/proto"
mgmtProto "github.com/wiretrustee/wiretrustee/management/proto"
mgmt "github.com/wiretrustee/wiretrustee/management/server"
"github.com/wiretrustee/wiretrustee/util"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"net"
"path/filepath"
"testing"
"time"
)

var tested *GrpcClient
var serverAddr string
var mgmtMockServer *mgmt.ManagementServiceServerMock
var serverKey wgtypes.Key

const ValidKey = "A2C8E62B-38F5-4553-B31E-DD66C696CEBB"

Expand Down Expand Up @@ -78,6 +87,39 @@ func startManagement(config *mgmt.Config, t *testing.T) (*grpc.Server, net.Liste
return s, lis
}

func startMockManagement(t *testing.T) (*grpc.Server, net.Listener) {
lis, err := net.Listen("tcp", ":0")
if err != nil {
t.Fatal(err)
}

s := grpc.NewServer()

serverKey, err = wgtypes.GenerateKey()
if err != nil {
t.Fatal(err)
}

mgmtMockServer = &mgmt.ManagementServiceServerMock{
GetServerKeyFunc: func(context.Context, *proto.Empty) (*proto.ServerKeyResponse, error) {
response := &proto.ServerKeyResponse{
Key: serverKey.PublicKey().String(),
}
return response, nil
},
}

mgmtProto.RegisterManagementServiceServer(s, mgmtMockServer)
go func() {
if err := s.Serve(lis); err != nil {
t.Error(err)
return
}
}()

return s, lis
}

func TestClient_GetServerPublicKey(t *testing.T) {

key, err := tested.GetServerPublicKey()
Expand Down Expand Up @@ -109,7 +151,8 @@ func TestClient_LoginRegistered(t *testing.T) {
if err != nil {
t.Error(err)
}
resp, err := tested.Register(*key, ValidKey)
info := system.GetInfo()
resp, err := tested.Register(*key, ValidKey, info)
if err != nil {
t.Error(err)
}
Expand All @@ -125,7 +168,8 @@ func TestClient_Sync(t *testing.T) {
t.Error(err)
}

_, err = tested.Register(*serverKey, ValidKey)
info := system.GetInfo()
_, err = tested.Register(*serverKey, ValidKey, info)
if err != nil {
t.Error(err)
}
Expand All @@ -139,7 +183,9 @@ func TestClient_Sync(t *testing.T) {
if err != nil {
t.Fatal(err)
}
_, err = remoteClient.Register(*serverKey, ValidKey)

info = system.GetInfo()
_, err = remoteClient.Register(*serverKey, ValidKey, info)
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -177,3 +223,82 @@ func TestClient_Sync(t *testing.T) {
t.Error("timeout waiting for test to finish")
}
}

func Test_SystemMetaDataFromClient(t *testing.T) {
_, lis := startMockManagement(t)

testKey, err := wgtypes.GenerateKey()
if err != nil {
log.Fatal(err)
}

serverAddr := lis.Addr().String()
ctx := context.Background()

testClient, err := NewClient(ctx, serverAddr, testKey, false)
if err != nil {
log.Fatalf("error while creating testClient: %v", err)
}

key, err := testClient.GetServerPublicKey()
if err != nil {
log.Fatalf("error while getting server public key from testclient, %v", err)
}

var actualMeta *proto.PeerSystemMeta
var actualValidKey string
var wg sync.WaitGroup
wg.Add(1)

mgmtMockServer.LoginFunc =
func(ctx context.Context, msg *proto.EncryptedMessage) (*proto.EncryptedMessage, error) {
peerKey, err := wgtypes.ParseKey(msg.GetWgPubKey())
if err != nil {
log.Warnf("error while parsing peer's Wireguard public key %s on Sync request.", msg.WgPubKey)
return nil, status.Errorf(codes.InvalidArgument, "provided wgPubKey %s is invalid", msg.WgPubKey)
}

loginReq := &proto.LoginRequest{}
err = encryption.DecryptMessage(peerKey, serverKey, msg.Body, loginReq)
if err != nil {
log.Fatal(err)
}

actualMeta = loginReq.GetMeta()
actualValidKey = loginReq.GetSetupKey()
wg.Done()

loginResp := &proto.LoginResponse{}
encryptedResp, err := encryption.EncryptMessage(peerKey, serverKey, loginResp)
if err != nil {
return nil, err
}

return &mgmtProto.EncryptedMessage{
WgPubKey: serverKey.PublicKey().String(),
Body: encryptedResp,
Version: 0,
}, nil
}

info := system.GetInfo()
_, err = testClient.Register(*key, ValidKey, info)
if err != nil {
t.Errorf("error while trying to register client: %v", err)
}

wg.Wait()

expectedMeta := &proto.PeerSystemMeta{
Hostname: info.Hostname,
GoOS: info.GoOS,
Kernel: info.Kernel,
Core: info.OSVersion,
Platform: info.Platform,
OS: info.OS,
WiretrusteeVersion: info.WiretrusteeVersion,
}

assert.Equal(t, ValidKey, actualValidKey)
assert.Equal(t, expectedMeta, actualMeta)
}
18 changes: 8 additions & 10 deletions management/client/grpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,18 +233,16 @@ func (c *GrpcClient) login(serverKey wgtypes.Key, req *proto.LoginRequest) (*pro
// Register registers peer on Management Server. It actually calls a Login endpoint with a provided setup key
// Takes care of encrypting and decrypting messages.
// This method will also collect system info and send it with the request (e.g. hostname, os, etc)
func (c *GrpcClient) Register(serverKey wgtypes.Key, setupKey string) (*proto.LoginResponse, error) {
gi := system.GetInfo()
func (c *GrpcClient) Register(serverKey wgtypes.Key, setupKey string, info *system.Info) (*proto.LoginResponse, error) {
meta := &proto.PeerSystemMeta{
Hostname: gi.Hostname,
GoOS: gi.GoOS,
OS: gi.OS,
Core: gi.OSVersion,
Platform: gi.Platform,
Kernel: gi.Kernel,
WiretrusteeVersion: gi.WiretrusteeVersion,
Hostname: info.Hostname,
GoOS: info.GoOS,
OS: info.OS,
Core: info.OSVersion,
Platform: info.Platform,
Kernel: info.Kernel,
WiretrusteeVersion: info.WiretrusteeVersion,
}
log.Debugf("detected system %v", meta)
return c.login(serverKey, &proto.LoginRequest{SetupKey: setupKey, Meta: meta})
}

Expand Down
Loading