| OLD | NEW |
| (Empty) |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 /** | |
| 6 * @fileoverview This file has two parts: | |
| 7 * | |
| 8 * 1. Typedefs for network properties. Note: These 'types' define a subset of | |
| 9 * ONC properties in the ONC data dictionary. The first letter is capitalized to | |
| 10 * match the ONC spec and avoid an extra layer of translation. | |
| 11 * See components/onc/docs/onc_spec.html for the complete spec. | |
| 12 * TODO(stevenjb): Replace with chrome.networkingPrivate.NetworkStateProperties | |
| 13 * once that is fully defined. | |
| 14 * | |
| 15 * 2. Helper functions to facilitate extracting and setting ONC properties. | |
| 16 */ | |
| 17 | |
| 18 var CrOnc = {}; | |
| 19 | |
| 20 /** @typedef {chrome.networkingPrivate.NetworkStateProperties} */ | |
| 21 CrOnc.NetworkStateProperties; | |
| 22 | |
| 23 /** @typedef {chrome.networkingPrivate.ManagedProperties} */ | |
| 24 CrOnc.NetworkProperties; | |
| 25 | |
| 26 /** @typedef {string|number|boolean|Object|Array<Object>} */ | |
| 27 CrOnc.NetworkPropertyType; | |
| 28 | |
| 29 /** | |
| 30 * Generic managed property type. This should match any of the basic managed | |
| 31 * types in chrome.networkingPrivate, e.g. networkingPrivate.ManagedBoolean. | |
| 32 * @typedef {{ | |
| 33 * Active: (!CrOnc.NetworkPropertyType|undefined), | |
| 34 * Effective: (string|undefined), | |
| 35 * UserPolicy: (!CrOnc.NetworkPropertyType|undefined), | |
| 36 * DevicePolicy: (!CrOnc.NetworkPropertyType|undefined), | |
| 37 * UserSetting: (!CrOnc.NetworkPropertyType|undefined), | |
| 38 * SharedSetting: (!CrOnc.NetworkPropertyType|undefined), | |
| 39 * UserEditable: (boolean|undefined), | |
| 40 * DeviceEditable: (boolean|undefined) | |
| 41 * }} | |
| 42 */ | |
| 43 CrOnc.ManagedProperty; | |
| 44 | |
| 45 /** @typedef {chrome.networkingPrivate.SIMLockStatus} */ | |
| 46 CrOnc.SIMLockStatus; | |
| 47 | |
| 48 /** @typedef {chrome.networkingPrivate.APNProperties} */ | |
| 49 CrOnc.APNProperties; | |
| 50 | |
| 51 /** @typedef {chrome.networkingPrivate.CellularSimState} */ | |
| 52 CrOnc.CellularSimState; | |
| 53 | |
| 54 /** @typedef {chrome.networkingPrivate.IPConfigProperties} */ | |
| 55 CrOnc.IPConfigProperties; | |
| 56 | |
| 57 /** @typedef {chrome.networkingPrivate.ManualProxySettings} */ | |
| 58 CrOnc.ManualProxySettings; | |
| 59 | |
| 60 /** @typedef {chrome.networkingPrivate.ProxyLocation} */ | |
| 61 CrOnc.ProxyLocation; | |
| 62 | |
| 63 /** @typedef {chrome.networkingPrivate.ProxySettings} */ | |
| 64 CrOnc.ProxySettings; | |
| 65 | |
| 66 // Modified version of IPConfigProperties to store RoutingPrefix as a | |
| 67 // human-readable string instead of as a number. | |
| 68 /** | |
| 69 * @typedef {{ | |
| 70 * Gateway: (string|undefined), | |
| 71 * IPAddress: (string|undefined), | |
| 72 * NameServers: (!Array<string>|undefined), | |
| 73 * RoutingPrefix: (string|undefined), | |
| 74 * Type: (string|undefined), | |
| 75 * WebProxyAutoDiscoveryUrl: (string|undefined) | |
| 76 * }} | |
| 77 */ | |
| 78 CrOnc.IPConfigUIProperties; | |
| 79 | |
| 80 /** @typedef {chrome.networkingPrivate.PaymentPortal} */ | |
| 81 CrOnc.PaymentPortal; | |
| 82 | |
| 83 CrOnc.ActivationState = chrome.networkingPrivate.ActivationStateType; | |
| 84 CrOnc.ConnectionState = chrome.networkingPrivate.ConnectionStateType; | |
| 85 CrOnc.IPConfigType = chrome.networkingPrivate.IPConfigType; | |
| 86 CrOnc.ProxySettingsType = chrome.networkingPrivate.ProxySettingsType; | |
| 87 CrOnc.Type = chrome.networkingPrivate.NetworkType; | |
| 88 | |
| 89 /** @enum {string} */ | |
| 90 CrOnc.IPType = { | |
| 91 IPV4: 'IPv4', | |
| 92 IPV6: 'IPv6', | |
| 93 }; | |
| 94 | |
| 95 /** @enum {string} */ | |
| 96 CrOnc.LockType = { | |
| 97 NONE: '', | |
| 98 PIN: 'sim-pin', | |
| 99 PUK: 'sim-puk', | |
| 100 }; | |
| 101 | |
| 102 /** @enum {string} */ | |
| 103 CrOnc.NetworkTechnology = { | |
| 104 CDMA1XRTT: 'CDMA1XRTT', | |
| 105 EDGE: 'EDGE', | |
| 106 EVDO: 'EVDO', | |
| 107 GPRS: 'GPRS', | |
| 108 GSM: 'GSM', | |
| 109 HSPA: 'HSPA', | |
| 110 HSPA_PLUS: 'HSPAPlus', | |
| 111 LTE: 'LTE', | |
| 112 LTE_ADVANCED: 'LTEAdvanced', | |
| 113 UMTS: 'UMTS', | |
| 114 UNKNOWN: 'Unknown', | |
| 115 }; | |
| 116 | |
| 117 /** @enum {string} */ | |
| 118 CrOnc.RoamingState = { | |
| 119 HOME: 'Home', | |
| 120 REQUIRED: 'Required', | |
| 121 ROAMING: 'Roaming', | |
| 122 UNKNOWN: 'Unknown', | |
| 123 }; | |
| 124 | |
| 125 /** @enum {string} */ | |
| 126 CrOnc.Security = { | |
| 127 NONE: 'None', | |
| 128 WEP_8021X: 'WEP-8021X', | |
| 129 WEP_PSK: 'WEP-PSK', | |
| 130 WPA_EAP: 'WPA-EAP', | |
| 131 WPA_PSK: 'WPA-PSK', | |
| 132 }; | |
| 133 | |
| 134 /** @enum {string} */ | |
| 135 CrOnc.Source = { | |
| 136 NONE: 'None', | |
| 137 DEVICE: 'Device', | |
| 138 DEVICE_POLICY: 'DevicePolicy', | |
| 139 USER: 'User', | |
| 140 USER_POLICY: 'UserPolicy', | |
| 141 }; | |
| 142 | |
| 143 /** | |
| 144 * Helper function to retrieve the active ONC property value from a managed | |
| 145 * dictionary. | |
| 146 * @param {!CrOnc.ManagedProperty|undefined} property The managed dictionary | |
| 147 * for the property if it exists or undefined. | |
| 148 * @return {!CrOnc.NetworkPropertyType|undefined} The active property value | |
| 149 * if it exists, otherwise undefined. | |
| 150 */ | |
| 151 CrOnc.getActiveValue = function(property) { | |
| 152 if (property == undefined) | |
| 153 return undefined; | |
| 154 | |
| 155 if (typeof property != 'object') { | |
| 156 console.error('getActiveValue called on non object: ' + | |
| 157 JSON.stringify(property)); | |
| 158 return undefined; | |
| 159 } | |
| 160 | |
| 161 // Return the Active value if it exists. | |
| 162 if ('Active' in property) | |
| 163 return property['Active']; | |
| 164 | |
| 165 // If no Active value is defined, return the effective value. | |
| 166 if ('Effective' in property) { | |
| 167 var effective = property.Effective; | |
| 168 if (effective in property) | |
| 169 return property[effective]; | |
| 170 } | |
| 171 | |
| 172 console.error('getActiveValue called on invalid ONC object: ' + | |
| 173 JSON.stringify(property)); | |
| 174 return undefined; | |
| 175 }; | |
| 176 | |
| 177 /** | |
| 178 * Converts a managed ONC dictionary into an unmanaged dictionary (i.e. a | |
| 179 * dictionary of active values). | |
| 180 * NOTE: This is not intended to be used with dictionaries that contain | |
| 181 * nested dictionaries. This will fail and return undefined in that case. | |
| 182 * @param {!Object|undefined} properties A managed ONC dictionary | |
| 183 * @return {!Object|undefined} An unmanaged version of |properties|. | |
| 184 */ | |
| 185 CrOnc.getSimpleActiveProperties = function(properties) { | |
| 186 'use strict'; | |
| 187 if (!properties) | |
| 188 return undefined; | |
| 189 var result = {}; | |
| 190 var keys = Object.keys(properties); | |
| 191 for (let k of keys) { | |
| 192 var prop = CrOnc.getActiveValue(properties[k]); | |
| 193 if (prop == undefined) { | |
| 194 console.error('getSimpleActiveProperties called on invalid ONC object:', | |
| 195 JSON.stringify(properties)); | |
| 196 return undefined; | |
| 197 } | |
| 198 result[k] = prop; | |
| 199 } | |
| 200 return result; | |
| 201 }; | |
| 202 | |
| 203 /** | |
| 204 * Returns an IPConfigProperties object for |type|. For IPV4, these will be the | |
| 205 * static properties if IPAddressConfigType is Static and StaticIPConfig is set. | |
| 206 * @param {!CrOnc.NetworkProperties|undefined} properties The ONC properties. | |
| 207 * @param {!CrOnc.IPType} type The IP Config type. | |
| 208 * @return {CrOnc.IPConfigProperties|undefined} The IP Config object, or | |
| 209 * undefined if no properties for |type| are available. | |
| 210 */ | |
| 211 CrOnc.getIPConfigForType = function(properties, type) { | |
| 212 'use strict'; | |
| 213 /** @type {!CrOnc.IPConfigProperties|undefined} */ var ipConfig = undefined; | |
| 214 var ipConfigs = properties.IPConfigs; | |
| 215 if (ipConfigs) { | |
| 216 for (let i = 0; i < ipConfigs.length; ++i) { | |
| 217 ipConfig = ipConfigs[i]; | |
| 218 if (ipConfig.Type == type) | |
| 219 break; | |
| 220 } | |
| 221 } | |
| 222 if (type != CrOnc.IPType.IPV4) | |
| 223 return ipConfig; | |
| 224 | |
| 225 var staticIpConfig = | |
| 226 /** @type {!CrOnc.IPConfigProperties|undefined} */( | |
| 227 CrOnc.getSimpleActiveProperties(properties.StaticIPConfig)); | |
| 228 if (!staticIpConfig) | |
| 229 return ipConfig; | |
| 230 | |
| 231 // If there is no entry in IPConfigs for |type|, return the static config. | |
| 232 if (!ipConfig) | |
| 233 return staticIpConfig; | |
| 234 | |
| 235 // Otherwise, merge the appropriate static values into the result. | |
| 236 if (staticIpConfig.IPAddress && | |
| 237 CrOnc.getActiveValue(properties.IPAddressConfigType) == 'Static') { | |
| 238 ipConfig.Gateway = staticIpConfig.Gateway; | |
| 239 ipConfig.IPAddress = staticIpConfig.IPAddress; | |
| 240 ipConfig.RoutingPrefix = staticIpConfig.RoutingPrefix; | |
| 241 ipConfig.Type = staticIpConfig.Type; | |
| 242 } | |
| 243 if (staticIpConfig.NameServers && | |
| 244 CrOnc.getActiveValue(properties.NameServersConfigType) == 'Static') { | |
| 245 ipConfig.NameServers = staticIpConfig.NameServers; | |
| 246 } | |
| 247 return ipConfig; | |
| 248 }; | |
| 249 | |
| 250 /** | |
| 251 * Gets the SignalStrength value from |properties| based on properties.Type. | |
| 252 * @param {!CrOnc.NetworkProperties|!CrOnc.NetworkStateProperties|undefined} | |
| 253 * properties The ONC network properties or state properties. | |
| 254 * @return {number} The signal strength value if it exists or 0. | |
| 255 */ | |
| 256 CrOnc.getSignalStrength = function(properties) { | |
| 257 var type = properties.Type; | |
| 258 if (type == CrOnc.Type.CELLULAR && properties.Cellular) | |
| 259 return properties.Cellular.SignalStrength || 0; | |
| 260 if (type == CrOnc.Type.WI_FI && properties.WiFi) | |
| 261 return properties.WiFi.SignalStrength || 0; | |
| 262 if (type == CrOnc.Type.WI_MAX && properties.WiMAX) | |
| 263 return properties.WiMAX.SignalStrength || 0; | |
| 264 return 0; | |
| 265 } | |
| 266 | |
| 267 /** | |
| 268 * Gets the Managed AutoConnect dictionary from |properties| based on | |
| 269 * properties.Type. | |
| 270 * @param {!CrOnc.NetworkProperties|undefined} | |
| 271 * properties The ONC network properties or state properties. | |
| 272 * @return {!chrome.networkingPrivate.ManagedBoolean|undefined} The AutoConnect | |
| 273 * managed dictionary or undefined. | |
| 274 */ | |
| 275 CrOnc.getManagedAutoConnect = function(properties) { | |
| 276 var type = properties.Type; | |
| 277 if (type == CrOnc.Type.CELLULAR && properties.Cellular) | |
| 278 return properties.Cellular.AutoConnect; | |
| 279 if (type == CrOnc.Type.VPN && properties.VPN) | |
| 280 return properties.VPN.AutoConnect; | |
| 281 if (type == CrOnc.Type.WI_FI && properties.WiFi) | |
| 282 return properties.WiFi.AutoConnect; | |
| 283 if (type == CrOnc.Type.WI_MAX && properties.WiMAX) | |
| 284 return properties.WiMAX.AutoConnect; | |
| 285 return undefined; | |
| 286 } | |
| 287 | |
| 288 /** | |
| 289 * Gets the AutoConnect value from |properties| based on properties.Type. | |
| 290 * @param {!CrOnc.NetworkProperties|undefined} | |
| 291 * properties The ONC network properties or state properties. | |
| 292 * @return {boolean} The AutoConnect value if it exists or false. | |
| 293 */ | |
| 294 CrOnc.getAutoConnect = function(properties) { | |
| 295 var autoconnect = CrOnc.getManagedAutoConnect(properties); | |
| 296 return !!CrOnc.getActiveValue(autoconnect); | |
| 297 } | |
| 298 | |
| 299 /** | |
| 300 * @param {!CrOnc.NetworkProperties|!CrOnc.NetworkStateProperties|undefined} | |
| 301 * properties The ONC network properties or state properties. | |
| 302 * @return {boolean} True if |properties| is a Cellular network with a | |
| 303 * locked SIM. | |
| 304 */ | |
| 305 CrOnc.isSimLocked = function(properties) { | |
| 306 if (!properties.Cellular) | |
| 307 return false; | |
| 308 var simLockStatus = properties.Cellular.SIMLockStatus; | |
| 309 if (simLockStatus == undefined) | |
| 310 return false; | |
| 311 return simLockStatus.LockType == CrOnc.LockType.PIN || | |
| 312 simLockStatus.LockType == CrOnc.LockType.PUK; | |
| 313 }; | |
| 314 | |
| 315 /** | |
| 316 * Modifies |config| to include the correct set of properties for configuring | |
| 317 * a network IP Address and NameServer configuration for |state|. Existing | |
| 318 * properties in |config| will be preserved unless invalid. | |
| 319 * @param {!chrome.networkingPrivate.NetworkConfigProperties} config A partial | |
| 320 * ONC configuration. | |
| 321 * @param {CrOnc.NetworkProperties|undefined} properties The ONC properties. | |
| 322 */ | |
| 323 CrOnc.setValidStaticIPConfig = function(config, properties) { | |
| 324 if (!config.IPAddressConfigType) { | |
| 325 var ipConfigType = /** @type {chrome.networkingPrivate.IPConfigType} */( | |
| 326 CrOnc.getActiveValue(properties.IPAddressConfigType)); | |
| 327 config.IPAddressConfigType = ipConfigType || CrOnc.IPConfigType.DHCP; | |
| 328 } | |
| 329 if (!config.NameServersConfigType) { | |
| 330 var nsConfigType = /** @type {chrome.networkingPrivate.IPConfigType} */( | |
| 331 CrOnc.getActiveValue(properties.NameServersConfigType)); | |
| 332 config.NameServersConfigType = nsConfigType || CrOnc.IPConfigType.DHCP; | |
| 333 } | |
| 334 if (config.IPAddressConfigType != CrOnc.IPConfigType.STATIC && | |
| 335 config.NameServersConfigType != CrOnc.IPConfigType.STATIC) { | |
| 336 if (config.hasOwnProperty('StaticIPConfig')) | |
| 337 delete config.StaticIPConfig; | |
| 338 return; | |
| 339 } | |
| 340 | |
| 341 if (!config.hasOwnProperty('StaticIPConfig')) { | |
| 342 config.StaticIPConfig = | |
| 343 /** @type {chrome.networkingPrivate.IPConfigProperties} */({}); | |
| 344 } | |
| 345 var staticIP = config.StaticIPConfig; | |
| 346 var stateIPConfig = CrOnc.getIPConfigForType(properties, CrOnc.IPType.IPV4); | |
| 347 if (config.IPAddressConfigType == 'Static') { | |
| 348 staticIP.Gateway = staticIP.Gateway || stateIPConfig.Gateway || ''; | |
| 349 staticIP.IPAddress = staticIP.IPAddress || stateIPConfig.IPAddress || ''; | |
| 350 staticIP.RoutingPrefix = | |
| 351 staticIP.RoutingPrefix || stateIPConfig.RoutingPrefix || 0; | |
| 352 staticIP.Type = staticIP.Type || stateIPConfig.Type || CrOnc.IPType.IPV4; | |
| 353 } | |
| 354 if (config.NameServersConfigType == 'Static') { | |
| 355 staticIP.NameServers = | |
| 356 staticIP.NameServers || stateIPConfig.NameServers || []; | |
| 357 } | |
| 358 }; | |
| 359 | |
| 360 | |
| 361 /** | |
| 362 * Sets the value of a property in an ONC dictionary. | |
| 363 * @param {!chrome.networkingPrivate.NetworkConfigProperties} properties | |
| 364 * The ONC property dictionary to modify. | |
| 365 * @param {string} key The property key which may be nested, e.g. 'Foo.Bar'. | |
| 366 * @param {!CrOnc.NetworkPropertyType} value The property value to set. | |
| 367 */ | |
| 368 CrOnc.setProperty = function(properties, key, value) { | |
| 369 while (true) { | |
| 370 var index = key.indexOf('.'); | |
| 371 if (index < 0) | |
| 372 break; | |
| 373 var keyComponent = key.substr(0, index); | |
| 374 if (!properties.hasOwnProperty(keyComponent)) | |
| 375 properties[keyComponent] = {}; | |
| 376 properties = properties[keyComponent]; | |
| 377 key = key.substr(index + 1); | |
| 378 } | |
| 379 properties[key] = value; | |
| 380 }; | |
| 381 | |
| 382 /** | |
| 383 * Calls setProperty with '{state.Type}.key', e.g. WiFi.AutoConnect. | |
| 384 * @param {!chrome.networkingPrivate.NetworkConfigProperties} properties The | |
| 385 * ONC properties to set. properties.Type must be set already. | |
| 386 * @param {string} key The type property key, e.g. 'AutoConnect'. | |
| 387 * @param {!CrOnc.NetworkPropertyType} value The property value to set. | |
| 388 */ | |
| 389 CrOnc.setTypeProperty = function(properties, key, value) { | |
| 390 if (properties.Type == undefined) { | |
| 391 console.error('Type not defined in properties: ', properties); | |
| 392 return; | |
| 393 } | |
| 394 var typeKey = properties.Type + '.' + key; | |
| 395 CrOnc.setProperty(properties, typeKey, value); | |
| 396 }; | |
| 397 | |
| 398 /** | |
| 399 * Returns the routing prefix as a string for a given prefix length. | |
| 400 * @param {number} prefixLength The ONC routing prefix length. | |
| 401 * @return {string} The corresponding netmask. | |
| 402 */ | |
| 403 CrOnc.getRoutingPrefixAsNetmask = function(prefixLength) { | |
| 404 'use strict'; | |
| 405 // Return the empty string for invalid inputs. | |
| 406 if (prefixLength < 0 || prefixLength > 32) | |
| 407 return ''; | |
| 408 var netmask = ''; | |
| 409 for (let i = 0; i < 4; ++i) { | |
| 410 let remainder = 8; | |
| 411 if (prefixLength >= 8) { | |
| 412 prefixLength -= 8; | |
| 413 } else { | |
| 414 remainder = prefixLength; | |
| 415 prefixLength = 0; | |
| 416 } | |
| 417 if (i > 0) | |
| 418 netmask += '.'; | |
| 419 let value = 0; | |
| 420 if (remainder != 0) | |
| 421 value = ((2 << (remainder - 1)) - 1) << (8 - remainder); | |
| 422 netmask += value.toString(); | |
| 423 } | |
| 424 return netmask; | |
| 425 }; | |
| 426 | |
| 427 /** | |
| 428 * Returns the routing prefix length as a number from the netmask string. | |
| 429 * @param {string} netmask The netmask string, e.g. 255.255.255.0. | |
| 430 * @return {number} The corresponding netmask or -1 if invalid. | |
| 431 */ | |
| 432 CrOnc.getRoutingPrefixAsLength = function(netmask) { | |
| 433 'use strict'; | |
| 434 var prefixLength = 0; | |
| 435 var tokens = netmask.split('.'); | |
| 436 if (tokens.length != 4) | |
| 437 return -1; | |
| 438 for (let i = 0; i < tokens.length; ++i) { | |
| 439 let token = tokens[i]; | |
| 440 // If we already found the last mask and the current one is not | |
| 441 // '0' then the netmask is invalid. For example, 255.224.255.0 | |
| 442 if (prefixLength / 8 != i) { | |
| 443 if (token != '0') | |
| 444 return -1; | |
| 445 } else if (token == '255') { | |
| 446 prefixLength += 8; | |
| 447 } else if (token == '254') { | |
| 448 prefixLength += 7; | |
| 449 } else if (token == '252') { | |
| 450 prefixLength += 6; | |
| 451 } else if (token == '248') { | |
| 452 prefixLength += 5; | |
| 453 } else if (token == '240') { | |
| 454 prefixLength += 4; | |
| 455 } else if (token == '224') { | |
| 456 prefixLength += 3; | |
| 457 } else if (token == '192') { | |
| 458 prefixLength += 2; | |
| 459 } else if (token == '128') { | |
| 460 prefixLength += 1; | |
| 461 } else if (token == '0') { | |
| 462 prefixLength += 0; | |
| 463 } else { | |
| 464 // mask is not a valid number. | |
| 465 return -1; | |
| 466 } | |
| 467 } | |
| 468 return prefixLength; | |
| 469 }; | |
| OLD | NEW |