Репозиторий Sisyphus
Последнее обновление: 1 октября 2023 | Пакетов: 18631 | Посещений: 37568962
en ru br
Репозитории ALT
S:0.25.4-alt1
5.1: 0.16.8.9-alt1
4.1: 0.16.8.9-alt1
3.0: 0.16.7-alt1_2
www.altlinux.org/Changes

Группа :: Графические оболочки/Enlightenment
Пакет: enlightenment

 Главная   Изменения   Спек   Патчи   Sources   Загрузить   Gear   Bugs and FR  Repocop 

Патч: enlightenment-0.22.2-up-auth.patch
Скачать


commit 3c4e25360eb65d0bc9dbfbc2d697898d5b42280d
Author: Carsten Haitzler (Rasterman) <raster@rasterman.com>
Date:   Mon Feb 26 19:01:46 2018 +0900
    e auth - move all auth to child process only (e_ckpasswd).
    
    this should fix T6211 ensuring no drivers can cause a segfault at exit
    time. this also happens to remove the enlightenment_sys -z option for
    openbsd and unifies all the passwd checking into the single
    enlightenment_ckpasswd binary util (that has ifdefs for openbsd,
    freebsd and linux pam in it).
    
    this simplifies code removing a mess of auth being done in multiple
    places, removes special fork vs run 1 exe or a different exe in
    different cases making it more maintainable. yes - this requires
    enlightenment_ckpasswd to be setuid root, but it already was when it
    was built.
    
    @fix
diff --git a/src/bin/e_auth.c b/src/bin/e_auth.c
index 2fabc25..00b0e5d 100644
--- a/src/bin/e_auth.c
+++ b/src/bin/e_auth.c
@@ -1,137 +1,6 @@
 #include "e.h"
 
-#if defined(HAVE_PAM) && !defined(__FreeBSD__)  && !defined(__OpenBSD__)
-# include <security/pam_appl.h>
-# include <pwd.h>
-
-
-typedef struct E_Auth
-{
-   struct
-   {
-      struct pam_conv conv;
-      pam_handle_t   *handle;
-   } pam;
-
-   char user[4096];
-   char passwd[4096];
-} E_Auth;
-
-static pid_t _e_auth_child_pid = -1;
-
-static char *
-_auth_auth_get_current_user(void)
-{
-   char *user;
-   struct passwd *pwent = NULL;
-
-   pwent = getpwuid(getuid());
-   if (!pwent) return NULL;
-   user = strdup(pwent->pw_name);
-   return user;
-}
-
-static int
-_auth_auth_pam_conv(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr)
-{
-   int replies = 0;
-   E_Auth *da = (E_Auth *)appdata_ptr;
-   struct pam_response *reply = NULL;
-
-   reply = (struct pam_response *)malloc(sizeof(struct pam_response) * num_msg);
-
-   if (!reply) return PAM_CONV_ERR;
-
-   for (replies = 0; replies < num_msg; replies++)
-     {
-        switch (msg[replies]->msg_style)
-          {
-           case PAM_PROMPT_ECHO_ON:
-             reply[replies].resp_retcode = PAM_SUCCESS;
-             reply[replies].resp = strdup(da->user);
-             break;
-
-           case PAM_PROMPT_ECHO_OFF:
-             reply[replies].resp_retcode = PAM_SUCCESS;
-             reply[replies].resp = strdup(da->passwd);
-             break;
-
-           case PAM_ERROR_MSG:
-           case PAM_TEXT_INFO:
-             reply[replies].resp_retcode = PAM_SUCCESS;
-             reply[replies].resp = NULL;
-             break;
-
-           default:
-             free(reply);
-             return PAM_CONV_ERR;
-          }
-     }
-   *resp = reply;
-   return PAM_SUCCESS;
-}
-
-static int
-_auth_pam_init(E_Auth *da)
-{
-   int pamerr;
-   const char *pam_prof;
-   char *current_host;
-   char *current_user;
-
-   if (!da) return -1;
-
-   da->pam.conv.conv = _auth_auth_pam_conv;
-   da->pam.conv.appdata_ptr = da;
-   da->pam.handle = NULL;
-
-   /* try other pam profiles - and system-auth (login for fbsd users) is a fallback */
-   pam_prof = "login";
-   if (ecore_file_exists("/etc/pam.d/enlightenment"))
-     pam_prof = "enlightenment";
-   else if (ecore_file_exists("/etc/pam.d/xscreensaver"))
-     pam_prof = "xscreensaver";
-   else if (ecore_file_exists("/etc/pam.d/kscreensaver"))
-     pam_prof = "kscreensaver";
-   else if (ecore_file_exists("/etc/pam.d/system-auth"))
-     pam_prof = "system-auth";
-   else if (ecore_file_exists("/etc/pam.d/system"))
-     pam_prof = "system";
-   else if (ecore_file_exists("/etc/pam.d/xdm"))
-     pam_prof = "xdm";
-   else if (ecore_file_exists("/etc/pam.d/gdm"))
-     pam_prof = "gdm";
-   else if (ecore_file_exists("/etc/pam.d/kdm"))
-     pam_prof = "kdm";
-
-   if ((pamerr = pam_start(pam_prof, da->user, &(da->pam.conv),
-                           &(da->pam.handle))) != PAM_SUCCESS)
-     return pamerr;
-
-   current_user = _auth_auth_get_current_user();
-
-   if ((pamerr = pam_set_item(da->pam.handle, PAM_USER, current_user)) != PAM_SUCCESS)
-     {
-        free(current_user);
-        return pamerr;
-     }
-
-   current_host = e_auth_hostname_get();
-   if ((pamerr = pam_set_item(da->pam.handle, PAM_RHOST, current_host)) != PAM_SUCCESS)
-     {
-        free(current_user);
-        free(current_host);
-        return pamerr;
-     }
-
-   free(current_user);
-   free(current_host);
-   return 0;
-}
-#endif  // HAVE_PAM && !__FreeBSD__ && !_OpenBSD__
-
 E_API int
