Compare commits

...

3 Commits

Author SHA1 Message Date
braginini
2033650908 Remove IdP client secret validation 2022-09-26 18:58:14 +02:00
Misha Bragin
34c1c7d901 Add hostname, userID, ui version to the HTTP API peer response (#479) 2022-09-26 18:02:45 +02:00
Misha Bragin
051fd3a4d7 Fix Management and Signal gRPC client stream leak (#482) 2022-09-26 18:02:20 +02:00
6 changed files with 40 additions and 34 deletions

View File

@@ -292,9 +292,6 @@ func isProviderConfigValid(config ProviderConfig) error {
if config.ClientID == "" { if config.ClientID == "" {
return fmt.Errorf(errorMSGFormat, "Client ID") return fmt.Errorf(errorMSGFormat, "Client ID")
} }
if config.ClientSecret == "" {
return fmt.Errorf(errorMSGFormat, "Client Secret")
}
if config.TokenEndpoint == "" { if config.TokenEndpoint == "" {
return fmt.Errorf(errorMSGFormat, "Token Endpoint") return fmt.Errorf(errorMSGFormat, "Token Endpoint")
} }

View File

@@ -109,7 +109,9 @@ func (c *GrpcClient) Sync(msgHandler func(msg *proto.SyncResponse) error) error
return err return err
} }
stream, err := c.connectToStream(*serverPubKey) ctx, cancelStream := context.WithCancel(c.ctx)
defer cancelStream()
stream, err := c.connectToStream(ctx, *serverPubKey)
if err != nil { if err != nil {
log.Debugf("failed to open Management Service stream: %s", err) log.Debugf("failed to open Management Service stream: %s", err)
if s, ok := gstatus.FromError(err); ok && s.Code() == codes.PermissionDenied { if s, ok := gstatus.FromError(err); ok && s.Code() == codes.PermissionDenied {
@@ -145,7 +147,7 @@ func (c *GrpcClient) Sync(msgHandler func(msg *proto.SyncResponse) error) error
return nil return nil
} }
func (c *GrpcClient) connectToStream(serverPubKey wgtypes.Key) (proto.ManagementService_SyncClient, error) { func (c *GrpcClient) connectToStream(ctx context.Context, serverPubKey wgtypes.Key) (proto.ManagementService_SyncClient, error) {
req := &proto.SyncRequest{} req := &proto.SyncRequest{}
myPrivateKey := c.key myPrivateKey := c.key
@@ -156,9 +158,12 @@ func (c *GrpcClient) connectToStream(serverPubKey wgtypes.Key) (proto.Management
log.Errorf("failed encrypting message: %s", err) log.Errorf("failed encrypting message: %s", err)
return nil, err return nil, err
} }
syncReq := &proto.EncryptedMessage{WgPubKey: myPublicKey.String(), Body: encryptedReq} syncReq := &proto.EncryptedMessage{WgPubKey: myPublicKey.String(), Body: encryptedReq}
return c.realClient.Sync(c.ctx, syncReq) sync, err := c.realClient.Sync(ctx, syncReq)
if err != nil {
return nil, err
}
return sync, nil
} }
func (c *GrpcClient) receiveEvents(stream proto.ManagementService_SyncClient, serverPubKey wgtypes.Key, msgHandler func(msg *proto.SyncResponse) error) error { func (c *GrpcClient) receiveEvents(stream proto.ManagementService_SyncClient, serverPubKey wgtypes.Key, msgHandler func(msg *proto.SyncResponse) error) error {

View File

@@ -96,20 +96,18 @@ components:
type: array type: array
items: items:
$ref: '#/components/schemas/GroupMinimum' $ref: '#/components/schemas/GroupMinimum'
activated_by:
description: Provides information of who activated the Peer. User or Setup Key
type: object
properties:
type:
type: string
value:
type: string
required:
- type
- value
ssh_enabled: ssh_enabled:
description: Indicates whether SSH server is enabled on this peer description: Indicates whether SSH server is enabled on this peer
type: boolean type: boolean
user_id:
description: User ID of the user that enrolled this peer
type: string
hostname:
description: Hostname of the machine
type: string
ui_version:
description: Peer's desktop UI version
type: string
required: required:
- ip - ip
- connected - connected
@@ -117,8 +115,8 @@ components:
- os - os
- version - version
- groups - groups
- activated_by
- ssh_enabled - ssh_enabled
- hostname
SetupKey: SetupKey:
type: object type: object
properties: properties:

View File

@@ -125,18 +125,15 @@ type PatchMinimumOp string
// Peer defines model for Peer. // Peer defines model for Peer.
type Peer struct { type Peer struct {
// Provides information of who activated the Peer. User or Setup Key
ActivatedBy struct {
Type string `json:"type"`
Value string `json:"value"`
} `json:"activated_by"`
// Peer to Management connection status // Peer to Management connection status
Connected bool `json:"connected"` Connected bool `json:"connected"`
// Groups that the peer belongs to // Groups that the peer belongs to
Groups []GroupMinimum `json:"groups"` Groups []GroupMinimum `json:"groups"`
// Hostname of the machine
Hostname string `json:"hostname"`
// Peer ID // Peer ID
Id string `json:"id"` Id string `json:"id"`
@@ -155,6 +152,12 @@ type Peer struct {
// Indicates whether SSH server is enabled on this peer // Indicates whether SSH server is enabled on this peer
SshEnabled bool `json:"ssh_enabled"` SshEnabled bool `json:"ssh_enabled"`
// Peer's desktop UI version
UiVersion *string `json:"ui_version,omitempty"`
// User ID of the user that enrolled this peer
UserId *string `json:"user_id,omitempty"`
// Peer's daemon or cli version // Peer's daemon or cli version
Version string `json:"version"` Version string `json:"version"`
} }

View File

@@ -144,5 +144,8 @@ func toPeerResponse(peer *server.Peer, account *server.Account) *api.Peer {
Version: peer.Meta.WtVersion, Version: peer.Meta.WtVersion,
Groups: groupsInfo, Groups: groupsInfo,
SshEnabled: peer.SSHEnabled, SshEnabled: peer.SSHEnabled,
Hostname: peer.Meta.Hostname,
UserId: &peer.UserID,
UiVersion: &peer.Meta.UIVersion,
} }
} }

View File

@@ -121,9 +121,11 @@ func (c *GrpcClient) Receive(msgHandler func(msg *proto.Message) error) error {
return fmt.Errorf("connection to signal is not ready and in %s state", connState) return fmt.Errorf("connection to signal is not ready and in %s state", connState)
} }
// connect to Signal stream identifying ourselves with a public Wireguard key // connect to Signal stream identifying ourselves with a public WireGuard key
// todo once the key rotation logic has been implemented, consider changing to some other identifier (received from management) // todo once the key rotation logic has been implemented, consider changing to some other identifier (received from management)
stream, err := c.connect(c.key.PublicKey().String()) ctx, cancelStream := context.WithCancel(c.ctx)
defer cancelStream()
stream, err := c.connect(ctx, c.key.PublicKey().String())
if err != nil { if err != nil {
log.Warnf("disconnected from the Signal Exchange due to an error: %v", err) log.Warnf("disconnected from the Signal Exchange due to an error: %v", err)
return err return err
@@ -180,15 +182,13 @@ func (c *GrpcClient) getStreamStatusChan() <-chan struct{} {
return c.connectedCh return c.connectedCh
} }
func (c *GrpcClient) connect(key string) (proto.SignalExchange_ConnectStreamClient, error) { func (c *GrpcClient) connect(ctx context.Context, key string) (proto.SignalExchange_ConnectStreamClient, error) {
c.stream = nil c.stream = nil
// add key fingerprint to the request header to be identified on the server side // add key fingerprint to the request header to be identified on the server side
md := metadata.New(map[string]string{proto.HeaderId: key}) md := metadata.New(map[string]string{proto.HeaderId: key})
ctx := metadata.NewOutgoingContext(c.ctx, md) metaCtx := metadata.NewOutgoingContext(ctx, md)
stream, err := c.realClient.ConnectStream(metaCtx, grpc.WaitForReady(true))
stream, err := c.realClient.ConnectStream(ctx, grpc.WaitForReady(true))
c.stream = stream c.stream = stream
if err != nil { if err != nil {
return nil, err return nil, err