summaryrefslogtreecommitdiff
path: root/src/tty-ask-password-agent/tty-ask-password-agent.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2015-10-14 22:40:23 +0200
committerLennart Poettering <lennart@poettering.net>2015-10-19 23:13:07 +0200
commit1602b008531ba6e0c704588cb2643daef26b71d9 (patch)
tree20cfee002c72138337da1822654af4e9266f4937 /src/tty-ask-password-agent/tty-ask-password-agent.c
parent0245cf8167d34e483955b90da7f5d5f154ca57ef (diff)
tree-wide: whenever we deal with passwords, erase them from memory after use
A bit snake-oilish, but can't hurt.
Diffstat (limited to 'src/tty-ask-password-agent/tty-ask-password-agent.c')
-rw-r--r--src/tty-ask-password-agent/tty-ask-password-agent.c97
1 files changed, 67 insertions, 30 deletions
diff --git a/src/tty-ask-password-agent/tty-ask-password-agent.c b/src/tty-ask-password-agent/tty-ask-password-agent.c
index 53986babae..7a5ac9fa9c 100644
--- a/src/tty-ask-password-agent/tty-ask-password-agent.c
+++ b/src/tty-ask-password-agent/tty-ask-password-agent.c
@@ -120,23 +120,30 @@ static int ask_password_plymouth(
y = now(CLOCK_MONOTONIC);
- if (y > until)
- return -ETIME;
+ if (y > until) {
+ r = -ETIME;
+ goto finish;
+ }
sleep_for = (int) ((until - y) / USEC_PER_MSEC);
}
- if (flag_file && access(flag_file, F_OK) < 0)
- return -errno;
+ if (flag_file && access(flag_file, F_OK) < 0) {
+ r = -errno;
+ goto finish;
+ }
j = poll(pollfd, notify >= 0 ? 2 : 1, sleep_for);
if (j < 0) {
if (errno == EINTR)
continue;
- return -errno;
- } else if (j == 0)
- return -ETIME;
+ r = -errno;
+ goto finish;
+ } else if (j == 0) {
+ r = -ETIME;
+ goto finish;
+ }
if (notify >= 0 && pollfd[POLL_INOTIFY].revents != 0)
flush_fd(notify);
@@ -149,9 +156,12 @@ static int ask_password_plymouth(
if (errno == EINTR || errno == EAGAIN)
continue;
- return -errno;
- } else if (k == 0)
- return -EIO;
+ r = -errno;
+ goto finish;
+ } else if (k == 0) {
+ r = -EIO;
+ goto finish;
+ }
p += k;
@@ -166,12 +176,14 @@ static int ask_password_plymouth(
* with a normal password request */
packet = mfree(packet);
- if (asprintf(&packet, "*\002%c%s%n", (int) (strlen(message) + 1), message, &n) < 0)
- return -ENOMEM;
+ if (asprintf(&packet, "*\002%c%s%n", (int) (strlen(message) + 1), message, &n) < 0) {
+ r = -ENOMEM;
+ goto finish;
+ }
r = loop_write(fd, packet, n+1, true);
if (r < 0)
- return r;
+ goto finish;
flags &= ~ASK_PASSWORD_ACCEPT_CACHED;
p = 0;
@@ -179,7 +191,8 @@ static int ask_password_plymouth(
}
/* No password, because UI not shown */
- return -ENOENT;
+ r = -ENOENT;
+ goto finish;
} else if (buffer[0] == 2 || buffer[0] == 9) {
uint32_t size;
@@ -191,32 +204,43 @@ static int ask_password_plymouth(
memcpy(&size, buffer+1, sizeof(size));
size = le32toh(size);
- if (size + 5 > sizeof(buffer))
- return -EIO;
+ if (size + 5 > sizeof(buffer)) {
+ r = -EIO;
+ goto finish;
+ }
if (p-5 < size)
continue;
l = strv_parse_nulstr(buffer + 5, size);
- if (!l)
- return -ENOMEM;
+ if (!l) {
+ r = -ENOMEM;
+ goto finish;
+ }
*ret = l;
break;
- } else
+ } else {
/* Unknown packet */
- return -EIO;
+ r = -EIO;
+ goto finish;
+ }
}
- return 0;
+ r = 0;
+
+finish:
+ memory_erase(buffer, sizeof(buffer));
+ return r;
}
static int parse_password(const char *filename, char **wall) {
_cleanup_free_ char *socket_name = NULL, *message = NULL, *packet = NULL;
+ bool accept_cached = false, echo = false;
+ size_t packet_length = 0;
uint64_t not_after = 0;
unsigned pid = 0;
- bool accept_cached = false, echo = false;
const ConfigTableItem items[] = {
{ "Ask", "Socket", config_parse_string, 0, &socket_name },
@@ -270,7 +294,6 @@ static int parse_password(const char *filename, char **wall) {
} else {
union sockaddr_union sa = {};
- size_t packet_length = 0;
_cleanup_close_ int socket_fd = -1;
assert(arg_action == ACTION_QUERY ||
@@ -307,6 +330,8 @@ static int parse_password(const char *filename, char **wall) {
}
}
+ strv_erase(passwords);
+
} else {
_cleanup_free_ char *password = NULL;
int tty_fd = -1;
@@ -338,28 +363,40 @@ static int parse_password(const char *filename, char **wall) {
strcpy(packet + 1, password);
}
}
+
+ string_erase(password);
}
- if (IN_SET(r, -ETIME, -ENOENT))
+ if (IN_SET(r, -ETIME, -ENOENT)) {
/* If the query went away, that's OK */
- return 0;
-
- if (r < 0)
- return log_error_errno(r, "Failed to query password: %m");
+ r = 0;
+ goto finish;
+ }
+ if (r < 0) {
+ log_error_errno(r, "Failed to query password: %m");
+ goto finish;
+ }
socket_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
- if (socket_fd < 0)
- return log_error_errno(errno, "socket(): %m");
+ if (socket_fd < 0) {
+ r = log_error_errno(errno, "socket(): %m");
+ goto finish;
+ }
sa.un.sun_family = AF_UNIX;
strncpy(sa.un.sun_path, socket_name, sizeof(sa.un.sun_path));
r = sendto(socket_fd, packet, packet_length, MSG_NOSIGNAL, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(socket_name));
+ memory_erase(packet, packet_length);
if (r < 0)
return log_error_errno(errno, "Failed to send: %m");
}
return 0;
+
+finish:
+ memory_erase(packet, packet_length);
+ return r;
}
static int wall_tty_block(void) {