-#if defined(__FreeBSD__)
 e_auth_begin(char *passwd)
 {
    char buf[PATH_MAX], *p;
@@ -159,109 +28,8 @@ 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;
+   for (p = passwd; *p; p++) *p = 0;
    if (passwd[0] || passwd[3]) fprintf(stderr, "ACK!\n");
 
    return ret;
 }
-#elif defined(__OpenBSD__)
-e_auth_begin(char *passwd)
-{
-   char exe_path[PATH_MAX], *p;
-   Ecore_Exe *exe = NULL;
-   int ret = 0;
-   int len = strlen(passwd);
-
-   if (len == 0) goto out;
-
-   snprintf(exe_path, sizeof(exe_path), "%s/enlightenment/utils/enlightenment_sys -z",
-            e_prefix_lib_get());
-
-   exe = ecore_exe_pipe_run(exe_path, ECORE_EXE_PIPE_WRITE, NULL);
-   if (!exe) goto out;
-   if (ecore_exe_send(exe, passwd, len) != EINA_TRUE) goto out;
-   if (ecore_exe_send(exe, "\n", 1) != 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);
-
-   for (p = passwd; *p; p++)
-     *p = 0;
-
-   return ret;
-}
-#elif defined(HAVE_PAM)
-e_auth_begin(char *passwd)
-{
-   /* child */
-   int pamerr;
-   E_Auth da;
-   char *current_user;
-   struct sigaction action;
-
-   _e_auth_child_pid = fork();
-   if (_e_auth_child_pid > 0) return _e_auth_child_pid;
-   if (_e_auth_child_pid < 0) return -1;
-
-   action.sa_handler = SIG_DFL;
-   action.sa_flags = SA_ONSTACK | SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
-   sigemptyset(&action.sa_mask);
-   sigaction(SIGSEGV, &action, NULL);
-   sigaction(SIGILL, &action, NULL);
-   sigaction(SIGFPE, &action, NULL);
-   sigaction(SIGBUS, &action, NULL);
-   sigaction(SIGABRT, &action, NULL);
-
-   current_user = _auth_auth_get_current_user();
-   eina_strlcpy(da.user, current_user, sizeof(da.user));
-   eina_strlcpy(da.passwd, passwd, sizeof(da.passwd));
-   /* security - null out passwd string once we are done with it */
-   e_util_memclear(passwd, strlen(passwd));
-
-   da.pam.handle = NULL;
-   da.pam.conv.conv = NULL;
-   da.pam.conv.appdata_ptr = NULL;
-
-   pamerr = _auth_pam_init(&da);
-   if (pamerr != PAM_SUCCESS)
-     {
-        free(current_user);
-        _exit(1);
-     }
-   pamerr = pam_authenticate(da.pam.handle, 0);
-   pam_end(da.pam.handle, pamerr);
-   /* security - null out passwd string once we are done with it */
-   e_util_memclear(da.passwd, sizeof(da.passwd));
-
-   if (pamerr == PAM_SUCCESS)
-     {
-        free(current_user);
-        _exit(0);
-     }
-   free(current_user);
-   _exit(-1);
-
-   return 0;
-}
-#else
-e_auth_begin(char *passwd EINA_UNUSED)
-{
-   return 0;
-}
-#endif
-
-E_API char *
-e_auth_hostname_get(void)
-{
-   return strdup("localhost");
-}
diff --git a/src/bin/e_auth.h b/src/bin/e_auth.h
index a91f064..2ca2837 100644
--- a/src/bin/e_auth.h
+++ b/src/bin/e_auth.h
@@ -2,7 +2,6 @@
 #define E_AUTH_H
 
 E_API int e_auth_begin(char *passwd);
