logo       

Sponsor
FREE Network Mapping Tool for Microsoft® Office Visio® Professional 2007
Don't map your network by hand - let LANsurveyor Exx press for Microsoft Visio Professional 2007 automatically create network diagrams for you!

Re: User authentication to services: msg#00034

freedesktop.dbus

Subject: Re: User authentication to services

On Thu, Jan 01, 1970 at 12:00:00AM +0000, Havoc Pennington wrote:
> On Tue, 2004-06-01 at 02:14, Rob Taylor wrote:
> > I'm interested in implementing a solution. However its not clear to me if
> > this proposed solution solves my problem - I need applications to be able
> > to authorise to a service, not a service to applications. and these
> > applications must not be forced to register as a service as there may be
> > multiple instances. Am i understanding this correctly?
> >
>
> Remember that all apps own at least one service, their unique base
> service name. (We have to come up with better terminology!)
>
> Each connection to the bus has a unique ID that never gets recycled (is
> never used by another connection to the same bus). This is called the
> "base service name" at the moment and looks like ":2-5" (the numbers
> change).
>
> Then connections can own 0-N additional well-known service names, such
> as "com.foobar.MyService" - these well-known names can refer to
> different connections at different times, since the owner can disconnect
> and another service can connect and take ownership instead.
>
> So in the authentication case you'd want to track the base service name,
> if you authenticated com.foobar.MyService you have a race condition
> since you don't know that the app currently owning the service is the
> same as the app you authenticated. With the base service name, if the
> name still exists it's still the same app.

Seems pretty silent now, the topic. But I need the get_sender_uid
feature too, so I tried something. Attention, I'm walking in total
darkness in the D-BUS code. :)

The following works for me:
sender = dbus_message_get_sender (message);
uid = dbus_bus_get_sender_uid (connection, sender, NULL);

D-BUS encodes the senders "base service name" in the incoming message,
so I made a method, which passes the name to a 'GetSenderUid' method
in dbus/bus/driver.c. The method iterates over all connections until the
right one is found and dbus_connection_get_unix_user() is called for it.
The uid is passed back to the calling dbus_bus_get_sender_uid().

Is there any better way to find the connection by its name?

Thanks,
Kay

Index: bus/driver.c
===================================================================
RCS file: /cvs/dbus/dbus/bus/driver.c,v
retrieving revision 1.49
diff -u -r1.49 driver.c
--- bus/driver.c 9 Jun 2004 18:15:09 -0000 1.49
+++ bus/driver.c 17 Jun 2004 00:19:32 -0000
@@ -829,6 +829,115 @@
return FALSE;
}

