mirror of
https://github.com/netbirdio/netbird.git
synced 2026-10-10 23:49:09 +02:00
Collect certificate proofs again when the owner's session changes and report lost proofs
This commit is contained in:
@@ -224,6 +224,11 @@ currently open**. Consequences worth designing around:
|
||||
- **Signing out changes the answer.** Posture can flip between compliant and
|
||||
non-compliant across a sign-out, so management should treat "no proof" as its own
|
||||
state rather than as a failed check, or users get disconnected at the sign-in screen.
|
||||
- **The engine notices the change.** Every minute it checks whether the profile owner's
|
||||
session came or went, and collects again when it did. A collection that proved nothing
|
||||
is retried every five minutes, for a keychain unlocked after login or a TPM resource
|
||||
manager started after the daemon. Losing every proof, and regaining one, is published
|
||||
as a system event, so the UI and `netbird status` show why access changed.
|
||||
- **Only the profile owner is asked.** The user certificate belongs to whoever owns the
|
||||
active NetBird profile. macOS asks the console user only when that user owns the
|
||||
profile, so a fast-user-switched account never answers for someone else. Windows asks
|
||||
|
||||
@@ -108,6 +108,11 @@ func CollectChallenges(ctx context.Context, store Store, challenges []*proto.Cer
|
||||
return proofs
|
||||
}
|
||||
|
||||
// HasChallenges reports whether any of checks asks for a certificate proof.
|
||||
func HasChallenges(checks []*proto.Checks) bool {
|
||||
return len(certificateChallenges(checks)) > 0
|
||||
}
|
||||
|
||||
func certificateChallenges(checks []*proto.Checks) []*proto.CertificateChallenge {
|
||||
var challenges []*proto.CertificateChallenge
|
||||
for _, check := range checks {
|
||||
|
||||
@@ -45,6 +45,20 @@ func CollectProofs(ctx context.Context, checks []*proto.Checks, peerKey []byte,
|
||||
return mergeProofs(proofs, userProofs)
|
||||
}
|
||||
|
||||
// UserContext identifies the user whose keychain a collection would include: the console
|
||||
// user when it owns the active profile, or empty when no user keychain would be asked. A
|
||||
// change means a collection made earlier no longer reflects what this Mac can prove.
|
||||
func UserContext(cfg Config) string {
|
||||
if os.Geteuid() != 0 {
|
||||
return ""
|
||||
}
|
||||
user, ok := CurrentConsoleUser()
|
||||
if !ok || !user.isOwner(cfg.ProfileOwner) {
|
||||
return ""
|
||||
}
|
||||
return strconv.FormatUint(uint64(user.UID), 10) + ":" + user.Name
|
||||
}
|
||||
|
||||
// collectAsConsoleUser runs the helper inside the desktop session of the logged-in
|
||||
// user. Dropping to their uid is not enough: keychain access is an XPC call to a
|
||||
// per-session securityd, so the helper has to enter their Mach bootstrap namespace,
|
||||
|
||||
@@ -17,6 +17,12 @@ func CollectProofs(ctx context.Context, checks []*proto.Checks, peerKey []byte,
|
||||
return Collect(ctx, storeWithToken(cfg), checks, peerKey)
|
||||
}
|
||||
|
||||
// UserContext identifies the user whose certificates a collection would include. These
|
||||
// platforms have no per-user store, so it never changes.
|
||||
func UserContext(Config) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// helperStore is the store the helper reads. Nothing launches a helper on these
|
||||
// platforms, so it is the platform default.
|
||||
func helperStore() Store {
|
||||
|
||||
@@ -44,6 +44,21 @@ func CollectProofs(ctx context.Context, checks []*proto.Checks, peerKey []byte,
|
||||
return mergeProofs(proofs, userProofs)
|
||||
}
|
||||
|
||||
// UserContext identifies the session whose store a collection would include: a session
|
||||
// of the profile owner, or empty when no user store would be asked. A change means a
|
||||
// collection made earlier no longer reflects what this machine can prove.
|
||||
func UserContext(cfg Config) string {
|
||||
if !runningAsLocalSystem() {
|
||||
return ""
|
||||
}
|
||||
user, ok := CurrentDesktopUser(cfg.ProfileOwner)
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
defer user.Close()
|
||||
return fmt.Sprintf("%d:%s", user.Session, user.Name)
|
||||
}
|
||||
|
||||
// helperStore is the store the helper reads. It runs as the signed-in user, so it wants
|
||||
// that user's store rather than the machine store the service already read.
|
||||
func helperStore() Store {
|
||||
|
||||
Reference in New Issue
Block a user