diff options
author | Stef Walter <stefw@collabora.co.uk> | 2011-06-24 15:31:02 +0200 |
---|---|---|
committer | Stef Walter <stefw@collabora.co.uk> | 2011-07-06 12:49:26 +0200 |
commit | fd7dee836d0b14efc48bf59955c8a12a72561043 (patch) | |
tree | b4dd8ffef5688edd3ca4321037d6acd2999cf929 /p11-kit | |
parent | 2cc2ab90a6b96ea75dfe4d6413e41539075e8f8a (diff) |
Add P11KitPin structure, which encapsulates a returned pin.
* Lets us use variable size buffers.
* Helps minimize copying.
Diffstat (limited to 'p11-kit')
-rw-r--r-- | p11-kit/pin.c | 171 | ||||
-rw-r--r-- | p11-kit/pin.h | 44 |
2 files changed, 191 insertions, 24 deletions
diff --git a/p11-kit/pin.c b/p11-kit/pin.c index 14cb171..879b6b7 100644 --- a/p11-kit/pin.c +++ b/p11-kit/pin.c @@ -42,11 +42,14 @@ #include "pin.h" #include "private.h" #include "ptr-array.h" +#include "util.h" #include <assert.h> #include <errno.h> +#include <fcntl.h> #include <stdlib.h> #include <string.h> +#include <unistd.h> /** * SECTION:p11-pin @@ -138,7 +141,7 @@ typedef struct _PinfileCallback { /* Readonly after construct */ p11_kit_pin_callback func; void *user_data; - p11_kit_pin_callback_destroy destroy; + p11_kit_pin_destroy_func destroy; } PinfileCallback; /* @@ -173,7 +176,7 @@ unref_pinfile_callback (void *pointer) int p11_kit_pin_register_callback (const char *pinfile, p11_kit_pin_callback callback, - void *callback_data, p11_kit_pin_callback_destroy callback_destroy) + void *callback_data, p11_kit_pin_destroy_func callback_destroy) { PinfileCallback *cb; ptr_array_t *callbacks; @@ -283,16 +286,15 @@ p11_kit_pin_unregister_callback (const char *pinfile, p11_kit_pin_callback callb _p11_unlock (); } -int +P11KitPin* p11_kit_pin_retrieve (const char *pinfile, P11KitUri *pin_uri, - const char *pin_description, P11KitPinFlags flags, - char *pin, size_t pin_length) + const char *pin_description, P11KitPinFlags flags) { PinfileCallback **snapshot = NULL; unsigned int snapshot_count = 0; ptr_array_t *callbacks; + P11KitPin *pin; unsigned int i; - int ret; _p11_lock (); @@ -315,12 +317,11 @@ p11_kit_pin_retrieve (const char *pinfile, P11KitUri *pin_uri, _p11_unlock (); if (snapshot == NULL) - return 0; + return NULL; - ret = 0; - for (i = snapshot_count; ret == 0 && i > 0; i--) { - ret = (snapshot[i - 1]->func) (pinfile, pin_uri, pin_description, flags, - snapshot[i - 1]->user_data, pin, pin_length); + for (pin = NULL, i = snapshot_count; pin == NULL && i > 0; i--) { + pin = (snapshot[i - 1]->func) (pinfile, pin_uri, pin_description, flags, + snapshot[i - 1]->user_data); } _p11_lock (); @@ -329,5 +330,151 @@ p11_kit_pin_retrieve (const char *pinfile, P11KitUri *pin_uri, free (snapshot); _p11_unlock (); - return ret; + return pin; +} + +P11KitPin* +p11_kit_pin_file_callback (const char *pinfile, + P11KitUri *pin_uri, + const char *pin_description, + P11KitPinFlags pin_flags, + void *callback_data) +{ + unsigned char *buffer; + size_t used, allocated; + int error = 0; + int fd; + int res; + + /* We don't support retries */ + if (pin_flags & P11_KIT_PIN_FLAGS_RETRY) + return NULL; + + fd = open (pinfile, O_RDONLY); + if (fd == -1) + return NULL; + + buffer = NULL; + used = 0; + allocated = 0; + + for (;;) { + if (used + 256 > allocated) { + buffer = xrealloc (buffer, used + 1024); + if (buffer == NULL) { + error = ENOMEM; + break; + } + allocated = used + 1024; + } + + res = read (fd, buffer + used, allocated - used); + if (res < 0) { + if (errno == EAGAIN) + continue; + error = errno; + free (buffer); + buffer = NULL; + error = errno; + break; + } else if (res == 0) { + break; + } else { + used += res; + } + } + + if (buffer == NULL) { + errno = error; + return NULL; + } + + return p11_kit_pin_new_for_buffer (buffer, used, free); +} + +struct _P11KitPin { + int ref_count; + unsigned char *buffer; + size_t length; + p11_kit_pin_destroy_func destroy; +}; + +P11KitPin* +p11_kit_pin_new (const unsigned char *value, size_t length) +{ + unsigned char *copy; + P11KitPin *pin; + + copy = malloc (length); + if (copy == NULL) + return NULL; + + memcpy (copy, value, length); + pin = p11_kit_pin_new_for_buffer (copy, length, free); + if (pin == NULL) + free (copy); + return pin; +} + +P11KitPin* +p11_kit_pin_new_for_string (const char *value) +{ + return p11_kit_pin_new ((const unsigned char *)value, strlen (value)); +} + +P11KitPin* +p11_kit_pin_new_for_buffer (unsigned char *buffer, size_t length, + p11_kit_pin_destroy_func destroy) +{ + P11KitPin *pin; + + pin = calloc (1, sizeof (P11KitPin)); + if (pin == NULL) + return NULL; + + pin->ref_count = 1; + pin->buffer = buffer; + pin->length = length; + pin->destroy = destroy; + + return pin; +} + +const unsigned char* +p11_kit_pin_get_value (P11KitPin *pin, size_t *length) +{ + if (length) + *length = pin->length; + return pin->buffer; +} + +P11KitPin* +p11_kit_pin_ref (P11KitPin *pin) +{ + _p11_lock (); + + pin->ref_count++; + + _p11_unlock (); + + return pin; +} + +void +p11_kit_pin_unref (P11KitPin *pin) +{ + int last = 0; + + _p11_lock (); + + last = (pin->ref_count == 1); + pin->ref_count--; + + _p11_unlock (); + + if (last) { + if (pin->destroy) + (pin->destroy) (pin->buffer); + free (pin); + } } diff --git a/p11-kit/pin.h b/p11-kit/pin.h index bb5daae..532aa54 100644 --- a/p11-kit/pin.h +++ b/p11-kit/pin.h @@ -41,6 +41,8 @@ extern "C" { #endif +typedef struct _P11KitPin P11KitPin; + typedef enum { P11_KIT_PIN_FLAGS_USER_LOGIN = 1, P11_KIT_PIN_FLAGS_SO_LOGIN = 2, @@ -52,31 +54,49 @@ typedef enum { #define P11_KIT_PIN_FALLBACK "" -typedef int (*p11_kit_pin_callback) (const char *pinfile, +typedef void (*p11_kit_pin_destroy_func) (void *callback_data); + +P11KitPin* p11_kit_pin_new (const unsigned char *value, + size_t length); + +P11KitPin* p11_kit_pin_new_for_string (const char *value); + +P11KitPin* p11_kit_pin_new_for_buffer (unsigned char *buffer, + size_t length, + p11_kit_pin_destroy_func destroy); + +P11KitPin* p11_kit_pin_ref (P11KitPin *pin); + +void p11_kit_pin_unref (P11KitPin *pin); + +const unsigned char * p11_kit_pin_get_value (P11KitPin *pin, + size_t *length); + +typedef P11KitPin* (*p11_kit_pin_callback) (const char *pinfile, P11KitUri *pin_uri, const char *pin_description, P11KitPinFlags pin_flags, - void *callback_data, - char *pin, - size_t pin_length); - -typedef void (*p11_kit_pin_callback_destroy) (void *callback_data); + void *callback_data); -int p11_kit_pin_register_callback (const char *pinfile, +int p11_kit_pin_register_callback (const char *pinfile, p11_kit_pin_callback callback, void *callback_data, - p11_kit_pin_callback_destroy callback_destroy); + p11_kit_pin_destroy_func callback_destroy); -void p11_kit_pin_unregister_callback (const char *pinfile, +void p11_kit_pin_unregister_callback (const char *pinfile, p11_kit_pin_callback callback, void *callback_data); -int p11_kit_pin_retrieve (const char *pinfile, +P11KitPin* p11_kit_pin_retrieve (const char *pinfile, + P11KitUri *pin_uri, + const char *pin_description, + P11KitPinFlags pin_flags); + +P11KitPin* p11_kit_pin_file_callback (const char *pinfile, P11KitUri *pin_uri, const char *pin_description, P11KitPinFlags pin_flags, - char *pin, - size_t pin_max); + void *callback_data); #ifdef __cplusplus } /* extern "C" */ |