2008-01-08 17:02:31 +00:00
|
|
|
diff -upr gnome-keyring-2.20.3.orig/daemon/gkr-daemon.c gnome-keyring-2.20.3/daemon/gkr-daemon.c
|
|
|
|
--- gnome-keyring-2.20.3.orig/daemon/gkr-daemon.c 2007-11-24 17:33:44.000000000 +0000
|
|
|
|
+++ gnome-keyring-2.20.3/daemon/gkr-daemon.c 2008-01-08 16:59:46.000000000 +0000
|
2007-10-05 09:12:19 +00:00
|
|
|
@@ -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"
|
|
|
|
|
2008-01-08 17:02:31 +00:00
|
|
|
@@ -183,6 +184,10 @@ main (int argc, char *argv[])
|
2007-10-05 09:12:19 +00:00
|
|
|
GIOChannel *channel;
|
|
|
|
GMainContext *ctx;
|
|
|
|
int i;
|
|
|
|
+ gboolean login;
|
|
|
|
+ char *login_password;
|
|
|
|
+ int len;
|
|
|
|
+ GkrKeyring *login_keyring;
|
|
|
|
|
|
|
|
g_type_init ();
|
|
|
|
g_thread_init (NULL);
|
2008-01-08 17:02:31 +00:00
|
|
|
@@ -214,6 +219,7 @@ main (int argc, char *argv[])
|
2007-10-05 09:12:19 +00:00
|
|
|
|
|
|
|
foreground = FALSE;
|
|
|
|
daemon = FALSE;
|
|
|
|
+ login = FALSE;
|
|
|
|
|
|
|
|
if (argc > 1) {
|
|
|
|
for (i = 1; i < argc; i++) {
|
2008-01-08 17:02:31 +00:00
|
|
|
@@ -221,8 +227,19 @@ main (int argc, char *argv[])
|
2007-10-05 09:12:19 +00:00
|
|
|
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 ();
|
2008-01-08 17:02:31 +00:00
|
|
|
@@ -318,6 +335,27 @@ main (int argc, char *argv[])
|
2007-10-05 09:12:19 +00:00
|
|
|
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 */
|
2008-01-08 17:02:31 +00:00
|
|
|
diff -upr gnome-keyring-2.20.3.orig/pam/gkr-pam-module.c gnome-keyring-2.20.3/pam/gkr-pam-module.c
|
|
|
|
--- gnome-keyring-2.20.3.orig/pam/gkr-pam-module.c 2007-11-30 18:50:29.000000000 +0000
|
|
|
|
+++ gnome-keyring-2.20.3/pam/gkr-pam-module.c 2008-01-08 17:00:50.000000000 +0000
|
|
|
|
@@ -249,17 +249,22 @@ cleanup_free_password (pam_handle_t *ph,
|
2007-10-05 09:12:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2008-01-08 17:02:31 +00:00
|
|
|
-setup_child (int outp[2], int errp[2], pam_handle_t *ph, struct passwd *pwd)
|
|
|
|
+setup_child (int inp[2], int outp[2], int errp[2], pam_handle_t *ph, struct passwd *pwd, const char *password)
|
2007-10-05 09:12:19 +00:00
|
|
|
{
|
|
|
|
- char *args[] = { GNOME_KEYRING_DAEMON, "-d", NULL};
|
|
|
|
+ char *args[] = { GNOME_KEYRING_DAEMON, "-d", "--login", NULL};
|
2008-01-08 17:02:31 +00:00
|
|
|
const char* display;
|
|
|
|
int ret;
|
|
|
|
|
2007-10-05 09:12:19 +00:00
|
|
|
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));
|
2008-01-08 17:02:31 +00:00
|
|
|
@@ -267,6 +272,8 @@ setup_child (int outp[2], int errp[2], p
|
2007-10-05 09:12:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Close unnecessary file descriptors */
|
|
|
|
+ close (inp[READ_END]);
|
|
|
|
+ close (inp[WRITE_END]);
|
|
|
|
close (outp[READ_END]);
|
|
|
|
close (outp[WRITE_END]);
|
|
|
|
close (errp[READ_END]);
|
2008-01-08 17:02:31 +00:00
|
|
|
@@ -358,9 +365,10 @@ setup_environment (char *line, void *arg
|
2007-10-05 09:12:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
2008-01-08 17:02:31 +00:00
|
|
|
@@ -382,7 +390,7 @@ start_daemon (pam_handle_t *ph, struct p
|
2007-10-05 09:12:19 +00:00
|
|
|
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;
|
2008-01-08 17:02:31 +00:00
|
|
|
@@ -397,7 +405,7 @@ start_daemon (pam_handle_t *ph, struct p
|
2007-10-05 09:12:19 +00:00
|
|
|
|
|
|
|
/* This is the child */
|
|
|
|
case 0:
|
2008-01-08 17:02:31 +00:00
|
|
|
- setup_child (outp, errp, ph, pwd);
|
|
|
|
+ setup_child (inp, outp, errp, ph, pwd, password);
|
2007-10-05 09:12:19 +00:00
|
|
|
/* Should never be reached */
|
|
|
|
break;
|
|
|
|
|
2008-01-08 17:02:31 +00:00
|
|
|
@@ -407,9 +415,16 @@ start_daemon (pam_handle_t *ph, struct p
|
2007-10-05 09:12:19 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/* 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
|
2008-01-08 17:02:31 +00:00
|
|
|
@@ -448,6 +463,8 @@ done:
|
2007-10-05 09:12:19 +00:00
|
|
|
/* 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]);
|
2008-01-08 17:02:31 +00:00
|
|
|
@@ -460,7 +477,7 @@ done:
|
2007-10-05 09:12:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
2008-01-08 17:02:31 +00:00
|
|
|
@@ -480,7 +497,7 @@ start_daemon_if_necessary (pam_handle_t
|
2007-10-05 09:12:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Not running, start process */
|
|
|
|
- return start_daemon (ph, pwd);
|
|
|
|
+ return start_daemon (ph, pwd, password);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2008-01-08 17:02:31 +00:00
|
|
|
@@ -701,6 +718,7 @@ pam_sm_authenticate (pam_handle_t *ph, i
|
2007-10-05 09:12:19 +00:00
|
|
|
struct passwd *pwd;
|
|
|
|
const char *user, *password;
|
|
|
|
const char *socket;
|
|
|
|
+ int started_daemon;
|
|
|
|
uint args;
|
|
|
|
int ret;
|
|
|
|
|
2008-01-08 17:02:31 +00:00
|
|
|
@@ -738,9 +756,11 @@ pam_sm_authenticate (pam_handle_t *ph, i
|
2007-10-05 09:12:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
+ 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;
|
|
|
|
}
|
2008-01-08 17:02:31 +00:00
|
|
|
@@ -749,10 +769,12 @@ pam_sm_authenticate (pam_handle_t *ph, i
|
2007-10-05 09:12:19 +00:00
|
|
|
|
|
|
|
/* 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),
|
2008-01-08 17:02:31 +00:00
|
|
|
@@ -772,6 +794,7 @@ pam_sm_open_session (pam_handle_t *ph, i
|
2007-10-05 09:12:19 +00:00
|
|
|
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);
|
2008-01-08 17:02:31 +00:00
|
|
|
@@ -787,29 +810,32 @@ pam_sm_open_session (pam_handle_t *ph, i
|
2007-10-05 09:12:19 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2008-01-08 17:02:31 +00:00
|
|
|
@@ -907,7 +933,7 @@ pam_chauthtok_update (pam_handle_t *ph,
|
2007-10-05 09:12:19 +00:00
|
|
|
* 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);
|
2007-10-08 07:30:19 +00:00
|
|
|
+ ret = start_daemon_if_necessary (ph, pwd, original);
|
2007-10-05 09:12:19 +00:00
|
|
|
if (ret != PAM_SUCCESS)
|
|
|
|
return ret;
|
|
|
|
|