UNPKG

@carboncollins/mobileconfig

Version:

Create and sign iOS mobileconfig configuration files

395 lines (358 loc) 20.3 kB
'use strict'; import MobileConfigPayload from './payload.mjs'; import { toSafeString, toSafeBoolean, toSafeData, toSafeInteger, toSafeArray, deleteEmptyKeys, hasRequiredValues } from '../safe.mjs'; const requiredValues = []; function toSafeQoSMarkingPolicy(value = {}) { if (value === undefined || value === null || typeof(value) !== typeof({}) || Object.keys(value) === 0) { return null; } else { const qosObj = { QoSMarkingWhitelistedAppIdentifiers: ((value !== undefined && value !== null && Array.isArray(value.qosMarkingWhitelistedAppIdentifiers)) ? toSafeArray(value.qosMarkingWhitelistedAppIdentifiers.map(id => toSafeString(id))) : null), QoSMarkingAppleAudioVideoCalls: toSafeBoolean(value.qosMarkingAppleAudioVideoCalls), QoSMarkingEnabled: toSafeBoolean(value.qosMarkingEnabled) }; return deleteEmptyKeys(qosObj); } } function toSafeEAPClientConfiguration(value = {}) { if (value === undefined || value === null || typeof(value) !== typeof({}) || Object.keys(value) === 0) { return null; } else { const eapObj = { Username: toSafeString(value.username), AcceptEAPTypes: ((value !== undefined && value !== null && Array.isArray(value.acceptEAPTypes)) ? toSafeArray(value.acceptEAPTypes.map(type => toSafeInteger(type))) : null), UserPassword: toSafeString(value.userPassword), OneTimePassword: toSafeBoolean(value.oneTimePassword), PayloadCertificateAnchorUUID: ((value !== undefined && value !== null && Array.isArray(value.certificateAnchorUUID)) ? toSafeArray(value.certificateAnchorUUID.map(uuid => toSafeString(uuid))) : null), TLSTrustedServerNames: ((value !== undefined && value !== null && Array.isArray(value.tlsTrustedServerNames)) ? toSafeArray(value.tlsTrustedServerNames.map(uuid => toSafeString(uuid))) : null), TLSAllowTrustExceptions: toSafeBoolean(value.tlsAllowTrustExceptions), TLSCertificateIsRequired: toSafeBoolean(value.tlsCertificateIsRequired), TLSMinimumVersion: toSafeString(value.tlsMinimumVersion), TLSMaximumVersion: toSafeString(value.tlsMaximumVersion), OuterIdentity: toSafeString(value.outerIdentity), TTLSInnerAuthentication: toSafeString(value.ttlsInnerAuthentication), EAPFASTUsePAC: toSafeBoolean(value.eapFASTUsePAC), EAPFASTProvisionPAC: toSafeBoolean(value.eapFASTProvisionPAC), EAPFASTProvisionPACAnonymously: toSafeBoolean(value.eapFASTProvisionPACAnonymously), EAPSIMNumberOfRANDs: toSafeInteger(value.eapSIMNumberOfRANDs) }; return deleteEmptyKeys(eapObj); } } /** * @class WiFiPayload * @description Structured model data for the WiFi payload * @author CarbonCollins <toastyghost@carboncollins.uk> * @memberof module:@carboncollins/mobileconfig * @extends module:@carboncollins/mobileconfig.MobileConfigPayload */ export default class WiFiPayload extends MobileConfigPayload { /** * @constructor * @description creates an instance of WiFiPayload * @param {Object|module:@carboncollins/mobileconfig.WiFiPayload} [options={}] An object of * options */ constructor(options = {}) { super(Object.assign({}, options, { type: 'com.apple.wifi.managed' })); /** * @member {String} [ssid=null] * @memberof module:@carboncollins/mobileconfig.WiFiPayload * @description SSID of the Wi-Fi network to be used. In iOS 7.0 and later, this is optional * if a `domainName` value is provided */ this.ssid = options.ssid || null; /** * @member {Boolean} [hiddenNetwork=false] * @memberof module:@carboncollins/mobileconfig.WiFiPayload * @description Besides SSID, the device uses information such as broadcast type and encryption * type to differentiate a network. By default (false), it is assumed that all configured * networks are open or broadcast. To specify a hidden network, must be true. */ this.hiddenNetwork = options.hiddenNetwork || false; /** * @member {Boolean} [autoJoin=true] * @memberof module:@carboncollins/mobileconfig.WiFiPayload * @description Optional. Default true. If true, the network is auto-joined. If false, the user * has to tap the network name to join it. Availability: Available in iOS 5.0 and later and in * all versions of macOS. */ this.autoJoin = options.autoJoin || true; /** * @member {Boolean} [isHotspot=false] * @memberof module:@carboncollins/mobileconfig.WiFiPayload * @description Optional. Default false. If true, the network is treated as a hotspot. * Availability: Available in iOS 7.0 and later and in macOS 10.9 and later. */ this.isHotspot = options.isHotspot || false; /** * @member {String} [domainName=null] * @memberof module:@carboncollins/mobileconfig.WiFiPayload * @description Optional. Domain Name used for Wi-Fi Hotspot 2.0 negotiation. This field can be * provided instead of `ssid`. Availability: Available in iOS 7.0 and later and in macOS 10.9 * and later.. */ this.domainName = options.domainName || null; /** * @member {Boolean} [serviceProviderRoamingEnabled=false] * @memberof module:@carboncollins/mobileconfig.WiFiPayload * @description Optional. If true, allows connection to roaming service providers. Defaults to * false. Availability: Available in iOS 7.0 and later and in macOS 10.9 and later. */ this.serviceProviderRoamingEnabled = options.serviceProviderRoamingEnabled || false; /** * @member {String[]} [roamingConsortiumOIs=[]] * @memberof module:@carboncollins/mobileconfig.WiFiPayload * @description Optional. Array of Roaming Consortium Organization Identifiers used for Wi-Fi * Hotspot 2.0 negotiation. Availability: Available in iOS 7.0 and later and in macOS 10.9 and * later.. */ this.roamingConsortiumOIs = options.roamingConsortiumOIs || []; /** * @member {String[]} [naiRealmNames=[]] * @memberof module:@carboncollins/mobileconfig.WiFiPayload * @description Optional. Array of strings. List of Network Access Identifier Realm names used * for Wi-Fi Hotspot 2.0 negotiation. Availability: Available in iOS 7.0 and later and in macOS * 10.9 and later.. */ this.naiRealmNames = options.naiRealmNames || []; /** * @member {String[]} [mccAndMNCs=[]] * @memberof module:@carboncollins/mobileconfig.WiFiPayload * @description Optional. Array of strings. List of Mobile Country Code (MCC)/Mobile Network * Code (MNC) pairs used for Wi-Fi Hotspot 2.0 negotiation. Each string must contain exactly * six digits. Availability: Available in iOS 7.0 and later. This feature is not supported in * macOS. */ this.mccAndMNCs = options.mccAndMNCs || []; /** * @member {String} [displayedOperatorName=null] * @memberof module:@carboncollins/mobileconfig.WiFiPayload * @description The operator name to display when connected to this network. Used only with * Wi-Fi Hotspot 2.0 access points. Availability: Available in iOS 7.0 and later and in macOS * 10.9 and later. */ this.displayedOperatorName = options.displayedOperatorName || null; /** * @member {Boolean} [captiveBypass=false] * @memberof module:@carboncollins/mobileconfig.WiFiPayload * @description Optional. If set to true, Captive Network detection will be bypassed when the * device connects to the network. Defaults to false. Availability: Available in iOS 10.0 and * later. */ this.captiveBypass = options.captiveBypass || false; /** * @member {qosMarkingPolocy} [qosMarkingPolicy={}] * @memberof module:@carboncollins/mobileconfig.WiFiPayload * @description Optional. When this dictionary is not present for a Wi-Fi network, all apps are * whitelisted to use L2 and L3 marking when the Wi-Fi network supports Cisco QoS fast lane. * When present in the Wi-Fi payload, the QoSMarkingPolicy dictionary should contain the list * of apps that are allowed to benefit from L2 and L3 marking. For dictionary keys, see the * table below. Availability: Available in iOS 10.0 and later and in macOS 10.13 and later. */ this.qosMarkingPolicy = options.qosMarkingPolicy || {}; /** * @member {String} [encryptionType=null] * @memberof module:@carboncollins/mobileconfig.WiFiPayload * @description The possible values are `WEP`, `WPA`, `WPA2`, `Any`, and `None`. WPA specifies * WPA only; WPA2 applies to both encryption types. Make sure that these values exactly match * the capabilities of the network access point. If you're unsure about the encryption type, or * would prefer that it apply to all encryption types, use the value Any. Availability: Key * available in iOS 4.0 and later and in all versions of macOS. The None value is available in * iOS 5.0 and later and the WPA2 value is available in iOS 8.0 and later. */ this.encryptionType = options.encryptionType || null; /** * @member {String} [encryptionType=null] * @memberof module:@carboncollins/mobileconfig.WiFiPayload * @description Optional. If the `encryptionType` field is set to WEP, WPA, or ANY, then this * field is used. Note: The absence of a password does not prevent a network from being added * to the list of known networks. The user is eventually prompted to provide the password * when connecting to that network. */ this.password = options.password || null; /** * @member {eapClientConfiguration} [eapClientConfiguration={}] * @memberof module:@carboncollins/mobileconfig.WiFiPayload * @description Optional. If the `encryptionType` field is set to WEP, WPA, or ANY, then this * field is used */ this.eapClientConfiguration = options.eapClientConfiguration || {}; /** * @member {String} [payloadCertificateUUID=null] * @memberof module:@carboncollins/mobileconfig.WiFiPayload * @description Optional. If the `encryptionType` field is set to WEP, WPA, or ANY, then this * field is used. Should be the uuid of the certificate to use. */ this.payloadCertificateUUID = options.payloadCertificateUUID || null; /** * @member {String} [proxyType=null] * @memberof module:@carboncollins/mobileconfig.WiFiPayload * @description Optional. Valid values are `None`, `Manual`, and `Auto`. Availability: * Available in iOS 5.0 and later and on all versions of macOS. */ this.proxyType = options.proxyType || null; /** * @member {String} [proxyServer=null] * @memberof module:@carboncollins/mobileconfig.WiFiPayload * @description The proxy server's network address. */ this.proxyServer = options.proxyServer || null; /** * @member {Number} [proxyServerPort=null] * @memberof module:@carboncollins/mobileconfig.WiFiPayload * @description The proxy server's port. */ this.proxyServerPort = options.proxyServerPort || null; /** * @member {String} [proxyUsername=null] * @memberof module:@carboncollins/mobileconfig.WiFiPayload * @description Optional. The username used to authenticate to the proxy server. */ this.proxyUsername = options.proxyUsername || null; /** * @member {String} [proxyPassword=null] * @memberof module:@carboncollins/mobileconfig.WiFiPayload * @description Optional. The password used to authenticate to the proxy server. */ this.proxyPassword = options.proxyPassword || null; /** * @member {String} [proxyPACURL=null] * @memberof module:@carboncollins/mobileconfig.WiFiPayload * @description Optional. The URL of the PAC file that defines the proxy configuration. */ this.proxyPACURL = options.proxyPACURL || null; /** * @member {Boolean} [proxyPACFallbackAllowed=false] * @memberof module:@carboncollins/mobileconfig.WiFiPayload * @description Optional. If false, prevents the device from connecting directly to the * destination if the PAC file is unreachable. Default is false. Availability: Available * in iOS 7 and later. */ this.proxyPACFallbackAllowed = options.proxyPACFallbackAllowed || null; } /** * @description generates a plist safe js object with all the required information for generating * a mobileconfig profile * @readonly * @memberof module:@carboncollins/mobileconfig.WiFiPayload * @author CarbonCollins <toastyghost@carboncollins.uk> * @returns {Object} a plist object encoded into a js object */ get plistSafeObject() { const plistObj = { SSID_STR: toSafeString(this.ssid), HIDDEN_NETWORK: toSafeBoolean(this.hiddenNetwork), AutoJoin: toSafeBoolean(this.autoJoin), EncryptionType: toSafeString(this.encryptionType), IsHotspot: toSafeBoolean(this.isHotspot), DomainName: toSafeString(this.domainName), ServiceProviderRoamingEnabled: toSafeBoolean(this.serviceProviderRoamingEnabled), RoamingConsortiumOIs: toSafeArray(this.roamingConsortiumOIs.slice(0).map(id => toSafeString(id))), NAIRealmNames: toSafeArray(this.naiRealmNames.slice(0).map(name => toSafeString(name))), MCCAndMNCs: toSafeArray(this.mccAndMNCs.slice(0).map(mccmnc => toSafeString(mccmnc))), DisplayedOperatorName: toSafeString(this.displayedOperatorName), ProxyType: toSafeString(this.proxyType), CaptiveBypass: toSafeBoolean(this.captiveBypass), QoSMarkingPolicy: toSafeQoSMarkingPolicy(this.qosMarkingPolicy), Password: toSafeString(this.password), EAPClientConfiguration: toSafeEAPClientConfiguration(this.eapClientConfiguration), PayloadCertificateUUID: toSafeString(this.payloadCertificateUUID), ProxyServer: toSafeString(this.proxyServer), ProxyServerPort: toSafeInteger(this.proxyServerPort), ProxyUsername: toSafeString(this.proxyUsername), ProxyPassword: toSafeString(this.proxyPassword), ProxyPACURL: toSafeString(this.proxyPACURL), ProxyPACFallbackAllowed: toSafeBoolean(this.proxyPACFallbackAllowed) }; deleteEmptyKeys(plistObj); return (hasRequiredValues(requiredValues, plistObj, 'com.apple.wifi.managed payload')) ? Object.assign({}, super.plistSafeObject, plistObj) : null; } } /** * @typedef {Object} qosMarkingPolocy * @description should contain a list of apps that are aloud to use L3 and L3 marking * * @property {String[]} qosMarkingWhitelistedAppIdentifiers Optional. Array of app bundle * identifiers that will be whitelisted for L2 and L3 marking for traffic sent to the Wi-Fi * network. If the array is not present but the QoSMarkingPolicy key is present (even empty) no app * gets whitelisted. * @property {Boolean} [qosMarkingAppleAudioVideoCalls=false] Optional. Specifies if audio and * video traffic of built-in audio/video services such as FaceTime and Wi-Fi Calling will be * whitelisted for L2 and L3 marking for traffic sent to the Wi-Fi network. Defaults to true. * @property {Boolean} [qosMarkingEnabled=true] Optional. May be used to disable L3 * marking and only use L2 marking for traffic sent to the Wi-Fi network. When this key is false * the system behaves as if Wi-Fi was not associated with a Cisco QoS fast lane network. Defaults * to true. */ /** * @typedef {Object} eapClientConfiguration * @description In addition to the standard encryption types, it is possible to specify an * enterprise profile for a given network via the `eapClientConfiguration` key. If present, its value * is a dictionary with the following keys. * * @property {String} [username=null] Optional. Unless you know the exact user name, this property * won't appear in an imported configuration. Users can enter this information when they * authenticate. * @property {Number[]} [acceptEAPTypes=[]] The following EAP types are accepted: `13 = TLS`, * `17 = LEAP`, `18 = EAP-SIM`, `21 = TTLS`, `23 = EAP-AKA`, `25 = PEAP`, and `43 = EAP-FAST` * @property {String} [userPassword=null] Optional. User password. If not provided, the user may be * prompted during login. * @property {Boolean} [oneTimePassword=false] Optional. If true, the user will be prompted for a * password each time they connect to the network. Defaults to false. * @property {String[]} [certificateAnchorUUID=[]] Optional. Identifies the certificates to be * trusted for this authentication. Each entry must contain the `uuid` of a certificate payload. Use * this key to prevent the device from asking the user if the listed certificates are trusted. * Dynamic trust (the certificate dialogue) is disabled if this property is specified, unless * `tlsAllowTrustExceptions` is also specified with the value true. * @property {String[]} [tlsTrustedServerNames=[]] Optional. This is the list of server certificate * common names that will be accepted. You can use wildcards to specify the name, such as * wpa.*.example.com. If a server presents a certificate that isn't in this list, it won't be * trusted. Used alone or in combination with `certificateAnchorUUID`, the property allows * someone to carefully craft which certificates to trust for the given network, and avoid * dynamically trusted certificates. Dynamic trust (the certificate dialogue) is disabled if this * property is specified, unless `tlsAllowTrustExceptions` is also specified with the value true. * @property {Boolean} [tlsAllowTrustExceptions=true|false] Optional. Allows/disallows a dynamic trust * decision by the user. The dynamic trust is the certificate dialogue that appears when a * certificate isn't trusted. If this is false, the authentication fails if the certificate isn't * already trusted. See `certificateAnchorUUID` and `tlsTrustedNames` above. The default value of * this property is true unless either `certificateAnchorUUID` or `tlsTrustedServerNames` is * supplied, in which case the default value is false. Availability: Deprecated and ignored in * iOS 8.0 and later. * @property {Boolean} [tlsCertificateIsRequired=true|false] Optional. If true, allows for * two-factor authentication for EAP-TTLS, PEAP, or EAP-FAST. If false, allows for zero-factor * authentication for EAP-TLS. The default is true for EAP-TLS, and false for other EAP types. * Availability: Available in iOS 7.0 and later. * @property {String} [tlsMinimumVersion=null] Optional. The minimum TLS version to be used with * EAP authentication. Value may be `1.0`, `1.1`, or `1.2`. If no value is specified, the default * minimum is 1.0. Availability: Available in iOS 11.0 and macOS 10.13 and later. * @property {String} [outerIdentity=null] Optional. This key is only relevant to `TTLS`, `PEAP`, * and `EAP-FAST`. This allows the user to hide his or her identity. The user's actual name appears * only inside the encrypted tunnel. For example, it could be set to "anonymous" or "anon", or * "anon@mycompany.net". It can increase security because an attacker can't see the authenticating * user's name in the clear. * @property {String} [ttlsInnerAuthentication=MSCHAPv2] Optional. Specifies the inner * authentication used by the TTLS module. Possible values are `PAP`, `CHAP`, `MSCHAP`, `MSCHAPv2`, * and `EA`. Defaults to `MSCHAPv2`. * @property {Boolean} [eapFASTUsePAC=false] Optional.If true, the device will use an existing PAC * if it's present. Otherwise, the server must present its identity using a certificate. Defaults * to false. * @property {Boolean} [eapFASTProvisionPAC=false] Optional. Used only if `eapFASTUsePAC` is true. * If set to true, allows PAC provisioning. Defaults to false. This value must be set to true for * EAP-FAST PAC usage to succeed, because there is no other way to provision a PAC. * @property {Boolean} [eapFASTProvisionPACAnonymously=false] Optional. If true, provisions the * device anonymously. Note that there are known man-in-the-middle attacks for anonymous * provisioning. Defaults to false. * @property {Number} [eapSIMNumberOfRANDs=3] Optional. Number of expected RANDs for EAPSIM. Valid * values are `2` and `3`. Defaults to 3. */