Logo Search packages:      
Sourcecode: ecryptfs-utils version File versions

pki_list.c

/*
 * Copyright (C) 2006 International Business Machines Corp.
 * Authors: Theresa Nelson <tmnelson@us.ibm.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 * 02111-1307, USA.
 */

#include <dirent.h>
#include <stdlib.h>
#include <string.h>
#ifndef S_SPLINT_S
#include <syslog.h>
#include <stdio.h>
#endif
#include <errno.h>
#include <fcntl.h>
#include <dlfcn.h>
#include <sys/stat.h>
#include "../include/ecryptfs.h"

static int
(*builtin_inits[])(char **pki_name, struct ecryptfs_pki_elem *head) = {
      &passphrase_init_pki,
      NULL
};

int ecryptfs_get_pki_list(struct ecryptfs_ctx* ctx)
{
      DIR *dp = NULL;
      struct dirent *ep;
      char *dir_name = NULL;
      int i;
      struct ecryptfs_pki_elem *curr_pki = &(ctx->pki_list_head);
      int (*init_walker)(char **pki_name, struct ecryptfs_pki_elem *head);
      int rc = 0;

      if (asprintf(&dir_name, "%s", ECRYPTFS_DEFAULT_PKI_DIR) == -1) {
            rc = -ENOMEM;
            goto out;
      }
      if (!(dp = opendir(dir_name))) {
            syslog(LOG_WARNING, "ERROR: Could not open pki directory\n");
            rc = -EPERM;
            goto out;
      }
      while ((ep = readdir(dp))) {
            struct ecryptfs_pki_elem *new_pki = NULL;
            size_t dir_length;
            char *path = NULL;
            char *pki_dir = ECRYPTFS_DEFAULT_PKI_DIR;
            char *pki_name;
            void *handle;
            int (*init)(char **pki_name, struct ecryptfs_pki_elem *head);

            /* Check if file ends with .so */
            dir_length = strlen(ep->d_name);
            if ((dir_length < 3)
                || strcmp((ep->d_name + (dir_length - 3)), ".so"))
                  continue;
            if (asprintf(&path, "%s/%s", pki_dir, ep->d_name) == -1) {
                  syslog(LOG_ERR, "Out of memory\n");
                  rc = -ENOMEM;
                  goto out;
            }
            rc = 0;
            handle = dlopen(path, RTLD_LAZY);
            if (!handle) {
                  syslog(LOG_ERR, "Could not open library handle\n");
                  goto end_loop;
            }
            init = (int (*)(char **pki_name,
                        struct ecryptfs_pki_elem *head))
                  dlsym(handle, "init_pki");
            if (!init) {
                  syslog (LOG_ERR, "%s\n", dlerror());
                  goto end_loop;
            }
            new_pki = malloc(sizeof(struct ecryptfs_pki_elem));
            if (!new_pki) {
                  syslog(LOG_ERR, "Out of memory\n");
                  free(path);
                  rc = -ENOMEM;
                  goto out;
            }
            memset(new_pki, 0, sizeof(struct ecryptfs_pki_elem));
            rc = (init)(&pki_name, new_pki);
            if (rc) {
                  syslog (LOG_ERR, "ERROR: Library function init_pki() "
                        "failed when run\n");
                  free(new_pki);
                  rc = 0;
                  goto end_loop;
            }
            new_pki->pki_name = pki_name;
            new_pki->lib_handle = handle;
            new_pki->libname = path;
            curr_pki->next = new_pki;
            curr_pki = new_pki;
            continue;
      end_loop:
            free(path);
      }
      closedir(dp);
      i = 0;
      init_walker = builtin_inits[i];
      while (init_walker) {
            struct ecryptfs_pki_elem *new_pki;
            char *pki_name;
            struct ecryptfs_pki_elem *tmp_pki;

            if (!(new_pki = malloc(sizeof(struct ecryptfs_pki_elem)))) {
                  syslog(LOG_ERR, "Out of memory\n");
                  rc = -ENOMEM;
                  goto out;
            }
            memset(new_pki, 0, sizeof(struct ecryptfs_pki_elem));
            if ((rc = (init_walker)(&pki_name, new_pki))) {
                  syslog (LOG_ERR, "ERROR: Library function init_pki() "
                        "failed when run\n");
                  free(new_pki);
                  rc = 0;
                  goto end_loop_2;
            }
            tmp_pki = ctx->pki_list_head.next;
            while (tmp_pki) {
                  if (strcmp(tmp_pki->pki_name, pki_name) == 0) {
                        free(new_pki->pki_name);
                        free(new_pki);
                        syslog(LOG_INFO, "Preferring [%s] file over "
                               "built-in module for key module with "
                               "name [%s]\n", tmp_pki->libname,
                               tmp_pki->pki_name);
                        goto end_loop_2;
                  }
                  tmp_pki = tmp_pki->next;
            }
            new_pki->pki_name = pki_name;
            curr_pki->next = new_pki;
            curr_pki = new_pki;
end_loop_2:
            i++;
            init_walker = builtin_inits[i];
      }
out:
      free(dir_name);
      return rc;
}

int ecryptfs_find_pki(struct ecryptfs_ctx *ctx, char *pki_name,
                  struct ecryptfs_pki_elem **desired_pki)
{
      struct ecryptfs_pki_elem *curr;
      int rc = 0;

      curr = ctx->pki_list_head.next;
      while (curr) {
            if (!strncmp(curr->pki_name, pki_name,
                       strlen(curr->pki_name))) {
                  *desired_pki = curr;
                  goto out;
            }
            curr = curr->next;
      }
      rc = 1;
out:
      return rc;
}

int ecryptfs_reset_pki(struct ecryptfs_ctx *ctx)
{
      struct ecryptfs_pki_elem *curr = ctx->pki_list_head.next;
      int rc = 0;

      while (curr) {
            struct ecryptfs_name_val_pair *pki_nvp = &(curr->nvp_head);
            pki_nvp = pki_nvp->next;
            while(pki_nvp){
                  free(pki_nvp->value);
                  pki_nvp->value = NULL;
                  pki_nvp = pki_nvp->next;
            }
            curr = curr->next;
      }
      return rc;
}

int ecryptfs_free_pki_list(struct ecryptfs_ctx *ctx)
{
      struct ecryptfs_pki_elem *curr = ctx->pki_list_head.next;
      struct ecryptfs_pki_elem *temp;

      while (curr) {
            free(curr->libname);
            temp = curr;
            curr = curr->next;
            free(temp);
      }
      return 0;
}

Generated by  Doxygen 1.6.0   Back to index