- int fd;
- const int verify = how2verify & CRYPT_FLAG_VERIFY;
- const int verify_if_possible = how2verify & CRYPT_FLAG_VERIFY_IF_POSSIBLE;
- char *pass = NULL;
- int newline_stop;
- int read_horizon;
-
- if(key_file && !strcmp(key_file, "-")) {
- /* Allow binary reading from stdin */
- fd = passphrase_fd;
- newline_stop = 0;
- read_horizon = 0;
- } else if (key_file) {
- fd = open(key_file, O_RDONLY);
- if (fd < 0) {
- char buf[128];
- set_error("Error opening key file: %s",
- strerror_r(errno, buf, 128));
- goto out_err;
- }
- newline_stop = 0;
-
- /* This can either be 0 (LUKS) or the actually number
- * of key bytes (default or passed by -s) */
- read_horizon = key_size;
- } else {
- fd = passphrase_fd;
- newline_stop = 1;
- read_horizon = 0; /* Infinite, if read from terminal or fd */
- }
-
- /* Interactive case */
- if(isatty(fd)) {
- int i;
-
- pass = safe_alloc(512);
- if (!pass || (i = interactive_pass(prompt, pass, 512, timeout))) {
- set_error("Error reading passphrase");
- goto out_err;
- }
- if (verify || verify_if_possible) {
- char pass_verify[512];
- i = interactive_pass("Verify passphrase: ", pass_verify, sizeof(pass_verify), timeout);
- if (i || strcmp(pass, pass_verify) != 0) {
- set_error("Passphrases do not match");
- goto out_err;
- }
- memset(pass_verify, 0, sizeof(pass_verify));
- }
- *passLen = strlen(pass);
- *key = pass;
- } else {
- /*
- * This is either a fd-input or a file, in neither case we can verify the input,
- * however we don't stop on new lines if it's a binary file.
- */
- int buflen, i;
-
- if(verify) {
- set_error("Can't do passphrase verification on non-tty inputs");
- goto out_err;
- }
- /* The following for control loop does an exhausting
- * read on the key material file, if requested with
- * key_size == 0, as it's done by LUKS. However, we
- * should warn the user, if it's a non-regular file,
- * such as /dev/random, because in this case, the loop
- * will read forever.
- */
- if(key_file && strcmp(key_file, "-") && read_horizon == 0) {
- struct stat st;
- if(stat(key_file, &st) < 0) {
- set_error("Can't stat key file");
- goto out_err;
- }
- if(!S_ISREG(st.st_mode)) {
- // set_error("Can't do exhausting read on non regular files");
- // goto out_err;
- fprintf(stderr,"Warning: exhausting read requested, but key file is not a regular file, function might never return.\n");
- }
- }
- buflen = 0;
- for(i = 0; read_horizon == 0 || i < read_horizon; i++) {
- if(i >= buflen - 1) {
- buflen += 128;
- pass = safe_realloc(pass, buflen);
- if (!pass) {
- set_error("Not enough memory while "
- "reading passphrase");
- goto out_err;
- }
- }
- if(read(fd, pass + i, 1) != 1 || (newline_stop && pass[i] == '\n'))
- break;
- }
- if(key_file)
- close(fd);
- pass[i] = 0;
- *key = pass;
- *passLen = i;