You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
122 lines
4.8 KiB
Kotlin
122 lines
4.8 KiB
Kotlin
// Copyright (c) Tailscale Inc & AUTHORS
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
package com.tailscale.ipn.mdm
|
|
|
|
import android.content.RestrictionsManager
|
|
import com.tailscale.ipn.App
|
|
import kotlin.reflect.KVisibility
|
|
import kotlin.reflect.full.declaredMemberProperties
|
|
import kotlin.reflect.full.isSubclassOf
|
|
import kotlin.reflect.jvm.jvmErasure
|
|
|
|
object MDMSettings {
|
|
// The String message used in this NoSuchKeyException must match the value of
|
|
// syspolicy.ErrNoSuchKey defined in Go. We compare against its exact text
|
|
// to determine whether the requested policy setting is not configured and
|
|
// an actual syspolicy.ErrNoSuchKey should be returned from syspolicyHandler
|
|
// to the backend.
|
|
class NoSuchKeyException : Exception("no such key")
|
|
|
|
val forceEnabled = BooleanMDMSetting("ForceEnabled", "Force Enabled Connection Toggle")
|
|
|
|
// Handled on the backed
|
|
val exitNodeID = StringMDMSetting("ExitNodeID", "Forced Exit Node: Stable ID")
|
|
|
|
// (jonathan) TODO: Unused but required. There is some funky go string duration parsing required
|
|
// here.
|
|
val keyExpirationNotice = StringMDMSetting("KeyExpirationNotice", "Key Expiration Notice Period")
|
|
|
|
val loginURL = StringMDMSetting("LoginURL", "Custom control server URL")
|
|
|
|
val managedByCaption = StringMDMSetting("ManagedByCaption", "Managed By - Caption")
|
|
|
|
val managedByOrganizationName =
|
|
StringMDMSetting("ManagedByOrganizationName", "Managed By - Organization Name")
|
|
|
|
val managedByURL = StringMDMSetting("ManagedByURL", "Managed By - Support URL")
|
|
|
|
// Handled on the backend
|
|
val tailnet = StringMDMSetting("Tailnet", "Recommended/Required Tailnet Name")
|
|
|
|
val hiddenNetworkDevices =
|
|
StringArrayListMDMSetting("HiddenNetworkDevices", "Hidden Network Device Categories")
|
|
|
|
// Unused on Android
|
|
val allowIncomingConnections =
|
|
AlwaysNeverUserDecidesMDMSetting("AllowIncomingConnections", "Allow Incoming Connections")
|
|
|
|
// Unused on Android
|
|
val detectThirdPartyAppConflicts =
|
|
AlwaysNeverUserDecidesMDMSetting(
|
|
"DetectThirdPartyAppConflicts", "Detect potentially problematic third-party apps")
|
|
|
|
val exitNodeAllowLANAccess =
|
|
AlwaysNeverUserDecidesMDMSetting(
|
|
"ExitNodeAllowLANAccess", "Allow LAN Access when using an exit node")
|
|
|
|
// Handled on the backend
|
|
val postureChecking =
|
|
AlwaysNeverUserDecidesMDMSetting("PostureChecking", "Enable Posture Checking")
|
|
|
|
val useTailscaleDNSSettings =
|
|
AlwaysNeverUserDecidesMDMSetting("UseTailscaleDNSSettings", "Use Tailscale DNS Settings")
|
|
|
|
// Unused on Android
|
|
val useTailscaleSubnets =
|
|
AlwaysNeverUserDecidesMDMSetting("UseTailscaleSubnets", "Use Tailscale Subnets")
|
|
|
|
val exitNodesPicker = ShowHideMDMSetting("ExitNodesPicker", "Exit Nodes Picker")
|
|
|
|
val manageTailnetLock = ShowHideMDMSetting("ManageTailnetLock", "“Manage Tailnet lock” menu item")
|
|
|
|
// Unused on Android
|
|
val resetToDefaults = ShowHideMDMSetting("ResetToDefaults", "“Reset to Defaults” menu item")
|
|
|
|
val runExitNode = ShowHideMDMSetting("RunExitNode", "Run as Exit Node")
|
|
|
|
// Unused on Android
|
|
val testMenu = ShowHideMDMSetting("TestMenu", "Show Debug Menu")
|
|
|
|
// Unused on Android
|
|
val updateMenu = ShowHideMDMSetting("UpdateMenu", "“Update Available” menu item")
|
|
|
|
// (jonathan) TODO: Use this when suggested exit nodes are implemented
|
|
val allowedSuggestedExitNodes =
|
|
StringArrayListMDMSetting("AllowedSuggestedExitNodes", "Allowed Suggested Exit Nodes")
|
|
|
|
// Allows admins to define a list of packages that won't be routed via Tailscale.
|
|
val excludedPackages = StringMDMSetting("ExcludedPackageNames", "Excluded Package Names")
|
|
// Allows admins to define a list of packages that will be routed via Tailscale, letting all other
|
|
// apps skip the VPN tunnel.
|
|
val includedPackages = StringMDMSetting("IncludedPackageNames", "Included Package Names")
|
|
|
|
// Handled on the backend
|
|
val authKey = StringMDMSetting("AuthKey", "Auth Key for login")
|
|
|
|
// Overrides the value provided by os.Hostname() in Go
|
|
val hostname = StringMDMSetting("Hostname", "Device Hostname")
|
|
|
|
// Allows admins to skip the get started intro screen
|
|
val onboardingFlow = ShowHideMDMSetting("OnboardingFlow", "Suppress the intro screen")
|
|
|
|
val allSettings by lazy {
|
|
MDMSettings::class
|
|
.declaredMemberProperties
|
|
.filter {
|
|
it.visibility == KVisibility.PUBLIC &&
|
|
it.returnType.jvmErasure.isSubclassOf(MDMSetting::class)
|
|
}
|
|
.map { it.call(MDMSettings) as MDMSetting<*> }
|
|
}
|
|
|
|
val allSettingsByKey by lazy { allSettings.associateBy { it.key } }
|
|
|
|
fun update(app: App, restrictionsManager: RestrictionsManager?) {
|
|
val bundle = restrictionsManager?.applicationRestrictions
|
|
val preferences = lazy { app.getEncryptedPrefs() }
|
|
allSettings.forEach { it.setFrom(bundle, preferences) }
|
|
app.notifyPolicyChanged()
|
|
}
|
|
}
|