forked from enlightenment/enlightenment
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
This commit is contained in:
parent
99b8d84485
commit
90fe5a4d0d
|
@ -2,6 +2,7 @@
|
|||
/enlightenment
|
||||
/enlightenment_alert
|
||||
/enlightenment_backlight
|
||||
/enlightenment_ckpasswd
|
||||
/enlightenment_fm_op
|
||||
/enlightenment_filemanager
|
||||
/enlightenment_imc
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue