ask-password: add support for caching passwords in the kernel keyring

This adds support for caching harddisk passwords in the kernel keyring
if it is available, thus supporting caching without Plymouth being
around.

This is also useful for hooking up "gdm-auto-login" with the collected
boot-time harddisk password, in order to support gnome keyring
passphrase unlocking via the HDD password, if it is the same.

Any passwords added to the kernel keyring this way have a timeout of
2.5min at which time they are purged from the kernel.
This commit is contained in:
Lennart Poettering
2015-10-07 12:26:14 +02:00
parent 0084360296
commit e287086b8a
16 changed files with 492 additions and 155 deletions
+45
View File
@@ -1063,3 +1063,48 @@ static inline int kcmp(pid_t pid1, pid_t pid2, int type, unsigned long idx1, uns
#ifndef INPUT_PROP_ACCELEROMETER
#define INPUT_PROP_ACCELEROMETER 0x06
#endif
#if !HAVE_DECL_KEY_SERIAL_T
typedef int32_t key_serial_t;
#endif
#if !HAVE_DECL_KEYCTL
static inline long keyctl(int cmd, unsigned long arg2, unsigned long arg3, unsigned long arg4,unsigned long arg5) {
#if defined(__NR_keyctl)
return syscall(__NR_keyctl, cmd, arg2, arg3, arg4, arg5);
#else
errno = ENOSYS;
return -1;
#endif
}
static inline key_serial_t add_key(const char *type, const char *description, const void *payload, size_t plen, key_serial_t ringid) {
#if defined (__NR_add_key)
return syscall(__NR_add_key, type, description, payload, plen, ringid);
#else
errno = ENOSYS;
return -1;
#endif
}
static inline key_serial_t request_key(const char *type, const char *description, const char * callout_info, key_serial_t destringid) {
#if defined (__NR_request_key)
return syscall(__NR_request_key, type, description, callout_info, destringid);
#else
errno = ENOSYS;
return -1;
#endif
}
#endif
#ifndef KEYCTL_READ
#define KEYCTL_READ 11
#endif
#ifndef KEYCTL_SET_TIMEOUT
#define KEYCTL_SET_TIMEOUT 15
#endif
#ifndef KEY_SPEC_USER_KEYRING
#define KEY_SPEC_USER_KEYRING -4
#endif
+79 -9
View File
@@ -188,17 +188,48 @@ char **strv_new(const char *x, ...) {
return r;
}
int strv_extend_strv(char ***a, char **b) {
int r;
char **s;
int strv_extend_strv(char ***a, char **b, bool filter_duplicates) {
char **s, **t;
size_t p, q, i = 0, j;
assert(a);
if (strv_isempty(b))
return 0;
p = strv_length(*a);
q = strv_length(b);
t = realloc(*a, sizeof(char*) * (p + q + 1));
if (!t)
return -ENOMEM;
t[p] = NULL;
*a = t;
STRV_FOREACH(s, b) {
r = strv_extend(a, *s);
if (r < 0)
return r;
if (filter_duplicates && strv_contains(t, *s))
continue;
t[p+i] = strdup(*s);
if (!t[p+i])
goto rollback;
i++;
t[p+i] = NULL;
}
return 0;
assert(i <= q);
return (int) i;
rollback:
for (j = 0; j < i; j++)
free(t[p + j]);
t[p] = NULL;
return -ENOMEM;
}
int strv_extend_strv_concat(char ***a, char **b, const char *suffix) {
@@ -618,6 +649,41 @@ char **strv_split_nulstr(const char *s) {
return r;
}
int strv_make_nulstr(char **l, char **p, size_t *q) {
size_t n_allocated = 0, n = 0;
_cleanup_free_ char *m = NULL;
char **i;
assert(p);
assert(q);
STRV_FOREACH(i, l) {
size_t z;
z = strlen(*i);
if (!GREEDY_REALLOC(m, n_allocated, n + z + 1))
return -ENOMEM;
memcpy(m + n, *i, z + 1);
n += z + 1;
}
if (!m) {
m = new0(char, 1);
if (!m)
return -ENOMEM;
n = 0;
}
*p = m;
*q = n;
m = NULL;
return 0;
}
bool strv_overlap(char **a, char **b) {
char **i;
@@ -644,8 +710,12 @@ char **strv_sort(char **l) {
}
bool strv_equal(char **a, char **b) {
if (!a || !b)
return a == b;
if (strv_isempty(a))
return strv_isempty(b);
if (strv_isempty(b))
return false;
for ( ; *a || *b; ++a, ++b)
if (!streq_ptr(*a, *b))
+2 -1
View File
@@ -40,7 +40,7 @@ void strv_clear(char **l);
char **strv_copy(char * const *l);
unsigned strv_length(char * const *l) _pure_;
int strv_extend_strv(char ***a, char **b);
int strv_extend_strv(char ***a, char **b, bool filter_duplicates);
int strv_extend_strv_concat(char ***a, char **b, const char *suffix);
int strv_extend(char ***l, const char *value);
int strv_extendf(char ***l, const char *format, ...) _printf_(2,0);
@@ -80,6 +80,7 @@ char *strv_join_quoted(char **l);
char **strv_parse_nulstr(const char *s, size_t l);
char **strv_split_nulstr(const char *s);
int strv_make_nulstr(char **l, char **p, size_t *n);
bool strv_overlap(char **a, char **b) _pure_;