-E_API char *e_auth_hostname_get(void);
 
 static inline int
 e_auth_hash_djb2(const char *key, int len)
diff --git a/src/bin/e_ckpasswd_main.c b/src/bin/e_ckpasswd_main.c
index c2508a7..8b6479a 100644
--- a/src/bin/e_ckpasswd_main.c
+++ b/src/bin/e_ckpasswd_main.c
@@ -1,81 +1,217 @@
-#include <sys/types.h>
+#include "config.h"
+
+#define __USE_MISC
+#define _SVID_SOURCE
+#define _DEFAULT_SOURCE
 
-#include <err.h>
-#include <pwd.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <string.h>
 #include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <pwd.h>
+#ifdef HAVE_ALLOCA_H
+#include <alloca.h>
+#endif
+
+#if defined(__OpenBSD__)
+
+static int
+_check_auth(uid_t uid, const char *guess)
+{
+   struct passwd *pwent;
+
+   pwent = getpwuid_shadow(uid);
+   if (!pwent) return -1;
+   if (!pwent->pw_passwd) return -1;
+
+   return crypt_checkpass(guess, pw_ent->pw_passwd);
+}
+
+
+
 
+
+#elif defined(__FreeBSD__)
 #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 int
+_check_auth(uid_t uid, const char *pw)
+{
+   struct passwd *pwent = getpwuid(uid);
+
+   if (!pwent) return -1;
+   if (!pwent->pw_passwd) return -1;
+
+   if (!strcmp(crypt(pw, pwent->pw_passwd), pwent->pw_passwd)) return 0;
+   return -1;
+}
+
+
+
+
+
+#elif defined(HAVE_PAM)
+# include <security/pam_appl.h>
+
+typedef struct
+{
+   const char *user;
+   const char *pw;
+} Authinfo;
+
+static int
+_conv_cb(int num, const struct pam_message **msg, struct pam_response **resp, void *data)
+{
+   Authinfo *ai = data;
+   int replies;
+   struct pam_response *reply = NULL;
+
+   reply = malloc(sizeof(struct pam_response) * num);
+   if (!reply) return PAM_CONV_ERR;
 
-static char pw[4096];
-struct passwd *pwent;
+   for (replies = 0; replies < num; replies++)
+     {
+        switch (msg[replies]->msg_style)
+          {
+           case PAM_PROMPT_ECHO_ON:
+             reply[replies].resp_retcode = PAM_SUCCESS;
+             reply[replies].resp = strdup(ai->user);
+             break;
+           case PAM_PROMPT_ECHO_OFF:
+             reply[replies].resp_retcode = PAM_SUCCESS;
+             reply[replies].resp = strdup(ai->pw);
+             break;
+           case PAM_ERROR_MSG:
+           case PAM_TEXT_INFO:
+             reply[replies].resp_retcode = PAM_SUCCESS;
+             reply[replies].resp = NULL;
+             break;
+           default:
+             free(reply);
+             return PAM_CONV_ERR;
+          }
+     }
+   *resp = reply;
+   return PAM_SUCCESS;
+}
 
