Index: auth-passwd.c
Prereq:  1.23 
####### ssh-1.2.27-SDI/ => ssh-1.2.27-SDI
*** ssh-1.2.27-SDI/auth-passwd.c	Wed May 12 04:19:23 1999
--- ssh-1.2.27-SDI/auth-passwd.c	Mon May 17 15:38:08 1999
***************
*** 301,306 ****
--- 301,320 ----
  static int securid_initialized = 0;
  #endif /* HAVE_SECURID */
  
+ #ifdef HAVE_SDIAUTH
+ /* New Support for Security Dynamics SecurID card.
+    Contributed by Donald McKillican <dmckilli@qc.bell.ca>. 
+    Contributed by Jean Chouanard <chouanard@parc.xerox.com>. 
+ */
+ #include "sdi_athd.h"
+ #include "sdi_size.h"
+ #include "sdi_type.h"
+ #include "sdacmvls.h"
+ #include "sdconf.h"
+ union config_record configure;
+ static int securid_initialized = 0;
+ #endif /* HAVE_SDIAUTH */
+ 
  #ifdef KERBEROS
  #if defined(KRB5)
  #include <krb5.h>
***************
*** 721,730 ****
    /* If the user has no SecurID card specified, we fall to normal 
       password code. */
  #endif /* HAVE_SECURID */
  
    /* Save the encrypted password. */
    strncpy(correct_passwd, saved_pw_passwd, sizeof(correct_passwd));
! 
  #ifdef SECURE_RPC
    /* try to register secret key for secure RPC */
    seteuid(pw->pw_uid);       /* just let it fail if ran by user */
--- 735,807 ----
    /* If the user has no SecurID card specified, we fall to normal 
       password code. */
  #endif /* HAVE_SECURID */
+ #ifdef HAVE_SDIAUTH
+   if (options.sdi_authentication && options.sdi_compatforcemode ){
+   /* Jean Chouanard <chouanard@parc.xerox.com>
+    * Special case:
+    * SDIAuth and  SDIcompatforcemode are defined
+    * password Auth IS NOT
+    * The SDISDIcompatforcemode will change the behavior of the server, to be compatible w/
+    * the *old* client:
+    * The server will have to, using the password authetication handshake, challenge the 
+    * user for securID. Next token code and new pin mode are NOT handle.
+    */
+     /* We use the same existing code Contributed by Donald McKillican <dmckilli@qc.bell.ca>. */
  
+     struct SD_CLIENT sd_dat, *sd;    
+     FILE * pfdAcefile;
+     char szVarAce[256]; 
+     char pinsize[20], pintype[20];
+ 
+     
+ 
+     if (getenv("VAR_ACE") == NULL) {
+       pfdAcefile = fopen ("/etc/sdace.txt","r"); 
+       
+       if (pfdAcefile == NULL){
+ 	log_msg("SDI: Cannot read /etc/sdace.txt");
+ 	packet_disconnect("SDI: Cannot read /etc/sdace.txt");
+       }
+       
+       fscanf(pfdAcefile, "%s", szVarAce);
+       fclose(pfdAcefile);
+       
+       if (putenv(szVarAce)){
+ 	log_msg("SDI: Cannot putenv szVarAce");
+ 	packet_disconnect("SDI: Cannot putenv szVarAce");
+ 	
+       } 
+     } 
+     debug("SDI: Special case: we use passwd auth");
+     log_msg("SecurID authentication for %.100s required.", server_user);
+     
+     /*
+      * if no pass code has been supplied, fail immediately: passing
+      * a null pass code to sd_check causes a core dump
+      */
+     if (*password == '\0') 
+       {
+ 	log_msg("No pass code given, authentication rejected.");
+ 	return 0;
+       }
+     
+     sd = &sd_dat;
+     if (!securid_initialized)
+       {
+ 	memset(&sd_dat, 0, sizeof(sd_dat));   /* clear struct */
+ 	creadcfg();		/*  accesses sdconf.rec  */
+ 	if (sd_init(sd)) 
+ 	  packet_disconnect("Cannot contact securid server.");
+ 	securid_initialized = 1;
+       }
+     return sd_check(password, server_user, sd) == ACM_OK;
+     /*NOTREACHED*/
+   }
+ #endif /* HAVE_SDIAUTH */
+ 
    /* Save the encrypted password. */
    strncpy(correct_passwd, saved_pw_passwd, sizeof(correct_passwd));
!   
  #ifdef SECURE_RPC
    /* try to register secret key for secure RPC */
    seteuid(pw->pw_uid);       /* just let it fail if ran by user */
Index: config.h.in
####### ssh-1.2.27-SDI/ => ssh-1.2.27-SDI
*** ssh-1.2.27-SDI/config.h.in	Wed May 12 04:20:04 1999
--- ssh-1.2.27-SDI/config.h.in	Mon May 17 15:38:08 1999
***************
*** 181,186 ****
--- 181,193 ----
  #undef TTY_GROUP
  
  /* Define this if you want to support Security Dynammics SecurID
+    cards. New mode*/
+ #undef HAVE_SDIAUTH
+ /* Define this if you want to support Security Dynammics SecurID
+    cards. New mode. Client side only*/
+ #undef HAVE_SDICLAUTH
+ 
+ /* Define this if you want to support Security Dynammics SecurID
     cards. */
  #undef HAVE_SECURID
  
Index: configure
####### ssh-1.2.27-SDI/ => ssh-1.2.27-SDI
*** ssh-1.2.27-SDI/configure	Wed May 12 04:20:06 1999
--- ssh-1.2.27-SDI/configure	Mon May 17 15:38:09 1999
***************
*** 45,50 ****
--- 45,54 ----
  ac_help="$ac_help
    --with-nologin-allow[=PATH]     If a nologin.allow override should be used (default /etc/nologin.allow). "
  ac_help="$ac_help
