summaryrefslogtreecommitdiffhomepage
path: root/ipn/ipnserver/actor.go
AgeCommit message (Collapse)AuthorFilesLines
2025-10-02feature/featuretags, all: add build features, use existing ones in more placesBrad Fitzpatrick1-0/+6
Saves 270 KB. Updates #12614 Change-Id: I4c3fe06d32c49edb3a4bb0758a8617d83f291cf5 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-09-21ipn/ipnauth: don't crash on OpenBSD trying to log username of unknown peerBrad Fitzpatrick1-1/+5
We never implemented the peercred package on OpenBSD (and I just tried again and failed), but we've always documented that the creds pointer can be nil for operating systems where we can't map the unix socket back to its UID. On those platforms, we set the default unix socket permissions such that only the admin can open it anyway and we don't have a read-only vs read-write distinction. OpenBSD was always in that camp, where any access to Tailscale's unix socket meant full access. But during some refactoring, we broke OpenBSD in that we started assuming during one logging path (during login) that Creds was non-nil when looking up an ipnauth.Actor's username, which wasn't relevant (it was called from a function "maybeUsernameOf" anyway, which threw away errors). Verified on an OpenBSD VM. We don't have any OpenBSD integration tests yet. Fixes #17209 Updates #17221 Change-Id: I473c5903dfaa645694bcc75e7f5d484f3dd6044d Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-06-17ipn: add missing entries for OpenBSDJuan Francisco Cantero Hurtado1-1/+1
Signed-off-by: Juan Francisco Cantero Hurtado <jfch@30041993.xyz>
2025-05-09ipn/ipn{server,test}: extract the LocalAPI test client and server into ipntestNick Khyl1-0/+6
In this PR, we extract the in-process LocalAPI client/server implementation from ipn/ipnserver/server_test.go into a new ipntest package to be used in high‑level black‑box tests, such as those for the tailscale CLI. Updates #15575 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-02-14various: keep tailscale connected when Always On mode is enabled on WindowsNick Khyl1-0/+1
In this PR, we enable the registration of LocalBackend extensions to exclude code specific to certain platforms or environments. We then introduce desktopSessionsExt, which is included only in Windows builds and only if the ts_omit_desktop_sessions tag is disabled for the build. This extension tracks desktop sessions and switches to (or remains on) the appropriate profile when a user signs in or out, locks their screen, or disconnects a remote session. As desktopSessionsExt requires an ipn/desktop.SessionManager, we register it with tsd.System for the tailscaled subprocess on Windows. We also fix a bug in the sessionWatcher implementation where it attempts to close a nil channel on stop. Updates #14823 Updates tailscale/corp#26247 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-02-12ipn/ipn{local,server}: extract logic that determines the "best" Tailscale ↵Nick Khyl1-2/+10
profile to use In this PR, we further refactor LocalBackend and Unattended Mode to extract the logic that determines which profile should be used at the time of the check, such as when a LocalAPI client connects or disconnects. We then update (*LocalBackend).switchProfileLockedOnEntry to to switch to the profile returned by (*LocalBackend).resolveBestProfileLocked() rather than to the caller-specified specified profile, and rename it to switchToBestProfileLockedOnEntry. This is done in preparation for updating (*LocalBackend).getBackgroundProfileIDLocked to support Always-On mode by determining which profile to use based on which users, if any, are currently logged in and have an active foreground desktop session. Updates #14823 Updates tailscale/corp#26247 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-02-11ipn/ipn{auth,server}: update ipnauth.Actor to carry a contextNick Khyl1-0/+3
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>
2025-02-04ipn/{ipnauth,ipnlocal,ipnserver}: move the AlwaysOn policy check from ↵Nick Khyl1-14/+3
ipnserver to ipnauth In this PR, we move the code that checks the AlwaysOn policy from ipnserver.actor to ipnauth. It is intended to be used by ipnauth.Actor implementations, and we temporarily make it exported while these implementations reside in ipnserver and in corp. We'll unexport it later. We also update [ipnauth.Actor.CheckProfileAccess] to accept an auditLogger, which is called to write details about the action to the audit log when required by the policy, and update LocalBackend.EditPrefsAs to use an auditLogger that writes to the regular backend log. Updates tailscale/corp#26146 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-02-01client/tailscale,ipn/ipn{local,server},util/syspolicy: implement the ↵Nick Khyl1-6/+34
AlwaysOn.OverrideWithReason policy setting In this PR, we update client/tailscale.LocalClient to allow sending requests with an optional X-Tailscale-Reason header. We then update ipn/ipnserver.{actor,Server} to retrieve this reason, if specified, and use it to determine whether ipnauth.Disconnect is allowed when the AlwaysOn.OverrideWithReason policy setting is enabled. For now, we log the reason, along with the profile and OS username, to the backend log. Finally, we update LocalBackend to remember when a disconnect was permitted and do not reconnect automatically unless the policy changes. Updates tailscale/corp#26146 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-01-31ipn/ipn{auth,server,local}: initial support for the always-on modeNick Khyl1-1/+12
In this PR, we update LocalBackend to set WantRunning=true when applying policy settings to the current profile's prefs, if the "always-on" mode is enabled. We also implement a new (*LocalBackend).EditPrefsAs() method, which is like EditPrefs but accepts an actor (e.g., a LocalAPI client's identity) that initiated the change. If WantRunning is being set to false, the new EditPrefsAs method checks whether the actor has ipnauth.Disconnect access to the profile and propagates an error if they do not. Finally, we update (*ipnserver.actor).CheckProfileAccess to allow a disconnect only if the "always-on" mode is not enabled by the AlwaysOn policy setting. This is not a comprehensive solution to the "always-on" mode across platforms, as instead of disconnecting a user could achieve the same effect by creating a new empty profile, initiating a reauth, or by deleting the profile. These are the things we should address in future PRs. Updates #14823 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-01-31ipn/{ipnauth, ipnserver}: extend the ipnauth.Actor interface with a ↵Nick Khyl1-0/+8
CheckProfileAccess method The implementations define it to verify whether the actor has the requested access to a login profile. Updates #14823 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-01-14ipn/ipnserver: use ipnauth.Actor instead of *ipnserver.actor whenever possibleNick Khyl1-4/+4
In preparation for adding test coverage for ipn/ipnserver.Server, we update it to use ipnauth.Actor instead of its concrete implementation where possible. Updates tailscale/corp#25804 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-01-09all: illumos/solaris userspace only supportNahum Shalman1-1/+1
Updates #14565 Change-Id: I743148144938794db0a224873ce76c10dbe6fa5f Signed-off-by: Nahum Shalman <nahamu@gmail.com>
2024-10-18ipn/{ipnauth,ipnlocal,ipnserver}: send the auth URL to the user who started ↵Nick Khyl1-1/+22
interactive login We add the ClientID() method to the ipnauth.Actor interface and updated ipnserver.actor to implement it. This method returns a unique ID of the connected client if the actor represents one. It helps link a series of interactions initiated by the client, such as when a notification needs to be sent back to a specific session, rather than all active sessions, in response to a certain request. We also add LocalBackend.WatchNotificationsAs and LocalBackend.StartLoginInteractiveAs methods, which are like WatchNotifications and StartLoginInteractive but accept an additional parameter specifying an ipnauth.Actor who initiates the operation. We store these actor identities in watchSession.owner and LocalBackend.authActor, respectively,and implement LocalBackend.sendTo and related helper methods to enable sending notifications to watchSessions associated with actors (or, more broadly, identifiable recipients). We then use the above to change who receives the BrowseToURL notifications: - For user-initiated, interactive logins, the notification is delivered only to the user who initiated the process. If the initiating actor represents a specific connected client, the URL notification is sent back to the same LocalAPI client that called StartLoginInteractive. Otherwise, the notification is sent to all clients connected as that user. Currently, we only differentiate between users on Windows, as it is inherently a multi-user OS. - In all other cases (e.g., node key expiration), we send the notification to all connected users. Updates tailscale/corp#18342 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2024-08-28ipn/{ipnauth,ipnlocal,ipnserver,localapi}: start baby step toward moving ↵Nick Khyl1-0/+188
access checks from the localapi.Handler to the LocalBackend Currently, we use PermitRead/PermitWrite/PermitCert permission flags to determine which operations are allowed for a LocalAPI client. These checks are performed when localapi.Handler handles a request. Additionally, certain operations (e.g., changing the serve config) requires the connected user to be a local admin. This approach is inherently racey and is subject to TOCTOU issues. We consider it to be more critical on Windows environments, which are inherently multi-user, and therefore we prevent more than one OS user from connecting and utilizing the LocalBackend at the same time. However, the same type of issues is also applicable to other platforms when switching between profiles that have different OperatorUser values in ipn.Prefs. We'd like to allow more than one Windows user to connect, but limit what they can see and do based on their access rights on the device (e.g., an local admin or not) and to the currently active LoginProfile (e.g., owner/operator or not), while preventing TOCTOU issues on Windows and other platforms. Therefore, we'd like to pass an actor from the LocalAPI to the LocalBackend to represent the user performing the operation. The LocalBackend, or the profileManager down the line, will then check the actor's access rights to perform a given operation on the device and against the current (and/or the target) profile. This PR does not change the current permission model in any way, but it introduces the concept of an actor and includes some preparatory work to pass it around. Temporarily, the ipnauth.Actor interface has methods like IsLocalSystem and IsLocalAdmin, which are only relevant to the current permission model. It also lacks methods that will actually be used in the new model. We'll be adding these gradually in the next PRs and removing the deprecated methods and the Permit* flags at the end of the transition. Updates tailscale/corp#18342 Signed-off-by: Nick Khyl <nickk@tailscale.com>