public async Task WhenBehaviorSetToForceAndPermissionsGranted_ThenDialogIsSkippedAndCredentialsAreGenerated()
        {
            var taskDialog = new Mock <ITaskDialog>();

            var credentialPrompt = CreateCredentialsPrompt(true, true, taskDialog);

            var settings = InstanceConnectionSettings.CreateNew(SampleInstance);

            settings.RdpCredentialGenerationBehavior.EnumValue = RdpCredentialGenerationBehavior.Force;

            await credentialPrompt.ShowCredentialsPromptAsync(
                null,
                SampleInstance,
                settings,
                true);

            Assert.AreEqual("bob", settings.RdpUsername.StringValue);
            Assert.AreEqual("secret", settings.RdpPassword.ClearTextValue);
            Assert.IsNull(settings.RdpDomain.Value);

            // No dialog shown.
            taskDialog.Verify(t => t.ShowOptionsTaskDialog(
                                  It.IsAny <IWin32Window>(),
                                  It.IsAny <IntPtr>(),
                                  It.IsAny <string>(),
                                  It.IsAny <string>(),
                                  It.IsAny <string>(),
                                  It.IsAny <string>(),
                                  It.IsAny <IList <string> >(),
                                  It.IsAny <string>(),
                                  out It.Ref <bool> .IsAny), Times.Never);
        }
Пример #2
0
        public async Task WhenNoSuggestedUserNameProvidedAndSilentIsTrue_ThenSuggestionIsDerivedFromSigninNameWithoutPrompting()
        {
            var serviceRegistry = new ServiceRegistry();

            var auth = new Mock <IAuthorization>();

            auth.SetupGet(a => a.Email).Returns("*****@*****.**");
            serviceRegistry.AddMock <IAuthorizationAdapter>()
            .SetupGet(a => a.Authorization).Returns(auth.Object);

            serviceRegistry.AddSingleton <IJobService, SynchronousJobService>();
            serviceRegistry.AddMock <IComputeEngineAdapter>()
            .Setup(a => a.ResetWindowsUserAsync(
                       It.IsAny <InstanceLocator>(),
                       It.Is <string>(user => user == "bobsemail"),
                       It.IsAny <CancellationToken>()))
            .ReturnsAsync(new NetworkCredential("bobsemail", "password"));

            var credDialog = serviceRegistry.AddMock <IGenerateCredentialsDialog>();
            var settings   = InstanceConnectionSettings.CreateNew(SampleInstance);

            var credentialsService = new CredentialsService(serviceRegistry);
            await credentialsService.GenerateCredentialsAsync(
                null,
                SampleInstance,
                settings,
                true);

            Assert.AreEqual("bobsemail", settings.RdpUsername.Value);
            Assert.AreEqual("password", settings.RdpPassword.ClearTextValue);
            credDialog.Verify(d => d.PromptForUsername(
                                  It.IsAny <IWin32Window>(),
                                  It.IsAny <string>()), Times.Never);
        }
        public async Task WhenNoSessionExists_ThenActivateOrConnectInstanceAsyncUsesKeyValidityFromSettings()
        {
            var settings = InstanceConnectionSettings.CreateNew(SampleLocator.ProjectId, SampleLocator.Name);

            settings.SshPort.IntValue        = 2222;
            settings.SshUsername.StringValue = "bob";

            var settingsService = this.serviceRegistry.AddMock <IConnectionSettingsService>();

            settingsService.Setup(s => s.GetConnectionSettings(It.IsAny <IProjectExplorerNode>()))
            .Returns(settings
                     .ToPersistentSettingsCollection(s => Assert.Fail("should not be called")));

            var sshSettingsRepository = this.serviceRegistry.GetService <SshSettingsRepository>();
            var sshSettings           = sshSettingsRepository.GetSettings();

            sshSettings.PublicKeyValidity.IntValue = (int)TimeSpan.FromDays(4).TotalSeconds;
            sshSettingsRepository.SetSettings(sshSettings);

            var vmNode = new Mock <IProjectExplorerInstanceNode>();

            vmNode.SetupGet(n => n.Instance).Returns(SampleLocator);

            var service = new SshConnectionService(this.serviceRegistry);
            await service.ActivateOrConnectInstanceAsync(vmNode.Object);

            this.authorizedKeyService.Verify(s => s.AuthorizeKeyAsync(
                                                 It.Is <InstanceLocator>(l => l == SampleLocator),
                                                 It.IsAny <ISshKey>(),
                                                 It.Is <TimeSpan>(validity => validity == TimeSpan.FromDays(4)),
                                                 It.IsAny <string>(),
                                                 It.IsAny <AuthorizeKeyMethods>(),
                                                 It.IsAny <CancellationToken>()), Times.Once);
        }
        private async Task <IRemoteDesktopSession> Connect(
            IapTunnel tunnel,
            InstanceLocator vmInstanceReference)
        {
            using (var gceAdapter = new ComputeEngineAdapter(this.serviceProvider.GetService <IAuthorizationAdapter>()))
            {
                var credentials = await gceAdapter.ResetWindowsUserAsync(
                    vmInstanceReference,
                    CreateRandomUsername(),
                    TimeSpan.FromSeconds(60),
                    CancellationToken.None);

                var settings = InstanceConnectionSettings.CreateNew(vmInstanceReference);
                settings.RdpUsername.Value            = credentials.UserName;
                settings.RdpPassword.Value            = credentials.SecurePassword;
                settings.RdpAuthenticationLevel.Value = RdpAuthenticationLevel.NoServerAuthentication;
                settings.RdpBitmapPersistence.Value   = RdpBitmapPersistence.Disabled;
                settings.RdpDesktopSize.Value         = RdpDesktopSize.ClientSize;

                var rdpService = new RemoteDesktopSessionBroker(this.serviceProvider);
                return(rdpService.Connect(
                           vmInstanceReference,
                           "localhost",
                           (ushort)tunnel.LocalPort,
                           settings));
            }
        }
