modules/libmar/sign/nss_secutil.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/modules/libmar/sign/nss_secutil.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,232 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +
     1.8 +/* With the exception of GetPasswordString, this file was
     1.9 +   copied from NSS's cmd/lib/secutil.c hg revision 8f011395145e */
    1.10 +
    1.11 +#include "nss_secutil.h"
    1.12 +
    1.13 +#include "prprf.h"
    1.14 +#ifdef XP_WIN
    1.15 +#include <io.h>
    1.16 +#else
    1.17 +#include <unistd.h>
    1.18 +#endif
    1.19 +
    1.20 +static char consoleName[] =  {
    1.21 +#ifdef XP_UNIX
    1.22 +  "/dev/tty"
    1.23 +#else
    1.24 +  "CON:"
    1.25 +#endif
    1.26 +};
    1.27 +
    1.28 +#if defined(_WINDOWS)
    1.29 +static char * quiet_fgets (char *buf, int length, FILE *input)
    1.30 +{
    1.31 +  int c;
    1.32 +  char *end = buf;
    1.33 +
    1.34 +  /* fflush (input); */
    1.35 +  memset (buf, 0, length);
    1.36 +
    1.37 +  if (!isatty(fileno(input))) {
    1.38 +    return fgets(buf,length,input);
    1.39 +  }
    1.40 +
    1.41 +  while (1)
    1.42 +  {
    1.43 +#if defined (_WIN32_WCE)
    1.44 +    c = getchar();	/* gets a character from stdin */
    1.45 +#else
    1.46 +    c = getch();	/* getch gets a character from the console */
    1.47 +#endif
    1.48 +    if (c == '\b')
    1.49 +    {
    1.50 +      if (end > buf)
    1.51 +        end--;
    1.52 +    }
    1.53 +
    1.54 +    else if (--length > 0)
    1.55 +      *end++ = c;
    1.56 +
    1.57 +    if (!c || c == '\n' || c == '\r')
    1.58 +      break;
    1.59 +  }
    1.60 +
    1.61 +  return buf;
    1.62 +}
    1.63 +#endif
    1.64 +
    1.65 +char *
    1.66 +GetPasswordString(void *arg, char *prompt)
    1.67 +{
    1.68 +  FILE *input = stdin;
    1.69 +  char phrase[200] = {'\0'};
    1.70 +  int isInputTerminal = isatty(fileno(stdin));
    1.71 +
    1.72 +#ifndef _WINDOWS
    1.73 +  if (isInputTerminal) {
    1.74 +    input = fopen(consoleName, "r");
    1.75 +    if (input == NULL) {
    1.76 +      fprintf(stderr, "Error opening input terminal for read\n");
    1.77 +      return NULL;
    1.78 +    }
    1.79 +  }
    1.80 +#endif 
    1.81 +
    1.82 +  if (isInputTerminal) {
    1.83 +    fprintf(stdout, "Please enter your password:\n");
    1.84 +    fflush(stdout);
    1.85 +  }
    1.86 +
    1.87 +  QUIET_FGETS (phrase, sizeof(phrase), input);
    1.88 +
    1.89 +  if (isInputTerminal) {
    1.90 +    fprintf(stdout, "\n");
    1.91 +  }
    1.92 +
    1.93 +#ifndef _WINDOWS
    1.94 +  if (isInputTerminal) {
    1.95 +    fclose(input);
    1.96 +  }
    1.97 +#endif
    1.98 +
    1.99 +  /* Strip off the newlines if present */
   1.100 +  if (phrase[PORT_Strlen(phrase)-1] == '\n' || 
   1.101 +      phrase[PORT_Strlen(phrase)-1] == '\r') {
   1.102 +    phrase[PORT_Strlen(phrase)-1] = 0;
   1.103 +  }
   1.104 +  return (char*) PORT_Strdup(phrase);
   1.105 +}
   1.106 +
   1.107 +char *
   1.108 +SECU_FilePasswd(PK11SlotInfo *slot, PRBool retry, void *arg)
   1.109 +{
   1.110 +  char* phrases, *phrase;
   1.111 +  PRFileDesc *fd;
   1.112 +  int32_t nb;
   1.113 +  char *pwFile = arg;
   1.114 +  int i;
   1.115 +  const long maxPwdFileSize = 4096;
   1.116 +  char* tokenName = NULL;
   1.117 +  int tokenLen = 0;
   1.118 +
   1.119 +  if (!pwFile)
   1.120 +    return 0;
   1.121 +
   1.122 +  if (retry) {
   1.123 +    return 0;  /* no good retrying - the files contents will be the same */
   1.124 +  }
   1.125 +
   1.126 +  phrases = PORT_ZAlloc(maxPwdFileSize);
   1.127 +
   1.128 +  if (!phrases) {
   1.129 +    return 0; /* out of memory */
   1.130 +  }
   1.131 +
   1.132 +  fd = PR_Open(pwFile, PR_RDONLY, 0);
   1.133 +  if (!fd) {
   1.134 +    fprintf(stderr, "No password file \"%s\" exists.\n", pwFile);
   1.135 +    PORT_Free(phrases);
   1.136 +    return NULL;
   1.137 +  }
   1.138 +
   1.139 +  nb = PR_Read(fd, phrases, maxPwdFileSize);
   1.140 +
   1.141 +  PR_Close(fd);
   1.142 +
   1.143 +  if (nb == 0) {
   1.144 +    fprintf(stderr,"password file contains no data\n");
   1.145 +    PORT_Free(phrases);
   1.146 +    return NULL;
   1.147 +  }
   1.148 +
   1.149 +  if (slot) {
   1.150 +    tokenName = PK11_GetTokenName(slot);
   1.151 +    if (tokenName) {
   1.152 +      tokenLen = PORT_Strlen(tokenName);
   1.153 +    }
   1.154 +  }
   1.155 +  i = 0;
   1.156 +  do
   1.157 +  {
   1.158 +    int startphrase = i;
   1.159 +    int phraseLen;
   1.160 +
   1.161 +    /* handle the Windows EOL case */
   1.162 +    while (phrases[i] != '\r' && phrases[i] != '\n' && i < nb) i++;
   1.163 +    /* terminate passphrase */
   1.164 +    phrases[i++] = '\0';
   1.165 +    /* clean up any EOL before the start of the next passphrase */
   1.166 +    while ( (i<nb) && (phrases[i] == '\r' || phrases[i] == '\n')) {
   1.167 +      phrases[i++] = '\0';
   1.168 +    }
   1.169 +    /* now analyze the current passphrase */
   1.170 +    phrase = &phrases[startphrase];
   1.171 +    if (!tokenName)
   1.172 +      break;
   1.173 +    if (PORT_Strncmp(phrase, tokenName, tokenLen)) continue;
   1.174 +    phraseLen = PORT_Strlen(phrase);
   1.175 +    if (phraseLen < (tokenLen+1)) continue;
   1.176 +    if (phrase[tokenLen] != ':') continue;
   1.177 +    phrase = &phrase[tokenLen+1];
   1.178 +    break;
   1.179 +
   1.180 +  } while (i<nb);
   1.181 +
   1.182 +  phrase = PORT_Strdup((char*)phrase);
   1.183 +  PORT_Free(phrases);
   1.184 +  return phrase;
   1.185 +}
   1.186 +
   1.187 +char *
   1.188 +SECU_GetModulePassword(PK11SlotInfo *slot, PRBool retry, void *arg) 
   1.189 +{
   1.190 +    char prompt[255];
   1.191 +    secuPWData *pwdata = (secuPWData *)arg;
   1.192 +    secuPWData pwnull = { PW_NONE, 0 };
   1.193 +    secuPWData pwxtrn = { PW_EXTERNAL, "external" };
   1.194 +    char *pw;
   1.195 +
   1.196 +    if (pwdata == NULL)
   1.197 +  pwdata = &pwnull;
   1.198 +
   1.199 +    if (PK11_ProtectedAuthenticationPath(slot)) {
   1.200 +  pwdata = &pwxtrn;
   1.201 +    }
   1.202 +    if (retry && pwdata->source != PW_NONE) {
   1.203 +  PR_fprintf(PR_STDERR, "Incorrect password/PIN entered.\n");
   1.204 +      return NULL;
   1.205 +    }
   1.206 +
   1.207 +    switch (pwdata->source) {
   1.208 +    case PW_NONE:
   1.209 +  sprintf(prompt, "Enter Password or Pin for \"%s\":",
   1.210 +                   PK11_GetTokenName(slot));
   1.211 +  return GetPasswordString(NULL, prompt);
   1.212 +    case PW_FROMFILE:
   1.213 +  /* Instead of opening and closing the file every time, get the pw
   1.214 +   * once, then keep it in memory (duh).
   1.215 +   */
   1.216 +  pw = SECU_FilePasswd(slot, retry, pwdata->data);
   1.217 +  pwdata->source = PW_PLAINTEXT;
   1.218 +  pwdata->data = PL_strdup(pw);
   1.219 +  /* it's already been dup'ed */
   1.220 +  return pw;
   1.221 +    case PW_EXTERNAL:
   1.222 +  sprintf(prompt, 
   1.223 +          "Press Enter, then enter PIN for \"%s\" on external device.\n",
   1.224 +    PK11_GetTokenName(slot));
   1.225 +  (void) GetPasswordString(NULL, prompt);
   1.226 +      /* Fall Through */
   1.227 +    case PW_PLAINTEXT:
   1.228 +  return PL_strdup(pwdata->data);
   1.229 +    default:
   1.230 +  break;
   1.231 +    }
   1.232 +
   1.233 +    PR_fprintf(PR_STDERR, "Password check failed:  No password found.\n");
   1.234 +    return NULL;
   1.235 +}

mercurial