diff -urN openssh-3.4p1-owl-always-auth/Makefile.in openssh-3.4p1/Makefile.in --- openssh-3.4p1-owl-always-auth/Makefile.in Wed Jun 26 03:45:42 2002 +++ openssh-3.4p1/Makefile.in Mon Jul 1 23:11:30 2002 @@ -64,7 +64,7 @@ SSHOBJS= ssh.o sshconnect.o sshconnect1.o sshconnect2.o sshtty.o readconf.o clientloop.o -SSHDOBJS= sshd.o auth.o auth1.o auth2.o auth2-hostbased.o auth2-kbdint.o auth2-none.o auth2-passwd.o auth2-pubkey.o auth-chall.o auth2-chall.o auth-rhosts.o auth-options.o auth-krb4.o auth-krb5.o auth-pam.o auth2-pam.o auth-passwd.o auth-rsa.o auth-rh-rsa.o auth-sia.o sshpty.o sshlogin.o loginrec.o servconf.o serverloop.o md5crypt.o session.o groupaccess.o auth-skey.o auth-bsdauth.o monitor_mm.o monitor.o +SSHDOBJS= sshd.o auth.o auth1.o auth2.o auth2-hostbased.o auth2-kbdint.o auth2-none.o auth2-passwd.o auth2-pubkey.o auth-chall.o auth2-chall.o auth-rhosts.o auth-options.o auth-krb4.o auth-krb5.o auth-pam.o appl_userpass.o auth2-pam.o auth-passwd.o auth-rsa.o auth-rh-rsa.o auth-sia.o sshpty.o sshlogin.o loginrec.o servconf.o serverloop.o md5crypt.o session.o groupaccess.o auth-skey.o auth-bsdauth.o monitor_mm.o monitor.o MANPAGES = scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-rand-helper.8.out ssh-keysign.8.out sshd_config.5.out ssh_config.5.out MANPAGES_IN = scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-rand-helper.8 ssh-keysign.8 sshd_config.5 ssh_config.5 diff -urN openssh-3.4p1-owl-always-auth/_pam_userpass.h openssh-3.4p1/_pam_userpass.h --- openssh-3.4p1-owl-always-auth/_pam_userpass.h Thu Jan 1 03:00:00 1970 +++ openssh-3.4p1/_pam_userpass.h Mon Jul 1 23:11:30 2002 @@ -0,0 +1,12 @@ +#ifndef __PAM_USERPASS_H +#define __PAM_USERPASS_H + +#define USERPASS_AGENT_ID "userpass" +#define USERPASS_AGENT_ID_LENGTH 8 + +#define USERPASS_USER_MASK 0x03 +#define USERPASS_USER_REQUIRED 1 +#define USERPASS_USER_KNOWN 2 +#define USERPASS_USER_FIXED 3 + +#endif diff -urN openssh-3.4p1-owl-always-auth/appl_userpass.c openssh-3.4p1/appl_userpass.c --- openssh-3.4p1-owl-always-auth/appl_userpass.c Thu Jan 1 03:00:00 1970 +++ openssh-3.4p1/appl_userpass.c Mon Jul 1 23:11:30 2002 @@ -0,0 +1,59 @@ +#include +#include + +#include +#include + +#ifndef PAM_BP_RCONTROL +/* Linux-PAM prior to 0.74 */ +#define PAM_BP_RCONTROL PAM_BP_CONTROL +#define PAM_BP_WDATA PAM_BP_DATA +#define PAM_BP_RDATA PAM_BP_DATA +#endif + +#include "_pam_userpass.h" +#include "pam_userpass.h" + +int pam_userpass_conv(int num_msg, const struct pam_message **msg, + struct pam_response **resp, void *appdata_ptr) +{ + pam_userpass_t *userpass = (pam_userpass_t *)appdata_ptr; + pamc_bp_t prompt; + const char *input; + char *output; + char flags; + + if (num_msg != 1 || msg[0]->msg_style != PAM_BINARY_PROMPT) + return PAM_CONV_ERR; + + prompt = (pamc_bp_t)msg[0]->msg; + input = PAM_BP_RDATA(prompt); + + if (PAM_BP_RCONTROL(prompt) != PAM_BPC_SELECT || + strncmp(input, USERPASS_AGENT_ID "/", USERPASS_AGENT_ID_LENGTH + 1)) + return PAM_CONV_ERR; + + flags = input[USERPASS_AGENT_ID_LENGTH + 1]; + input += USERPASS_AGENT_ID_LENGTH + 1 + 1; + + if ((flags & USERPASS_USER_MASK) == USERPASS_USER_FIXED && + strcmp(input, userpass->user)) + return PAM_CONV_AGAIN; + + if (!(*resp = malloc(sizeof(struct pam_response)))) + return PAM_CONV_ERR; + + prompt = NULL; + PAM_BP_RENEW(&prompt, PAM_BPC_DONE, + strlen(userpass->user) + 1 + strlen(userpass->pass)); + output = PAM_BP_WDATA(prompt); + + strcpy(output, userpass->user); + output += strlen(output) + 1; + memcpy(output, userpass->pass, strlen(userpass->pass)); + + (*resp)[0].resp_retcode = 0; + (*resp)[0].resp = (char *)prompt; + + return PAM_SUCCESS; +} diff -urN openssh-3.4p1-owl-always-auth/auth-pam.c openssh-3.4p1/auth-pam.c --- openssh-3.4p1-owl-always-auth/auth-pam.c Mon Jul 1 23:09:55 2002 +++ openssh-3.4p1/auth-pam.c Mon Jul 1 23:38:11 2002 @@ -34,6 +34,9 @@ #include "canohost.h" #include "readpass.h" +#include +#include "pam_userpass.h" + extern char *__progname; RCSID("$Id$"); @@ -45,13 +48,13 @@ struct pam_response **resp, void *appdata_ptr); /* module-local variables */ +static pam_userpass_t userpass; static struct pam_conv conv = { do_pam_conversation, - NULL + &userpass }; static char *__pam_msg = NULL; static pam_handle_t *__pamh = NULL; -static const char *__pampasswd = NULL; /* states for do_pam_conversation() */ enum { INITIAL_LOGIN, OTHER } pamstate = INITIAL_LOGIN; @@ -83,18 +86,45 @@ * PAM conversation function. * There are two states this can run in. * - * INITIAL_LOGIN mode simply feeds the password from the client into - * PAM in response to PAM_PROMPT_ECHO_OFF, and collects output - * messages with into __pam_msg. This is used during initial - * authentication to bypass the normal PAM password prompt. + * INITIAL_LOGIN mode simply feeds the username and the password from + * the client into PAM via Linux-PAM binary prompts and queues any text + * messages for printing later. * - * OTHER mode handles PAM_PROMPT_ECHO_OFF with read_passphrase() - * and outputs messages to stderr. This mode is used if pam_chauthtok() - * is called to update expired passwords. + * OTHER mode is a regular PAM conversation. This mode is used if + * pam_chauthtok() is called to update expired passwords. */ static int do_pam_conversation(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) { + if (pamstate == INITIAL_LOGIN) { + int i, status; + + status = pam_userpass_conv(num_msg, msg, resp, appdata_ptr); + if (status != PAM_CONV_ERR) + return status; + + if (!(*resp = malloc(num_msg * sizeof(struct pam_response)))) + return PAM_CONV_ERR; + for (i = 0; i < num_msg; i++) { + switch (msg[i]->msg_style) { + case PAM_ERROR_MSG: + case PAM_TEXT_INFO: + message_cat(&__pam_msg, msg[i]->msg); + (*resp)[i].resp_retcode = PAM_SUCCESS; + (*resp)[i].resp = NULL; + continue; + default: + free(*resp); + *resp = NULL; + return PAM_CONV_ERR; + } + } + return PAM_SUCCESS; + } + + return misc_conv(num_msg, msg, resp, appdata_ptr); + +#if 0 struct pam_response *reply; int count; char buf[1024]; @@ -170,6 +200,7 @@ *resp = reply; return PAM_SUCCESS; +#endif } /* Called at exit to cleanly shutdown PAM */ @@ -221,7 +252,8 @@ if (*password == '\0' && options.permit_empty_passwd == 0) return 0; - __pampasswd = password; + userpass.user = pw ? pw->pw_name : "ILLEGAL USER"; + userpass.pass = password; pamstate = INITIAL_LOGIN; pam_retval = do_pam_authenticate( diff -urN openssh-3.4p1-owl-always-auth/pam_userpass.h openssh-3.4p1/pam_userpass.h --- openssh-3.4p1-owl-always-auth/pam_userpass.h Thu Jan 1 03:00:00 1970 +++ openssh-3.4p1/pam_userpass.h Mon Jul 1 23:11:30 2002 @@ -0,0 +1,14 @@ +#ifndef _PAM_USERPASS_H +#define _PAM_USERPASS_H + +#include + +typedef struct { + const char *user; + const char *pass; +} pam_userpass_t; + +extern int pam_userpass_conv(int num_msg, const struct pam_message **msg, + struct pam_response **resp, void *appdata_ptr); + +#endif