Beispiel #1
0
        public CanvasService()
        {
            _platform = new AndroidPlatform();
            var metrics = Forms.Context.Resources.DisplayMetrics;

            _scale = ((float)metrics.DensityDpi / (int)DisplayMetricsDensity.Default);
        }
Beispiel #2
0
        public static async Task <Bitmap> GetBitmapAsync(SvgImage svgImage, int width, int height)
        {
            Bitmap result = null;

            Stream svgStream = await SvgService.GetSvgStreamAsync(svgImage).ConfigureAwait(false);

            await Task.Run(() =>
            {
                var svgReader = new SvgReader(new StreamReader(svgStream));

                var graphics = svgReader.Graphic;

                var scale = 1.0;

                if (height >= width)
                {
                    scale = height / graphics.Size.Height;
                }
                else
                {
                    scale = width / graphics.Size.Width;
                }

                var canvas = new AndroidPlatform().CreateImageCanvas(graphics.Size, scale);
                graphics.Draw(canvas);
                var image = (BitmapImage)canvas.GetImage();
                result    = image.Bitmap;
            });

            return(result);
        }
        public IAppInstance Run(IAppInstall App)
        {
            AndroidAppInstall DroidAppInstall = App as AndroidAppInstall;

            if (DroidAppInstall == null)
            {
                throw new Exception("AppInstance is of incorrect type!");
            }

            // wake the device - we can install while its asleep but not run
            PowerOn();

            // kill any currently running instance:
            KillRunningProcess(DroidAppInstall.AndroidPackageName);

            string LaunchActivity = AndroidPlatform.GetLaunchableActivityName();

            Log.Info("Launching {0} on '{1}' ", DroidAppInstall.AndroidPackageName + "/" + LaunchActivity, ToString());
            Log.Verbose("\t{0}", DroidAppInstall.CommandLine);

            // Clear the device's logcat in preparation for the test..
            RunAdbDeviceCommand("logcat --clear");

            // start the app on device!
            string         CommandLine = "shell am start -W -S -n " + DroidAppInstall.AndroidPackageName + "/" + LaunchActivity;
            IProcessResult Process     = RunAdbDeviceCommand(CommandLine, false, true);

            return(new AndroidAppInstance(this, DroidAppInstall, Process));
        }
        /// <summary>
        /// Runs an ADB command at the global scope
        /// </summary>
        /// <param name="Args"></param>
        /// <param name="Wait"></param>
        /// <returns></returns>
        public static IProcessResult RunAdbGlobalCommand(string Args, bool Wait = true, bool bShouldLogCommand = false)
        {
            CommandUtils.ERunOptions RunOptions = CommandUtils.ERunOptions.AppMustExist | CommandUtils.ERunOptions.NoWaitForExit;

            if (Log.IsVeryVerbose)
            {
                RunOptions |= CommandUtils.ERunOptions.AllowSpew;
            }
            else
            {
                RunOptions |= CommandUtils.ERunOptions.NoLoggingOfRunCommand;
            }

            if (bShouldLogCommand)
            {
                Log.Verbose("Running ADB Command: adb {0}", Args);
            }

            IProcessResult Process = AndroidPlatform.RunAdbCommand(null, null, Args, null, RunOptions);

            if (Wait)
            {
                Process.WaitForExit();
            }

            return(Process);
        }
Beispiel #5
0
        public static IWebProxy CreateDefaultProxy()
        {
#if FEATURE_NO_BSD_SOCKETS
            throw new PlatformNotSupportedException();
#elif MONOTOUCH
            return(Mono.Net.CFNetwork.GetDefaultProxy());
#elif MONODROID
            // Return the system web proxy.  This only works for ICS+.
            var data = AndroidPlatform.GetDefaultProxy();
            if (data != null)
            {
                return(data);
            }

            return(new WebProxy(true));
#else
            if (Platform.IsMacOS)
            {
                var data = Mono.Net.CFNetwork.GetDefaultProxy();
                if (data != null)
                {
                    return(data);
                }
            }

            return(new WebProxy(true));
#endif
        }
Beispiel #6
0
        private static SynchronizationContext GetThreadLocalContext()
        {
            SynchronizationContext context = null;

#if FEATURE_CORECLR
#if FEATURE_LEGACYNETCF
            if (CompatibilitySwitches.IsAppEarlierThanWindowsPhoneMango)
            {
                context = s_appDomainStaticContext;
            }
            else
#endif //FEATURE_LEGACYNETCF
            context = s_threadStaticContext;
#endif //FEATURE_CORECLR

#if FEATURE_APPX
            if (context == null && Environment.IsWinRTSupported)
            {
                context = GetWinRTContext();
            }
#endif

#if MONODROID
            if (context == null)
            {
                context = AndroidPlatform.GetDefaultSyncContext();
            }
#endif

            return(context);
        }
Beispiel #7
0
            static int GetInterfaceAddresses(out IntPtr ifap)
            {
#if MONODROID
                return(AndroidPlatform.GetInterfaceAddresses(out ifap));
#else
                return(getifaddrs(out ifap));
#endif
            }
