Add authentication code. Only allow root & same user connect to ibus-daemon.

This commit is contained in:
Peng Huang 2009-04-20 15:00:19 +08:00
Родитель 1e4f119f94
Коммит 164626ec6f
7 изменённых файлов: 140 добавлений и 6 удалений

Просмотреть файл

@ -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;
@ -132,6 +136,16 @@ bus_connection_destroy (BusConnection *connection)
priv->names = NULL;
}
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)

Просмотреть файл

@ -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);

Просмотреть файл

@ -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,11 +111,34 @@ 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.
@ -239,6 +266,13 @@ _out:
parent_class->destroy (IBUS_OBJECT (connection));
}
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)

Просмотреть файл

@ -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,
@ -207,6 +210,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.
@ -216,6 +228,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.

Просмотреть файл

@ -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

Просмотреть файл

@ -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);
}

Просмотреть файл

@ -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