Пример #5
0
        public void WhenSuggestedUserNameProvided_ThenSuggestionIsUsed()
        {
            var serviceRegistry = new ServiceRegistry();
            var credDialog      = serviceRegistry.AddMock <IGenerateCredentialsDialog>();

            credDialog
            .Setup(d => d.PromptForUsername(
                       It.IsAny <IWin32Window>(),
                       It.IsAny <string>()))
            .Returns <string>(null);    // Cancel dialog

            var settings = InstanceConnectionSettings.CreateNew(SampleInstance);

            settings.RdpUsername.Value = "alice";

            var credentialsService = new CredentialsService(serviceRegistry);

            AssertEx.ThrowsAggregateException <TaskCanceledException>(
                () => credentialsService.GenerateCredentialsAsync(
                    null,
                    SampleInstance,
                    settings,
                    false).Wait());

            credDialog.Verify(d => d.PromptForUsername(
                                  It.IsAny <IWin32Window>(),
                                  It.Is <string>(u => u == "alice")), Times.Once);
        }
Пример #6
0
        public void WhenNoSuggestedUserNameProvided_ThenSuggestionIsDerivedFromSigninName()
        {
            var serviceRegistry = new ServiceRegistry();

            var auth = new Mock <IAuthorization>();

            auth.SetupGet(a => a.Email).Returns("*****@*****.**");

            serviceRegistry.AddMock <IAuthorizationAdapter>()
            .SetupGet(a => a.Authorization).Returns(auth.Object);

            var credDialog = serviceRegistry.AddMock <IGenerateCredentialsDialog>();

            credDialog
            .Setup(d => d.PromptForUsername(
                       It.IsAny <IWin32Window>(),
                       It.IsAny <string>()))
            .Returns <string>(null);    // Cancel dialog


            var settings = InstanceConnectionSettings.CreateNew(SampleInstance);

            var credentialsService = new CredentialsService(serviceRegistry);

            AssertEx.ThrowsAggregateException <TaskCanceledException>(
                () => credentialsService.GenerateCredentialsAsync(
                    null,
                    SampleInstance,
                    settings,
                    false).Wait());

            credDialog.Verify(d => d.PromptForUsername(
                                  It.IsAny <IWin32Window>(),
                                  It.Is <string>(u => u == "bobsemail")), Times.Once);
        }
        public async Task WhenNoSessionExists_ThenActivateOrConnectInstanceAsyncUsesPreferredUsername()
        {
            var settings = InstanceConnectionSettings.CreateNew(SampleLocator.ProjectId, SampleLocator.Name);

            settings.SshPort.IntValue        = 2222;
            settings.SshUsername.StringValue = "bob";

            var settingsService = this.serviceRegistry.AddMock <IConnectionSettingsService>();

            settingsService.Setup(s => s.GetConnectionSettings(It.IsAny <IProjectExplorerNode>()))
            .Returns(settings
                     .ToPersistentSettingsCollection(s => Assert.Fail("should not be called")));

            var vmNode = new Mock <IProjectExplorerVmInstanceNode>();

            vmNode.SetupGet(n => n.Reference).Returns(SampleLocator);

            var service = new SshConnectionService(this.serviceRegistry);
            await service.ActivateOrConnectInstanceAsync(vmNode.Object);

            this.authorizedKeyService.Verify(s => s.AuthorizeKeyAsync(
                                                 It.Is <InstanceLocator>(l => l == SampleLocator),
                                                 It.IsAny <ISshKey>(),
                                                 It.IsAny <TimeSpan>(),
                                                 It.Is <string>(user => user == "bob"),
                                                 It.IsAny <AuthorizeKeyMethods>(),
                                                 It.IsAny <CancellationToken>()), Times.Once);
        }
        public async Task WhenNoSessionExists_ThenActivateOrConnectInstanceAsyncUsesConnectionTimeout()
        {
            var settings = InstanceConnectionSettings.CreateNew(SampleLocator.ProjectId, SampleLocator.Name);

            settings.SshPort.IntValue = 2222;
            settings.SshConnectionTimeout.IntValue = (int)TimeSpan.FromSeconds(123).TotalSeconds;

            var settingsService = this.serviceRegistry.AddMock <IConnectionSettingsService>();

            settingsService.Setup(s => s.GetConnectionSettings(It.IsAny <IProjectExplorerNode>()))
            .Returns(settings
                     .ToPersistentSettingsCollection(s => Assert.Fail("should not be called")));

            var vmNode = new Mock <IProjectExplorerVmInstanceNode>();

            vmNode.SetupGet(n => n.Reference).Returns(SampleLocator);

            var service = new SshConnectionService(this.serviceRegistry);
            await service.ActivateOrConnectInstanceAsync(vmNode.Object);

            this.tunnelBrokerService.Verify(s => s.ConnectAsync(
                                                It.Is <TunnelDestination>(d => d.RemotePort == 2222),
                                                It.IsAny <ISshRelayPolicy>(),
                                                It.Is <TimeSpan>(t => t == TimeSpan.FromSeconds(123))), Times.Once);
        }
        public async Task WhenCredentialsInvalid_ThenErrorIsShownAndWindowIsClosed(
            [WindowsInstance(MachineType = MachineTypeForRdp)] ResourceTask <InstanceLocator> testInstance,
            [Credential(Role = PredefinedRole.IapTunnelUser)] ResourceTask <ICredential> credential)
        {
            var locator = await testInstance;

            using (var tunnel = IapTunnel.ForRdp(
                       locator,
                       await credential))
            {
                var settings = InstanceConnectionSettings.CreateNew(
                    locator.ProjectId,
                    locator.Name);
                settings.RdpUsername.StringValue                 = "wrong";
                settings.RdpPassword.Value                       = SecureStringExtensions.FromClearText("wrong");
                settings.RdpAuthenticationLevel.EnumValue        = RdpAuthenticationLevel.NoServerAuthentication;
                settings.RdpUserAuthenticationBehavior.EnumValue = RdpUserAuthenticationBehavior.AbortOnFailure;
                settings.RdpDesktopSize.EnumValue                = RdpDesktopSize.ClientSize;

                var rdpService = new RemoteDesktopSessionBroker(this.serviceProvider);
                var session    = rdpService.Connect(
                    locator,
                    "localhost",
                    (ushort)tunnel.LocalPort,
                    settings);

                AwaitEvent <SessionAbortedEvent>();
                Assert.IsNotNull(this.ExceptionShown);
                Assert.IsInstanceOf(typeof(RdpDisconnectedException), this.ExceptionShown);
                Assert.AreEqual(2055, ((RdpDisconnectedException)this.ExceptionShown).DisconnectReason);
            }
        }
        public void WhenParseStringCreatedByToString_ResultIsSame()
        {
            var settings = InstanceConnectionSettings.CreateNew("project-1", "instance-1");

            settings.RdpUsername.Value                     = "user";
            settings.RdpDomain.Value                       = "domain";
            settings.RdpConnectionBar.Value                = RdpConnectionBarState.Off;
            settings.RdpDesktopSize.Value                  = RdpDesktopSize.ScreenSize;
            settings.RdpAuthenticationLevel.Value          = RdpAuthenticationLevel.RequireServerAuthentication;
            settings.RdpColorDepth.Value                   = RdpColorDepth.TrueColor;
            settings.RdpAudioMode.Value                    = RdpAudioMode.PlayOnServer;
            settings.RdpRedirectClipboard.Value            = RdpRedirectClipboard.Disabled;
            settings.RdpCredentialGenerationBehavior.Value = RdpCredentialGenerationBehavior.Disallow;

            var url = new IapRdpUrl(
                new InstanceLocator("project-1", "us-central1-a", "instance-1"),
                settings.ToUrlQuery());

            var copy = InstanceConnectionSettings.FromUrl(url);

            Assert.AreEqual("user", copy.RdpUsername.Value);
            Assert.AreEqual("domain", copy.RdpDomain.Value);
            Assert.AreEqual(RdpConnectionBarState.Off, copy.RdpConnectionBar.Value);
            Assert.AreEqual(RdpDesktopSize.ScreenSize, copy.RdpDesktopSize.Value);
            Assert.AreEqual(RdpAuthenticationLevel.RequireServerAuthentication, copy.RdpAuthenticationLevel.Value);
            Assert.AreEqual(RdpColorDepth.TrueColor, copy.RdpColorDepth.Value);
            Assert.AreEqual(RdpAudioMode.PlayOnServer, copy.RdpAudioMode.Value);
            Assert.AreEqual(RdpRedirectClipboard.Disabled, copy.RdpRedirectClipboard.Value);
            Assert.AreEqual(RdpCredentialGenerationBehavior.Disallow, copy.RdpCredentialGenerationBehavior.Value);
        }
        public void WhenKeyAuthorizationFails_ThenActivateOrConnectInstanceAsyncActivatesSessionThrowsSshKeyPushFailedException()
        {
            var settingsService = this.serviceRegistry.AddMock <IConnectionSettingsService>();

            settingsService.Setup(s => s.GetConnectionSettings(It.IsAny <IProjectExplorerNode>()))
            .Returns(
                InstanceConnectionSettings
                .CreateNew(SampleLocator.ProjectId, SampleLocator.Name)
                .ToPersistentSettingsCollection(s => Assert.Fail("should not be called")));

            this.authorizedKeyService.Setup(a => a.AuthorizeKeyAsync(
                                                It.IsAny <InstanceLocator>(),
                                                It.IsAny <ISshKey>(),
                                                It.IsAny <TimeSpan>(),
                                                It.IsAny <string>(),
                                                It.IsAny <AuthorizeKeyMethods>(),
                                                It.IsAny <CancellationToken>()))
            .ThrowsAsync(new SshKeyPushFailedException("mock", HelpTopics.ManagingOsLogin));

            var vmNode = new Mock <IProjectExplorerVmInstanceNode>();

            vmNode.SetupGet(n => n.Reference).Returns(SampleLocator);

            var service = new SshConnectionService(this.serviceRegistry);

            AssertEx.ThrowsAggregateException <SshKeyPushFailedException>(
                () => service.ActivateOrConnectInstanceAsync(vmNode.Object).Wait());
        }
        public void WhenQueryStringContainsValidUserOrDomain_ThenSettingsUseDecodedValues()
        {
            var url = IapRdpUrl.FromString("iap-rdp:///my-project/us-central1-a/my-instance?" +
                                           "userNAME=John%20Doe&PassworD=ignore&Domain=%20%20mydomain&");
            var settings = InstanceConnectionSettings.FromUrl(url);

            Assert.AreEqual("John Doe", settings.RdpUsername.Value);
            Assert.IsNull(settings.RdpPassword.Value);
            Assert.AreEqual("  mydomain", settings.RdpDomain.Value);
        }
