A few bug-fixes for pam_ssh:
authorPeter Avalos <pavalos@theshell.com>
Mon, 29 Dec 2008 00:26:38 +0000 (19:26 -0500)
committerPeter Avalos <pavalos@theshell.com>
Fri, 2 Jan 2009 05:56:33 +0000 (00:56 -0500)
-Narrow the use of user credentials.
-Fix one case where openpam_restore_cred() might be called twice in a
row.
-Do not use passphraseless keys for authentication unless the nullok
option was specified.
-Correct the logic for determining whether the user has already entered
a password.

Obtained-from: FreeBSD

lib/pam_module/pam_ssh/pam_ssh.8
lib/pam_module/pam_ssh/pam_ssh.c

index c3024ac..1e8a402 100644 (file)
@@ -32,7 +32,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD: src/lib/libpam/modules/pam_ssh/pam_ssh.8,v 1.13 2004/07/02 23:52:18 ru Exp $
+.\" $FreeBSD: src/lib/libpam/modules/pam_ssh/pam_ssh.8,v 1.14 2005/09/22 05:35:24 des Exp $
 .\" $DragonFly: src/lib/pam_module/pam_ssh/pam_ssh.8,v 1.1 2005/07/12 23:26:49 joerg Exp $
 .\"
 .Dd November 26, 2001
@@ -94,6 +94,11 @@ This option is similar to the
 option,
 except that if the previously obtained password fails,
 the user is prompted for another password.
+.It Cm nullok
+Normally, keys with no passphrase are ignored for authentication
+purposes.
+If this option is set, keys with no passphrase will be taken into
+consideration, allowing the user to log in with a blank password.
 .El
 .Ss SSH Session Management Module
 The
index 8e8bf56..1f53638 100644 (file)
@@ -31,7 +31,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libpam/modules/pam_ssh/pam_ssh.c,v 1.40 2004/02/10 10:13:21 des Exp $
+ * $FreeBSD: src/lib/libpam/modules/pam_ssh/pam_ssh.c,v 1.45 2007/12/21 12:00:15 des Exp $
  * $DragonFly: src/lib/pam_module/pam_ssh/pam_ssh.c,v 1.2 2006/09/29 06:35:03 corecode Exp $
  */
 
@@ -58,6 +58,7 @@
 
 #include "buffer.h"
 #include "key.h"
+#include "buffer.h"
 #include "authfd.h"
 #include "authfile.h"
 
@@ -135,9 +136,12 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags __unused,
     int argc __unused, const char *argv[] __unused)
 {
        const char **kfn, *passphrase, *user;
+       const void *item;
        struct passwd *pwd;
        struct pam_ssh_key *psk;
-       int nkeys, pam_err, pass;
+       int nkeys, nullok, pam_err, pass;
+
+       nullok = (openpam_get_option(pamh, "nullok") != NULL);
 
        /* PEM is not loaded by default */
        OpenSSL_add_all_algorithms();
@@ -152,24 +156,25 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags __unused,
        if (pwd->pw_dir == NULL)
                return (PAM_AUTH_ERR);
 
-       /* switch to user credentials */
-       pam_err = openpam_borrow_cred(pamh, pwd);
-       if (pam_err != PAM_SUCCESS)
-               return (pam_err);
-
-       pass = (pam_get_item(pamh, PAM_AUTHTOK,
-           (const void **)&passphrase) == PAM_SUCCESS);
+       nkeys = 0;
+       pass = (pam_get_item(pamh, PAM_AUTHTOK, &item) == PAM_SUCCESS &&
+           item != NULL);
  load_keys:
        /* get passphrase */
        pam_err = pam_get_authtok(pamh, PAM_AUTHTOK,
            &passphrase, pam_ssh_prompt);
-       if (pam_err != PAM_SUCCESS) {
-               openpam_restore_cred(pamh);
+       if (pam_err != PAM_SUCCESS)
+               return (pam_err);
+
+       if (*passphrase == '\0' && !nullok)
+               goto skip_keys;
+
+       /* switch to user credentials */
+       pam_err = openpam_borrow_cred(pamh, pwd);
+       if (pam_err != PAM_SUCCESS)
                return (pam_err);
-       }
 
        /* try to load keys from all keyfiles we know of */
-       nkeys = 0;
        for (kfn = pam_ssh_keyfiles; *kfn != NULL; ++kfn) {
                psk = pam_ssh_load_key(pwd->pw_dir, *kfn, passphrase);
                if (psk != NULL) {
@@ -178,6 +183,10 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags __unused,
                }
        }
 
+       /* switch back to arbitrator credentials */
+       openpam_restore_cred(pamh);
+
+ skip_keys:
        /*
         * If we tried an old token and didn't get anything, and
         * try_first_pass was specified, try again after prompting the
@@ -190,9 +199,6 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags __unused,
                goto load_keys;
        }
 
-       /* switch back to arbitrator credentials before returning */
-       openpam_restore_cred(pamh);
-
        /* no keys? */
        if (nkeys == 0)
                return (PAM_AUTH_ERR);
@@ -256,10 +262,8 @@ pam_ssh_start_agent(pam_handle_t *pamh)
        FILE *f;
 
        /* get a pipe which we will use to read the agent's output */
-       if (pipe(agent_pipe) == -1) {
-               openpam_restore_cred(pamh);
+       if (pipe(agent_pipe) == -1)
                return (PAM_SYSTEM_ERR);
-       }
 
        /* start the agent */
        openpam_log(PAM_LOG_DEBUG, "starting an ssh agent");