]> mj.ucw.cz Git - eval.git/commitdiff
Moved md5crypt and pedant to utils/ and make them compile again.
authorMartin Mares <mj@ucw.cz>
Thu, 15 May 2008 09:38:15 +0000 (11:38 +0200)
committerMartin Mares <mj@ucw.cz>
Thu, 15 May 2008 09:38:15 +0000 (11:38 +0200)
Makefile
src/md5.c [deleted file]
src/md5.h [deleted file]
src/md5crypt.c [deleted file]
src/pedant.c [deleted file]
utils/Makefile [new file with mode: 0644]
utils/md5.c [new file with mode: 0644]
utils/md5.h [new file with mode: 0644]
utils/md5crypt.c [new file with mode: 0644]
utils/pedant.c [new file with mode: 0644]

index 1d2b6cb20dc446f1fda8dc0786fc2209bce8d157..3a68c0808e78039dd5d2309f8e520a2035e43b7c 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -22,6 +22,7 @@ include $(s)/sherlock/Makefile
 endif
 
 include $(s)/box/Makefile
+include $(s)/utils/Makefile
 
 # And finally the default rules of the build system
 include $(s)/build/Makebottom
diff --git a/src/md5.c b/src/md5.c
deleted file mode 100644 (file)
index 76a1460..0000000
--- a/src/md5.c
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * This code implements the MD5 message-digest algorithm.
- * The algorithm is due to Ron Rivest.  This code was
- * written by Colin Plumb in 1993, no copyright is claimed.
- * This code is in the public domain; do with it what you wish.
- *
- * Equivalent code is available from RSA Data Security, Inc.
- * This code has been tested against that, and is equivalent,
- * except that you don't need to include two pages of legalese
- * with every copy.
- *
- * To compute the message digest of a chunk of bytes, declare an
- * MD5Context structure, pass it to MD5Init, call MD5Update as
- * needed on buffers full of bytes, and then call MD5Final, which
- * will fill a supplied 16-byte array with the digest.
- */
-
-#include "md5.h"
-
-#include <string.h>            /* for memcpy() */
-#include <endian.h>
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-#define byteReverse(buf, len)  /* Nothing */
-#else
-void byteReverse(unsigned char *buf, unsigned longs);
-
-/*
- * Note: this code is harmless on little-endian machines.
- */
-void byteReverse(unsigned char *buf, unsigned longs)
-{
-    uint32 t;
-    do {
-       t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
-           ((unsigned) buf[1] << 8 | buf[0]);
-       *(uint32 *) buf = t;
-       buf += 4;
-    } while (--longs);
-}
-#endif
-
-/*
- * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
- * initialization constants.
- */
-void MD5Init(struct MD5Context *ctx)
-{
-    ctx->buf[0] = 0x67452301;
-    ctx->buf[1] = 0xefcdab89;
-    ctx->buf[2] = 0x98badcfe;
-    ctx->buf[3] = 0x10325476;
-
-    ctx->bits[0] = 0;
-    ctx->bits[1] = 0;
-}
-
-/*
- * Update context to reflect the concatenation of another buffer full
- * of bytes.
- */
-void MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len)
-{
-    uint32 t;
-
-    /* Update bitcount */
-
-    t = ctx->bits[0];
-    if ((ctx->bits[0] = t + ((uint32) len << 3)) < t)
-       ctx->bits[1]++;         /* Carry from low to high */
-    ctx->bits[1] += len >> 29;
-
-    t = (t >> 3) & 0x3f;       /* Bytes already in shsInfo->data */
-
-    /* Handle any leading odd-sized chunks */
-
-    if (t) {
-       unsigned char *p = (unsigned char *) ctx->in + t;
-
-       t = 64 - t;
-       if (len < t) {
-           memcpy(p, buf, len);
-           return;
-       }
-       memcpy(p, buf, t);
-       byteReverse(ctx->in, 16);
-       MD5Transform(ctx->buf, (uint32 *) ctx->in);
-       buf += t;
-       len -= t;
-    }
-    /* Process data in 64-byte chunks */
-
-    while (len >= 64) {
-       memcpy(ctx->in, buf, 64);
-       byteReverse(ctx->in, 16);
-       MD5Transform(ctx->buf, (uint32 *) ctx->in);
-       buf += 64;
-       len -= 64;
-    }
-
-    /* Handle any remaining bytes of data. */
-
-    memcpy(ctx->in, buf, len);
-}
-
-/*
- * Final wrapup - pad to 64-byte boundary with the bit pattern 
- * 1 0* (64-bit count of bits processed, MSB-first)
- */
-void MD5Final(unsigned char digest[16], struct MD5Context *ctx)
-{
-    unsigned count;
-    unsigned char *p;
-
-    /* Compute number of bytes mod 64 */
-    count = (ctx->bits[0] >> 3) & 0x3F;
-
-    /* Set the first char of padding to 0x80.  This is safe since there is
-       always at least one byte free */
-    p = ctx->in + count;
-    *p++ = 0x80;
-
-    /* Bytes of padding needed to make 64 bytes */
-    count = 64 - 1 - count;
-
-    /* Pad out to 56 mod 64 */
-    if (count < 8) {
-       /* Two lots of padding:  Pad the first block to 64 bytes */
-       memset(p, 0, count);
-       byteReverse(ctx->in, 16);
-       MD5Transform(ctx->buf, (uint32 *) ctx->in);
-
-       /* Now fill the next block with 56 bytes */
-       memset(ctx->in, 0, 56);
-    } else {
-       /* Pad block to 56 bytes */
-       memset(p, 0, count - 8);
-    }
-    byteReverse(ctx->in, 14);
-
-    /* Append length in bits and transform */
-    ((uint32 *) ctx->in)[14] = ctx->bits[0];
-    ((uint32 *) ctx->in)[15] = ctx->bits[1];
-
-    MD5Transform(ctx->buf, (uint32 *) ctx->in);
-    byteReverse((unsigned char *) ctx->buf, 4);
-    memcpy(digest, ctx->buf, 16);
-    memset((char *) ctx, 0, sizeof(ctx));      /* In case it's sensitive */
-}
-
-/* The four core functions - F1 is optimized somewhat */
-
-/* #define F1(x, y, z) (x & y | ~x & z) */
-#define F1(x, y, z) (z ^ (x & (y ^ z)))
-#define F2(x, y, z) F1(z, x, y)
-#define F3(x, y, z) (x ^ y ^ z)
-#define F4(x, y, z) (y ^ (x | ~z))
-
-/* This is the central step in the MD5 algorithm. */
-#define MD5STEP(f, w, x, y, z, data, s) \
-       ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
-
-/*
- * The core of the MD5 algorithm, this alters an existing MD5 hash to
- * reflect the addition of 16 longwords of new data.  MD5Update blocks
- * the data and converts bytes into longwords for this routine.
- */
-void MD5Transform(uint32 buf[4], uint32 const in[16])
-{
-    register uint32 a, b, c, d;
-
-    a = buf[0];
-    b = buf[1];
-    c = buf[2];
-    d = buf[3];
-
-    MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
-    MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
-    MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
-    MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
-    MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
-    MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
-    MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
-    MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
-    MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
-    MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
-    MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
-    MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
-    MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
-    MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
-    MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
-    MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
-
-    MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
-    MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
-    MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
-    MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
-    MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
-    MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
-    MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
-    MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
-    MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
-    MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
-    MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
-    MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
-    MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
-    MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
-    MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
-    MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
-
-    MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
-    MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
-    MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
-    MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
-    MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
-    MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
-    MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
-    MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
-    MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
-    MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
-    MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
-    MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
-    MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
-    MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
-    MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
-    MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
-
-    MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
-    MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
-    MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
-    MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
-    MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
-    MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
-    MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
-    MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
-    MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
-    MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
-    MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
-    MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
-    MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
-    MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
-    MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
-    MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
-
-    buf[0] += a;
-    buf[1] += b;
-    buf[2] += c;
-    buf[3] += d;
-}
diff --git a/src/md5.h b/src/md5.h
deleted file mode 100644 (file)
index 5775254..0000000
--- a/src/md5.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef MD5_H
-#define MD5_H
-
-#include <sys/types.h>
-
-typedef u_int32_t uint32;
-
-struct MD5Context {
-       uint32 buf[4];
-       uint32 bits[2];
-       unsigned char in[64];
-};
-
-void MD5Init(struct MD5Context *context);
-void MD5Update(struct MD5Context *context, unsigned char const *buf,
-              unsigned len);
-void MD5Final(unsigned char digest[16], struct MD5Context *context);
-void MD5Transform(uint32 buf[4], uint32 const in[16]);
-
-#endif /* !MD5_H */
diff --git a/src/md5crypt.c b/src/md5crypt.c
deleted file mode 100644 (file)
index de9694f..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * md5crypt based on lib/md5crypt.c from Linux shadow package.
- * adapted by Martin Mares <mj@ucw.cz> in June 2004
- * ----------------------------------------------------------------------------
- * "THE BEER-WARE LICENSE" (Revision 42):
- * <phk@login.dknet.dk> wrote this file.  As long as you retain this notice you
- * can do whatever you want with this stuff. If we meet some day, and you think
- * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
- * ----------------------------------------------------------------------------
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include "md5.h"
-
-static unsigned char itoa64[] =                /* 0 ... 63 => ascii - 64 */
-       "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
-
-static void
-to64(char *s, unsigned int v, int n)
-{
-  while (--n >= 0)
-    {
-      *s++ = itoa64[v&0x3f];
-      v >>= 6;
-    }
-}
-
-static char *
-libshadow_md5_crypt(const char *pw, const char *salt)
-{
-       static char     *magic = "$1$"; /*
-                                                * This string is magic for
-                                                * this algorithm.  Having
-                                                * it this way, we can get
-                                                * get better later on
-                                                */
-       static char     passwd[120], *p;
-       static const char *sp,*ep;
-       unsigned char   final[16];
-       int sl,pl,i,j;
-       struct MD5Context ctx,ctx1;
-       unsigned long l;
-
-       /* Refine the Salt first */
-       sp = salt;
-
-       /* If it starts with the magic string, then skip that */
-       if(!strncmp(sp,magic,strlen(magic)))
-               sp += strlen(magic);
-
-       /* It stops at the first '$', max 8 chars */
-       for(ep=sp;*ep && *ep != '$' && ep < (sp+8);ep++)
-               continue;
-
-       /* get the length of the true salt */
-       sl = ep - sp;
-
-       MD5Init(&ctx);
-
-       /* The password first, since that is what is most unknown */
-       MD5Update(&ctx,pw,strlen(pw));
-
-       /* Then our magic string */
-       MD5Update(&ctx,magic,strlen(magic));
-
-       /* Then the raw salt */
-       MD5Update(&ctx,sp,sl);
-
-       /* Then just as many characters of the MD5(pw,salt,pw) */
-       MD5Init(&ctx1);
-       MD5Update(&ctx1,pw,strlen(pw));
-       MD5Update(&ctx1,sp,sl);
-       MD5Update(&ctx1,pw,strlen(pw));
-       MD5Final(final,&ctx1);
-       for(pl = strlen(pw); pl > 0; pl -= 16)
-               MD5Update(&ctx,final,pl>16 ? 16 : pl);
-
-       /* Don't leave anything around in vm they could use. */
-       memset(final,0,sizeof final);
-
-       /* Then something really weird... */
-       for (j=0,i = strlen(pw); i ; i >>= 1)
-               if(i&1)
-                   MD5Update(&ctx, final+j, 1);
-               else
-                   MD5Update(&ctx, pw+j, 1);
-
-       /* Now make the output string */
-       strcpy(passwd,magic);
-       strncat(passwd,sp,sl);
-       strcat(passwd,"$");
-
-       MD5Final(final,&ctx);
-
-       /*
-        * and now, just to make sure things don't run too fast
-        * On a 60 Mhz Pentium this takes 34 msec, so you would
-        * need 30 seconds to build a 1000 entry dictionary...
-        */
-       for(i=0;i<1000;i++) {
-               MD5Init(&ctx1);
-               if(i & 1)
-                       MD5Update(&ctx1,pw,strlen(pw));
-               else
-                       MD5Update(&ctx1,final,16);
-
-               if(i % 3)
-                       MD5Update(&ctx1,sp,sl);
-
-               if(i % 7)
-                       MD5Update(&ctx1,pw,strlen(pw));
-
-               if(i & 1)
-                       MD5Update(&ctx1,final,16);
-               else
-                       MD5Update(&ctx1,pw,strlen(pw));
-               MD5Final(final,&ctx1);
-       }
-
-       p = passwd + strlen(passwd);
-
-       l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; to64(p,l,4); p += 4;
-       l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; to64(p,l,4); p += 4;
-       l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; to64(p,l,4); p += 4;
-       l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; to64(p,l,4); p += 4;
-       l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; to64(p,l,4); p += 4;
-       l =                    final[11]                ; to64(p,l,2); p += 2;
-       *p = '\0';
-
-       /* Don't leave anything around in vm they could use. */
-       memset(final,0,sizeof final);
-
-       return passwd;
-}
-
-int main(void)
-{
-  char pass[256], salt[10], rand[8];
-  int fd = open("/dev/urandom", O_RDONLY);
-  int n;
-  if (fd < 0)
-    {
-      fprintf(stderr, "unable to open /dev/urandom: %m\n");
-      return 1;
-    }
-  while (fgets(pass, sizeof(pass), stdin))
-    {
-      char *c = strchr(pass, '\n');
-      if (c)
-       *c = 0;
-      if (read(fd, rand, sizeof(rand)) != sizeof(rand))
-       {
-         fprintf(stderr, "Error reading /dev/urandom: %m\n");
-         return 1;
-       }
-      for (n=0; n<2; n++)
-       to64(salt+4*n, *(uint32 *)(rand+4*n), 4);
-      salt[8] = 0;
-      printf("%s\n", libshadow_md5_crypt(pass, salt));
-    }
-  return 0;
-}
diff --git a/src/pedant.c b/src/pedant.c
deleted file mode 100644 (file)
index bb33dd1..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- *     A Pedantic Check of Text Input/Output File Syntax
- *
- *     (c) 2005--2007 Martin Mares <mj@ucw.cz>
- */
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <getopt.h>
-
-static int max = -1;
-static int no_stats;
-static int line = 1;
-static int warn_total, warn_shown;
-
-static void warn(char *msg, ...)
-{
-#define NUM_TYPES 16
-  static char *seen[NUM_TYPES];
-  static int cnt[NUM_TYPES];
-  int type = 0;
-
-  va_list args;
-  va_start(args, msg);
-
-  warn_total++;
-  if (max >= 0)
-    {
-      for (type=0; type < NUM_TYPES && seen[type] && seen[type] != msg; type++)
-       ;
-      if (type >= NUM_TYPES)
-       goto done;
-      seen[type] = msg;
-      if (cnt[type]++ >= max)
-       goto done;
-    }
-  warn_shown++;
-  printf("Line %d: ", line);
-  vprintf(msg, args);
-  putchar('\n');
-done:
-  va_end(args);
-}
-
-static void check(void)
-{
-  int pos = 0;
-  int maxlen = 0;
-  int lastlen = -1;
-  int space = 0;
-  int c;
-  while ((c = getchar()) >= 0)
-    {
-      if (c == '\n')
-       {
-         if (space)
-           warn("Trailing spaces");
-         if (line == 1 && !pos)
-           warn("Leading empty line");
-         if (maxlen < pos)
-           maxlen = pos;
-         if (!lastlen && !pos)
-           warn("Consecutive empty lines");
-         lastlen = pos;
-         line++;
-         pos = space = 0;
-       }
-      else
-       {
-         if (c == ' ')
-           {
-             if (!pos)
-               warn("Leading spaces");
-             if (space == 1)
-               warn("Consecutive spaces");
-             space++;
-           }
-         else
-           {
-             space = 0;
-             if (c < ' ' || c >= 0x7f)
-               warn("Invalid character 0x%02x", c);
-           }
-         pos++;
-       }
-    }
-  if (pos)
-    warn("Incomplete line at the end of file");
-  else if (!lastlen)
-    {
-      line--;
-      warn("Trailing empty line");
-      line++;
-    }
-  if (warn_shown < warn_total)
-    printf("(and %d more warnings)\n", warn_total - warn_shown);
-  if (!no_stats)
-    printf("Found %d lines, the longest has %d chars\n", line-1, maxlen);
-}
-
-static void usage(void)
-{
-  fprintf(stderr, "Usage: pedant [-m <max>] [-s]\n");
-  exit(1);
-}
-
-int main(int argc, char **argv)
-{
-  int opt;
-  while ((opt = getopt(argc, argv, "m:s")) >= 0)
-    switch (opt)
-      {
-      case 'm':
-       max = atoi(optarg);
-       break;
-      case 's':
-       no_stats++;
-       break;
-      default:
-       usage();
-      }
-  if (optind < argc)
-    usage();
-
-  check();
-  return 0;
-}
diff --git a/utils/Makefile b/utils/Makefile
new file mode 100644 (file)
index 0000000..07a8369
--- /dev/null
@@ -0,0 +1,8 @@
+# Makefile for MO-Eval utilities
+# (c) 2008 Martin Mares <mj@ucw.cz>
+
+DIRS+=utils
+PROGS+=$(addprefix $(o)/utils/,md5crypt pedant)
+
+$(o)/utils/md5crypt: $(o)/utils/md5crypt.o $(o)/utils/md5.o
+$(o)/utils/pedant: $(o)/utils/pedant.o
diff --git a/utils/md5.c b/utils/md5.c
new file mode 100644 (file)
index 0000000..76a1460
--- /dev/null
@@ -0,0 +1,249 @@
+/*
+ * This code implements the MD5 message-digest algorithm.
+ * The algorithm is due to Ron Rivest.  This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, declare an
+ * MD5Context structure, pass it to MD5Init, call MD5Update as
+ * needed on buffers full of bytes, and then call MD5Final, which
+ * will fill a supplied 16-byte array with the digest.
+ */
+
+#include "md5.h"
+
+#include <string.h>            /* for memcpy() */
+#include <endian.h>
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define byteReverse(buf, len)  /* Nothing */
+#else
+void byteReverse(unsigned char *buf, unsigned longs);
+
+/*
+ * Note: this code is harmless on little-endian machines.
+ */
+void byteReverse(unsigned char *buf, unsigned longs)
+{
+    uint32 t;
+    do {
+       t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
+           ((unsigned) buf[1] << 8 | buf[0]);
+       *(uint32 *) buf = t;
+       buf += 4;
+    } while (--longs);
+}
+#endif
+
+/*
+ * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
+ * initialization constants.
+ */
+void MD5Init(struct MD5Context *ctx)
+{
+    ctx->buf[0] = 0x67452301;
+    ctx->buf[1] = 0xefcdab89;
+    ctx->buf[2] = 0x98badcfe;
+    ctx->buf[3] = 0x10325476;
+
+    ctx->bits[0] = 0;
+    ctx->bits[1] = 0;
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len)
+{
+    uint32 t;
+
+    /* Update bitcount */
+
+    t = ctx->bits[0];
+    if ((ctx->bits[0] = t + ((uint32) len << 3)) < t)
+       ctx->bits[1]++;         /* Carry from low to high */
+    ctx->bits[1] += len >> 29;
+
+    t = (t >> 3) & 0x3f;       /* Bytes already in shsInfo->data */
+
+    /* Handle any leading odd-sized chunks */
+
+    if (t) {
+       unsigned char *p = (unsigned char *) ctx->in + t;
+
+       t = 64 - t;
+       if (len < t) {
+           memcpy(p, buf, len);
+           return;
+       }
+       memcpy(p, buf, t);
+       byteReverse(ctx->in, 16);
+       MD5Transform(ctx->buf, (uint32 *) ctx->in);
+       buf += t;
+       len -= t;
+    }
+    /* Process data in 64-byte chunks */
+
+    while (len >= 64) {
+       memcpy(ctx->in, buf, 64);
+       byteReverse(ctx->in, 16);
+       MD5Transform(ctx->buf, (uint32 *) ctx->in);
+       buf += 64;
+       len -= 64;
+    }
+
+    /* Handle any remaining bytes of data. */
+
+    memcpy(ctx->in, buf, len);
+}
+
+/*
+ * Final wrapup - pad to 64-byte boundary with the bit pattern 
+ * 1 0* (64-bit count of bits processed, MSB-first)
+ */
+void MD5Final(unsigned char digest[16], struct MD5Context *ctx)
+{
+    unsigned count;
+    unsigned char *p;
+
+    /* Compute number of bytes mod 64 */
+    count = (ctx->bits[0] >> 3) & 0x3F;
+
+    /* Set the first char of padding to 0x80.  This is safe since there is
+       always at least one byte free */
+    p = ctx->in + count;
+    *p++ = 0x80;
+
+    /* Bytes of padding needed to make 64 bytes */
+    count = 64 - 1 - count;
+
+    /* Pad out to 56 mod 64 */
+    if (count < 8) {
+       /* Two lots of padding:  Pad the first block to 64 bytes */
+       memset(p, 0, count);
+       byteReverse(ctx->in, 16);
+       MD5Transform(ctx->buf, (uint32 *) ctx->in);
+
+       /* Now fill the next block with 56 bytes */
+       memset(ctx->in, 0, 56);
+    } else {
+       /* Pad block to 56 bytes */
+       memset(p, 0, count - 8);
+    }
+    byteReverse(ctx->in, 14);
+
+    /* Append length in bits and transform */
+    ((uint32 *) ctx->in)[14] = ctx->bits[0];
+    ((uint32 *) ctx->in)[15] = ctx->bits[1];
+
+    MD5Transform(ctx->buf, (uint32 *) ctx->in);
+    byteReverse((unsigned char *) ctx->buf, 4);
+    memcpy(digest, ctx->buf, 16);
+    memset((char *) ctx, 0, sizeof(ctx));      /* In case it's sensitive */
+}
+
+/* The four core functions - F1 is optimized somewhat */
+
+/* #define F1(x, y, z) (x & y | ~x & z) */
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1(z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+
+/* This is the central step in the MD5 algorithm. */
+#define MD5STEP(f, w, x, y, z, data, s) \
+       ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
+
+/*
+ * The core of the MD5 algorithm, this alters an existing MD5 hash to
+ * reflect the addition of 16 longwords of new data.  MD5Update blocks
+ * the data and converts bytes into longwords for this routine.
+ */
+void MD5Transform(uint32 buf[4], uint32 const in[16])
+{
+    register uint32 a, b, c, d;
+
+    a = buf[0];
+    b = buf[1];
+    c = buf[2];
+    d = buf[3];
+
+    MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
+    MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
+    MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
+    MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
+    MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
+    MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
+    MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
+    MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
+    MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
+    MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
+    MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
+    MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
+    MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
+    MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
+    MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
+    MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
+
+    MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
+    MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
+    MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
+    MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
+    MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
+    MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
+    MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
+    MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
+    MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
+    MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
+    MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
+    MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
+    MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
+    MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
+    MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
+    MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
+
+    MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
+    MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
+    MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
+    MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
+    MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
+    MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
+    MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
+    MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
+    MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
+    MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
+    MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
+    MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
+    MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
+    MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
+    MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
+    MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
+
+    MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
+    MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
+    MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
+    MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
+    MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
+    MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
+    MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
+    MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
+    MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
+    MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
+    MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
+    MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
+    MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
+    MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
+    MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
+    MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
+
+    buf[0] += a;
+    buf[1] += b;
+    buf[2] += c;
+    buf[3] += d;
+}
diff --git a/utils/md5.h b/utils/md5.h
new file mode 100644 (file)
index 0000000..5775254
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef MD5_H
+#define MD5_H
+
+#include <sys/types.h>
+
+typedef u_int32_t uint32;
+
+struct MD5Context {
+       uint32 buf[4];
+       uint32 bits[2];
+       unsigned char in[64];
+};
+
+void MD5Init(struct MD5Context *context);
+void MD5Update(struct MD5Context *context, unsigned char const *buf,
+              unsigned len);
+void MD5Final(unsigned char digest[16], struct MD5Context *context);
+void MD5Transform(uint32 buf[4], uint32 const in[16]);
+
+#endif /* !MD5_H */
diff --git a/utils/md5crypt.c b/utils/md5crypt.c
new file mode 100644 (file)
index 0000000..de9694f
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ * md5crypt based on lib/md5crypt.c from Linux shadow package.
+ * adapted by Martin Mares <mj@ucw.cz> in June 2004
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <phk@login.dknet.dk> wrote this file.  As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include "md5.h"
+
+static unsigned char itoa64[] =                /* 0 ... 63 => ascii - 64 */
+       "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+static void
+to64(char *s, unsigned int v, int n)
+{
+  while (--n >= 0)
+    {
+      *s++ = itoa64[v&0x3f];
+      v >>= 6;
+    }
+}
+
+static char *
+libshadow_md5_crypt(const char *pw, const char *salt)
+{
+       static char     *magic = "$1$"; /*
+                                                * This string is magic for
+                                                * this algorithm.  Having
+                                                * it this way, we can get
+                                                * get better later on
+                                                */
+       static char     passwd[120], *p;
+       static const char *sp,*ep;
+       unsigned char   final[16];
+       int sl,pl,i,j;
+       struct MD5Context ctx,ctx1;
+       unsigned long l;
+
+       /* Refine the Salt first */
+       sp = salt;
+
+       /* If it starts with the magic string, then skip that */
+       if(!strncmp(sp,magic,strlen(magic)))
+               sp += strlen(magic);
+
+       /* It stops at the first '$', max 8 chars */
+       for(ep=sp;*ep && *ep != '$' && ep < (sp+8);ep++)
+               continue;
+
+       /* get the length of the true salt */
+       sl = ep - sp;
+
+       MD5Init(&ctx);
+
+       /* The password first, since that is what is most unknown */
+       MD5Update(&ctx,pw,strlen(pw));
+
+       /* Then our magic string */
+       MD5Update(&ctx,magic,strlen(magic));
+
+       /* Then the raw salt */
+       MD5Update(&ctx,sp,sl);
+
+       /* Then just as many characters of the MD5(pw,salt,pw) */
+       MD5Init(&ctx1);
+       MD5Update(&ctx1,pw,strlen(pw));
+       MD5Update(&ctx1,sp,sl);
+       MD5Update(&ctx1,pw,strlen(pw));
+       MD5Final(final,&ctx1);
+       for(pl = strlen(pw); pl > 0; pl -= 16)
+               MD5Update(&ctx,final,pl>16 ? 16 : pl);
+
+       /* Don't leave anything around in vm they could use. */
+       memset(final,0,sizeof final);
+
+       /* Then something really weird... */
+       for (j=0,i = strlen(pw); i ; i >>= 1)
+               if(i&1)
+                   MD5Update(&ctx, final+j, 1);
+               else
+                   MD5Update(&ctx, pw+j, 1);
+
+       /* Now make the output string */
+       strcpy(passwd,magic);
+       strncat(passwd,sp,sl);
+       strcat(passwd,"$");
+
+       MD5Final(final,&ctx);
+
+       /*
+        * and now, just to make sure things don't run too fast
+        * On a 60 Mhz Pentium this takes 34 msec, so you would
+        * need 30 seconds to build a 1000 entry dictionary...
+        */
+       for(i=0;i<1000;i++) {
+               MD5Init(&ctx1);
+               if(i & 1)
+                       MD5Update(&ctx1,pw,strlen(pw));
+               else
+                       MD5Update(&ctx1,final,16);
+
+               if(i % 3)
+                       MD5Update(&ctx1,sp,sl);
+
+               if(i % 7)
+                       MD5Update(&ctx1,pw,strlen(pw));
+
+               if(i & 1)
+                       MD5Update(&ctx1,final,16);
+               else
+                       MD5Update(&ctx1,pw,strlen(pw));
+               MD5Final(final,&ctx1);
+       }
+
+       p = passwd + strlen(passwd);
+
+       l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; to64(p,l,4); p += 4;
+       l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; to64(p,l,4); p += 4;
+       l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; to64(p,l,4); p += 4;
+       l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; to64(p,l,4); p += 4;
+       l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; to64(p,l,4); p += 4;
+       l =                    final[11]                ; to64(p,l,2); p += 2;
+       *p = '\0';
+
+       /* Don't leave anything around in vm they could use. */
+       memset(final,0,sizeof final);
+
+       return passwd;
+}
+
+int main(void)
+{
+  char pass[256], salt[10], rand[8];
+  int fd = open("/dev/urandom", O_RDONLY);
+  int n;
+  if (fd < 0)
+    {
+      fprintf(stderr, "unable to open /dev/urandom: %m\n");
+      return 1;
+    }
+  while (fgets(pass, sizeof(pass), stdin))
+    {
+      char *c = strchr(pass, '\n');
+      if (c)
+       *c = 0;
+      if (read(fd, rand, sizeof(rand)) != sizeof(rand))
+       {
+         fprintf(stderr, "Error reading /dev/urandom: %m\n");
+         return 1;
+       }
+      for (n=0; n<2; n++)
+       to64(salt+4*n, *(uint32 *)(rand+4*n), 4);
+      salt[8] = 0;
+      printf("%s\n", libshadow_md5_crypt(pass, salt));
+    }
+  return 0;
+}
diff --git a/utils/pedant.c b/utils/pedant.c
new file mode 100644 (file)
index 0000000..bb33dd1
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ *     A Pedantic Check of Text Input/Output File Syntax
+ *
+ *     (c) 2005--2007 Martin Mares <mj@ucw.cz>
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <getopt.h>
+
+static int max = -1;
+static int no_stats;
+static int line = 1;
+static int warn_total, warn_shown;
+
+static void warn(char *msg, ...)
+{
+#define NUM_TYPES 16
+  static char *seen[NUM_TYPES];
+  static int cnt[NUM_TYPES];
+  int type = 0;
+
+  va_list args;
+  va_start(args, msg);
+
+  warn_total++;
+  if (max >= 0)
+    {
+      for (type=0; type < NUM_TYPES && seen[type] && seen[type] != msg; type++)
+       ;
+      if (type >= NUM_TYPES)
+       goto done;
+      seen[type] = msg;
+      if (cnt[type]++ >= max)
+       goto done;
+    }
+  warn_shown++;
+  printf("Line %d: ", line);
+  vprintf(msg, args);
+  putchar('\n');
+done:
+  va_end(args);
+}
+
+static void check(void)
+{
+  int pos = 0;
+  int maxlen = 0;
+  int lastlen = -1;
+  int space = 0;
+  int c;
+  while ((c = getchar()) >= 0)
+    {
+      if (c == '\n')
+       {
+         if (space)
+           warn("Trailing spaces");
+         if (line == 1 && !pos)
+           warn("Leading empty line");
+         if (maxlen < pos)
+           maxlen = pos;
+         if (!lastlen && !pos)
+           warn("Consecutive empty lines");
+         lastlen = pos;
+         line++;
+         pos = space = 0;
+       }
+      else
+       {
+         if (c == ' ')
+           {
+             if (!pos)
+               warn("Leading spaces");
+             if (space == 1)
+               warn("Consecutive spaces");
+             space++;
+           }
+         else
+           {
+             space = 0;
+             if (c < ' ' || c >= 0x7f)
+               warn("Invalid character 0x%02x", c);
+           }
+         pos++;
+       }
+    }
+  if (pos)
+    warn("Incomplete line at the end of file");
+  else if (!lastlen)
+    {
+      line--;
+      warn("Trailing empty line");
+      line++;
+    }
+  if (warn_shown < warn_total)
+    printf("(and %d more warnings)\n", warn_total - warn_shown);
+  if (!no_stats)
+    printf("Found %d lines, the longest has %d chars\n", line-1, maxlen);
+}
+
+static void usage(void)
+{
+  fprintf(stderr, "Usage: pedant [-m <max>] [-s]\n");
+  exit(1);
+}
+
+int main(int argc, char **argv)
+{
+  int opt;
+  while ((opt = getopt(argc, argv, "m:s")) >= 0)
+    switch (opt)
+      {
+      case 'm':
+       max = atoi(optarg);
+       break;
+      case 's':
+       no_stats++;
+       break;
+      default:
+       usage();
+      }
+  if (optind < argc)
+    usage();
+
+  check();
+  return 0;
+}