q66 pushed a commit to branch master.

http://git.enlightenment.org/core/enlightenment.git/commit/?id=90fe5a4d0dc75f25f08459ca5e40bd720cdcd6c0

commit 90fe5a4d0dc75f25f08459ca5e40bd720cdcd6c0
Author: Conrad Meyer <cse....@gmail.com>
Date:   Tue Apr 21 13:11:56 2015 +0100

    e_auth: Add suid helper for lokker own-pw checking on FreeBSD
    
    Summary:
    PAM on FreeBSD, unlike on Linux, does not allow users to check their own
    password. Instead, we need a suid helper to do it for us. Add such a
    helper on FreeBSD.
    
    For now, it is limited to checking users in the local password database
    (traditional Unix passwd file). This could and should be extended to use
    PAM in a later patch.
    
    Test Plan:
    Tested empty pw, wrong pw, correct pw at lock screen; observed correct 
behavior
    in each instance.
    
    Reviewers: q66, zmike
    
    Reviewed By: q66, zmike
    
    Subscribers: cedric, seoz
    
    Differential Revision: https://phab.enlightenment.org/D2355
---
 src/bin/.gitignore        |  1 +
 src/bin/Makefile.mk       | 14 ++++++++
 src/bin/e_auth.c          | 41 +++++++++++++++++++++---
 src/bin/e_ckpasswd_main.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 133 insertions(+), 4 deletions(-)

diff --git a/src/bin/.gitignore b/src/bin/.gitignore
index df39011..7addf4d 100644
--- a/src/bin/.gitignore
+++ b/src/bin/.gitignore
@@ -2,6 +2,7 @@
 /enlightenment
 /enlightenment_alert
 /enlightenment_backlight
+/enlightenment_ckpasswd
 /enlightenment_fm_op
 /enlightenment_filemanager
 /enlightenment_imc
diff --git a/src/bin/Makefile.mk b/src/bin/Makefile.mk
index 5afdb4a..ecc6f7b 100644
--- a/src/bin/Makefile.mk
+++ b/src/bin/Makefile.mk
@@ -36,6 +36,9 @@ src/bin/enlightenment_static_grabber
 if ! HAVE_WAYLAND_ONLY
 internal_bin_PROGRAMS += src/bin/enlightenment_alert
 endif
+if HAVE_FREEBSD
+internal_bin_PROGRAMS += src/bin/enlightenment_ckpasswd
+endif
 
 ENLIGHTENMENTHEADERS = \
 src/bin/e_about.h \
@@ -423,6 +426,14 @@ src/bin/e_backlight_main.c
 src_bin_enlightenment_backlight_CPPFLAGS = @SUID_CFLAGS@ @EEZE_CFLAGS@
 src_bin_enlightenment_backlight_LDADD = @SUID_LDFLAGS@ @EEZE_LIBS@
 
+if HAVE_FREEBSD
+src_bin_enlightenment_ckpasswd_SOURCES = \
+src/bin/e_ckpasswd_main.c
+
+src_bin_enlightenment_ckpasswd_CPPFLAGS = @SUID_CFLAGS@
+src_bin_enlightenment_ckpasswd_LDADD = @SUID_LDFLAGS@ -lcrypt
+endif
+
 src_bin_enlightenment_alert_SOURCES = \
 src/bin/e_alert_main.c
 
@@ -453,6 +464,9 @@ setuid_root_mode = a=rx,u+xs
 enlightenment-sys-install-data-hook:
        @chmod $(setuid_root_mode) 
$(DESTDIR)$(libdir)/enlightenment/utils/enlightenment_sys$(EXEEXT) || true
        @chmod $(setuid_root_mode) 
$(DESTDIR)$(libdir)/enlightenment/utils/enlightenment_backlight$(EXEEXT) || true
+if HAVE_FREEBSD
+       @chmod $(setuid_root_mode) 
$(DESTDIR)$(libdir)/enlightenment/utils/enlightenment_ckpasswd$(EXEEXT) || true
+endif
 installed_headersdir = $(prefix)/include/enlightenment
 installed_headers_DATA = $(ENLIGHTENMENTHEADERS) src/bin/e_fm_shared_types.h
 INSTALL_DATA_HOOKS += enlightenment-sys-install-data-hook
