cordova-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From shaz...@apache.org
Subject ios commit: CB-10048 - clobbering of <access> tags to ATS directives CB-10057 - removing <access> tag does not remove ATS entry
Date Fri, 04 Dec 2015 10:32:09 GMT
Repository: cordova-ios
Updated Branches:
  refs/heads/master f2e056e5f -> 8d4196f77


CB-10048 - clobbering of <access> tags to ATS directives
CB-10057 - removing <access> tag does not remove ATS entry

(this was applied in cordova-lib/src/metadata/ios_parser.js)


Project: http://git-wip-us.apache.org/repos/asf/cordova-ios/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-ios/commit/8d4196f7
Tree: http://git-wip-us.apache.org/repos/asf/cordova-ios/tree/8d4196f7
Diff: http://git-wip-us.apache.org/repos/asf/cordova-ios/diff/8d4196f7

Branch: refs/heads/master
Commit: 8d4196f77cd0eaff8fa802a4d5173d867da90940
Parents: f2e056e
Author: Shazron Abdullah <shazron@apache.org>
Authored: Fri Dec 4 02:32:01 2015 -0800
Committer: Shazron Abdullah <shazron@apache.org>
Committed: Fri Dec 4 02:32:01 2015 -0800

----------------------------------------------------------------------
 bin/templates/scripts/cordova/lib/prepare.js | 190 +++++++++++++---------
 1 file changed, 114 insertions(+), 76 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/8d4196f7/bin/templates/scripts/cordova/lib/prepare.js
