1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
|
#include <stdio.h>
#include <string.h>
#include "insecure_memzero.h"
#include "warnp.h"
#include "readpass.h"
/* Maximum file length. */
#define MAXPASSLEN 2048
/**
* readpass_file(passwd, filename):
* Read a passphrase from ${filename} and return it as a malloced
* NUL-terminated string via ${passwd}. Print an error and fail if the file
* is 2048 characters or more, or if it contains any newline \n or \r\n
* characters other than at the end of the file. Do not include the \n or
* \r\n characters in the passphrase.
*/
int
readpass_file(char ** passwd, const char * filename)
{
FILE * f;
char passbuf[MAXPASSLEN];
/* Open the file. */
if ((f = fopen(filename, "r")) == NULL) {
warnp("fopen(%s)", filename);
goto err1;
}
/* Get a line from the file. */
if ((fgets(passbuf, MAXPASSLEN, f)) == NULL) {
if (ferror(f)) {
warnp("fread(%s)", filename);
goto err2;
} else {
/* We have a 0-byte password. */
passbuf[0] = '\0';
}
}
/* Bail if there's the line is too long, or if there's a second line. */
if (fgetc(f) != EOF) {
warn0("line too long, or more than 1 line in %s", filename);
goto err2;
}
/* Close the file. */
if (fclose(f)) {
warnp("fclose(%s)", filename);
goto err1;
}
/* Truncate at any newline character. */
passbuf[strcspn(passbuf, "\r\n")] = '\0';
/* Copy the password out. */
if ((*passwd = strdup(passbuf)) == NULL) {
warnp("Cannot allocate memory");
goto err1;
}
/* Clean up. */
insecure_memzero(passbuf, MAXPASSLEN);
/* Success! */
return (0);
err2:
if (fclose(f))
warnp("fclose");
err1:
/* No harm in running this for all error paths. */
insecure_memzero(passbuf, MAXPASSLEN);
/* Failure! */
return (-1);
}
|