+   --with-sdiauth[=PATH]   Enable *new* support for Security Dynamics SecurID card."
+ ac_help="$ac_help
+   --with-sdiclauth        Enable *new* support for Security Dynamics SecurID card, Client side only."
+ ac_help="$ac_help
    --with-securid[=PATH]   Enable support for Security Dynamics SecurID card."
  ac_help="$ac_help
    --with-tis[=DIR]        Enable support for TIS authentication server."
***************
*** 6540,6545 ****
--- 6544,6624 ----
     echo "$ac_t""no" 1>&6 
  
  fi
+ 
+ 
+ echo $ac_n "checking whether to support *new* SecurID""... $ac_c" 1>&6
+ echo "configure:6554: checking whether to support SecurID" >&5
+ # Check whether --with-sdiauth or --without-sdiauth was given.
+ if test "${with_sdiauth+set}" = set; then
+   withval="$with_sdiauth"
+    case "$withval" in
+   no)
+     echo "$ac_t""no" 1>&6
+     ;;
+   yes)
+     echo "$ac_t""yes" 1>&6
+     if test '!' -f /usr/ace/sdiclient.a; then
+       { echo "configure: error: SecurID sdiclient.a not found in /usr/ace: you must supply the path." 1>&2; exit 1; }
+     fi
+     echo "$ac_t""yes" 1>&6
+     echo "$ac_t""Assuming SecurID headers and libraries are in /usr/ace." 1>&6
+     cat >> confdefs.h <<\EOF
+ #define HAVE_SDIAUTH 1
+ EOF
+ 
+     CFLAGS="$CFLAGS -I/usr/ace"
+     LIBS="/usr/ace/sdiclient.a $LIBS"
+     ;;
+   *)
+     echo "$ac_t""yes" 1>&6
+     if test '!' -f $withval/sdiclient.a; then
+       { echo "configure: error: SecurID sdiclient.a not found in $withval: please supply the correct path." 1>&2; exit 1; }
+     fi
+     echo "$ac_t""Assuming SecurID headers and libraries are in $withval." 1>&6
+     cat >> confdefs.h <<\EOF
+ #define HAVE_SDIAUTH 1
+ #define HAVE_SDICLAUTH 1
+ EOF
+ 
+     CFLAGS="$CFLAGS -I$withval"
+     LIBS="$withval/sdiclient.a $LIBS"
+     ;;
+   esac 
+ else
+   echo "$ac_t""no" 1>&6
+ 
+ fi
+ 
+ echo $ac_n "checking whether to support *new* SecurID, Client side *only*""... $ac_c" 1>&6
+ echo "configure:6554: checking whether to support SecurID, client side" >&5
+ # Check whether --with-sdiclauth or --without-sdiclauth was given.
+ if test "${with_sdiclauth+set}" = set; then
+   withval="$with_sdiclauth"
+    case "$withval" in
+   no)
+     echo "$ac_t""no" 1>&6
+     ;;
+   yes)
+     echo "$ac_t""yes" 1>&6
+     echo "$ac_t""yes" 1>&6
+     cat >> confdefs.h <<\EOF
+ #define HAVE_SDICLAUTH 1
+ EOF
+ 
+     ;;
+   *)
+     echo "$ac_t""yes" 1>&6
+     echo "$ac_t""yes" 1>&6
+     cat >> confdefs.h <<\EOF
+ #define HAVE_SDICLAUTH 1
+ EOF
+ 
+     ;;
+   esac 
+ else
+   echo "$ac_t""no" 1>&6
+ 
+ fi
  
  
  echo $ac_n "checking whether to support SecurID""... $ac_c" 1>&6
Index: configure.in
####### ssh-1.2.27-SDI/ => ssh-1.2.27-SDI
*** ssh-1.2.27-SDI/configure.in	Wed May 12 04:20:02 1999
--- ssh-1.2.27-SDI/configure.in	Mon May 17 15:38:09 1999
***************
*** 857,862 ****
--- 857,917 ----
    [ AC_MSG_RESULT(no) ]
  )
  
