Doc and build updates
[libfprint.git] / libfprint / data.c
blob79d161db158cd7597caeb51290a473d9f0e41257
1 /*
2 * Fingerprint data handling and storage
3 * Copyright (C) 2007 Daniel Drake <dsd@gentoo.org>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 #include <config.h>
21 #include <errno.h>
22 #include <string.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <unistd.h>
27 #include <glib.h>
29 #include "fp_internal.h"
31 #define DIR_PERMS 0700
33 /** @defgroup print_data Stored prints
34 * Stored prints are represented by a structure named <tt>fp_print_data</tt>.
35 * Stored prints are originally obtained from an enrollment function such as
36 * fp_enroll_finger().
38 * This page documents the various operations you can do with a stored print.
39 * Note that by default, "stored prints" are not actually stored anywhere
40 * except in RAM. For the simple scenarios, libfprint provides a simple API
41 * for you to save and load the stored prints referring to a single user in
42 * their home directory. For more advanced users, libfprint provides APIs for
43 * you to convert print data to a byte string, and to reconstruct stored prints
44 * from such data at a later point. You are welcome to store these byte strings
45 * in any fashion that suits you.
48 static char *base_store = NULL;
50 static void storage_setup(void)
52 const char *homedir;
54 homedir = g_getenv("HOME");
55 if (!homedir)
56 homedir = g_get_home_dir();
57 if (!homedir)
58 return;
60 base_store = g_build_filename(homedir, ".fprint/prints", NULL);
61 g_mkdir_with_parents(base_store, DIR_PERMS);
62 /* FIXME handle failure */
65 void fpi_data_exit(void)
67 g_free(base_store);
70 #define FP_FINGER_IS_VALID(finger) \
71 ((finger) >= LEFT_THUMB && (finger) <= RIGHT_LITTLE)
73 /* for debug messages only */
74 static const char *finger_num_to_str(enum fp_finger finger)
76 const char *names[] = {
77 [LEFT_THUMB] = "left thumb",
78 [LEFT_INDEX] = "left index",
79 [LEFT_MIDDLE] = "left middle",
80 [LEFT_RING] = "left ring",
81 [LEFT_LITTLE] = "left little",
82 [RIGHT_THUMB] = "right thumb",
83 [RIGHT_INDEX] = "right index",
84 [RIGHT_MIDDLE] = "right middle",
85 [RIGHT_RING] = "right ring",
86 [RIGHT_LITTLE] = "right little",
88 if (!FP_FINGER_IS_VALID(finger))
89 return "UNKNOWN";
90 return names[finger];
93 static struct fp_print_data *print_data_new(uint16_t driver_id,
94 uint32_t devtype, enum fp_print_data_type type, size_t length)
96 struct fp_print_data *data = g_malloc(sizeof(*data) + length);
97 fp_dbg("length=%zd driver=%02x devtype=%04x", length, driver_id, devtype);
98 memset(data, 0, sizeof(*data));
99 data->driver_id = driver_id;
100 data->devtype = devtype;
101 data->type = type;
102 data->length = length;
103 return data;
106 struct fp_print_data *fpi_print_data_new(struct fp_dev *dev, size_t length)
108 struct fp_print_data *data = g_malloc(sizeof(*data) + length);
109 memset(data, 0, sizeof(*data));
110 return print_data_new(dev->drv->id, dev->devtype,
111 fpi_driver_get_data_type(dev->drv), length);
114 /** \ingroup print_data
115 * Convert a stored print into a unified representation inside a data buffer.
116 * You can then store this data buffer in any way that suits you, and load
117 * it back at some later time using fp_print_data_from_data().
118 * \param data the stored print
119 * \param ret output location for the data buffer. Must be freed with free()
120 * after use.
121 * \returns the size of the freshly allocated buffer, or 0 on error.
123 API_EXPORTED size_t fp_print_data_get_data(struct fp_print_data *data,
124 unsigned char **ret)
126 struct fpi_print_data_fp1 *buf;
127 size_t buflen;
129 fp_dbg("");
131 buflen = sizeof(*buf) + data->length;
132 buf = malloc(buflen);
133 if (!buf)
134 return 0;
136 *ret = (unsigned char *) buf;
137 buf->prefix[0] = 'F';
138 buf->prefix[1] = 'P';
139 buf->prefix[2] = '1';
140 buf->driver_id = GUINT16_TO_LE(data->driver_id);
141 buf->devtype = GUINT32_TO_LE(data->devtype);
142 buf->data_type = data->type;
143 memcpy(buf->data, data->data, data->length);
144 return buflen;
147 /** \ingroup print_data
148 * Load a stored print from a data buffer. The contents of said buffer must
149 * be the untouched contents of a buffer previously supplied to you by the
150 * fp_print_data_get_data() function.
151 * \param buf the data buffer
152 * \param buflen the length of the buffer
153 * \returns the stored print represented by the data, or NULL on error. Must
154 * be freed with fp_print_data_free() after use.
156 API_EXPORTED struct fp_print_data *fp_print_data_from_data(unsigned char *buf,
157 size_t buflen)
159 struct fpi_print_data_fp1 *raw = (struct fpi_print_data_fp1 *) buf;
160 size_t print_data_len;
161 struct fp_print_data *data;
163 fp_dbg("buffer size %zd", buflen);
164 if (buflen < sizeof(*raw))
165 return NULL;
167 if (strncmp(raw->prefix, "FP1", 3) != 0) {
168 fp_dbg("bad header prefix");
169 return NULL;
172 print_data_len = buflen - sizeof(*raw);
173 data = print_data_new(GUINT16_FROM_LE(raw->driver_id),
174 GUINT32_FROM_LE(raw->devtype), raw->data_type, print_data_len);
175 memcpy(data->data, raw->data, print_data_len);
176 return data;
179 static char *get_path_to_storedir(uint16_t driver_id, uint32_t devtype)
181 char idstr[5];
182 char devtypestr[9];
184 g_snprintf(idstr, sizeof(idstr), "%04x", driver_id);
185 g_snprintf(devtypestr, sizeof(devtypestr), "%08x", devtype);
187 return g_build_filename(base_store, idstr, devtypestr, NULL);
190 static char *__get_path_to_print(uint16_t driver_id, uint32_t devtype,
191 enum fp_finger finger)
193 char *dirpath;
194 char *path;
195 char fingername[2];
197 g_snprintf(fingername, 2, "%x", finger);
199 dirpath = get_path_to_storedir(driver_id, devtype);
200 path = g_build_filename(dirpath, fingername, NULL);
201 g_free(dirpath);
202 return path;
205 static char *get_path_to_print(struct fp_dev *dev, enum fp_finger finger)
207 return __get_path_to_print(dev->drv->id, dev->devtype, finger);
210 /** \ingroup print_data
211 * Saves a stored print to disk, assigned to a specific finger. Even though
212 * you are limited to storing only the 10 human fingers, this is a
213 * per-device-type limit. For example, you can store the users right index
214 * finger from a DigitalPersona scanner, and you can also save the right index
215 * finger from a UPEK scanner. When you later come to load the print, the right
216 * one will be automatically selected.
218 * This function will unconditionally overwrite a fingerprint previously
219 * saved for the same finger and device type. The print is saved in a hidden
220 * directory beneath the current user's home directory.
221 * \param data the stored print to save to disk
222 * \param finger the finger that this print corresponds to
223 * \returns 0 on success, non-zero on error.
225 API_EXPORTED int fp_print_data_save(struct fp_print_data *data,
226 enum fp_finger finger)
228 GError *err = NULL;
229 char *path;
230 char *dirpath;
231 unsigned char *buf;
232 size_t len;
233 int r;
235 if (!base_store)
236 storage_setup();
238 fp_dbg("save %s print from driver %04x", finger_num_to_str(finger),
239 data->driver_id);
240 len = fp_print_data_get_data(data, &buf);
241 if (!len)
242 return -ENOMEM;
244 path = __get_path_to_print(data->driver_id, data->devtype, finger);
245 dirpath = g_path_get_dirname(path);
246 r = g_mkdir_with_parents(dirpath, DIR_PERMS);
247 if (r < 0) {
248 fp_err("couldn't create storage directory");
249 g_free(path);
250 g_free(dirpath);
251 return r;
254 fp_dbg("saving to %s", path);
255 g_file_set_contents(path, buf, len, &err);
256 free(buf);
257 g_free(dirpath);
258 g_free(path);
259 if (err) {
260 r = err->code;
261 fp_err("save failed: %s", err->message);
262 g_error_free(err);
263 /* FIXME interpret error codes */
264 return r;
267 return 0;
270 gboolean fpi_print_data_compatible(uint16_t driver_id1, uint32_t devtype1,
271 enum fp_print_data_type type1, uint16_t driver_id2, uint32_t devtype2,
272 enum fp_print_data_type type2)
274 if (driver_id1 != driver_id2) {
275 fp_dbg("driver ID mismatch: %02x vs %02x", driver_id1, driver_id2);
276 return FALSE;
279 if (devtype1 != devtype2) {
280 fp_dbg("devtype mismatch: %04x vs %04x", devtype1, devtype2);
281 return FALSE;
284 if (type1 != type2) {
285 fp_dbg("type mismatch: %d vs %d", type1, type2);
286 return FALSE;
289 return TRUE;
292 static int load_from_file(char *path, struct fp_print_data **data)
294 gsize length;
295 gchar *contents;
296 GError *err = NULL;
297 struct fp_print_data *fdata;
299 fp_dbg("from %s", path);
300 g_file_get_contents(path, &contents, &length, &err);
301 if (err) {
302 int r = err->code;
303 fp_err("%s load failed: %s", path, err->message);
304 g_error_free(err);
305 /* FIXME interpret more error codes */
306 if (r == G_FILE_ERROR_NOENT)
307 return -ENOENT;
308 else
309 return r;
312 fdata = fp_print_data_from_data(contents, length);
313 g_free(contents);
314 if (!fdata)
315 return -EIO;
316 *data = fdata;
317 return 0;
320 /** \ingroup print_data
321 * Loads a previously stored print from disk. The print must have been saved
322 * earlier using the fp_print_data_save() function.
324 * A return code of -ENOENT indicates that the fingerprint requested could not
325 * be found. Other error codes (both positive and negative) are possible for
326 * obscure error conditions (e.g. corruption).
328 * \param dev the device you are loading the print for
329 * \param finger the finger of the file you are loading
330 * \param data output location to put the corresponding stored print. Must be
331 * freed with fp_print_data_free() after use.
332 * \returns 0 on success, non-zero on error
334 API_EXPORTED int fp_print_data_load(struct fp_dev *dev,
335 enum fp_finger finger, struct fp_print_data **data)
337 gchar *path;
338 struct fp_print_data *fdata;
339 int r;
341 if (!base_store)
342 storage_setup();
344 path = get_path_to_print(dev, finger);
345 r = load_from_file(path, &fdata);
346 g_free(path);
347 if (r)
348 return r;
350 if (!fp_dev_supports_print_data(dev, fdata)) {
351 fp_err("print data is not compatible!");
352 fp_print_data_free(fdata);
353 return -EINVAL;
356 *data = fdata;
357 return 0;
360 /** \ingroup print_data
361 * Attempts to load a stored print based on a \ref dscv_print
362 * "discovered print" record.
364 * A return code of -ENOENT indicates that the file referred to by the
365 * discovered print could not be found. Other error codes (both positive and
366 * negative) are possible for obscure error conditions (e.g. corruption).
368 * \param print the discovered print
369 * \param data output location to point to the corresponding stored print. Must
370 * be freed with fp_print_data_free() after use.
371 * \returns 0 on success, non-zero on error.
373 API_EXPORTED int fp_print_data_from_dscv_print(struct fp_dscv_print *print,
374 struct fp_print_data **data)
376 return load_from_file(print->path, data);
379 /** \ingroup print_data
380 * Frees a stored print. Must be called when you are finished using the print.
381 * \param data the stored print to destroy. If NULL, function simply returns.
383 API_EXPORTED void fp_print_data_free(struct fp_print_data *data)
385 g_free(data);
388 /** \ingroup print_data
389 * Gets the \ref driver_id "driver ID" for a stored print. The driver ID
390 * indicates which driver the print originally came from. The print is
391 * only usable with a device controlled by that driver.
392 * \param data the stored print
393 * \returns the driver ID of the driver compatible with the print
395 API_EXPORTED uint16_t fp_print_data_get_driver_id(struct fp_print_data *data)
397 return data->driver_id;
400 /** \ingroup print_data
401 * Gets the \ref devtype "devtype" for a stored print. The devtype represents
402 * which type of device under the parent driver is compatible with the print.
403 * \param data the stored print
404 * \returns the devtype of the device range compatible with the print
406 API_EXPORTED uint32_t fp_print_data_get_devtype(struct fp_print_data *data)
408 return data->devtype;
411 /** @defgroup dscv_print Print discovery
412 * The \ref print_data "stored print" documentation detailed a simple API
413 * for storing per-device prints for a single user, namely
414 * fp_print_data_save(). It also detailed a load function,
415 * fp_print_data_load(), but usage of this function is limited to scenarios
416 * where you know which device you would like to use, and you know which
417 * finger you are looking to verify.
419 * In other cases, it would be more useful to be able to enumerate all
420 * previously saved prints, potentially even before device discovery. These
421 * functions are designed to offer this functionality to you.
423 * Discovered prints are stored in a <tt>dscv_print</tt> structure, and you
424 * can use functions documented below to access some information about these
425 * prints. You can determine if a discovered print appears to be compatible
426 * with a device using functions such as fp_dscv_dev_supports_dscv_print() and
427 * fp_dev_supports_dscv_print().
429 * When you are ready to use the print, you can load it into memory in the form
430 * of a stored print by using the fp_print_data_from_dscv_print() function.
432 * You may have noticed the use of the word "appears" in the above paragraphs.
433 * libfprint performs print discovery simply by examining the file and
434 * directory structure of libfprint's private data store. It does not examine
435 * the actual prints themselves. Just because a print has been discovered
436 * and appears to be compatible with a certain device does not necessarily mean
437 * that it is usable; when you come to load or use it, under unusual
438 * circumstances it may turn out that the print is corrupt or not for the
439 * device that it appeared to be. Also, it is possible that the print may have
440 * been deleted by the time you come to load it.
443 static GSList *scan_dev_store_dir(char *devpath, uint16_t driver_id,
444 uint32_t devtype, GSList *list)
446 GError *err = NULL;
447 const gchar *ent;
448 struct fp_dscv_print *print;
450 GDir *dir = g_dir_open(devpath, 0, &err);
451 if (!dir) {
452 fp_err("opendir %s failed: %s", devpath, err->message);
453 g_error_free(err);
454 return list;
457 while (ent = g_dir_read_name(dir)) {
458 /* ent is an 1 hex character fp_finger code */
459 guint64 val;
460 enum fp_finger finger;
461 gchar *endptr;
463 if (*ent == 0 || strlen(ent) != 1)
464 continue;
466 val = g_ascii_strtoull(ent, &endptr, 16);
467 if (endptr == ent || !FP_FINGER_IS_VALID(val)) {
468 fp_dbg("skipping print file %s", ent);
469 continue;
472 finger = (enum fp_finger) val;
473 print = g_malloc(sizeof(*print));
474 print->driver_id = driver_id;
475 print->devtype = devtype;
476 print->path = g_build_filename(devpath, ent, NULL);
477 print->finger = finger;
478 list = g_slist_prepend(list, print);
481 g_dir_close(dir);
482 return list;
485 static GSList *scan_driver_store_dir(char *drvpath, uint16_t driver_id,
486 GSList *list)
488 GError *err = NULL;
489 const gchar *ent;
491 GDir *dir = g_dir_open(drvpath, 0, &err);
492 if (!dir) {
493 fp_err("opendir %s failed: %s", drvpath, err->message);
494 g_error_free(err);
495 return list;
498 while (ent = g_dir_read_name(dir)) {
499 /* ent is an 8 hex character devtype */
500 guint64 val;
501 uint32_t devtype;
502 gchar *endptr;
503 gchar *path;
505 if (*ent == 0 || strlen(ent) != 8)
506 continue;
508 val = g_ascii_strtoull(ent, &endptr, 16);
509 if (endptr == ent) {
510 fp_dbg("skipping devtype %s", ent);
511 continue;
514 devtype = (uint32_t) val;
515 path = g_build_filename(drvpath, ent, NULL);
516 list = scan_dev_store_dir(path, driver_id, devtype, list);
517 g_free(path);
520 g_dir_close(dir);
521 return list;
524 /** \ingroup dscv_print
525 * Scans the users home directory and returns a list of prints that were
526 * previously saved using fp_print_data_save().
527 * \returns a NULL-terminated list of discovered prints, must be freed with
528 * fp_dscv_prints_free() after use.
530 API_EXPORTED struct fp_dscv_print **fp_discover_prints(void)
532 GDir *dir;
533 const gchar *ent;
534 GError *err = NULL;
535 GSList *tmplist = NULL;
536 GSList *elem;
537 unsigned int tmplist_len;
538 struct fp_dscv_print **list;
539 unsigned int i;
541 if (!base_store)
542 storage_setup();
544 dir = g_dir_open(base_store, 0, &err);
545 if (!dir) {
546 fp_err("opendir %s failed: %s", base_store, err->message);
547 g_error_free(err);
548 return NULL;
551 while (ent = g_dir_read_name(dir)) {
552 /* ent is a 4 hex digit driver_id */
553 gchar *endptr;
554 gchar *path;
555 guint64 val;
556 uint16_t driver_id;
558 if (*ent == 0 || strlen(ent) != 4)
559 continue;
561 val = g_ascii_strtoull(ent, &endptr, 16);
562 if (endptr == ent) {
563 fp_dbg("skipping drv id %s", ent);
564 continue;
567 driver_id = (uint16_t) val;
568 path = g_build_filename(base_store, ent, NULL);
569 tmplist = scan_driver_store_dir(path, driver_id, tmplist);
570 g_free(path);
573 g_dir_close(dir);
574 tmplist_len = g_slist_length(tmplist);
575 list = g_malloc(sizeof(*list) * (tmplist_len + 1));
576 elem = tmplist;
577 for (i = 0; i < tmplist_len; i++, elem = g_slist_next(elem))
578 list[i] = elem->data;
579 list[tmplist_len] = NULL; /* NULL-terminate */
581 g_slist_free(tmplist);
582 return list;
585 /** \ingroup dscv_print
586 * Frees a list of discovered prints. This function also frees the discovered
587 * prints themselves, so make sure you do not use any discovered prints
588 * after calling this function.
589 * \param prints the list of discovered prints. If NULL, function simply
590 * returns.
592 API_EXPORTED void fp_dscv_prints_free(struct fp_dscv_print **prints)
594 int i;
595 struct fp_dscv_print *print;
597 if (!prints)
598 return;
600 for (i = 0; print = prints[i]; i++) {
601 if (print)
602 g_free(print->path);
603 g_free(print);
605 g_free(prints);
608 /** \ingroup dscv_print
609 * Gets the \ref driver_id "driver ID" for a discovered print. The driver ID
610 * indicates which driver the print originally came from. The print is only
611 * usable with a device controlled by that driver.
612 * \param print the discovered print
613 * \returns the driver ID of the driver compatible with the print
615 API_EXPORTED uint16_t fp_dscv_print_get_driver_id(struct fp_dscv_print *print)
617 return print->driver_id;
620 /** \ingroup dscv_print
621 * Gets the \ref devtype "devtype" for a discovered print. The devtype
622 * represents which type of device under the parent driver is compatible
623 * with the print.
624 * \param print the discovered print
625 * \returns the devtype of the device range compatible with the print
627 API_EXPORTED uint32_t fp_dscv_print_get_devtype(struct fp_dscv_print *print)
629 return print->devtype;
632 /** \ingroup dscv_print
633 * Gets the finger code for a discovered print.
634 * \param print discovered print
635 * \returns a finger code from #fp_finger
637 API_EXPORTED enum fp_finger fp_dscv_print_get_finger(struct fp_dscv_print *print)
639 return print->finger;