Beispiel #1
0
        public async Task <NetworkCredential> GenerateAndSaveCredentialsAsync(
            IWin32Window owner,
            VmInstanceNode vmNode,
            string suggestedUsername = null)
        {
            var credentials = await GenerateCredentialsAsync(
                owner,
                vmNode.Reference,
                suggestedUsername ?? this.authService.Authorization.SuggestWindowsUsername());

            if (credentials == null)
            {
                // Aborted.
                return(null);
            }

            // Update node to persist settings.
            vmNode.Username          = credentials.UserName;
            vmNode.CleartextPassword = credentials.Password;
            vmNode.Domain            = null;
            vmNode.SaveChanges();

            // Fire an event to update anybody using the node.
            await this.eventService.FireAsync(new ProjectExplorerNodeSelectedEvent(vmNode));

            return(credentials);
        }
        public async Task ActivateOrConnectInstanceWithCredentialPromptAsync(
            IWin32Window owner,
            VmInstanceNode vmNode)
        {
            if (this.remoteDesktopService.TryActivate(vmNode.Reference))
            {
                // RDP session was active, nothing left to do.
                return;
            }

            // Select node so that tracking windows are updated.
            vmNode.Select();

            var settings = vmNode.SettingsEditor;

            if (string.IsNullOrEmpty(settings.Username) || settings.Password == null || settings.Password.Length == 0)
            {
                int selectedOption = this.taskDialog.ShowOptionsTaskDialog(
                    owner,
                    UnsafeNativeMethods.TD_INFORMATION_ICON,
                    "Credentials",
                    $"You have not configured any credentials for {vmNode.InstanceName}",
                    "Would you like to configure or generate credentials now?",
                    null,
                    new[]
                {
                    "Configure credentials",
                    "Generate new credentials", // Same as pressing 'OK'
                    "Connect anyway"            // Same as pressing 'Cancel'
                },
                    null,                       //"Do not show this prompt again",
                    out bool donotAskAgain);

                if (selectedOption == 0)
                {
                    // Configure credentials -> jump to settings.
                    this.settingsEditor.ShowWindow();

                    return;
                }
                else if (selectedOption == 1)
                {
                    // Generate new credentials.
                    await this.credentialsService.GenerateCredentialsAsync(
                        owner,
                        vmNode.Reference,
                        vmNode.SettingsEditor)
                    .ConfigureAwait(true);
                }
                else if (selectedOption == 2)
                {
                    // Cancel - just continue connecting.
                }
            }

            await ConnectInstanceAsync(
                vmNode.Reference,
                vmNode.CreateConnectionSettings())
            .ConfigureAwait(true);
        }
Beispiel #3
0
        private async Task GenerateCredentials(VmInstanceNode vmNode)
        {
            // Derive a suggested username from the Windows login name.
            var suggestedUsername = Environment.UserName;

            // Prompt for username to use.
            var username = new GenerateCredentialsDialog().PromptForUsername(this, suggestedUsername);

            if (username == null)
            {
                return;
            }

            var credentials = await this.jobService.RunInBackground(
                new JobDescription("Generating Windows logon credentials..."),
                token =>
            {
                return(this.serviceProvider.GetService <IComputeEngineAdapter>()
                       .ResetWindowsUserAsync(vmNode.Reference, username, token));
            });

            new ShowCredentialsDialog().ShowDialog(
                this,
                credentials.UserName,
                credentials.Password);

            // Update node to persist settings.
            vmNode.Username          = credentials.UserName;
            vmNode.CleartextPassword = credentials.Password;
            vmNode.Domain            = null;
            vmNode.SaveChanges();

            // Fire an event to update anybody using the node.
            await this.eventService.FireAsync(new ProjectExplorerNodeSelectedEvent(vmNode));
        }
        public void Populate(
            IEnumerable <Instance> allInstances,
            Func <InstanceLocator, bool> isConnected)
        {
            this.Nodes.Clear();

            // Narrow the list down to Windows instances - there is no point
            // of adding Linux instanes to the list of servers.
            var instances = allInstances.Where(i => ComputeEngineAdapter.IsWindowsInstance(i));
            var zoneIds   = instances.Select(i => InventoryNode.ShortIdFromUrl(i.Zone)).ToHashSet();

            foreach (var zoneId in zoneIds)
            {
                var zoneSettings = this.settingsRepository.GetZoneSettings(
                    this.ProjectId,
                    zoneId);
                var zoneNode = new ZoneNode(
                    zoneSettings,
                    changedSettings => this.settingsRepository.SetZoneSettings(this.ProjectId, changedSettings),
                    this);

                var instancesInZone = instances
                                      .Where(i => InventoryNode.ShortIdFromUrl(i.Zone) == zoneId)
                                      .OrderBy(i => i.Name);

                foreach (var instance in instancesInZone)
                {
                    var instanceSettings = this.settingsRepository.GetVmInstanceSettings(
                        this.ProjectId,
                        instance.Name);
                    var instanceNode = new VmInstanceNode(
                        instance,
                        instanceSettings,
                        changedSettings => this.settingsRepository.SetVmInstanceSettings(this.ProjectId, changedSettings),
                        zoneNode);
                    instanceNode.IsConnected = isConnected(
                        new InstanceLocator(this.ProjectId, zoneId, instance.Name));

                    zoneNode.Nodes.Add(instanceNode);
                }

                this.Nodes.Add(zoneNode);
                zoneNode.Expand();
            }

            Expand();
        }
Beispiel #5
0
        private async Task ConnectInstance(VmInstanceNode vmNode)
        {
            if (this.remoteDesktopService.TryActivate(vmNode.Reference))
            {
                // RDP session was already open, nothing left to do.
                return;
            }

            var destination = new TunnelDestination(vmNode.Reference, RemoteDesktopPort);

            // TODO: make configurable
            var timeout = TimeSpan.FromSeconds(30);

            var tunnel = await this.jobService.RunInBackground(
                new JobDescription("Opening Cloud IAP tunnel..."),
                async token =>
            {
                try
                {
                    var tunnelBrokerService = this.serviceProvider.GetService <TunnelBrokerService>();
                    return(await tunnelBrokerService.ConnectAsync(destination, timeout));
                }
                catch (NetworkStreamClosedException e)
                {
                    throw new ApplicationException(
                        "Connecting to the instance failed. Make sure that you have " +
                        "configured your firewall rules to permit Cloud IAP access " +
                        $"to {vmNode.InstanceName}",
                        e);
                }
                catch (UnauthorizedException)
                {
                    throw new ApplicationException(
                        "You are not authorized to connect to this VM instance.\n\n" +
                        $"Verify that the Cloud IAP API is enabled in the project {vmNode.Reference.ProjectId} " +
                        "and that your user has the 'IAP-secured Tunnel User' role.");
                }
            });

            this.remoteDesktopService.Connect(
                vmNode.Reference,
                "localhost",
                (ushort)tunnel.LocalPort,
                vmNode.EffectiveSettingsWithInheritanceApplied);
        }