+ AC_MSG_CHECKING(whether to support New SecurID Authentication)
+ AC_ARG_WITH(sdiauth,
+ [  --with-sdiauth[=PATH]   Enable support for Security Dynamics SecurID card as a new authentication.],
+ [ case "$withval" in
+   no)
+     AC_MSG_RESULT(no)
+     ;;
+   yes)
+     AC_MSG_RESULT(yes)
+     if test '!' -f /usr/ace/sdiclient.a; then
+       AC_ERROR(SecurID sdiclient.a not found in /usr/ace: you must supply the path.)
+     fi
+     AC_MSG_RESULT(yes)
+     AC_MSG_RESULT(Assuming SecurID headers and libraries are in /usr/ace.)
+     AC_DEFINE(HAVE_SDIAUTH)
+     AC_DEFINE(HAVE_SDICLAUTH)
+     CFLAGS="$CFLAGS -I/usr/ace"
+     LIBS="/usr/ace/sdiclient.a $LIBS"
+     ;;
+   *)
+     AC_MSG_RESULT(yes)
+     if test '!' -f $withval/sdiclient.a; then
+       AC_ERROR(SecurID sdiclient.a not found in $withval: please supply the correct path.)
+     fi
+     AC_MSG_RESULT(Assuming SecurID headers and libraries are in $withval.)
+     AC_DEFINE(HAVE_SDIAUTH)
+     AC_DEFINE(HAVE_SDICLAUTH)
+     CFLAGS="$CFLAGS -I$withval"
+     LIBS="$withval/sdiclient.a $LIBS"
+     ;;
+   esac ],
+   AC_MSG_RESULT(no)
+ )
+ 
+ AC_MSG_CHECKING(whether to support New SecurID Authentication, client side)
+ AC_ARG_WITH(sdiclauth,
+ [  --with-sdiclauth   Enable support for Security Dynamics SecurID card as a new authenticationn client side.],
+ [ case "$withval" in
+   no)
+     AC_MSG_RESULT(no)
+     ;;
+   yes)
+     AC_MSG_RESULT(yes)
+     AC_MSG_RESULT(yes)
+     AC_DEFINE(HAVE_SDICLAUTH)
+     ;;
+   *)
+     AC_MSG_RESULT(yes)
+     AC_MSG_RESULT(yes)
+     AC_DEFINE(HAVE_SDICLAUTH)
+     ;;
+   esac ],
+   AC_MSG_RESULT(no)
+ )
+ 
  AC_MSG_CHECKING(whether to support SecurID)
  AC_ARG_WITH(securid,
  [  --with-securid[=PATH]   Enable support for Security Dynamics SecurID card.],
Index: readconf.c
Prereq:  1.15 
####### ssh-1.2.27-SDI/ => ssh-1.2.27-SDI
*** ssh-1.2.27-SDI/readconf.c	Wed May 12 04:19:27 1999
--- ssh-1.2.27-SDI/readconf.c	Mon May 17 15:38:09 1999
***************
*** 172,177 ****
--- 172,180 ----
    oKeepAlives, oUsePrivilegedPort, oKerberosAuthentication,
    oKerberosTgtPassing, oClearAllForwardings, oNumberOfPasswordPrompts,
    oXauthPath, oGatewayPorts, oPasswordPromptLogin, oPasswordPromptHost
+ #ifdef HAVE_SDICLAUTH
+ ,  oSDIAuthentication
+ #endif /* HAVE_SDICLAUTH */
  } OpCodes;
  
  /* Textual representations of the tokens. */
***************
*** 219,224 ****
--- 222,230 ----
    { "gatewayports", oGatewayPorts },
    { "passwordpromptlogin", oPasswordPromptLogin },
    { "passwordprompthost", oPasswordPromptHost },
+ #ifdef HAVE_SDICLAUTH
+   { "sdiauthentication", oSDIAuthentication },
+ #endif /* HAVE_SDICLAUTH */
    { NULL, 0 }
  };
  
***************
*** 342,347 ****
--- 348,360 ----
        intptr = &options->tis_authentication;
        goto parse_flag;
        
+ #ifdef HAVE_SDICLAUTH
+     case oSDIAuthentication:
+       intptr = &options->sdi_authentication;
+       goto parse_flag;
+       
+ #endif /* HAVE_SDICLAUTH */
+ 
      case oRhostsRSAAuthentication:
        intptr = &options->rhosts_rsa_authentication;
        goto parse_flag;
***************
*** 708,713 ****
--- 721,729 ----
    options->no_user_given = 0;
    options->xauth_path = NULL;
    options->gateway_ports = -1;
+ #ifdef HAVE_SDICLAUTH
+   options->sdi_authentication = -1;
+ #endif /* HAVE_SDICLAUTH */
  }
  
  /* Called after processing other sources of option data, this fills those
***************
*** 736,742 ****
      options->kerberos_tgt_passing = 0;
  #endif /* defined(KERBEROS_TGT_PASSING) && defined(KRB5) */
    if (options->tis_authentication == -1)
!     options->tis_authentication = 0;
    if (options->password_authentication == -1)
      options->password_authentication = 1;
    if (options->rhosts_rsa_authentication == -1)
--- 752,758 ----
      options->kerberos_tgt_passing = 0;
  #endif /* defined(KERBEROS_TGT_PASSING) && defined(KRB5) */
    if (options->tis_authentication == -1)
!     options->tis_authentication = 1;
    if (options->password_authentication == -1)
      options->password_authentication = 1;
    if (options->rhosts_rsa_authentication == -1)
***************
*** 800,804 ****
--- 816,824 ----
  #endif  /* !XAUTH_PATH */
    if (options->gateway_ports == -1)
      options->gateway_ports = 0;
+ #ifdef HAVE_SDICLAUTH
+   if (options->sdi_authentication == -1)
+   options->sdi_authentication = 1;
+ #endif /* HAVE_SDICLAUTH */
  }
  
Index: readconf.h
Prereq:  1.10 
####### ssh-1.2.27-SDI/ => ssh-1.2.27-SDI
*** ssh-1.2.27-SDI/readconf.h	Wed May 12 04:19:27 1999
--- ssh-1.2.27-SDI/readconf.h	Mon May 17 15:38:09 1999
***************
*** 126,131 ****
--- 126,135 ----
    Forward remote_forwards[SSH_MAX_FORWARDS_PER_DIRECTION];
    char *xauth_path;
    int gateway_ports;
+ #ifdef HAVE_SDICLAUTH
+   /* SecurID option */
+   int sdi_authentication;	/* Try SDI authentication. */
+ #endif /* HAVE_SDICLAUTH */
  } Options;
  
  
Index: servconf.c
Prereq:  1.14 
####### ssh-1.2.27-SDI/ => ssh-1.2.27-SDI
*** ssh-1.2.27-SDI/servconf.c	Wed May 12 04:19:28 1999
--- ssh-1.2.27-SDI/servconf.c	Mon May 17 15:38:09 1999
***************
*** 122,127 ****
--- 122,131 ----
    options->num_deny_users = 0;
    options->num_allow_groups = 0;
    options->num_deny_groups = 0;
+ #ifdef HAVE_SDIAUTH
+   options->sdi_authentication = -1;
+   options->sdi_compatforcemode = -1;
+ #endif /* HAVE_SDIAUTH */
  #ifdef F_SECURE_COMMERCIAL
  
  
***************
*** 234,239 ****
--- 238,249 ----
      options->password_expire_warning_days = 14;
    if (options->account_expire_warning_days == -1)
      options->account_expire_warning_days = 14;
