]> andersk Git - openssh.git/commitdiff
- (dtucker) [auth-pam.c auth-pam.h auth-passwd.c]: Bug #874: Re-add PAM
authordtucker <dtucker>
Sun, 30 May 2004 10:43:59 +0000 (10:43 +0000)
committerdtucker <dtucker>
Sun, 30 May 2004 10:43:59 +0000 (10:43 +0000)
   support for PasswordAuthentication=yes.  ok djm@

ChangeLog
auth-pam.c
auth-pam.h
auth-passwd.c

index ca7a590cf510f121d9d46844b3ab383f41360859..7f76f814e7079c59fb4e3ac5a4ee1965c2dc0791 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+20040530
+ - (dtucker) [auth-pam.c auth-pam.h auth-passwd.c]: Bug #874: Re-add PAM 
+   support for PasswordAuthentication=yes.  ok djm@
+
 20040527
  - (dtucker) [contrib/caldera/openssh.spec contrib/redhat/openssh.spec
    contrib/README CREDITS INSTALL] Bug #873: Correct URLs for x11-ssh-askpass
index 6a78a287b34a4ee45194aab852a993eb82fd52ab..ff4b01401b1e062902e5c26469ce61b9f8151fbc 100644 (file)
@@ -169,6 +169,7 @@ static int sshpam_cred_established = 0;
 static int sshpam_account_status = -1;
 static char **sshpam_env = NULL;
 static Authctxt *sshpam_authctxt = NULL;
+static const char *sshpam_password = NULL;
 
 /* Some PAM implementations don't implement this */
 #ifndef HAVE_PAM_GETENVLIST
@@ -951,4 +952,100 @@ free_pam_environment(char **env)
        xfree(env);
 }
 
+/*
+ * "Blind" conversation function for password authentication.  Assumes that
+ * echo-off prompts are for the password and stores messages for later
+ * display.
+ */
+static int
+sshpam_passwd_conv(int n, const struct pam_message **msg,
+    struct pam_response **resp, void *data)
+{
+       struct pam_response *reply;
+       int i;
+       size_t len;
+
+       debug3("PAM: %s called with %d messages", __func__, n);
+
+       *resp = NULL;
+
+       if (n <= 0 || n > PAM_MAX_NUM_MSG)
+               return (PAM_CONV_ERR);
+
+       if ((reply = malloc(n * sizeof(*reply))) == NULL)
+               return (PAM_CONV_ERR);
+       memset(reply, 0, n * sizeof(*reply));
+
+       for (i = 0; i < n; ++i) {
+               switch (PAM_MSG_MEMBER(msg, i, msg_style)) {
+               case PAM_PROMPT_ECHO_OFF:
+                       if (sshpam_password == NULL)
+                               goto fail;
+                       reply[i].resp = xstrdup(sshpam_password);
+                       reply[i].resp_retcode = PAM_SUCCESS;
+                       break;
+               case PAM_ERROR_MSG:
+               case PAM_TEXT_INFO:
+                       len = strlen(PAM_MSG_MEMBER(msg, i, msg));
+                       if (len > 0) {
+                               buffer_append(&loginmsg,
+                                   PAM_MSG_MEMBER(msg, i, msg), len);
+                               buffer_append(&loginmsg, "\n", 1);
+                       }
+                       reply[i].resp = xstrdup("");
+                       reply[i].resp_retcode = PAM_SUCCESS;
+                       break;
+               default:
+                       goto fail;
+               }
+       }
+       *resp = reply;
+       return (PAM_SUCCESS);
+
+ fail: 
+       for(i = 0; i < n; i++) {
+               if (reply[i].resp != NULL)
+                       xfree(reply[i].resp);
+       }
+       xfree(reply);
+       return (PAM_CONV_ERR);
+}
+
+static struct pam_conv passwd_conv = { sshpam_passwd_conv, NULL };
+
+/*
+ * Attempt password authentication via PAM
+ */
+int
+sshpam_auth_passwd(Authctxt *authctxt, const char *password)
+{
+       int flags = (options.permit_empty_passwd == 0 ?
+           PAM_DISALLOW_NULL_AUTHTOK : 0);
+
+       if (!options.use_pam || sshpam_handle == NULL)
+               fatal("PAM: %s called when PAM disabled or failed to "
+                   "initialise.", __func__);
+
+       sshpam_password = password;
+       sshpam_authctxt = authctxt;
+
+       sshpam_err = pam_set_item(sshpam_handle, PAM_CONV,
+           (const void *)&passwd_conv);
+       if (sshpam_err != PAM_SUCCESS)
+               fatal("PAM: %s: failed to set PAM_CONV: %s", __func__,
+                   pam_strerror(sshpam_handle, sshpam_err));
+
+       sshpam_err = pam_authenticate(sshpam_handle, flags);
+       sshpam_password = NULL;
+       if (sshpam_err == PAM_SUCCESS && authctxt->valid) {
+               debug("PAM: password authentication accepted for %.100s",
+                   authctxt->user);
+               return 1;
+       } else {
+               debug("PAM: password authentication failed for %.100s: %s",
+                   authctxt->valid ? authctxt->user : "an illegal user",
+                   pam_strerror(sshpam_handle, sshpam_err));
+               return 0;
+       }
+}
 #endif /* USE_PAM */
index ff501f64e77e9cb27cc708c367f66ebd2dcdd781..f756b315ebc0f356643dd7d1e75baf921cbf9110 100644 (file)
@@ -44,5 +44,6 @@ char ** fetch_pam_child_environment(void);
 void free_pam_environment(char **);
 void sshpam_thread_cleanup(void);
 void sshpam_cleanup(void);
+int sshpam_auth_passwd(Authctxt *, const char *);
 
 #endif /* USE_PAM */
index beaf0fa6cbf3ee71564fea04f6d81807831823fd..da247df7d0f377cea97966243785c9daa872b39d 100644 (file)
@@ -91,6 +91,10 @@ auth_password(Authctxt *authctxt, const char *password)
                return ok;
        }
 #endif
+#ifdef USE_PAM
+       if (options.use_pam)
+               return (sshpam_auth_passwd(authctxt, password) && ok);
+#endif
 #if defined(USE_SHADOW) && defined(HAS_SHADOW_EXPIRE)
        if (!expire_checked) {
                expire_checked = 1;
This page took 0.091764 seconds and 5 git commands to generate.