From 0c3f127c86af818d260966d2292b199757087157 Mon Sep 17 00:00:00 2001 From: Simon Poirier Date: Sat, 11 Jul 2009 21:39:46 +0000 Subject: repackage --- (limited to 'src/sugar/gsm-xsmp.c') diff --git a/src/sugar/gsm-xsmp.c b/src/sugar/gsm-xsmp.c deleted file mode 100644 index aa9dff1..0000000 --- a/src/sugar/gsm-xsmp.c +++ /dev/null @@ -1,535 +0,0 @@ -/* xsmp.c - * Copyright (C) 2007 Novell, Inc. - * - * 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 - * Lesser 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. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "gsm-client-xsmp.h" -#include "gsm-xsmp.h" - -#include -#include -#include -#include - -#ifdef HAVE_X11_XTRANS_XTRANS_H -/* Get the proto for _IceTransNoListen */ -#define ICE_t -#define TRANS_SERVER -#include -#undef ICE_t -#undef TRANS_SERVER -#endif /* HAVE_X11_XTRANS_XTRANS_H */ - -static IceListenObj *xsmp_sockets; -static int num_xsmp_sockets, num_local_xsmp_sockets; - -static gboolean update_iceauthority (gboolean adding); - -static gboolean accept_ice_connection (GIOChannel *source, - GIOCondition condition, - gpointer data); -static Status accept_xsmp_connection (SmsConn conn, - SmPointer manager_data, - unsigned long *mask_ret, - SmsCallbacks *callbacks_ret, - char **failure_reason_ret); - -static void ice_error_handler (IceConn conn, - Bool swap, - int offending_minor_opcode, - unsigned long offending_sequence_num, - int error_class, - int severity, - IcePointer values); -static void ice_io_error_handler (IceConn conn); -static void sms_error_handler (SmsConn sms_conn, - Bool swap, - int offending_minor_opcode, - unsigned long offending_sequence_num, - int error_class, - int severity, - IcePointer values); -/** - * gsm_xsmp_init: - * - * Initializes XSMP. Notably, it creates the XSMP listening socket and - * sets the SESSION_MANAGER environment variable to point to it. - **/ -char * -gsm_xsmp_init (void) -{ - char error[256]; - mode_t saved_umask; - char *network_id_list; - int i; - - /* Set up sane error handlers */ - IceSetErrorHandler (ice_error_handler); - IceSetIOErrorHandler (ice_io_error_handler); - SmsSetErrorHandler (sms_error_handler); - - /* Initialize libSM; we pass NULL for hostBasedAuthProc to disable - * host-based authentication. - */ - if (!SmsInitialize (PACKAGE, VERSION, accept_xsmp_connection, - NULL, NULL, sizeof (error), error)) - g_error("Could not initialize libSM: %s", error); - -#ifdef HAVE_X11_XTRANS_XTRANS_H - /* By default, IceListenForConnections will open one socket for each - * transport type known to X. We don't want connections from remote - * hosts, so for security reasons it would be best if ICE didn't - * even open any non-local sockets. So we use an internal ICElib - * method to disable them here. Unfortunately, there is no way to - * ask X what transport types it knows about, so we're forced to - * guess. - */ - _IceTransNoListen ("tcp"); -#endif - - /* Create the XSMP socket. Older versions of IceListenForConnections - * have a bug which causes the umask to be set to 0 on certain types - * of failures. Probably not an issue on any modern systems, but - * we'll play it safe. - */ - saved_umask = umask (0); - umask (saved_umask); - if (!IceListenForConnections (&num_xsmp_sockets, &xsmp_sockets, - sizeof (error), error)) - g_error ("Could not create ICE listening socket: %s", error); - umask (saved_umask); - - /* Find the local sockets in the returned socket list and move them - * to the start of the list. - */ - for (i = num_local_xsmp_sockets = 0; i < num_xsmp_sockets; i++) - { - char *id = IceGetListenConnectionString (xsmp_sockets[i]); - - if (!strncmp (id, "local/", sizeof ("local/") - 1) || - !strncmp (id, "unix/", sizeof ("unix/") - 1)) - { - if (i > num_local_xsmp_sockets) - { - IceListenObj tmp = xsmp_sockets[i]; - xsmp_sockets[i] = xsmp_sockets[num_local_xsmp_sockets]; - xsmp_sockets[num_local_xsmp_sockets] = tmp; - } - num_local_xsmp_sockets++; - } - free (id); - } - - if (num_local_xsmp_sockets == 0) - g_error ("IceListenForConnections did not return a local listener!"); - -#ifdef HAVE_X11_XTRANS_XTRANS_H - if (num_local_xsmp_sockets != num_xsmp_sockets) - { - /* Xtrans was apparently compiled with support for some - * non-local transport besides TCP (which we disabled above); we - * won't create IO watches on those extra sockets, so - * connections to them will never be noticed, but they're still - * there, which is inelegant. - * - * If the g_warning below is triggering for you and you want to - * stop it, the fix is to add additional _IceTransNoListen() - * calls above. - */ - network_id_list = - IceComposeNetworkIdList (num_xsmp_sockets - num_local_xsmp_sockets, - xsmp_sockets + num_local_xsmp_sockets); - g_warning ("IceListenForConnections returned %d non-local listeners: %s", - num_xsmp_sockets - num_local_xsmp_sockets, network_id_list); - free (network_id_list); - } -#endif - - /* Update .ICEauthority with new auth entries for our socket */ - if (!update_iceauthority (TRUE)) - { - /* FIXME: is this really fatal? Hm... */ - g_error ("Could not update ICEauthority file %s", - IceAuthFileName ()); - } - - network_id_list = IceComposeNetworkIdList (num_local_xsmp_sockets, - xsmp_sockets); - - return network_id_list; -} - -/** - * gsm_xsmp_run: - * - * Sets the XSMP server to start accepting connections. - **/ -void -gsm_xsmp_run (void) -{ - GIOChannel *channel; - int i; - - for (i = 0; i < num_local_xsmp_sockets; i++) - { - channel = g_io_channel_unix_new (IceGetListenConnectionNumber (xsmp_sockets[i])); - g_io_add_watch (channel, G_IO_IN | G_IO_HUP | G_IO_ERR, - accept_ice_connection, xsmp_sockets[i]); - g_io_channel_unref (channel); - } -} - -/** - * gsm_xsmp_shutdown: - * - * Shuts down the XSMP server and closes the ICE listening socket - **/ -void -gsm_xsmp_shutdown (void) -{ - update_iceauthority (FALSE); - - IceFreeListenObjs (num_xsmp_sockets, xsmp_sockets); - xsmp_sockets = NULL; -} - -/** - * gsm_xsmp_generate_client_id: - * - * Generates a new XSMP client ID. - * - * Return value: an XSMP client ID. - **/ -char * -gsm_xsmp_generate_client_id (void) -{ - static int sequence = -1; - static guint rand1 = 0, rand2 = 0; - static pid_t pid = 0; - struct timeval tv; - - /* The XSMP spec defines the ID as: - * - * Version: "1" - * Address type and address: - * "1" + an IPv4 address as 8 hex digits - * "2" + a DECNET address as 12 hex digits - * "6" + an IPv6 address as 32 hex digits - * Time stamp: milliseconds since UNIX epoch as 13 decimal digits - * Process-ID type and process-ID: - * "1" + POSIX PID as 10 decimal digits - * Sequence number as 4 decimal digits - * - * XSMP client IDs are supposed to be globally unique: if - * SmsGenerateClientID() is unable to determine a network - * address for the machine, it gives up and returns %NULL. - * GNOME and KDE have traditionally used a fourth address - * format in this case: - * "0" + 16 random hex digits - * - * We don't even bother trying SmsGenerateClientID(), since the - * user's IP address is probably "192.168.1.*" anyway, so a random - * number is actually more likely to be globally unique. - */ - - if (!rand1) - { - rand1 = g_random_int (); - rand2 = g_random_int (); - pid = getpid (); - } - - sequence = (sequence + 1) % 10000; - gettimeofday (&tv, NULL); - return g_strdup_printf ("10%.04x%.04x%.10lu%.3u%.10lu%.4d", - rand1, rand2, - (unsigned long) tv.tv_sec, - (unsigned) tv.tv_usec, - (unsigned long) pid, - sequence); -} - -/* This is called (by glib via xsmp->ice_connection_watch) when a - * connection is first received on the ICE listening socket. (We - * expect that the client will then initiate XSMP on the connection; - * if it does not, GsmClientXSMP will eventually time out and close - * the connection.) - * - * FIXME: it would probably make more sense to not create a - * GsmClientXSMP object until accept_xsmp_connection, below (and to do - * the timing-out here in xsmp.c). - */ -static gboolean -accept_ice_connection (GIOChannel *source, - GIOCondition condition, - gpointer data) -{ - IceListenObj listener = data; - IceConn ice_conn; - IceAcceptStatus status; - GsmClientXSMP *client; - - g_debug ("accept_ice_connection()"); - - ice_conn = IceAcceptConnection (listener, &status); - if (status != IceAcceptSuccess) - { - g_debug ("IceAcceptConnection returned %d", status); - return TRUE; - } - - client = gsm_client_xsmp_new (ice_conn); - ice_conn->context = client; - return TRUE; -} - -/* This is called (by libSM) when XSMP is initiated on an ICE - * connection that was already accepted by accept_ice_connection. - */ -static Status -accept_xsmp_connection (SmsConn sms_conn, SmPointer manager_data, - unsigned long *mask_ret, SmsCallbacks *callbacks_ret, - char **failure_reason_ret) -{ - IceConn ice_conn; - GsmClientXSMP *client; - - /* FIXME: what about during shutdown but before gsm_xsmp_shutdown? */ - if (!xsmp_sockets) - { - g_debug ("In shutdown, rejecting new client"); - - *failure_reason_ret = - strdup (_("Refusing new client connection because the session is currently being shut down\n")); - return FALSE; - } - - ice_conn = SmsGetIceConnection (sms_conn); - client = ice_conn->context; - - g_return_val_if_fail (client != NULL, TRUE); - - gsm_client_xsmp_connect (client, sms_conn, mask_ret, callbacks_ret); - return TRUE; -} - -/* ICEauthority stuff */ - -/* Various magic numbers stolen from iceauth.c */ -#define GSM_ICE_AUTH_RETRIES 10 -#define GSM_ICE_AUTH_INTERVAL 2 /* 2 seconds */ -#define GSM_ICE_AUTH_LOCK_TIMEOUT 600 /* 10 minutes */ - -#define GSM_ICE_MAGIC_COOKIE_AUTH_NAME "MIT-MAGIC-COOKIE-1" -#define GSM_ICE_MAGIC_COOKIE_LEN 16 - -static IceAuthFileEntry * -auth_entry_new (const char *protocol, const char *network_id) -{ - IceAuthFileEntry *file_entry; - IceAuthDataEntry data_entry; - - file_entry = malloc (sizeof (IceAuthFileEntry)); - - file_entry->protocol_name = strdup (protocol); - file_entry->protocol_data = NULL; - file_entry->protocol_data_length = 0; - file_entry->network_id = strdup (network_id); - file_entry->auth_name = strdup (GSM_ICE_MAGIC_COOKIE_AUTH_NAME); - file_entry->auth_data = IceGenerateMagicCookie (GSM_ICE_MAGIC_COOKIE_LEN); - file_entry->auth_data_length = GSM_ICE_MAGIC_COOKIE_LEN; - - /* Also create an in-memory copy, which is what the server will - * actually use for checking client auth. - */ - data_entry.protocol_name = file_entry->protocol_name; - data_entry.network_id = file_entry->network_id; - data_entry.auth_name = file_entry->auth_name; - data_entry.auth_data = file_entry->auth_data; - data_entry.auth_data_length = file_entry->auth_data_length; - IceSetPaAuthData (1, &data_entry); - - return file_entry; -} - -static gboolean -update_iceauthority (gboolean adding) -{ - char *filename = IceAuthFileName (); - char **our_network_ids; - FILE *fp; - IceAuthFileEntry *auth_entry; - GSList *entries, *e; - int i; - gboolean ok = FALSE; - - if (IceLockAuthFile (filename, GSM_ICE_AUTH_RETRIES, GSM_ICE_AUTH_INTERVAL, - GSM_ICE_AUTH_LOCK_TIMEOUT) != IceAuthLockSuccess) - return FALSE; - - our_network_ids = g_malloc (num_local_xsmp_sockets * sizeof (char *)); - for (i = 0; i < num_local_xsmp_sockets; i++) - our_network_ids[i] = IceGetListenConnectionString (xsmp_sockets[i]); - - entries = NULL; - - fp = fopen (filename, "r+"); - if (fp) - { - while ((auth_entry = IceReadAuthFileEntry (fp)) != NULL) - { - /* Skip/delete entries with no network ID (invalid), or with - * our network ID; if we're starting up, an entry with our - * ID must be a stale entry left behind by an old process, - * and if we're shutting down, it won't be valid in the - * future, so either way we want to remove it from the list. - */ - if (!auth_entry->network_id) - { - IceFreeAuthFileEntry (auth_entry); - continue; - } - - for (i = 0; i < num_local_xsmp_sockets; i++) - { - if (!strcmp (auth_entry->network_id, our_network_ids[i])) - { - IceFreeAuthFileEntry (auth_entry); - break; - } - } - if (i != num_local_xsmp_sockets) - continue; - - entries = g_slist_prepend (entries, auth_entry); - } - - rewind (fp); - } - else - { - int fd; - - if (g_file_test (filename, G_FILE_TEST_EXISTS)) - { - g_warning ("Unable to read ICE authority file: %s", filename); - goto cleanup; - } - - fd = open (filename, O_CREAT | O_WRONLY, 0600); - fp = fdopen (fd, "w"); - if (!fp) - { - g_warning ("Unable to write to ICE authority file: %s", filename); - if (fd != -1) - close (fd); - goto cleanup; - } - } - - if (adding) - { - for (i = 0; i < num_local_xsmp_sockets; i++) - { - entries = g_slist_append (entries, - auth_entry_new ("ICE", our_network_ids[i])); - entries = g_slist_prepend (entries, - auth_entry_new ("XSMP", our_network_ids[i])); - } - } - - for (e = entries; e; e = e->next) - { - IceAuthFileEntry *auth_entry = e->data; - IceWriteAuthFileEntry (fp, auth_entry); - IceFreeAuthFileEntry (auth_entry); - } - g_slist_free (entries); - - fclose (fp); - ok = TRUE; - - cleanup: - IceUnlockAuthFile (filename); - for (i = 0; i < num_local_xsmp_sockets; i++) - free (our_network_ids[i]); - g_free (our_network_ids); - - return ok; -} - -/* Error handlers */ - -static void -ice_error_handler (IceConn conn, Bool swap, int offending_minor_opcode, - unsigned long offending_sequence, int error_class, - int severity, IcePointer values) -{ - g_debug ("ice_error_handler (%p, %s, %d, %lx, %d, %d)", - conn, swap ? "TRUE" : "FALSE", offending_minor_opcode, - offending_sequence, error_class, severity); - - if (severity == IceCanContinue) - return; - - /* FIXME: the ICElib docs are completely vague about what we're - * supposed to do in this case. Need to verify that calling - * IceCloseConnection() here is guaranteed to cause neither - * free-memory-reads nor leaks. - */ - IceCloseConnection (conn); -} - -static void -ice_io_error_handler (IceConn conn) -{ - g_debug ("ice_io_error_handler (%p)", conn); - - /* We don't need to do anything here; the next call to - * IceProcessMessages() for this connection will receive - * IceProcessMessagesIOError and we can handle the error there. - */ -} - -static void -sms_error_handler (SmsConn conn, Bool swap, int offending_minor_opcode, - unsigned long offending_sequence_num, int error_class, - int severity, IcePointer values) -{ - g_debug ("sms_error_handler (%p, %s, %d, %lx, %d, %d)", - conn, swap ? "TRUE" : "FALSE", offending_minor_opcode, - offending_sequence_num, error_class, severity); - - /* We don't need to do anything here; if the connection needs to be - * closed, libSM will do that itself. - */ -} -- cgit v0.9.1