2022-03-25 11:05:17 -04:00
|
|
|
package wireguard
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/edgelesssys/constellation/coordinator/peer"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/stretchr/testify/require"
|
2022-06-30 09:24:36 -04:00
|
|
|
"go.uber.org/goleak"
|
2022-03-25 11:05:17 -04:00
|
|
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
|
|
|
)
|
|
|
|
|
2022-06-30 09:24:36 -04:00
|
|
|
func TestMain(m *testing.M) {
|
|
|
|
goleak.VerifyTestMain(m)
|
|
|
|
}
|
|
|
|
|
2022-03-25 11:05:17 -04:00
|
|
|
func TestUpdatePeer(t *testing.T) {
|
|
|
|
requirePre := require.New(t)
|
|
|
|
|
|
|
|
firstKey, err := wgtypes.GenerateKey()
|
|
|
|
requirePre.NoError(err)
|
2022-04-13 06:39:55 -04:00
|
|
|
peer1 := peer.Peer{PublicIP: "192.0.2.11", VPNIP: "192.0.2.21", VPNPubKey: firstKey[:]}
|
2022-03-25 11:05:17 -04:00
|
|
|
firstKeyUpd, err := wgtypes.GenerateKey()
|
|
|
|
requirePre.NoError(err)
|
2022-04-13 06:39:55 -04:00
|
|
|
peer1KeyUpd := peer.Peer{PublicIP: "192.0.2.11", VPNIP: "192.0.2.21", VPNPubKey: firstKeyUpd[:]}
|
2022-03-25 11:05:17 -04:00
|
|
|
secondKey, err := wgtypes.GenerateKey()
|
|
|
|
requirePre.NoError(err)
|
2022-04-13 06:39:55 -04:00
|
|
|
peer2 := peer.Peer{PublicIP: "192.0.2.12", VPNIP: "192.0.2.22", VPNPubKey: secondKey[:]}
|
2022-03-25 11:05:17 -04:00
|
|
|
thirdKey, err := wgtypes.GenerateKey()
|
|
|
|
requirePre.NoError(err)
|
2022-04-13 06:39:55 -04:00
|
|
|
peer3 := peer.Peer{PublicIP: "192.0.2.13", VPNIP: "192.0.2.23", VPNPubKey: thirdKey[:]}
|
2022-03-25 11:05:17 -04:00
|
|
|
fourthKey, err := wgtypes.GenerateKey()
|
|
|
|
requirePre.NoError(err)
|
2022-04-13 06:39:55 -04:00
|
|
|
peerAdmin := peer.Peer{PublicIP: "192.0.2.10", VPNIP: "192.0.2.25", VPNPubKey: fourthKey[:]}
|
|
|
|
peerAdminNoEndp := peer.Peer{VPNIP: "192.0.2.25", VPNPubKey: fourthKey[:]}
|
2022-03-25 11:05:17 -04:00
|
|
|
|
|
|
|
checkError := func(peers []wgtypes.Peer, err error) []wgtypes.Peer {
|
|
|
|
requirePre.NoError(err)
|
|
|
|
return peers
|
|
|
|
}
|
|
|
|
|
|
|
|
testCases := map[string]struct {
|
2022-04-26 10:54:05 -04:00
|
|
|
storePeers []peer.Peer
|
|
|
|
vpnPeers []wgtypes.Peer
|
|
|
|
excludedIP map[string]struct{}
|
|
|
|
wantErr bool
|
|
|
|
wantVPNPeers []wgtypes.Peer
|
2022-03-25 11:05:17 -04:00
|
|
|
}{
|
|
|
|
"basic": {
|
2022-04-26 10:54:05 -04:00
|
|
|
storePeers: []peer.Peer{peer1, peer3},
|
|
|
|
vpnPeers: checkError(transformToWgpeer([]peer.Peer{peer1, peer2})),
|
|
|
|
wantVPNPeers: checkError(transformToWgpeer([]peer.Peer{peer1, peer3})),
|
2022-03-25 11:05:17 -04:00
|
|
|
},
|
|
|
|
"previously empty": {
|
2022-04-26 10:54:05 -04:00
|
|
|
storePeers: []peer.Peer{peer1, peer2},
|
|
|
|
wantVPNPeers: checkError(transformToWgpeer([]peer.Peer{peer1, peer2})),
|
2022-03-25 11:05:17 -04:00
|
|
|
},
|
|
|
|
"no changes": {
|
2022-04-26 10:54:05 -04:00
|
|
|
storePeers: []peer.Peer{peer1, peer2},
|
|
|
|
vpnPeers: checkError(transformToWgpeer([]peer.Peer{peer1, peer2})),
|
|
|
|
wantVPNPeers: checkError(transformToWgpeer([]peer.Peer{peer1, peer2})),
|
2022-03-25 11:05:17 -04:00
|
|
|
},
|
|
|
|
"key update": {
|
2022-04-26 10:54:05 -04:00
|
|
|
storePeers: []peer.Peer{peer1KeyUpd, peer3},
|
|
|
|
vpnPeers: checkError(transformToWgpeer([]peer.Peer{peer1, peer2})),
|
|
|
|
wantVPNPeers: checkError(transformToWgpeer([]peer.Peer{peer1KeyUpd, peer3})),
|
2022-03-25 11:05:17 -04:00
|
|
|
},
|
2022-04-13 06:39:55 -04:00
|
|
|
"not update Endpoint changes": {
|
2022-04-26 10:54:05 -04:00
|
|
|
storePeers: []peer.Peer{peerAdminNoEndp, peer3},
|
|
|
|
vpnPeers: checkError(transformToWgpeer([]peer.Peer{peerAdmin, peer3})),
|
|
|
|
wantVPNPeers: checkError(transformToWgpeer([]peer.Peer{peerAdmin, peer3})),
|
2022-03-25 11:05:17 -04:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for name, tc := range testCases {
|
|
|
|
t.Run(name, func(t *testing.T) {
|
|
|
|
assert := assert.New(t)
|
|
|
|
require := require.New(t)
|
|
|
|
|
|
|
|
fakewg := fakewgClient{}
|
|
|
|
fakewg.devices = make(map[string]*wgtypes.Device)
|
2022-04-13 06:39:55 -04:00
|
|
|
wg := Wireguard{client: &fakewg}
|
2022-03-25 11:05:17 -04:00
|
|
|
|
|
|
|
fakewg.devices[netInterface] = &wgtypes.Device{Peers: tc.vpnPeers}
|
|
|
|
|
|
|
|
updateErr := wg.UpdatePeers(tc.storePeers)
|
|
|
|
|
2022-04-26 10:54:05 -04:00
|
|
|
if tc.wantErr {
|
2022-03-25 11:05:17 -04:00
|
|
|
assert.Error(updateErr)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
require.NoError(updateErr)
|
|
|
|
|
2022-04-26 10:54:05 -04:00
|
|
|
assert.ElementsMatch(tc.wantVPNPeers, fakewg.devices[netInterface].Peers)
|
2022-03-25 11:05:17 -04:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
type fakewgClient struct {
|
|
|
|
devices map[string]*wgtypes.Device
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *fakewgClient) Device(name string) (*wgtypes.Device, error) {
|
|
|
|
if val, ok := w.devices[name]; ok {
|
|
|
|
return val, nil
|
|
|
|
}
|
|
|
|
return nil, errors.New("device does not exist")
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *fakewgClient) ConfigureDevice(name string, cfg wgtypes.Config) error {
|
|
|
|
var newPeerList []wgtypes.Peer
|
|
|
|
var operation bool
|
|
|
|
vpnPeers := make(map[wgtypes.Key]wgtypes.Peer)
|
|
|
|
|
|
|
|
for _, peer := range w.devices[netInterface].Peers {
|
|
|
|
vpnPeers[peer.PublicKey] = peer
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, configPeer := range cfg.Peers {
|
|
|
|
operation = false
|
|
|
|
for _, vpnPeer := range w.devices[netInterface].Peers {
|
|
|
|
// wireguard matches internally via pubkey
|
|
|
|
if vpnPeer.PublicKey == configPeer.PublicKey {
|
|
|
|
operation = true
|
|
|
|
if configPeer.Remove {
|
|
|
|
delete(vpnPeers, vpnPeer.PublicKey)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
if configPeer.UpdateOnly {
|
|
|
|
vpnPeers[vpnPeer.PublicKey] = wgtypes.Peer{
|
|
|
|
PublicKey: vpnPeer.PublicKey,
|
|
|
|
AllowedIPs: vpnPeer.AllowedIPs,
|
|
|
|
Endpoint: configPeer.Endpoint,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if !operation {
|
|
|
|
vpnPeers[configPeer.PublicKey] = wgtypes.Peer{
|
|
|
|
PublicKey: configPeer.PublicKey,
|
|
|
|
AllowedIPs: configPeer.AllowedIPs,
|
|
|
|
Endpoint: configPeer.Endpoint,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for _, peer := range vpnPeers {
|
|
|
|
newPeerList = append(newPeerList, peer)
|
|
|
|
}
|
|
|
|
w.devices[netInterface].Peers = newPeerList
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *fakewgClient) Close() error {
|
|
|
|
return nil
|
|
|
|
}
|