[BACK]Return to auth-skey.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Diff for /src/usr.bin/ssh/Attic/auth-skey.c between version 1.9.2.1 and 1.9.2.2

version 1.9.2.1, 2001/02/16 20:12:52 version 1.9.2.2, 2001/09/27 00:15:41
Line 1 
Line 1 
 /*  /*
  * Copyright (c) 1999,2000 Markus Friedl.  All rights reserved.   * Copyright (c) 2001 Markus Friedl.  All rights reserved.
  *   *
  * Redistribution and use in source and binary forms, with or without   * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions   * modification, are permitted provided that the following conditions
Line 21 
Line 21 
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.   * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */   */
   
 #include "includes.h"  #include "includes.h"
 RCSID("$OpenBSD$");  RCSID("$OpenBSD$");
   
 #include "ssh.h"  #ifdef SKEY
 #include "packet.h"  
 #include <sha1.h>  
   
 /*  #include <skey.h>
  * try skey authentication,  
  * return 1 on success, 0 on failure, -1 if skey is not available  
  */  
   
 int  #include "xmalloc.h"
 auth_skey_password(struct passwd * pw, const char *password)  #include "auth.h"
   
   static void *
   skey_init_ctx(Authctxt *authctxt)
 {  {
         if (strncasecmp(password, "s/key", 5) == 0) {          return authctxt;
                 char *skeyinfo = skey_keyinfo(pw->pw_name);  
                 if (skeyinfo == NULL) {  
                         debug("generating fake skeyinfo for %.100s.",  
                             pw->pw_name);  
                         skeyinfo = skey_fake_keyinfo(pw->pw_name);  
                 }  
                 if (skeyinfo != NULL)  
                         packet_send_debug("%s", skeyinfo);  
                 /* Try again. */  
                 return 0;  
         } else if (skey_haskey(pw->pw_name) == 0 &&  
                    skey_passcheck(pw->pw_name, (char *) password) != -1) {  
                 /* Authentication succeeded. */  
                 return 1;  
         }  
         /* Fall back to ordinary passwd authentication. */  
         return -1;  
 }  }
   
 /* from %OpenBSD: skeylogin.c,v 1.32 1999/08/16 14:46:56 millert Exp % */  #define PROMPT "\nS/Key Password: "
   
 #define ROUND(x)   (((x)[0] << 24) + (((x)[1]) << 16) + (((x)[2]) << 8) + \  static int
                     ((x)[3]))  skey_query(void *ctx, char **name, char **infotxt,
       u_int* numprompts, char ***prompts, u_int **echo_on)
 /*  
  * hash_collapse()  
  */  
 static u_int32_t  
 hash_collapse(s)  
         u_char *s;  
 {  {
         int len, target;          Authctxt *authctxt = ctx;
         u_int32_t i;          char challenge[1024], *p;
           int len;
         if ((strlen(s) % sizeof(u_int32_t)) == 0)          struct skey skey;
                 target = strlen(s);    /* Multiple of 4 */  
         else  
                 target = strlen(s) - (strlen(s) % sizeof(u_int32_t));  
   
         for (i = 0, len = 0; len < target; len += 4)          if (skeychallenge(&skey, authctxt->user, challenge) == -1)
                 i ^= ROUND(s + len);                  return -1;
   
         return i;          *name       = xstrdup("");
           *infotxt    = xstrdup("");
           *numprompts = 1;
           *prompts = xmalloc(*numprompts * sizeof(char*));
           *echo_on = xmalloc(*numprompts * sizeof(u_int));
           (*echo_on)[0] = 0;
   
           len = strlen(challenge) + strlen(PROMPT) + 1;
           p = xmalloc(len);
           p[0] = '\0';
           strlcat(p, challenge, len);
           strlcat(p, PROMPT, len);
           (*prompts)[0] = p;
   
           return 0;
 }  }
   
 char *  static int
 skey_fake_keyinfo(char *username)  skey_respond(void *ctx, u_int numresponses, char **responses)
 {  {
         int i;          Authctxt *authctxt = ctx;
         u_int ptr;  
         u_char hseed[SKEY_MAX_SEED_LEN], flg = 1, *up;          if (authctxt->valid &&
         char pbuf[SKEY_MAX_PW_LEN+1];              numresponses == 1 &&
         static char skeyprompt[SKEY_MAX_CHALLENGE+1];              skey_haskey(authctxt->pw->pw_name) == 0 &&
         char *secret = NULL;              skey_passcheck(authctxt->pw->pw_name, responses[0]) != -1)
         size_t secretlen = 0;              return 0;
         SHA1_CTX ctx;          return -1;
         char *p, *u;  }
   
         /*  static void
          * Base first 4 chars of seed on hostname.  skey_free_ctx(void *ctx)
          * Add some filler for short hostnames if necessary.  {
          */          /* we don't have a special context */
         if (gethostname(pbuf, sizeof(pbuf)) == -1)  
                 *(p = pbuf) = '.';  
         else  
                 for (p = pbuf; *p && isalnum(*p); p++)  
                         if (isalpha(*p) && isupper(*p))  
                                 *p = tolower(*p);  
         if (*p && pbuf - p < 4)  
                 (void)strncpy(p, "asjd", 4 - (pbuf - p));  
         pbuf[4] = '\0';  
   
         /* Hash the username if possible */  
         if ((up = SHA1Data(username, strlen(username), NULL)) != NULL) {  
                 struct stat sb;  
                 time_t t;  
                 int fd;  
   
                 /* Collapse the hash */  
                 ptr = hash_collapse(up);  
                 memset(up, 0, strlen(up));  
   
                 /* See if the random file's there, else use ctime */  
                 if ((fd = open(_SKEY_RAND_FILE_PATH_, O_RDONLY)) != -1  
                     && fstat(fd, &sb) == 0 &&  
                     sb.st_size > (off_t)SKEY_MAX_SEED_LEN &&  
                     lseek(fd, ptr % (sb.st_size - SKEY_MAX_SEED_LEN),  
                     SEEK_SET) != -1 && read(fd, hseed,  
                     SKEY_MAX_SEED_LEN) == SKEY_MAX_SEED_LEN) {  
                         close(fd);  
                         fd = -1;  
                         secret = hseed;  
                         secretlen = SKEY_MAX_SEED_LEN;  
                         flg = 0;  
                 } else if (!stat(_PATH_MEM, &sb) || !stat("/", &sb)) {  
                         t = sb.st_ctime;  
                         secret = ctime(&t);  
                         secretlen = strlen(secret);  
                         flg = 0;  
                 }  
                 if (fd != -1)  
                         close(fd);  
         }  
   
         /* Put that in your pipe and smoke it */  
         if (flg == 0) {  
                 /* Hash secret value with username */  
                 SHA1Init(&ctx);  
                 SHA1Update(&ctx, secret, secretlen);  
                 SHA1Update(&ctx, username, strlen(username));  
                 SHA1End(&ctx, up);  
   
                 /* Zero out */  
                 memset(secret, 0, secretlen);  
   
                 /* Now hash the hash */  
                 SHA1Init(&ctx);  
                 SHA1Update(&ctx, up, strlen(up));  
                 SHA1End(&ctx, up);  
   
                 ptr = hash_collapse(up + 4);  
   
                 for (i = 4; i < 9; i++) {  
                         pbuf[i] = (ptr % 10) + '0';  
                         ptr /= 10;  
                 }  
                 pbuf[i] = '\0';  
   
                 /* Sequence number */  
                 ptr = ((up[2] + up[3]) % 99) + 1;  
   
                 memset(up, 0, 20); /* SHA1 specific */  
                 free(up);  
   
                 (void)snprintf(skeyprompt, sizeof skeyprompt,  
                               "otp-%.*s %d %.*s",  
                               SKEY_MAX_HASHNAME_LEN,  
                               skey_get_algorithm(),  
                               ptr, SKEY_MAX_SEED_LEN,  
                               pbuf);  
         } else {  
                 /* Base last 8 chars of seed on username */  
                 u = username;  
                 i = 8;  
                 p = &pbuf[4];  
                 do {  
                         if (*u == 0) {  
                                 /* Pad remainder with zeros */  
                                 while (--i >= 0)  
                                         *p++ = '0';  
                                 break;  
                         }  
   
                         *p++ = (*u++ % 10) + '0';  
                 } while (--i != 0);  
                 pbuf[12] = '\0';  
   
                 (void)snprintf(skeyprompt, sizeof skeyprompt,  
                               "otp-%.*s %d %.*s",  
                               SKEY_MAX_HASHNAME_LEN,  
                               skey_get_algorithm(),  
                               99, SKEY_MAX_SEED_LEN, pbuf);  
         }  
         return skeyprompt;  
 }  }
   
   KbdintDevice skey_device = {
           "skey",
           skey_init_ctx,
           skey_query,
           skey_respond,
           skey_free_ctx
   };
   #endif /* SKEY */

Legend:
Removed from v.1.9.2.1  
changed lines
  Added in v.1.9.2.2