Diego Zuccato ha scritto:
All comments welcome! :-)
First of all an auto-comment: as is, it works only when all users
enrolled all fingers.
If some users have only some fingers enrolled, it could crash due to
uninitialized fingers[X].fp . This patch, 0.2 based, replaces the older one.
BYtE,
Diego.
21a22
> #include <stdlib.h>
24a26
> #include <time.h>
159c161,225
< static int do_auth(pam_handle_t *pamh)
---
> /* "options" container.
> - Must be terminated by {0, NULL, 0, NULL}
> - if an option in the starting part of another, the longer one must come
> first
> (so if XX and XXY are valid options, XXY must be before XX in the array)
> */
> struct cmdline_options {
> char shortopt; /* short version for the option: f=X */
> char *longopt; /* long version for the option: foo=X */
> int type; /* type of var: 0=int, 1=string, 2=boolean */
> void *var; /* ptr to the target var */
> };
>
> /* Very basic commandline options parser, to avoid other dependencies on
> external libraries */
> static void cmdline_parse(int argc, const char **argv, const struct
> cmdline_options *opts) {
> int c;
> for(c=0; c<argc; ++c) {
> const struct cmdline_options *o=opts; /* struct is const,
> pointer is not! */
> while (o->shortopt || o->longopt) {
> int ol=strlen(o->longopt);
> int found=0;
> if (argv[c][0] == o->shortopt && argv[c][1]=='=') {
> /* is a short opt */
> found=1;
> ol=1;
> } else {
> if ((argv[c][ol] == '=') && /* is a long
> opt */
> (0 == strncmp(argv[c], o->longopt, ol))) {
> found=1;
> }
> }
> if (found) {
> const char *arg=argv[c]+ol+1; /* argument to
> the option */
> switch (o->type) {
> case 0: { /* Integer */
> int *iv=o->var;
> *iv=atoi(arg);
> }
> break;
> case 1: { /* String */
> const char **sv=o->var;
> *sv=arg; /* REFERENCES the
> (constant) argument */
> }
> break;
> case 2: { /* Boolean */
> int *bv=o->var;
> if (tolower(arg[0]) == 'y' ||
> tolower(arg[0]) == 't') {
> *bv=!0;
> } else {
> *bv=0;
> }
> }
> break;
> default:
> /* TODO: Should log "parser error:
> undefined type" */
> break;
> }
> break; /* Jump out of while() */
> }
> ++o; /* Go to next option descriptio */
> }
> /* TODO: here we could check !(o->shortopt || o->longopt) to
> warn about unrecognized options in config file */
> }
> }
>
> static int do_auth(pam_handle_t *pamh, int argc, const char **argv)
168a235,271
> int reqfinger=-1; /* [0-9]; default: autodetect requred finger */
> int reqnfingers=1; /* [1-10]; default: 1 (single finger auth) */
> int randomfingers=0; /* bool, default: false (fixed finger) */
>
>
> const struct cmdline_options opts[]={
> {'f', "finger", 0, &reqfinger},
> {'n', "nfingers", 0, &reqnfingers},
> {'r', "randomize", 2, &randomfingers},
> {0, NULL, 0, NULL} /* terminate array */
> };
> cmdline_parse(argc, argv, opts);
>
> /* "Sanitize" cmdline options */
> if (reqnfingers < 1 || reqnfingers > 10) { /* out of range */
> reqnfingers=1;
> }
> if (reqnfingers > 1) { /* more than one finger implies random fingers
> (no way to supply a list, atm) */
> randomfingers=1;
> }
> if (randomfingers) { /* random implies no fixed finger */
> reqfinger=-1;
> }
>
> #if DEBUG
> {
> char buff[4096];
> char *b=buff;
> for(r=0; r<argc; ++r) {
> b+=sprintf(b, "pam_fprint option: '%s'\n", argv[r]);
> }
> b+=sprintf(b, "reqfinger = %d (%s)\n", reqfinger, fingerstr(reqfinger));
> b+=sprintf(b, "reqnfingers = %d\n", reqnfingers);
> b+=sprintf(b, "randomfingers = %d\n", randomfingers);
> send_info_msg(pamh, buff);
> }
> #endif
184,186c287,298
< r = find_dev_and_print(ddevs, prints, &ddev, &print);
< if (r) {
< fp_dscv_prints_free(prints);
---
> if (reqfinger == -1 && reqnfingers == 1 && randomfingers == 0) {
> /* old behaviour: one, system-chosen, fixed fingerprint */
> r = find_dev_and_print(ddevs, prints, &ddev, &print);
> if (r) {
> fp_dscv_prints_free(prints);
> fp_dscv_devs_free(ddevs);
> send_info_msg(pamh, "Could not locate any suitable
> fingerprints "
> "matched with available hardware.");
> return PAM_AUTHINFO_UNAVAIL;
> }
>
> dev = fp_dev_open(ddev);
188,191c300,303
< send_info_msg(pamh, "Could not locate any suitable fingerprints
"
< "matched with available hardware.");
< return PAM_AUTHINFO_UNAVAIL;
< }
---
> if (!dev) {
> fp_dscv_prints_free(prints);
> return PAM_AUTHINFO_UNAVAIL;
> }
193,198c305
< dev = fp_dev_open(ddev);
< fp_dscv_devs_free(ddevs);
< if (!dev) {
< fp_dscv_prints_free(prints);
< return PAM_AUTHINFO_UNAVAIL;
< }
---
> finger = fp_dscv_print_get_finger(print);
200c307,312
< finger = fp_dscv_print_get_finger(print);
---
> r = fp_print_data_from_dscv_print(print, &data);
> fp_dscv_prints_free(prints);
> if (r) {
> fp_dev_close(dev);
> return PAM_AUTHINFO_UNAVAIL;
> }
202,204c314,315
< r = fp_print_data_from_dscv_print(print, &data);
< fp_dscv_prints_free(prints);
< if (r) {
---
> r = do_verify(pamh, dev, data, finger);
> fp_print_data_free(data);
206,207c317,335
< return PAM_AUTHINFO_UNAVAIL;
< }
---
> } else {
> /* new behaviour */
> int cnt, skipped;
> int matched=0; /* num of successfully matched unique
> fingerprints */
>
> struct fingersmap {
> struct fp_dscv_print *fp;
> enum fp_finger fn;
> } fingers[10];/* Shuffle for DIFFERENT random prints */
>
> /* Fill the fingers array */
> for (cnt=0; cnt<10; ++cnt) {
> fingers[cnt].fn=LEFT_THUMB+cnt;
> fingers[cnt].fp=NULL;
> }
> /* Map discovered fingerprints into the array */
> for (cnt=0; NULL!=(print=prints[cnt]); ++cnt) {
>
> fingers[fp_dscv_print_get_finger(print)-LEFT_THUMB].fp=print;
> }
209,211c337,397
< r = do_verify(pamh, dev, data, finger);
< fp_print_data_free(data);
< fp_dev_close(dev);
---
> if (reqfinger != -1) {
> /* Set the only required finger */
> fingers[0].fp=fingers[reqfinger].fp;
> fingers[0].fn=LEFT_THUMB+reqfinger;
> } else {
> unsigned long ltime=(unsigned long)time(NULL);
> srandom((ltime&0x0000FFFFL)^(ltime>>16));
>
> if (randomfingers) {
> int f1, f2;
> /* Shuffle the fingers array */
> for (cnt=0; cnt<15; ++cnt) {
> enum fp_finger tfn;
> struct fp_dscv_print *tfp;
> f1=random()%10;
> f2=random()%10;
>
> /* swap fingers[f1] and fingers[f2] */
> tfn=fingers[f1].fn;
> fingers[f1].fn=fingers[f2].fn;
> fingers[f2].fn=tfn;
> tfp=fingers[f1].fp;
> fingers[f1].fp=fingers[f2].fp;
> fingers[f2].fp=tfp;
> }
> }
> }
> /* Now try to acquire and verify reqnfingers fingerprints */
> skipped=0;
> for (cnt=0; cnt<reqnfingers+skipped && cnt+skipped<10; ++cnt) {
> print=fingers[cnt+skipped].fp;
>
> if(NULL==print) { /* finger not enrolled: try
> next one */
> ++skipped;
> continue;
> }
>
> /* Note that different fingerprints could be on
> different readers! */
> ddev = fp_dscv_dev_for_dscv_print(ddevs, print);
> dev = fp_dev_open(ddev);
> if (!dev) {
> break;
> }
>
> r = fp_print_data_from_dscv_print(print, &data);
> if (r) {
> fp_dev_close(dev);
> break;
> }
>
> if(PAM_SUCCESS==do_verify(pamh, dev, data,
> fingers[cnt+skipped].fn)) {
> ++matched;
> }
> fp_print_data_free(data);
> fp_dev_close(dev);
> }
> r=(matched==reqnfingers)?PAM_SUCCESS:PAM_AUTH_ERR;
>
> fp_dscv_prints_free(prints);
> fp_dscv_devs_free(ddevs);
> }
249c435
< r = do_auth(pamh);
---
> r = do_auth(pamh, argc, argv);
_______________________________________________
fprint mailing list
[email protected]
http://lists.reactivated.net/mailman/listinfo/fprint