TISviaPAM patch
Frank Cusack
frank at google.com
Tue Oct 9 18:14:34 EST 2001
On Mon, Oct 08, 2001 at 08:46:33PM -0700, Frank Cusack wrote:
> Here is a patch that does TIS auth via PAM. It's controlled by a switch
> in the sshd_config. You'd use it by having a PAM module that sets
> PAM_PROMPT_ECHO_ON. eg, you could use it with pam_skey or pam_smxs.
>
> The patch is against the 2.9.9p2 distribution.
oops. Here's the actual patch.
/fc
-------------- next part --------------
Add 'TISviaPAM' option, which uses PAM for ssh1 TIS authentication.
This allows arbitrary challenge/response authentications instead
of the built-in S/Key. Also fixed 2-3 small typos and a bug in
password handling for TIS (turn echo on).
Index: openssh/auth-pam.c
@@ -26,6 +26,8 @@
#ifdef USE_PAM
#include "ssh.h"
+#include "ssh1.h"
+#include "packet.h"
#include "xmalloc.h"
#include "log.h"
#include "auth-pam.h"
@@ -54,6 +56,8 @@
/* states for do_pam_conversation() */
enum { INITIAL_LOGIN, OTHER } pamstate = INITIAL_LOGIN;
+/* which type of prompts we should handle, set in auth_pam_password */
+static int pamprompt;
/* remember whether pam_acct_mgmt() returned PAM_NEWAUTHTOK_REQD */
static int password_change_required = 0;
/* remember whether the last pam_authenticate() succeeded or not */
@@ -98,6 +102,10 @@
int count;
char buf[1024];
+ u_int dlen;
+ int plen, type;
+ char *response;
+
/* PAM will free this later */
reply = malloc(num_msg * sizeof(*reply));
if (reply == NULL)
@@ -111,10 +119,40 @@
*/
switch(PAM_MSG_MEMBER(msg, count, msg_style)) {
case PAM_PROMPT_ECHO_ON:
- free(reply);
- return PAM_CONV_ERR;
+ if (pamprompt != PAM_PROMPT_ECHO_ON ||
+ (*msg)[count].msg == NULL) {
+ free(reply);
+ return PAM_CONV_ERR;
+ }
+
+ /* handle challenge/response (ssh1 TIS) */
+ /* Send the challenge */
+ strlcpy(buf, PAM_MSG_MEMBER(msg, count, msg),
+ sizeof(buf));
+ debug("sending challenge '%s'", buf);
+ packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE);
+ packet_put_cstring(buf);
+ packet_send();
+ packet_write_wait();
+
+ /* Give the response to the PAM module */
+ if ((type = packet_read(&plen)) !=
+ SSH_CMSG_AUTH_TIS_RESPONSE) {
+ free(reply);
+ return PAM_CONV_ERR;
+ }
+ debug("rcvd SSH_CMSG_AUTH_TIS_RESPONSE");
+ response = packet_get_string(&dlen);
+ debug("got response '%s'", response);
+ packet_integrity_check(plen, 4 + dlen, type);
+ reply[count].resp = xstrdup(response);
+ reply[count].resp_retcode = PAM_SUCCESS;
+ xfree(response);
+ break;
+
case PAM_PROMPT_ECHO_OFF:
- if (__pampasswd == NULL) {
+ if (__pampasswd == NULL ||
+ pamprompt != PAM_PROMPT_ECHO_OFF) {
free(reply);
return PAM_CONV_ERR;
}
@@ -198,8 +236,8 @@
}
}
-/* Attempt password authentation using PAM */
-int auth_pam_password(struct passwd *pw, const char *password)
+/* Attempt password authentication using PAM */
+int auth_pam_password(struct passwd *pw, const char *password, int prompt_type)
{
extern ServerOptions options;
int pam_retval;
@@ -211,12 +249,14 @@
return 0;
if (pw->pw_uid == 0 && options.permit_root_login == PERMIT_NO_PASSWD)
return 0;
- if (*password == '\0' && options.permit_empty_passwd == 0)
+ if (*password == '\0' && options.permit_empty_passwd == 0 &&
+ prompt_type == PAM_PROMPT_ECHO_OFF)
return 0;
__pampasswd = password;
pamstate = INITIAL_LOGIN;
+ pamprompt = prompt_type;
pam_retval = do_pam_authenticate(0);
if (pam_retval == PAM_SUCCESS) {
debug("PAM Password authentication accepted for "
Index: openssh/auth-pam.h
@@ -7,7 +7,7 @@
void start_pam(const char *user);
void finish_pam(void);
-int auth_pam_password(struct passwd *pw, const char *password);
+int auth_pam_password(struct passwd *pw, const char *password, int prompt_type);
char **fetch_pam_environment(void);
int do_pam_authenticate(int flags);
int do_pam_account(char *username, char *remote_user);
Index: openssh/auth1.c
@@ -89,7 +89,7 @@
(!options.kerberos_authentication || options.kerberos_or_local_passwd) &&
#endif
#ifdef USE_PAM
- auth_pam_password(pw, "")) {
+ auth_pam_password(pw, "", PAM_PROMPT_ECHO_OFF)) {
#elif defined(HAVE_OSF_SIA)
0) {
#else
@@ -258,7 +258,8 @@
#ifdef USE_PAM
/* Do PAM auth with password */
- authenticated = auth_pam_password(pw, password);
+ authenticated = auth_pam_password(pw, password,
+ PAM_PROMPT_ECHO_OFF);
#elif defined(HAVE_OSF_SIA)
/* Do SIA auth with password */
authenticated = auth_sia_password(authctxt->user,
@@ -275,6 +276,15 @@
case SSH_CMSG_AUTH_TIS:
debug("rcvd SSH_CMSG_AUTH_TIS");
if (options.challenge_response_authentication == 1) {
+#ifdef USE_PAM
+ if (options.tis_via_pam == 1) {
+ authenticated = auth_pam_password(pw, "",
+ PAM_PROMPT_ECHO_ON);
+ break;
+ } else {
+#else
+ {
+#endif /* USE_PAM */
char *challenge = get_challenge(authctxt);
if (challenge != NULL) {
debug("sending challenge '%s'", challenge);
@@ -285,6 +295,7 @@
packet_write_wait();
continue;
}
+ }
}
break;
case SSH_CMSG_AUTH_TIS_RESPONSE:
Index: openssh/auth2-chall.c
@@ -139,7 +139,7 @@
}
/*
- * try challenge-reponse, set authctxt->postponed if we have to
+ * try challenge-response, set authctxt->postponed if we have to
* wait for the response.
*/
int
Index: openssh/auth2.c
@@ -122,7 +122,7 @@
x_authctxt = authctxt; /*XXX*/
- /* challenge-reponse is implemented via keyboard interactive */
+ /* challenge-response is implemented via keyboard interactive */
if (options.challenge_response_authentication)
options.kbd_interactive_authentication = 1;
if (options.pam_authentication_via_kbd_int)
@@ -344,7 +344,7 @@
return(0);
#endif
#ifdef USE_PAM
- return auth_pam_password(authctxt->pw, "");
+ return auth_pam_password(authctxt->pw, "", PAM_PROMPT_ECHO_OFF);
#elif defined(HAVE_OSF_SIA)
return 0;
#else /* !HAVE_OSF_SIA && !USE_PAM */
@@ -369,7 +369,7 @@
check_nt_auth(1, authctxt->pw->pw_uid) &&
#endif
#ifdef USE_PAM
- auth_pam_password(authctxt->pw, password) == 1)
+ auth_pam_password(authctxt->pw, password, PAM_PROMPT_ECHO_OFF) == 1)
#elif defined(HAVE_OSF_SIA)
auth_sia_password(authctxt->user, password) == 1)
#else /* !USE_PAM && !HAVE_OSF_SIA */
Index: openssh/servconf.c
@@ -83,6 +83,7 @@
options->password_authentication = -1;
options->kbd_interactive_authentication = -1;
options->challenge_response_authentication = -1;
+ options->tis_via_pam = -1;
options->permit_empty_passwd = -1;
options->use_login = -1;
options->allow_tcp_forwarding = -1;
@@ -234,7 +235,7 @@
#ifdef AFS
sAFSTokenPassing,
#endif
- sChallengeResponseAuthentication,
+ sChallengeResponseAuthentication, sTISviaPAM,
sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
sPrintMotd, sPrintLastLog, sIgnoreRhosts,
sX11Forwarding, sX11DisplayOffset,
@@ -286,6 +287,7 @@
{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
{ "challengeresponseauthentication", sChallengeResponseAuthentication },
{ "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
+ { "tisviapam", sTISviaPAM },
{ "checkmail", sDeprecated },
{ "listenaddress", sListenAddress },
{ "printmotd", sPrintMotd },
@@ -626,6 +628,10 @@
intptr = &options->challenge_response_authentication;
goto parse_flag;
+ case sTISviaPAM:
+ intptr = &options->tis_via_pam;
+ goto parse_flag;
+
case sPrintMotd:
intptr = &options->print_motd;
goto parse_flag;
Index: openssh/servconf.h
@@ -94,6 +94,7 @@
* authentication. */
int kbd_interactive_authentication; /* If true, permit */
int challenge_response_authentication;
+ int tis_via_pam; /* Use PAM for TIS? */
int permit_empty_passwd; /* If false, do not permit empty
* passwords. */
int use_login; /* If true, login(1) is used */
Index: openssh/sshconnect1.c
@@ -821,7 +821,7 @@
char prompt[1024];
char *challenge, *response;
- debug("Doing challenge reponse authentication.");
+ debug("Doing challenge response authentication.");
for (i = 0; i < options.number_of_password_prompts; i++) {
/* request a challenge */
@@ -849,7 +849,7 @@
if (options.cipher == SSH_CIPHER_NONE)
log("WARNING: Encryption is disabled! "
"Reponse will be transmitted in clear text.");
- response = read_passphrase(prompt, 0);
+ response = read_passphrase(prompt, RP_ECHO);
if (strcmp(response, "") == 0) {
xfree(response);
break;
Index: openssh/sshd.8
@@ -379,6 +379,12 @@
are supported.
The default is
.Dq yes .
+.It Cm TISviaPAM
+Specifies whether protocol version 1 challenge response authentication (TIS)
+should be handled via PAM. This is incompatible with with password
+authentication.
+The default is
+.Dq no .
.It Cm Ciphers
Specifies the ciphers allowed for protocol version 2.
Multiple ciphers must be comma-separated.
Index: openssh/sshd_config
@@ -52,6 +52,9 @@
# Uncomment to disable s/key passwords
#ChallengeResponseAuthentication no
+# Do ssh1 TIS authentication (challenge/response) via PAM?
+# ChallengeResponseAuthentication must be set for this to take effect.
+#TISviaPAM no
# Uncomment to enable PAM keyboard-interactive authentication
# Warning: enabling this may bypass the setting of 'PasswordAuthentication'
More information about the openssh-unix-dev
mailing list