- added README for PAM module
- added a few error messages - fixed certificate caching (which is still kludgy) git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@44 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
parent
1194017d5a
commit
e53cfa4595
|
@ -44,6 +44,8 @@
|
|||
#define SC_ERROR_BUFFER_TOO_SMALL -1017
|
||||
#define SC_ERROR_CARD_NOT_PRESENT -1018
|
||||
#define SC_ERROR_RESOURCE_MANAGER -1019
|
||||
#define SC_ERROR_CARD_REMOVED -1020
|
||||
#define SC_ERROR_INVALID_PIN_LENGTH -1021
|
||||
|
||||
#define SC_APDU_CASE_NONE 0
|
||||
#define SC_APDU_CASE_1 1
|
||||
|
@ -117,8 +119,9 @@ struct sc_file {
|
|||
struct sc_card {
|
||||
int class;
|
||||
struct sc_context *context;
|
||||
|
||||
SCARDHANDLE pcsc_card;
|
||||
const char *reader;
|
||||
int reader;
|
||||
char atr[SC_MAX_ATR_SIZE];
|
||||
int atr_len;
|
||||
|
||||
|
@ -170,8 +173,15 @@ int sc_destroy_context(struct sc_context *ctx);
|
|||
int sc_connect_card(struct sc_context *ctx,
|
||||
int reader, struct sc_card **card);
|
||||
int sc_disconnect_card(struct sc_card *card);
|
||||
|
||||
/* Checks if a card is present on the supplied reader
|
||||
* Returns: 1 if card present, 0 if card absent and < 0 in case of an error */
|
||||
int sc_detect_card(struct sc_context *ctx, int reader);
|
||||
/* timeout of -1 means forever, reader of -1 means all readers */
|
||||
|
||||
/* Waits for card insertion on the supplied reader
|
||||
* timeout of -1 means forever, reader of -1 means all readers
|
||||
* Returns: 1 if a card was found, 0 if timeout occured
|
||||
* and < 0 in case of an error */
|
||||
int sc_wait_for_card(struct sc_context *ctx, int reader, int timeout);
|
||||
|
||||
int sc_lock(struct sc_card *card);
|
||||
|
|
|
@ -129,18 +129,25 @@ int sc_pkcs15_read_certificate(struct sc_pkcs15_card *p15card,
|
|||
struct sc_file file;
|
||||
char *data = NULL;
|
||||
struct sc_pkcs15_cert *cert;
|
||||
char fname[50];
|
||||
char fname[150];
|
||||
u8 buf[2048];
|
||||
|
||||
FILE *crtf = NULL;
|
||||
int cert_found = 0;
|
||||
|
||||
char *homedir;
|
||||
|
||||
assert(p15card != NULL && info != NULL && cert_out != NULL);
|
||||
|
||||
#if 1
|
||||
/* FIXME: Remove this kludge */
|
||||
sprintf(fname, "/tmp/fineid-%02X.crt", info->id.value[0]);
|
||||
homedir = getenv("HOME");
|
||||
if (homedir == NULL)
|
||||
goto no_cert;
|
||||
sprintf(fname, "%s/.eid/%s_%02X.crt", homedir, p15card->label, info->id.value[0]);
|
||||
crtf = fopen(fname, "r");
|
||||
if (crtf != NULL) {
|
||||
if (crtf == NULL)
|
||||
goto no_cert;
|
||||
|
||||
r = fread(buf, 1, sizeof(buf), crtf);
|
||||
if (r > 0) {
|
||||
data = malloc(r);
|
||||
|
@ -149,7 +156,8 @@ int sc_pkcs15_read_certificate(struct sc_pkcs15_card *p15card,
|
|||
cert_found = 1;
|
||||
}
|
||||
fclose(crtf);
|
||||
}
|
||||
no_cert:
|
||||
#endif
|
||||
if (!cert_found) {
|
||||
r = sc_select_file(p15card->card, &file, &info->path,
|
||||
SC_SELECT_FILE_BY_PATH);
|
||||
|
@ -165,11 +173,13 @@ int sc_pkcs15_read_certificate(struct sc_pkcs15_card *p15card,
|
|||
}
|
||||
len = r;
|
||||
/* FIXME: kludge! */
|
||||
#if 1
|
||||
crtf = fopen(fname, "w");
|
||||
if (crtf != NULL) {
|
||||
fwrite(data, len, 1, crtf);
|
||||
fclose(crtf);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
cert = malloc(sizeof(struct sc_pkcs15_cert));
|
||||
if (cert == NULL) {
|
||||
|
|
|
@ -171,7 +171,7 @@ int sc_pkcs15_verify_pin(struct sc_pkcs15_card *p15card,
|
|||
if (pin->magic != SC_PKCS15_PIN_MAGIC)
|
||||
return SC_ERROR_OBJECT_NOT_VALID;
|
||||
if (pinlen > pin->stored_length || pinlen < pin->min_length)
|
||||
return SC_ERROR_INVALID_ARGUMENTS;
|
||||
return SC_ERROR_INVALID_PIN_LENGTH;
|
||||
card = p15card->card;
|
||||
r = sc_select_file(card, &file, &pin->path,
|
||||
SC_SELECT_FILE_BY_PATH);
|
||||
|
|
|
@ -174,9 +174,19 @@ static int sc_transceive_t0(struct sc_card *card, struct sc_apdu *apdu)
|
|||
rv = SCardTransmit(card->pcsc_card, &sSendPci, s, dwSendLength,
|
||||
&sRecvPci, r, &dwRecvLength);
|
||||
if (rv != SCARD_S_SUCCESS) {
|
||||
fprintf(stderr, "SCardTransmit failed with 0x%08x\n",
|
||||
(int) rv);
|
||||
switch (rv) {
|
||||
case SCARD_W_REMOVED_CARD:
|
||||
return SC_ERROR_CARD_REMOVED;
|
||||
case SCARD_E_NOT_TRANSACTED:
|
||||
if (sc_detect_card(card->context, card->reader) != 1)
|
||||
return SC_ERROR_CARD_REMOVED;
|
||||
return SC_ERROR_TRANSMIT_FAILED;
|
||||
default:
|
||||
if (sc_debug) {
|
||||
fprintf(stderr, "SCardTransmit returned 0x%08lX.\n", rv);
|
||||
return SC_ERROR_TRANSMIT_FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
apdu->resplen = dwRecvLength;
|
||||
memcpy(apdu->resp, r, dwRecvLength);
|
||||
|
@ -530,7 +540,6 @@ int sc_wait_for_card(struct sc_context *ctx, int reader, int timeout)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int sc_establish_context(struct sc_context **ctx_out)
|
||||
{
|
||||
struct sc_context *ctx;
|
||||
|
@ -658,6 +667,8 @@ int sc_connect_card(struct sc_context *ctx,
|
|||
free(card);
|
||||
return -1; /* FIXME */
|
||||
}
|
||||
card->reader = reader;
|
||||
card->context = ctx;
|
||||
card->pcsc_card = card_handle;
|
||||
i = rgReaderStates[0].cbAtr;
|
||||
if (i >= SC_MAX_ATR_SIZE)
|
||||
|
@ -671,7 +682,6 @@ int sc_connect_card(struct sc_context *ctx,
|
|||
} else {
|
||||
card->class = 0; /* FIXME */
|
||||
}
|
||||
card->reader = ctx->readers[reader];
|
||||
*card_out = card;
|
||||
|
||||
return 0;
|
||||
|
@ -703,8 +713,12 @@ const char *sc_strerror(int error)
|
|||
"PIN code incorrect",
|
||||
"Security status not satisfied",
|
||||
"Error connecting to Resource Manager",
|
||||
"Invalid ASN.1 object",
|
||||
"Buffer too small",
|
||||
|
||||
"Card not present",
|
||||
"Error with Resource Manager",
|
||||
"Card removed",
|
||||
"Invalid PIN length"
|
||||
};
|
||||
int nr_errors = sizeof(errors) / sizeof(errors[0]);
|
||||
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
Steps required to make the PAM module work:
|
||||
|
||||
1. Compile and link the pam_pkcs15.so shared library.
|
||||
2. Copy pam_pkcs.so to /lib/security.
|
||||
3. Edit /etc/pam.d/login file. Add the following line before the
|
||||
pam_unix.so (on Debian) or pam_pwdb.so (on Red Hat) entry:
|
||||
auth sufficient /lib/security/pam_pkcs15.so
|
||||
4. Copy your PEM encoded certificate to a file in your home directory
|
||||
called '.eid/authorized_certificates'.
|
||||
NOTE: You can use the 'certtest' program to get the PEM encoded
|
||||
certificate.
|
||||
5. Try to login with your card in the reader.
|
||||
|
|
@ -305,7 +305,9 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t * pamh, int flags, int argc, con
|
|||
DBG(printf("Verifying PIN code...\n"));
|
||||
r = sc_pkcs15_verify_pin(p15card, &p15card->pin_info[0], password, strlen(password));
|
||||
if (r) {
|
||||
printf("PIN code verification failed: %s\n", sc_strerror(r));
|
||||
DBG(printf("PIN code verification failed: %s\n", sc_strerror(r)));
|
||||
if (r == SC_ERROR_CARD_REMOVED)
|
||||
printf("SmartCard removed.\n");
|
||||
goto end;
|
||||
}
|
||||
DBG(printf("Awright! PIN code correct!\n"));
|
||||
|
|
|
@ -99,5 +99,6 @@ int main(int argc, char *argv[])
|
|||
printf("\n");
|
||||
sc_asn1_print_tags(cert->data, cert->data_len);
|
||||
}
|
||||
sc_test_cleanup();
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue