modules/libmar/sign/nss_secutil.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 /* With the exception of GetPasswordString, this file was
     6    copied from NSS's cmd/lib/secutil.c hg revision 8f011395145e */
     8 #include "nss_secutil.h"
    10 #include "prprf.h"
    11 #ifdef XP_WIN
    12 #include <io.h>
    13 #else
    14 #include <unistd.h>
    15 #endif
    17 static char consoleName[] =  {
    18 #ifdef XP_UNIX
    19   "/dev/tty"
    20 #else
    21   "CON:"
    22 #endif
    23 };
    25 #if defined(_WINDOWS)
    26 static char * quiet_fgets (char *buf, int length, FILE *input)
    27 {
    28   int c;
    29   char *end = buf;
    31   /* fflush (input); */
    32   memset (buf, 0, length);
    34   if (!isatty(fileno(input))) {
    35     return fgets(buf,length,input);
    36   }
    38   while (1)
    39   {
    40 #if defined (_WIN32_WCE)
    41     c = getchar();	/* gets a character from stdin */
    42 #else
    43     c = getch();	/* getch gets a character from the console */
    44 #endif
    45     if (c == '\b')
    46     {
    47       if (end > buf)
    48         end--;
    49     }
    51     else if (--length > 0)
    52       *end++ = c;
    54     if (!c || c == '\n' || c == '\r')
    55       break;
    56   }
    58   return buf;
    59 }
    60 #endif
    62 char *
    63 GetPasswordString(void *arg, char *prompt)
    64 {
    65   FILE *input = stdin;
    66   char phrase[200] = {'\0'};
    67   int isInputTerminal = isatty(fileno(stdin));
    69 #ifndef _WINDOWS
    70   if (isInputTerminal) {
    71     input = fopen(consoleName, "r");
    72     if (input == NULL) {
    73       fprintf(stderr, "Error opening input terminal for read\n");
    74       return NULL;
    75     }
    76   }
    77 #endif 
    79   if (isInputTerminal) {
    80     fprintf(stdout, "Please enter your password:\n");
    81     fflush(stdout);
    82   }
    84   QUIET_FGETS (phrase, sizeof(phrase), input);
    86   if (isInputTerminal) {
    87     fprintf(stdout, "\n");
    88   }
    90 #ifndef _WINDOWS
    91   if (isInputTerminal) {
    92     fclose(input);
    93   }
    94 #endif
    96   /* Strip off the newlines if present */
    97   if (phrase[PORT_Strlen(phrase)-1] == '\n' || 
    98       phrase[PORT_Strlen(phrase)-1] == '\r') {
    99     phrase[PORT_Strlen(phrase)-1] = 0;
   100   }
   101   return (char*) PORT_Strdup(phrase);
   102 }
   104 char *
   105 SECU_FilePasswd(PK11SlotInfo *slot, PRBool retry, void *arg)
   106 {
   107   char* phrases, *phrase;
   108   PRFileDesc *fd;
   109   int32_t nb;
   110   char *pwFile = arg;
   111   int i;
   112   const long maxPwdFileSize = 4096;
   113   char* tokenName = NULL;
   114   int tokenLen = 0;
   116   if (!pwFile)
   117     return 0;
   119   if (retry) {
   120     return 0;  /* no good retrying - the files contents will be the same */
   121   }
   123   phrases = PORT_ZAlloc(maxPwdFileSize);
   125   if (!phrases) {
   126     return 0; /* out of memory */
   127   }
   129   fd = PR_Open(pwFile, PR_RDONLY, 0);
   130   if (!fd) {
   131     fprintf(stderr, "No password file \"%s\" exists.\n", pwFile);
   132     PORT_Free(phrases);
   133     return NULL;
   134   }
   136   nb = PR_Read(fd, phrases, maxPwdFileSize);
   138   PR_Close(fd);
   140   if (nb == 0) {
   141     fprintf(stderr,"password file contains no data\n");
   142     PORT_Free(phrases);
   143     return NULL;
   144   }
   146   if (slot) {
   147     tokenName = PK11_GetTokenName(slot);
   148     if (tokenName) {
   149       tokenLen = PORT_Strlen(tokenName);
   150     }
   151   }
   152   i = 0;
   153   do
   154   {
   155     int startphrase = i;
   156     int phraseLen;
   158     /* handle the Windows EOL case */
   159     while (phrases[i] != '\r' && phrases[i] != '\n' && i < nb) i++;
   160     /* terminate passphrase */
   161     phrases[i++] = '\0';
   162     /* clean up any EOL before the start of the next passphrase */
   163     while ( (i<nb) && (phrases[i] == '\r' || phrases[i] == '\n')) {
   164       phrases[i++] = '\0';
   165     }
   166     /* now analyze the current passphrase */
   167     phrase = &phrases[startphrase];
   168     if (!tokenName)
   169       break;
   170     if (PORT_Strncmp(phrase, tokenName, tokenLen)) continue;
   171     phraseLen = PORT_Strlen(phrase);
   172     if (phraseLen < (tokenLen+1)) continue;
   173     if (phrase[tokenLen] != ':') continue;
   174     phrase = &phrase[tokenLen+1];
   175     break;
   177   } while (i<nb);
   179   phrase = PORT_Strdup((char*)phrase);
   180   PORT_Free(phrases);
   181   return phrase;
   182 }
   184 char *
   185 SECU_GetModulePassword(PK11SlotInfo *slot, PRBool retry, void *arg) 
   186 {
   187     char prompt[255];
   188     secuPWData *pwdata = (secuPWData *)arg;
   189     secuPWData pwnull = { PW_NONE, 0 };
   190     secuPWData pwxtrn = { PW_EXTERNAL, "external" };
   191     char *pw;
   193     if (pwdata == NULL)
   194   pwdata = &pwnull;
   196     if (PK11_ProtectedAuthenticationPath(slot)) {
   197   pwdata = &pwxtrn;
   198     }
   199     if (retry && pwdata->source != PW_NONE) {
   200   PR_fprintf(PR_STDERR, "Incorrect password/PIN entered.\n");
   201       return NULL;
   202     }
   204     switch (pwdata->source) {
   205     case PW_NONE:
   206   sprintf(prompt, "Enter Password or Pin for \"%s\":",
   207                    PK11_GetTokenName(slot));
   208   return GetPasswordString(NULL, prompt);
   209     case PW_FROMFILE:
   210   /* Instead of opening and closing the file every time, get the pw
   211    * once, then keep it in memory (duh).
   212    */
   213   pw = SECU_FilePasswd(slot, retry, pwdata->data);
   214   pwdata->source = PW_PLAINTEXT;
   215   pwdata->data = PL_strdup(pw);
   216   /* it's already been dup'ed */
   217   return pw;
   218     case PW_EXTERNAL:
   219   sprintf(prompt, 
   220           "Press Enter, then enter PIN for \"%s\" on external device.\n",
   221     PK11_GetTokenName(slot));
   222   (void) GetPasswordString(NULL, prompt);
   223       /* Fall Through */
   224     case PW_PLAINTEXT:
   225   return PL_strdup(pwdata->data);
   226     default:
   227   break;
   228     }
   230     PR_fprintf(PR_STDERR, "Password check failed:  No password found.\n");
   231     return NULL;
   232 }

mercurial