+ #ifdef HAVE_SDIAUTH
+   if (options->sdi_authentication == -1)
+     options->sdi_authentication = 0;
+   if (options->sdi_compatforcemode == -1)
+     options->sdi_compatforcemode = 0;
+ #endif /* HAVE_SDIAUTH */
  }
  
  #define WHITESPACE " \t\r\n="
***************
*** 253,258 ****
--- 263,271 ----
    sXauthPath, sCheckMail, sDenyGroups, sAllowGroups, sIgnoreRootRhosts,
    sAllowSHosts, sDenySHosts, sPasswordExpireWarningDays,
    sAccountExpireWarningDays
+ #ifdef HAVE_SDIAUTH
+    , sSDIAuthentication, sSDICompatforcemode
+ #endif /* HAVE_SDIAUTH */
  #ifdef F_SECURE_COMMERCIAL
  
  
***************
*** 289,294 ****
--- 302,311 ----
    { "denyusers", sDenyUsers },
    { "allowgroups", sAllowGroups },
    { "denygroups", sDenyGroups },
+ #ifdef HAVE_SDIAUTH
+   { "sdiauthentication", sSDIAuthentication },
+   { "sdicompatforcemode", sSDICompatforcemode },
+ #endif /* HAVE_SDIAUTH */
  #ifdef F_SECURE_COMMERCIAL
  
  
***************
*** 580,585 ****
--- 597,612 ----
  	  intptr = &options->tis_authentication;
  	  goto parse_flag;
  	  
+ #ifdef HAVE_SDIAUTH
+ 	case sSDIAuthentication:
+ 	  intptr = &options->sdi_authentication;
+ 	  goto parse_flag;
+ 	  
+ 	case sSDICompatforcemode:
+ 	  intptr = &options->sdi_compatforcemode;
+ 	  goto parse_flag;
+ #endif /* HAVE_SDIAUTH */
+ 	  
  	case sPasswordAuthentication:
  	  intptr = &options->password_authentication;
  	  goto parse_flag;
Index: servconf.h
Prereq:  1.11 
####### ssh-1.2.27-SDI/ => ssh-1.2.27-SDI
*** ssh-1.2.27-SDI/servconf.h	Wed May 12 04:19:28 1999
--- ssh-1.2.27-SDI/servconf.h	Mon May 17 15:38:09 1999
***************
*** 154,159 ****
--- 154,163 ----
  #endif /* F_SECURE_COMMERCIAL */
    int password_expire_warning_days;
    int account_expire_warning_days;
+ #ifdef HAVE_SDIAUTH
+   int sdi_authentication;	/* If true, permit SDI  auth. */
+   int sdi_compatforcemode;	/* If true, require SDI auth even w/ client supporting *only* passwordauth. */
+ #endif /* HAVE_SDIAUTH */
  } ServerOptions;
  
  /* Initializes the server options to special values that indicate that they
Index: ssh.1.in
Prereq:  1.18 
####### ssh-1.2.27-SDI/ => ssh-1.2.27-SDI
*** ssh-1.2.27-SDI/ssh.1.in	Wed May 12 04:19:30 1999
--- ssh-1.2.27-SDI/ssh.1.in	Mon May 17 15:38:09 1999
***************
*** 314,319 ****
--- 314,322 ----
  exist or the user is not found, the corresponding name in the TIS
  database is supposed to be the same.
  .LP
+ If HAVE_SDIAUTH was defined, SecurID authentication may be used. The Client
+ will handle correctly the "next token mode" and new PIN request". 
+ .LP
  If other authentication methods fail, 
  .B ssh
  prompts the user for a password.  The password is sent to the remote
***************
*** 903,908 ****
--- 906,918 ----
  "\fByes\fR", "\fBno\fR" or "\fBask\fR".
  .ne 3
  
+ .TP
+ .B SDIAuthentication
+ Specifies whether to try SecurID authentication.  The argument to this
+ keyword must be
+ .YN
+ .ne 3
+ 
  .TP
  .B TISAuthentication
  Specifies whether to try TIS authentication.  The argument to this
Index: ssh.h
Prereq:  1.27 
####### ssh-1.2.27-SDI/ => ssh-1.2.27-SDI
*** ssh-1.2.27-SDI/ssh.h	Wed May 12 04:19:28 1999
--- ssh-1.2.27-SDI/ssh.h	Mon May 17 15:38:09 1999
***************
*** 336,341 ****
--- 336,345 ----
  
  /* If you add new methods add them after this using random number between 16-31
     so if someone else adds also new methods you dont use same number. */
+ #ifdef HAVE_SDICLAUTH
+ #define SSH_AUTH_SDI	        16
+ #define SSH_AUTH_SDIPASS        17
+ #endif /* HAVE_SDICLAUTH */
  
  /* Protocol flags.  These are bit masks. */
  #define SSH_PROTOFLAG_SCREEN_NUMBER     1 /* X11 forwarding includes screen */
***************
*** 411,417 ****
--- 415,435 ----
     use some random number between 64-127 so if someone else adds something else
     you dont use same numbers */
  
+ /* Cleanner support of the newer securID protocol:
+  * will support next token mode and new pin required for example.
+  * Jean Chouanard <chouanard@parc.xerox.com>
+  */
+ #define SSH_CMSG_ACM_OK                         64
+ #define SSH_CMSG_ACM_ACCESS_DENIED              65
+ #define SSH_CMSG_ACM_NEXT_CODE_REQUIRED         66
+ #define SSH_CMSG_ACM_NEXT_CODE                  67
+ #define SSH_CMSG_ACM_NEW_PIN_REQUIRED           68
+ #define SSH_CMSG_ACM_NEW_PIN_ACCEPTED           69
+ #define SSH_CMSG_ACM_NEW_PIN_REJECTED           70
+ #define SSH_CMSG_ACM_NEW_PIN                    71
  