-static void
-zeropw(void)
+static int
+_check_auth(uid_t uid, const char *pw)
 {
-   /* security - null out passwd string once we are done with it */
-   memset(pw, 0, sizeof(pw));
-   if (pw[0] || pw[3]) printf("ACK!\n");
+   Authinfo ai;
+   struct passwd *pwent;
+   const char *user;
+   const char *prof;
+   const char *host;
+   struct stat st;
+   pam_handle_t *handle;
+   int pamerr;
+   struct pam_conv conv;
+
+   pwent = getpwuid(uid);
+   if (!pwent) return -1;
+   user = pwent->pw_name;
+   if (!user) return -1;
+
+   host = "localhost";
+
+   prof = "login";
+   if      (!stat("/etc/pam.d/enlightenment", &st)) prof = "enlightenment";
+   else if (!stat("/etc/pam.d/xscreensaver", &st))  prof = "xscreensaver";
+   else if (!stat("/etc/pam.d/kscreensaver", &st))  prof = "kscreensaver";
+   else if (!stat("/etc/pam.d/system-auth", &st))   prof = "system-auth";
+   else if (!stat("/etc/pam.d/system", &st))        prof = "system";
+   else if (!stat("/etc/pam.d/xdm", &st))           prof = "xdm";
+   else if (!stat("/etc/pam.d/gdm", &st))           prof = "gdm";
+   else if (!stat("/etc/pam.d/kdm", &st))           prof = "kdm";
+
+   ai.user = user;
+   ai.pw = pw;
+
+   conv.conv = _conv_cb;
+   conv.appdata_ptr = &ai;
+   if (pam_start(prof, user, &conv, &handle) != PAM_SUCCESS) return -1;
+   if (pam_set_item(handle, PAM_USER, user) != PAM_SUCCESS) return -1;
+   if (pam_set_item(handle, PAM_RHOST, host) != PAM_SUCCESS) return -1;
+
+   pamerr = pam_authenticate(handle, 0);
+   pam_end(handle, pamerr);
+
+   if (pamerr != PAM_SUCCESS) return -1;
+
+   return 0;
+}
+
+
 
-   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");
+
+#else
+
+static int
+_check_auth(uid_t uid, const char *pw)
+{
+   return -1;
 }
 
+
+
+
+
+#endif
+
 int
 main(int argc, char **argv)
 {
    ssize_t rd;
    uid_t id;
-   int i;
+   char pw[4096], *p;
 
-   for (i = 1; i < argc; i++)
+   if (argc != 1)
      {
-        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);
-          }
+        int i;
+
+        for (i = 1; i < argc; i++)
+          fprintf(stderr, "Unknown option %s\n", argv[i]);
+        fprintf(stderr,
+                "This is an internal tool for Enlightenment\n");
+        goto err;
      }
-   if (argc != 1)
-     exit(130);
 
+   // get uid who ran this
    id = getuid();
 
-   if (atexit(zeropw)) err(131, "atexit");
-
+   // read passwd from stdin
    rd = read(0, pw, sizeof(pw) - 1);
-   if (rd < 0) err(132, "read");
-
-   if (setuid(0) != 0)
+   if (rd < 0)
      {
-        printf("ERROR: UNABLE TO ASSUME ROOT PRIVILEGES\n");
-        exit(133);
+        fprintf(stderr,
+                "Error. Can't read passwd on stdin\n");
+        goto err;
      }
-   if (setgid(0) != 0)
+   pw[rd] = 0;
+   for (p = pw; *p; p++)
      {
-        printf("ERROR: UNABLE TO ASSUME ROOT GROUP PRIVILEGES\n");
-        exit(134);
+        if ((*p == '\r') || (*p == '\n'))
+          {
+             *p = 0;
+             break;
+          }
      }
 
-   pwent = getpwuid(id);
-   if (pwent == NULL) return -2;
-
-   if (strcmp(crypt(pw, pwent->pw_passwd), pwent->pw_passwd) == 0)
-     return 0;
-
+   // If we are setuid root then try become root - we can work without though
+   // if pam etc. can work without being root
+   if (setuid(0) != 0)
+     fprintf(stderr,
+             "Warning. Can't become user root. If password auth requires root then this will fail\n");
+   if (setgid(0) != 0)
+     fprintf(stderr,
+             "Warning. Can't become group root. If password auth requires root then this will fail\n");
+   if (_check_auth(id, pw) == 0) return 0;
+err:
+   fprintf(stderr,
+           "Password auth fail\n");
    return -1;
 }
diff --git a/src/bin/e_desklock.c b/src/bin/e_desklock.c
index 8a1214a..7b99fcc 100644
--- a/src/bin/e_desklock.c
+++ b/src/bin/e_desklock.c
@@ -268,16 +268,6 @@ e_desklock_show(Eina_Bool suspend)
         return 1;
      }
 
