Lower CreateTemporaryAccess complexity and emit VncAuth for session pubkeys

This commit is contained in:
Viktor Liu
2026-05-22 12:01:18 +02:00
parent 1cc5967198
commit 0f03c612d1
3 changed files with 27 additions and 14 deletions

View File

@@ -183,8 +183,12 @@ func ToSyncResponse(ctx context.Context, config *nbconfig.Config, httpConfig *nb
response.NetworkMap.SshAuth = &proto.SSHAuth{AuthorizedUsers: hashedUsers, MachineUsers: machineUsers, UserIDClaim: userIDClaim}
}
if networkMap.VNCAuthorizedUsers != nil {
hashedUsers, machineUsers := buildAuthorizedUsersProto(ctx, networkMap.VNCAuthorizedUsers)
if networkMap.VNCAuthorizedUsers != nil || len(networkMap.VNCSessionPubKeys) > 0 {
var hashedUsers [][]byte
var machineUsers map[string]*proto.MachineUserIndexes
if networkMap.VNCAuthorizedUsers != nil {
hashedUsers, machineUsers = buildAuthorizedUsersProto(ctx, networkMap.VNCAuthorizedUsers)
}
response.NetworkMap.VncAuth = &proto.VNCAuth{
AuthorizedUsers: hashedUsers,
MachineUsers: machineUsers,

View File

@@ -519,20 +519,12 @@ func (h *Handler) CreateTemporaryAccess(w http.ResponseWriter, r *http.Request)
policy.Rules[0].AuthorizedUser = userAuth.UserId
}
if protocol == types.PolicyRuleProtocolNetbirdVNC {
if req.SessionPubKey == nil || *req.SessionPubKey == "" {
util.WriteError(r.Context(), status.Errorf(status.InvalidArgument, "session_pub_key is required for VNC temporary access"), w)
return
}
pub, err := base64.StdEncoding.DecodeString(*req.SessionPubKey)
pubKey, err := validateVNCSessionPubKey(req.SessionPubKey)
if err != nil {
util.WriteError(r.Context(), status.Errorf(status.InvalidArgument, "session_pub_key is not valid base64: %v", err), w)
util.WriteError(r.Context(), err, w)
return
}
if len(pub) != 32 {
util.WriteError(r.Context(), status.Errorf(status.InvalidArgument, "session_pub_key must decode to 32 bytes, got %d", len(pub)), w)
return
}
policy.Rules[0].SessionPubKey = *req.SessionPubKey
policy.Rules[0].SessionPubKey = pubKey
}
_, err = h.accountManager.SavePolicy(r.Context(), userAuth.AccountId, userAuth.UserId, policy, true)
@@ -552,6 +544,23 @@ func (h *Handler) CreateTemporaryAccess(w http.ResponseWriter, r *http.Request)
util.WriteJSONObject(r.Context(), w, resp)
}
// validateVNCSessionPubKey ensures the request carries a base64-encoded
// 32-byte X25519 public key for VNC temporary access. Returns the original
// base64 string on success.
func validateVNCSessionPubKey(raw *string) (string, error) {
if raw == nil || *raw == "" {
return "", status.Errorf(status.InvalidArgument, "session_pub_key is required for VNC temporary access")
}
pub, err := base64.StdEncoding.DecodeString(*raw)
if err != nil {
return "", status.Errorf(status.InvalidArgument, "session_pub_key is not valid base64: %v", err)
}
if len(pub) != 32 {
return "", status.Errorf(status.InvalidArgument, "session_pub_key must decode to 32 bytes, got %d", len(pub))
}
return *raw, nil
}
func toAccessiblePeers(netMap *types.NetworkMap, dnsDomain string) []api.AccessiblePeer {
accessiblePeers := make([]api.AccessiblePeer, 0, len(netMap.Peers)+len(netMap.OfflinePeers))
for _, p := range netMap.Peers {

View File

@@ -3391,7 +3391,7 @@ type PeerTemporaryAccessRequest struct {
// Rules List of temporary access rules
Rules []string `json:"rules"`
// SessionPubKey Ephemeral Ed25519 public key the requester will sign session-binding challenges with. Required for VNC rules; ignored for SSH and L4.
// SessionPubKey Ephemeral base64-encoded X25519 public key used with Noise_IK to bind the VNC session. Required for VNC rules; ignored for SSH and L4.
SessionPubKey *string `json:"session_pub_key,omitempty"`
// WgPubKey Peer's WireGuard public key