Commit 2933600b authored by Stefan Walter's avatar Stefan Walter

Moved agent into seahorse-daemon process.

    * HACKING:
    * Makefile.am:
    * configure.in:
    * agent/eggtrayicon.* (removed):
    * agent/seahorse-agent-io.c:
    * agent/seahorse-agent.c:
    * agent/seahorse-agent.h:
    * daemon/Makefile.am:
    * daemon/seahorse-daemon.c:
    * daemon/seahorse-daemon.h:
    * libseahorse/Makefile.am:
    * libseahorse/eggtrayicon.c:
    * libseahorse/eggtrayicon.h:
    * libseahorse/seahorse-prefs-cache.c:
    * libseahorse/seahorse-prefs.glade: Moved agent into seahorse-daemon
    process.
parent c5ab7114
2005-05-19 Nate Nielsen <nielsen@memberwebs.com>
* Merge seahorse-0-8 changes into HEAD
* HACKING:
* Makefile.am:
* configure.in:
* agent/eggtrayicon.* (removed):
* agent/seahorse-agent-io.c:
* agent/seahorse-agent.c:
* agent/seahorse-agent.h:
* daemon/Makefile.am:
* daemon/seahorse-daemon.c:
* daemon/seahorse-daemon.h:
* libseahorse/Makefile.am:
* libseahorse/eggtrayicon.c:
* libseahorse/eggtrayicon.h:
* libseahorse/seahorse-prefs-cache.c:
* libseahorse/seahorse-prefs.glade: Moved agent into seahorse-daemon
process.
2005-05-18 Nate Nielsen <nielsen@memberwebs.com>
......
......@@ -6,12 +6,16 @@ with possibe enhancements and any current bugs.
Here is a description of the modules:
o agent: GPG Password caching agent
o agent: GPG Password caching agent. This is compiled into seahorse-daemon.
(See 'daemon' below)
o bonobo: Bonobo servers. Currently there is the only the Nautilus Context Menu
server. Bonobo is being phased out of usage, and as such nothing new should
probably go in here.
o daemon: Various background servers and processes run in this daemon including
the gpg agent, dbus server, etc...
o data: Data files that need to be processed. Current this is just schemas. They
are here because there will be multiple schemas files to separate the app and
pgp settings.
......
......@@ -12,7 +12,16 @@ else
NAUTILUS_DIR =
endif
SUBDIRS = libseahorse src po data help pixmaps plugins $(AGENT_DIR) $(NAUTILUS_DIR)
SUBDIRS = libseahorse \
src \
po \
data \
help \
pixmaps \
plugins \
$(NAUTILUS_DIR) \
$(AGENT_DIR) \
daemon
EXTRA_DIST = \
AUTHORS \
......
......@@ -5,3 +5,4 @@ Makefile
seahorse-agent
*.gladep
*.o
*.a
......@@ -6,24 +6,20 @@ pixmapsdir = $(datadir)/pixmaps/
INCLUDES = -I$(top_builddir) \
-I$(top_srcdir) \
-I$(top_srcdir)/libseahorse \
-I$(top_srcdir)/daemon \
$(SEAHORSE_CFLAGS) \
-DDATA_DIR=\""$(datadir)"\" \
-DSEAHORSE_GLADEDIR=\""$(gladedir)"\" \
-DLOCALEDIR=\""$(localedir)"\" \
-DPIXMAPSDIR=\""$(pixmapsdir)"\"
bin_PROGRAMS = seahorse-agent
noinst_LIBRARIES = libseahorseagent.a
seahorse_agent_SOURCES = seahorse-agent.c seahorse-agent.h seahorse-agent-actions.c \
seahorse-agent-cache.c seahorse-agent-prompt.c seahorse-agent-io.c \
gtk-secure-entry.c gtk-secure-entry.h seahorse-agent-secmem.h \
seahorse-agent-secmem.c seahorse-agent-status.c \
eggtrayicon.h eggtrayicon.c
libseahorseagent_a_SOURCES = seahorse-agent.c seahorse-agent.h seahorse-agent-actions.c \
seahorse-agent-cache.c seahorse-agent-prompt.c seahorse-agent-io.c \
gtk-secure-entry.c gtk-secure-entry.h seahorse-agent-secmem.h \
seahorse-agent-secmem.c seahorse-agent-status.c
seahorse_agent_LDADD = \
$(top_builddir)/libseahorse/libseahorse-internal.la \
$(SEAHORSE_LIBS)
glade_DATA = \
seahorse-agent-cache.glade
......@@ -32,6 +28,3 @@ EXTRA_DIST = \
CLEANFILES = *.gladep* *.bak \
$(desktop_DATA)
install-exec-hook:
chmod u+s $(bindir)/seahorse-agent
/*
* Seahorse
*
* Copyright (C) 2004 Nate Nielsen
* Copyright (C) 2004-2005 Nate Nielsen
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -83,12 +83,11 @@ struct _SeahorseAgentConn {
#define ASS_ERR "ERR "
#define NL "\n"
/* -----------------------------------------------------------------------------
*/
/* -------------------------------------------------------------------------- */
/* Create the socket and fill in sockname with its path */
int
seahorse_agent_io_socket (const char **socketname)
seahorse_agent_io_socket ()
{
struct sockaddr_un addr;
gchar *t;
......@@ -141,12 +140,15 @@ seahorse_agent_io_socket (const char **socketname)
if (chmod(g_socket_name, 0600) == -1)
g_warning ("couldn't set permissions on socket: %s", strerror (errno));
if (socketname)
*socketname = g_socket_name;
return 0;
}
const gchar*
seahorse_agent_io_get_socket ()
{
return g_socket_name;
}
/* Free the given connection structure */
static void
free_conn (SeahorseAgentConn *cn)
......@@ -588,5 +590,5 @@ seahorse_agent_io_uninit ()
}
g_socket_name[0] = 0;
}
}
}
......@@ -34,17 +34,12 @@
#include "config.h"
#include "seahorse-agent.h"
#include "seahorse-agent-secmem.h"
#include "seahorse-gpg-options.h"
/* -----------------------------------------------------------------------------
* GLOBALS
*/
gboolean seahorse_agent_displayvars = FALSE;
gboolean seahorse_agent_cshell = FALSE;
gboolean g_daemonize = TRUE;
gboolean g_displayvars = FALSE;
gboolean g_cshell = FALSE;
gboolean g_quit = FALSE;
/* PUBLISHING AGENT INFO ---------------------------------------------------- */
/* The GPG settings we modify */
static const gchar *confs[4] = {
......@@ -57,56 +52,31 @@ static const gchar *confs[4] = {
/* Previous gpg.conf settings */
static gchar *prev_values[4];
static const struct poptOption options[] = {
{ "cshell", 'c', POPT_ARG_NONE | POPT_ARG_VAL, &g_cshell, TRUE,
N_("Print variables in for a C type shell"), NULL },
{ "no-daemonize", 'd', POPT_ARG_NONE | POPT_ARG_VAL, &g_daemonize, FALSE,
N_("Do not daemonize seahorse-agent"), NULL },
{ "variables", 'v', POPT_ARG_NONE | POPT_ARG_VAL, &g_displayvars, TRUE,
N_("Display variables instead of editing gpg.conf"), NULL },
POPT_AUTOHELP
POPT_TABLEEND
};
/* -----------------------------------------------------------------------------
*/
/* Print out the socket name info: <name>:<pid>:<protocol_version> */
static void
process_display (const char *sockname, pid_t pid)
process_display (const gchar *socket, pid_t pid)
{
if (g_cshell) {
if (seahorse_agent_cshell) {
fprintf (stdout, "setenv GPG_AGENT_INFO %s:%lu:1",
sockname, (long unsigned int) pid);
socket, (long unsigned int) pid);
} else {
fprintf (stdout, "GPG_AGENT_INFO=%s:%lu:1; export GPG_AGENT_INFO",
sockname, (long unsigned int) pid);
socket, (long unsigned int) pid);
}
fflush (stdout);
}
/* Remove our agent info from gpg.conf */
static void
unprocess_gpg_conf ()
{
seahorse_gpg_options_change_vals (confs, prev_values, NULL);
}
/* Add our agent info to gpg.conf */
static void
process_gpg_conf (const char *sockname, pid_t pid)
process_gpg_conf (const gchar *socket, pid_t pid)
{
GError *error = NULL;
gchar *agent_info;
gchar *values[4];
gboolean b;
g_assert (sockname && sockname[0]);
g_assert (socket && socket[0]);
memset (prev_values, 0, sizeof (prev_values));
/* Read in the current values for the options */
......@@ -122,7 +92,7 @@ process_gpg_conf (const char *sockname, pid_t pid)
prev_values[3] = NULL; /* null terminate */
}
agent_info = g_strdup_printf ("%s:%lu:1", sockname, (unsigned long) pid);
agent_info = g_strdup_printf ("%s:%lu:1", socket, (unsigned long) pid);
values[0] = agent_info; /* gpg-agent-info */
values[1] = ""; /* use-agent */
......@@ -141,187 +111,52 @@ process_gpg_conf (const char *sockname, pid_t pid)
}
}
/* Remove our agent info from gpg.conf */
static void
daemonize (const char *sockname)
{
/*
* We can't use the normal daemon call, because we have
* special things to do in the parent after forking
*/
pid_t pid;
int i;
if (g_daemonize) {
switch ((pid = fork ())) {
case -1:
err (1, _("couldn't fork process"));
break;
/* The child */
case 0:
if (setsid () == -1)
err (1, _("couldn't create new process group"));
/* Close std descriptors */
for (i = 0; i <= 2; i++)
close (i);
/* Open stdin, stdout and stderr. GPGME doesn't work without this */
open ("/dev/null", O_RDONLY, 0666);
open ("/dev/null", O_WRONLY, 0666);
open ("/dev/null", O_WRONLY, 0666);
chdir ("/tmp");
return;
};
}
/* Not daemonizing */
else {
pid = getpid ();
}
/* The parent, or not daemonized */
if (g_displayvars)
process_display (sockname, pid);
else
process_gpg_conf (sockname, pid);
if (g_daemonize)
exit (0);
}
static void
on_quit (int signal)
unprocess_gpg_conf ()
{
g_quit = 1;
seahorse_gpg_options_change_vals (confs, prev_values, NULL);
}
static gboolean
check_quit (gpointer data)
void
seahorse_agent_prefork ()
{
if (g_quit) {
gtk_main_quit ();
return FALSE;
}
return TRUE;
if (seahorse_agent_io_socket () == -1)
_exit (1); /* Message already printed */
}
static void
log_handler (const gchar *log_domain, GLogLevelFlags log_level,
const gchar *message, gpointer user_data)
void
seahorse_agent_postfork (pid_t child)
{
int level;
/* Note that crit and err are the other way around in syslog */
switch (G_LOG_LEVEL_MASK & log_level) {
case G_LOG_LEVEL_ERROR:
level = LOG_CRIT;
break;
case G_LOG_LEVEL_CRITICAL:
level = LOG_ERR;
break;
case G_LOG_LEVEL_WARNING:
level = LOG_WARNING;
break;
case G_LOG_LEVEL_MESSAGE:
level = LOG_NOTICE;
break;
case G_LOG_LEVEL_INFO:
level = LOG_INFO;
break;
case G_LOG_LEVEL_DEBUG:
level = LOG_DEBUG;
break;
default:
level = LOG_ERR;
break;
}
const gchar *socket = seahorse_agent_io_get_socket ();
g_return_if_fail (socket != NULL);
/* Log to syslog first */
if(log_domain)
syslog (level, "%s: %s", log_domain, message);
/* If any of these fail, they simply exit */
if (seahorse_agent_displayvars)
process_display (socket, child);
else
syslog (level, "%s", message);
/* And then to default handler for aborting and stuff like that */
g_log_default_handler (log_domain, log_level, message, user_data);
}
static void
prepare_logging ()
{
GLogLevelFlags flags = G_LOG_FLAG_FATAL | G_LOG_LEVEL_ERROR |
G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING |
G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO;
openlog ("seahorse-agent", LOG_PID, LOG_AUTH);
g_log_set_handler (NULL, flags, log_handler, NULL);
g_log_set_handler ("Glib", flags, log_handler, NULL);
g_log_set_handler ("Gtk", flags, log_handler, NULL);
g_log_set_handler ("Gnome", flags, log_handler, NULL);
process_gpg_conf (socket, child);
}
int
main (int argc, char **argv)
seahorse_agent_init ()
{
const char *sockname;
GnomeProgram *program = NULL;
secmem_init (65536);
/* We need to drop privileges completely for security */
#if defined(HAVE_SETRESUID) && defined(HAVE_SETRESGID)
/* Not in header files for all OSs, even where present */
int setresuid(uid_t ruid, uid_t euid, uid_t suid);
int setresgid(gid_t rgid, gid_t egid, gid_t sgid);
if (setresuid (getuid (), getuid (), getuid ()) == -1 ||
setresgid (getgid (), getgid (), getgid ()) == -1)
#else
if (setuid (getuid ()) == -1 || setgid (getgid ()) == -1)
#endif
err (1, _("couldn't drop privileges properly"));
program = gnome_program_init(PACKAGE, VERSION, LIBGNOMEUI_MODULE, argc, argv,
GNOME_PARAM_POPT_TABLE, options,
GNOME_PARAM_HUMAN_READABLE_NAME, _("Encryption Passphrase Agent"),
GNOME_PARAM_APP_DATADIR, DATA_DIR, NULL);
if (seahorse_agent_io_socket (&sockname) == -1)
return 1; /* message already printed */
/*
* All functions after this point have to print messages
* nicely and not just called exit()
*/
daemonize (sockname);
/* Handle some signals */
signal (SIGINT, on_quit);
signal (SIGTERM, on_quit);
g_timeout_add (100, check_quit, NULL);
if (seahorse_agent_io_init () == -1)
return -1; /* message already printed */
/* We log to the syslog */
prepare_logging ();
/* Initialize our sub systems */
seahorse_agent_actions_init ();
seahorse_agent_cache_init ();
return 0;
}
if (seahorse_agent_io_init () == -1)
return 1; /* message already printed */
gtk_main ();
if (!g_displayvars)
void
seahorse_agent_uninit ()
{
if (!seahorse_agent_displayvars)
unprocess_gpg_conf ();
/* If any windows are open this closes them */
seahorse_agent_prompt_cleanup ();
seahorse_agent_status_cleanup ();
......@@ -330,6 +165,4 @@ main (int argc, char **argv)
seahorse_agent_cache_uninit ();
seahorse_agent_actions_uninit ();
seahorse_agent_io_uninit ();
return 0;
}
......@@ -39,6 +39,22 @@
#define SETTING_EXPIRE "/apps/seahorse/agent/cache_expire"
#define SETTING_TTL "/apps/seahorse/agent/cache_ttl"
/* -----------------------------------------------------------------------------
* seahorse-agent.c
*/
/* Called from the original process before and after fork */
void seahorse_agent_prefork ();
void seahorse_agent_postfork (pid_t child);
/* Called in the new child process */
int seahorse_agent_init ();
void seahorse_agent_uninit ();
/* Global options to set from the command line */
extern gboolean seahorse_agent_displayvars;
extern gboolean seahorse_agent_cshell;
/* -----------------------------------------------------------------------------
* seahorse-agent-io.c
*/
......@@ -46,7 +62,8 @@
struct _SeahorseAgentConn;
typedef struct _SeahorseAgentConn SeahorseAgentConn;
int seahorse_agent_io_socket (const char **socketname);
int seahorse_agent_io_socket ();
const gchar* seahorse_agent_io_get_socket ();
int seahorse_agent_io_init ();
void seahorse_agent_io_uninit ();
void seahorse_agent_io_reply (SeahorseAgentConn *rq, gboolean ok, const gchar *response);
......
......@@ -366,6 +366,7 @@ data/Makefile
pixmaps/Makefile
src/Makefile
agent/Makefile
daemon/Makefile
plugins/Makefile
plugins/nautilus/Makefile
plugins/nautilus-ext/Makefile
......
Makefile.in
Makefile
*.o
*.a
*.la
*.lo
seahorse-daemon
gladedir = $(datadir)/seahorse/glade/
localedir = $(datadir)/locale
pixmapsdir = $(datadir)/pixmaps/
INCLUDES = -I$(top_builddir) \
-I$(top_srcdir) \
-I$(top_srcdir)/libseahorse \
-I$(top_srcdir)/agent \
$(SEAHORSE_CFLAGS) \
-DDATA_DIR=\""$(datadir)"\" \
-DSEAHORSE_GLADEDIR=\""$(gladedir)"\" \
-DLOCALEDIR=\""$(localedir)"\" \
-DPIXMAPSDIR=\""$(pixmapsdir)"\"
bin_PROGRAMS = seahorse-daemon
seahorse_daemon_SOURCES = \
seahorse-daemon.c \
seahorse-daemon.h
seahorse_daemon_LDADD = \
$(top_builddir)/agent/libseahorseagent.a \
$(top_builddir)/libseahorse/libseahorse-internal.la \
$(SEAHORSE_LIBS)
glade_DATA =
EXTRA_DIST = \
$(glade_DATA)
CLEANFILES = *.gladep* *.bak
install-exec-hook:
chmod u+s $(bindir)/seahorse-daemon
/*
* Seahorse
*
* Copyright (C) 2005 Nate Nielsen
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <sys/types.h>
#include <sys/signal.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <err.h>
#include <unistd.h>
#include <syslog.h>
#include <fcntl.h>
#include <gnome.h>
#include "config.h"
#include "seahorse-daemon.h"
#ifdef WITH_AGENT
#include "seahorse-agent.h"
#include "seahorse-agent-secmem.h"
#endif
static gboolean g_daemonize = TRUE;
static gboolean g_quit = FALSE;
static const struct poptOption options[] = {
{ "no-daemonize", 'd', POPT_ARG_NONE | POPT_ARG_VAL, &g_daemonize, FALSE,
N_("Do not daemonize seahorse-agent"), NULL },
#ifdef WITH_AGENT
{ "cshell", 'c', POPT_ARG_NONE | POPT_ARG_VAL, &seahorse_agent_cshell, TRUE,
N_("Print variables in for a C type shell"), NULL },
{ "variables", 'v', POPT_ARG_NONE | POPT_ARG_VAL, &seahorse_agent_displayvars, TRUE,
N_("Display variables instead of editing gpg.conf"), NULL },
#endif
POPT_AUTOHELP
POPT_TABLEEND
};
static void
daemonize ()
{
/*
* We can't use the normal daemon call, because we have
* special things to do in the parent after forking
*/
pid_t pid;
int i;
if (g_daemonize) {
switch ((pid = fork ())) {
case -1:
err (1, _("couldn't fork process"));
break;
/* The child */
case 0:
if (setsid () == -1)
err (1, _("couldn't create new process group"));
/* Close std descriptors */
for (i = 0; i <= 2; i++)
close (i);
/* Open stdin, stdout and stderr. GPGME doesn't work without this */
open ("/dev/null", O_RDONLY, 0666);
open ("/dev/null", O_WRONLY, 0666);
open ("/dev/null", O_WRONLY, 0666);
chdir ("/tmp");
return;
};
}
/* Not daemonizing */
else {
pid = getpid ();
}
#ifdef WITH_AGENT
/* Let the agent do it's thing */
seahorse_agent_postfork (pid);
#endif
/* The parent, or not daemonized */
if (g_daemonize)
exit (0);
}
static void
on_quit (int signal)
{
g_quit = 1;
}
static gboolean
check_quit (gpointer data)
{
if (g_quit) {
gtk_main_quit ();
return FALSE;
}
return TRUE;
}
static void
log_handler (const gchar *log_domain, GLogLevelFlags log_level,
const gchar *message, gpointer user_data)
{
int level;
/* Note that crit and err are the other way around in syslog */
switch (G_LOG_LEVEL_MASK & log_level) {
case G_LOG_LEVEL_ERROR:
level = LOG_CRIT;
break;
case G_LOG_LEVEL_CRITICAL:
level = LOG_ERR;
break;
case G_LOG_LEVEL_WARNING:
level = LOG_WARNING;
break;
case G_LOG_LEVEL_MESSAGE:
level = LOG_NOTICE;
break;
case G_LOG_LEVEL_INFO:
level = LOG_INFO;
break;
case G_LOG_LEVEL_DEBUG:
level = LOG_DEBUG;
break;
default:
level = LOG_ERR;
break;
}
/* Log to syslog first */
if (log_domain)
syslog (level, "%s: %s", log_domain, message);
else
syslog (level, "%s", message);
/* And then to default handler for aborting and stuff like that */
g_log_default_handler (log_domain, log_level, message, user_data);
}
static void
prepare_logging ()
{
GLogLevelFlags flags = G_LOG_FLAG_FATAL | G_LOG_LEVEL_ERROR |
G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING |
G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO;
openlog ("seahorse-daemon", LOG_PID, LOG_AUTH);
g_log_set_handler (NULL, flags, log_handler, NULL);
g_log_set_handler ("Glib", flags, log_handler, NULL);
g_log_set_handler ("Gtk", flags, log_handler, NULL);
g_log_set_handler ("Gnome", flags, log_handler, NULL);
}
int main(int argc, char* argv[])
{
GnomeProgram *program = NULL;
#ifdef WITH_AGENT
secmem_init (65536);
#endif
/* We need to drop privileges completely for security */
#if defined(HAVE_SETRESUID) && defined(HAVE_SETRESGID)
/* Not in header files for all OSs, even where present */
int setresuid(uid_t ruid, uid_t euid, uid_t suid);
int setresgid(gid_t rgid, gid_t egid, gid_t sgid);
if (setresuid (getuid (), getuid (), getuid ()) == -1 ||
setresgid (getgid (), getgid (), getgid ()) == -1)
#else