From f2c4c191c6ad27de1c06b7c2b6536840ac6b5507 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Fri, 2 Sep 2016 14:30:15 +0200 Subject: [PATCH] [msbuild] Set NSAllowArbitraryLoads when debugging watchOS apps. (#746) * [msbuild] Move detection of network configuration to a separate task. * [msbuild] Set NSAllowArbitraryLoads when debugging watchOS apps. The only way to have reliable http connections from the watchOS 2 device to the mac is to set NSAllowArbitraryLoads. See also: https://forums.developer.apple.com/thread/6205 --- external/Xamarin.MacDev | 2 +- .../Tasks/CompileAppManifestTaskBase.cs | 37 ++++++++ .../Tasks/CreateDebugConfigurationTaskBase.cs | 49 +++-------- ...DetectDebugNetworkConfigurationTaskBase.cs | 84 +++++++++++++++++++ .../Xamarin.iOS.Common.targets | 22 ++++- .../Xamarin.iOS.Tasks.Core.csproj | 1 + .../Tasks/DetectDebugNetworkConfiguration.cs | 6 ++ .../Xamarin.iOS.Tasks.csproj | 1 + 8 files changed, 160 insertions(+), 42 deletions(-) create mode 100644 msbuild/Xamarin.iOS.Tasks.Core/Tasks/DetectDebugNetworkConfigurationTaskBase.cs create mode 100644 msbuild/Xamarin.iOS.Tasks/Tasks/DetectDebugNetworkConfiguration.cs diff --git a/external/Xamarin.MacDev b/external/Xamarin.MacDev index 248017c6c9..a71513695b 160000 --- a/external/Xamarin.MacDev +++ b/external/Xamarin.MacDev @@ -1 +1 @@ -Subproject commit 248017c6c95b205f6bdfbfec77fca98254fe7cf0 +Subproject commit a71513695b0357b30c903039cd16bd1cd8609d0c diff --git a/msbuild/Xamarin.iOS.Tasks.Core/Tasks/CompileAppManifestTaskBase.cs b/msbuild/Xamarin.iOS.Tasks.Core/Tasks/CompileAppManifestTaskBase.cs index 55cd488d89..9154f35293 100644 --- a/msbuild/Xamarin.iOS.Tasks.Core/Tasks/CompileAppManifestTaskBase.cs +++ b/msbuild/Xamarin.iOS.Tasks.Core/Tasks/CompileAppManifestTaskBase.cs @@ -31,6 +31,11 @@ namespace Xamarin.iOS.Tasks [Required] public string TargetFrameworkIdentifier { get; set; } + [Required] + public bool Debug { get; set; } + + public string DebugIPAddresses { get; set; } + public string ResourceRules { get; set; } public PlatformFramework Framework { @@ -54,6 +59,8 @@ namespace Xamarin.iOS.Tasks Log.LogTaskProperty ("Architecture", Architecture); Log.LogTaskProperty ("AssemblyName", AssemblyName); Log.LogTaskProperty ("BundleIdentifier", BundleIdentifier); + Log.LogTaskProperty ("Debug", Debug); + Log.LogTaskProperty ("DebugIPAddresses", DebugIPAddresses); Log.LogTaskProperty ("DefaultSdkVersion", DefaultSdkVersion); Log.LogTaskProperty ("IsAppExtension", IsAppExtension); Log.LogTaskProperty ("IsWatchApp", IsWatchApp); @@ -177,6 +184,9 @@ namespace Xamarin.iOS.Tasks plist.SetIfNotPresent (ManifestKeys.MinimumOSVersion, minimumOSVersion.ToString ()); + if (IsWatchExtension && Debug) + SetAppTransportSecurity (plist); + // Remove any Xamarin Studio specific keys plist.Remove (ManifestKeys.XSLaunchImageAssets); plist.Remove (ManifestKeys.XSAppIconAssets); @@ -225,6 +235,33 @@ namespace Xamarin.iOS.Tasks } } + void SetAppTransportSecurity (PDictionary plist) + { + // Debugging over http has a couple of gotchas: + // * We can't use https, because that requires a valid server certificate, + // which we can't ensure. + // It would also require a hostname for the mac, which it might not have either. + // * NSAppTransportSecurity/NSExceptionDomains does not allow exceptions based + // on IP address (only hostname). + // * Which means the only way to make sure watchOS allows connections from + // the app on device to the mac is to disable App Transport Security altogether. + // Good news: watchOS 3 will apparently not apply ATS when connecting + // directly to IP addresses, which means we won't have to do this at all + // (sometime in the future). + + PDictionary ats; + + if (!plist.TryGetValue (ManifestKeys.NSAppTransportSecurity, out ats)) + plist.Add (ManifestKeys.NSAppTransportSecurity, ats = new PDictionary ()); + + if (ats.GetBoolean (ManifestKeys.NSAllowsArbitraryLoads)) { + Log.LogMessage (MessageImportance.Low, "All http loads are already allowed."); + } else { + Log.LogMessage (MessageImportance.Low, "Allowed arbitrary HTTP loads to support debugging."); + ats.SetBooleanOrRemove (ManifestKeys.NSAllowsArbitraryLoads, true); + } + } + void Validation (PDictionary plist) { var supportsIPhone = (supportedDevices & IPhoneDeviceType.IPhone) != 0 diff --git a/msbuild/Xamarin.iOS.Tasks.Core/Tasks/CreateDebugConfigurationTaskBase.cs b/msbuild/Xamarin.iOS.Tasks.Core/Tasks/CreateDebugConfigurationTaskBase.cs index 09dcbf80b6..bbed1e7f53 100644 --- a/msbuild/Xamarin.iOS.Tasks.Core/Tasks/CreateDebugConfigurationTaskBase.cs +++ b/msbuild/Xamarin.iOS.Tasks.Core/Tasks/CreateDebugConfigurationTaskBase.cs @@ -22,7 +22,7 @@ namespace Xamarin.iOS.Tasks [Required] public bool DebugOverWiFi { get; set; } - public string DebuggerHosts { get; set; } + public string DebugIPAddresses { get; set; } [Required] public string DebuggerPort { get; set; } @@ -35,57 +35,30 @@ namespace Xamarin.iOS.Tasks public override bool Execute () { var path = Path.Combine (AppBundleDir, "MonoTouchDebugConfiguration.txt"); - var ips = new List (); Log.LogTaskName ("CreateDebugConfiguration"); Log.LogTaskProperty ("AppBundleDir", AppBundleDir); Log.LogTaskProperty ("DebugOverWiFi", DebugOverWiFi); - Log.LogTaskProperty ("DebuggerHosts", DebuggerHosts); + Log.LogTaskProperty ("DebugIPAddresses", DebugIPAddresses); Log.LogTaskProperty ("DebuggerPort", DebuggerPort); Log.LogTaskProperty ("SdkIsSimulator", SdkIsSimulator); - if (SdkIsSimulator) { - ips.Add (IPAddress.Loopback); - } else if (DebugOverWiFi) { - string[] hosts = null; - - if (!string.IsNullOrEmpty (DebuggerHosts)) - hosts = DebuggerHosts.Split (new [] { ';' }, StringSplitOptions.RemoveEmptyEntries); - - if (hosts == null || hosts.Length == 0) { - try { - ips.AddRange (Dns.GetHostEntry (Dns.GetHostName ()).AddressList); - } catch { - Log.LogError ("Could not resolve host IPs for WiFi debugger settings"); - return false; - } - } else { - foreach (var host in hosts) { - IPAddress ip; - - if (IPAddress.TryParse (host, out ip)) - ips.Add (ip); - } - } - - if (ips == null || ips.Count == 0) { - Log.LogError ("This machine does not have any network adapters. This is required when debugging or profiling on device over WiFi."); - return false; - } - } + var ips = DebugIPAddresses?.Split (new char [] { ';' }, StringSplitOptions.RemoveEmptyEntries); try { using (var stream = new FileStream (path, FileMode.Create, FileAccess.Write)) { using (var writer = new StreamWriter (stream)) { var added = new HashSet (); - foreach (var ip in ips) { - string str = ip.ToString (); + if (ips != null) { + foreach (var ip in ips) { + string str = ip.ToString (); - if (added.Contains (str)) - continue; + if (added.Contains (str)) + continue; - writer.WriteLine ("IP: {0}", str); - added.Add (str); + writer.WriteLine ("IP: {0}", str); + added.Add (str); + } } if (!DebugOverWiFi && !SdkIsSimulator) diff --git a/msbuild/Xamarin.iOS.Tasks.Core/Tasks/DetectDebugNetworkConfigurationTaskBase.cs b/msbuild/Xamarin.iOS.Tasks.Core/Tasks/DetectDebugNetworkConfigurationTaskBase.cs new file mode 100644 index 0000000000..3af2326139 --- /dev/null +++ b/msbuild/Xamarin.iOS.Tasks.Core/Tasks/DetectDebugNetworkConfigurationTaskBase.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; + +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; + +using Xamarin.MacDev.Tasks; +using Xamarin.MacDev; + +namespace Xamarin.iOS.Tasks +{ + public abstract class DetectDebugNetworkConfigurationBase : Task + { + #region Inputs + + public string SessionId { get; set; } + + [Required] + public bool DebugOverWiFi { get; set; } + + public string DebuggerHosts { get; set; } + + [Required] + public bool SdkIsSimulator { get; set; } + + #endregion + + #region Outputs + + [Output] + public string DebugIPAddresses { get; set; } + + #endregion + + + public override bool Execute () + { + Log.LogTaskName ("DetectDebugNetworkConfiguration"); + Log.LogTaskProperty ("DebugOverWiFi", DebugOverWiFi); + Log.LogTaskProperty ("DebuggerHosts", DebuggerHosts); + Log.LogTaskProperty ("SdkIsSimulator", SdkIsSimulator); + + var ips = new List (); + + if (SdkIsSimulator) { + ips.Add (IPAddress.Loopback.ToString ()); + } else if (DebugOverWiFi) { + string [] hosts = null; + + if (!string.IsNullOrEmpty (DebuggerHosts)) + hosts = DebuggerHosts.Split (new [] { ';' }, StringSplitOptions.RemoveEmptyEntries); + + if (hosts == null || hosts.Length == 0) { + try { + ips.AddRange (Dns.GetHostEntry (Dns.GetHostName ()).AddressList.Select ((v) => v.ToString ())); + } catch { + Log.LogError ("Could not resolve host IPs for WiFi debugger settings"); + return false; + } + } else { + foreach (var host in hosts) { + IPAddress ip; + + if (IPAddress.TryParse (host, out ip)) + ips.Add (ip.ToString ()); + } + } + + if (ips == null || ips.Count == 0) { + Log.LogError ("This machine does not have any network adapters. This is required when debugging or profiling on device over WiFi."); + return false; + } + } + + DebugIPAddresses = string.Join (";", ips.ToArray ()); + + Log.LogTaskProperty ("DebugIPAddresses", DebugIPAddresses); + + return !Log.HasLoggedErrors; + } + } +} diff --git a/msbuild/Xamarin.iOS.Tasks.Core/Xamarin.iOS.Common.targets b/msbuild/Xamarin.iOS.Tasks.Core/Xamarin.iOS.Common.targets index 609d7bd49b..26c262080c 100644 --- a/msbuild/Xamarin.iOS.Tasks.Core/Xamarin.iOS.Common.targets +++ b/msbuild/Xamarin.iOS.Tasks.Core/Xamarin.iOS.Common.targets @@ -51,6 +51,7 @@ Copyright (C) 2013-2016 Xamarin. All rights reserved. + @@ -594,7 +595,7 @@ Copyright (C) 2013-2016 Xamarin. All rights reserved. @@ -832,14 +835,14 @@ Copyright (C) 2013-2016 Xamarin. All rights reserved. @@ -1356,6 +1359,19 @@ Copyright (C) 2013-2016 Xamarin. All rights reserved. + + + + + + + diff --git a/msbuild/Xamarin.iOS.Tasks.Core/Xamarin.iOS.Tasks.Core.csproj b/msbuild/Xamarin.iOS.Tasks.Core/Xamarin.iOS.Tasks.Core.csproj index 539f51f3fd..ed3d05f700 100644 --- a/msbuild/Xamarin.iOS.Tasks.Core/Xamarin.iOS.Tasks.Core.csproj +++ b/msbuild/Xamarin.iOS.Tasks.Core/Xamarin.iOS.Tasks.Core.csproj @@ -88,6 +88,7 @@ + diff --git a/msbuild/Xamarin.iOS.Tasks/Tasks/DetectDebugNetworkConfiguration.cs b/msbuild/Xamarin.iOS.Tasks/Tasks/DetectDebugNetworkConfiguration.cs new file mode 100644 index 0000000000..0154808ee6 --- /dev/null +++ b/msbuild/Xamarin.iOS.Tasks/Tasks/DetectDebugNetworkConfiguration.cs @@ -0,0 +1,6 @@ +namespace Xamarin.iOS.Tasks +{ + public class DetectDebugNetworkConfiguration : DetectDebugNetworkConfigurationBase + { + } +} diff --git a/msbuild/Xamarin.iOS.Tasks/Xamarin.iOS.Tasks.csproj b/msbuild/Xamarin.iOS.Tasks/Xamarin.iOS.Tasks.csproj index d7b3718a8b..b029e40fa8 100644 --- a/msbuild/Xamarin.iOS.Tasks/Xamarin.iOS.Tasks.csproj +++ b/msbuild/Xamarin.iOS.Tasks/Xamarin.iOS.Tasks.csproj @@ -70,6 +70,7 @@ +