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

Reply via email to