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

io.c

/**
 * Copyright (C) 2006 International Business Machines
 * Author(s): Trevor Highland <tshighla@us.ibm.com>
 *            Theresa Nelson <tmnelson@us.ibm.com>
 *            Tyler Hicks <tyhicks@ou.edu>
 *
 * I/O functions for mount helper
 *
 * 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 <stdio.h>
#include <string.h>
#include <termios.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/mman.h>
#include "ecryptfs.h"
#include "io.h"

static int disable_echo(struct termios *saved_settings)
{
      struct termios current_settings;
      int rc = 0;

      rc = tcgetattr(0, &current_settings);
      if (rc)
            return rc;
      *saved_settings = current_settings;
      current_settings.c_lflag &= ~ECHO;
      rc = tcsetattr(0, TCSANOW, &current_settings);
      return rc;
}

static int enable_echo(struct termios *saved_settings)
{
      return tcsetattr(0, TCSANOW, saved_settings);
}

int get_string_stdin(char **val, char *prompt, int echo)
{
#define DEFAULT_STRING_LENGTH 16
      int count = 0;
      struct termios saved_settings;
      int length = DEFAULT_STRING_LENGTH;
      char *temp;
      int rc = 0;

      printf("%s: ", prompt);
      temp = malloc(length);
      if (!temp) {
            rc = -ENOMEM;
            goto out;
      }
      *val = temp;
      if (!echo) {
            rc = disable_echo(&saved_settings);
            if (rc)
                  goto out;
      }
      do {
            if (count == length) {
                  temp = malloc(length * 2);
                  if (!temp) {
                        rc = -ENOMEM;
                        goto out;
                  }
                  memcpy(temp, *val, length);
                  memset(*val, 0, length);
                  length *= 2;
                  free(*val);
                  *val = temp;
            }
            (*val)[count] = getchar();
            count++;
      } while((*val)[count-1] != '\n');
      (*val)[count - 1] = '\0';
      if (!echo) {
            printf("\n");
            rc = enable_echo(&saved_settings);
      }
out:
      return rc;
}

int get_string(char *val, int len, int echo)
{
      int count = 0;
      struct termios saved_settings;
      int rc = 0;

      if (echo == ECRYPTFS_ECHO_OFF) {
            rc = disable_echo(&saved_settings);
            if (rc)
                  goto out;
      }
      do {
            val[count] = getchar();
            count++;
      } while(val[count-1] != '\n' && (count < len));
      if (count > len)
            val[len - 1] = '\0';
      else
            val[count - 1] = '\0';
      if (echo == ECRYPTFS_ECHO_OFF) {
            printf("\n");
            rc = enable_echo(&saved_settings);
      }
out:
      return rc;
}

static inline int munch_newline(void)
{
      if (getchar() == '\n')
            return 0;
      while (getchar() != '\n');
      return -1;
}

int manager_menu(void)
{
      char str[8];
      int selection;

      printf("\neCryptfs key management menu\n");
      printf("-------------------------------\n");
      printf("\t%d. Add passphrase key to keyring\n", MME_MOUNT_PASSPHRASE);
      printf("\t%d. Add public key to keyring\n", MME_MOUNT_PUBKEY);
      printf("\t%d. Generate new public/private keypair\n", MME_GEN_PUBKEY);
      printf("\t%d. Abort management\n", MME_ABORT);
try_again:
      printf("\nMake selection: ");
      str[0] = getchar();
      if (munch_newline()) {
            printf("Invalid selection\n");
            goto try_again;
      }
      str[strlen(str)] = '\0';
      selection = atoi(str);
      switch (selection) {
      case MME_MOUNT_PASSPHRASE:
      case MME_MOUNT_PUBKEY:
      case MME_GEN_PUBKEY:
      case MME_ABORT:
            break;
      default:
            printf("Invalid selection\n");
            goto try_again;
      }
      return selection;
}

int read_passphrase_salt(char *pass, char *salt)
{
      char *confirmed_pass;
      int rc = 0;

      confirmed_pass = malloc(ECRYPTFS_MAX_PASSWORD_LENGTH);
      if (!confirmed_pass) {
            rc = -ENOMEM;
            ecryptfs_syslog(LOG_ERR, "Failed to allocate memory\n");
            goto out;
      }
      mlock(confirmed_pass, ECRYPTFS_MAX_PASSWORD_LENGTH);
      printf("\n\tMount-wide passphrase: ");
      rc = get_string(pass, ECRYPTFS_MAX_PASSWORD_LENGTH, ECRYPTFS_ECHO_OFF);
      if (rc)
            goto out;
      if (pass[0] == '\0') {
            printf("Invalid passphrase. Aborting mount.\n");
            rc = -EINVAL;
            goto out;
      }
      printf("\tConfirm passphrase: ");
      rc = get_string(confirmed_pass, ECRYPTFS_MAX_PASSWORD_LENGTH,
                  ECRYPTFS_ECHO_OFF);
      if (rc) {
            ecryptfs_syslog(LOG_ERR, "Failed to read passphrase\n");
            goto out;
      }
      if (strcmp(pass, confirmed_pass) != 0) {
            printf("Passphrase mismatch. Aborting mount\n");
            rc = -EINVAL;
            goto out;
      }
      printf("\tUsing the default salt value\n");
out:
      memset(confirmed_pass, 0, ECRYPTFS_MAX_PASSWORD_LENGTH);
      free(confirmed_pass);
      return rc;
}

int ecryptfs_set_name_value_pairs(struct ecryptfs_name_val_pair *nvp)
{
      char *val_input = NULL;
      int rc = 0;

      if (!(nvp->next)) {
            printf("No PKI parameters required\n");
            rc = 0;
            goto out;
      }
      val_input = malloc(MAX_PKI_VALUE_SIZE + 1);
      if (!val_input) {
            rc = -errno;
            ecryptfs_syslog(LOG_ERR, "Failed to allocate memory: %s\n",
                        strerror(errno));
            goto out;
      }
      mlock(val_input, MAX_PKI_VALUE_SIZE + 1);
      nvp = nvp->next;
      while (nvp) {
            if(nvp->flags & ECRYPTFS_DEFAULT_VALUE_SET)
                  printf("\t%s [%s]: ", nvp->name, nvp->value);
            else
                  printf("\t%s: ", nvp->name);
            if (get_string(val_input, MAX_PKI_VALUE_SIZE,
                         nvp->flags & ECRYPTFS_ECHO)) {
                  rc = -EIO;
                  fprintf(stderr, "Failed to read user input\n");
                  goto out;
            }
            if(!(nvp->flags & ECRYPTFS_DEFAULT_VALUE_SET)
               || *val_input !='\0') {
                  rc = asprintf(&nvp->value, "%s", val_input);
                  if (rc < 0) {
                        rc = -ENOMEM;
                        ecryptfs_syslog(LOG_ERR, "Failed to allocate memory\n");
                        goto out;
                  }
            }
            if (nvp->flags & ECRYPTFS_MLOCK) {
                  if (mlock(nvp->value, rc) < 0) {
                        rc = -errno;
                        ecryptfs_syslog(LOG_ERR, "Failed to lock "
                                    "memory used to store user "
                                    "input: %s\n", strerror(errno));
                        goto out;
                  }
            }
            nvp = nvp->next;
      }
      rc = 0;
out:
      if (val_input) {
            memset(val_input, 0, MAX_PKI_VALUE_SIZE);
            free(val_input);
      }
      return rc;
}

int ecryptfs_select_pki(struct ecryptfs_ctx *ctx,
                        struct ecryptfs_pki_elem **selected_pki)
{
        int rc;
        int pki_type;
        int count;
        struct ecryptfs_pki_elem *curr;
        char str[8];
      int default_pki = 1;

prompt_user:
        count = 1;
        curr = ctx->pki_list_head.next;
        if (!curr) {
                rc = 1;
                goto out;
        }
        if (!(curr->next))
                goto success;
      printf("\nThe following PKI modules are available:\n");
        while (curr) {
                printf("\t%i. %s\n", count, curr->pki_name);
                count++;
                curr = curr->next;
        }
      printf("\nSelect desired PKI [%d]: ", default_pki);
        fgets(str, 4, stdin);
      printf("\n");
        str[strlen(str)] = '\0';
      if (str[0] == '\n')
            pki_type = default_pki;
      else
            pki_type = atoi(str);
        if (pki_type < 1 || pki_type >= count) {
                char *pch = strstr(str, "\n");

                printf("Invalid selection\n");
                if (!pch) {
                        int ch;

                        while ((ch = getchar()) != '\n');
                }
                goto prompt_user;
        }
        curr = ctx->pki_list_head.next;
        while(pki_type > 1) {
                curr = curr->next;
                pki_type--;
        }
success:
        *selected_pki = curr;
        rc = 0;
out:
        return rc;
}

Generated by  Doxygen 1.6.0   Back to index