Beispiel #8
0
        public static T UseAndroid <T>(this T builder) where T : AppBuilderBase <T>, new()
        {
            var options = AvaloniaLocator.Current.GetService <AndroidPlatformOptions>() ?? new AndroidPlatformOptions();

            builder.UseWindowingSubsystem(() => AndroidPlatform.Initialize(builder.ApplicationType, options), "Android");
            builder.UseSkia();
            return(builder);
        }
Beispiel #9
0
            static void FreeInterfaceAddresses(IntPtr ifap)
            {
#if MONODROID
                AndroidPlatform.FreeInterfaceAddresses(ifap);
#else
                freeifaddrs(ifap);
#endif
            }
Beispiel #10
0
        public async void Render( )
        {
            //added check because both *may* not be set at the same time, this negates the error throwing unfortuantely. --bwc
            if (String.IsNullOrEmpty(Element.SvgPath) || (Element.SvgAssembly == null))
            {
                return;
            }

            if (_formsControl != null)
            {
                await Task.Run(async( ) =>
                {
                    Stream svgStream = _formsControl.SvgAssembly.GetManifestResourceStream(_formsControl.SvgPath);

                    if (svgStream == null)
                    {
                        throw new Exception(string.Format("Error retrieving {0} make sure Build Action is Embedded Resource", _formsControl.SvgPath));
                    }

                    SvgReader r = new SvgReader(new StreamReader(svgStream), new StylesParser(new ValuesParser( )), new ValuesParser( ));

                    this.ReplaceColors(r.Graphic, Element.ReplacementColors);

                    Graphic graphics = r.Graphic;
                    int width        = PixelToDP((int)_formsControl.WidthRequest <= 0 ? 100 : (int)_formsControl.WidthRequest);
                    int height       = PixelToDP((int)_formsControl.HeightRequest <= 0 ? 100 : (int)_formsControl.HeightRequest);
                    double scale     = 1.0;

                    if (height >= width)
                    {
                        scale = height / graphics.Size.Height;
                    }
                    else
                    {
                        scale = width / graphics.Size.Width;
                    }

                    IImageCanvas canvas = new AndroidPlatform( ).CreateImageCanvas(graphics.Size, scale);

                    graphics.Draw(canvas);
                    BitmapImage image = (BitmapImage)canvas.GetImage( );


                    return(image);
                }).ContinueWith(taskResult =>
                {
                    Device.BeginInvokeOnMainThread(() =>
                    {
                        var imageView = new ImageView(Context);
                        imageView.SetScaleType(ImageView.ScaleType.FitXy);
                        imageView.SetImageBitmap(taskResult.Result.Bitmap);
                        SetNativeControl(imageView);
                    });
                });
            }
        }
        static bool EvaluateSystem(XX509CertificateCollection certs, XX509CertificateCollection anchors, string host, X509Chain chain, ref SslPolicyErrors errors, ref int status11)
        {
            var  leaf = certs [0];
            bool result;

#if MONODROID
            result = AndroidPlatform.TrustEvaluateSsl(certs);
            if (result)
            {
                // chain.Build() + GetErrorsFromChain() (above) will ALWAYS fail on
                // Android (there are no mozroots or preinstalled root certificates),
                // thus `errors` will ALWAYS have RemoteCertificateChainErrors.
                // Android just verified the chain; clear RemoteCertificateChainErrors.
                errors &= ~SslPolicyErrors.RemoteCertificateChainErrors;
            }
#else
            if (is_macosx)
            {
                // Attempt to use OSX certificates
                // Ideally we should return the SecTrustResult
                OSX509Certificates.SecTrustResult trustResult = OSX509Certificates.SecTrustResult.Deny;
                try {
                    trustResult = OSX509Certificates.TrustEvaluateSsl(certs, anchors, host);
                    // We could use the other values of trustResult to pass this extra information
                    // to the .NET 2 callback for values like SecTrustResult.Confirm
                    result = (trustResult == OSX509Certificates.SecTrustResult.Proceed ||
                              trustResult == OSX509Certificates.SecTrustResult.Unspecified);
                } catch {
                    result  = false;
                    errors |= SslPolicyErrors.RemoteCertificateChainErrors;
                    // Ignore
                }

                if (result)
                {
                    // TrustEvaluateSsl was successful so there's no trust error
                    // IOW we discard our own chain (since we trust OSX one instead)
                    errors = 0;
                }
                else
                {
                    // callback and DefaultCertificatePolicy needs this since 'result' is not specified
                    status11 = (int)trustResult;
                    errors  |= SslPolicyErrors.RemoteCertificateChainErrors;
                }
            }
            else
            {
                result = BuildX509Chain(certs, chain, ref errors, ref status11);
            }
#endif

            return(result);
        }
        protected override async void OnElementChanged(ElementChangedEventArgs <SvgImage> e)
        {
            base.OnElementChanged(e);

            if (_formsControl != null)
            {
                await Task.Run(async() =>
                {
                    var svgStream = _formsControl.SvgAssembly.GetManifestResourceStream(_formsControl.SvgPath);

                    if (svgStream == null)
                    {
                        throw new Exception(string.Format("Error retrieving {0} make sure Build Action is Embedded Resource",
                                                          _formsControl.SvgPath));
                    }

                    var r = new SvgReader(new StreamReader(svgStream), new StylesParser(new ValuesParser()), new ValuesParser());

                    var graphics = r.Graphic;

                    var width  = PixelToDP((int)_formsControl.WidthRequest <= 0 ? 100 : (int)_formsControl.WidthRequest);
                    var height = PixelToDP((int)_formsControl.HeightRequest <= 0 ? 100 : (int)_formsControl.HeightRequest);

                    var scale = 1.0;

                    if (height >= width)
                    {
                        scale = height / graphics.Size.Height;
                    }
                    else
                    {
                        scale = width / graphics.Size.Width;
                    }

                    var canvas = new AndroidPlatform().CreateImageCanvas(graphics.Size, scale);
                    graphics.Draw(canvas);
                    var image = (BitmapImage)canvas.GetImage();

                    return(image);
                }).ContinueWith(taskResult =>
                {
                    Device.BeginInvokeOnMainThread(() =>
                    {
                        var imageView = new ImageView(Context);

                        imageView.SetScaleType(ImageView.ScaleType.CenterInside);
                        imageView.SetImageBitmap(taskResult.Result.Bitmap);

                        SetNativeControl(imageView);
                    });
                });
            }
        }
