Add authentication code. Only allow root & same user connect to ibus-daemon.
authorPeng Huang <shawn.p.huang@gmail.com>
Mon, 20 Apr 2009 07:00:19 +0000 (15:00 +0800)
committerPeng Huang <shawn.p.huang@gmail.com>
Mon, 20 Apr 2009 07:00:19 +0000 (15:00 +0800)
bus/connection.c
bus/server.c
src/ibusconnection.c
src/ibusconnection.h
src/ibusmarshalers.list
src/ibusserver.c
src/ibusserver.h

index fd05ab1..acdebb1 100644 (file)
@@ -39,6 +39,9 @@ typedef struct _BusConnectionPrivate BusConnectionPrivate;
 static void     bus_connection_class_init   (BusConnectionClass     *klass);
 static void     bus_connection_init         (BusConnection          *connection);
 static void     bus_connection_destroy      (BusConnection          *connection);
+static gboolean bus_connection_authenticate_unix_user
+                                            (IBusConnection         *connection,
+                                             gulong                  uid);
 static gboolean bus_connection_ibus_message (BusConnection          *connection,
                                              IBusMessage            *message);
 #if 0
@@ -94,6 +97,7 @@ bus_connection_class_init (BusConnectionClass *klass)
 
     ibus_object_class->destroy = (IBusObjectDestroyFunc) bus_connection_destroy;
 
+    ibus_connection_class->authenticate_unix_user = bus_connection_authenticate_unix_user;
     ibus_connection_class->ibus_message =
             (IBusIBusMessageFunc) bus_connection_ibus_message;
 
@@ -133,6 +137,16 @@ bus_connection_destroy (BusConnection *connection)
 }
 
 static gboolean
