[Bug 118] New: Implement TIS (protocol 1) via PAM
bugzilla-daemon at mindrot.org
bugzilla-daemon at mindrot.org
Fri Feb 15 21:44:21 EST 2002
http://bugzilla.mindrot.org/show_bug.cgi?id=118
Summary: Implement TIS (protocol 1) via PAM
Product: Portable OpenSSH
Version: -current
Platform: All
OS/Version: All
Status: NEW
Severity: normal
Priority: P3
Component: sshd
AssignedTo: openssh-unix-dev at mindrot.org
ReportedBy: fcusack at fcusack.com
Currently, TIS is handled "natively" by sshd and only supports
S/Key. With this patch, TIS is done via PAM, which gives a lot
more flexibility on choice of "backend", eg you could do x9.9 tokens
with protocol 1.
It's a little bit less flexible if you have a server you want to
be capable of doing either C/R or password. You can't do both
via PAM in protocol 1. But the patch doesn't *break* doing both,
you need merely turn off the TISviaPAM option and you are limited
to the builtin S/Key for C/R.
I hope this cut/pastes ok.
This also fixes a bug in the current TIS handling, it turns echo on
when doing TIS.
diff -uNr openssh-3.0.2p1.orig/auth-pam.c openssh-3.0.2p1/auth-pam.c
--- openssh-3.0.2p1.orig/auth-pam.c Fri Nov 9 12:22:17 2001
+++ openssh-3.0.2p1/auth-pam.c Fri Feb 15 02:17:19 2002
@@ -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(
options.permit_empty_passwd == 0 ? PAM_DISALLOW_NULL_AUTHTOK : 0);
if (pam_retval == PAM_SUCCESS) {
diff -uNr openssh-3.0.2p1.orig/auth-pam.h openssh-3.0.2p1/auth-pam.h
--- openssh-3.0.2p1.orig/auth-pam.h Mon Mar 26 22:12:24 2001
+++ openssh-3.0.2p1/auth-pam.h Fri Feb 15 02:15:02 2002
@@ -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);
diff -uNr openssh-3.0.2p1.orig/auth1.c openssh-3.0.2p1/auth1.c
--- openssh-3.0.2p1.orig/auth1.c Tue Nov 13 04:46:19 2001
+++ openssh-3.0.2p1/auth1.c Fri Feb 15 02:15:02 2002
@@ -85,7 +85,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
@@ -252,7 +252,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,
@@ -269,6 +270,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);
@@ -279,6 +289,7 @@
packet_write_wait();
continue;
}
+ }
}
break;
case SSH_CMSG_AUTH_TIS_RESPONSE:
diff -uNr openssh-3.0.2p1.orig/auth2.c openssh-3.0.2p1/auth2.c
--- openssh-3.0.2p1.orig/auth2.c Tue Nov 13 04:46:19 2001
+++ openssh-3.0.2p1/auth2.c Fri Feb 15 02:20:36 2002
@@ -345,7 +345,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 */
@@ -370,7 +370,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 */
diff -uNr openssh-3.0.2p1.orig/servconf.c openssh-3.0.2p1/servconf.c
--- openssh-3.0.2p1.orig/servconf.c Tue Nov 13 05:03:15 2001
+++ openssh-3.0.2p1/servconf.c Fri Feb 15 02:15:05 2002
@@ -88,6 +88,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;
@@ -249,7 +250,7 @@
#ifdef AFS
sAFSTokenPassing,
#endif
- sChallengeResponseAuthentication,
+ sChallengeResponseAuthentication, sTISviaPAM,
sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
sPrintMotd, sPrintLastLog, sIgnoreRhosts,
sX11Forwarding, sX11DisplayOffset,
@@ -304,6 +305,7 @@
{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
{ "challengeresponseauthentication", sChallengeResponseAuthentication }, {
"skeyauthentication", sChallengeResponseAuthentication }, /* alias */
+ { "tisviapam", sTISviaPAM },
{ "checkmail", sDeprecated },
{ "listenaddress", sListenAddress },
{ "printmotd", sPrintMotd },
@@ -648,6 +650,10 @@
case sChallengeResponseAuthentication:
intptr = &options->challenge_response_authentication;
+ goto parse_flag;
+
+ case sTISviaPAM:
+ intptr = &options->tis_via_pam;
goto parse_flag;
case sPrintMotd:
diff -uNr openssh-3.0.2p1.orig/servconf.h openssh-3.0.2p1/servconf.h
--- openssh-3.0.2p1.orig/servconf.h Wed Sep 12 09:40:06 2001
+++ openssh-3.0.2p1/servconf.h Fri Feb 15 02:15:05 2002
@@ -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 */
diff -uNr openssh-3.0.2p1.orig/sshconnect1.c openssh-3.0.2p1/sshconnect1.c
--- openssh-3.0.2p1.orig/sshconnect1.c Tue Oct 9 22:03:12 2001
+++ openssh-3.0.2p1/sshconnect1.c Fri Feb 15 02:15:05 2002
@@ -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;
diff -uNr openssh-3.0.2p1.orig/sshd.8 openssh-3.0.2p1/sshd.8
--- openssh-3.0.2p1.orig/sshd.8 Sat Dec 1 15:37:08 2001
+++ openssh-3.0.2p1/sshd.8 Fri Feb 15 02:15:05 2002
@@ -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.
diff -uNr openssh-3.0.2p1.orig/sshd_config openssh-3.0.2p1/sshd_config
--- openssh-3.0.2p1.orig/sshd_config Thu Sep 20 16:15:44 2001
+++ openssh-3.0.2p1/sshd_config Fri Feb 15 02:15:05 2002
@@ -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'
------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.
More information about the openssh-unix-dev
mailing list