Beispiel #13
0
        protected override void OnCreate(
            Bundle bundle)
        {
            base.OnCreate(bundle);

            if (null == this._app)
            {
                var platform = new AndroidPlatform(this);
                this._app = new TestApp(platform);
            }

            this._app.Start();
        }
Beispiel #14
0
        private static SynchronizationContext GetThreadLocalContext()
        {
            SynchronizationContext context = null;

#if FEATURE_APPX
            if (context == null && Environment.IsWinRTSupported)
            {
                context = GetWinRTContext();
            }
#endif

#if MONODROID
            if (context == null)
            {
                context = AndroidPlatform.GetDefaultSyncContext();
            }
#endif

            return(context);
        }
Beispiel #15
0
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
            AndroidPlatform.Initialize();

            // Iconize
            Iconize.With(new MaterialModule());
            //IconControls.Init();

            // ZXing
            ZXingPlatform.Init();
            MobileBarcodeScanner.Initialize(Application);

            // Xamarin bootstrap
            Xamarin.Forms.Forms.Init(this, bundle);
            LoadApplication(new AndroidApp
            {
                MainActivity = this
            });
        }
Beispiel #16
0
        public static IWebProxy CreateDefaultProxy()
        {
#if MONOTOUCH
            return(Mono.Net.CFNetwork.GetDefaultProxy());
#elif MONODROID
            // Return the system web proxy.  This only works for ICS+.
            var data = AndroidPlatform.GetDefaultProxy();
            if (data != null)
            {
                return(data);
            }
#else
            if (Platform.IsMacOS)
            {
                var data = Mono.Net.CFNetwork.GetDefaultProxy();
                if (data != null)
                {
                    return(data);
                }
            }
#endif

            return(new WebProxy(true));
        }
        public IAppInstall InstallApplication(UnrealAppConfig AppConfig)
        {
            // todo - pass this through
            AndroidBuild Build = AppConfig.Build as AndroidBuild;

            // Ensure APK exists
            if (Build == null)
            {
                throw new AutomationException("Invalid build for Android!");
            }

            // kill any currently running instance:
            KillRunningProcess(Build.AndroidPackageName);

            bool SkipDeploy = Globals.Params.ParseParam("SkipDeploy");

            if (SkipDeploy == false)
            {
                // Establish remote directory locations
                string         DeviceStorageQueryCommand = AndroidPlatform.GetStorageQueryCommand();
                IProcessResult StorageQueryResult        = RunAdbDeviceCommand(DeviceStorageQueryCommand);
                string         StorageLocation           = StorageQueryResult.Output.Trim(); // "/mnt/sdcard";

                // remote dir used to save things
                string RemoteDir = StorageLocation + "/UE4Game/" + AppConfig.ProjectName;

                // if not a bulk/dev build, remote dir will be under /{StorageLocation}/Android/data/{PackageName}
                if ((Build.Flags & (BuildFlags.Bulk | BuildFlags.CanReplaceExecutable)) == 0)
                {
                    RemoteDir = StorageLocation + "/Android/data/" + Build.AndroidPackageName + "/files/UE4Game/" + AppConfig.ProjectName;
                }

                string DependencyDir = RemoteDir + "/deps";

                // device artifact path, always clear between runs
                DeviceArtifactPath = string.Format("{0}/{1}/Saved", RemoteDir, AppConfig.ProjectName);
                RunAdbDeviceCommand(string.Format("shell rm -r {0}", DeviceArtifactPath));

                // path for OBB files
                string OBBRemoteDestination = string.Format("{0}/obb/{1}", StorageLocation, Build.AndroidPackageName);

                if (Globals.Params.ParseParam("cleandevice"))
                {
                    Log.Info("Cleaning previous builds due to presence of -cleandevice");

                    // we need to ununstall then install the apk - don't care if it fails, may have been deleted
                    Log.Info("Uninstalling {0}", Build.AndroidPackageName);
                    RunAdbDeviceCommand(string.Format("uninstall {0}", Build.AndroidPackageName));

                    Log.Info("Removing {0}", RemoteDir);
                    RunAdbDeviceCommand(string.Format("shell rm -r {0}", RemoteDir));

                    Log.Info("Removing {0}", OBBRemoteDestination);
                    RunAdbDeviceCommand(string.Format("shell rm -r {0}", OBBRemoteDestination));
                }

                // remote dir on the device, create it if it doesn't exist
                RunAdbDeviceCommand(string.Format("shell mkdir -p {0}/", RemoteDir));

                IProcessResult AdbResult;
                string         AdbCommand;

                // path to the APK to install.
                string ApkPath = Build.SourceApkPath;

                // check for a local newer executable
                if (Globals.Params.ParseParam("dev"))
                {
                    //string ApkFileName = Path.GetFileName(ApkPath);

                    string ApkFileName2 = UnrealHelpers.GetExecutableName(AppConfig.ProjectName, UnrealTargetPlatform.Android, AppConfig.Configuration, AppConfig.ProcessType, "apk");

                    string LocalAPK = Path.Combine(Environment.CurrentDirectory, AppConfig.ProjectName, "Binaries/Android", ApkFileName2);

                    bool LocalFileExists = File.Exists(LocalAPK);
                    bool LocalFileNewer  = LocalFileExists && File.GetLastWriteTime(LocalAPK) > File.GetLastWriteTime(ApkPath);

                    Log.Verbose("Checking for newer binary at {0}", LocalAPK);
                    Log.Verbose("LocalFile exists: {0}. Newer: {1}", LocalFileExists, LocalFileNewer);

                    if (LocalFileExists && LocalFileNewer)
                    {
                        ApkPath = LocalAPK;
                    }
                }

                // first install the APK
                CopyFileToDevice(Build.AndroidPackageName, ApkPath, "");

                // obb files need to be named based on APK version (grrr), so find that out. This should return something like
                // versionCode=2 minSdk=21 targetSdk=21
                string PackageInfo = RunAdbDeviceCommand(string.Format("shell dumpsys package {0} | grep versionCode", Build.AndroidPackageName)).Output;
                var    Match       = Regex.Match(PackageInfo, @"versionCode=([\d\.]+)\s");
                if (Match.Success == false)
                {
                    throw new AutomationException("Failed to find version info for APK!");
                }
                string PackageVersion = Match.Groups[1].ToString();

                // Convert the files from the source to final destination names
                Dictionary <string, string> FilesToInstall = new Dictionary <string, string>();

                Console.WriteLine("trying to copy files over.");
                if (AppConfig.FilesToCopy != null)
                {
                    if (LocalDirectoryMappings.Count == 0)
                    {
                        Console.WriteLine("Populating Directory");
                        PopulateDirectoryMappings(DeviceArtifactPath);
                    }
                    Console.WriteLine("trying to copy files over.");
                    foreach (UnrealFileToCopy FileToCopy in AppConfig.FilesToCopy)
                    {
                        string PathToCopyTo = Path.Combine(LocalDirectoryMappings[FileToCopy.TargetBaseDirectory], FileToCopy.TargetRelativeLocation);
                        if (File.Exists(FileToCopy.SourceFileLocation))
                        {
                            FileInfo SrcInfo = new FileInfo(FileToCopy.SourceFileLocation);
                            SrcInfo.IsReadOnly = false;
                            FilesToInstall.Add(FileToCopy.SourceFileLocation, PathToCopyTo.Replace("\\", "/"));
                            Console.WriteLine("Copying {0} to {1}", FileToCopy.SourceFileLocation, PathToCopyTo);
                        }

                        else
                        {
                            Log.Warning("File to copy {0} not found", FileToCopy);
                        }
                    }
                }

                Build.FilesToInstall.Keys.ToList().ForEach(K =>
                {
                    string SrcPath  = K;
                    string DestPath = Build.FilesToInstall[K];

                    string DestFile = Path.GetFileName(DestPath);

                    // If we installed a new APK we need to change the package version
                    Match OBBMatch = Regex.Match(DestFile, @"main\.(\d+)\.com.*\.obb");
                    if (OBBMatch.Success)
                    {
                        string NewFileName = DestFile.Replace(OBBMatch.Groups[1].ToString(), PackageVersion);
                        DestPath           = DestPath.Replace(DestFile, NewFileName);
                    }

                    DestPath = Regex.Replace(DestPath, "%STORAGE%", StorageLocation, RegexOptions.IgnoreCase);

                    FilesToInstall.Add(SrcPath, DestPath);
                });



                // get a list of files in the destination OBB directory
                AdbResult = RunAdbDeviceCommand(string.Format("shell ls {0}", OBBRemoteDestination));

                // if != 0 then no folder exists
                if (AdbResult.ExitCode == 0)
                {
                    IEnumerable <string> CurrentRemoteFileList = AdbResult.Output.Replace("\r\n", "\n").Split('\n');
                    IEnumerable <string> NewRemoteFileList     = FilesToInstall.Values.Select(F => Path.GetFileName(F));

                    // delete any files that should not be there
                    foreach (string FileName in CurrentRemoteFileList)
                    {
                        if (FileName.StartsWith(".") || FileName.Length == 0)
                        {
                            continue;
                        }

                        if (NewRemoteFileList.Contains(FileName) == false)
                        {
                            RunAdbDeviceCommand(string.Format("shell rm {0}/{1}", OBBRemoteDestination, FileName));
                        }
                    }
                }

                foreach (var KV in FilesToInstall)
                {
                    string LocalFile  = KV.Key;
                    string RemoteFile = KV.Value;

                    CopyFileToDevice(Build.AndroidPackageName, LocalFile, RemoteFile);
                }

                // create a tempfile, insert the command line, and push it over
                string TmpFile = Path.GetTempFileName();

                CommandLineFilePath = string.Format("{0}/UE4CommandLine.txt", RemoteDir);

                // I've seen a weird thing where adb push truncates by a byte, so add some padding...
                File.WriteAllText(TmpFile, AppConfig.CommandLine + "    ");
                AdbCommand = string.Format("push {0} {1}", TmpFile, CommandLineFilePath);
                RunAdbDeviceCommand(AdbCommand);


                File.Delete(TmpFile);
            }
            else
            {
                Log.Info("Skipping install of {0} (-skipdeploy)", Build.AndroidPackageName);
            }

            AndroidAppInstall AppInstall = new AndroidAppInstall(this, AppConfig.ProjectName, Build.AndroidPackageName, AppConfig.CommandLine);

            return(AppInstall);
        }
 public static T UseAndroid <T>(this T builder) where T : AppBuilderBase <T>, new()
 {
     return(builder
            .UseWindowingSubsystem(() => AndroidPlatform.Initialize(), "Android")
            .UseSkia());
 }
