- int fd, regular_file, read_stdin, char_read, unlimited_read = 0;
- int r = -EINVAL;
- char *pass = NULL;
- size_t buflen, i;
- struct stat st;
-
- *key = NULL;
- *key_size = 0;
-
- /* Passphrase read from stdin? */
- read_stdin = (!key_file || !strcmp(key_file, "-")) ? 1 : 0;
-
- if(read_stdin && isatty(STDIN_FILENO))
- return crypt_get_key_tty(prompt, key, key_size, timeout, verify, cd);
-
- if (keyfile_size_max < 0) {
- log_err(cd, _("Negative keyfile size not permitted.\n"));
- return -EINVAL;
- }
-
- if (read_stdin)
- log_dbg("STDIN descriptor passphrase entry requested.");
- else
- log_dbg("File descriptor passphrase entry requested.");
-
- /* If not requsted otherwise, we limit input to prevent memory exhaustion */
- if (keyfile_size_max == 0) {
- keyfile_size_max = DEFAULT_KEYFILE_SIZE_MAXKB * 1024;
- unlimited_read = 1;
- }
-
- fd = read_stdin ? STDIN_FILENO : open(key_file, O_RDONLY);
- if (fd < 0) {
- log_err(cd, _("Failed to open key file.\n"));
- return -EINVAL;
- }
-
- /* use 4k for buffer (page divisor but avoid huge pages) */
- buflen = 4096 - sizeof(struct safe_allocation);
- regular_file = 0;
- if(!read_stdin) {
- if(stat(key_file, &st) < 0) {
- log_err(cd, _("Failed to stat key file.\n"));
- goto out_err;
- }
- if(S_ISREG(st.st_mode)) {
- regular_file = 1;
- /* known keyfile size, alloc it in one step */
- if (st.st_size >= keyfile_size_max)
- buflen = keyfile_size_max;
- else
- buflen = st.st_size;
- }
- }
-
- pass = crypt_safe_alloc(buflen);
- if (!pass) {
- log_err(cd, _("Out of memory while reading passphrase.\n"));
- goto out_err;
- }
-
- for(i = 0; i < keyfile_size_max; i++) {
- if(i == buflen) {
- buflen += 4096;
- pass = crypt_safe_realloc(pass, buflen);
- if (!pass) {
- log_err(cd, _("Out of memory while reading passphrase.\n"));
- r = -ENOMEM;
- goto out_err;
- }
- }
-
- char_read = read(fd, &pass[i], 1);
- if (char_read < 0) {
- log_err(cd, _("Error reading passphrase.\n"));
- goto out_err;
- }
-
- /* Stop on newline only if not requested read from keyfile */
- if(char_read == 0 || (!key_file && pass[i] == '\n'))
- break;
- }
-
- /* Fail if piped input dies reading nothing */
- if(!i && !regular_file) {
- log_dbg("Nothing read on input.");
- r = -EPIPE;
- goto out_err;
- }
-
- /* Fail if we exceeded internal default (no specified size) */
- if (unlimited_read && i == keyfile_size_max) {
- log_err(cd, _("Maximum keyfile size exceeeded.\n"));
- goto out_err;
- }
-
- if (!unlimited_read && i != keyfile_size_max) {
- log_err(cd, _("Cannot read requested amount of data.\n"));
- goto out_err;
- }
-
- /* Well, for historical reasons reading empty keyfile is not fail. */
- if(!i) {
- crypt_safe_free(pass);
- pass = NULL;
- }
-
- *key = pass;
- *key_size = i;
- r = 0;
-out_err:
- if(fd != STDIN_FILENO)
- close(fd);
-
- if (r)
- crypt_safe_free(pass);
- return r;