From 3423ce3039033e8bf54860a2b955fdf8c1f21be7 Mon Sep 17 00:00:00 2001 From: William Jon McCann Date: Fri, 17 Aug 2007 12:59:41 -0400 Subject: add a vt monitor test, move getfd to sysdeps, add a check for the root user --- src/Makefile.am | 14 +++++- src/ck-sysdeps-unix.c | 114 +++++++++++++++++++++++++++++++++++++++++++- src/ck-sysdeps.h | 11 +++++ src/ck-vt-monitor.c | 5 +- src/getfd.c | 97 ------------------------------------- src/main.c | 6 +++ src/test-tty-idle-monitor.c | 12 +---- src/test-vt-monitor.c | 83 ++++++++++++++++++++++++++++++++ 8 files changed, 230 insertions(+), 112 deletions(-) delete mode 100644 src/getfd.c create mode 100644 src/test-vt-monitor.c diff --git a/src/Makefile.am b/src/Makefile.am index 244e39e..a5dc1e6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -91,7 +91,6 @@ console_kit_daemon_SOURCES = \ ck-session.c \ ck-log.h \ ck-log.c \ - getfd.c \ $(BUILT_SOURCES) \ $(NULL) @@ -115,6 +114,18 @@ console_kit_daemon_LDADD = \ noinst_PROGRAMS = \ test-tty-idle-monitor \ + test-vt-monitor \ + $(NULL) + +test_vt_monitor_SOURCES = \ + ck-vt-monitor.h \ + ck-vt-monitor.c \ + test-vt-monitor.c \ + $(NULL) + +test_vt_monitor_LDADD = \ + $(CONSOLE_KIT_LIBS) \ + libck.la \ $(NULL) test_tty_idle_monitor_SOURCES = \ @@ -127,6 +138,7 @@ test_tty_idle_monitor_SOURCES = \ test_tty_idle_monitor_LDADD = \ $(CONSOLE_KIT_LIBS) \ + libck.la \ $(NULL) EXTRA_DIST = \ diff --git a/src/ck-sysdeps-unix.c b/src/ck-sysdeps-unix.c index aadca48..4bad4b6 100644 --- a/src/ck-sysdeps-unix.c +++ b/src/ck-sysdeps-unix.c @@ -25,10 +25,15 @@ #include #include #include +#include #include #include #include -#include +#include + +#ifdef __linux__ +#include +#endif #ifdef HAVE_GETPEERUCRED #include @@ -96,3 +101,110 @@ ck_get_socket_peer_credentials (int socket_fd, return ret; } + + +/* + * getfd.c + * + * Get an fd for use with kbd/console ioctls. + * We try several things because opening /dev/console will fail + * if someone else used X (which does a chown on /dev/console). + */ + +gboolean +ck_fd_is_a_console (int fd) +{ + char arg; + int kb_ok; + + arg = 0; + +#ifdef __linux__ + kb_ok = (ioctl (fd, KDGKBTYPE, &arg) == 0 + && ((arg == KB_101) || (arg == KB_84))); +#else + kb_ok = 1; +#endif + + return (isatty (fd) && kb_ok); +} + +static int +open_a_console (char *fnam) +{ + int fd; + + fd = open (fnam, O_RDONLY | O_NOCTTY); + if (fd < 0 && errno == EACCES) + fd = open (fnam, O_WRONLY | O_NOCTTY); + + if (fd < 0) + return -1; + + if (! ck_fd_is_a_console (fd)) { + close (fd); + fd = -1; + } + + return fd; +} + +int +ck_get_a_console_fd (void) +{ + int fd; + +#ifdef _PATH_TTY + fd = open_a_console (_PATH_TTY); + if (fd >= 0) + return fd; +#endif + + fd = open_a_console ("/dev/tty"); + if (fd >= 0) + return fd; + +#ifdef _PATH_CONSOLE + fd = open_a_console (_PATH_CONSOLE); + if (fd >= 0) + return fd; +#endif + + fd = open_a_console ("/dev/console"); + if (fd >= 0) + return fd; + + for (fd = 0; fd < 3; fd++) { + if (ck_fd_is_a_console (fd)) { + return fd; + } + } + + return -1; +} + +gboolean +ck_is_root_user (void) +{ +#ifndef G_OS_WIN32 + uid_t ruid, euid, suid; /* Real, effective and saved user ID's */ + gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */ + +#ifdef HAVE_GETRESUID + if (getresuid (&ruid, &euid, &suid) != 0 || + getresgid (&rgid, &egid, &sgid) != 0) +#endif /* HAVE_GETRESUID */ + { + suid = ruid = getuid (); + sgid = rgid = getgid (); + euid = geteuid (); + egid = getegid (); + } + + if (ruid == 0) { + return TRUE; + } + +#endif + return FALSE; +} diff --git a/src/ck-sysdeps.h b/src/ck-sysdeps.h index ce3fae9..86d4425 100644 --- a/src/ck-sysdeps.h +++ b/src/ck-sysdeps.h @@ -21,8 +21,14 @@ #ifndef __CK_SYSDEPS_H #define __CK_SYSDEPS_H +#include "config.h" + #include +#ifdef HAVE_PATHS_H +#include +#endif /* HAVE_PATHS_H */ + G_BEGIN_DECLS typedef struct _CkProcessStat CkProcessStat; @@ -50,6 +56,11 @@ gboolean ck_get_socket_peer_credentials (int socket_fd, uid_t *uid, GError **error); +int ck_get_a_console_fd (void); + +gboolean ck_fd_is_a_console (int fd); + +gboolean ck_is_root_user (void); G_END_DECLS diff --git a/src/ck-vt-monitor.c b/src/ck-vt-monitor.c index 40f834a..4291bdd 100644 --- a/src/ck-vt-monitor.c +++ b/src/ck-vt-monitor.c @@ -44,6 +44,7 @@ #include #include "ck-vt-monitor.h" +#include "ck-sysdeps.h" #include "ck-marshal.h" #define ERROR -1 @@ -430,8 +431,6 @@ ck_vt_monitor_class_init (CkVtMonitorClass *klass) g_type_class_add_private (klass, sizeof (CkVtMonitorPrivate)); } -extern int getfd (void); - static void ck_vt_monitor_init (CkVtMonitor *vt_monitor) { @@ -439,7 +438,7 @@ ck_vt_monitor_init (CkVtMonitor *vt_monitor) vt_monitor->priv = CK_VT_MONITOR_GET_PRIVATE (vt_monitor); - fd = getfd (); + fd = ck_get_a_console_fd (); vt_monitor->priv->vfd = fd; if (fd == ERROR) { diff --git a/src/getfd.c b/src/getfd.c deleted file mode 100644 index 8aa46ca..0000000 --- a/src/getfd.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Adapted from kbd-1.12 - * License: GPL - * - */ - -#include "config.h" - -#include -#include -#include -#include -#ifdef __linux__ -#include -#endif -#include - -#ifdef HAVE_PATHS_H -#include -#endif /* HAVE_PATHS_H */ - -/* - * getfd.c - * - * Get an fd for use with kbd/console ioctls. - * We try several things because opening /dev/console will fail - * if someone else used X (which does a chown on /dev/console). - */ - -static int -is_a_console (int fd) -{ - char arg; - int kb_ok; - - arg = 0; - -#ifdef __linux__ - kb_ok = (ioctl (fd, KDGKBTYPE, &arg) == 0 - && ((arg == KB_101) || (arg == KB_84))); -#else - kb_ok = 1; -#endif - - return (isatty (fd) && kb_ok); -} - -static int -open_a_console (char *fnam) -{ - int fd; - - fd = open (fnam, O_RDONLY | O_NOCTTY); - if (fd < 0 && errno == EACCES) - fd = open (fnam, O_WRONLY | O_NOCTTY); - - if (fd < 0) - return -1; - - if (! is_a_console (fd)) { - close (fd); - fd = -1; - } - - return fd; -} - -int getfd (void) -{ - int fd; - -#ifdef _PATH_TTY - fd = open_a_console (_PATH_TTY); - if (fd >= 0) - return fd; -#endif - - fd = open_a_console ("/dev/tty"); - if (fd >= 0) - return fd; - -#ifdef _PATH_CONSOLE - fd = open_a_console (_PATH_CONSOLE); - if (fd >= 0) - return fd; -#endif - - fd = open_a_console ("/dev/console"); - if (fd >= 0) - return fd; - - for (fd = 0; fd < 3; fd++) - if (is_a_console (fd)) - return fd; - - return -1; -} diff --git a/src/main.c b/src/main.c index 90856db..12ff51e 100644 --- a/src/main.c +++ b/src/main.c @@ -38,6 +38,7 @@ #include #include +#include "ck-sysdeps.h" #include "ck-manager.h" #include "ck-log.h" @@ -283,6 +284,11 @@ main (int argc, dbus_g_thread_init (); g_type_init (); + if (! ck_is_root_user ()) { + g_warning ("Must be run as root"); + exit (1); + } + context = g_option_context_new (_("Console kit daemon")); g_option_context_add_main_entries (context, entries, NULL); g_option_context_parse (context, &argc, &argv, NULL); diff --git a/src/test-tty-idle-monitor.c b/src/test-tty-idle-monitor.c index 8517f75..725505d 100644 --- a/src/test-tty-idle-monitor.c +++ b/src/test-tty-idle-monitor.c @@ -41,6 +41,7 @@ #include #include "ck-tty-idle-monitor.h" +#include "ck-sysdeps.h" static void idle_changed_cb (CkTtyIdleMonitor *monitor, @@ -55,8 +56,6 @@ is_console (const char *device) { int fd; gboolean ret; - int kb_ok; - char arg; ret = FALSE; fd = open (device, O_RDONLY | O_NOCTTY); @@ -64,14 +63,7 @@ is_console (const char *device) goto out; } -#ifdef __linux__ - kb_ok = (ioctl (fd, KDGKBTYPE, &arg) == 0 - && ((arg == KB_101) || (arg == KB_84))); -#else - kb_ok = 1; -#endif - - ret = (isatty (fd) && kb_ok); + ret = ck_fd_is_a_console (fd); close (fd); diff --git a/src/test-vt-monitor.c b/src/test-vt-monitor.c new file mode 100644 index 0000000..e660645 --- /dev/null +++ b/src/test-vt-monitor.c @@ -0,0 +1,83 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 William Jon McCann + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include "ck-vt-monitor.h" + +static void +activated_cb (CkVtMonitor *monitor, + guint num, + gpointer data) +{ + g_message ("VT %u activated", num); +} + +int +main (int argc, char **argv) +{ + GMainLoop *loop; + CkVtMonitor *monitor; + + if (! g_thread_supported ()) { + g_thread_init (NULL); + } + g_type_init (); + + if (! ck_is_root_user ()) { + g_warning ("Must be run as root"); + exit (1); + } + + g_message ("Testing the VT monitor.\n Should print messages when VT is switched."); + + monitor = ck_vt_monitor_new (); + + g_signal_connect (monitor, + "active-changed", + G_CALLBACK (activated_cb), + NULL); + + loop = g_main_loop_new (NULL, FALSE); + + g_main_loop_run (loop); + + g_object_unref (monitor); + + g_main_loop_unref (loop); + + return 0; +} -- cgit