bus: Use XDG_RUNTIME_DIR for Unix socket directory
g_dbus_server_new_sync() is failed with address "unix:tmpdir=/tmp/ibus" in BSD systems because BSD systems do not support abstract socket files and use the real files but no directory "/tmp/ibus". Now the default directory will be an unique "unix:tmpdir=$XDG_RUNTIME_DIR/ibus" by user in Linux and "unix:tmpdir=/tmp" in BSD and mkdir() runs with the directory mode 0700 not to modify by malicious users. BUG=https://github.com/ibus/ibus/issues/2116
This commit is contained in:
Родитель
3d442dbf93
Коммит
a141a14102
|
@ -2,7 +2,7 @@
|
|||
/* vim:set et sts=4: */
|
||||
/* ibus - The Input Bus
|
||||
* Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
|
||||
* Copyright (C) 2008-2010 Red Hat, Inc.
|
||||
* Copyright (C) 2008-2019 Red Hat, Inc.
|
||||
* Copyright (c) 2012 Google, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
|
@ -21,10 +21,12 @@
|
|||
* USA
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "global.h"
|
||||
|
||||
gchar **g_argv = NULL;
|
||||
gchar *g_address = "unix:tmpdir=/tmp/ibus";
|
||||
gchar *g_address = IBUS_SOCKET_DIR;
|
||||
gchar *g_cache = "auto";
|
||||
gboolean g_mempro = FALSE;
|
||||
gboolean g_verbose = FALSE;
|
||||
|
|
99
bus/server.c
99
bus/server.c
|
@ -22,6 +22,8 @@
|
|||
*/
|
||||
#include "server.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <glib/gstdio.h>
|
||||
#include <gio/gio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -180,28 +182,102 @@ bus_acquired_handler (GDBusConnection *connection,
|
|||
NULL);
|
||||
}
|
||||
|
||||
static gchar *
|
||||
_bus_extract_address (void)
|
||||
{
|
||||
gchar *socket_address = g_strdup (g_address);
|
||||
gchar *p;
|
||||
|
||||
#define IF_REPLACE_VARIABLE_WITH_FUNC(variable, func, format) \
|
||||
if ((p = g_strstr_len (socket_address, -1, (variable)))) { \
|
||||
gchar *sub1 = g_strndup (socket_address, p - socket_address); \
|
||||
gchar *sub2 = g_strdup (p + strlen (variable)); \
|
||||
gchar *tmp = g_strdup_printf ("%s" format "%s", \
|
||||
sub1, (func) (), sub2); \
|
||||
g_free (sub1); \
|
||||
g_free (sub2); \
|
||||
g_free (socket_address); \
|
||||
socket_address = tmp; \
|
||||
}
|
||||
|
||||
IF_REPLACE_VARIABLE_WITH_FUNC ("$XDG_RUNTIME_DIR",
|
||||
g_get_user_runtime_dir,
|
||||
"%s")
|
||||
else
|
||||
IF_REPLACE_VARIABLE_WITH_FUNC ("$XDG_CACHE_HOME",
|
||||
g_get_user_cache_dir,
|
||||
"%s")
|
||||
else
|
||||
IF_REPLACE_VARIABLE_WITH_FUNC ("$UID", getuid, "%d")
|
||||
|
||||
#undef IF_REPLACE_VARIABLE_WITH_FUNC
|
||||
|
||||
return socket_address;
|
||||
}
|
||||
|
||||
void
|
||||
bus_server_init (void)
|
||||
{
|
||||
GError *error = NULL;
|
||||
#define IBUS_UNIX_TMPDIR "unix:tmpdir="
|
||||
#define IBUS_UNIX_PATH "unix:path="
|
||||
#define IBUS_UNIX_ABSTRACT "unix:abstract="
|
||||
#define IBUS_UNIX_DIR "unix:dir="
|
||||
|
||||
gchar *socket_address;
|
||||
GDBusServerFlags flags = G_DBUS_SERVER_FLAGS_NONE;
|
||||
gchar *guid;
|
||||
GDBusAuthObserver *observer;
|
||||
GError *error = NULL;
|
||||
gchar *unix_dir = NULL;
|
||||
|
||||
dbus = bus_dbus_impl_get_default ();
|
||||
ibus = bus_ibus_impl_get_default ();
|
||||
bus_dbus_impl_register_object (dbus, (IBusService *)ibus);
|
||||
|
||||
/* init server */
|
||||
socket_address = _bus_extract_address ();
|
||||
|
||||
#define IF_GET_UNIX_DIR(prefix) \
|
||||
if (g_str_has_prefix (socket_address, (prefix))) { \
|
||||
unix_dir = g_strdup (socket_address + strlen (prefix)); \
|
||||
}
|
||||
|
||||
IF_GET_UNIX_DIR (IBUS_UNIX_TMPDIR)
|
||||
else
|
||||
IF_GET_UNIX_DIR (IBUS_UNIX_PATH)
|
||||
else
|
||||
IF_GET_UNIX_DIR (IBUS_UNIX_ABSTRACT)
|
||||
else
|
||||
IF_GET_UNIX_DIR (IBUS_UNIX_DIR)
|
||||
else {
|
||||
g_error ("Your socket address \"%s\" does not correspond with "
|
||||
"one of the following formats; "
|
||||
IBUS_UNIX_TMPDIR "DIR, " IBUS_UNIX_PATH "FILE, "
|
||||
IBUS_UNIX_ABSTRACT "FILE, " IBUS_UNIX_DIR "DIR.",
|
||||
socket_address);
|
||||
}
|
||||
if (!g_file_test (unix_dir, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) {
|
||||
/* Require mkdir for BSD system. */
|
||||
if (g_mkdir_with_parents (unix_dir, 0) != 0) {
|
||||
g_error ("mkdir is failed in: %s: %s",
|
||||
unix_dir, g_strerror (errno));
|
||||
}
|
||||
/* The mode 0700 can eliminate malicious users change the mode.
|
||||
* `chmod` runs for the last directory only not to change the modes
|
||||
* of the parent directories. E.g. "/tmp/ibus".
|
||||
*/
|
||||
if (g_chmod (unix_dir, 0700) != 0) {
|
||||
g_error ("chmod(700) is failed in: %s: %s",
|
||||
unix_dir, g_strerror (errno));
|
||||
}
|
||||
}
|
||||
g_free (unix_dir);
|
||||
guid = g_dbus_generate_guid ();
|
||||
observer = g_dbus_auth_observer_new ();
|
||||
if (!g_str_has_prefix (g_address, "unix:tmpdir=") &&
|
||||
!g_str_has_prefix (g_address, "unix:path=")) {
|
||||
g_error ("Your socket address does not have the format unix:tmpdir=$DIR "
|
||||
"or unix:path=$FILE; %s", g_address);
|
||||
}
|
||||
server = g_dbus_server_new_sync (
|
||||
g_address, /* the place where the socket file lives, e.g. /tmp, abstract namespace, etc. */
|
||||
/* the place where the socket file lives, e.g. /tmp,
|
||||
* abstract namespace, etc. */
|
||||
socket_address,
|
||||
flags, guid,
|
||||
observer,
|
||||
NULL /* cancellable */,
|
||||
|
@ -209,8 +285,9 @@ bus_server_init (void)
|
|||
if (server == NULL) {
|
||||
g_error ("g_dbus_server_new_sync() is failed with address %s "
|
||||
"and guid %s: %s",
|
||||
g_address, guid, error->message);
|
||||
socket_address, guid, error->message);
|
||||
}
|
||||
g_free (socket_address);
|
||||
g_free (guid);
|
||||
|
||||
g_signal_connect (observer, "allow-mechanism",
|
||||
|
@ -235,6 +312,12 @@ bus_server_init (void)
|
|||
G_BUS_NAME_OWNER_FLAGS_NONE,
|
||||
bus_acquired_handler,
|
||||
NULL, NULL, NULL, NULL);
|
||||
|
||||
#undef IF_GET_UNIX_DIR
|
||||
#undef IBUS_UNIX_TMPDIR
|
||||
#undef IBUS_UNIX_PATH
|
||||
#undef IBUS_UNIX_ABSTRACT
|
||||
#undef IBUS_UNIX_DIR
|
||||
}
|
||||
|
||||
const gchar *
|
||||
|
|
25
configure.ac
25
configure.ac
|
@ -702,6 +702,30 @@ the UCD files from https://www.unicode.org/Public/UNIDATA/)
|
|||
enable_unicode_dict="yes (enabled, use --disable-unicode-dict to disable)"
|
||||
fi
|
||||
|
||||
AC_ARG_WITH(socket-dir,
|
||||
AS_HELP_STRING([--with-socket-dir[=DIR]],
|
||||
[Set the default socket directory to connect ibus-daemon with D-Bus
|
||||
connections (default: "$XDG_RUNTIME_DIR/ibus").
|
||||
The best practice of the socket directory would be unique per user
|
||||
not to modify by malicious users but XDG_RUNTIME_DIR is not integrated
|
||||
in BSD systems and the BSD's default is "/tmp".
|
||||
"$XDG_RUMTIME_DIR", "$XDG_CACHE_HOME", "$UID" are extracted by
|
||||
ibus-daemon.
|
||||
ibus-daemon also runs mkdir for the socket directory since BSD
|
||||
systems do not support abstract socket paths.
|
||||
The socket path on a NFS mount would not be a good idea likes
|
||||
"/home/$USER" because the directory is not sometimes accessible
|
||||
with the network condition.]),
|
||||
[IBUS_SOCKET_DIR=$with_socket_dir],
|
||||
[case $host in
|
||||
*linux*) IBUS_SOCKET_DIR='unix:tmpdir=$XDG_RUNTIME_DIR/ibus';;
|
||||
*) IBUS_SOCKET_DIR='unix:tmpdir=/tmp';;
|
||||
esac]
|
||||
|
||||
)
|
||||
AC_DEFINE_UNQUOTED(IBUS_SOCKET_DIR, "$IBUS_SOCKET_DIR",
|
||||
[The default socket directory to connect ibus-daemon.])
|
||||
|
||||
# Check iso-codes.
|
||||
PKG_CHECK_MODULES(ISOCODES, [
|
||||
iso-codes
|
||||
|
@ -793,6 +817,7 @@ Build options:
|
|||
CLDR annotation directory $EMOJI_ANNOTATION_DIR
|
||||
Enable Unicode dict $enable_unicode_dict
|
||||
UCD directory $UCD_DIR
|
||||
Socket directory "$IBUS_SOCKET_DIR"
|
||||
Run test cases $enable_tests
|
||||
Install tests $enable_install_tests
|
||||
])
|
||||
|
|
Загрузка…
Ссылка в новой задаче