diff options
| -rw-r--r-- | configure.ac | 2 | ||||
| -rw-r--r-- | src/Makefile.am | 1 | ||||
| -rw-r--r-- | src/ck-sysdeps-unix.c | 84 | ||||
| -rw-r--r-- | src/ck-sysdeps.h | 7 | ||||
| -rw-r--r-- | tools/ck-get-x11-display-device.c | 34 | ||||
| -rw-r--r-- | tools/ck-get-x11-server-pid.c | 31 | 
6 files changed, 107 insertions, 52 deletions
diff --git a/configure.ac b/configure.ac index fa4be49..d52a56d 100644 --- a/configure.ac +++ b/configure.ac @@ -40,6 +40,8 @@ X11_REQUIRED_VERSION=1.0.0  AC_CHECK_HEADERS(unistd.h)  AC_CHECK_HEADERS(paths.h) +AC_CHECK_FUNCS(getpeerucred getpeereid) +  AC_TYPE_UID_T  PKG_CHECK_MODULES(CONSOLE_KIT, diff --git a/src/Makefile.am b/src/Makefile.am index 948b247..244e39e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -29,6 +29,7 @@ noinst_LTLIBRARIES =            \  libck_la_SOURCES =		\  	ck-sysdeps.h		\ +	ck-sysdeps-unix.c	\  	$(NULL)  if CK_COMPILE_LINUX diff --git a/src/ck-sysdeps-unix.c b/src/ck-sysdeps-unix.c new file mode 100644 index 0000000..6520105 --- /dev/null +++ b/src/ck-sysdeps-unix.c @@ -0,0 +1,84 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2006 William Jon McCann <mccann@jhu.edu> + * + * 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 <stdlib.h> +#include <stdio.h> +#include <fcntl.h> +#include <unistd.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#ifdef HAVE_GETPEERUCRED +#include <ucred.h> +#endif + +#include "ck-sysdeps.h" + +gboolean +ck_get_socket_peer_credentials   (int      socket_fd, +                                  pid_t   *pid, +                                  uid_t   *uid, +                                  GError **error) +{ +        gboolean ret; +        uid_t    uid_read; +        pid_t    pid_read; + +        uid_read = 0; +        pid_read = 0; +        ret = FALSE; + +#ifdef SO_PEERCRED +        struct ucred cr; +        socklen_t cr_len; + +        cr_len = sizeof (cr); + +        if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 && cr_len == sizeof (cr)) { +                pid_read = cr.pid; +                uid_read = cr.uid; +                ret = TRUE; +        } else { +                g_warning ("Failed to getsockopt() credentials, returned len %d/%d: %s\n", +                           cr_len, +                           (int) sizeof (cr), +                           g_strerror (errno)); +        } +#elif defined(HAVE_GETPEERUCRED) +        ucred_t * ucred = NULL; +        if (getpeerucred (client_fd, &ucred) == 0) { +                pid_read = ucred_getpid (ucred); +                uid_read = ucred_geteuid (ucred); +                ret = TRUE; +        } else { +                g_warning ("Failed to getpeerucred() credentials: %s\n", +                           g_strerror (errno)); +        } +        if (ucred != NULL) { +                ucred_free (ucred); +        } +#else /* !SO_PEERCRED && !HAVE_GETPEERUCRED */ +        g_warning ("Socket credentials not supported on this OS\n"); +#endif + +        return ret; +} diff --git a/src/ck-sysdeps.h b/src/ck-sysdeps.h index 7a5f768..ce3fae9 100644 --- a/src/ck-sysdeps.h +++ b/src/ck-sysdeps.h @@ -44,6 +44,13 @@ GHashTable  *ck_unix_pid_get_env_hash         (pid_t           pid);  pid_t        ck_unix_pid_get_ppid             (pid_t           pid);  uid_t        ck_unix_pid_get_uid              (pid_t           pid); + +gboolean     ck_get_socket_peer_credentials   (int             socket_fd, +                                               pid_t          *pid, +                                               uid_t          *uid, +                                               GError        **error); + +  G_END_DECLS  #endif /* __CK_SYSDEPS_H */ diff --git a/tools/ck-get-x11-display-device.c b/tools/ck-get-x11-display-device.c index 92a7936..723d239 100644 --- a/tools/ck-get-x11-display-device.c +++ b/tools/ck-get-x11-display-device.c @@ -58,31 +58,6 @@ get_tty_for_pid (int pid)          return device;  } -static int -get_peer_pid (int fd) -{ -        int pid = -1; -#ifdef SO_PEERCRED -        struct ucred cr; -        socklen_t cr_len; - -        cr_len = sizeof (cr); - -        if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 && cr_len == sizeof (cr)) { -                /* paranoia check for peer running as root */ -                if (cr.uid == 0) { -                        pid = cr.pid; -                } -        } else { -                g_warning ("Failed to getsockopt() credentials, returned len %d/%d: %s\n", -                           cr_len, -                           (int) sizeof (cr), -                           g_strerror (errno)); -        } -#endif -        return pid; -} -  static Display *  display_init (const char *display_name)  { @@ -134,12 +109,13 @@ main (int    argc,          fd = ConnectionNumber (xdisplay);          if (fd > 0) { -                int pid; -                char *device; +                int      pid; +                char    *device; +                gboolean res;                  ret = 0; -                pid = get_peer_pid (fd); -                if (pid != -1) { +                res = ck_get_socket_peer_credentials (fd, &pid, NULL, NULL); +                if (res) {                          device = get_tty_for_pid (pid);                          if (device != NULL) {                                  printf ("%s\n", device); diff --git a/tools/ck-get-x11-server-pid.c b/tools/ck-get-x11-server-pid.c index cd48cd1..eedb9af 100644 --- a/tools/ck-get-x11-server-pid.c +++ b/tools/ck-get-x11-server-pid.c @@ -32,28 +32,7 @@  #include <X11/Xlib.h>  #include <glib.h> -static void -print_peer_pid (int fd) -{ -#ifdef SO_PEERCRED -        struct ucred cr; -        socklen_t cr_len; - -        cr_len = sizeof (cr); - -        if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 && cr_len == sizeof (cr)) { -                /* paranoia check for peer running as root */ -                if (cr.uid == 0) { -                        printf ("%u\n", cr.pid); -                } -        } else { -                g_warning ("Failed to getsockopt() credentials, returned len %d/%d: %s\n", -                           cr_len, -                           (int) sizeof (cr), -                           g_strerror (errno)); -        } -#endif -} +#include "ck-sysdeps.h"  static Display *  display_init (int *argc, char ***argv) @@ -92,8 +71,14 @@ main (int    argc,          fd = ConnectionNumber (xdisplay);          if (fd > 0) { +                int      pid; +                gboolean res; +                  ret = 0; -                print_peer_pid (fd); +                res = ck_get_socket_peer_credentials (fd, &pid, NULL, NULL); +                if (res) { +                        printf ("%u\n", pid); +                }          }  	return ret;  | 
