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 |