From 0f2100c69cf7e1f385fc7cebe7d50742715b92ee Mon Sep 17 00:00:00 2001 From: Greg Domzalski Date: Tue, 28 Jun 2022 12:40:03 -0700 Subject: [PATCH 1/3] Make SCardListener dormant when service not present --- .../Devices/SmartCard/DesktopSmartCardDeviceListener.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Yubico.Core/src/Yubico/Core/Devices/SmartCard/DesktopSmartCardDeviceListener.cs b/Yubico.Core/src/Yubico/Core/Devices/SmartCard/DesktopSmartCardDeviceListener.cs index d7a63c81..ad6d9ae9 100644 --- a/Yubico.Core/src/Yubico/Core/Devices/SmartCard/DesktopSmartCardDeviceListener.cs +++ b/Yubico.Core/src/Yubico/Core/Devices/SmartCard/DesktopSmartCardDeviceListener.cs @@ -50,6 +50,15 @@ public DesktopSmartCardDeviceListener() uint result = SCardEstablishContext(SCARD_SCOPE.USER, out SCardContext context); _log.SCardApiCall(nameof(SCardEstablishContext), result); + // If we failed to establish context to the smart card subsystem, something substantially wrong + // has occured. We should not continue, and the device listener should remain dormant. + if (result != ErrorCode.SCARD_S_SUCCESS) + { + _context = new SCardContext(IntPtr.Zero); + _readerStates = Array.Empty(); + return; + } + _context = context; _readerStates = GetReaderStateList(); From d3b2dd0b8801a854963ebdaa1b12c661f2d75eb7 Mon Sep 17 00:00:00 2001 From: Greg Domzalski Date: Tue, 28 Jun 2022 13:10:41 -0700 Subject: [PATCH 2/3] Dispose of context to satisfy compiler --- .../Core/Devices/SmartCard/DesktopSmartCardDeviceListener.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Yubico.Core/src/Yubico/Core/Devices/SmartCard/DesktopSmartCardDeviceListener.cs b/Yubico.Core/src/Yubico/Core/Devices/SmartCard/DesktopSmartCardDeviceListener.cs index ad6d9ae9..238ef0e8 100644 --- a/Yubico.Core/src/Yubico/Core/Devices/SmartCard/DesktopSmartCardDeviceListener.cs +++ b/Yubico.Core/src/Yubico/Core/Devices/SmartCard/DesktopSmartCardDeviceListener.cs @@ -54,8 +54,10 @@ public DesktopSmartCardDeviceListener() // has occured. We should not continue, and the device listener should remain dormant. if (result != ErrorCode.SCARD_S_SUCCESS) { + context.Dispose(); // Needed to satisfy analyzer (even though it should be null already) _context = new SCardContext(IntPtr.Zero); _readerStates = Array.Empty(); + _log.LogWarning("SmartCardDeviceListener dormant as SDK was unable to establish a context to the PCSC service."); return; } From 39a27655fc55fbec4f071be1445f0a11c1c47b8a Mon Sep 17 00:00:00 2001 From: Greg Domzalski Date: Wed, 29 Jun 2022 16:25:33 -0700 Subject: [PATCH 3/3] Add status property to SmartCardDeviceListener --- .../DesktopSmartCardDeviceListener.cs | 4 ++ .../Devices/SmartCard/DeviceListenerStatus.cs | 37 +++++++++++++++++++ .../SmartCard/SmartCardDeviceListener.cs | 5 +++ 3 files changed, 46 insertions(+) create mode 100644 Yubico.Core/src/Yubico/Core/Devices/SmartCard/DeviceListenerStatus.cs diff --git a/Yubico.Core/src/Yubico/Core/Devices/SmartCard/DesktopSmartCardDeviceListener.cs b/Yubico.Core/src/Yubico/Core/Devices/SmartCard/DesktopSmartCardDeviceListener.cs index 238ef0e8..a8c95e27 100644 --- a/Yubico.Core/src/Yubico/Core/Devices/SmartCard/DesktopSmartCardDeviceListener.cs +++ b/Yubico.Core/src/Yubico/Core/Devices/SmartCard/DesktopSmartCardDeviceListener.cs @@ -46,6 +46,7 @@ internal class DesktopSmartCardDeviceListener : SmartCardDeviceListener, IDispos public DesktopSmartCardDeviceListener() { _log.LogInformation("Creating DesktopSmartCardDeviceListener."); + Status = DeviceListenerStatus.Stopped; uint result = SCardEstablishContext(SCARD_SCOPE.USER, out SCardContext context); _log.SCardApiCall(nameof(SCardEstablishContext), result); @@ -57,6 +58,7 @@ public DesktopSmartCardDeviceListener() context.Dispose(); // Needed to satisfy analyzer (even though it should be null already) _context = new SCardContext(IntPtr.Zero); _readerStates = Array.Empty(); + Status = DeviceListenerStatus.Error; _log.LogWarning("SmartCardDeviceListener dormant as SDK was unable to establish a context to the PCSC service."); return; } @@ -79,6 +81,7 @@ private void StartListening() IsBackground = true }; _isListening = true; + Status = DeviceListenerStatus.Started; _listenerThread.Start(); } } @@ -153,6 +156,7 @@ private void StopListening() ClearEventHandlers(); _isListening = false; + Status = DeviceListenerStatus.Stopped; _listenerThread.Join(); } diff --git a/Yubico.Core/src/Yubico/Core/Devices/SmartCard/DeviceListenerStatus.cs b/Yubico.Core/src/Yubico/Core/Devices/SmartCard/DeviceListenerStatus.cs new file mode 100644 index 00000000..a38e925b --- /dev/null +++ b/Yubico.Core/src/Yubico/Core/Devices/SmartCard/DeviceListenerStatus.cs @@ -0,0 +1,37 @@ +// Copyright 2022 Yubico AB +// +// Licensed under the Apache License, Version 2.0 (the "License"). +// You may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Yubico.Core.Devices.SmartCard +{ + /// + /// An enumeration that represents the status of a device listener. + /// + public enum DeviceListenerStatus + { + /// + /// The listener has not been started, and is not currently listening for devices. No events will be raised. + /// + Stopped, + + /// + /// The listener has been successfully started. + /// + Started, + + /// + /// The listener encountered an error and could not start. No events will be raised. + /// + Error + } +} diff --git a/Yubico.Core/src/Yubico/Core/Devices/SmartCard/SmartCardDeviceListener.cs b/Yubico.Core/src/Yubico/Core/Devices/SmartCard/SmartCardDeviceListener.cs index 02521dd8..996dde36 100644 --- a/Yubico.Core/src/Yubico/Core/Devices/SmartCard/SmartCardDeviceListener.cs +++ b/Yubico.Core/src/Yubico/Core/Devices/SmartCard/SmartCardDeviceListener.cs @@ -47,6 +47,11 @@ public abstract class SmartCardDeviceListener /// public event EventHandler? Removed; + /// + /// A status that indicates the state of the device listener. + /// + public DeviceListenerStatus Status { get; set; } + /// /// Creates an instance of a . ///