Пример #13
0
        public async Task WhenConnectingByUrlWithUsernameAndCredentialsExist_ThenConnectionIsMadeWithUsernameFromUrl()
        {
            var settings = InstanceConnectionSettings.CreateNew("project", "instance-1");

            settings.RdpUsername.Value = "existinguser";
            settings.RdpPassword.Value = SecureStringExtensions.FromClearText("password");

            var settingsService = this.serviceRegistry.AddMock <IConnectionSettingsService>();

            settingsService.Setup(s => s.GetConnectionSettings(
                                      It.IsAny <IProjectModelNode>()))
            .Returns(
                settings.ToPersistentSettingsCollection(s => Assert.Fail("should not be called")));

            var vmNode = new Mock <IProjectModelInstanceNode>();

            vmNode.SetupGet(n => n.Instance)
            .Returns(new InstanceLocator("project-1", "zone-1", "instance-1"));

            this.serviceRegistry.AddMock <ICredentialPrompt>()
            .Setup(p => p.ShowCredentialsPromptAsync(
                       It.IsAny <IWin32Window>(),
                       It.IsAny <InstanceLocator>(),
                       It.IsAny <ConnectionSettingsBase>(),
                       It.IsAny <bool>()));
            this.serviceRegistry.AddMock <IProjectModelService>()
            .Setup(p => p.GetNodeAsync(
                       It.IsAny <ResourceLocator>(),
                       It.IsAny <CancellationToken>()))
            .ReturnsAsync(vmNode.Object);

            var remoteDesktopService = new Mock <IRemoteDesktopSessionBroker>();

            remoteDesktopService.Setup(s => s.Connect(
                                           It.IsAny <InstanceLocator>(),
                                           "localhost",
                                           It.IsAny <ushort>(),
                                           It.IsAny <InstanceConnectionSettings>())).Returns <IRemoteDesktopSession>(null);

            this.serviceRegistry.AddSingleton <IRemoteDesktopSessionBroker>(remoteDesktopService.Object);

            var service = new RdpConnectionService(this.serviceRegistry);
            await service.ActivateOrConnectInstanceAsync(
                IapRdpUrl.FromString("iap-rdp:///project/us-central-1/instance-1?username=john%20doe"));

            remoteDesktopService.Verify(s => s.Connect(
                                            It.IsAny <InstanceLocator>(),
                                            "localhost",
                                            It.IsAny <ushort>(),
                                            It.Is <InstanceConnectionSettings>(i => i.RdpUsername.StringValue == "john doe")), Times.Once);
            settingsService.Verify(s => s.GetConnectionSettings(
                                       It.IsAny <IProjectModelNode>()), Times.Once);
        }
