Commit | Line | Data |
---|---|---|
f8beb284 MW |
1 | /*Id:$*/ |
2 | /*Name:$*/ | |
3 | ||
4 | #include "stralloc.h" | |
5 | #include "surf.h" | |
6 | #include "uint32.h" | |
7 | #include "makehash.h" | |
8 | ||
9 | typedef struct { | |
10 | uint32 seed[32]; | |
11 | uint32 sum[8]; | |
12 | uint32 out[8]; | |
13 | uint32 in[12]; | |
14 | int todo; | |
15 | } surfpcs; | |
16 | ||
17 | #define SURFPCS_LEN 32 | |
18 | ||
19 | static void surfpcs_init(s,k) | |
20 | surfpcs *s; | |
21 | uint32 k[32]; | |
22 | { | |
23 | int i; | |
24 | for (i = 0;i < 32;++i) s->seed[i] = k[i]; | |
25 | for (i = 0;i < 8;++i) s->sum[i] = 0; | |
26 | for (i = 0;i < 12;++i) s->in[i] = 0; | |
27 | s->todo = 0; | |
28 | } | |
29 | ||
30 | static uint32 littleendian[8] = { | |
31 | 50462976, 117835012, 185207048, 252579084, | |
32 | 319951120, 387323156, 454695192, 522067228 | |
33 | } ; | |
34 | #define end ((unsigned char *) littleendian) | |
35 | ||
36 | #define data ((unsigned char *) s->in) | |
37 | #define outdata ((unsigned char *) s->out) | |
38 | ||
39 | static void surfpcs_addlc(s,x,n) | |
40 | /* modified from Dan's surfpcs_add by skipping ' ' & '\t' and */ | |
41 | /* case-independence */ | |
42 | surfpcs *s; | |
43 | unsigned char *x; | |
44 | unsigned int n; | |
45 | { | |
46 | register unsigned char ch; | |
47 | int i; | |
48 | while (n--) { | |
49 | ch = *x++; | |
50 | if (ch == ' ' || ch == '\t') continue; | |
51 | if (ch >= 'A' && ch <= 'Z') | |
52 | data[end[s->todo++]] = ch - 'A' + 'a'; | |
53 | else | |
54 | data[end[s->todo++]] = ch; | |
55 | if (s->todo == 32) { | |
56 | s->todo = 0; | |
57 | if (!++s->in[8]) | |
58 | if (!++s->in[9]) | |
59 | if (!++s->in[10]) | |
60 | ++s->in[11]; | |
61 | surf(s->out,s->in,s->seed); | |
62 | for (i = 0;i < 8;++i) | |
63 | s->sum[i] += s->out[i]; | |
64 | } | |
65 | } | |
66 | } | |
67 | ||
68 | static void surfpcs_out(s,h) | |
69 | surfpcs *s; | |
70 | unsigned char h[32]; | |
71 | { | |
72 | int i; | |
73 | surfpcs_addlc(s,".",1); | |
74 | while (s->todo) surfpcs_addlc(s,"",1); | |
75 | for (i = 0;i < 8;++i) s->in[i] = s->sum[i]; | |
76 | for (;i < 12;++i) s->in[i] = 0; | |
77 | surf(s->out,s->in,s->seed); | |
78 | for (i = 0;i < 32;++i) h[i] = outdata[end[i]]; | |
79 | } | |
80 | ||
81 | void makehash(indata,inlen,hash) | |
82 | char *indata; | |
83 | unsigned int inlen; | |
84 | char *hash; | |
85 | /* makes hash[COOKIE=20] from stralloc *indata, ignoring case and */ | |
86 | /* SPACE/TAB */ | |
87 | { | |
88 | unsigned char h[32]; | |
89 | surfpcs s; | |
90 | uint32 seed[32]; | |
91 | int i; | |
92 | ||
93 | for (i = 0;i < 32;++i) seed[i] = 0; | |
94 | surfpcs_init(&s,seed); | |
95 | surfpcs_addlc(&s,indata,inlen); | |
96 | surfpcs_out(&s,h); | |
97 | for (i = 0;i < 20;++i) | |
98 | hash[i] = 'a' + (h[i] & 15); | |
99 | } | |
100 | ||
101 | static stralloc dummy = {0}; | |
102 | ||
103 | void mkauthhash(s,len,h) | |
104 | char *s; unsigned int len; char *h; | |
105 | /* This is a string that should be the same for all messages from a given */ | |
106 | /* author. Doesn't have to be the real rfc822 address. We look for a '@' */ | |
107 | /* and grab everything up to the next '>', ' ', or ';'. We go back the same */ | |
108 | /* way, then take everything up to the '@' or the first '-'. The latter */ | |
109 | /* avoids problems with posters that band their addresses. */ | |
110 | { | |
111 | unsigned int i,j,k,l; | |
112 | register char ch; | |
113 | ||
114 | j = k = l = 0; | |
115 | i = byte_rchr(s,len,'@'); | |
116 | if (i < len) { /* if not then i=sa->len, j=k=l=0 */ | |
117 | j = i; | |
118 | while (++j < len) { /* if not found, then j=sa->len */ | |
119 | ch = s[j]; | |
120 | if (ch == '>' || ch == ' ' || ch == ';') break; | |
121 | } | |
122 | k = i; | |
123 | while (k > 0) { /* k <= i */ | |
124 | ch = s[--k]; | |
125 | if (ch == '<' || ch == ' ' || ch == ';') break; | |
126 | } | |
127 | l = k; /* k <= l <= i; */ | |
128 | while (l < i && s[l] != '-') ++l; | |
129 | if (!stralloc_copyb(&dummy,s + k, l - k)) die_nomem(); | |
130 | if (!stralloc_catb(&dummy,s + i, j - i)) die_nomem(); | |
131 | makehash(dummy.s,dummy.len,h); | |
132 | } else /* use entire line if no '@' found */ | |
133 | makehash(s,len,h); | |
134 | } | |
135 | ||
136 |