Beispiel #19
0
 protected override MonoBtlsX509 OnGetBySubject(MonoBtlsX509Name name)
 {
     return(AndroidPlatform.CertStoreLookup(name));
 }
        async void UpdateSVGSource()
        {
            await Task.Run(async() =>
            {
                Uri u;
                try{
                    u = new Uri(_formsControl.SvgPath);
                }catch (Exception e) {
                    Insights.Report(e);
                    return(null);
                }
                var path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), Path.GetFileName(u.AbsolutePath));
                if (!File.Exists(path))
                {
                    using (var client = new HttpClient()) {
                        try{
                            var bytes = await client.GetByteArrayAsync(_formsControl.SvgPath);
                            File.WriteAllBytes(path, bytes);
                        }catch (Exception e) {
                            Insights.Report(e);
                            return(null);
                        }
                    }
                }

                var svgStream = File.OpenRead(path);

                if (svgStream == null)
                {
                    throw new Exception(string.Format("Error retrieving {0} make sure Build Action is Embedded Resource",
                                                      _formsControl.SvgPath));
                }
                SvgReader r;
                try{
                    r = new SvgReader(new StreamReader(svgStream), new StylesParser(new ValuesParser()), new ValuesParser());
                }catch (Exception e) {
                    Insights.Report(e);
                    return(null);
                }

                var graphics = r.Graphic;

                var width  = PixelToDP((int)_formsControl.WidthRequest <= 0 ? 100 : (int)_formsControl.WidthRequest);
                var height = PixelToDP((int)_formsControl.HeightRequest <= 0 ? 100 : (int)_formsControl.HeightRequest);

                var scale = 1.0;

                if (height >= width)
                {
                    scale = height / graphics.Size.Height;
                }
                else
                {
                    scale = width / graphics.Size.Width;
                }

                try{
                    var canvas = new AndroidPlatform().CreateImageCanvas(graphics.Size, scale);
                    graphics.Draw(canvas);
                    var image = (BitmapImage)canvas.GetImage();
                    return(image);
                }
                catch (Exception e) {
                    Insights.Report(e);
                    return(null);
                }
            }).ContinueWith(taskResult =>
            {
                Device.BeginInvokeOnMainThread(() =>
                {
                    var imageView = new ImageView(Context);
                    SetNativeControl(imageView);
                    if (taskResult.Result == null)
                    {
                        var id = getResourceId(_formsControl.SvgDefaultImage, "drawable", Context.PackageName);
                        Control.SetImageResource(id);
                        return;
                    }

                    imageView.SetScaleType(ImageView.ScaleType.CenterInside);
                    imageView.SetImageBitmap(taskResult.Result.Bitmap);
                });
            });
        }
