20
20
#include " YubiKeyInterfacePCSC.h"
21
21
#include " YubiKeyInterfaceUSB.h"
22
22
23
+ #include < QtConcurrent>
24
+
23
25
YubiKey::YubiKey ()
24
26
: m_interfaces_detect_mutex(QMutex::Recursive)
25
27
{
26
28
int num_interfaces = 0 ;
27
29
28
30
if (YubiKeyInterfaceUSB::instance ()->isInitialized ()) {
29
31
++num_interfaces;
32
+ connect (YubiKeyInterfaceUSB::instance (), SIGNAL (challengeStarted ()), this , SIGNAL (challengeStarted ()));
33
+ connect (YubiKeyInterfaceUSB::instance (), SIGNAL (challengeCompleted ()), this , SIGNAL (challengeCompleted ()));
30
34
} else {
31
35
qDebug (" YubiKey: USB interface is not initialized." );
32
36
}
33
- connect (YubiKeyInterfaceUSB::instance (), SIGNAL (challengeStarted ()), this , SIGNAL (challengeStarted ()));
34
- connect (YubiKeyInterfaceUSB::instance (), SIGNAL (challengeCompleted ()), this , SIGNAL (challengeCompleted ()));
35
37
36
38
if (YubiKeyInterfacePCSC::instance ()->isInitialized ()) {
37
39
++num_interfaces;
40
+ connect (YubiKeyInterfacePCSC::instance (), SIGNAL (challengeStarted ()), this , SIGNAL (challengeStarted ()));
41
+ connect (YubiKeyInterfacePCSC::instance (), SIGNAL (challengeCompleted ()), this , SIGNAL (challengeCompleted ()));
38
42
} else {
39
43
qDebug (" YubiKey: PCSC interface is disabled or not initialized." );
40
44
}
41
- connect (YubiKeyInterfacePCSC::instance (), SIGNAL (challengeStarted ()), this , SIGNAL (challengeStarted ()));
42
- connect (YubiKeyInterfacePCSC::instance (), SIGNAL (challengeCompleted ()), this , SIGNAL (challengeCompleted ()));
43
45
44
- // Collapse the detectComplete signals from all interfaces into one signal
45
- // If multiple interfaces are used, wait for them all to finish
46
- auto detect_handler = [this , num_interfaces](bool found) {
47
- if (!m_interfaces_detect_mutex.tryLock (1000 )) {
48
- return ;
49
- }
50
- m_interfaces_detect_found |= found;
51
- m_interfaces_detect_completed++;
52
- if (m_interfaces_detect_completed != -1 && m_interfaces_detect_completed == num_interfaces) {
53
- m_interfaces_detect_completed = -1 ;
54
- emit detectComplete (m_interfaces_detect_found);
55
- }
56
- m_interfaces_detect_mutex.unlock ();
57
- };
58
- connect (YubiKeyInterfaceUSB::instance (), &YubiKeyInterfaceUSB::detectComplete, this , detect_handler);
59
- connect (YubiKeyInterfacePCSC::instance (), &YubiKeyInterfacePCSC::detectComplete, this , detect_handler);
60
-
61
- if (num_interfaces != 0 ) {
62
- m_initialized = true ;
63
- // clang-format off
64
- connect (&m_interactionTimer, SIGNAL (timeout ()), this , SIGNAL (userInteractionRequest ()));
65
- connect (this , &YubiKey::challengeStarted, this , [this ] { m_interactionTimer.start (); });
66
- connect (this , &YubiKey::challengeCompleted, this , [this ] { m_interactionTimer.stop (); });
67
- // clang-format on
68
- }
46
+ m_initialized = num_interfaces > 0 ;
47
+
48
+ m_interactionTimer.setSingleShot (true );
49
+ m_interactionTimer.setInterval (200 );
50
+ connect (&m_interactionTimer, SIGNAL (timeout ()), this , SIGNAL (userInteractionRequest ()));
51
+ connect (this , &YubiKey::challengeStarted, this , [this ] { m_interactionTimer.start (); });
52
+ connect (this , &YubiKey::challengeCompleted, this , [this ] { m_interactionTimer.stop (); });
69
53
}
70
54
71
55
YubiKey* YubiKey::m_instance (nullptr );
@@ -84,12 +68,23 @@ bool YubiKey::isInitialized()
84
68
return m_initialized;
85
69
}
86
70
87
- void YubiKey::findValidKeys ()
71
+ bool YubiKey::findValidKeys ()
88
72
{
89
- m_interfaces_detect_completed = 0 ;
90
- m_interfaces_detect_found = false ;
91
- YubiKeyInterfaceUSB::instance ()->findValidKeys ();
92
- YubiKeyInterfacePCSC::instance ()->findValidKeys ();
73
+ bool found = false ;
74
+ if (m_interfaces_detect_mutex.tryLock (1000 )) {
75
+ found |= YubiKeyInterfaceUSB::instance ()->findValidKeys ();
76
+ found |= YubiKeyInterfacePCSC::instance ()->findValidKeys ();
77
+ m_interfaces_detect_mutex.unlock ();
78
+ }
79
+ return found;
80
+ }
81
+
82
+ void YubiKey::findValidKeysAsync ()
83
+ {
84
+ QtConcurrent::run ([this ] {
85
+ bool found = findValidKeys ();
86
+ emit detectComplete (found);
87
+ });
93
88
}
94
89
95
90
QList<YubiKeySlot> YubiKey::foundKeys ()
@@ -207,6 +202,11 @@ YubiKey::challenge(YubiKeySlot slot, const QByteArray& challenge, Botan::secure_
207
202
{
208
203
m_error.clear ();
209
204
205
+ // Make sure we tried to find available keys
206
+ if (foundKeys ().isEmpty ()) {
207
+ findValidKeys ();
208
+ }
209
+
210
210
if (YubiKeyInterfaceUSB::instance ()->hasFoundKey (slot)) {
211
211
return YubiKeyInterfaceUSB::instance ()->challenge (slot, challenge, response);
212
212
}
0 commit comments