X-Git-Url: https://git.distorted.org.uk/~mdw/ezmlm/blobdiff_plain/5b62e993b0af39700031c2875d7f6654e6a02850..f8beb284087c279acfb30506f5bb32baa4949b44:/makehash.c diff --git a/makehash.c b/makehash.c new file mode 100644 index 0000000..efa4971 --- /dev/null +++ b/makehash.c @@ -0,0 +1,136 @@ +/*Id:$*/ +/*Name:$*/ + +#include "stralloc.h" +#include "surf.h" +#include "uint32.h" +#include "makehash.h" + +typedef struct { + uint32 seed[32]; + uint32 sum[8]; + uint32 out[8]; + uint32 in[12]; + int todo; +} surfpcs; + +#define SURFPCS_LEN 32 + +static void surfpcs_init(s,k) +surfpcs *s; +uint32 k[32]; +{ + int i; + for (i = 0;i < 32;++i) s->seed[i] = k[i]; + for (i = 0;i < 8;++i) s->sum[i] = 0; + for (i = 0;i < 12;++i) s->in[i] = 0; + s->todo = 0; +} + +static uint32 littleendian[8] = { + 50462976, 117835012, 185207048, 252579084, + 319951120, 387323156, 454695192, 522067228 +} ; +#define end ((unsigned char *) littleendian) + +#define data ((unsigned char *) s->in) +#define outdata ((unsigned char *) s->out) + +static void surfpcs_addlc(s,x,n) + /* modified from Dan's surfpcs_add by skipping ' ' & '\t' and */ + /* case-independence */ +surfpcs *s; +unsigned char *x; +unsigned int n; +{ + register unsigned char ch; + int i; + while (n--) { + ch = *x++; + if (ch == ' ' || ch == '\t') continue; + if (ch >= 'A' && ch <= 'Z') + data[end[s->todo++]] = ch - 'A' + 'a'; + else + data[end[s->todo++]] = ch; + if (s->todo == 32) { + s->todo = 0; + if (!++s->in[8]) + if (!++s->in[9]) + if (!++s->in[10]) + ++s->in[11]; + surf(s->out,s->in,s->seed); + for (i = 0;i < 8;++i) + s->sum[i] += s->out[i]; + } + } +} + +static void surfpcs_out(s,h) +surfpcs *s; +unsigned char h[32]; +{ + int i; + surfpcs_addlc(s,".",1); + while (s->todo) surfpcs_addlc(s,"",1); + for (i = 0;i < 8;++i) s->in[i] = s->sum[i]; + for (;i < 12;++i) s->in[i] = 0; + surf(s->out,s->in,s->seed); + for (i = 0;i < 32;++i) h[i] = outdata[end[i]]; +} + +void makehash(indata,inlen,hash) +char *indata; +unsigned int inlen; +char *hash; + /* makes hash[COOKIE=20] from stralloc *indata, ignoring case and */ + /* SPACE/TAB */ +{ + unsigned char h[32]; + surfpcs s; + uint32 seed[32]; + int i; + + for (i = 0;i < 32;++i) seed[i] = 0; + surfpcs_init(&s,seed); + surfpcs_addlc(&s,indata,inlen); + surfpcs_out(&s,h); + for (i = 0;i < 20;++i) + hash[i] = 'a' + (h[i] & 15); +} + +static stralloc dummy = {0}; + +void mkauthhash(s,len,h) +char *s; unsigned int len; char *h; +/* This is a string that should be the same for all messages from a given */ +/* author. Doesn't have to be the real rfc822 address. We look for a '@' */ +/* and grab everything up to the next '>', ' ', or ';'. We go back the same */ +/* way, then take everything up to the '@' or the first '-'. The latter */ +/* avoids problems with posters that band their addresses. */ +{ + unsigned int i,j,k,l; + register char ch; + + j = k = l = 0; + i = byte_rchr(s,len,'@'); + if (i < len) { /* if not then i=sa->len, j=k=l=0 */ + j = i; + while (++j < len) { /* if not found, then j=sa->len */ + ch = s[j]; + if (ch == '>' || ch == ' ' || ch == ';') break; + } + k = i; + while (k > 0) { /* k <= i */ + ch = s[--k]; + if (ch == '<' || ch == ' ' || ch == ';') break; + } + l = k; /* k <= l <= i; */ + while (l < i && s[l] != '-') ++l; + if (!stralloc_copyb(&dummy,s + k, l - k)) die_nomem(); + if (!stralloc_catb(&dummy,s + i, j - i)) die_nomem(); + makehash(dummy.s,dummy.len,h); + } else /* use entire line if no '@' found */ + makehash(s,len,h); +} + +