[gnome-screensaver] Implement OpenBSD authentication using bsd_auth(3).



commit d7ab99c00a01bea870cf51d855ecf320e0d23bac
Author: Antoine Jacoutot <ajacoutot openbsd org>
Date:   Wed Nov 30 12:02:48 2011 +0100

    Implement OpenBSD authentication using bsd_auth(3).
    
    https://bugzilla.gnome.org/show_bug.cgi?id=651554
    OpenBSD does not have nor use pam(8) for password authentication but
    instead uses bsd_auth(3): add a bsd_auth authentication scheme to
    make locking possible.
    
    With inputs and review from Colin Walters and Matthias Clasen.

 configure.ac          |   56 +++++++++++++++++++++++++--
 src/Makefile.am       |   11 +++--
 src/gs-auth-bsdauth.c |  102 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/setuid.c          |   18 +++++++++
 4 files changed, 179 insertions(+), 8 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 4c0e039..a4f990f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -448,6 +448,45 @@ if test "$ac_macosx" = yes; then
 fi
 
 dnl ---------------------------------------------------------------------------
+dnl - Check for bsd_auth(3) (OpenBSD)
+dnl ---------------------------------------------------------------------------
+
+have_bsdauth=no
+with_bsdauth_req=unspecified
+NEED_SETUID=no
+
+case "$host" in                                                                                       
+  *-openbsd*)                                                                                         
+    with_bsdauth=yes
+    AUTH_SCHEME=bsdauth
+    NEED_SETUID=no
+    if test "x$enable_locking" = "xyes"; then
+      with_bsdauth_req=yes
+      NEED_SETUID=yes
+    fi
+esac  
+
+if test "$with_bsdauth" = yes ; then
+  AC_CACHE_CHECK([for BSD Authentication], ac_cv_bsdauth,
+    [AC_TRY_X_COMPILE([#include <stdlib.h>
+                       #include <unistd.h>
+                       #include <sys/types.h>
+                       #include <bsd_auth.h>],
+      [int ok = auth_userokay("x", 0, "x", "x");],
+      [ac_cv_bsdauth=yes],
+      [ac_cv_bsdauth=no])])
+  if test "$ac_cv_bsdauth" = yes; then
+    have_bsdauth=yes
+  fi
+fi
+
+if test "$have_bsdauth" = yes; then
+  AC_DEFINE(HAVE_BSDAUTH, 1, [Define to 1 if using bsd_auth(3) authentication])
+fi
+
+AC_SUBST(NEED_SETUID)
+
+dnl ---------------------------------------------------------------------------
 dnl - Check for PAM
 dnl ---------------------------------------------------------------------------
 
@@ -467,12 +506,13 @@ fi
 AC_SUBST(PAM_PREFIX)
 
 have_pam=no
-if test "x$enable_locking" = "xyes"; then
+if test "x$enable_locking" = "xyes" -a "x$have_bsdauth" = "xno"; then
 AC_CHECK_LIB(pam, pam_start, have_pam=yes)
 fi
 
 if test "x$have_pam" = "xyes"; then
         AUTH_LIBS="${AUTH_LIBS} -lpam"
+        AUTH_SCHEME=pam
         # On Linux, sigtimedwait() is in libc; on Solaris, it's in librt.
         have_timedwait=no
         AC_CHECK_LIB(c, sigtimedwait, [have_timedwait=yes])
@@ -506,14 +546,17 @@ if test "x$have_pam" = "xyes"; then
           AC_MSG_RESULT(unknown)
         fi
 
-else
+elif test "x$have_bsdauth" = "xno"; then
 	AC_MSG_ERROR("PAM libraries not found")
 fi
 AC_SUBST(HAVE_PAM)
 AC_SUBST(AUTH_LIBS)
+AC_SUBST(AUTH_SCHEME)
 
-AC_CHECK_HEADERS([security/pam_modutil.h security/pam_ext.h])
-AC_CHECK_LIB(pam, pam_syslog, [AC_DEFINE(HAVE_PAM_SYSLOG, [], [Define to 1 if you have the pam_syslog function])])
+if test "x$have_pam" = "xyes"; then
+  AC_CHECK_HEADERS([security/pam_modutil.h security/pam_ext.h])
+  AC_CHECK_LIB(pam, pam_syslog, [AC_DEFINE(HAVE_PAM_SYSLOG, [], [Define to 1 if you have the pam_syslog function])])
+fi
 
 dnl test whether struct pam_message is const (Linux) or not (Sun)
 if test "x$have_pam" = "xyes"; then
@@ -695,7 +738,12 @@ echo "
 
         Screen locking enabled:   ${enable_locking}
         Show keyboard indicator:  ${with_kbd_layout_indicator}
+"
+
+if test "x$have_pam" = "xyes" ; then
+echo "\
         PAM prefix:               ${PAM_PREFIX}
 
 "
+fi
 
diff --git a/src/Makefile.am b/src/Makefile.am
index a3dcf57..0f07b36 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -60,6 +60,10 @@ gnome_screensaver_command_LDADD =	\
 	$(GNOME_SCREENSAVER_COMMAND_LIBS)	\
 	$(NULL)
 
+AUTH_SOURCES =				\
+	gs-auth- AUTH_SCHEME@.c		\
+	$(NULL)
+
 test_fade_SOURCES = 			\
 	test-fade.c 			\
 	gs-fade.c	 		\
@@ -76,7 +80,7 @@ test_fade_LDADD =			\
 test_passwd_SOURCES = 			\
 	test-passwd.c 			\
 	gs-auth.h			\
-	gs-auth-pam.c			\
+	$(AUTH_SOURCES)			\
 	setuid.c			\
 	setuid.h			\
 	subprocs.c			\
@@ -134,7 +138,7 @@ gnome_screensaver_dialog_SOURCES = 	\
 	subprocs.c			\
 	subprocs.h			\
 	gs-auth.h			\
-	gs-auth-pam.c			\
+	$(AUTH_SOURCES)			\
 	$(NULL)
 
 gnome_screensaver_dialog_LDADD =	\
@@ -210,8 +214,7 @@ install-exec-hook:
 	@if [ "x NEED_SETUID@" = "xyes" ]; then \
 	    echo "***" ; \
 	    echo "***  Warning: gnome-screensaver has been compiled with support for" ; \
-	    echo "***           shadow passwords.  If your system actually uses shadow" ; \
-	    echo "***           passwords then it must be installed as a setuid root" ; \
+	    echo "***           bsdauth(3) and must be installed as a setuid root" ; \
 	    echo "***           program in order for locking to work.  To do this, you" ; \
 	    echo "***           must run:" ; \
 	    echo "***" ; \
diff --git a/src/gs-auth-bsdauth.c b/src/gs-auth-bsdauth.c
new file mode 100644
index 0000000..f6cdb28
--- /dev/null
+++ b/src/gs-auth-bsdauth.c
@@ -0,0 +1,102 @@
+/* $OpenBSD: gs-auth-bsdauth.c,v 1.3 2011/09/12 07:28:54 jasper Exp $
+ * gs-auth-bsdauth.c --- verifying typed passwords with bsd_auth(3)
+ *
+ * Copyright (c) 1993-1998 Jamie Zawinski <jwz jwz org>
+ * Copyright (C) 2006 William Jon McCann <mccann jhu edu>
+ * Copyright (c) 2009 Antoine Jacoutot <ajacoutot openbsd org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <pwd.h>
+#include <sys/types.h>
+
+#include <login_cap.h>
+#include <bsd_auth.h>
+
+#include "gs-auth.h"
+#include "subprocs.h"
+
+static gboolean verbose_enabled = FALSE;
+
+GQuark
+gs_auth_error_quark (void)
+{
+	static GQuark quark = 0;
+	if (! quark) {
+		quark = g_quark_from_static_string ("gs_auth_error");
+	}
+
+	return quark;
+}
+
+void
+gs_auth_set_verbose (gboolean enabled)
+{
+	verbose_enabled = enabled;
+}
+
+gboolean
+gs_auth_get_verbose (void)
+{
+	return verbose_enabled;
+}
+
+gboolean
+gs_auth_verify_user (const char       *username,
+                     const char       *display, 
+                     GSAuthMessageFunc func,
+                     gpointer          data,
+                     GError          **error)
+{
+	int res;
+	char *password;
+
+	/* ask for the password for user */
+	if (func != NULL) {
+		func (GS_AUTH_MESSAGE_PROMPT_ECHO_OFF,
+		    "Password: ",
+		    &password,
+		    data);
+	}
+
+	if (password == NULL) {
+		return FALSE;
+	}
+
+	/* authenticate */
+	res = auth_userokay((char *)username, NULL, "auth-gnome-screensaver", password);
+
+	return res;
+}
+
+gboolean
+gs_auth_init (void)
+{
+	return TRUE;
+}
+
+gboolean
+gs_auth_priv_init (void)
+{
+	return TRUE;
+}
diff --git a/src/setuid.c b/src/setuid.c
index adb3503..695c48a 100644
--- a/src/setuid.c
+++ b/src/setuid.c
@@ -194,6 +194,23 @@ hack_uid (char **nolock_reason,
                         *orig_uid = uid_gid_string (euid, egid);
                 }
 
+#ifdef HAVE_BSDAUTH /* we need to setgid auth to run the bsd_auth(3) login_* helpers */
+                {
+                        struct group *authg = getgrnam("auth");
+                        if (!authg || !authg->gr_name || !*authg->gr_name) {
+                                        reason = g_strdup ("no such group as \"auth\" for bsdauth.");
+
+                                        ret = FALSE;
+                                        goto out;
+                        }
+                        if (! set_ids_by_number (uid, authg->gr_gid, uid_message)) {
+                                        reason = g_strdup ("cannot setgid \"auth\" for bsdauth.");
+
+                                        ret = FALSE;
+                                        goto out;
+                        }
+                }
+#else /* !HAVE_BSDAUTH */
                 if (uid != euid || gid != egid) {
                         if (! set_ids_by_number (uid, gid, uid_message)) {
                                 reason = g_strdup ("unable to discard privileges.");
@@ -202,6 +219,7 @@ hack_uid (char **nolock_reason,
                                 goto out;
                         }
                 }
+#endif
         }
 
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]