2021-08-09 19:21:48 +02:00
|
|
|
package client
|
2021-05-01 12:45:37 +02:00
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"strings"
|
2023-03-15 07:54:51 +01:00
|
|
|
|
|
|
|
"github.com/netbirdio/netbird/signal/proto"
|
|
|
|
"github.com/netbirdio/netbird/version"
|
|
|
|
|
|
|
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
2021-05-01 12:45:37 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
// A set of tools to exchange connection details (Wireguard endpoints) with the remote peer.
|
|
|
|
|
2021-11-06 15:00:13 +01:00
|
|
|
// Status is the status of the client
|
|
|
|
type Status string
|
|
|
|
|
2021-11-14 19:41:17 +01:00
|
|
|
const StreamConnected Status = "Connected"
|
|
|
|
const StreamDisconnected Status = "Disconnected"
|
2021-11-06 15:00:13 +01:00
|
|
|
|
2023-03-16 16:46:17 +01:00
|
|
|
const (
|
|
|
|
// DirectCheck indicates support to direct mode checks
|
|
|
|
DirectCheck uint32 = 1
|
|
|
|
)
|
|
|
|
|
|
|
|
// FeaturesSupport register protocol supported features
|
|
|
|
type FeaturesSupport struct {
|
|
|
|
DirectCheck bool
|
|
|
|
}
|
|
|
|
|
2022-01-18 16:44:58 +01:00
|
|
|
type Client interface {
|
|
|
|
io.Closer
|
|
|
|
StreamConnected() bool
|
|
|
|
GetStatus() Status
|
|
|
|
Receive(msgHandler func(msg *proto.Message) error) error
|
|
|
|
Ready() bool
|
2024-01-22 12:20:24 +01:00
|
|
|
IsHealthy() bool
|
2022-01-18 16:44:58 +01:00
|
|
|
WaitStreamConnected()
|
|
|
|
SendToStream(msg *proto.EncryptedMessage) error
|
|
|
|
Send(msg *proto.Message) error
|
2021-05-01 12:45:37 +02:00
|
|
|
}
|
|
|
|
|
2021-05-15 12:20:49 +02:00
|
|
|
// UnMarshalCredential parses the credentials from the message and returns a Credential instance
|
2021-05-01 12:45:37 +02:00
|
|
|
func UnMarshalCredential(msg *proto.Message) (*Credential, error) {
|
2021-05-01 18:29:59 +02:00
|
|
|
|
|
|
|
credential := strings.Split(msg.GetBody().GetPayload(), ":")
|
2021-05-01 12:45:37 +02:00
|
|
|
if len(credential) != 2 {
|
|
|
|
return nil, fmt.Errorf("error parsing message body %s", msg.Body)
|
|
|
|
}
|
|
|
|
return &Credential{
|
|
|
|
UFrag: credential[0],
|
|
|
|
Pwd: credential[1],
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
2024-01-08 12:25:35 +01:00
|
|
|
// MarshalCredential marshal a Credential instance and returns a Message object
|
|
|
|
func MarshalCredential(myKey wgtypes.Key, myPort int, remoteKey wgtypes.Key, credential *Credential, t proto.Body_Type,
|
|
|
|
rosenpassPubKey []byte, rosenpassAddr string) (*proto.Message, error) {
|
2021-05-01 12:45:37 +02:00
|
|
|
return &proto.Message{
|
2021-05-01 18:29:59 +02:00
|
|
|
Key: myKey.PublicKey().String(),
|
|
|
|
RemoteKey: remoteKey.String(),
|
|
|
|
Body: &proto.Body{
|
2022-09-02 19:33:35 +02:00
|
|
|
Type: t,
|
|
|
|
Payload: fmt.Sprintf("%s:%s", credential.UFrag, credential.Pwd),
|
|
|
|
WgListenPort: uint32(myPort),
|
2023-03-15 07:54:51 +01:00
|
|
|
NetBirdVersion: version.NetbirdVersion(),
|
2024-01-08 12:25:35 +01:00
|
|
|
RosenpassConfig: &proto.RosenpassConfig{
|
|
|
|
RosenpassPubKey: rosenpassPubKey,
|
|
|
|
RosenpassServerAddr: rosenpassAddr,
|
|
|
|
},
|
2021-05-01 18:29:59 +02:00
|
|
|
},
|
|
|
|
}, nil
|
2021-05-01 12:45:37 +02:00
|
|
|
}
|
|
|
|
|
2022-01-18 16:44:58 +01:00
|
|
|
// Credential is an instance of a GrpcClient's Credential
|
2021-05-01 12:45:37 +02:00
|
|
|
type Credential struct {
|
|
|
|
UFrag string
|
|
|
|
Pwd string
|
|
|
|
}
|
2023-03-16 16:46:17 +01:00
|
|
|
|
|
|
|
// ParseFeaturesSupported parses a slice of supported features into FeaturesSupport
|
|
|
|
func ParseFeaturesSupported(featuresMessage []uint32) FeaturesSupport {
|
|
|
|
var protoSupport FeaturesSupport
|
|
|
|
for _, feature := range featuresMessage {
|
|
|
|
if feature == DirectCheck {
|
|
|
|
protoSupport.DirectCheck = true
|
|
|
|
return protoSupport
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return protoSupport
|
|
|
|
}
|