+bus_connection_authenticate_unix_user (IBusConnection *connection,
+                                       gulong          uid)
+{
+    /* just allow root or same user connect to ibus */
+    if (uid == 0 || uid == getuid ())
+        return TRUE;
+    return FALSE;
+}
+
+static gboolean
 bus_connection_ibus_message (BusConnection  *connection,
                              IBusMessage    *message)
 {
index 1c796f2..9b9c305 100644 (file)
@@ -84,6 +84,11 @@ bus_server_listen (BusServer *server)
 {
     g_assert (BUS_IS_SERVER (server));
 
+    const gchar *mechanisms[] = {
+        "EXTERNAL",
+        NULL
+    };
+
     // const gchar *address = "unix:abstract=/tmp/ibus-c"
     const gchar *address;
     const gchar *path;
@@ -97,6 +102,7 @@ bus_server_listen (BusServer *server)
 
     retval = ibus_server_listen (IBUS_SERVER (server), address);
     chmod (ibus_get_socket_path (), 0600);
+    ibus_server_set_auth_mechanisms ((IBusServer *)server, mechanisms);
 
     if (!retval) {
         g_printerr ("Can not listen on %s! Please try remove directory %s and run again.", address, path);
index 1ba12ad..fed1e5a 100644 (file)
@@ -26,6 +26,7 @@
    (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_TYPE_CONNECTION, IBusConnectionPrivate))
 
 enum {
+    AUTHENTICATE_UNIX_USER,
     IBUS_SIGNAL,
     IBUS_MESSAGE,
     IBUS_MESSAGE_SENT,
@@ -48,6 +49,9 @@ static void     ibus_connection_class_init  (IBusConnectionClass    *klass);
 static void     ibus_connection_init        (IBusConnection         *connection);
 static void     ibus_connection_destroy     (IBusConnection         *connection);
 
+static gboolean ibus_connection_authenticate_unix_user
+                                            (IBusConnection         *connection,
+                                             gulong                  uid);
 static gboolean ibus_connection_ibus_message(IBusConnection         *connection,
                                              IBusMessage            *message);
 static gboolean ibus_connection_ibus_signal (IBusConnection         *connection,
@@ -107,12 +111,35 @@ ibus_connection_class_init (IBusConnectionClass *klass)
 
     object_class->destroy = (IBusObjectDestroyFunc) ibus_connection_destroy;
 
+    klass->authenticate_unix_user = ibus_connection_authenticate_unix_user;
     klass->ibus_message = ibus_connection_ibus_message;
     klass->ibus_signal  = ibus_connection_ibus_signal;
     klass->disconnected = ibus_connection_disconnected;
 
     /* install signals */
     /**
+     * IBusConnection::authenticate-unix-user:
+     * @ibusconnection: The object which received the signal.
+     * @uid: unix user id.
+     *
+     * Emitted when sending an ibus-message.
+     * Implement the member function ibus_message() in extended class to receive this signal.
+     *
+     * <note><para>@user_data is not actually a valid parameter. It is displayed because GtkDoc.</para></note>
+     *
+     * Returns: TRUE if succeed; FALSE otherwise.
+     */
+    connection_signals[AUTHENTICATE_UNIX_USER] =
+        g_signal_new (I_("authenticate-unix-user"),
+            G_TYPE_FROM_CLASS (klass),
+            G_SIGNAL_RUN_LAST,
+            G_STRUCT_OFFSET (IBusConnectionClass, authenticate_unix_user),
+            NULL, NULL,
+            ibus_marshal_BOOLEAN__ULONG,
+            G_TYPE_BOOLEAN, 1,
+            G_TYPE_ULONG);
+
+    /**
      * IBusConnection::ibus-message:
      * @ibusconnection: The object which received the signal.
      * @message: An IBusMessage.
@@ -240,6 +267,13 @@ _out:
 }
 
 static gboolean
+ibus_connection_authenticate_unix_user (IBusConnection *connection,
+                                        gulong          uid)
+{
+    return FALSE;
+}
+
+static gboolean
 ibus_connection_ibus_message (IBusConnection *connection,
                               IBusMessage    *message)
 {
@@ -270,16 +304,28 @@ ibus_connection_disconnected (IBusConnection         *connection)
     ibus_object_destroy (IBUS_OBJECT (connection));
 }
 
-static DBusHandlerResult
-_connection_handle_message_cb (DBusConnection   *dbus_connection,
-                               IBusMessage      *message,
-                               IBusConnection   *connection)
+static dbus_bool_t
+_connection_allow_unix_user_cb (DBusConnection *dbus_connection,
+                                gulong          uid,
+                                IBusConnection *connection)
 {
     gboolean retval = FALSE;
 
-    gint type;
+    g_signal_emit (connection, connection_signals[AUTHENTICATE_UNIX_USER], 0, uid, &retval);
+
+    if (retval)
+        return TRUE;
+
+    return FALSE;
+}
+
+static DBusHandlerResult
+_connection_handle_message_cb (DBusConnection *dbus_connection,
+                               IBusMessage    *message,
+                               IBusConnection *connection)
+{
+    gboolean retval = FALSE;
 
-    type = ibus_message_get_type (message);
     g_signal_emit (connection, connection_signals[IBUS_MESSAGE], 0, message, &retval);
 
     if (retval)
@@ -316,6 +362,10 @@ ibus_connection_set_connection (IBusConnection *connection, DBusConnection *dbus
 
     dbus_connection_set_data (priv->connection, _get_slot(), connection, NULL);
 
+    dbus_connection_set_unix_user_function (priv->connection,
+                    (DBusAllowUnixUserFunction) _connection_allow_unix_user_cb,
+                    connection, NULL);
+
     result = dbus_connection_add_filter (priv->connection,
                     (DBusHandleMessageFunction) _connection_handle_message_cb,
                     connection, NULL);
@@ -406,6 +456,18 @@ ibus_connection_is_connected (IBusConnection *connection)
     return dbus_connection_get_is_connected (priv->connection);
 }
 
+gboolean
+ibus_connection_is_authenticated (IBusConnection *connection)
+{
+    IBusConnectionPrivate *priv;
+    priv = IBUS_CONNECTION_GET_PRIVATE (connection);
+
+    if (priv->connection == NULL) {
+        return FALSE;
+    }
+    return dbus_connection_get_is_authenticated (priv->connection);
+}
+
 DBusConnection *
 ibus_connection_get_connection (IBusConnection *connection)
 {
@@ -415,6 +477,19 @@ ibus_connection_get_connection (IBusConnection *connection)
     return priv->connection;
 }
 
+glong
+ibus_connection_get_unix_user (IBusConnection *connection)
+{
+    IBusConnectionPrivate *priv;
+    priv = IBUS_CONNECTION_GET_PRIVATE (connection);
+
+    gulong uid;
+
+    if (priv->connection && dbus_connection_get_unix_user (priv->connection, &uid))
+        return uid;
+    return -1;
+}
+
 gboolean
 ibus_connection_read_write_dispatch (IBusConnection *connection,
                                      gint            timeout)
index e18bfe3..7a1294c 100644 (file)
@@ -124,6 +124,9 @@ struct _IBusConnectionClass {
     IBusObjectClass parent;
 
     /* signals */
+    gboolean    (* authenticate_unix_user)
+                                    (IBusConnection   *connection,
+                                     gulong            uid);
     gboolean    (* ibus_message)    (IBusConnection   *connection,
                                      IBusMessage      *message);
     gboolean    (* ibus_signal)     (IBusConnection   *connection,
@@ -208,6 +211,15 @@ void             ibus_connection_close              (IBusConnection     *connect
 gboolean         ibus_connection_is_connected       (IBusConnection     *connection);
 
 /**
+ * ibus_connection_is_authenticated:
+ * @connection: An IBusConnection.
+ * @returns: TRUE for authenticated; FALSE otherwise.
+ *
+ * Whether an IBusConnection is authenticated.
+ */
+gboolean         ibus_connection_is_authenticated   (IBusConnection     *connection);
+
+/**
  * ibus_connection_get_connection:
  * @connection: An IBusConnection.
  * @returns: The corresponding DBusConnection.
@@ -217,6 +229,15 @@ gboolean         ibus_connection_is_connected       (IBusConnection     *connect
 DBusConnection  *ibus_connection_get_connection     (IBusConnection     *connection);
 
 /**
+ * ibus_connection_get_unix_user:
+ * @connection: An IBusConnection.
+ * @returns: The UNIX UID of peer user.
+ *
+ * Return The UNIX UID of peer user.
+ */
+glong            ibus_connection_get_unix_user      (IBusConnection     *connection);
+
+/**
  * ibus_connection_read_write_dispatch:
  * @connection: An IBusConnection.
  * @timeout: Maximum time to block or -1 for infinite.
index 7ef0c76..37eedc2 100644 (file)
@@ -7,6 +7,7 @@ VOID:STRING,UINT
 BOOL:POINTER
 BOOL:POINTER,POINTER
 BOOL:UINT,UINT
+BOOL:ULONG
 VOID:INT,INT,INT,INT
 VOID:UINT,UINT
 VOID:OBJECT,UINT,BOOL
index 2299856..0c3ee8b 100644 (file)
@@ -328,3 +328,18 @@ ibus_server_is_connected (IBusServer *server)
     return dbus_server_get_is_connected (priv->server);
 }
 
+
+gboolean
+ibus_server_set_auth_mechanisms (IBusServer   *server,
+                                 const gchar **mechanisms)
+{
+    g_assert (IBUS_IS_SERVER (server));
+
+    IBusServerPrivate *priv;
+    priv = IBUS_SERVER_GET_PRIVATE (server);
+
+    g_assert (priv->server != NULL);
+
+    return dbus_server_set_auth_mechanisms (priv->server, mechanisms);
+}
+
index cf3547f..f99479b 100644 (file)
@@ -73,6 +73,8 @@ void             ibus_server_disconnect         (IBusServer     *server);
 const gchar     *ibus_server_get_address        (IBusServer     *server);
 const gchar     *ibus_server_get_id             (IBusServer     *server);
 gboolean         ibus_server_is_connected       (IBusServer     *server);
+gboolean         ibus_server_set_auth_mechanisms(IBusServer     *server,
+                                                 const gchar   **mechanisms);
 
 G_END_DECLS
 #endif