|
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 |
}
|