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); }
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}"); }