Пример #14
0
        private async Task ConnectInstanceAsync(
            InstanceLocator instance,
            InstanceConnectionSettings settings)
        {
            var tunnel = await this.jobService.RunInBackground(
                new JobDescription(
                    $"Opening Cloud IAP tunnel to {instance.Name}...",
                    JobUserFeedbackType.BackgroundFeedback),
                async token =>
            {
                try
                {
                    var destination = new TunnelDestination(
                        instance,
                        (ushort)settings.RdpPort.IntValue);

                    // Give IAP the same timeout for probing as RDP itself.
                    // Note that the timeouts are not additive.
                    var timeout = TimeSpan.FromSeconds(settings.RdpConnectionTimeout.IntValue);

                    return(await this.tunnelBroker.ConnectAsync(
                               destination,
                               new SameProcessRelayPolicy(),
                               timeout)
                           .ConfigureAwait(false));
                }
                catch (NetworkStreamClosedException e)
                {
                    throw new ConnectionFailedException(
                        "Connecting to the instance failed. Make sure that you have " +
                        "configured your firewall rules to permit Cloud IAP access " +
                        $"to {instance.Name}",
                        HelpTopics.CreateIapFirewallRule,
                        e);
                }
                catch (UnauthorizedException)
                {
                    throw new ConnectionFailedException(
                        "You are not authorized to connect to this VM instance.\n\n" +
                        $"Verify that the Cloud IAP API is enabled in the project {instance.ProjectId} " +
                        "and that your user has the 'IAP-secured Tunnel User' role.",
                        HelpTopics.IapAccess);
                }
            }).ConfigureAwait(true);

            this.sessionBroker.Connect(
                instance,
                "localhost",
                (ushort)tunnel.LocalPort,
                settings);
        }
