Changeset 694 in openpam for trunk/lib


Ignore:
Timestamp:
Aug 15, 2013, 3:23:58 PM (7 years ago)
Author:
Dag-Erling Smørgrav
Message:

Rename oath_dummy_key() to oath_key_dummy() and move it into its own file.

Location:
trunk/lib/liboath
Files:
2 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/lib/liboath/Makefile.am

    r689 r694  
    1111        oath_totp.c \
    1212        oath_key_alloc.c \
     13        oath_key_dummy.c \
    1314        oath_key_free.c \
    1415        oath_key.c
  • trunk/lib/liboath/oath_key.c

    r689 r694  
    267267        return (uri);
    268268}
    269 
    270 struct oath_key *
    271 oath_dummy_key(enum oath_mode mode, enum oath_hash hash, unsigned int digits)
    272 {
    273         struct oath_key *key;
    274 
    275         if ((key = oath_key_alloc()) == NULL)
    276                 return (NULL);
    277         key->mode = mode;
    278         key->digits = digits;
    279         key->counter = 0;
    280         key->timestep = 30;
    281         key->hash = hash;
    282         strcpy(key->label, "oath-dummy-key");
    283         key->labellen = strlen(key->label);
    284         key->keylen = sizeof key->key;
    285         return (key);
    286 }
  • trunk/lib/liboath/oath_key_dummy.c

    r689 r694  
    3434#endif
    3535
    36 #include <sys/types.h>
    37 
    38 #include <errno.h>
    3936#include <inttypes.h>
    40 #include <limits.h>
    41 #include <stdio.h>
    42 #include <stdlib.h>
    4337#include <string.h>
    44 
    45 #include <security/pam_appl.h>
    46 #include <security/openpam.h>
    47 
    48 #include "openpam_asprintf.h"
    49 #include "openpam_strlcmp.h"
    5038
    5139#include <security/oath.h>
    5240
    5341/*
    54  * Allocate a struct oath_key and populate it from a Google Authenticator
    55  * otpauth URI
     42 * OATH
     43 *
     44 * Creates a dummy OATH key structure
    5645 */
    57 struct oath_key *
    58 oath_key_from_uri(const char *uri)
    59 {
    60         struct oath_key *key;
    61         const char *p, *q, *r;
    62         uintmax_t n;
    63         char *e;
    64 
    65         if ((key = oath_key_alloc()) == NULL)
    66                 return (NULL);
    67 
    68         /* check method */
    69         p = uri;
    70         if (strlcmp("otpauth://", p, 10) != 0)
    71                 goto invalid;
    72         p += 10;
    73 
    74         /* check mode (hotp = event, totp = time-sync) */
    75         if ((q = strchr(p, '/')) == NULL)
    76                 goto invalid;
    77         if (strlcmp("hotp", p, q - p) == 0) {
    78                 key->mode = om_hotp;
    79         } else if (strlcmp("totp", p, q - p) == 0) {
    80                 key->mode = om_totp;
    81         } else {
    82                 goto invalid;
    83         }
    84         p = q + 1;
    85 
    86         /* extract label */
    87         if ((q = strchr(p, '?')) == NULL)
    88                 goto invalid;
    89         if ((key->labellen = q - p + 1) > sizeof key->label)
    90                 goto invalid;
    91         memcpy(key->label, p, q - p);
    92         key->label[q - p] = '\0';
    93         p = q + 1;
    94 
    95         /* extract parameters */
    96         key->counter = UINT64_MAX;
    97         while (*p != '\0') {
    98                 if ((q = strchr(p, '=')) == NULL)
    99                         goto invalid;
    100                 q = q + 1;
    101                 if ((r = strchr(p, '&')) == NULL)
    102                         r = strchr(p, '\0');
    103                 if (r < q)
    104                         /* & before = */
    105                         goto invalid;
    106                 /* p points to key, q points to value, r points to & or NUL */
    107                 if (strlcmp("secret=", p, q - p) == 0) {
    108                         if (key->keylen != 0)
    109                                 /* dupe */
    110                                 goto invalid;
    111                         key->keylen = sizeof key->key;
    112                         if (base32_dec(q, r - q, key->key, &key->keylen) != 0)
    113                                 goto invalid;
    114                         if (base32_enclen(key->keylen) != (size_t)(r - q))
    115                                 goto invalid;
    116                 } else if (strlcmp("algorithm=", p, q - p) == 0) {
    117                         if (key->hash != oh_undef)
    118                                 /* dupe */
    119                                 goto invalid;
    120                         if (strlcmp("SHA1", q, r - q) == 0)
    121                                 key->hash = oh_sha1;
    122                         else if (strlcmp("SHA256", q, r - q) == 0)
    123                                 key->hash = oh_sha256;
    124                         else if (strlcmp("SHA512", q, r - q) == 0)
    125                                 key->hash = oh_sha512;
    126                         else if (strlcmp("MD5", q, r - q) == 0)
    127                                 key->hash = oh_md5;
    128                         else
    129                                 goto invalid;
    130                 } else if (strlcmp("digits=", p, q - p) == 0) {
    131                         if (key->digits != 0)
    132                                 /* dupe */
    133                                 goto invalid;
    134                         /* only 6 or 8 */
    135                         if (r - q != 1 || (*q != '6' && *q != '8'))
    136                                 goto invalid;
    137                         key->digits = *q - '0';
    138                 } else if (strlcmp("counter=", p, q - p) == 0) {
    139                         if (key->counter != UINT64_MAX)
    140                                 /* dupe */
    141                                 goto invalid;
    142                         n = strtoumax(q, &e, 10);
    143                         if (e != r || n >= UINT64_MAX)
    144                                 goto invalid;
    145                         key->counter = (uint64_t)n;
    146                 } else if (strlcmp("period=", p, q - p) == 0) {
    147                         if (key->timestep != 0)
    148                                 /* dupe */
    149                                 goto invalid;
    150                         n = strtoumax(q, &e, 10);
    151                         if (e != r || n > OATH_MAX_TIMESTEP)
    152                                 goto invalid;
    153                         key->timestep = n;
    154                 } else {
    155                         goto invalid;
    156                 }
    157                 /* final parameter? */
    158                 if (*r == '\0')
    159                         break;
    160                 /* skip & and continue */
    161                 p = r + 1;
    162         }
    163 
    164         /* sanity checks and default values */
    165         if (key->mode == om_hotp) {
    166                 if (key->timestep != 0)
    167                         goto invalid;
    168                 if (key->counter == UINTMAX_MAX)
    169                         key->counter = 0;
    170         } else if (key->mode == om_totp) {
    171                 if (key->counter != UINTMAX_MAX)
    172                         goto invalid;
    173                 if (key->timestep == 0)
    174                         key->timestep = OATH_DEF_TIMESTEP;
    175         } else {
    176                 /* unreachable */
    177                 oath_key_free(key);
    178                 return (NULL);
    179         }
    180         if (key->hash == oh_undef)
    181                 key->hash = oh_sha1;
    182         if (key->digits == 0)
    183                 key->digits = 6;
    184         if (key->keylen == 0)
    185                 goto invalid;
    186         return (key);
    187 
    188 invalid:
    189         openpam_log(PAM_LOG_NOTICE, "invalid OATH URI: %s", uri);
    190         oath_key_free(key);
    191         return (NULL);
    192 }
    19346
    19447struct oath_key *
    195 oath_key_from_file(const char *filename)
    196 {
    197         struct oath_key *key;
    198         FILE *f;
    199         char *line;
    200         size_t len;
    201 
    202         if ((f = fopen(filename, "r")) == NULL)
    203                 return (NULL);
    204         /* get first non-empty non-comment line */
    205         line = openpam_readline(f, NULL, &len);
    206         if (strlcmp("otpauth://", line, len) == 0) {
    207                 key = oath_key_from_uri(line);
    208         } else {
    209                 openpam_log(PAM_LOG_ERROR,
    210                     "unrecognized key file format: %s", filename);
    211                 key = NULL;
    212         }
    213         fclose(f);
    214         return (key);
    215 }
    216 
    217 char *
    218 oath_key_to_uri(const struct oath_key *key)
    219 {
    220         const char *hash;
    221         char *tmp, *uri;
    222         size_t kslen, urilen;
    223 
    224         switch (key->hash) {
    225         case oh_sha1:
    226                 hash = "SHA1";
    227                 break;
    228         case oh_sha256:
    229                 hash = "SHA256";
    230                 break;
    231         case oh_sha512:
    232                 hash = "SHA512";
    233                 break;
    234         case oh_md5:
    235                 hash = "MD5";
    236                 break;
    237         default:
    238                 return (NULL);
    239         }
    240 
    241         if (key->mode == om_hotp) {
    242                 urilen = asprintf(&uri, "otpauth://"
    243                     "%s/%s?algorithm=%s&digits=%d&counter=%ju&secret=",
    244                     "hotp", key->label, hash, key->digits,
    245                     (uintmax_t)key->counter);
    246         } else if (key->mode == om_totp) {
    247                 urilen = asprintf(&uri, "otpauth://"
    248                     "%s/%s?algorithm=%s&digits=%d&period=%u&secret=",
    249                     "totp", key->label, hash, key->digits, key->timestep);
    250         } else {
    251                 /* unreachable */
    252                 return (NULL);
    253         }
    254 
    255         /* compute length of base32-encoded key and append it */
    256         kslen = base32_enclen(key->keylen) + 1;
    257         if ((tmp = realloc(uri, urilen + kslen)) == NULL) {
    258                 free(uri);
    259                 return (NULL);
    260         }
    261         uri = tmp;
    262         if (base32_enc(key->key, key->keylen, uri + urilen, &kslen) != 0) {
    263                 free(uri);
    264                 return (NULL);
    265         }
    266 
    267         return (uri);
    268 }
    269 
    270 struct oath_key *
    271 oath_dummy_key(enum oath_mode mode, enum oath_hash hash, unsigned int digits)
     48oath_key_dummy(enum oath_mode mode, enum oath_hash hash, unsigned int digits)
    27249{
    27350        struct oath_key *key;
     
    28562        return (key);
    28663}
     64
     65/**
     66 * The =oath_key_dummy function allocates and initializes a dummy OATH key
     67 * structure.
     68 * Authentication attempts using a dummy key will always fail.
     69 *
     70 * Keys allocated with =oath_key_dummy must be freed using =oath_key_free.
     71 *
     72 * >oath_key_alloc
     73 * >oath_key_free
     74 *
     75 * AUTHOR UIO
     76 */
Note: See TracChangeset for help on using the changeset viewer.