----------------------------------------------------------------------
diff --git a/bin/templates/scripts/cordova/lib/prepare.js b/bin/templates/scripts/cordova/lib/prepare.js
index 3d62c98..e5637ed 100644
--- a/bin/templates/scripts/cordova/lib/prepare.js
+++ b/bin/templates/scripts/cordova/lib/prepare.js
@@ -144,10 +144,13 @@ function updateProject(platformConfig, locations) {
     var CFBundleVersion = platformConfig.ios_CFBundleVersion() || default_CFBundleVersion(version);
     infoPlist['CFBundleVersion'] = CFBundleVersion;
 
-    var ats = (infoPlist['NSAppTransportSecurity'] || {});
-    ats = processAccessEntriesAsATS(platformConfig, ats);
-    ats = processAllowNavigationEntriesAsATS(platformConfig, ats);
-    infoPlist['NSAppTransportSecurity'] = ats;
+    // replace Info.plist ATS entries according to <access> and <allow-navigation>
config.xml entries
+    var ats = writeATSEntries(platformConfig);
+    if (Object.keys(ats).length > 0) {
+        infoPlist['NSAppTransportSecurity'] = ats;
+    } else {
+        delete infoPlist['NSAppTransportSecurity'];
+    }
 
     handleOrientationSettings(platformConfig, infoPlist);
 
@@ -368,112 +371,147 @@ function getOrientationValue(platformConfig) {
     return ORIENTATION_DEFAULT;
 }
 
-function processAccessEntriesAsATS(config, ats) {
-    // CB-9569 - Support <access> tag to Application Transport Security (ATS) in iOS
9+
+/*
+    Parses all <access> and <allow-navigation> entries and consolidates duplicates
(for ATS).
+    Returns an object with a Hostname as the key, and the value an object with properties:
+        { 
+            Hostname, // String
+            NSExceptionAllowsInsecureHTTPLoads, // boolean 
+            NSIncludesSubdomains,  // boolean
+            NSExceptionMinimumTLSVersion, // String
+             NSExceptionRequiresForwardSecrecy // boolean 
+        }
+*/
+function processAccessAndAllowNavigationEntries(config) {
     var accesses = config.getAccesses();
-
-    // the default is the wildcard, so if there are no access tags, we add the wildcard in
-    if (accesses.length === 0) {
-        accesses.push({ 'origin' : '*'});
-    }
-
-    if (!ats) {
-        ats = {};
-    }
-
-    accesses.forEach(function(access) {
-        ats = processUrlAsATS(ats, access.origin, access.minimum_tls_version, access.requires_forward_secrecy);
-    });
-
-    return ats;
-}
-
-function processAllowNavigationEntriesAsATS(config, ats) {
-    // CB-9569 - Support <allow-navigation> tag to Application Transport Security (ATS)
in iOS 9+
     var allow_navigations = config.getAllowNavigations();
-
-    if (!ats) {
-        ats = {};
-    }
-
-    allow_navigations.forEach(function(allow_navigation) {
-        ats = processUrlAsATS(ats, allow_navigation.href, allow_navigation.minimum_tls_version,
allow_navigation.requires_forward_secrecy);
-    });
-
-    return ats;
+    
+    return allow_navigations
+    // we concat allow_navigations and accesses, after processing accesses
+    .concat(accesses.map(function(obj) {
+        // map accesses to a common key interface using 'href', not origin
+        obj.href = obj.origin;
+        delete obj.origin;
+        return obj;
+    }))
+    // we reduce the array to an object with all the entries processed (key is Hostname)
+    .reduce(function(previousReturn, currentElement) {
+        var obj = parseWhitelistUrlForATS(currentElement.href, currentElement.minimum_tls_version,
currentElement.requires_forward_secrecy);
+        if (obj) {
+            // we 'union' duplicate entries
+            var item = previousReturn[obj.Hostname];
+            if (!item) {
+                item = {};
+            }
+            for(var o in obj) {
+                if (obj.hasOwnProperty(o)) {
+                    item[o] = obj[o];
+                }
+            }
+            previousReturn[obj.Hostname] = item;
+        }  
+        return previousReturn;
+    }, {});
 }
 
-function processUrlAsATS(ats0, url, minimum_tls_version, requires_forward_secrecy) {
-
-    var ats = JSON.parse(JSON.stringify(ats0)); // (shallow) copy, to prevent side effects,
+testable
+/*
+    Parses a URL and returns an object with these keys:
+        { 
+            Hostname, // String
+            NSExceptionAllowsInsecureHTTPLoads, // boolean (default: false)
+            NSIncludesSubdomains,  // boolean (default: false)
+            NSExceptionMinimumTLSVersion, // String (default: 'TLSv1.2')
+            NSExceptionRequiresForwardSecrecy // boolean (default: true)
+        }
+        
+    null is returned if the URL cannot be parsed, or is to be skipped for ATS.
+*/
+function parseWhitelistUrlForATS(url, minimum_tls_version, requires_forward_secrecy) {
+    var href = URL.parse(url);
+    var retObj = {};
+    retObj.Hostname = href.hostname;
 
     if (url === '*') {
-        ats['NSAllowsArbitraryLoads'] = true;
-        return ats;
+        return {
+            Hostname : '*'
+        };
     }
+    
+    // Guiding principle: we only set values in retObj if they are NOT the default
 
-    if (!ats['NSExceptionDomains']) {
-        ats['NSExceptionDomains'] = {};
-    }
-    // TODO: require URL
-    var href = URL.parse(url);
-    var includesSubdomains = false;
-    var hostname = href.hostname;
-
-    if (!hostname) {
+    if (!retObj.Hostname) {
         // check origin, if it allows subdomains (wildcard in hostname), we set NSIncludesSubdomains
to YES. Default is NO
         var subdomain1 = '/*.'; // wildcard in hostname
         var subdomain2 = '*://*.'; // wildcard in hostname and protocol
         var subdomain3 = '*://'; // wildcard in protocol only
         if (href.pathname.indexOf(subdomain1) === 0) {
-            includesSubdomains = true;
-            hostname = href.pathname.substring(subdomain1.length);
+            retObj.NSIncludesSubdomains = true;
+            retObj.Hostname = href.pathname.substring(subdomain1.length);
         } else if (href.pathname.indexOf(subdomain2) === 0) {
-            includesSubdomains = true;
-            hostname = href.pathname.substring(subdomain2.length);
+            retObj.NSIncludesSubdomains = true;
+            retObj.Hostname = href.pathname.substring(subdomain2.length);
         } else if (href.pathname.indexOf(subdomain3) === 0) {
-            includesSubdomains = false;
-            hostname = href.pathname.substring(subdomain3.length);
+            retObj.Hostname = href.pathname.substring(subdomain3.length);
         } else {
             // Handling "scheme:*" case to avoid creating of a blank key in NSExceptionDomains.
-            return ats;
+            return null;
         }
     }
 
-    // get existing entry, if any
-    var exceptionDomain = ats['NSExceptionDomains'][hostname] || {};
-
-    if (includesSubdomains) {
-        exceptionDomain['NSIncludesSubdomains'] = true;
-    } else {
-        delete exceptionDomain['NSIncludesSubdomains'];
-    }
-
     if (minimum_tls_version && minimum_tls_version !== 'TLSv1.2') { // default is
TLSv1.2
-        exceptionDomain['NSExceptionMinimumTLSVersion'] = minimum_tls_version;
-    } else {
-        delete exceptionDomain['NSExceptionMinimumTLSVersion'];
+        retObj.NSExceptionMinimumTLSVersion = minimum_tls_version;
     }
 
     var rfs = (requires_forward_secrecy === 'true');
     if (requires_forward_secrecy && !rfs) { // default is true
-        exceptionDomain['NSExceptionRequiresForwardSecrecy'] = rfs;
-    } else {
-        delete exceptionDomain['NSExceptionRequiresForwardSecrecy'];
+        retObj.NSExceptionRequiresForwardSecrecy = false;
     }
 
     // if the scheme is HTTP, we set NSExceptionAllowsInsecureHTTPLoads to YES. Default is
NO
     if (href.protocol === 'http:') {
-        exceptionDomain['NSExceptionAllowsInsecureHTTPLoads'] = true;
+        retObj.NSExceptionAllowsInsecureHTTPLoads = true;
     }
     else if (!href.protocol && href.pathname.indexOf('*:/') === 0) { // wilcard in
protocol
-        exceptionDomain['NSExceptionAllowsInsecureHTTPLoads'] = true;
-    } else {
-        delete exceptionDomain['NSExceptionAllowsInsecureHTTPLoads'];
+        retObj.NSExceptionAllowsInsecureHTTPLoads = true;
     }
+    
+    return retObj;
+}
 
-    ats['NSExceptionDomains'][hostname] = exceptionDomain;
 
+/*
+    App Transport Security (ATS) writer from <access> and <allow-navigation>
tags
+    in config.xml
+*/
+function writeATSEntries(config) {
+  var pObj = processAccessAndAllowNavigationEntries(config);
+  
+    var ats = {};
+
+    for(var hostname in pObj) {
+        if (pObj.hasOwnProperty(hostname)) {
+              if (hostname === '*') {
+                  ats['NSAllowsArbitraryLoads'] = true;
+                  continue;              
+              }
+              
+              var entry = pObj[hostname];
+              var exceptionDomain = {};
+              
+              for(var key in entry) {
+                  if (entry.hasOwnProperty(key) && key !== 'Hostname') {
+                      exceptionDomain[key] = entry[key];
+                  }
+              }
+
+              if (!ats['NSExceptionDomains']) {
+                  ats['NSExceptionDomains'] = {};
+              }
+
+              ats['NSExceptionDomains'][hostname] = exceptionDomain;
+        }
+    }
+    
     return ats;
 }
 


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org


Mime
View raw message