+struct connection_match
+{
+ DBusConnection *connection;
+ const char *sender;
+};
+
+static dbus_bool_t
+match_sender (DBusConnection *connection,
+ void *data)
+{
+ const char *conn_sender;
+ struct connection_match *match;
+
+ _dbus_verbose ("match_sender() conn=%p\n", connection);
+
+ match = (struct connection_match*) data;
+
+ conn_sender = bus_connection_get_name (connection);
+ if (conn_sender == NULL)
+ return TRUE;
+
+ if (strcmp (match->sender, conn_sender) == 0)
+ {
+ match->connection = connection;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static dbus_bool_t
+bus_driver_handle_get_sender_uid (DBusConnection *connection,
+ BusTransaction *transaction,
+ DBusMessage *message,
+ DBusError *error)
+{
+ char *sender = NULL;
+ DBusMessage *reply = NULL;
+ unsigned long uid;
+ struct connection_match match;
+ BusContext *context;
+ BusConnections *connections;
+
+ _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+
+ if (! dbus_message_get_args (message, error,
+ DBUS_TYPE_STRING, &sender,
+ DBUS_TYPE_INVALID))
+ goto failed;
+
+ _dbus_verbose ("bus_driver_handle_get_sender_uid() asked for %s\n", sender);
+
+ /* iterate over connections and pick the one with our 'base service name' */
+ match.connection = NULL;
+ match.sender = sender;
+
+ context = bus_connection_get_context (connection);
+ connections = bus_context_get_connections (context);
+
+ bus_connections_foreach (connections, match_sender, (void *) &match);
+ if (match.connection == NULL)
+ {
+ dbus_set_error (error,
+ DBUS_ERROR_FAILED,
+ "Could not determine connection '%s'", sender);
+ goto failed;
+ }
+
+ _dbus_verbose ("bus_driver_handle_get_sender_uid() found connection\n");
+
+ if (!dbus_connection_get_unix_user (match.connection, &uid))
+ if (context == NULL)
+ {
+ dbus_set_error (error,
+ DBUS_ERROR_FAILED,
+ "Could not determine uid for '%s'", sender);
+ goto failed;
+ }
+
+ _dbus_verbose ("bus_driver_handle_get_sender_uid() found uid=%i\n",
(dbus_uint32_t) uid);
+
+ reply = dbus_message_new_method_return (message);
+ if (reply == NULL)
+ goto oom;
+
+ if (! dbus_message_append_args (reply,
+ DBUS_TYPE_UINT32, (dbus_uint32_t) uid,
+ DBUS_TYPE_INVALID))
+ goto oom;
+
+ if (! bus_transaction_send_from_driver (transaction, connection, reply))
+ goto oom;
+
+ dbus_message_unref (reply);
+ dbus_free (sender);
+
+ return TRUE;
+
+ oom:
+ BUS_SET_OOM (error);
+
+ failed:
+ _DBUS_ASSERT_ERROR_IS_SET (error);
+ if (reply)
+ dbus_message_unref (reply);
+ dbus_free (sender);
+ return FALSE;
+}
+
static dbus_bool_t
bus_driver_handle_reload_config (DBusConnection *connection,
BusTransaction *transaction,
@@ -875,6 +984,7 @@
{ "AddMatch", bus_driver_handle_add_match },
{ "RemoveMatch", bus_driver_handle_remove_match },
{ "GetServiceOwner", bus_driver_handle_get_service_owner },
+ { "GetSenderUid", bus_driver_handle_get_sender_uid },
{ "ReloadConfig", bus_driver_handle_reload_config }
};

Index: dbus/dbus-bus.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-bus.c,v
retrieving revision 1.29
diff -u -r1.29 dbus-bus.c
--- dbus/dbus-bus.c 9 Jun 2004 18:15:09 -0000 1.29
+++ dbus/dbus-bus.c 17 Jun 2004 00:19:32 -0000
@@ -627,6 +627,78 @@
}

/**
+ * Asks the bus to return the uid of a sender.
+ *
+ * @param connection the connection
+ * @param service_name the service name
+ * @param error location to store the error
+ * @returns a result code, -1 if error is set
+ */
+dbus_uint32_t
+dbus_bus_get_sender_uid (DBusConnection *connection,
+ const char *sender,
+ DBusError *error)
+{
+ DBusMessage *message, *reply;
+ dbus_uint32_t uid;
+
+ _dbus_return_val_if_fail (connection != NULL, 0);
+ _dbus_return_val_if_fail (sender != NULL, 0);
+ _dbus_return_val_if_error_is_set (error, 0);
+
+ message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
+ DBUS_PATH_ORG_FREEDESKTOP_DBUS,
+ DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
+ "GetSenderUid");
+
+ if (message == NULL)
+ {
+ _DBUS_SET_OOM (error);
+ return -1;
+ }
+
+ if (!dbus_message_append_args (message,
+ DBUS_TYPE_STRING, sender,
+ DBUS_TYPE_INVALID))
+ {
+ dbus_message_unref (message);
+ _DBUS_SET_OOM (error);
+ return -1;
+ }
+
+ reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
+ error);
+
+ dbus_message_unref (message);
+
+ if (reply == NULL)
+ {
+ _DBUS_ASSERT_ERROR_IS_SET (error);
+ return -1;
+ }
+
+ if (dbus_set_error_from_message (error, reply))
+ {
+ _DBUS_ASSERT_ERROR_IS_SET (error);
+ dbus_message_unref (reply);
+ return -1;
+ }
+
+ if (!dbus_message_get_args (reply, error,
+ DBUS_TYPE_UINT32, &uid,
+ DBUS_TYPE_INVALID))
+ {
+ _DBUS_ASSERT_ERROR_IS_SET (error);
+ dbus_message_unref (reply);
+ return -1;
+ }
+
+ dbus_message_unref (reply);
+
+ return uid;
+}
+
+/**
* Checks whether a certain service exists.
*
* @param connection the connection
Index: dbus/dbus-bus.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-bus.h,v
retrieving revision 1.9
diff -u -r1.9 dbus-bus.h
--- dbus/dbus-bus.h 2 Dec 2003 10:44:21 -0000 1.9
+++ dbus/dbus-bus.h 17 Jun 2004 00:19:32 -0000
@@ -45,6 +45,9 @@
dbus_bool_t dbus_bus_set_base_service (DBusConnection *connection,
const char *base_service);
const char* dbus_bus_get_base_service (DBusConnection *connection);
+dbus_uint32_t dbus_bus_get_sender_uid (DBusConnection *connection,
+ const char *sender,
+ DBusError *error);
int dbus_bus_acquire_service (DBusConnection *connection,
const char *service_name,
unsigned int flags,





Only community members can participate in forum threads. You must Register or log in to contribute.

<Prev in Thread] Current Thread [Next in Thread>
Sponsor
FREE Network Mapping Tool for Microsoft® OfficeVisio Professional 2007
Don't map your network by hand - let LANsurveyor Express for Microsoft Visio Professional 2007
automatically create network diagrams for you!
Google Custom Search

Free Magazines

Cisco News
Receive a free quarterly e-newsletter with exclusive articles on how Cisco IT uses its own products and solutions to enable the business.
subscribe

Systems Management News, the newspaper for IT systems administration and data center managers! Each issue of Systems Management News is chock-full of news and analysis to help you understand what's happening in your field.
subscribe

The Enterprise Newsweekly eWeek is the essential technology information source for builders of e-business.
subscribe

Oracle Magazine Oracle Magazine contains technology strategy articles, sample code, tips, Oracle and partner news, how to articles for developers and DBAs, and more. Oracle (NASDAQ: ORCL) is the world's largest enterprise software company.
subscribe

Total Telecom Total Telecom is "The Economist of the communications industry".
subscribe

Navigation

Home | sitemap | advertise | OSDir is an inevitable website. super tiny logo