Skip to content

Commit bb4aa9d

Browse files
committed
pivy-agent: call SCardEstablishContext again on certain errors
This allows the pivy-agent to continue running after a pcscd restart or certain MacOS power mgmt operations.
1 parent d120209 commit bb4aa9d

File tree

3 files changed

+44
-5
lines changed

3 files changed

+44
-5
lines changed

piv.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1096,7 +1096,16 @@ piv_enumerate(SCARDCONTEXT ctx, struct piv_token **tokens)
10961096
errf_t *err;
10971097

10981098
rv = SCardListReaders(ctx, NULL, NULL, &readersLen);
1099-
if (rv != SCARD_S_SUCCESS) {
1099+
switch (rv) {
1100+
case SCARD_S_SUCCESS:
1101+
break;
1102+
case SCARD_E_NO_SERVICE:
1103+
case SCARD_E_INVALID_HANDLE:
1104+
case SCARD_E_SERVICE_STOPPED:
1105+
return (errf("PCSCContextError",
1106+
pcscerrf("SCardListReaders", rv),
1107+
"PCSC context is not functional"));
1108+
default:
11001109
return (pcscerrf("SCardListReaders", rv));
11011110
}
11021111
readers = calloc(1, readersLen);
@@ -1215,7 +1224,16 @@ piv_find(SCARDCONTEXT ctx, const uint8_t *guid, size_t guidlen,
12151224
errf_t *err;
12161225

12171226
rv = SCardListReaders(ctx, NULL, NULL, &readersLen);
1218-
if (rv != SCARD_S_SUCCESS) {
1227+
switch (rv) {
1228+
case SCARD_S_SUCCESS:
1229+
break;
1230+
case SCARD_E_NO_SERVICE:
1231+
case SCARD_E_INVALID_HANDLE:
1232+
case SCARD_E_SERVICE_STOPPED:
1233+
return (errf("PCSCContextError",
1234+
pcscerrf("SCardListReaders", rv),
1235+
"PCSC context is not functional"));
1236+
default:
12191237
return (pcscerrf("SCardListReaders", rv));
12201238
}
12211239
readers = calloc(1, readersLen);

piv.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,8 @@ errf_t *piv_enumerate(SCARDCONTEXT ctx, struct piv_token **tokens);
241241
*
242242
* Errors:
243243
* - PCSCError: a PCSC call failed in a way that is not retryable
244+
* - PCSCContextError: a PCSC call failed in a way that indicates the
245+
* SCARDCONTEXT is no longer valid
244246
* - DuplicateError: a GUID prefix was given and it is not unique on the system
245247
* - NotFoundError: token matching the guid was not found
246248
*/

pivy-agent.c

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,9 @@
151151
"(try ssh-add -X)")
152152
#define flagserrf(val) \
153153
errf("FlagsError", NULL, "unsupported flags value: %x", val)
154+
#define pcscerrf(call, rv) \
155+
errf("PCSCError", NULL, call " failed: %d (%s)", \
156+
rv, pcsc_stringify_error(rv))
154157

155158
typedef enum confirm_mode {
156159
C_NEVER,
@@ -418,6 +421,7 @@ agent_piv_open(void)
418421
{
419422
struct piv_slot *slot;
420423
errf_t *err = NULL;
424+
int rv;
421425

422426
if (txnopen) {
423427
txntimeout = monotime() + 2000;
@@ -431,8 +435,22 @@ agent_piv_open(void)
431435
if (ks != NULL)
432436
piv_release(ks);
433437

438+
findagain:
434439
err = piv_find(ctx, guid, guid_len, &ks);
435-
if (err) {
440+
if (err && errf_caused_by(err, "PCSCContextError")) {
441+
ks = NULL;
442+
bunyan_log(BNY_TRACE, "got context error, re-initing",
443+
"error", BNY_ERF, err, NULL);
444+
errf_free(err);
445+
SCardReleaseContext(ctx);
446+
rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL,
447+
NULL, &ctx);
448+
if (rv != SCARD_S_SUCCESS) {
449+
err = pcscerrf("SCardEstablishContext", rv);
450+
return (err);
451+
}
452+
goto findagain;
453+
} else if (err) {
436454
ks = NULL;
437455
err = errf("EnumerationError", err, "Failed to "
438456
"find specified PIV token on the system");
@@ -2797,8 +2815,9 @@ main(int ac, char **av)
27972815

27982816
r = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &ctx);
27992817
if (r != SCARD_S_SUCCESS) {
2800-
bunyan_log(BNY_ERROR, "SCardEstablishContext failed",
2801-
"error", BNY_STRING, pcsc_stringify_error(r), NULL);
2818+
err = pcscerrf("SCardEstablishContext", r);
2819+
bunyan_log(BNY_ERROR, "error setting up PCSC lib context",
2820+
"error", BNY_ERF, err, NULL);
28022821
return (1);
28032822
}
28042823

0 commit comments

Comments
 (0)