Beispiel #21
0
            // Used when the obsolete ICertificatePolicy is set to DefaultCertificatePolicy
            // and the new ServerCertificateValidationCallback is not null
            internal ValidationResult ValidateChain(MSX.X509CertificateCollection certs)
            {
                // user_denied is true if the user callback is called and returns false
                bool user_denied = false;

                if (certs == null || certs.Count == 0)
                {
                    return(null);
                }

                ICertificatePolicy policy = ServicePointManager.CertificatePolicy;

                X509Certificate2 leaf    = new X509Certificate2(certs [0].RawData);
                int             status11 = 0;     // Error code passed to the obsolete ICertificatePolicy callback
                SslPolicyErrors errors   = 0;
                X509Chain       chain    = null;
                bool            result   = false;

#if MONOTOUCH
                // The X509Chain is not really usable with MonoTouch (since the decision is not based on this data)
                // However if someone wants to override the results (good or bad) from iOS then they will want all
                // the certificates that the server provided (which generally does not include the root) so, only
                // if there's a user callback, we'll create the X509Chain but won't build it
                // ref: https://bugzilla.xamarin.com/show_bug.cgi?id=7245
                if (ServerCertificateValidationCallback != null)
                {
#endif
                chain             = new X509Chain();
                chain.ChainPolicy = new X509ChainPolicy();
#if !MONOTOUCH
                chain.ChainPolicy.RevocationMode = revocation_mode;
#endif
                for (int i = 1; i < certs.Count; i++)
                {
                    X509Certificate2 c2 = new X509Certificate2(certs [i].RawData);
                    chain.ChainPolicy.ExtraStore.Add(c2);
                }
#if MONOTOUCH
            }
#else
                try {
                    if (!chain.Build(leaf))
                    {
                        errors |= GetErrorsFromChain(chain);
                    }
                } catch (Exception e) {
                    Console.Error.WriteLine("ERROR building certificate chain: {0}", e);
                    Console.Error.WriteLine("Please, report this problem to the Mono team");
                    errors |= SslPolicyErrors.RemoteCertificateChainErrors;
                }

                // for OSX and iOS we're using the native API to check for the SSL server policy and host names
                if (!is_macosx)
                {
                    if (!CheckCertificateUsage(leaf))
                    {
                        errors  |= SslPolicyErrors.RemoteCertificateChainErrors;
                        status11 = -2146762490;                         //CERT_E_PURPOSE 0x800B0106
                    }

                    if (!CheckServerIdentity(certs [0], host))
                    {
                        errors  |= SslPolicyErrors.RemoteCertificateNameMismatch;
                        status11 = -2146762481;                         // CERT_E_CN_NO_MATCH 0x800B010F
                    }
                }
                else
                {
#endif
            // Attempt to use OSX certificates
            // Ideally we should return the SecTrustResult
            OSX509Certificates.SecTrustResult trustResult = OSX509Certificates.SecTrustResult.Deny;
            try {
                trustResult = OSX509Certificates.TrustEvaluateSsl(certs, host);
                // We could use the other values of trustResult to pass this extra information
                // to the .NET 2 callback for values like SecTrustResult.Confirm
                result = (trustResult == OSX509Certificates.SecTrustResult.Proceed ||
                          trustResult == OSX509Certificates.SecTrustResult.Unspecified);
            } catch {
                // Ignore
            }

            if (result)
            {
                // TrustEvaluateSsl was successful so there's no trust error
                // IOW we discard our own chain (since we trust OSX one instead)
                errors = 0;
            }
            else
            {
                // callback and DefaultCertificatePolicy needs this since 'result' is not specified
                status11 = (int)trustResult;
                errors  |= SslPolicyErrors.RemoteCertificateChainErrors;
            }
#if !MONOTOUCH
        }
#endif

#if MONODROID && SECURITY_DEP
            result = AndroidPlatform.TrustEvaluateSsl(certs, sender, leaf, chain, errors);
            if (result)
            {
                // chain.Build() + GetErrorsFromChain() (above) will ALWAYS fail on
                // Android (there are no mozroots or preinstalled root certificates),
                // thus `errors` will ALWAYS have RemoteCertificateChainErrors.
                // Android just verified the chain; clear RemoteCertificateChainErrors.
                errors &= ~SslPolicyErrors.RemoteCertificateChainErrors;
            }
#endif

            if (policy != null && (!(policy is DefaultCertificatePolicy) || cb == null))
            {
                ServicePoint   sp  = null;
                HttpWebRequest req = sender as HttpWebRequest;
                if (req != null)
                {
                    sp = req.ServicePointNoLock;
                }
                if (status11 == 0 && errors != 0)
                {
                    status11 = GetStatusFromChain(chain);
                }

                // pre 2.0 callback
                result      = policy.CheckValidationResult(sp, leaf, req, status11);
                user_denied = !result && !(policy is DefaultCertificatePolicy);
            }
            // If there's a 2.0 callback, it takes precedence
            if (ServerCertificateValidationCallback != null)
            {
                result      = ServerCertificateValidationCallback(sender, leaf, chain, errors);
                user_denied = !result;
            }
            return(new ValidationResult(result, user_denied, status11));
        }
        ValidationResult ValidateChain(string host, X509Certificate2Collection certs, SslPolicyErrors errors)
        {
            // user_denied is true if the user callback is called and returns false
            bool user_denied = false;
            bool result      = false;

            var hasCallback = certValidationCallback != null || callbackWrapper != null;

            X509Certificate2 leaf;

            if (certs == null || certs.Count == 0)
            {
                leaf = null;
            }
            else
            {
                leaf = certs [0];
            }

            if (tlsStream != null)
            {
                request.ServicePoint.SetServerCertificate(leaf);
            }

            if (leaf == null)
            {
                errors |= SslPolicyErrors.RemoteCertificateNotAvailable;
                if (hasCallback)
                {
                    if (callbackWrapper != null)
                    {
                        result = callbackWrapper.Invoke(certValidationCallback, leaf, null, (MonoSslPolicyErrors)errors);
                    }
                    else
                    {
                        result = certValidationCallback.Invoke(sender, leaf, null, errors);
                    }
                    user_denied = !result;
                }
                return(new ValidationResult(result, user_denied, 0, (MonoSslPolicyErrors)errors));
            }

            bool needsChain;
            bool skipSystemValidators = false;

            if (!CertificateValidationHelper.SupportsX509Chain || is_mobile || is_macosx)
            {
                needsChain = false;
            }
            else if (settings != null)
            {
                skipSystemValidators = settings.SkipSystemValidators;
                needsChain           = !settings.SkipSystemValidators || settings.CallbackNeedsCertificateChain;
            }
            else
            {
                needsChain = true;
            }

            ICertificatePolicy policy = ServicePointManager.GetLegacyCertificatePolicy();

            int       status11 = 0;       // Error code passed to the obsolete ICertificatePolicy callback
            X509Chain chain    = null;

            if (needsChain)
            {
                chain             = new X509Chain();
                chain.ChainPolicy = new X509ChainPolicy();


#if !MONOTOUCH
                chain.ChainPolicy.RevocationMode = revocation_mode;
#endif
                for (int i = 1; i < certs.Count; i++)
                {
                    chain.ChainPolicy.ExtraStore.Add(certs [i]);
                }
            }

#if !MONOTOUCH
            if (needsChain)
            {
                try {
                    if (!chain.Build(leaf))
                    {
                        errors |= GetErrorsFromChain(chain);
                    }
                } catch (Exception e) {
                    Console.Error.WriteLine("ERROR building certificate chain: {0}", e);
                    Console.Error.WriteLine("Please, report this problem to the Mono team");
                    errors |= SslPolicyErrors.RemoteCertificateChainErrors;
                }
            }

            // for OSX and iOS we're using the native API to check for the SSL server policy and host names
            if (!is_macosx)
            {
                if (!CheckCertificateUsage(leaf))
                {
                    errors  |= SslPolicyErrors.RemoteCertificateChainErrors;
                    status11 = -2146762490;                     //CERT_E_PURPOSE 0x800B0106
                }

                if (host != null && !CheckServerIdentity(leaf, host))
                {
                    errors  |= SslPolicyErrors.RemoteCertificateNameMismatch;
                    status11 = -2146762481;                     // CERT_E_CN_NO_MATCH 0x800B010F
                }
            }
#endif

            if (is_macosx && !skipSystemValidators)
            {
                // Attempt to use OSX certificates
                // Ideally we should return the SecTrustResult
                OSX509Certificates.SecTrustResult trustResult = OSX509Certificates.SecTrustResult.Deny;
                try {
                    trustResult = OSX509Certificates.TrustEvaluateSsl(certs, host);
                    // We could use the other values of trustResult to pass this extra information
                    // to the .NET 2 callback for values like SecTrustResult.Confirm
                    result = (trustResult == OSX509Certificates.SecTrustResult.Proceed ||
                              trustResult == OSX509Certificates.SecTrustResult.Unspecified);
                } catch {
                    // Ignore
                }

                if (result)
                {
                    // TrustEvaluateSsl was successful so there's no trust error
                    // IOW we discard our own chain (since we trust OSX one instead)
                    errors = 0;
                }
                else
                {
                    // callback and DefaultCertificatePolicy needs this since 'result' is not specified
                    status11 = (int)trustResult;
                    errors  |= SslPolicyErrors.RemoteCertificateChainErrors;
                }
            }


#if MONODROID && SECURITY_DEP
            if (!skipSystemValidators)
            {
                result = AndroidPlatform.TrustEvaluateSsl(certs, sender, leaf, chain, errors);
                if (result)
                {
                    // chain.Build() + GetErrorsFromChain() (above) will ALWAYS fail on
                    // Android (there are no mozroots or preinstalled root certificates),
                    // thus `errors` will ALWAYS have RemoteCertificateChainErrors.
                    // Android just verified the chain; clear RemoteCertificateChainErrors.
                    errors &= ~SslPolicyErrors.RemoteCertificateChainErrors;
                }
            }
#endif

            if (policy != null && (!(policy is DefaultCertificatePolicy) || certValidationCallback == null))
            {
                ServicePoint sp = null;
                if (request != null)
                {
                    sp = request.ServicePointNoLock;
                }
                if (status11 == 0 && errors != 0)
                {
                    status11 = GetStatusFromChain(chain);
                }

                // pre 2.0 callback
                result      = policy.CheckValidationResult(sp, leaf, request, status11);
                user_denied = !result && !(policy is DefaultCertificatePolicy);
            }
            // If there's a 2.0 callback, it takes precedence
            if (hasCallback)
            {
                if (callbackWrapper != null)
                {
                    result = callbackWrapper.Invoke(certValidationCallback, leaf, chain, (MonoSslPolicyErrors)errors);
                }
                else
                {
                    result = certValidationCallback.Invoke(sender, leaf, chain, errors);
                }
                user_denied = !result;
            }
            return(new ValidationResult(result, user_denied, status11, (MonoSslPolicyErrors)errors));
        }