Пример #15
0
        public async Task WhenConnectingByNodeAndPersistentCredentialsAllowed_ThenCredentialsAreUsed()
        {
            var settings = InstanceConnectionSettings.CreateNew("project", "instance-1");

            settings.RdpUsername.Value = "existinguser";
            settings.RdpPassword.Value = SecureStringExtensions.FromClearText("password");

            bool settingsSaved = false;

            var settingsService = this.serviceRegistry.AddMock <IConnectionSettingsService>();

            settingsService.Setup(s => s.GetConnectionSettings(
                                      It.IsAny <IProjectExplorerNode>()))
            .Returns(
                settings.ToPersistentSettingsCollection(s => settingsSaved = true));

            var vmNode = new Mock <IProjectExplorerInstanceNode>();

            vmNode.SetupGet(n => n.Instance)
            .Returns(new InstanceLocator("project-1", "zone-1", "instance-1"));

            this.serviceRegistry.AddMock <IProjectExplorer>()
            .Setup(p => p.TryFindNode(
                       It.IsAny <InstanceLocator>()))
            .Returns(vmNode.Object);

            var remoteDesktopService = new Mock <IRemoteDesktopSessionBroker>();

            remoteDesktopService.Setup(s => s.Connect(
                                           It.IsAny <InstanceLocator>(),
                                           "localhost",
                                           It.IsAny <ushort>(),
                                           It.IsAny <InstanceConnectionSettings>())).Returns <IRemoteDesktopSession>(null);

            this.serviceRegistry.AddSingleton <IRemoteDesktopSessionBroker>(remoteDesktopService.Object);

            var service = new RdpConnectionService(this.serviceRegistry);
            await service.ActivateOrConnectInstanceAsync(vmNode.Object, true);

            remoteDesktopService.Verify(s => s.Connect(
                                            It.IsAny <InstanceLocator>(),
                                            "localhost",
                                            It.IsAny <ushort>(),
                                            It.Is <InstanceConnectionSettings>(i =>
                                                                               i.RdpUsername.StringValue == "existinguser" &&
                                                                               i.RdpPassword.ClearTextValue == "password")), Times.Once);

            Assert.IsTrue(settingsSaved);
        }
        public async Task WhenCredentialsFoundAndBehaviorSetToAllowIfNoCredentialsFound_ThenDialogIsSkipped(
            [Values(true, false)] bool isGrantedPermissionToGenerateCredentials)
        {
            var taskDialog = new Mock <ITaskDialog>();

            taskDialog.Setup(t => t.ShowOptionsTaskDialog(
                                 It.IsAny <IWin32Window>(),
                                 It.IsAny <IntPtr>(),
                                 It.IsAny <string>(),
                                 It.IsAny <string>(),
                                 It.IsAny <string>(),
                                 It.IsAny <string>(),
                                 It.IsAny <IList <string> >(),
                                 It.IsAny <string>(),
                                 out It.Ref <bool> .IsAny)).Returns(0);

            var credentialPrompt = CreateCredentialsPrompt(
                isGrantedPermissionToGenerateCredentials,
                false,
                taskDialog);

            var settings = InstanceConnectionSettings.CreateNew(SampleInstance);

            settings.RdpCredentialGenerationBehavior.EnumValue = RdpCredentialGenerationBehavior.AllowIfNoCredentialsFound;
            settings.RdpUsername.StringValue    = "alice";
            settings.RdpPassword.ClearTextValue = "alicespassword";

            await credentialPrompt.ShowCredentialsPromptAsync(
                null,
                SampleInstance,
                settings,
                true);

            Assert.AreEqual("alice", settings.RdpUsername.Value);
            Assert.AreEqual("alicespassword", settings.RdpPassword.ClearTextValue);
            Assert.IsNull(settings.RdpDomain.Value);

            taskDialog.Verify(t => t.ShowOptionsTaskDialog(
                                  It.IsAny <IWin32Window>(),
                                  It.IsAny <IntPtr>(),
                                  It.IsAny <string>(),
                                  It.IsAny <string>(),
                                  It.IsAny <string>(),
                                  It.IsAny <string>(),
                                  It.IsAny <IList <string> >(),
                                  It.IsAny <string>(),
                                  out It.Ref <bool> .IsAny), Times.Never);
        }
        public void WhenVmInstanceSettingsArePopulated_ThenToUrlQueryExcludesPassword()
        {
            var settings = InstanceConnectionSettings.CreateNew("pro-1", "instance-1");

            settings.RdpUsername.Value              = "bob";
            settings.RdpPassword.ClearTextValue     = "secret";
            settings.RdpRedirectClipboard.EnumValue = RdpRedirectClipboard.Disabled;
            settings.RdpConnectionTimeout.IntValue  = 123;

            var query = settings.ToUrlQuery();

            Assert.AreEqual(3, query.Count);
            Assert.AreEqual("bob", query["Username"]);
            Assert.AreEqual("0", query["RedirectClipboard"]);
            Assert.AreEqual("123", query["ConnectionTimeout"]);
        }
        public void WhenSettingsContainsEscapableChars_ThenToStringEscapesThem()
        {
            var settings = InstanceConnectionSettings.CreateNew("project-1", "instance-1");

            settings.RdpUsername.Value = "Tom & Jerry?";
            settings.RdpDomain.Value   = "\"?\"";

            var url = new IapRdpUrl(
                new InstanceLocator("project-1", "us-central1-a", "instance-1"),
                settings.ToUrlQuery());

            Assert.AreEqual(
                "iap-rdp:///project-1/us-central1-a/instance-1?" +
                "Username=Tom+%26+Jerry%3f&Domain=%22%3f%22",
                url.ToString());
        }
        public void WhenServerInvalid_ThenErrorIsShownAndWindowIsClosed()
        {
            var settings = InstanceConnectionSettings.CreateNew(this.SampleLocator);

            var rdpService = new RemoteDesktopSessionBroker(this.serviceProvider);

            rdpService.Connect(
                this.SampleLocator,
                "invalid.corp",
                3389,
                settings);

            AwaitEvent <SessionAbortedEvent>();
            Assert.IsInstanceOf(typeof(RdpDisconnectedException), this.ExceptionShown);
            Assert.AreEqual(260, ((RdpDisconnectedException)this.ExceptionShown).DisconnectReason);
        }
        public void WhenQueryStringContainsNonsense_ThenSettingsUsesDefaults()
        {
            var url      = IapRdpUrl.FromString("iap-rdp:///my-project/us-central1-a/my-instance?a=b&user=wrongcase&_");
            var settings = InstanceConnectionSettings.FromUrl(url);

            Assert.IsNull(settings.RdpUsername.Value);
            Assert.IsNull(settings.RdpPassword.Value);
            Assert.IsNull(settings.RdpDomain.Value);
            Assert.AreEqual(RdpConnectionBarState._Default, settings.RdpConnectionBar.Value);
            Assert.AreEqual(RdpDesktopSize._Default, settings.RdpDesktopSize.Value);
            Assert.AreEqual(RdpAuthenticationLevel._Default, settings.RdpAuthenticationLevel.Value);
            Assert.AreEqual(RdpColorDepth._Default, settings.RdpColorDepth.Value);
            Assert.AreEqual(RdpAudioMode._Default, settings.RdpAudioMode.Value);
            Assert.AreEqual(RdpRedirectClipboard._Default, settings.RdpRedirectClipboard.Value);
            Assert.AreEqual(RdpCredentialGenerationBehavior._Default, settings.RdpCredentialGenerationBehavior.Value);
        }
        public void WhenWrongPort_ThenErrorIsShownAndWindowIsClosed()
        {
            var settings = InstanceConnectionSettings.CreateNew(this.SampleLocator);

            var rdpService = new RemoteDesktopSessionBroker(this.serviceProvider);

            rdpService.Connect(
                this.SampleLocator,
                "localhost",
                135,    // That one will be listening, but it is RPC, not RDP.
                settings);

            AwaitEvent <SessionAbortedEvent>();
            Assert.IsInstanceOf(typeof(RdpDisconnectedException), this.ExceptionShown);
            Assert.AreEqual(2308, ((RdpDisconnectedException)this.ExceptionShown).DisconnectReason);
        }
        public void WhenQueryStringContainsValidSettings_ThenSettingsUseDecodedValues()
        {
            var url = IapRdpUrl.FromString("iap-rdp:///my-project/us-central1-a/my-instance?" +
                                           "ConnectionBar=1&DesktopSize=1&AuthenticationLevel=0&ColorDepth=2&" +
                                           "AudioMode=2&RedirectClipboard=0&CredentialGenerationBehavior=0&Rdpport=13389");
            var settings = InstanceConnectionSettings.FromUrl(url);

            Assert.AreEqual(RdpConnectionBarState.Pinned, settings.RdpConnectionBar.Value);
            Assert.AreEqual(RdpDesktopSize.ScreenSize, settings.RdpDesktopSize.Value);
            Assert.AreEqual(RdpAuthenticationLevel.AttemptServerAuthentication, settings.RdpAuthenticationLevel.Value);
            Assert.AreEqual(RdpColorDepth.DeepColor, settings.RdpColorDepth.Value);
            Assert.AreEqual(RdpAudioMode.DoNotPlay, settings.RdpAudioMode.Value);
            Assert.AreEqual(RdpRedirectClipboard.Disabled, settings.RdpRedirectClipboard.Value);
            Assert.AreEqual(RdpCredentialGenerationBehavior.Allow, settings.RdpCredentialGenerationBehavior.Value);
            Assert.AreEqual(13389, settings.RdpPort.Value);
        }
        public async Task WhenSigningOutPerSendKeys_ThenWindowIsClosed(
            [WindowsInstance(ImageFamily = WindowsInstanceAttribute.WindowsServer2019)]
            ResourceTask <InstanceLocator> testInstance,
            [Credential(Role = PredefinedRole.IapTunnelUser)] ResourceTask <ICredential> credential)
        {
            var locator = await testInstance;

            using (var tunnel = IapTunnel.ForRdp(
                       locator,
                       await credential))
                using (var gceAdapter = new ComputeEngineAdapter(this.serviceProvider.GetService <IAuthorizationAdapter>()))
                {
                    var credentials = await gceAdapter.ResetWindowsUserAsync(
                        locator,
                        CreateRandomUsername(),
                        TimeSpan.FromSeconds(60),
                        CancellationToken.None);

                    var settings = InstanceConnectionSettings.CreateNew(
                        locator.ProjectId,
                        locator.Name);
                    settings.RdpUsername.StringValue          = credentials.UserName;
                    settings.RdpPassword.Value                = credentials.SecurePassword;
                    settings.RdpAuthenticationLevel.EnumValue = RdpAuthenticationLevel.NoServerAuthentication;
                    settings.RdpBitmapPersistence.EnumValue   = RdpBitmapPersistence.Disabled;
                    settings.RdpDesktopSize.EnumValue         = RdpDesktopSize.ClientSize;

                    var rdpService = new RemoteDesktopSessionBroker(this.serviceProvider);
                    var session    = (RemoteDesktopPane)rdpService.Connect(
                        locator,
                        "localhost",
                        (ushort)tunnel.LocalPort,
                        settings);

                    AwaitEvent <SessionStartedEvent>();

                    Thread.Sleep(5000);
                    session.ShowSecurityScreen();
                    Thread.Sleep(1000);
                    session.SendKeys(Keys.Menu, Keys.S); // Sign out.

                    AwaitEvent <SessionEndedEvent>();
                    Assert.IsNull(this.ExceptionShown);
                }
        }
        public void WhenPortNotListening_ThenErrorIsShownAndWindowIsClosed()
        {
            var settings = InstanceConnectionSettings.CreateNew(this.SampleLocator);

            settings.RdpConnectionTimeout.IntValue = 5;

            var rdpService = new RemoteDesktopSessionBroker(this.serviceProvider);

            rdpService.Connect(
                this.SampleLocator,
                "localhost",
                1,
                settings);

            AwaitEvent <SessionAbortedEvent>();
            Assert.IsInstanceOf(typeof(RdpDisconnectedException), this.ExceptionShown);
            Assert.AreEqual(516, ((RdpDisconnectedException)this.ExceptionShown).DisconnectReason);
        }