+ 
+ 
  /* define this and debug() will print local hostname */
  #define LOCAL_HOSTNAME_IN_DEBUG 1
  
Index: sshconnect.c
Prereq:  1.32 
####### ssh-1.2.27-SDI/ => ssh-1.2.27-SDI
*** ssh-1.2.27-SDI/sshconnect.c	Wed May 12 04:19:29 1999
--- ssh-1.2.27-SDI/sshconnect.c	Mon May 17 15:38:10 1999
***************
*** 201,206 ****
--- 201,207 ----
   * $Endlog$
   */
  
+ 
  #include "includes.h"
  #include <gmp.h>
  #include "xmalloc.h"
***************
*** 1293,1298 ****
--- 1294,1302 ----
    krb5_principal client;
  #endif
  #endif
+ #ifdef HAVE_SDICLAUTH
+   int sdiauth_tried = 0;
+ #endif /* HAVE_SDICLAUTH */
    
    /* Convert the user-supplied hostname into all lowercase. */
    host = xstrdup(orighost);
***************
*** 1723,1729 ****
--- 1727,1861 ----
                                     !options->batch_mode))
            return; /* Successful connection. */
      }
+ 
+ #ifdef HAVE_SDICLAUTH
+   /* Support for securID authentication 
+      with "next token mode" and "new pin required".
+      Contributed by Jean Chouanard <chouanard@parc.xerox.com> */
+ 
+   if ((supported_authentications & (1 << SSH_AUTH_SDI)) &&
+       options->sdi_authentication && !options->batch_mode)
+     {
+       char mprompt[128];
+       char *pin, *pin2;
+       char *pin_type;
+       char  *pin_size;
+       int pin_user_select;
+       char *p;
+ #define CANNOT_CHOOSE_PIN       0
+ #define USER_SELECTABLE         1
+ #define MUST_CHOOSE_PIN         2
+ 
+       debug("Doing SDI authentication.");
+       sdiauth_tried = 1;
+       if (options->cipher == SSH_CIPHER_NONE)
+ 	log_msg("WARNING: Encryption is disabled! Password will be transmitted in clear text.");
+       /* 
+        * We must challenge the ACE server with the couple
+        * Username//passcode. The answer is either binary: OK or DENIED 
+        * or will request an extra handshake for additionnal verification
+        * (Next token mode) or setup (New PIN required)
+        */
+ 
+       /* Always good to ask the PASSCODE :-) */
+       
+       password = read_passphrase(pw->pw_uid, "Passcode : ", 0);
+       packet_start(SSH_AUTH_SDI);
+       packet_put_string(password, strlen(password));
+       memset(password, 0, strlen(password));
+       xfree(password);
+       packet_send();
+       packet_write_wait();
+       
+       type = packet_read();
+       
+       switch(type)
+ 	{
+ 	case SSH_SMSG_SUCCESS:
+ 	  debug("SDI authentication accepted.");
+ 	  return; /* Successful connection. */
+ 	  break;
+ 	case SSH_SMSG_FAILURE:
+ 	  /* Authentication failure : the ACE server is not accessible */
+ 	  debug("SDI authentication failed.");
+ 	  break;
+ 	case SSH_CMSG_ACM_NEXT_CODE_REQUIRED:
+ 	  debug("SDI authentication NEXT_CODE_REQUIRED.");
+ 	  password = read_passphrase(pw->pw_uid, "Next Token is required.\n Wait for the Token to change, \n then enter the new Token displayed on your card.\n Next Token : ", 0);
+ 	  
+ 	  packet_start(SSH_CMSG_ACM_NEXT_CODE);
+ 	  packet_put_string(password, strlen(password));
+ 	  memset(password, 0, strlen(password));
+ 	  xfree(password);
+ 	  packet_send();
+ 	  packet_write_wait();
+ 	  type = packet_read();
+ 	  if (type == SSH_SMSG_SUCCESS)
+ 	    return; /* Successful connection. */
+ 	  if (type != SSH_SMSG_FAILURE)
+ 	    packet_disconnect("Protocol error: got %d in response to SDI next token",
+ 			      type);
+ 	  
+ 	  break;
+ 	case SSH_CMSG_ACM_NEW_PIN_REQUIRED:
+ 	  debug("SDI authentication NEW_PIN_REQUIRED.");
+ 	  read_confirmation("New PIN required; do you wish to continue? (yes/no): ");
+ 	  pin_type = packet_get_string(NULL);
+ 	  pin_size = packet_get_string(NULL);
+ 	  pin_user_select = packet_get_int();
+ 	  switch(pin_user_select)
+ 	    {
+ 	    case CANNOT_CHOOSE_PIN:
+ 	      debug("SDI authentication : Cannot handle CANNOT_CHOOSE_PIN.");
+ 	      packet_disconnect("SDI authentication : Cannot handle CANNOT_CHOOSE_PIN.");
+ 	    case USER_SELECTABLE:
+ 	    case MUST_CHOOSE_PIN:
+ 	      /*
+ 	       * It's *not* clean: we treat USER_SELECTABLE as if it was MUST_CHOOSE_PIN
+ 	       * But it's better than nothing!
+ 	       */
+ 	      snprintf(mprompt,sizeof(mprompt), "\n\tEnter your new PIN, containing %.4s %.40s :",
+ 		      pin_size, pin_type);
+ 	      pin = read_passphrase(pw->pw_uid,mprompt, 0);
+ 	      pin2 = read_passphrase(pw->pw_uid,"\tPlease re-enter new PIN: ",0);
+ 	      for (p = pin; (*p = tolower(*p)); p++);
+ 	      for (p = pin2; (*p = tolower(*p)); p++);
+ 	      if ((strlen(pin) == strlen(pin2)) && (*pin != '\0') && (memcmp(pin, pin2, strlen(pin)) == 0)){
+ 		/* PIN seems ok, go on */
+ 		  
+ 		packet_start(SSH_CMSG_ACM_NEW_PIN);
+ 		packet_put_string(pin,strlen(pin));
+ 		packet_send();
+ 		packet_write_wait();
+ 		/*
+ 		 * Wait for the answer of the sshd server
+ 		 */
+ 		type = packet_read();
+ 		if (type != SSH_CMSG_ACM_NEW_PIN_ACCEPTED){
+ 		  /* PIN incorrect or do not match */
+ 		  fatal("PIN rejected.\n");
+ 		}else{
+ 		  /*
+ 		   * New PIN was accepted. Need now the next token :-(
+ 		   */
+ 		  fatal("New PIN accepted. Wait for the code on your token to change before using it.");
+ 		}
+ 	      }else{
+ 		fatal("PIN do not match. Please try again.\n");
+ 	      }
+ 	    default:
+ 	      break;
+ 	    }
+ 	  break;
+ 	case SSH_CMSG_ACM_ACCESS_DENIED:
+ 	  break;
+ 	default:
+ 	  break;
+ 	}
+     }
    