Beispiel #23
0
        public static IWebProxy GetSystemWebProxy()
        {
#if MONOTOUCH
            return(CFNetwork.GetDefaultProxy());
#else
#if MONODROID
            // Return the system web proxy.  This only works for ICS+.
            var androidProxy = AndroidPlatform.GetDefaultProxy();
            if (androidProxy != null)
            {
                return(androidProxy);
            }
#endif
#if !NET_2_1 && !SSHARP
            if (IsWindows())
            {
                int iProxyEnable =
                    (int)Microsoft.Win32.Registry.GetValue("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", "ProxyEnable", 0);

                if (iProxyEnable > 0)
                {
                    string    strHttpProxy   = "";
                    bool      bBypassOnLocal = false;
                    ArrayList al             = new ArrayList();

                    string strProxyServer =
                        (string)Microsoft.Win32.Registry.GetValue("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", "ProxyServer", null);
                    string strProxyOverrride =
                        (string)Microsoft.Win32.Registry.GetValue("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", "ProxyOverride", null);

                    if (strProxyServer.Contains("="))
                    {
                        foreach (string strEntry in strProxyServer.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries))
                        {
                            if (strEntry.StartsWith("http="))
                            {
                                strHttpProxy = strEntry.Substring(5);
                                break;
                            }
                        }
                    }
                    else
                    {
                        strHttpProxy = strProxyServer;
                    }

                    if (strProxyOverrride != null)
                    {
                        string[] bypassList = strProxyOverrride.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);

                        foreach (string str in bypassList)
                        {
                            if (str != "<local>")
                            {
                                al.Add(str);
                            }
                            else
                            {
                                bBypassOnLocal = true;
                            }
                        }
                    }

                    return(new WebProxy(strHttpProxy, bBypassOnLocal, al.ToArray(typeof(string)) as string[]));
                }
            }
            else
            {
#endif
#if !NETCF
            if (Platform.IsMacOS)
            {
                return(CFNetwork.GetDefaultProxy());
            }
#endif
#if !SSHARP
            string address = Environment.GetEnvironmentVariable("http_proxy");

            if (address == null)
            {
                address = Environment.GetEnvironmentVariable("HTTP_PROXY");
            }

            if (address != null)
            {
                try
                {
                    if (!address.StartsWith("http://"))
                    {
                        address = "http://" + address;
                    }

                    Uri       uri = new Uri(address);
                    IPAddress ip;

                    if (IPAddress.TryParse(uri.Host, out ip))
                    {
                        if (IPAddress.Any.Equals(ip))
                        {
                            UriBuilder builder = new UriBuilder(uri);
                            builder.Host = "127.0.0.1";
                            uri          = builder.Uri;
                        }
                        else if (IPAddress.IPv6Any.Equals(ip))
                        {
                            UriBuilder builder = new UriBuilder(uri);
                            builder.Host = "[::1]";
                            uri          = builder.Uri;
                        }
                    }

                    bool      bBypassOnLocal = false;
                    ArrayList al             = new ArrayList();
                    string    bypass         = Environment.GetEnvironmentVariable("no_proxy");

                    if (bypass == null)
                    {
                        bypass = Environment.GetEnvironmentVariable("NO_PROXY");
                    }

                    if (bypass != null)
                    {
                        string[] bypassList = bypass.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

                        foreach (string str in bypassList)
                        {
                            if (str != "*.local")
                            {
                                al.Add(str);
                            }
                            else
                            {
                                bBypassOnLocal = true;
                            }
                        }
                    }

                    return(new WebProxy(uri, bBypassOnLocal, al.ToArray(typeof(string)) as string[]));
                }
                catch (UriFormatException)
                {
                }
            }
#if !NET_2_1
        }
#endif
#endif
            return(new WebProxy());
#endif // MONOTOUCH
        }