Пример #25
0
        public async Task WhenConnected_ThenGetActivePaneReturnsPane(
            [WindowsInstance(MachineType = MachineTypeForRdp)] ResourceTask <InstanceLocator> testInstance,
            [Credential(Role = PredefinedRole.IapTunnelUser)] ResourceTask <ICredential> credential)
        {
            var locator = await testInstance;

            using (var tunnel = IapTunnel.ForRdp(
                       locator,
                       await credential))
                using (var gceAdapter = new ComputeEngineAdapter(this.serviceProvider.GetService <IAuthorizationAdapter>()))
                {
                    var credentials = await gceAdapter.ResetWindowsUserAsync(
                        locator,
                        CreateRandomUsername(),
                        TimeSpan.FromSeconds(60),
                        CancellationToken.None);

                    var settings = InstanceConnectionSettings.CreateNew(
                        locator.ProjectId,
                        locator.Name);
                    settings.RdpUsername.StringValue = credentials.UserName;
                    settings.RdpPassword.Value       = credentials.SecurePassword;

                    // Connect
                    var broker = new RemoteDesktopSessionBroker(this.serviceProvider);
                    IRemoteDesktopSession session = null;
                    AssertRaisesEvent <SessionStartedEvent>(
                        () => session = (RemoteDesktopPane)broker.Connect(
                            locator,
                            "localhost",
                            (ushort)tunnel.LocalPort,
                            settings));

                    Assert.IsNull(this.ExceptionShown);

                    Assert.AreSame(session, RemoteDesktopPane.TryGetActivePane(this.mainForm));
                    Assert.AreSame(session, RemoteDesktopPane.TryGetExistingPane(this.mainForm, locator));
                    Assert.IsTrue(broker.IsConnected(locator));
                    Assert.IsTrue(broker.TryActivate(locator));

                    AssertRaisesEvent <SessionEndedEvent>(
                        () => session.Close());
                }
        }
        public void WhenQueryStringContainsOutOfRangeValues_ThenSettingsUsesDefaults()
        {
            var url = IapRdpUrl.FromString("iap-rdp:///my-project/us-central1-a/my-instance?" +
                                           "ConnectionBar=-1&DesktopSize=a&AuthenticationLevel=null&ColorDepth=&" +
                                           "AudioMode=9999&RedirectClipboard=b&RedirectClipboard=c&" +
                                           "CredentialGenerationBehavior=-11");
            var settings = InstanceConnectionSettings.FromUrl(url);

            Assert.IsNull(settings.RdpUsername.Value);
            Assert.IsNull(settings.RdpPassword.Value);
            Assert.IsNull(settings.RdpDomain.Value);
            Assert.AreEqual(RdpConnectionBarState._Default, settings.RdpConnectionBar.Value);
            Assert.AreEqual(RdpDesktopSize._Default, settings.RdpDesktopSize.Value);
            Assert.AreEqual(RdpAuthenticationLevel._Default, settings.RdpAuthenticationLevel.Value);
            Assert.AreEqual(RdpColorDepth._Default, settings.RdpColorDepth.Value);
            Assert.AreEqual(RdpAudioMode._Default, settings.RdpAudioMode.Value);
            Assert.AreEqual(RdpRedirectClipboard._Default, settings.RdpRedirectClipboard.Value);
            Assert.AreEqual(RdpCredentialGenerationBehavior._Default, settings.RdpCredentialGenerationBehavior.Value);
        }
