Blame modules/libmar/sign/nss_secutil.c

Packit f0b94e
/* This Source Code Form is subject to the terms of the Mozilla Public
Packit f0b94e
 * License, v. 2.0. If a copy of the MPL was not distributed with this
Packit f0b94e
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
Packit f0b94e
Packit f0b94e
/* With the exception of GetPasswordString, this file was
Packit f0b94e
   copied from NSS's cmd/lib/secutil.c hg revision 8f011395145e */
Packit f0b94e
Packit f0b94e
#include "nss_secutil.h"
Packit f0b94e
Packit f0b94e
#include "prprf.h"
Packit f0b94e
#ifdef XP_WIN
Packit f0b94e
#include <io.h>
Packit f0b94e
#else
Packit f0b94e
#include <unistd.h>
Packit f0b94e
#endif
Packit f0b94e
Packit f0b94e
#if defined(_WINDOWS)
Packit f0b94e
static char * quiet_fgets (char *buf, int length, FILE *input)
Packit f0b94e
{
Packit f0b94e
  int c;
Packit f0b94e
  char *end = buf;
Packit f0b94e
Packit f0b94e
  /* fflush (input); */
Packit f0b94e
  memset (buf, 0, length);
Packit f0b94e
Packit f0b94e
  if (!isatty(fileno(input))) {
Packit f0b94e
    return fgets(buf,length,input);
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  while (1)
Packit f0b94e
  {
Packit f0b94e
#if defined (_WIN32_WCE)
Packit f0b94e
    c = getchar();	/* gets a character from stdin */
Packit f0b94e
#else
Packit f0b94e
    c = getch();	/* getch gets a character from the console */
Packit f0b94e
#endif
Packit f0b94e
    if (c == '\b')
Packit f0b94e
    {
Packit f0b94e
      if (end > buf)
Packit f0b94e
        end--;
Packit f0b94e
    }
Packit f0b94e
Packit f0b94e
    else if (--length > 0)
Packit f0b94e
      *end++ = c;
Packit f0b94e
Packit f0b94e
    if (!c || c == '\n' || c == '\r')
Packit f0b94e
      break;
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  return buf;
Packit f0b94e
}
Packit f0b94e
#endif
Packit f0b94e
Packit f0b94e
char *
Packit f0b94e
GetPasswordString(void *arg, char *prompt)
Packit f0b94e
{
Packit f0b94e
  FILE *input = stdin;
Packit f0b94e
  char phrase[200] = {'\0'};
Packit f0b94e
  int isInputTerminal = isatty(fileno(stdin));
Packit f0b94e
Packit f0b94e
#ifndef _WINDOWS
Packit f0b94e
  if (isInputTerminal) {
Packit f0b94e
    static char consoleName[] =  {
Packit f0b94e
#ifdef XP_UNIX
Packit f0b94e
      "/dev/tty"
Packit f0b94e
#else
Packit f0b94e
      "CON:"
Packit f0b94e
#endif
Packit f0b94e
    };
Packit f0b94e
Packit f0b94e
    input = fopen(consoleName, "r");
Packit f0b94e
    if (input == NULL) {
Packit f0b94e
      fprintf(stderr, "Error opening input terminal for read\n");
Packit f0b94e
      return NULL;
Packit f0b94e
    }
Packit f0b94e
  }
Packit f0b94e
#endif 
Packit f0b94e
Packit f0b94e
  if (isInputTerminal) {
Packit f0b94e
    fprintf(stdout, "Please enter your password:\n");
Packit f0b94e
    fflush(stdout);
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  if (!QUIET_FGETS(phrase, sizeof(phrase), input)) {
Packit f0b94e
    fprintf(stderr, "QUIET_FGETS failed\n");
Packit f0b94e
    return NULL;
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  if (isInputTerminal) {
Packit f0b94e
    fprintf(stdout, "\n");
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
#ifndef _WINDOWS
Packit f0b94e
  if (isInputTerminal) {
Packit f0b94e
    fclose(input);
Packit f0b94e
  }
Packit f0b94e
#endif
Packit f0b94e
Packit f0b94e
  /* Strip off the newlines if present */
Packit f0b94e
  if (phrase[PORT_Strlen(phrase)-1] == '\n' || 
Packit f0b94e
      phrase[PORT_Strlen(phrase)-1] == '\r') {
Packit f0b94e
    phrase[PORT_Strlen(phrase)-1] = 0;
Packit f0b94e
  }
Packit f0b94e
  return (char*) PORT_Strdup(phrase);
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
char *
Packit f0b94e
SECU_FilePasswd(PK11SlotInfo *slot, PRBool retry, void *arg)
Packit f0b94e
{
Packit f0b94e
  char* phrases, *phrase;
Packit f0b94e
  PRFileDesc *fd;
Packit f0b94e
  int32_t nb;
Packit f0b94e
  char *pwFile = arg;
Packit f0b94e
  int i;
Packit f0b94e
  const long maxPwdFileSize = 4096;
Packit f0b94e
  char* tokenName = NULL;
Packit f0b94e
  int tokenLen = 0;
Packit f0b94e
Packit f0b94e
  if (!pwFile)
Packit f0b94e
    return 0;
Packit f0b94e
Packit f0b94e
  if (retry) {
Packit f0b94e
    return 0;  /* no good retrying - the files contents will be the same */
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  phrases = PORT_ZAlloc(maxPwdFileSize);
Packit f0b94e
Packit f0b94e
  if (!phrases) {
Packit f0b94e
    return 0; /* out of memory */
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  fd = PR_Open(pwFile, PR_RDONLY, 0);
Packit f0b94e
  if (!fd) {
Packit f0b94e
    fprintf(stderr, "No password file \"%s\" exists.\n", pwFile);
Packit f0b94e
    PORT_Free(phrases);
Packit f0b94e
    return NULL;
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  nb = PR_Read(fd, phrases, maxPwdFileSize);
Packit f0b94e
Packit f0b94e
  PR_Close(fd);
Packit f0b94e
Packit f0b94e
  if (nb == 0) {
Packit f0b94e
    fprintf(stderr,"password file contains no data\n");
Packit f0b94e
    PORT_Free(phrases);
Packit f0b94e
    return NULL;
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  if (slot) {
Packit f0b94e
    tokenName = PK11_GetTokenName(slot);
Packit f0b94e
    if (tokenName) {
Packit f0b94e
      tokenLen = PORT_Strlen(tokenName);
Packit f0b94e
    }
Packit f0b94e
  }
Packit f0b94e
  i = 0;
Packit f0b94e
  do
Packit f0b94e
  {
Packit f0b94e
    int startphrase = i;
Packit f0b94e
    int phraseLen;
Packit f0b94e
Packit f0b94e
    /* handle the Windows EOL case */
Packit f0b94e
    while (phrases[i] != '\r' && phrases[i] != '\n' && i < nb) i++;
Packit f0b94e
    /* terminate passphrase */
Packit f0b94e
    phrases[i++] = '\0';
Packit f0b94e
    /* clean up any EOL before the start of the next passphrase */
Packit f0b94e
    while ( (i
Packit f0b94e
      phrases[i++] = '\0';
Packit f0b94e
    }
Packit f0b94e
    /* now analyze the current passphrase */
Packit f0b94e
    phrase = &phrases[startphrase];
Packit f0b94e
    if (!tokenName)
Packit f0b94e
      break;
Packit f0b94e
    if (PORT_Strncmp(phrase, tokenName, tokenLen)) continue;
Packit f0b94e
    phraseLen = PORT_Strlen(phrase);
Packit f0b94e
    if (phraseLen < (tokenLen+1)) continue;
Packit f0b94e
    if (phrase[tokenLen] != ':') continue;
Packit f0b94e
    phrase = &phrase[tokenLen+1];
Packit f0b94e
    break;
Packit f0b94e
Packit f0b94e
  } while (i
Packit f0b94e
Packit f0b94e
  phrase = PORT_Strdup((char*)phrase);
Packit f0b94e
  PORT_Free(phrases);
Packit f0b94e
  return phrase;
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
char *
Packit f0b94e
SECU_GetModulePassword(PK11SlotInfo *slot, PRBool retry, void *arg) 
Packit f0b94e
{
Packit f0b94e
    char prompt[255];
Packit f0b94e
    secuPWData *pwdata = (secuPWData *)arg;
Packit f0b94e
    secuPWData pwnull = { PW_NONE, 0 };
Packit f0b94e
    secuPWData pwxtrn = { PW_EXTERNAL, "external" };
Packit f0b94e
    char *pw;
Packit f0b94e
Packit f0b94e
    if (pwdata == NULL)
Packit f0b94e
  pwdata = &pwnull;
Packit f0b94e
Packit f0b94e
    if (PK11_ProtectedAuthenticationPath(slot)) {
Packit f0b94e
  pwdata = &pwxtrn;
Packit f0b94e
    }
Packit f0b94e
    if (retry && pwdata->source != PW_NONE) {
Packit f0b94e
  PR_fprintf(PR_STDERR, "Incorrect password/PIN entered.\n");
Packit f0b94e
      return NULL;
Packit f0b94e
    }
Packit f0b94e
Packit f0b94e
    switch (pwdata->source) {
Packit f0b94e
    case PW_NONE:
Packit f0b94e
  sprintf(prompt, "Enter Password or Pin for \"%s\":",
Packit f0b94e
                   PK11_GetTokenName(slot));
Packit f0b94e
  return GetPasswordString(NULL, prompt);
Packit f0b94e
    case PW_FROMFILE:
Packit f0b94e
  /* Instead of opening and closing the file every time, get the pw
Packit f0b94e
   * once, then keep it in memory (duh).
Packit f0b94e
   */
Packit f0b94e
  pw = SECU_FilePasswd(slot, retry, pwdata->data);
Packit f0b94e
  pwdata->source = PW_PLAINTEXT;
Packit f0b94e
  pwdata->data = PL_strdup(pw);
Packit f0b94e
  /* it's already been dup'ed */
Packit f0b94e
  return pw;
Packit f0b94e
    case PW_EXTERNAL:
Packit f0b94e
  sprintf(prompt, 
Packit f0b94e
          "Press Enter, then enter PIN for \"%s\" on external device.\n",
Packit f0b94e
    PK11_GetTokenName(slot));
Packit f0b94e
  pw = GetPasswordString(NULL, prompt);
Packit f0b94e
  if (pw) {
Packit f0b94e
    memset(pw, 0, PORT_Strlen(pw));
Packit f0b94e
    PORT_Free(pw);
Packit f0b94e
  }
Packit f0b94e
      /* Fall Through */
Packit f0b94e
    case PW_PLAINTEXT:
Packit f0b94e
  return PL_strdup(pwdata->data);
Packit f0b94e
    default:
Packit f0b94e
  break;
Packit f0b94e
    }
Packit f0b94e
Packit f0b94e
    PR_fprintf(PR_STDERR, "Password check failed:  No password found.\n");
Packit f0b94e
    return NULL;
Packit f0b94e
}