- Have the pam module tell the daemon to init the login keyring without

using the socket as selinux limits access to that
This commit is contained in:
Alexander Larsson 2007-10-05 09:12:19 +00:00
parent 9c64b5b498
commit c9093190f4
2 changed files with 298 additions and 1 deletions

View File

@ -0,0 +1,291 @@
diff -ur gnome-keyring-2.20.orig/daemon/gkr-daemon.c gnome-keyring-2.20/daemon/gkr-daemon.c
--- gnome-keyring-2.20.orig/daemon/gkr-daemon.c 2007-10-05 12:40:28.000000000 +0200
+++ gnome-keyring-2.20/daemon/gkr-daemon.c 2007-10-05 12:55:26.000000000 +0200
@@ -27,6 +27,7 @@
#include "common/gkr-async.h"
#include "common/gkr-cleanup.h"
#include "common/gkr-unix-signal.h"
+#include "common/gkr-location.h"
#include "keyrings/gkr-keyrings.h"
@@ -183,6 +184,10 @@
GIOChannel *channel;
GMainContext *ctx;
int i;
+ gboolean login;
+ char *login_password;
+ int len;
+ GkrKeyring *login_keyring;
g_type_init ();
g_thread_init (NULL);
@@ -211,6 +216,7 @@
foreground = FALSE;
daemon = FALSE;
+ login = FALSE;
if (argc > 1) {
for (i = 1; i < argc; i++) {
@@ -218,8 +224,19 @@
foreground = TRUE;
if (strcmp (argv[i], "-d") == 0)
daemon = TRUE;
+ if (strcmp (argv[i], "--login") == 0)
+ login = TRUE;
}
}
+
+ login_password = NULL;
+ if (login) {
+ login_password = gnome_keyring_memory_alloc (256);
+ fgets (login_password, 256, stdin);
+ len = strlen (login_password);
+ if (login_password[len-1] == '\n')
+ login_password[len-1] = 0;
+ }
if (!foreground) {
pid = fork ();
@@ -315,6 +332,27 @@
gkr_daemon_dbus_setup (loop, path);
#endif
+
+ if (login_password) {
+ login_keyring = gkr_keyrings_get_login ();
+ if (login_keyring) {
+ if (!gkr_keyring_unlock (login_keyring,
+ login_password)) {
+ g_warning ("Failed to unlock login keyring");
+ }
+ } else {
+ login_keyring =
+ gkr_keyring_create (GKR_LOCATION_BASE_LOCAL,
+ "login",
+ login_password);
+ if (login_keyring) {
+ gkr_keyrings_add (login_keyring);
+ g_object_unref (login_keyring);
+ }
+ }
+ gnome_keyring_memory_free (login_password);
+ }
+
g_main_loop_run (loop);
/* Make sure no other threads are running */
diff -ur gnome-keyring-2.20.orig/pam/gkr-pam-module.c gnome-keyring-2.20/pam/gkr-pam-module.c
--- gnome-keyring-2.20.orig/pam/gkr-pam-module.c 2007-10-05 12:40:28.000000000 +0200
+++ gnome-keyring-2.20/pam/gkr-pam-module.c 2007-10-05 12:42:05.000000000 +0200
@@ -249,15 +249,20 @@
}
static void
-setup_child (int outp[2], int errp[2], struct passwd *pwd)
+setup_child (int inp[2], int outp[2], int errp[2], struct passwd *pwd, const char *password)
{
- char *args[] = { GNOME_KEYRING_DAEMON, "-d", NULL};
-
+ char *args[] = { GNOME_KEYRING_DAEMON, "-d", "--login", NULL};
+
assert (pwd);
assert (pwd->pw_dir);
-
+
+ /* If no password, don't pas in --login */
+ if (password == NULL)
+ args[2] = NULL;
+
/* Fix up our end of the pipes */
- if (dup2 (outp[WRITE_END], STDOUT) < 0 ||
+ if (dup2 (inp[READ_END], STDIN) < 0 ||
+ dup2 (outp[WRITE_END], STDOUT) < 0 ||
dup2 (errp[WRITE_END], STDERR) < 0) {
syslog (GKR_LOG_ERR, "gkr-pam: couldn't setup pipes: %s",
strerror (errno));
@@ -265,6 +270,8 @@
}
/* Close unnecessary file descriptors */
+ close (inp[READ_END]);
+ close (inp[WRITE_END]);
close (outp[READ_END]);
close (outp[WRITE_END]);
close (errp[READ_END]);
@@ -348,9 +355,10 @@
}
static int
-start_daemon (pam_handle_t *ph, struct passwd *pwd)
+start_daemon (pam_handle_t *ph, struct passwd *pwd, const char *password)
{
struct sigaction defsact, oldsact;
+ int inp[2] = { -1, -1 };
int outp[2] = { -1, -1 };
int errp[2] = { -1, -1 };
int ret = PAM_SERVICE_ERR;
@@ -372,7 +380,7 @@
sigaction (SIGCHLD, &defsact, &oldsact);
/* Create the necessary pipes */
- if (pipe (outp) < 0 || pipe (errp) < 0) {
+ if (pipe (inp) < 0 || pipe (outp) < 0 || pipe (errp) < 0) {
syslog (GKR_LOG_ERR, "gkr-pam: couldn't create pipes: %s",
strerror (errno));
goto done;
@@ -387,7 +395,7 @@
/* This is the child */
case 0:
- setup_child (outp, errp, pwd);
+ setup_child (inp, outp, errp, pwd, password);
/* Should never be reached */
break;
@@ -397,9 +405,16 @@
};
/* Close our unneeded ends of the pipes */
+ close (inp[READ_END]);
close (outp[WRITE_END]);
close (errp[WRITE_END]);
- outp[WRITE_END] = errp[WRITE_END] = -1;
+ inp[READ_END] = outp[WRITE_END] = errp[WRITE_END] = -1;
+
+ if (password) {
+ /* Write the login keyring password */
+ write (inp[WRITE_END], password, strlen (password));
+ write (inp[WRITE_END], "\n", 1);
+ }
/*
* Note that we're not using select() or any such. We know how the
@@ -438,6 +453,8 @@
/* Restore old handler */
sigaction (SIGCHLD, &oldsact, NULL);
+ close_safe (inp[0]);
+ close_safe (inp[1]);
close_safe (outp[0]);
close_safe (outp[1]);
close_safe (errp[0]);
@@ -450,7 +467,7 @@
}
static int
-start_daemon_if_necessary (pam_handle_t *ph, struct passwd *pwd)
+start_daemon_if_necessary (pam_handle_t *ph, struct passwd *pwd, const char *password)
{
const char *socket;
int ret;
@@ -470,7 +487,7 @@
}
/* Not running, start process */
- return start_daemon (ph, pwd);
+ return start_daemon (ph, pwd, password);
}
static int
@@ -691,6 +708,7 @@
struct passwd *pwd;
const char *user, *password;
const char *socket;
+ int started_daemon;
uint args;
int ret;
@@ -728,9 +746,11 @@
}
+ started_daemon = 0;
/* Should we start the daemon? */
if (args & ARG_AUTO_START) {
- ret = start_daemon_if_necessary (ph, pwd);
+ started_daemon = 1;
+ ret = start_daemon_if_necessary (ph, pwd, password);
if (ret != PAM_SUCCESS)
return ret;
}
@@ -739,10 +759,12 @@
/* If gnome keyring is running, then unlock now */
if (socket) {
- ret = unlock_keyring (ph, pwd, password);
- if (ret != PAM_SUCCESS)
- return ret;
-
+ /* If we started the daemon, its already unlocked, since we passed the password */
+ if (!started_daemon) {
+ ret = unlock_keyring (ph, pwd, password);
+ if (ret != PAM_SUCCESS)
+ return ret;
+ }
/* Otherwise start in open session, store password */
} else {
if (pam_set_data (ph, "gkr_system_authtok", strdup (password),
@@ -762,6 +784,7 @@
struct passwd *pwd;
int ret;
uint args = parse_args (argc, argv);
+ int started_daemon;
/* Figure out the user name */
ret = pam_get_user (ph, &user, NULL);
@@ -777,29 +800,32 @@
return PAM_SERVICE_ERR;
}
- /* Should we start the daemon? */
- if (args & ARG_AUTO_START) {
- ret = start_daemon_if_necessary (ph, pwd);
- if (ret != PAM_SUCCESS)
- return ret;
- }
-
/* Get the stored authtok here */
if (pam_get_data (ph, "gkr_system_authtok", (const void**)&password) != PAM_SUCCESS) {
-
/*
* No password, no worries, maybe this (PAM using) application
* didn't do authentication, or is hopeless and wants to call
* different PAM callbacks from different processes.
*
* No use complaining
- */
- return PAM_SUCCESS;
+ */
+ password = NULL;
}
- if (unlock_keyring (ph, pwd, password) != PAM_SUCCESS)
- return PAM_SERVICE_ERR;
+ started_daemon = 0;
+ /* Should we start the daemon? */
+ if (args & ARG_AUTO_START) {
+ started_daemon = 1;
+ ret = start_daemon_if_necessary (ph, pwd, password);
+ if (ret != PAM_SUCCESS)
+ return ret;
+ }
+ if (!started_daemon && password != NULL) {
+ if (unlock_keyring (ph, pwd, password) != PAM_SUCCESS)
+ return PAM_SERVICE_ERR;
+ }
+
return PAM_SUCCESS;
}
@@ -897,7 +923,7 @@
* argument. Because if the password is being changed, then making
* the 'login' keyring match it is a priority.
*/
- ret = start_daemon_if_necessary (ph, pwd);
+ ret = start_daemon_if_necessary (ph, pwd, password);
if (ret != PAM_SUCCESS)
return ret;

View File

@ -3,7 +3,7 @@
Summary: A framework for managing user passwords and other secrets Summary: A framework for managing user passwords and other secrets
Name: gnome-keyring Name: gnome-keyring
Version: 2.20 Version: 2.20
Release: 3%{?dist} Release: 4%{?dist}
License: GPLv2+ and LGPLv2+ License: GPLv2+ and LGPLv2+
Group: System Environment/Libraries Group: System Environment/Libraries
Source: http://download.gnome.org/sources/gnome-keyring/2.20/gnome-keyring-%{version}.tar.bz2 Source: http://download.gnome.org/sources/gnome-keyring/2.20/gnome-keyring-%{version}.tar.bz2
@ -23,6 +23,7 @@ BuildRequires: perl(XML::Parser)
Patch1: gnome-keyring-2.20-add_new_keyrings.patch Patch1: gnome-keyring-2.20-add_new_keyrings.patch
Patch2: gnome-keyring-2.20-no-unset-default.patch Patch2: gnome-keyring-2.20-no-unset-default.patch
Patch3: gnome-keyring-2.20-no_match.patch Patch3: gnome-keyring-2.20-no_match.patch
Patch4: gnome-keyring-2.20-selinux-pam.patch
%description %description
gnome-keyring manages passwords and other types of secrets gnome-keyring manages passwords and other types of secrets
@ -65,6 +66,7 @@ and start the keyring daemon.
%patch1 -p0 -b .add_new_keyrings %patch1 -p0 -b .add_new_keyrings
%patch2 -p1 -b .no_unset_default %patch2 -p1 -b .no_unset_default
%patch3 -p0 -b .no_match %patch3 -p0 -b .no_match
%patch4 -p1 -b .selinux_pam
%build %build
aclocal aclocal
@ -111,6 +113,10 @@ rm -rf $RPM_BUILD_ROOT
%changelog %changelog
* Thu Oct 4 2007 Alexander Larsson <alexl@redhat.com> - 2.20-4
- Have the pam module tell the daemon to init the login keyring
without using the socket as selinux limits access to that
* Thu Oct 4 2007 Alexander Larsson <alexl@redhat.com> - 2.20-3 * Thu Oct 4 2007 Alexander Larsson <alexl@redhat.com> - 2.20-3
- Add NO_MATCH error patch from svn. Will fix apps that - Add NO_MATCH error patch from svn. Will fix apps that
can't handle empty list matches can't handle empty list matches