Пример #27
0
        public async Task WhenConnectingByNodeAndPersistentCredentialsDisallowed_ThenPasswordIsClear()
        {
            var settings = InstanceConnectionSettings.CreateNew("project", "instance-1");

            settings.RdpUsername.Value = "existinguser";
            settings.RdpPassword.Value = SecureStringExtensions.FromClearText("password");

            var settingsService = this.serviceRegistry.AddMock <IConnectionSettingsService>();

            settingsService.Setup(s => s.GetConnectionSettings(
                                      It.IsAny <IProjectModelNode>()))
            .Returns(
                settings.ToPersistentSettingsCollection(s => Assert.Fail("should not be called")));

            var vmNode = CreateInstanceNodeMock();

            this.serviceRegistry.AddMock <IProjectModelService>()
            .Setup(p => p.GetNodeAsync(
                       It.IsAny <ResourceLocator>(),
                       It.IsAny <CancellationToken>()))
            .ReturnsAsync(vmNode.Object);

            var remoteDesktopService = new Mock <IRemoteDesktopSessionBroker>();

            remoteDesktopService.Setup(s => s.Connect(
                                           It.IsAny <InstanceLocator>(),
                                           "localhost",
                                           It.IsAny <ushort>(),
                                           It.IsAny <InstanceConnectionSettings>())).Returns <IRemoteDesktopSession>(null);

            this.serviceRegistry.AddSingleton <IRemoteDesktopSessionBroker>(remoteDesktopService.Object);

            var service = new RdpConnectionService(this.serviceRegistry);
            await service.ActivateOrConnectInstanceAsync(vmNode.Object, false);

            remoteDesktopService.Verify(s => s.Connect(
                                            It.IsAny <InstanceLocator>(),
                                            "localhost",
                                            It.IsAny <ushort>(),
                                            It.Is <InstanceConnectionSettings>(i =>
                                                                               i.RdpUsername.StringValue == "existinguser" &&
                                                                               i.RdpPassword.ClearTextValue == "")), Times.Once);
        }
        public async Task WhenNoCredentialsFoundAndPermissionGrantedAndBehaviorSetToAllowIfNoCredentialsFound_ThenGenerateOptionIsShown()
        {
            var taskDialog = new Mock <ITaskDialog>();

            taskDialog.Setup(t => t.ShowOptionsTaskDialog(
                                 It.IsAny <IWin32Window>(),
                                 It.IsAny <IntPtr>(),
                                 It.IsAny <string>(),
                                 It.IsAny <string>(),
                                 It.IsAny <string>(),
                                 It.IsAny <string>(),
                                 It.IsAny <IList <string> >(),
                                 It.IsAny <string>(),
                                 out It.Ref <bool> .IsAny)).Returns(0);

            var credentialPrompt = CreateCredentialsPrompt(true, false, taskDialog);

            var settings = InstanceConnectionSettings.CreateNew(SampleInstance);

            settings.RdpCredentialGenerationBehavior.EnumValue = RdpCredentialGenerationBehavior.AllowIfNoCredentialsFound;

            await credentialPrompt.ShowCredentialsPromptAsync(
                null,
                SampleInstance,
                settings,
                true);

            Assert.AreEqual("bob", settings.RdpUsername.Value);
            Assert.AreEqual("secret", settings.RdpPassword.ClearTextValue);
            Assert.IsNull(settings.RdpDomain.Value);

            taskDialog.Verify(t => t.ShowOptionsTaskDialog(
                                  It.IsAny <IWin32Window>(),
                                  It.IsAny <IntPtr>(),
                                  It.IsAny <string>(),
                                  It.IsAny <string>(),
                                  It.IsAny <string>(),
                                  It.IsAny <string>(),
                                  It.Is <IList <string> >(options => options.Count == 3),
                                  It.IsAny <string>(),
                                  out It.Ref <bool> .IsAny), Times.Once);
        }
        public async Task WhenNoCredentialsFoundAndBehaviorSetToDisallowAndJumpToSettingsNotAllowed_ThenDialogIsSkipped()
        {
            var taskDialog = new Mock <ITaskDialog>();

            taskDialog.Setup(t => t.ShowOptionsTaskDialog(
                                 It.IsAny <IWin32Window>(),
                                 It.IsAny <IntPtr>(),
                                 It.IsAny <string>(),
                                 It.IsAny <string>(),
                                 It.IsAny <string>(),
                                 It.IsAny <string>(),
                                 It.IsAny <IList <string> >(),
                                 It.IsAny <string>(),
                                 out It.Ref <bool> .IsAny)).Returns(1);

            var credentialPrompt = CreateCredentialsPrompt(true, false, taskDialog);

            var settings = InstanceConnectionSettings.CreateNew(SampleInstance);

            settings.RdpCredentialGenerationBehavior.EnumValue = RdpCredentialGenerationBehavior.Disallow;

            await credentialPrompt.ShowCredentialsPromptAsync(
                null,
                SampleInstance,
                settings,
                false);

            Assert.IsNull(settings.RdpUsername.Value);
            Assert.IsNull(settings.RdpPassword.Value);
            Assert.IsNull(settings.RdpDomain.Value);

            taskDialog.Verify(t => t.ShowOptionsTaskDialog(
                                  It.IsAny <IWin32Window>(),
                                  It.IsAny <IntPtr>(),
                                  It.IsAny <string>(),
                                  It.IsAny <string>(),
                                  It.IsAny <string>(),
                                  It.IsAny <string>(),
                                  It.IsAny <IList <string> >(),
                                  It.IsAny <string>(),
                                  out It.Ref <bool> .IsAny), Times.Never);
        }
        public void WhenBehaviorSetToForceAndPermissionsNotGranted_ThenJumpToSettingsOptionIsShown()
        {
            var taskDialog = new Mock <ITaskDialog>();

            taskDialog.Setup(t => t.ShowOptionsTaskDialog(
                                 It.IsAny <IWin32Window>(),
                                 It.IsAny <IntPtr>(),
                                 It.IsAny <string>(),
                                 It.IsAny <string>(),
                                 It.IsAny <string>(),
                                 It.IsAny <string>(),
                                 It.IsAny <IList <string> >(),
                                 It.IsAny <string>(),
                                 out It.Ref <bool> .IsAny)).Returns(0);

            var credentialPrompt = CreateCredentialsPrompt(false, false, taskDialog);
            var window           = this.serviceRegistry.AddMock <IConnectionSettingsWindow>();

            var settings = InstanceConnectionSettings.CreateNew(SampleInstance);

            settings.RdpCredentialGenerationBehavior.EnumValue = RdpCredentialGenerationBehavior.Force;

            AssertEx.ThrowsAggregateException <TaskCanceledException>(
                () => credentialPrompt.ShowCredentialsPromptAsync(
                    null,
                    SampleInstance,
                    settings,
                    true).Wait());

            window.Verify(w => w.ShowWindow(), Times.Once);
            taskDialog.Verify(t => t.ShowOptionsTaskDialog(
                                  It.IsAny <IWin32Window>(),
                                  It.IsAny <IntPtr>(),
                                  It.IsAny <string>(),
                                  It.IsAny <string>(),
                                  It.IsAny <string>(),
                                  It.IsAny <string>(),
                                  It.Is <IList <string> >(options => options.Count == 2),
                                  It.IsAny <string>(),
                                  out It.Ref <bool> .IsAny), Times.Once);
        }