text: /*
   * asleap - recover weak LEAP passwords.  Pronounced "asleep".
   *
   * $Id: utils.c,v 1.5 2004/07/31 02:38:15 jwright Exp $
   *
   * Copyright (c) 2004, Joshua Wright <jwright@hasborg.com>
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License version 2 as
   * published by the Free Software Foundation. See COPYING for more
   * details.
   *
   * asleap is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   */
  
  /*
   * Significant code is graciously taken from the following:
   * MS-CHAPv2 and attack tools by Jochen Eisinger, Univ. of Freiburg
   * lamont_dump from nmap's utils.cc.  Thanks Fyodor.
   */
  
  #include <stdlib.h>
  #include <stdio.h>
  #include <stdarg.h>
  #include <string.h>
  #include <stdint.h>
  #include <crypt.h>
  #include <unistd.h>
  #include <ctype.h>
  #include <netinet/in.h> /* for ntohs() */
  #include "utils.h"
  
  
  void lamont_hdump(unsigned char *bp, unsigned int length);
  char *printmac(unsigned char *mac);
  
  /* A better version of hdump, from Lamont Granquist.  Modified slightly
     by Fyodor (fyodor@DHP.com) */
  void lamont_hdump(unsigned char *bp, unsigned int length) {
  
    /* stolen from tcpdump, then kludged extensively */
  
    static const char asciify[] = "................................ !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~.................................................................................................................................";
  
    const unsigned short *sp;
    const unsigned char *ap;
    unsigned int i, j;
    int nshorts, nshorts2;
    int padding;
  
    printf("\n\t");
    padding = 0;
    sp = (unsigned short *)bp;
    ap = (unsigned char *)bp;
    nshorts = (unsigned int) length / sizeof(unsigned short);
    nshorts2 = (unsigned int) length / sizeof(unsigned short);
    i = 0;
    j = 0;
    while(1) {
      while (--nshorts >= 0) {
        printf(" %04x", ntohs(*sp));
        sp++;
        if ((++i % 8) == 0)
          break;
      }
      if (nshorts < 0) {
        if ((length & 1) && (((i-1) % 8) != 0)) {
          printf(" %02x  ", *(unsigned char *)sp);
          padding++;
        }
        nshorts = (8 - (nshorts2 - nshorts));
        while(--nshorts >= 0) {
          printf("     ");
        }
        if (!padding) printf("     ");
      }
      printf("  ");
  
      while (--nshorts2 >= 0) {
        printf("%c%c", asciify[*ap], asciify[*(ap+1)]);
        ap += 2;
        if ((++j % 8) == 0) {
          printf("\n\t");
          break;
        }
      }
      if (nshorts2 < 0) {
        if ((length & 1) && (((j-1) % 8) != 0)) {
          printf("%c", asciify[*ap]);
        }
        break;
      }
    }
    if ((length & 1) && (((i-1) % 8) == 0)) {
      printf(" %02x", *(unsigned char *)sp);
      printf("                                       %c", asciify[*ap]);
    }
    printf("\n");
  }
  
  
  /*  taken from ppp/pppd/extra_crypto.c 
   *  Copyright (c) Tim Hockin, Cobalt Networks Inc. and others 
   */
  unsigned char Get7Bits(unsigned char *input, int startBit)
  {
      register unsigned int word;
  
      word = (unsigned) input[startBit / 8] << 8;
      word |= (unsigned) input[startBit / 8 + 1];
  
      word >>= 15 - (startBit % 8 + 7);
  
      return word & 0xFE;
  }
  
  
  void MakeKey(unsigned char *key, unsigned char *des_key)
  {
      des_key[0] = Get7Bits(key, 0);
      des_key[1] = Get7Bits(key, 7);
      des_key[2] = Get7Bits(key, 14);
      des_key[3] = Get7Bits(key, 21);
      des_key[4] = Get7Bits(key, 28);
      des_key[5] = Get7Bits(key, 35);
      des_key[6] = Get7Bits(key, 42);
      des_key[7] = Get7Bits(key, 49);
  
  }
  
  
  /* in == 8-byte string (expanded version of the 56-bit key)
   * out == 64-byte string where each byte is either 1 or 0
   * Note that the low-order "bit" is always ignored by by setkey()
   */
  void Expand(unsigned char *in, unsigned char *out)
  {
      int j, c;
      int i;
  
      for (i = 0; i < 64; in++) {
          c = *in;
          for (j = 7; j >= 0; j--)
              *out++ = (c >> j) & 1;
          i += 8;
      }
  }
  
  /* The inverse of Expand
   */
  void Collapse(unsigned char *in, unsigned char *out)
  {
      int j;
      int i;
      unsigned int c;
  
      for (i = 0; i < 64; i += 8, out++) {
          c = 0;
          for (j = 7; j >= 0; j--, in++)
              c |= *in << j;
          *out = c & 0xff;
      }
  }
  
  void
  DesEncrypt(unsigned char *clear, unsigned char *key, unsigned char *cipher)
  {
      unsigned char des_key[8];
      unsigned char crypt_key[66];
      unsigned char des_input[66];
  
      MakeKey(key, des_key);
  
      Expand(des_key, crypt_key);
      setkey(crypt_key);
  
      Expand(clear, des_input);
      encrypt(des_input, 0);
      Collapse(des_input, cipher);
  }
  
  int IsBlank(char *s) {
  
      int len, i;
      if (s == NULL) { 
          return(1); 
      }
  
      len = strlen(s);
  
      if (len == 0) { 
          return(1); 
      }
  
      for (i=0; i < len; i++) {
         if (s[i] != ' ') {
             return(0);
         }
      }
      return(0);
  }
  
  char *printmac(unsigned char *mac) {
      static char macstring[18];
  
      memset(&macstring, 0, sizeof(macstring));
      (void)snprintf(macstring, sizeof(macstring), 
          "%02x:%02x:%02x:%02x:%02x:%02x",
          mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
      return(macstring);
  }
  
  