-#if ! defined(HAVE_PAM) && ! defined(__OpenBSD__)
-   if (e_desklock_is_system())
-     {
-        e_util_dialog_show(_("Error - no PAM support"),
-                           _("No PAM support was built into Enlightenment, so<ps/>"
-                             "desk locking is disabled."));
-        return 0;
-     }
-#endif
-
    if (e_desklock_is_personal())
      {
         if (!e_config->desklock_passwd)
diff --git a/src/bin/e_sys_main.c b/src/bin/e_sys_main.c
index 9043b58..e5e4e7a 100644
--- a/src/bin/e_sys_main.c
+++ b/src/bin/e_sys_main.c
@@ -49,57 +49,6 @@ static int       auth_etc_enlightenment_sysactions(char *a,
 static void      auth_etc_enlightenment_sysactions_perm(char *path);
 static char     *get_word(char *s,
                           char *d);
-#if defined(__OpenBSD__)
-
-static void
-_exit_backoff(void)
-{
-   sleep(3);
-   exit(1 << 7);
-}
-
-static int
-_check_auth(const char *guess)
-{
-   struct passwd *pw_ent;
-   uid_t uid = getuid();
-
-   pw_ent = getpwuid_shadow(uid);
-   if (!pw_ent)
-     _exit_backoff();
-
-   return crypt_checkpass(guess, pw_ent->pw_passwd);
-}
-
-static int
-auth_generic_enlightenment_desklock(void)
-{
-   char buf[4096];
-   char byte[1];
-   int res = -1;
-   int i = 0;
-
-   while (read(STDIN_FILENO, byte, sizeof(byte)) > 0)
-     {
-        if (byte[0] == '\n') break;
-        buf[i++] = byte[0];
-        if (i == sizeof(buf) -1) break;
-     }
-
-   buf[i] = '\0';
-
-   if (!i)
-     _exit_backoff();
-
-   res = _check_auth(buf);
-
-   if (res) _exit_backoff();
-
-   return res;
-}
-
-#endif
-
 /* local subsystem globals */
 static Eina_Hash *actions = NULL;
 static uid_t uid = -1;
@@ -132,15 +81,6 @@ main(int argc,
              exit(0);
           }
      }
-#if defined(__OpenBSD__)
-   if (argc >= 2)
-     {
-        if (!strcmp(argv[1], "-z"))
-          {
-             exit(auth_generic_enlightenment_desklock());
-          }
-     }
-#endif
    if (argc >= 3)
      {
         if ((argc == 3) && (!strcmp(argv[1], "-t")))
diff --git a/src/bin/meson.build b/src/bin/meson.build
index a8f6aa7..f1624ac 100644
--- a/src/bin/meson.build
+++ b/src/bin/meson.build
@@ -35,8 +35,14 @@ deps_e = [
   dep_intl
 ]
 
+deps_ckpass = [ ]
+
+if freebsd == true
+  deps_ckpass += dep_crypt
+endif
+
 if config_h.has('HAVE_PAM') == true
-  deps_e += dep_pam
+  deps_ckpass += dep_pam
 endif
 
 requires_e = ' '.join([
@@ -553,16 +559,15 @@ executable('enlightenment_sys',
           )
 suid_exes += join_paths(dir_e_utils, 'enlightenment_sys')
 
-if freebsd == true
-  executable('enlightenment_ckpasswd',
-             'e_ckpasswd_main.c',
-             dependencies : [ dep_crypt ],
-             c_args       : suid_cflags,
-             link_args    : suid_ldflags,
-             install_dir  : dir_e_utils,
-             install      : true
-            )
-  suid_exes += join_paths(dir_e_utils, 'enlightenment_ckpasswd')
-endif
+executable('enlightenment_ckpasswd',
+           'e_ckpasswd_main.c',
+           include_directories: include_directories('../..'),
+           dependencies : deps_ckpass,
+           c_args       : suid_cflags,
+           link_args    : suid_ldflags,
+           install_dir  : dir_e_utils,
+           install      : true
+          )
+suid_exes += join_paths(dir_e_utils, 'enlightenment_ckpasswd')
 
 subdir('e_fm')
 
дизайн и разработка: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
текущий майнтейнер: Michael Shigorin