Android14 企业wifi连接

141 阅读3分钟

packages/modules/Wifi/service/java/com/android/server/wifi/WifiConfigManager.java


    /**
     * Add a network or update a network configuration to our database.
     * If the supplied networkId is INVALID_NETWORK_ID, we create a new empty
     * network configuration. Otherwise, the networkId should refer to an existing configuration.
     *
     * @param config provided WifiConfiguration object.
     * @param uid UID of the app requesting the network addition/modification.
     * @param packageName Package name of the app requesting the network addition/modification.
     * @param overrideCreator when this set to true, will overrider the creator to the current
     *                        modifier.
     * @return NetworkUpdateResult object representing status of the update.
     *         WifiConfiguration object representing the existing configuration matching
     *         the new config, or null if none matches.
     */
    private @NonNull Pair<NetworkUpdateResult, WifiConfiguration> addOrUpdateNetworkInternal(
            @NonNull WifiConfiguration config, int uid, @Nullable String packageName,
            boolean overrideCreator) {
        if (mVerboseLoggingEnabled) {
            Log.v(TAG, "Adding/Updating network " + config.getPrintableSsid());
        }
        WifiConfiguration newInternalConfig = null;

        long supportedFeatures = mWifiInjector.getActiveModeWarden()
                .getPrimaryClientModeManager().getSupportedFeatures();

        // First check if we already have a network with the provided network id or configKey.
        WifiConfiguration existingInternalConfig = getInternalConfiguredNetwork(config);
        // No existing network found. So, potentially a network add.
        if (existingInternalConfig == null) {
            if (!WifiConfigurationUtil.validate(config, supportedFeatures,
                    WifiConfigurationUtil.VALIDATE_FOR_ADD)) {
                Log.e(TAG, "Cannot add network with invalid config");
                return new Pair<>(
                        new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID,
                                STATUS_INVALID_CONFIGURATION),
                        existingInternalConfig);
            }
            newInternalConfig =
                    createNewInternalWifiConfigurationFromExternal(config, uid, packageName);
            // Since the original config provided may have had an empty
            // {@link WifiConfiguration#allowedKeyMgmt} field, check again if we already have a
            // network with the the same configkey.
            existingInternalConfig =
                    getInternalConfiguredNetwork(newInternalConfig.getProfileKey());
        }
        // Existing network found. So, a network update.
        if (existingInternalConfig != null) {
            if (!WifiConfigurationUtil.validate(
                    config, supportedFeatures, WifiConfigurationUtil.VALIDATE_FOR_UPDATE)) {
                Log.e(TAG, "Cannot update network with invalid config");
                return new Pair<>(
                        new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID,
                                STATUS_INVALID_CONFIGURATION),
                        existingInternalConfig);
            }
            // Check for the app's permission before we let it update this network.
            if (!canModifyNetwork(existingInternalConfig, uid, packageName)) {
                Log.e(TAG, "UID " + uid + " does not have permission to update configuration "
                        + config.getProfileKey());
                return new Pair<>(
                        new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID,
                                STATUS_NO_PERMISSION_MODIFY_CONFIG),
                        existingInternalConfig);
            }
            if (mWifiPermissionsUtil.checkNetworkSettingsPermission(uid)
                    && !config.isPasspoint()) {
                logUserActionEvents(existingInternalConfig, config);
            }
            newInternalConfig =
                    updateExistingInternalWifiConfigurationFromExternal(
                            existingInternalConfig, config, uid, packageName, overrideCreator);
        }

        if (!WifiConfigurationUtil.addUpgradableSecurityTypeIfNecessary(newInternalConfig)) {
            return new Pair<>(
                    new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID),
                    existingInternalConfig);
        }

        // Only add networks with proxy settings if the user has permission to
        if (WifiConfigurationUtil.hasProxyChanged(existingInternalConfig, newInternalConfig)
                && !canModifyProxySettings(uid, packageName)) {
            Log.e(TAG, "UID " + uid + " does not have permission to modify proxy Settings "
                    + config.getProfileKey() + ". Must have NETWORK_SETTINGS,"
                    + " or be device or profile owner.");
            return new Pair<>(
                    new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID),
                    existingInternalConfig);
        }

        // Only allow changes in Repeater Enabled flag if the user has permission to
        if (WifiConfigurationUtil.hasRepeaterEnabledChanged(
                existingInternalConfig, newInternalConfig)
                && !mWifiPermissionsUtil.checkNetworkSettingsPermission(uid)
                && !mWifiPermissionsUtil.checkConfigOverridePermission(uid)) {
            Log.e(TAG, "UID " + uid
                    + " does not have permission to modify Repeater Enabled Settings "
                    + " , or add a network with Repeater Enabled set to true "
                    + config.getProfileKey() + ". Must have NETWORK_SETTINGS.");
            return new Pair<>(
                    new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID),
                    existingInternalConfig);
        }

        if (WifiConfigurationUtil.hasMacRandomizationSettingsChanged(existingInternalConfig,
                newInternalConfig) && !mWifiPermissionsUtil.checkNetworkSettingsPermission(uid)
                && !mWifiPermissionsUtil.checkNetworkSetupWizardPermission(uid)
                && !mWifiPermissionsUtil.checkConfigOverridePermission(uid)
                && !(newInternalConfig.isPasspoint() && uid == newInternalConfig.creatorUid)
                && !config.fromWifiNetworkSuggestion
                && !mWifiPermissionsUtil.isDeviceInDemoMode(mContext)
                && !(mWifiPermissionsUtil.isAdmin(uid, packageName)
                && uid == newInternalConfig.creatorUid)) {
            Log.e(TAG, "UID " + uid + " does not have permission to modify MAC randomization "
                    + "Settings " + config.getProfileKey() + ". Must have "
                    + "NETWORK_SETTINGS or NETWORK_SETUP_WIZARD or be in Demo Mode "
                    + "or be the creator adding or updating a passpoint network "
                    + "or be an admin updating their own network.");
            return new Pair<>(
                    new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID),
                    existingInternalConfig);
        }

        if (config.isEnterprise()
                && config.enterpriseConfig.isEapMethodServerCertUsed()
                && !config.enterpriseConfig.isMandatoryParameterSetForServerCertValidation()
                && !config.enterpriseConfig.isTrustOnFirstUseEnabled()) {
            boolean isSettingsOrSuw = mContext.checkPermission(Manifest.permission.NETWORK_SETTINGS,
                    -1 /* pid */, uid) == PERMISSION_GRANTED
                    || mContext.checkPermission(Manifest.permission.NETWORK_SETUP_WIZARD,
                    -1 /* pid */, uid) == PERMISSION_GRANTED;
            if (!(mWifiInjector.getWifiGlobals().isInsecureEnterpriseConfigurationAllowed()
                    && isSettingsOrSuw)) {
                Log.e(TAG, "Enterprise network configuration is missing either a Root CA "
                        + "or a domain name");
                return new Pair<>(
                        new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID,
                                STATUS_INVALID_CONFIGURATION_ENTERPRISE),
                        existingInternalConfig);
            }
            Log.w(TAG, "Insecure Enterprise network " + config.SSID
                    + " configured by Settings/SUW");

            // Implicit user approval, when creating an insecure connection which is allowed
            // in the configuration of the device
            newInternalConfig.enterpriseConfig.setUserApproveNoCaCert(true);
        }

        // Update the keys for saved enterprise networks. For Passpoint, the certificates
        // and keys are installed at the time the provider is installed. For suggestion enterprise
        // network the certificates and keys are installed at the time the suggestion is added
        if (!config.isPasspoint() && !config.fromWifiNetworkSuggestion && config.isEnterprise()) {
            if (!(mWifiKeyStore.updateNetworkKeys(newInternalConfig, existingInternalConfig))) {
                return new Pair<>(
                        new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID),
                        existingInternalConfig);
            }
        }

        // Validate an Enterprise network with Trust On First Use.
        if (config.isEnterprise() && config.enterpriseConfig.isTrustOnFirstUseEnabled()) {
            if ((supportedFeatures & WIFI_FEATURE_TRUST_ON_FIRST_USE) == 0) {
                Log.e(TAG, "Trust On First Use could not be set "
                        + "when Trust On First Use is not supported.");
                return new Pair<>(
                        new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID),
                        existingInternalConfig);
            }
            if (!config.enterpriseConfig.isEapMethodServerCertUsed()) {
                Log.e(TAG, "Trust On First Use could not be set "
                        + "when the server certificate is not used.");
                return new Pair<>(
                        new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID),
                        existingInternalConfig);
            } else if (config.enterpriseConfig.hasCaCertificate()) {
                Log.e(TAG, "Trust On First Use could not be set "
                        + "when Root CA certificate is set.");
                return new Pair<>(
                        new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID),
                        existingInternalConfig);
            }
        }

        boolean newNetwork = (existingInternalConfig == null);
        // This is needed to inform IpClient about any IP configuration changes.
        boolean hasIpChanged =
                newNetwork || WifiConfigurationUtil.hasIpChanged(
                        existingInternalConfig, newInternalConfig);
        boolean hasProxyChanged =
                newNetwork || WifiConfigurationUtil.hasProxyChanged(
                        existingInternalConfig, newInternalConfig);
        // Reset the |hasEverConnected| flag if the credential parameters changed in this update.
        boolean hasCredentialChanged =
                newNetwork || WifiConfigurationUtil.hasCredentialChanged(
                        existingInternalConfig, newInternalConfig);
        if (hasCredentialChanged) {
            newInternalConfig.getNetworkSelectionStatus().setHasEverConnected(false);
            newInternalConfig.setHasPreSharedKeyChanged(true);
            Log.i(TAG, "Credential changed for netId=" + newInternalConfig.networkId);
        }

        // Add it to our internal map. This will replace any existing network configuration for
        // updates.
        try {
            if (null != existingInternalConfig) {
                mConfiguredNetworks.remove(existingInternalConfig.networkId);
            }
            mConfiguredNetworks.put(newInternalConfig);
        } catch (IllegalArgumentException e) {
            Log.e(TAG, "Failed to add network to config map", e);
            return new Pair<>(
                    new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID),
                    existingInternalConfig);
        }
        if (removeExcessNetworks(uid, packageName)) {
            if (mConfiguredNetworks.getForAllUsers(newInternalConfig.networkId) == null) {
                Log.e(TAG, "Cannot add network because number of configured networks is maxed.");
                return new Pair<>(
                        new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID),
                        existingInternalConfig);
            }
        }

        // Only re-enable network: 1. add or update user saved network; 2. add or update a user
        // saved passpoint network framework consider it is a new network.
        if (!newInternalConfig.fromWifiNetworkSuggestion
                && (!newInternalConfig.isPasspoint() || newNetwork)) {
            userEnabledNetwork(newInternalConfig.networkId);
        }

        // Stage the backup of the SettingsProvider package which backs this up.
        mBackupManagerProxy.notifyDataChanged();

        NetworkUpdateResult result = new NetworkUpdateResult(
                newInternalConfig.networkId,
                STATUS_SUCCESS,
                hasIpChanged,
                hasProxyChanged,
                hasCredentialChanged,
                newNetwork);

        localLog("addOrUpdateNetworkInternal: added/updated config."
                + " netId=" + newInternalConfig.networkId
                + " configKey=" + newInternalConfig.getProfileKey()
                + " uid=" + Integer.toString(newInternalConfig.creatorUid)
                + " name=" + newInternalConfig.creatorName);
        return new Pair<>(result, existingInternalConfig);
    }

packages/modules/Wifi/service/ServiceWifiResources/res/values/config.xml

<!-- Whether to allow Settings or SUW to create insecure Enterprise networks where server

         certificate is not validated, by not specifying a Root CA certificate and/or server domain

         name. It is STRONGLY RECOMMENDED to be set to false -->

    <bool translatable="false" name="config_wifiAllowInsecureEnterpriseConfigurationsForSettingsAndSUW">false</bool>