]> granicus.if.org Git - sudo/commitdiff
Use the auth_getpass (and the plugin conversation fuction) for Tru64
authorTodd C. Miller <Todd.Miller@courtesan.com>
Tue, 6 Oct 2015 16:25:53 +0000 (10:25 -0600)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Tue, 6 Oct 2015 16:25:53 +0000 (10:25 -0600)
SIA.  This prevents sudo from sleeping while holding the tty ticket
lock.

plugins/sudoers/auth/sia.c
plugins/sudoers/auth/sudo_auth.c
plugins/sudoers/auth/sudo_auth.h

index a7d262c1826832a758c248233aed0fb52a444ca8..7856f22d506c498556b6cd5ef8d7ff1605742503 100644 (file)
 #include "sudoers.h"
 #include "sudo_auth.h"
 
-static int sudo_collect(int, int, uchar_t *, int, prompt_t *);
-
-static char *def_prompt;
 static char **sudo_argv;
 static int sudo_argc;
 
-#define PROMPT_IS_PASSWORD(_p) \
-    (strncmp((_p), "Password:", 9) == 0 && \
-       ((_p)[9] == '\0' || ((_p)[9] == ' ' && (_p)[10] == '\0')))
-
-/*
- * Collection routine (callback) for limiting the timeouts in SIA
- * prompts and (possibly) setting a custom prompt.
- */
-static int
-sudo_collect(int timeout, int rendition, uchar_t *title, int nprompts,
-    prompt_t *prompts)
-{
-    int rval;
-    sigset_t mask, omask;
-    debug_decl(sudo_collect, SUDOERS_DEBUG_AUTH)
-
-    switch (rendition) {
-       case SIAFORM:
-       case SIAONELINER:
-           if (timeout <= 0 || timeout > def_passwd_timeout * 60)
-               timeout = def_passwd_timeout * 60;
-           /*
-            * Substitute custom prompt if a) the sudo prompt is not "Password:"
-            * and b) the SIA prompt is "Password:" (so we know it is safe).
-            * This keeps us from overwriting things like S/Key challenges.
-            */
-           if (!PROMPT_IS_PASSWORD(def_prompt) &&
-               PROMPT_IS_PASSWORD((char *)prompts[0].prompt))
-               prompts[0].prompt = (unsigned char *)def_prompt;
-           break;
-       default:
-           break;
-    }
-
-    /* Unblock SIGINT and SIGQUIT during password entry. */
-    sigemptyset(&mask);
-    sigaddset(&mask, SIGINT);
-    sigaddset(&mask, SIGQUIT);
-    sigprocmask(SIG_UNBLOCK, &mask, &omask);
-
-    rval = sia_collect_trm(timeout, rendition, title, nprompts, prompts);
-
-    /* Restore previous signal mask. */
-    sigprocmask(SIG_SETMASK, &omask, NULL);
-
-    debug_return_int(rval);
-}
-
 int
 sudo_sia_setup(struct passwd *pw, char **promptp, sudo_auth *auth)
 {
-    SIAENTITY *siah = NULL;
+    SIAENTITY *siah;
     int i;
     debug_decl(sudo_sia_setup, SUDOERS_DEBUG_AUTH)
 
@@ -115,40 +64,90 @@ sudo_sia_setup(struct passwd *pw, char **promptp, sudo_auth *auth)
        sudo_argv[i + 1] = NewArgv[i];
     sudo_argv[sudo_argc] = NULL;
 
-    if (sia_ses_init(&siah, sudo_argc, sudo_argv, NULL, pw->pw_name, user_ttypath, 1, NULL) != SIASUCCESS) {
-
+    /* We don't let SIA prompt the user for input. */
+    if (sia_ses_init(&siah, sudo_argc, sudo_argv, NULL, pw->pw_name, user_ttypath, 0, NULL) != SIASUCCESS) {
        log_warning(0, N_("unable to initialize SIA session"));
        debug_return_int(AUTH_FATAL);
     }
 
-    auth->data = (void *) siah;
+    auth->data = siah;
     debug_return_int(AUTH_SUCCESS);
 }
 
 int
-sudo_sia_verify(struct passwd *pw, char *prompt, sudo_auth *auth, struct sudo_conv_callback *callback)
+sudo_sia_verify(struct passwd *pw, char *prompt, sudo_auth *auth,
+    struct sudo_conv_callback *callback)
 {
-    SIAENTITY *siah = (SIAENTITY *) auth->data;
+    SIAENTITY *siah = auth->data;
+    char *pass;
+    int rc;
     debug_decl(sudo_sia_verify, SUDOERS_DEBUG_AUTH)
 
-    def_prompt = prompt;               /* for sudo_collect */
+    /* Get password, return AUTH_INTR if we got ^C */
+    pass = auth_getpass(prompt, def_passwd_timeout * 60,
+        SUDO_CONV_PROMPT_ECHO_OFF, callback);
+    if (pass == NULL)
+       debug_return_int(AUTH_INTR);
+
+    /* Check password and zero out plaintext copy. */
+    rc = sia_ses_authent(NULL, pass, siah);
+    memset_s(pass, SUDO_CONV_REPL_MAX, 0, strlen(pass));
 
-    /* XXX - need a way to detect user hitting ^C or EOF at prompt */
-    if (sia_ses_reauthent(sudo_collect, siah) == SIASUCCESS)
+    if (rc == SIASUCCESS)
        debug_return_int(AUTH_SUCCESS);
-    else
-       debug_return_int(AUTH_FAILURE);
+    if (ISSET(rc, SIASTOP))
+       debug_return_int(AUTH_FATAL);
+    debug_return_int(AUTH_FAILURE);
 }
 
 int
 sudo_sia_cleanup(struct passwd *pw, sudo_auth *auth)
 {
-    SIAENTITY *siah = (SIAENTITY *) auth->data;
+    SIAENTITY *siah = auth->data;
     debug_decl(sudo_sia_cleanup, SUDOERS_DEBUG_AUTH)
 
     (void) sia_ses_release(&siah);
+    auth->data = NULL;
     free(sudo_argv);
     debug_return_int(AUTH_SUCCESS);
 }
 
+int
+sudo_sia_begin_session(struct passwd *pw, char **user_envp[], sudo_auth *auth)
+{
+    SIAENTITY *siah;
+    int status = AUTH_FATAL;
+    debug_decl(sudo_sia_begin_session, SUDOERS_DEBUG_AUTH)
+
+    /* Re-init sia for the target user's session. */
+    if (sia_ses_init(&siah, NewArgc, NewArgv, NULL, pw->pw_name, user_ttypath, 0, NULL) != SIASUCCESS) {
+       log_warning(0, N_("unable to initialize SIA session"));
+       goto done;
+    }
+
+    if (sia_make_entity_pwd(pw, siah) != SIASUCCESS) {
+       sudo_warn("sia_make_entity_pwd");
+       goto done;
+    }
+
+    status = AUTH_FAILURE;             /* no more fatal errors. */
+
+    siah->authtype = SIA_A_NONE;
+    if (sia_ses_estab(sia_collect_trm, siah) != SIASUCCESS) {
+       sudo_warn("sia_ses_estab");
+       goto done;
+    }
+
+    if (sia_ses_launch(sia_collect_trm, siah) != SIASUCCESS) {
+       sudo_warn("sia_ses_launch");
+       goto done;
+    }
+
+    status = AUTH_SUCCESS;
+
+done:
+    (void) sia_ses_release(&siah);
+    debug_return_int(status);
+}
+
 #endif /* HAVE_SIA_SES_INIT */
index eeba9bdfc3c7b37240cd37078c98993a95a28d25..e03af6fdccd919936912e07d27f3ad4e7c90e420 100644 (file)
@@ -50,7 +50,7 @@ static sudo_auth auth_switch[] = {
     AUTH_ENTRY("SecurId", FLAG_STANDALONE, sudo_securid_init, sudo_securid_setup, sudo_securid_verify, NULL, NULL, NULL)
 #endif
 #ifdef HAVE_SIA_SES_INIT
-    AUTH_ENTRY("sia", FLAG_STANDALONE, NULL, sudo_sia_setup, sudo_sia_verify, sudo_sia_cleanup, NULL, NULL)
+    AUTH_ENTRY("sia", FLAG_STANDALONE, NULL, sudo_sia_setup, sudo_sia_verify, sudo_sia_cleanup, sudo_sia_begin_session, NULL)
 #endif
 #ifdef HAVE_FWTK
     AUTH_ENTRY("fwtk", FLAG_STANDALONE, sudo_fwtk_init, NULL, sudo_fwtk_verify, sudo_fwtk_cleanup, NULL, NULL)
index 1e12f86071d234c151e8dd976e7eb01ee74f081f..028c1ce31fded163faf1705ef3c3a67061adc355 100644 (file)
@@ -74,6 +74,7 @@ int sudo_securid_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct s
 int sudo_sia_setup(struct passwd *pw, char **prompt, sudo_auth *auth);
 int sudo_sia_verify(struct passwd *pw, char *prompt, sudo_auth *auth, struct sudo_conv_callback *callback);
 int sudo_sia_cleanup(struct passwd *pw, sudo_auth *auth);
+int sudo_sia_begin_session(struct passwd *pw, char **user_env[], sudo_auth *auth);
 
 /* Prototypes for normal methods */
 int sudo_afs_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_conv_callback *callback);