ipn/ipn{auth,server}: update ipnauth.Actor to carry a context
The context carries additional information about the actor, such as the request reason, and is canceled when the actor is done. Additionally, we implement three new ipn.Actor types that wrap other actors to modify their behavior: - WithRequestReason, which adds a request reason to the actor; - WithoutClose, which narrows the actor's interface to prevent it from being closed; - WithPolicyChecks, which adds policy checks to the actor's CheckProfileAccess method. Updates #14823 Signed-off-by: Nick Khyl <nickk@tailscale.com>
This commit is contained in:
@@ -7,10 +7,36 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"tailscale.com/client/tailscale/apitype"
|
||||
"tailscale.com/ipn"
|
||||
"tailscale.com/util/syspolicy"
|
||||
)
|
||||
|
||||
type actorWithPolicyChecks struct{ Actor }
|
||||
|
||||
// WithPolicyChecks returns an [Actor] that wraps the given actor and
|
||||
// performs additional policy checks on top of the access checks
|
||||
// implemented by the wrapped actor.
|
||||
func WithPolicyChecks(actor Actor) Actor {
|
||||
// TODO(nickkhyl): We should probably exclude the Windows Local System
|
||||
// account from policy checks as well.
|
||||
switch actor.(type) {
|
||||
case unrestricted:
|
||||
return actor
|
||||
default:
|
||||
return &actorWithPolicyChecks{Actor: actor}
|
||||
}
|
||||
}
|
||||
|
||||
// CheckProfileAccess implements [Actor].
|
||||
func (a actorWithPolicyChecks) CheckProfileAccess(profile ipn.LoginProfileView, requestedAccess ProfileAccess, auditLogger AuditLogFunc) error {
|
||||
if err := a.Actor.CheckProfileAccess(profile, requestedAccess, auditLogger); err != nil {
|
||||
return err
|
||||
}
|
||||
requestReason := apitype.RequestReasonKey.Value(a.Context())
|
||||
return CheckDisconnectPolicy(a.Actor, profile, requestReason, auditLogger)
|
||||
}
|
||||
|
||||
// CheckDisconnectPolicy checks if the policy allows the specified actor to disconnect
|
||||
// Tailscale with the given optional reason. It returns nil if the operation is allowed,
|
||||
// or an error if it is not. If auditLogger is non-nil, it is called to log the action
|
||||
|
||||
Reference in New Issue
Block a user