diff --git a/src/bin/e_auth.c b/src/bin/e_auth.c
index a85df6b..6d23d8b 100644
--- a/src/bin/e_auth.c
+++ b/src/bin/e_auth.c
@@ -1,6 +1,6 @@
 #include "e.h"
 
-#ifdef HAVE_PAM
+#if defined(HAVE_PAM) && !defined(__FreeBSD__)
 # include <security/pam_appl.h>
 # include <pwd.h>
 
@@ -128,11 +128,44 @@ _auth_pam_init(E_Auth *da)
    free(current_host);
    return 0;
 }
-
-#endif
+#endif  // HAVE_PAM && !__FreeBSD__
 
 EAPI int
-#ifdef HAVE_PAM
+#if defined(__FreeBSD__)
+e_auth_begin(char *passwd)
+{
+   char buf[PATH_MAX], *p;
+   Ecore_Exe *exe = NULL;
+   int ret = 0;
+
+   if (strlen(passwd) == 0) goto out;
+
+   snprintf(buf, sizeof(buf), "%s/enlightenment/utils/enlightenment_ckpasswd",
+            e_prefix_lib_get());
+
+   exe = ecore_exe_pipe_run(buf, ECORE_EXE_PIPE_WRITE, NULL);
+   if (ecore_exe_send(exe, passwd, strlen(passwd)) != EINA_TRUE) goto out;
+   ecore_exe_close_stdin(exe);
+
+   ret = ecore_exe_pid_get(exe);
+   if (ret == -1)
+     {
+        ret = 0;
+        goto out;
+     }
+
+   exe = NULL;
+out:
+   if (exe) ecore_exe_free(exe);
+
+   /* security - null out passwd string once we are done with it */
+   for (p = passwd; *p; p++)
+     *p = 0;
+   if (passwd[0] || passwd[3]) fprintf(stderr, "ACK!\n");
+
+   return ret;
+}
+#elif defined(HAVE_PAM)
 e_auth_begin(char *passwd)
 {
    /* child */
diff --git a/src/bin/e_ckpasswd_main.c b/src/bin/e_ckpasswd_main.c
new file mode 100644
index 0000000..c2508a7
--- /dev/null
+++ b/src/bin/e_ckpasswd_main.c
@@ -0,0 +1,81 @@
+#include <sys/types.h>
+
+#include <err.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <security/pam_constants.h>
+
+// Exit codes, per src/modules/lokker/lokker.c:
+// 0: success (unlock)
+// 1-128: PAM error but also unlock (!!!)
+// else: failed.
+
+static char pw[4096];
+struct passwd *pwent;
+
+static void
+zeropw(void)
+{
+   /* security - null out passwd string once we are done with it */
+   memset(pw, 0, sizeof(pw));
+   if (pw[0] || pw[3]) printf("ACK!\n");
+
+   if (pwent == NULL) return;
+   if (pwent->pw_passwd == NULL) return;
+
+   /* security - null out passwd string once we are done with it */
+   memset(pwent->pw_passwd, 0, strlen(pwent->pw_passwd));
+   if (pwent->pw_passwd[0]) printf("ACK!\n");
+}
+
+int
+main(int argc, char **argv)
+{
+   ssize_t rd;
+   uid_t id;
+   int i;
+
+   for (i = 1; i < argc; i++)
+     {
+        if ((!strcmp(argv[i], "-h")) ||
+            (!strcmp(argv[i], "-help")) ||
+            (!strcmp(argv[i], "--help")))
+          {
+             printf("This is an internal tool for Enlightenment.\n"
+                    "do not use it.\n");
+             exit(129);
+          }
+     }
+   if (argc != 1)
+     exit(130);
+
+   id = getuid();
+
+   if (atexit(zeropw)) err(131, "atexit");
+
+   rd = read(0, pw, sizeof(pw) - 1);
+   if (rd < 0) err(132, "read");
+
+   if (setuid(0) != 0)
+     {
+        printf("ERROR: UNABLE TO ASSUME ROOT PRIVILEGES\n");
+        exit(133);
+     }
+   if (setgid(0) != 0)
+     {
+        printf("ERROR: UNABLE TO ASSUME ROOT GROUP PRIVILEGES\n");
+        exit(134);
+     }
+
+   pwent = getpwuid(id);
+   if (pwent == NULL) return -2;
+
+   if (strcmp(crypt(pw, pwent->pw_passwd), pwent->pw_passwd) == 0)
+     return 0;
+
+   return -1;
+}

-- 


Reply via email to