static int get_alignment(int fd)
{
- int alignment = DEFAULT_ALIGNMENT;
+ int alignment = DEFAULT_MEM_ALIGNMENT;
#ifdef _PC_REC_XFER_ALIGN
alignment = fpathconf(fd, _PC_REC_XFER_ALIGN);
if (alignment < 0)
- alignment = DEFAULT_ALIGNMENT;
+ alignment = DEFAULT_MEM_ALIGNMENT;
#endif
return alignment;
}
tcsetattr(infd, TCSAFLUSH, &orig);
out_err:
- if (!failed)
- (void)write(outfd, "\n", 1);
+ if (!failed && write(outfd, "\n", 1));
+
if (infd != STDIN_FILENO)
close(infd);
return failed;
/*
* Password reading behaviour matrix of get_key
- *
+ * FIXME: rewrite this from scratch.
* p v n h
* -----------------+---+---+---+---
* interactive | Y | Y | Y | Inf
const char *key_file, int timeout, int how2verify,
struct crypt_device *cd)
{
- int fd;
+ int fd = -1;
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;
int regular_file = 0;
+ int read_stdin;
int r;
+ struct stat st;
- if(key_file && !strcmp(key_file, "-")) {
- /* Allow binary reading from stdin */
- fd = STDIN_FILENO;
- newline_stop = 0;
- read_horizon = 0;
- } else if (key_file) {
- fd = open(key_file, O_RDONLY);
- if (fd < 0) {
- log_err(cd, "Failed to open key file %s.\n", key_file);
- goto out_err;
- }
- newline_stop = 0;
+ /* Passphrase read from stdin? */
+ read_stdin = (!key_file || !strcmp(key_file, "-")) ? 1 : 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 = STDIN_FILENO;
- newline_stop = 1;
- read_horizon = 0; /* Infinite, if read from terminal or fd */
+ /* read_horizon applies only for real keyfile, not stdin or terminal */
+ read_horizon = (key_file && !read_stdin) ? key_size : 0 /* until EOF */;
+
+ /* Setup file descriptior */
+ fd = read_stdin ? STDIN_FILENO : open(key_file, O_RDONLY);
+ if (fd < 0) {
+ log_err(cd, _("Failed to open key file %s.\n"), key_file ?: "-");
+ goto out_err;
}
/* Interactive case */
pass = safe_alloc(MAX_TTY_PASSWORD_LEN);
if (!pass || (i = interactive_pass(prompt, pass, MAX_TTY_PASSWORD_LEN, timeout))) {
- log_err(cd, "Error reading passphrase from terminal.\n");
+ log_err(cd, _("Error reading passphrase from terminal.\n"));
goto out_err;
}
if (verify || verify_if_possible) {
char pass_verify[MAX_TTY_PASSWORD_LEN];
- i = interactive_pass("Verify passphrase: ", pass_verify, sizeof(pass_verify), timeout);
+ i = interactive_pass(_("Verify passphrase: "), pass_verify, sizeof(pass_verify), timeout);
if (i || strcmp(pass, pass_verify) != 0) {
- log_err(cd, "Passphrases do not match.\n");
+ log_err(cd, _("Passphrases do not match.\n"));
goto out_err;
}
memset(pass_verify, 0, sizeof(pass_verify));
int buflen, i;
if(verify) {
- log_err(cd, "Can't do passphrase verification on non-tty inputs.\n");
+ log_err(cd, _("Can't do passphrase verification on non-tty inputs.\n"));
goto out_err;
}
/* The following for control loop does an exhausting
* 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(!read_stdin && read_horizon == 0) {
if(stat(key_file, &st) < 0) {
- log_err(cd, "Failed to stat key file %s.\n", key_file);
+ log_err(cd, _("Failed to stat key file %s.\n"), key_file);
goto out_err;
}
if(!S_ISREG(st.st_mode))
- log_std(cd, "Warning: exhausting read requested, but key file %s"
- " is not a regular file, function might never return.\n",
+ log_std(cd, _("Warning: exhausting read requested, but key file %s"
+ " is not a regular file, function might never return.\n"),
key_file);
else
regular_file = 1;
buflen += 128;
pass = safe_realloc(pass, buflen);
if (!pass) {
- log_err(cd, "Out of memory while reading passphrase.\n");
+ log_err(cd, _("Out of memory while reading passphrase.\n"));
goto out_err;
}
}
goto out_err;
}
- if(r == 0 || (newline_stop && pass[i] == '\n'))
+ /* Stop on newline only if not requested read from keyfile */
+ if(r == 0 || (!key_file && pass[i] == '\n'))
break;
}
- if(key_file)
- close(fd);
/* Fail if piped input dies reading nothing */
if(!i && !regular_file) {
log_dbg("Error reading passphrase.");
*key = pass;
*passLen = i;
}
+ if(fd != STDIN_FILENO)
+ close(fd);
return;
out_err:
+ if(fd >= 0 && fd != STDIN_FILENO)
+ close(fd);
if(pass)
safe_free(pass);
*key = NULL;
}
return _memlock_count ? 1 : 0;
}
+
+/* DEVICE TOPOLOGY */
+
+/* block device topology ioctls, introduced in 2.6.32 */
+#ifndef BLKIOMIN
+#define BLKIOMIN _IO(0x12,120)
+#define BLKIOOPT _IO(0x12,121)
+#define BLKALIGNOFF _IO(0x12,122)
+#endif
+
+void get_topology_alignment(const char *device,
+ unsigned long *required_alignment, /* bytes */
+ unsigned long *alignment_offset, /* bytes */
+ unsigned long default_alignment)
+{
+ int dev_alignment_offset = 0;
+ unsigned int min_io_size = 0, opt_io_size = 0;
+ unsigned long temp_alignment = 0;
+ int fd;
+
+ *required_alignment = default_alignment;
+ *alignment_offset = 0;
+
+ fd = open(device, O_RDONLY);
+ if (fd == -1)
+ return;
+
+ /* minimum io size */
+ if (ioctl(fd, BLKIOMIN, &min_io_size) == -1) {
+ log_dbg("Topology info for %s not supported, using default offset %lu bytes.",
+ device, default_alignment);
+ goto out;
+ }
+
+ /* optimal io size */
+ if (ioctl(fd, BLKIOOPT, &opt_io_size) == -1)
+ opt_io_size = min_io_size;
+
+ /* alignment offset, bogus -1 means misaligned/unknown */
+ if (ioctl(fd, BLKALIGNOFF, &dev_alignment_offset) == -1 || dev_alignment_offset < 0)
+ dev_alignment_offset = 0;
+ *alignment_offset = (unsigned long)dev_alignment_offset;
+
+ temp_alignment = (unsigned long)min_io_size;
+
+ if (temp_alignment < (unsigned long)opt_io_size)
+ temp_alignment = (unsigned long)opt_io_size;
+
+ /* If calculated alignment is multiple of default, keep default */
+ if (temp_alignment && (default_alignment % temp_alignment))
+ *required_alignment = temp_alignment;
+
+ log_dbg("Topology: IO (%u/%u), offset = %lu; Required alignment is %lu bytes.",
+ min_io_size, opt_io_size, *alignment_offset, *required_alignment);
+out:
+ (void)close(fd);
+}