proposed linc API change ...
- From: Michael Meeks <michael ximian com>
- To: Release Team <gnome2-release-team gnome org>
- Cc: Mark McLoughlin <mark skynet ie>, orbit-list gnome org
- Subject: proposed linc API change ...
- Date: 16 Jan 2002 13:44:54 +0000
Hi Guys,
I hope we can fast track this, since ultimately it's a really simple
flag addition. The rational for this is that ORBit has always used
'security by obscurity' ie. generating a very random object key and then
hoping that no-one can guess it [ much like X cookies, but more random
]. Sadly Solaris has no good way to produce safe random numbers,
consequently we have taken a drastic performance hit - test measurements
show this to be a factor of ~1000 over the new method we propose [ for
object instantiation ].
So - in order to use this far faster, simpler approach - we need to be
able to detect whether an incoming connection comes from a local machine
- and is thus de-facto secure, this is the case for Unix domain sockets,
and also loopback TCP/IP connections.
So - we want to add this flag and some internal gubbins to make it
work; this would only affect ORBit2 and linc and have no external API
impact, whilst providing a massive Solaris/AIX/HPUX performance boost.
The only substantial change is:
Index: include/linc/linc-types.h
===================================================================
RCS file: /cvs/gnome/linc/include/linc/linc-types.h,v
retrieving revision 1.23
diff -u -p -u -r1.23 linc-types.h
--- include/linc/linc-types.h 2001/12/31 10:29:10 1.23
+++ include/linc/linc-types.h 2002/01/16 13:24:27
@@ -21,7 +21,8 @@ G_BEGIN_DECLS
typedef enum {
LINC_CONNECTION_SSL = 1 << 0,
LINC_CONNECTION_NONBLOCKING = 1 << 1,
- LINC_CONNECTION_BLOCK_SIGNAL = 1 << 2
+ LINC_CONNECTION_BLOCK_SIGNAL = 1 << 2,
+ LINC_CONNECTION_LOCAL_ONLY = 1 << 3
} LINCConnectionOptions;
typedef struct _LincWatch LincWatch;
But; we also add a virtual method to:
Index: include/linc/linc-protocol.h
===================================================================
RCS file: /cvs/gnome/linc/include/linc/linc-protocol.h,v
retrieving revision 1.13
diff -u -p -u -r1.13 linc-protocol.h
--- include/linc/linc-protocol.h 2001/12/20 09:35:18 1.13
+++ include/linc/linc-protocol.h 2002/01/16 13:24:27
@@ -41,6 +41,10 @@ typedef gboolean (*LINCProtocolGetSockIn
gchar **hostname,
gchar **service);
+typedef gboolean (*LINCProtocolIsLocal) (const LINCProtocolInfo *proto,
+ const struct sockaddr *sockaddr,
+ socklen_t saddr_len);
+
struct _LINCProtocolInfo {
const char *name;
int family;
@@ -52,6 +56,7 @@ struct _LINCProtocolInfo {
LINCProtocolDestroyFunc destroy;
LINCProtocolGetSockAddrFunc get_sockaddr;
LINCProtocolGetSockInfoFunc get_sockinfo;
+ LINCProtocolIsLocal is_local;
};
LINCProtocolInfo * const linc_protocol_find (const char *name);
Essentially for internal use.
The rest of the patch follows,
Thanks,
Michael.
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/linc/ChangeLog,v
retrieving revision 1.99
diff -u -p -u -r1.99 ChangeLog
--- ChangeLog 2002/01/10 19:05:53 1.99
+++ ChangeLog 2002/01/16 13:24:27
@@ -1,3 +1,21 @@
+2002-01-16 Michael Meeks <michael@ximian.com>
+
+ * src/linc-protocols.c (get_local_hostname): impl. so
+ we can call it lots.
+ (linc_protocol_get_sockinfo_ipv46): upd.
+ (linc_protocol_get_sockinfo_unix): upd.
+ (linc_protocol_is_local): impl.
+ (linc_protocol_unix_is_local): impl.
+ (linc_protocol_is_local_ipv46): impl.
+
+ * src/linc-server.c (linc_server_accept_connection):
+ check for remote connections - if in local only mode,
+ using new is_local API.
+
+ * include/linc/linc-protocol.h: add is_local.
+
+ * include/linc/linc-types.h: add local only flag.
+
2002-10-10 Roland Juelich <rj@atecom.com>
* src/linc-source.c (linc_io_add_watch): create our own
Index: src/linc-private.h
===================================================================
RCS file: /cvs/gnome/linc/src/linc-private.h,v
retrieving revision 1.13
diff -u -p -u -r1.13 linc-private.h
--- src/linc-private.h 2002/01/10 19:05:56 1.13
+++ src/linc-private.h 2002/01/16 13:24:27
@@ -76,8 +76,11 @@ struct sockaddr *linc_protocol_get_socka
gboolean linc_protocol_get_sockinfo (const LINCProtocolInfo *proto,
const struct sockaddr *saddr,
gchar **hostname,
-
gchar **service);
+
+gboolean linc_protocol_is_local (const LINCProtocolInfo *proto,
+ const struct sockaddr *saddr,
+ socklen_t saddr_len);
LincWatch *linc_io_add_watch_fd (int fd,
GIOCondition condition,
Index: src/linc-protocols.c
===================================================================
RCS file: /cvs/gnome/linc/src/linc-protocols.c,v
retrieving revision 1.34
diff -u -p -u -r1.34 linc-protocols.c
--- src/linc-protocols.c 2001/12/14 10:55:59 1.34
+++ src/linc-protocols.c 2002/01/16 13:24:27
@@ -197,6 +197,61 @@ linc_set_tmpdir (const char *dir)
#define LINC_RESOLV_CLEAR_IPV6
#endif
+#if defined(AF_INET) || defined(AF_INET6) || defined (AF_UNIX)
+static const char *
+get_local_hostname (void)
+{
+ static char local_host[NI_MAXHOST] = { 0 };
+
+ if (local_host [0])
+ return local_host;
+
+ if (gethostname (local_host, NI_MAXHOST) == -1)
+ return NULL;
+
+ return local_host;
+}
+
+static gboolean
+linc_protocol_is_local_ipv46 (const LINCProtocolInfo *proto,
+ const struct sockaddr *saddr,
+ socklen_t saddr_len)
+{
+ int i;
+ static int warned = 0;
+ static struct hostent *local_hostent = NULL;
+
+ if (!local_hostent)
+ local_hostent = gethostbyname (get_local_hostname ());
+
+ if (!local_hostent) {
+ if (!warned++)
+ g_warning ("can't gethostbyname on '%s'",
+ get_local_hostname ());
+ return FALSE;
+ }
+
+ if (local_hostent->h_addrtype != saddr->sa_family) {
+ if (!warned++)
+ g_warning ("FIXME: can't compare different family "
+ "address types for locality");
+ return FALSE;
+ }
+
+ g_warning ("Compare vs %d matches len %d",
+ local_hostent->h_length, saddr_len);
+
+ for (i = 0; i < local_hostent->h_length; i++) {
+ if (!memcmp (local_hostent->h_addr_list [i],
+ saddr->sa_data, saddr_len))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+#endif
+
/*
* linc_protocol_get_sockaddr_ipv4:
* @proto: the #LINCProtocolInfo structure for the IPv4 protocol.
@@ -458,11 +513,10 @@ linc_protocol_get_sockinfo_ipv46 (struct
gchar **hostname,
char **portnum)
{
-
if (!host) {
- char local_host[MAXHOSTNAMELEN];
+ const char *local_host;
- if (gethostname (local_host, MAXHOSTNAMELEN) == -1)
+ if (!(local_host = get_local_hostname ()))
return FALSE;
host = gethostbyname (local_host);
@@ -598,12 +652,12 @@ linc_protocol_get_sockinfo_unix (const L
g_assert (proto && saddr && saddr->sa_family == AF_UNIX);
if (hostname) {
- gchar hname [NI_MAXHOST];
+ const char *local_host;
- if (gethostname (hname, NI_MAXHOST) == -1)
+ if (!(local_host = get_local_hostname ()))
return FALSE;
- *hostname = g_strdup (hname);
+ *hostname = g_strdup (local_host);
}
if (sock_path)
@@ -665,6 +719,27 @@ linc_protocol_get_sockinfo (const LINCPr
return FALSE;
}
+/**
+ * linc_protocol_is_local:
+ * @proto: the protocol
+ * @saddr: the socket address of a connecting client.
+ *
+ * This method determines if the client is from the same
+ * machine or not - per protocol.
+ *
+ * Return value: TRUE if the connection is local, else FALSE
+ **/
+gboolean
+linc_protocol_is_local (const LINCProtocolInfo *proto,
+ const struct sockaddr *saddr,
+ socklen_t saddr_len)
+{
+ if (proto && proto->is_local)
+ return proto->is_local (proto, saddr, saddr_len);
+
+ return FALSE;
+}
+
/*
* af_unix_destroy:
* @fd: file descriptor of the socket.
@@ -681,6 +756,14 @@ linc_protocol_unix_destroy (int
{
unlink (pathname);
}
+
+static gboolean
+linc_protocol_unix_is_local (const LINCProtocolInfo *proto,
+ const struct sockaddr *saddr,
+ socklen_t saddr_len)
+{
+ return TRUE;
+}
#endif /* AF_UNIX */
/*
@@ -724,7 +807,8 @@ static LINCProtocolInfo static_linc_prot
linc_protocol_tcp_setup, /* setup */
NULL, /* destroy */
linc_protocol_get_sockaddr_ipv4,/* get_sockaddr */
- linc_protocol_get_sockinfo_ipv4 /* get_sockinfo */
+ linc_protocol_get_sockinfo_ipv4,/* get_sockinfo */
+ linc_protocol_is_local_ipv46 /* is_local */
},
#endif
#if defined(AF_INET6)
@@ -737,7 +821,8 @@ static LINCProtocolInfo static_linc_prot
linc_protocol_tcp_setup, /* setup */
NULL, /* destroy */
linc_protocol_get_sockaddr_ipv6,/* get_sockaddr */
- linc_protocol_get_sockinfo_ipv6 /* get_sockinfo */
+ linc_protocol_get_sockinfo_ipv6,/* get_sockinfo */
+ linc_protocol_is_local_ipv46 /* is_local */
},
#endif
#ifdef AF_UNIX
@@ -750,7 +835,8 @@ static LINCProtocolInfo static_linc_prot
NULL, /* setup */
linc_protocol_unix_destroy, /* destroy */
linc_protocol_get_sockaddr_unix, /* get_sockaddr */
- linc_protocol_get_sockinfo_unix /* get_sockinfo */
+ linc_protocol_get_sockinfo_unix, /* get_sockinfo */
+ linc_protocol_unix_is_local /* is_local */
},
#endif
#ifdef AF_IRDA
@@ -763,7 +849,8 @@ static LINCProtocolInfo static_linc_prot
NULL, /* setup */
NULL, /* destroy */
linc_protocol_get_sockaddr_irda, /* get_sockaddr */
- linc_protocol_get_sockinfo_irda /* get_sockinfo */
+ linc_protocol_get_sockinfo_irda, /* get_sockinfo */
+ NULL /* is_local */
},
#endif
{ NULL /* name */ }
Index: src/linc-server.c
===================================================================
RCS file: /cvs/gnome/linc/src/linc-server.c,v
retrieving revision 1.45
diff -u -p -u -r1.45 linc-server.c
--- src/linc-server.c 2002/01/04 22:50:58 1.45
+++ src/linc-server.c 2002/01/16 13:24:27
@@ -151,6 +151,12 @@ linc_server_accept_connection (LINCServe
return FALSE; /* error */
}
+ if (server->create_options & LINC_CONNECTION_LOCAL_ONLY &&
+ !linc_protocol_is_local (server->proto, saddr, addrlen)) {
+ close (fd);
+ return FALSE;
+ }
+
if (server->create_options & LINC_CONNECTION_NONBLOCKING)
if (fcntl (fd, F_SETFL, O_NONBLOCK) < 0) {
d_printf ("failed to set O_NONBLOCK on %d", fd);
--
mmeeks@gnu.org <><, Pseudo Engineer, itinerant idiot
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]