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