2021-09-02 14:41:54 +02:00
|
|
|
package server
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/hmac"
|
|
|
|
"crypto/sha1"
|
|
|
|
"encoding/base64"
|
|
|
|
"testing"
|
|
|
|
"time"
|
2023-11-10 16:33:13 +01:00
|
|
|
|
|
|
|
"github.com/netbirdio/netbird/util"
|
2021-09-02 14:41:54 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
var TurnTestHost = &Host{
|
|
|
|
Proto: UDP,
|
|
|
|
URI: "turn:turn.wiretrustee.com:77777",
|
|
|
|
Username: "username",
|
2021-09-03 17:47:40 +02:00
|
|
|
Password: "",
|
2021-09-02 14:41:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestTimeBasedAuthSecretsManager_GenerateCredentials(t *testing.T) {
|
|
|
|
ttl := util.Duration{Duration: time.Hour}
|
2021-09-03 17:47:40 +02:00
|
|
|
secret := "some_secret"
|
2021-09-02 14:41:54 +02:00
|
|
|
peersManager := NewPeersUpdateManager()
|
|
|
|
|
|
|
|
tested := NewTimeBasedAuthSecretsManager(peersManager, &TURNConfig{
|
|
|
|
CredentialsTTL: ttl,
|
|
|
|
Secret: secret,
|
|
|
|
Turns: []*Host{TurnTestHost},
|
|
|
|
})
|
|
|
|
|
|
|
|
credentials := tested.GenerateCredentials()
|
|
|
|
|
|
|
|
if credentials.Username == "" {
|
|
|
|
t.Errorf("expected generated TURN username not to be empty, got empty")
|
|
|
|
}
|
|
|
|
if credentials.Password == "" {
|
|
|
|
t.Errorf("expected generated TURN password not to be empty, got empty")
|
|
|
|
}
|
|
|
|
|
2023-11-10 16:33:13 +01:00
|
|
|
validateMAC(t, credentials.Username, credentials.Password, []byte(secret))
|
2021-09-02 14:41:54 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestTimeBasedAuthSecretsManager_SetupRefresh(t *testing.T) {
|
|
|
|
ttl := util.Duration{Duration: 2 * time.Second}
|
2021-09-03 17:47:40 +02:00
|
|
|
secret := "some_secret"
|
2021-09-02 14:41:54 +02:00
|
|
|
peersManager := NewPeersUpdateManager()
|
|
|
|
peer := "some_peer"
|
|
|
|
updateChannel := peersManager.CreateChannel(peer)
|
|
|
|
|
|
|
|
tested := NewTimeBasedAuthSecretsManager(peersManager, &TURNConfig{
|
|
|
|
CredentialsTTL: ttl,
|
|
|
|
Secret: secret,
|
|
|
|
Turns: []*Host{TurnTestHost},
|
|
|
|
})
|
|
|
|
|
|
|
|
tested.SetupRefresh(peer)
|
|
|
|
|
|
|
|
if _, ok := tested.cancelMap[peer]; !ok {
|
|
|
|
t.Errorf("expecting peer to be present in a cancel map, got not present")
|
|
|
|
}
|
|
|
|
|
|
|
|
var updates []*UpdateMessage
|
|
|
|
|
|
|
|
loop:
|
|
|
|
for timeout := time.After(5 * time.Second); ; {
|
|
|
|
|
|
|
|
select {
|
|
|
|
case update := <-updateChannel:
|
|
|
|
updates = append(updates, update)
|
|
|
|
case <-timeout:
|
|
|
|
break loop
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(updates) >= 2 {
|
|
|
|
break loop
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(updates) < 2 {
|
|
|
|
t.Errorf("expecting 2 peer credentials updates, got %v", len(updates))
|
|
|
|
}
|
|
|
|
|
|
|
|
firstUpdate := updates[0].Update.GetWiretrusteeConfig().Turns[0]
|
|
|
|
secondUpdate := updates[1].Update.GetWiretrusteeConfig().Turns[0]
|
|
|
|
|
|
|
|
if firstUpdate.Password == secondUpdate.Password {
|
|
|
|
t.Errorf("expecting first credential update password %v to be diffeerent from second, got equal", firstUpdate.Password)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestTimeBasedAuthSecretsManager_CancelRefresh(t *testing.T) {
|
|
|
|
ttl := util.Duration{Duration: time.Hour}
|
2021-09-03 17:47:40 +02:00
|
|
|
secret := "some_secret"
|
2021-09-02 14:41:54 +02:00
|
|
|
peersManager := NewPeersUpdateManager()
|
|
|
|
peer := "some_peer"
|
|
|
|
|
|
|
|
tested := NewTimeBasedAuthSecretsManager(peersManager, &TURNConfig{
|
|
|
|
CredentialsTTL: ttl,
|
|
|
|
Secret: secret,
|
|
|
|
Turns: []*Host{TurnTestHost},
|
|
|
|
})
|
|
|
|
|
|
|
|
tested.SetupRefresh(peer)
|
|
|
|
if _, ok := tested.cancelMap[peer]; !ok {
|
|
|
|
t.Errorf("expecting peer to be present in a cancel map, got not present")
|
|
|
|
}
|
|
|
|
|
|
|
|
tested.CancelRefresh(peer)
|
|
|
|
if _, ok := tested.cancelMap[peer]; ok {
|
|
|
|
t.Errorf("expecting peer to be not present in a cancel map, got present")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-10 16:33:13 +01:00
|
|
|
func validateMAC(t *testing.T, username string, actualMAC string, key []byte) {
|
|
|
|
t.Helper()
|
2021-09-02 14:41:54 +02:00
|
|
|
mac := hmac.New(sha1.New, key)
|
|
|
|
|
|
|
|
_, err := mac.Write([]byte(username))
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
expectedMAC := mac.Sum(nil)
|
|
|
|
decodedMAC, err := base64.StdEncoding.DecodeString(actualMAC)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
equal := hmac.Equal(decodedMAC, expectedMAC)
|
|
|
|
|
|
|
|
if !equal {
|
|
|
|
t.Errorf("expected password MAC to be %s. got %s", expectedMAC, decodedMAC)
|
|
|
|
}
|
|
|
|
}
|