root/source4/heimdal/lib/hx509/ks_dir.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dir_init
  2. dir_free
  3. dir_iter_start
  4. dir_iter
  5. dir_iter_end
  6. _hx509_ks_dir_register

   1 /*
   2  * Copyright (c) 2006 Kungliga Tekniska Högskolan
   3  * (Royal Institute of Technology, Stockholm, Sweden).
   4  * All rights reserved.
   5  *
   6  * Redistribution and use in source and binary forms, with or without
   7  * modification, are permitted provided that the following conditions
   8  * are met:
   9  *
  10  * 1. Redistributions of source code must retain the above copyright
  11  *    notice, this list of conditions and the following disclaimer.
  12  *
  13  * 2. Redistributions in binary form must reproduce the above copyright
  14  *    notice, this list of conditions and the following disclaimer in the
  15  *    documentation and/or other materials provided with the distribution.
  16  *
  17  * 3. Neither the name of the Institute nor the names of its contributors
  18  *    may be used to endorse or promote products derived from this software
  19  *    without specific prior written permission.
  20  *
  21  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
  22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
  25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31  * SUCH DAMAGE.
  32  */
  33 
  34 #include "hx_locl.h"
  35 RCSID("$Id$");
  36 #include <dirent.h>
  37 
  38 /*
  39  * The DIR keyset module is strange compared to the other modules
  40  * since it does lazy evaluation and really doesn't keep any local
  41  * state except for the directory iteration and cert iteration of
  42  * files. DIR ignores most errors so that the consumer doesn't get
  43  * failes for stray files in directories.
  44  */
  45 
  46 struct dircursor {
  47     DIR *dir;
  48     hx509_certs certs;
  49     void *iter;
  50 };
  51 
  52 /*
  53  *
  54  */
  55 
  56 static int
  57 dir_init(hx509_context context,
     /* [<][>][^][v][top][bottom][index][help] */
  58          hx509_certs certs, void **data, int flags,
  59          const char *residue, hx509_lock lock)
  60 {
  61     *data = NULL;
  62 
  63     {
  64         struct stat sb;
  65         int ret;
  66 
  67         ret = stat(residue, &sb);
  68         if (ret == -1) {
  69             hx509_set_error_string(context, 0, ENOENT,
  70                                    "No such file %s", residue);
  71             return ENOENT;
  72         }
  73 
  74         if ((sb.st_mode & S_IFDIR) == 0) {
  75             hx509_set_error_string(context, 0, ENOTDIR,
  76                                    "%s is not a directory", residue);
  77             return ENOTDIR;
  78         }
  79     }
  80 
  81     *data = strdup(residue);
  82     if (*data == NULL) {
  83         hx509_clear_error_string(context);
  84         return ENOMEM;
  85     }
  86 
  87     return 0;
  88 }
  89 
  90 static int
  91 dir_free(hx509_certs certs, void *data)
     /* [<][>][^][v][top][bottom][index][help] */
  92 {
  93     free(data);
  94     return 0;
  95 }
  96 
  97 
  98 
  99 static int
 100 dir_iter_start(hx509_context context,
     /* [<][>][^][v][top][bottom][index][help] */
 101                hx509_certs certs, void *data, void **cursor)
 102 {
 103     struct dircursor *d;
 104 
 105     *cursor = NULL;
 106 
 107     d = calloc(1, sizeof(*d));
 108     if (d == NULL) {
 109         hx509_clear_error_string(context);
 110         return ENOMEM;
 111     }
 112 
 113     d->dir = opendir(data);
 114     if (d->dir == NULL) {
 115         hx509_clear_error_string(context);
 116         free(d);
 117         return errno;
 118     }
 119     rk_cloexec(dirfd(d->dir));
 120     d->certs = NULL;
 121     d->iter = NULL;
 122 
 123     *cursor = d;
 124     return 0;
 125 }
 126 
 127 static int
 128 dir_iter(hx509_context context,
     /* [<][>][^][v][top][bottom][index][help] */
 129          hx509_certs certs, void *data, void *iter, hx509_cert *cert)
 130 {
 131     struct dircursor *d = iter;
 132     int ret = 0;
 133 
 134     *cert = NULL;
 135 
 136     do {
 137         struct dirent *dir;
 138         char *fn;
 139 
 140         if (d->certs) {
 141             ret = hx509_certs_next_cert(context, d->certs, d->iter, cert);
 142             if (ret) {
 143                 hx509_certs_end_seq(context, d->certs, d->iter);
 144                 d->iter = NULL;
 145                 hx509_certs_free(&d->certs);
 146                 return ret;
 147             }
 148             if (*cert) {
 149                 ret = 0;
 150                 break;
 151             }
 152             hx509_certs_end_seq(context, d->certs, d->iter);
 153             d->iter = NULL;
 154             hx509_certs_free(&d->certs);
 155         }
 156 
 157         dir = readdir(d->dir);
 158         if (dir == NULL) {
 159             ret = 0;
 160             break;
 161         }
 162         if (strcmp(dir->d_name, ".") == 0 || strcmp(dir->d_name, "..") == 0)
 163             continue;
 164         
 165         if (asprintf(&fn, "FILE:%s/%s", (char *)data, dir->d_name) == -1)
 166             return ENOMEM;
 167         
 168         ret = hx509_certs_init(context, fn, 0, NULL, &d->certs);
 169         if (ret == 0) {
 170 
 171             ret = hx509_certs_start_seq(context, d->certs, &d->iter);
 172             if (ret)
 173             hx509_certs_free(&d->certs);
 174         }
 175         /* ignore errors */
 176         if (ret) {
 177             d->certs = NULL;
 178             ret = 0;
 179         }
 180 
 181         free(fn);
 182     } while(ret == 0);
 183 
 184     return ret;
 185 }
 186 
 187 
 188 static int
 189 dir_iter_end(hx509_context context,
     /* [<][>][^][v][top][bottom][index][help] */
 190              hx509_certs certs,
 191              void *data,
 192              void *cursor)
 193 {
 194     struct dircursor *d = cursor;
 195 
 196     if (d->certs) {
 197         hx509_certs_end_seq(context, d->certs, d->iter);
 198         d->iter = NULL;
 199         hx509_certs_free(&d->certs);
 200     }
 201     closedir(d->dir);
 202     free(d);
 203     return 0;
 204 }
 205 
 206 
 207 static struct hx509_keyset_ops keyset_dir = {
 208     "DIR",
 209     0,
 210     dir_init,
 211     NULL,
 212     dir_free,
 213     NULL,
 214     NULL,
 215     dir_iter_start,
 216     dir_iter,
 217     dir_iter_end
 218 };
 219 
 220 void
 221 _hx509_ks_dir_register(hx509_context context)
     /* [<][>][^][v][top][bottom][index][help] */
 222 {
 223     _hx509_ks_register(context, &keyset_dir);
 224 }

/* [<][>][^][v][top][bottom][index][help] */