mirror of
https://github.com/tmux/tmux.git
synced 2026-10-16 08:24:23 +00:00
Give the server its own session keyring on Linux
The server otherwise keeps the session keyring of the login session that started it, which pam_keyinit(8) may revoke when that session ends, leaving the server and its panes unable to use the kernel keyring. Join a new session keyring with the user keyring linked in once the configuration file has been loaded, and revoke it when the server exits. This is controlled by a new session-keyring server option, on by default.
This commit is contained in:
42
compat/keyring-linux.c
Normal file
42
compat/keyring-linux.c
Normal file
@@ -0,0 +1,42 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#include <linux/keyctl.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "tmux.h"
|
||||
|
||||
/* Serial of the session keyring we joined, or 0 if none. */
|
||||
static long keyring_serial;
|
||||
|
||||
/*
|
||||
* Create a new session keyring since the current one belongs to the login
|
||||
* session which we're meant to outlive (and pam_keyinit(8) is likely to revoke
|
||||
* the login session's keyring when it ends).
|
||||
*/
|
||||
void
|
||||
keyring_join(void)
|
||||
{
|
||||
long serial;
|
||||
|
||||
serial = syscall(SYS_keyctl, KEYCTL_JOIN_SESSION_KEYRING, NULL);
|
||||
if (serial == -1) {
|
||||
log_debug("%s: join failed: %s", __func__, strerror(errno));
|
||||
return;
|
||||
}
|
||||
if (syscall(SYS_keyctl, KEYCTL_LINK, KEY_SPEC_USER_KEYRING,
|
||||
KEY_SPEC_SESSION_KEYRING) == -1)
|
||||
log_debug("%s: link failed: %s", __func__, strerror(errno));
|
||||
keyring_serial = serial;
|
||||
}
|
||||
|
||||
void
|
||||
keyring_revoke(void)
|
||||
{
|
||||
if (keyring_serial == 0)
|
||||
return;
|
||||
if (syscall(SYS_keyctl, KEYCTL_REVOKE, keyring_serial) == -1)
|
||||
log_debug("%s: revoke failed: %s", __func__, strerror(errno));
|
||||
}
|
||||
Reference in New Issue
Block a user