async Task OnWorkstationLock(int sessionId, WorkstationEventType eventType)
        {
            if (eventType != WorkstationEventType.ComputerLock &&
                eventType != WorkstationEventType.ComputerLogoff)
            {
                return;
            }

            var we = _eventSaver.GetPrevSessionWorkstationEvent();

            we.EventId = eventType;

            lock (_lpLock)
            {
                if (_lockProcedure != null && (DateTime.UtcNow - _lockProcedure.Time).TotalSeconds <= LOCK_EVENT_TIMEOUT)
                {
                    we.Note     = _lockProcedure.Reason.ToString();
                    we.DeviceId = _bleDeviceManager.Find(_lockProcedure.Mac, 1)?.SerialNo; // Todo: Replace channel magic number with const
                }
                else
                {
                    we.Note = WorkstationLockingReason.NonHideez.ToString();
                }

                _lockProcedure = null;
            }

            await _eventSaver.AddNewAsync(we, true);
        }
예제 #2
0
 public void EnableDeviceReconnect(string deviceId)
 {
     lock (_reconnectListLock)
     {
         var device = _deviceManager.Find(deviceId);
         if (device != null)
         {
             EnableDeviceReconnect(device);
         }
     }
 }
        async Task RemoteConnection_VerifyCommandAsync(RemoteConnection_VerifyCommandMessage args)
        {
            try
            {
                var pipeDevice = _deviceManager.Find(args.ConnectionId) as IPipeDevice;

                if (pipeDevice == null)
                {
                    throw new HideezException(HideezErrorCode.RemoteDeviceNotFound, args.ConnectionId);
                }

                var response = await pipeDevice.OnVerifyCommandAsync(args.Data);

                await _messenger.Publish(new RemoteConnection_VerifyCommandMessageReply(response));
            }
            catch (Exception ex)
            {
                Error(ex);
                throw;
            }
        }
        async Task MainWorkflow(string mac, bool rebondOnConnectionFail, bool tryUnlock, Action <WorkstationUnlockResult> onUnlockAttempt, CancellationToken ct)
        {
            // Ignore MainFlow requests for devices that are already connected
            // IsConnected-true indicates that device already finished main flow or is in progress
            var existingDevice = _deviceManager.Find(mac, (int)DefaultDeviceChannel.Main);

            if (existingDevice != null && existingDevice.IsConnected && !WorkstationHelper.IsActiveSessionLocked())
            {
                return;
            }

            WriteLine($"Started main workflow ({mac})");

            var flowId = Guid.NewGuid().ToString();

            Started?.Invoke(this, flowId);

            bool    workflowFinishedSuccessfully = false;
            bool    deleteVaultBond = false;
            string  errorMessage    = null;
            IDevice device          = null;

            try
            {
                await _ui.SendNotification(string.Empty, mac);

                _subp.PermissionsCheckProcessor.CheckPermissions();

                // Start periodic screen activator to raise the "curtain"
                if (WorkstationHelper.IsActiveSessionLocked())
                {
                    _screenActivator?.ActivateScreen();
                    _screenActivator?.StartPeriodicScreenActivation(0);

                    await new WaitWorkstationUnlockerConnectProc(_workstationUnlocker)
                    .Run(SdkConfig.WorkstationUnlockerConnectTimeout, ct);
                }

                device = await _subp.VaultConnectionProcessor.ConnectVault(mac, rebondOnConnectionFail, ct);

                device.Disconnected       += OnVaultDisconnectedDuringFlow;
                device.OperationCancelled += OnCancelledByVaultButton;

                await _subp.VaultConnectionProcessor.WaitVaultInitialization(mac, device, ct);

                if (device.IsBoot)
                {
                    throw new WorkflowException(TranslationSource.Instance["ConnectionFlow.Error.VaultInBootloaderMode"]);
                }

                device.SetUserProperty(CustomProperties.HW_CONNECTION_STATE_PROP, HwVaultConnectionState.Initializing);

                HwVaultInfoFromHesDto vaultInfo = new HwVaultInfoFromHesDto(); // Initializes with default values for when HES is not connected
                if (_hesConnection.State == HesConnectionState.Connected)
                {
                    vaultInfo = await _hesConnection.UpdateHwVaultProperties(new HwVaultInfoFromClientDto(device), true);
                }

                _subp.CacheVaultInfoProcessor.CacheAndUpdateVaultOwner(ref device, vaultInfo, ct);

                await _subp.LicensingProcessor.CheckLicense(device, vaultInfo, ct);

                vaultInfo = await _subp.StateUpdateProcessor.UpdateVaultStatus(device, vaultInfo, ct);

                vaultInfo = await _subp.ActivationProcessor.ActivateVault(device, vaultInfo, ct);

                await _subp.MasterkeyProcessor.AuthVault(device, ct);

                var osAccUpdateTask = _subp.AccountsUpdateProcessor.UpdateAccounts(device, vaultInfo, true);
                if (_workstationUnlocker.IsConnected && WorkstationHelper.IsActiveSessionLocked() && tryUnlock)
                {
                    await Task.WhenAll(_subp.UserAuthorizationProcessor.AuthorizeUser(device, ct), osAccUpdateTask);

                    _screenActivator?.StopPeriodicScreenActivation();
                    await _subp.UnlockProcessor.UnlockWorkstation(device, flowId, onUnlockAttempt, ct);
                }
                else
                {
                    await osAccUpdateTask;
                }

                device.SetUserProperty(CustomProperties.HW_CONNECTION_STATE_PROP, HwVaultConnectionState.Finalizing);
                WriteLine($"Finalizing main workflow: ({device.Id})");
                DeviceFinilizingMainFlow?.Invoke(this, device);

                await _subp.AccountsUpdateProcessor.UpdateAccounts(device, vaultInfo, false);

                device.SetUserProperty(CustomProperties.HW_CONNECTION_STATE_PROP, HwVaultConnectionState.Online);

                if (_hesConnection.State == HesConnectionState.Connected)
                {
                    await _hesConnection.UpdateHwVaultProperties(new HwVaultInfoFromClientDto(device), false);
                }

                workflowFinishedSuccessfully = true;
            }
            catch (HideezException ex)
            {
                switch (ex.ErrorCode)
                {
                case HideezErrorCode.DeviceIsLocked:
                case HideezErrorCode.DeviceNotAssignedToUser:
                case HideezErrorCode.HesDeviceNotFound:
                case HideezErrorCode.HesDeviceCompromised:
                case HideezErrorCode.DeviceHasBeenWiped:
                    // There errors require bond removal
                    deleteVaultBond = true;
                    errorMessage    = HideezExceptionLocalization.GetErrorAsString(ex);
                    break;

                case HideezErrorCode.ButtonConfirmationTimeout:
                case HideezErrorCode.GetPinTimeout:
                case HideezErrorCode.GetActivationCodeTimeout:
                    // Silent handling
                    WriteLine(ex);
                    break;

                case HideezErrorCode.HesNotConnected:
                    // We need to display an error message which is different from one that is usually shown for that error code.
                    errorMessage = TranslationSource.Instance["ConnectionFlow.Error.UnexpectedlyLostNetworkConnection"];
                    break;

                default:
                    errorMessage = HideezExceptionLocalization.GetErrorAsString(ex);
                    break;
                }
            }
            catch (VaultFailedToAuthorizeException ex)
            {
                // User should never receive this error unless there is a bug in algorithm
                errorMessage = HideezExceptionLocalization.GetErrorAsString(ex);
            }
            catch (WorkstationUnlockFailedException ex)
            {
                // Silent handling of failed workstation unlock
                // The actual message will be displayed by credential provider
                WriteLine(ex);
            }
            catch (OperationCanceledException ex)
            {
                // Silent cancelation handling
                WriteLine(ex);
            }
            catch (TimeoutException ex)
            {
                // Silent timeout handling
                WriteLine(ex);
            }
            catch (WebSocketException ex)
            {
                // Retrieve the most inner WebSocketException to retrieve the error code
                if (ex.WebSocketErrorCode != 0)
                {
                    errorMessage = string.Format(TranslationSource.Instance["ConnectionFlow.Error.UnexpectedNetworkError"], ex.WebSocketErrorCode);
                }
                else if (ex.ErrorCode != 0)
                {
                    errorMessage = string.Format(TranslationSource.Instance["ConnectionFlow.Error.UnexpectedNetworkError"], ex.ErrorCode);
                }
                else if (ex.InnerException is Win32Exception)
                {
                    errorMessage = string.Format(TranslationSource.Instance["ConnectionFlow.Error.UnexpectedNetworkError"], "native " + (ex.InnerException as Win32Exception).NativeErrorCode);
                }
            }
            catch (Exception ex)
            {
                errorMessage = HideezExceptionLocalization.GetErrorAsString(ex);
            }
            finally
            {
                if (device != null)
                {
                    device.Disconnected       -= OnVaultDisconnectedDuringFlow;
                    device.OperationCancelled -= OnCancelledByVaultButton;
                }
                _screenActivator?.StopPeriodicScreenActivation();
            }

            await WorkflowCleanup(errorMessage, mac, device, workflowFinishedSuccessfully, deleteVaultBond);

            Finished?.Invoke(this, flowId);

            WriteLine($"Main workflow end {mac}");
        }