+ #endif /* HAVE_SDICLAUTH */
+ 
    /* Support for TIS authentication server
       Contributed by Andre April <Andre.April@cediti.be>. */
    /* Try Tis authentication daemon if the server supports it. */
***************
*** 1769,1776 ****
--- 1901,1918 ----
      }
    
    /* Try password authentication if the server supports it. */
+ #ifdef HAVE_SDICLAUTH
+   /* 
+    * Old client without new securID support will use this to send there securID passcode,
+    * if the server support securid and compatforcemode.
+    */
+   
+   if (((supported_authentications & (1 << SSH_AUTH_PASSWORD)&&!(supported_authentications & (1 << SSH_AUTH_SDIPASS))) || (!sdiauth_tried && (supported_authentications & (1 << SSH_AUTH_SDIPASS)) && ((supported_authentications & (1 << SSH_AUTH_SDI)) && !options->sdi_authentication) )) &&
+       options->password_authentication && !options->batch_mode)
+ #else  
    if ((supported_authentications & (1 << SSH_AUTH_PASSWORD)) &&
        options->password_authentication && !options->batch_mode)
+ #endif /* HAVE_SDICLAUTH */
      {
        char prompt[80];
        debug("Doing password authentication.");
Index: sshd.8.in
Prereq:  1.21 
####### ssh-1.2.27-SDI/ => ssh-1.2.27-SDI
*** ssh-1.2.27-SDI/sshd.8.in	Wed May 12 04:19:31 1999
--- ssh-1.2.27-SDI/sshd.8.in	Mon May 17 15:38:10 1999
***************
*** 210,216 ****
  Next, the server and the client enter an authentication dialog.  The
  client tries to authenticate itself using \|\s+2.\s0rhosts
  authentication, \|\s+2.\s0rhosts authentication combined with RSA host
! authentication, RSA challenge-response authentication, TIS channenge
  response authentication, or password
  based authentication.
  .LP
--- 210,216 ----
  Next, the server and the client enter an authentication dialog.  The
  client tries to authenticate itself using \|\s+2.\s0rhosts
  authentication, \|\s+2.\s0rhosts authentication combined with RSA host
! authentication, RSA challenge-response authentication, TIS challenge
  response authentication, or password
  based authentication.
  .LP
***************
*** 678,683 ****
--- 678,696 ----
  LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7.  The default is DAEMON.
  
  .TP
+ .B SDIAuthentication
+ Specifies wether authentication through Security Dynamics
+ .B ACE
+ (8) server is allowed. The default is "no".
+ 
+ .TP
+ .B SDICompatforcemode
+ Specifies, if SDIAuthentication is set to yes, if we should try the 
+ PasswordAuthentication protocol to check securID. It enable new server
+ to require securID even with old clients.
+ The default is "no".
+ 
+ .TP
  .B TISAuthentication
  Specifies wether authentication through TIS
  .B authsrv
Index: sshd.c
Prereq:  1.61 
####### ssh-1.2.27-SDI/ => ssh-1.2.27-SDI
*** ssh-1.2.27-SDI/sshd.c	Wed May 12 04:19:29 1999
--- ssh-1.2.27-SDI/sshd.c	Mon May 17 15:50:31 1999
***************
*** 547,552 ****
--- 547,564 ----
  char *ticket = "none\0";
  #endif /* KERBEROS */
  
+ 
+ #ifdef HAVE_SDIAUTH
+ /* SecurID include files */
+ #include "sdi_athd.h"
+ #include "sdi_size.h"
+ #include "sdi_type.h"
+ #include "sdi_defs.h"
+ #include "sdconf.h"
+ #include "sdacmvls.h"
+ #endif /* HAVE_SDIAUTH */
+ 
+ 
  /* Server configuration options. */
  ServerOptions options;
  
***************
*** 1470,1475 ****
--- 1482,1499 ----
    if (options.tis_authentication)
      auth_mask |= 1 << SSH_AUTH_TIS;
  #endif
+ #ifdef HAVE_SDIAUTH
+   if (options.sdi_authentication){
+     auth_mask |= 1 << SSH_AUTH_SDI;
+     if (options.sdi_compatforcemode){
+       /* New client wo/ SDIAuth */
+       auth_mask |= 1 << SSH_AUTH_SDIPASS;
+       /* Old client */
+       auth_mask |= 1 << SSH_AUTH_PASSWORD;
+     }
+   }
+ #endif /* HAVE_SDIAUTH */
+ 
  #ifdef KERBEROS
  #ifdef KRB5
    if (options.kerberos_authentication)
***************
*** 2162,2172 ****
    const char *ipaddr;
    char *cap_hlist, *hp;
    int perm_denied = 0;
!   
    hostname = get_canonical_hostname();
    ipaddr = get_remote_ipaddr();
  #endif /* HAVE_LOGIN_CAP_H */
  
    if (strlen(user) > 255)
      do_authentication_fail_loop();
  
--- 2186,2200 ----
    const char *ipaddr;
    char *cap_hlist, *hp;
    int perm_denied = 0;
! 
    hostname = get_canonical_hostname();
    ipaddr = get_remote_ipaddr();
  #endif /* HAVE_LOGIN_CAP_H */
  
+ #ifdef HAVE_SDIAUTH
+   int sdiauth_tried = 0;
+ #endif
+   
    if (strlen(user) > 255)
      do_authentication_fail_loop();
  
***************
*** 2267,2272 ****
--- 2295,2302 ----
    else
      {
        /* Indicate that authentication is needed. */
+       debug("Authentication needed for %.100s.", user);
+   
        packet_start(SSH_SMSG_FAILURE);
        packet_send();
        packet_write_wait();
***************
*** 2483,2488 ****
--- 2513,2717 ----
            }
            break;
  
+ #ifdef HAVE_SDIAUTH
+ 	case SSH_AUTH_SDI:
+ 	  /* Support for securID authentication (version > 3.x)
+ 	     with "next token mode" and "new pin required".
+ 	     Contributed by Jean Chouanard <chouanard@parc.xerox.com> */
+ 	  
+ 	  if (!options.sdi_authentication) {
+ 	    packet_get_all();
+ 	    log_msg("SDI authsrv authentication disabled.");
+ 	    break;
+ 	  } else {  
+ 	    
+ 	    struct SD_CLIENT sd_dat, *sd;
+ 	    int ret;
+ 	    
+ 	    char buf[128];
+ 	    char prompt[128];
+ 	    char inbuf[128];
+ 	    char passcode[LENPRNST + 4];
+ 	    char *key, *value, *resp;  
+ 	    FILE * pfdAcefile;
+ 	    char szVarAce[256]; 
+ 	    char pinsize[20], pintype[20];
+ #define CANCELLED    1
+ 	    
+ 	    sdiauth_tried = 1;
+ 	    if (getenv("VAR_ACE") == NULL) {
+ 	      pfdAcefile = fopen ("/etc/sdace.txt","r"); 
+ 	      if (pfdAcefile == NULL){
+ 		log_msg("SDI: Cannot read /etc/sdace.txt");
+ 		packet_start(SSH_SMSG_FAILURE);
+ 		packet_send();
+ 		packet_write_wait();
+ 		break;
+ 	      }
+ 	      fscanf(pfdAcefile, "%s", szVarAce);
+ 	      fclose(pfdAcefile);
+ 	      if (putenv(szVarAce)){
+ 		log_msg("SDI: Cannot putenv szVarAce");
+ 		packet_start(SSH_SMSG_FAILURE);
+ 	      packet_send();
+ 	      packet_write_wait();
+ 	      break;
+ 	      } 
+ 	    } 
+ 	    memset(&sd_dat, 0, sizeof(sd_dat));   /* clear struct */
+ 	    sd = &sd_dat;
+ 	    if(creadcfg())  /* access sdconf.rec */
+ 	      {
+ 		log_msg("SDI: Cannot readcfg");
+ 		packet_start(SSH_SMSG_FAILURE);
+ 		packet_send();
+ 		packet_write_wait();
+ 		break;
+ 	      }  
+ 	    if (sd_init(sd)) /* initialize socket */
+ 	      {
+ 		log_msg("SDI: Cannot init");
+ 		packet_start(SSH_SMSG_FAILURE);
+ 		packet_send();
+ 		packet_write_wait();
+ 		break;
+ 	      }  
+ 
+ 	    /*
+ 	     * Lets challenge the ACE server with the
+ 	     * couple user//passcode
+ 	     */  
+ 	    password = packet_get_string(NULL);
+ 	    memcpy(passcode, password, LENPRNST + 4);  
+ 	    ret = sd_check(passcode, user, sd);
+ 	    switch (ret) { 
+ 	    case ACM_OK:  
+ 	      log_msg("SDI authentication for %.100s accepted.",user);
+ 	      memset(password, 0, strlen(password)); 
+ 	      xfree(password);
+ 	      authentication_type = SSH_AUTH_SDI;
+ 	      authenticated = 1;
+ 	      break;
+ 	    case ACM_ACCESS_DENIED:
+ 	      debug("SDI authentication for %.100s failed: ACCESS_DENIED",user);
+ 	      memset(password, 0, strlen(password));
+ 	      xfree(password);
+ 	      break;
+ 	    case ACM_NEXT_CODE_REQUIRED:
+ 	      debug("SDI Next code required for %.100s",user);
+ 	      packet_start(SSH_CMSG_ACM_NEXT_CODE_REQUIRED);
+ 	      packet_send();
+ 	      packet_write_wait();
+ 	      type = packet_read();
+ 	      if (type != SSH_CMSG_ACM_NEXT_CODE ){
+ 		packet_get_all();
+ 		log_msg("Protocol error: got %d in respsonse to SDI Next code challenge",
+ 			type);
+ 		break;
+ 	      }
+ 	      /*
+ 	       * we have the next token
+ 	       * lets check it
+ 	       */
+ 	      memset(password, 0, strlen(password));
+ 	      xfree(password);
+ 	      password = packet_get_string(NULL);
+ 	      memcpy(passcode, password, LENPRNST + 4); 
+ 	      if (sd_next(passcode, sd) == ACM_OK){
+ 		memset(password, 0, strlen(password)); 
+ 		xfree(password);
+ 		authentication_type = SSH_AUTH_SDI;
+ 		authenticated = 1;
+ 		break;
+ 	      }else{
+ 		debug("SDI next token for %s failed",user);
+ 		memset(password, 0, strlen(password));
+ 		xfree(password);
+ 		break;
+ 	      }
+ 	      break;
+ 	    case ACM_NEW_PIN_REQUIRED:
+ 	      /*
+ 	       * We can cancel all CANNOT_CHOOSE_PIN
+ 	       * As the we don't handle automatic PIN generation
+ 	       */
+ 	      debug("SDI New PIN required for %.100s.",user);
+ 	      if (sd->user_selectable == CANNOT_CHOOSE_PIN)
+ 		sd_pin("", CANCELLED, sd);
+ 		
+ 	      if (sd->alphanumeric)
+ 		strcpy(pintype, "characters");
+ 	      else 
+ 		strcpy(pintype, "digits");
+ 	      if (sd->min_pin_len == sd->max_pin_len)
+ 		snprintf(pinsize, sizeof(pinsize), "%.4d", sd->min_pin_len);
+ 	      else 
+ 		snprintf(pinsize, sizeof(pinsize), "%.4d to %.4d", sd->min_pin_len, sd->max_pin_len);
+ 	      packet_start(SSH_CMSG_ACM_NEW_PIN_REQUIRED);
+ 	      packet_put_string(pintype,strlen(pintype));
+ 	      packet_put_string(pinsize,strlen(pinsize));
+ 	      packet_put_int(sd->user_selectable);
+ 	      packet_send();
+ 	      packet_write_wait();
+ 	      /*
+ 	       * Get the new PIN
+ 	       */
+ 	      
+ 	      type = packet_read();
+ 	      if (type != SSH_CMSG_ACM_NEW_PIN) {
+ 		packet_get_all();
+ 		sd_pin("", CANCELLED, sd);
+ 		log_msg("Protocol error: got %d in respsonse to NEW_PIN_REQUIRED",
+ 			type);
+ 		break;
+ 	      }
+ 	      password = packet_get_string(NULL);
+ 	      /*
+ 	       * Call the ACE server to validate the new PIN
+ 	       */
+ 	      memcpy(inbuf, password,128);
+ 	      memset(password, 0, strlen(password));
+ 	      xfree(password);
+ 	      if (check_pin(inbuf, sd) == 0){
+ 		/*
+ 		 * PIN incorrect
+ 		 */
+ 		debug("SDI check_pin() failed for user %.100s",user);
+ 		memset(inbuf, 0, strlen(inbuf));
+ 		packet_start(SSH_CMSG_ACM_NEW_PIN_REJECTED);
+ 		packet_send();
+ 		packet_write_wait();
+ 		exit(254);
+ 		break;
+ 	      }
+ 	      if (sd_pin(inbuf, 0, sd)== ACM_NEW_PIN_ACCEPTED){
+ 		debug("SDI sd_pin() for %.100s accepted.",user);
+ 		memset(inbuf, 0, strlen(inbuf));
+ 		packet_start(SSH_CMSG_ACM_NEW_PIN_ACCEPTED);
+ 		packet_send();
+ 		packet_write_wait();
+ 		exit(0);
+ 		
+ 		break;
+ 	      }	   
+ 	      /*
+ 	       * PIN rejected 
+ 	       */
+ 	      debug("SDI sd_pin() for %.100s failed",user);
+ 	      memset(inbuf, 0, strlen(inbuf));
+ 	      packet_start(SSH_CMSG_ACM_NEW_PIN_REJECTED);
+ 	      packet_send();
+ 	      packet_write_wait();
+ 	      exit(254);
+ 
+ 	      break;
+ 	    
+ 	    default:
+ 	    }
+ 	  }
+ 	  break;
+ #endif /*HAVE_SDIAUTH */
+ 
  #ifdef HAVE_TIS
          case SSH_CMSG_AUTH_TIS:
            /* Support for TIS authentication server
***************
*** 2568,2574 ****
              if (!strncmp(buf, "challenge ", 10) ||
                  !strncmp(buf, "chalnecho ", 10)) {
                snprintf(prompt, sizeof(prompt),
!                        "Challenge \"%.100s\": ",&buf[10]);
                debug("TIS challenge %.500s", buf);
                packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE);
                packet_put_string(prompt, strlen(prompt));
--- 2797,2803 ----
              if (!strncmp(buf, "challenge ", 10) ||
                  !strncmp(buf, "chalnecho ", 10)) {
                snprintf(prompt, sizeof(prompt),
!                        "Challenge %.100s ",&buf[10]);
                debug("TIS challenge %.500s", buf);
                packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE);
                packet_put_string(prompt, strlen(prompt));
***************
*** 2622,2629 ****
  #endif
          case SSH_CMSG_AUTH_PASSWORD:
            if (!options.password_authentication)
!             {
!               packet_get_all();
                log_msg("Password authentication disabled.");
                break;
              }
--- 2851,2872 ----
  #endif
          case SSH_CMSG_AUTH_PASSWORD:
            if (!options.password_authentication)
! #ifdef HAVE_SDIAUTH
! 	    /* Jean Chouanard <chouanard@parc.xerox.com>
! 	     * Special case:
! 	     * SDIAuth and  SDIcompatforcemode are defined
! 	     * password Auth IS NOT
! 	     * The SDIcompatforcemode will change the behavior of the server, to be compatible w/
! 	     * the *old* client:
! 	     * The server will have to, using the password authetication handshake, challenge the 
! 	     * user for securID. Next token code and new pin mode are NOT handle.
! 	     */
! 	    
! 	    if ((!options.sdi_authentication) || (!options.sdi_compatforcemode) || (sdiauth_tried) ){
! #else
! 	    {
! #endif
! 	      packet_get_all();
                log_msg("Password authentication disabled.");
                break;
              }
