tstats.c - mixmaster - mixmaster 3.0 patched for libressl
HTML git clone git://parazyd.org/mixmaster.git
DIR Log
DIR Files
DIR Refs
DIR README
---
tstats.c (11869B)
---
1 /* Mixmaster version 3.0 -- (C) 1999 - 2006 Anonymizer Inc. and others.
2
3 Mixmaster may be redistributed and modified under certain conditions.
4 This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
5 ANY KIND, either express or implied. See the file COPYRIGHT for
6 details.
7
8 Remailer statistics
9 $Id: stats.c 934 2006-06-24 13:40:39Z rabbi $ */
10
11
12 #include "mix3.h"
13 #include <stdio.h>
14 #include <string.h>
15 #include <time.h>
16
17 /* log that a message of type t has been received. Statistics for type 2
18 messages are taken from the IDLOG instead of calling this function */
19 int stats_log(int t)
20 {
21 FILE *f;
22
23 f = mix_openfile(STATS, "a");
24 if (f == NULL) {
25 errlog(ERRORMSG, "Can't open %s!\n", STATS);
26 return (-1);
27 }
28 lock(f);
29 fprintf(f, "%d 1 %ld\n", t, (long) time(NULL));
30 unlock(f);
31 fclose(f);
32 return (0);
33 }
34
35 /* log the current pool size after sending messages */
36 int stats_out(int pool)
37 {
38 FILE *f;
39
40 if (REMAIL == 0)
41 return (0); /* don't keep statistics for the client */
42
43 f = mix_openfile(STATS, "a");
44 if (f == NULL) {
45 errlog(ERRORMSG, "Can't open %s!\n", STATS);
46 return (-1);
47 }
48 lock(f);
49 fprintf(f, "p 1 %d %ld\n", pool, (long) time(NULL));
50 unlock(f);
51 fclose(f);
52 return (0);
53 }
54
55 int stats(BUFFER *b)
56 {
57 FILE *s, *f;
58 char line[LINELEN];
59 long now, today, then;
60 time_t t;
61 long updated = 0, havestats = 0;
62 int msgd[7][24], msg[7][80];
63 /* 0 .. Unencrypted
64 * 1 .. Type I PGP
65 * 2 .. Mix
66 *
67 * 3 .. intermediate
68 * 4 .. final hop mail
69 * 5 .. final hop news
70 * 6 .. randhopped (will get counted in intermediate again)
71 */
72 int poold[2][24], pool[2][80];
73 int i, num, type, assigned, daysum;
74 char c;
75 idlog_t idbuf;
76
77 now = (time(NULL) / (60 * 60) + 1) * 60 * 60;
78 today = (now / SECONDSPERDAY) * SECONDSPERDAY;
79
80 for (i = 0; i < 24; i++)
81 msgd[0][i] = msgd[1][i] = msgd[2][i] = msgd[3][i] = msgd[4][i] = msgd[5][i] = msgd[6][i]= poold[0][i] = poold[1][i] = 0;
82 for (i = 0; i < 80; i++)
83 msg[0][i] = msg[1][i] = msg[2][i] = msg[3][i] = msg[4][i] = msg[5][i] = msg[6][i] = pool[0][i] = pool[1][i] = 0;
84
85 s = mix_openfile(STATS, "r");
86 if (s != NULL) {
87 lock(s);
88 fscanf(s, "%ld", &updated);
89 while (fgets(line, sizeof(line), s) != NULL) {
90 switch (line[0]) {
91 case '0':
92 case '1':
93 case '2':
94 case '3':
95 case '4':
96 case '5':
97 case '6':
98 c = '\0';
99 assigned = sscanf(line, "%d %d %ld %c", &type, &num, &then, &c);
100 daysum = (assigned == 4 && c == 'd');
101
102 if (now - then < 0 || (daysum && today - then < 0))
103 break; /* keep memory consistent even if the time
104 suddenly goes backwards :) */
105 if (now - then < SECONDSPERDAY && !daysum)
106 msgd[type][(now - then) / (60 * 60)] += num;
107 else if (today - then < 80 * SECONDSPERDAY)
108 msg[type][(today - then) / SECONDSPERDAY] += num;
109 if (havestats == 0 || then < havestats)
110 havestats = then;
111 break;
112 case 'p':
113 c = '\0';
114 assigned = sscanf(line, "p %d %d %ld %c", &num, &i, &then, &c);
115 daysum = (assigned == 4 && c == 'd');
116
117 if (now - then < 0 || (daysum && today - then < 0))
118 break;
119 if (now - then < SECONDSPERDAY && !daysum) {
120 poold[0][(now - then) / (60 * 60)] += num;
121 poold[1][(now - then) / (60 * 60)] += i;
122 } else if (today - then < 80 * SECONDSPERDAY) {
123 pool[0][(today - then) / (24 * 60 * 60)] += num;
124 pool[1][(today - then) / (24 * 60 * 60)] += i;
125 }
126 if (havestats == 0 || then < havestats)
127 havestats = then;
128 break;
129 }
130 }
131 unlock(s);
132 fclose(s);
133 }
134 f = mix_openfile(IDLOG, "rb");
135 if (f != NULL) {
136 while (fread(&idbuf, 1, sizeof(idlog_t), f) == sizeof(idlog_t)) {
137 then = idbuf.time;
138 if (then < updated || now - then < 0)
139 continue;
140 if (now - then < SECONDSPERDAY)
141 msgd[2][(now - then) / (60 * 60)]++;
142 else if (today - then < 80 * SECONDSPERDAY)
143 msg[2][(today - then) / SECONDSPERDAY]++;
144 if (havestats == 0 || then < havestats)
145 havestats = then;
146 }
147 fclose(f);
148 }
149 if (havestats == 0) {
150 if (b != NULL)
151 errlog(NOTICE, "No statistics available.\n");
152 return (-1);
153 }
154 s = mix_openfile(STATS, "w");
155 if (s == NULL) {
156 errlog(ERRORMSG, "Can't create %s!\n", STATS);
157 return (-1);
158 }
159 lock(s);
160 fprintf(s, "%ld\n", (long) time(NULL)); /* time of stats.log update */
161 for (i = 0; i < 24; i++) {
162 for (type = 0; type < 7; type++)
163 if (msgd[type][i] > 0)
164 fprintf(s, "%d %d %ld\n", type, msgd[type][i], now - i * 60 * 60);
165 if (poold[0][i] > 0)
166 fprintf(s, "p %d %d %ld\n", poold[0][i], poold[1][i], now - i * 60 * 60);
167 }
168 for (i = 0; i < 80; i++) {
169 for (type = 0; type < 7; type++)
170 if (msg[type][i] > 0)
171 fprintf(s, "%d %d %ld d\n", type, msg[type][i],
172 today - i * 24 * 60 * 60);
173 if (pool[0][i] > 0)
174 fprintf(s, "p %d %d %ld d\n", pool[0][i], pool[1][i],
175 today - i * 24 * 60 * 60);
176 }
177 unlock(s);
178 fclose(s);
179 if (b != NULL) {
180 struct tm *gt;
181
182 buf_sets(b, "Subject: Statistics for the ");
183 buf_appends(b, SHORTNAME);
184 buf_appends(b, " remailer\n\n");
185
186 buf_appends(b, "Number of messages in the past 24 hours:\n");
187 t = now;
188 gt = gmtime(&t);
189 for (i = 23; i >= 0; i--) {
190 buf_appendf(b, " %2dh: ", (24 + gt->tm_hour - i) % 24);
191 if (MIX) {
192 if (PGP || UNENCRYPTED)
193 buf_appends(b, " Mix:");
194 buf_appendf(b, "%4d", msgd[2][i]);
195 }
196 if (PGP)
197 buf_appendf(b, " PGP: %4d", msgd[1][i]);
198 if (UNENCRYPTED)
199 buf_appendf(b, " Unencrypted:%4d", msgd[0][i]);
200 if (poold[0][i] > 0)
201 buf_appendf(b, " [Pool size:%4d]", poold[1][i] / poold[0][i]);
202 #if 0
203 else
204 buf_appends(b, " [ no remailing ]");
205 #endif /* 0 */
206 buf_nl(b);
207 }
208 if ((today - havestats) / SECONDSPERDAY >= 1)
209 buf_appends(b, "\nNumber of messages per day:\n");
210 for ((i = (today - havestats) / SECONDSPERDAY) > 79 ? 79 : i;
211 i >= 1; i--) {
212 t = now - i * SECONDSPERDAY;
213 gt = gmtime(&t);
214 strftime(line, LINELEN, "%d %b: ", gt);
215 buf_appends(b, line);
216
217 if (MIX) {
218 if (PGP || UNENCRYPTED)
219 buf_appends(b, " Mix:");
220 buf_appendf(b, "%4d", msg[2][i]);
221 }
222 if (PGP)
223 buf_appendf(b, " PGP: %4d", msg[1][i]);
224 if (UNENCRYPTED)
225 buf_appendf(b, " Unencrypted:%4d", msg[0][i]);
226 if (STATSDETAILS) {
227 buf_appendf(b, " Intermediate:%4d", msg[3][i]);
228 buf_appendf(b, " Mail:%4d", msg[4][i]);
229 buf_appendf(b, " Postings:%4d", msg[5][i]);
230 if (MIDDLEMAN)
231 buf_appendf(b, " Randhopped:%4d", msg[6][i]);
232 }
233 if (pool[0][i] > 0)
234 buf_appendf(b, " [Pool size:%4d]", pool[1][i] / pool[0][i]);
235 #if 0
236 else
237 buf_appends(b, " [ no remailing ]");
238 #endif /* 0 */
239 buf_nl(b);
240 }
241 }
242 return (0);
243 }
244
245 int conf(BUFFER *out)
246 {
247 FILE *f;
248 BUFFER *b, *line;
249 int flag = 0;
250 REMAILER remailer[MAXREM];
251 int pgpkeyid[MAXREM];
252 int i, num;
253 char tmpline[LINELEN];
254
255 b = buf_new();
256 line = buf_new();
257
258 buf_sets(out, "Subject: Capabilities of the ");
259 buf_appends(out, SHORTNAME);
260 buf_appends(out, " remailer\n\n");
261 buf_appends(out, remailer_type);
262 buf_appends(out, VERSION);
263 buf_nl(out);
264
265 if (MIX + PGP + UNENCRYPTED == 1)
266 buf_appends(out, "Supported format:");
267 else
268 buf_appends(out, "Supported formats:\n");
269 if (MIX)
270 buf_appends(out, " Mixmaster\n");
271 if (PGP)
272 buf_appends(out, " Cypherpunk with PGP encryption\n");
273 if (UNENCRYPTED)
274 buf_appends(out, " Cypherpunk (unencrypted)\n");
275
276 buf_appendf(out, "Pool size: %d\n", POOLSIZE);
277 if (SIZELIMIT)
278 buf_appendf(out, "Maximum message size: %d kB\n", SIZELIMIT);
279
280 /* display destinations to which delivery is explicitly permitted
281 when in middleman mode (contents of DESTALLOW file.) */
282
283 if (MIDDLEMAN) {
284 f = mix_openfile(DESTALLOW, "r");
285 if (f != NULL) {
286 buf_read(b, f);
287 fclose(f);
288 while(buf_getline(b, line) != -1) {
289 if (line->length > 0 && line->data[0] != '#') {
290 if (flag == 0) {
291 buf_appends(out, "In addition to other remailers, this remailer also sends mail to these\n addresses directly:\n");
292 flag = 1;
293 }
294 buf_appendf(out, " %b\n", line);
295 }
296 }
297 }
298 }
299
300 flag = 0;
301 f = mix_openfile(HDRFILTER, "r");
302 if (f != NULL) {
303 buf_read(b, f);
304 fclose(f);
305 while(buf_getline(b, line) != -1)
306 if (line->length > 0 && line->data[0] != '#') {
307 if (flag == 0) {
308 buf_appends(out, "The following header lines will be filtered:\n");
309 flag = 1;
310 }
311 buf_appends(out, " ");
312 if (line->length > 3 && streq(line->data + line->length - 2, "/q")) {
313 buf_append(out, line->data, line->length - 1);
314 buf_appends(out, " => delete message");
315 }
316 else
317 buf_cat(out, line);
318 buf_nl(out);
319 }
320 buf_free(b);
321 }
322 flag = 0;
323 b = readdestblk( );
324 if ( b != NULL ) {
325 while(buf_getline(b, line) != -1)
326 if (line->length > 0 && !bufleft(line, "#") && !buffind(line, "@")) {
327 /* mail addresses are not listed */
328 if (flag == 0) {
329 if (NEWS[0])
330 buf_appends(out,
331 "The following newsgroups/domains are blocked:\n");
332 else
333 buf_appends(out, "The following domains are blocked:\n");
334 flag = 1;
335 }
336 buf_appendf(out, " %b\n", line);
337 }
338 if (flag == 0 && NEWS[0])
339 buf_appends(out, "Note that other newsgroups may be unavailable at the remailer's news server.\n");
340 }
341
342 buf_nl(out);
343 conf_premail(out);
344
345 if (LISTSUPPORTED) {
346 /* SUPPORTED CPUNK (TYPE I) REMAILERS
347 * 0xDC7532F9 "Heex Remailer <remailer@xmailer.ods.org>"
348 * 0x759ED311 "znar <ka5tkn@cox-internet.com>"
349 *
350 * SUPPORTED MIXMASTER (TYPE II) REMAILERS
351 * aarg remailer@aarg.net 475f3f9fe8da22896c10082695a92c2d 2.9b33 C
352 * anon mixmaster@anon.978.org 7384ba1eec585bfd7d2b0e9b307f0b1d 2.9b36 MCNm
353 */
354
355 buf_nl(out);
356 #ifdef USE_PGP
357 if (PGP) {
358 buf_appends(out, "SUPPORTED CPUNK (TYPE I) REMAILERS\n");
359 num = t1_rlist(remailer, NULL);
360 pgp_rkeylist(remailer, pgpkeyid, num);
361 for (i=1; i<=num; i++) {
362 if (remailer[i].flags.pgp) {
363 snprintf(tmpline, LINELEN, "0x%08X \"%s <%s>\"\n", pgpkeyid[i], remailer[i].name, remailer[i].addr);
364 tmpline[LINELEN-1] = '\0';
365 buf_appends(out, tmpline);
366 }
367 }
368 buf_nl(out);
369 }
370 #endif /* USE_PGP */
371 if (MIX) {
372 buf_appends(out, "SUPPORTED MIXMASTER (TYPE II) REMAILERS\n");
373 prepare_type2list(out);
374 buf_nl(out);
375 }
376 }
377
378
379 if ( b ) buf_free(b);
380 buf_free(line);
381 return (0);
382 }
383
384 void conf_premail(BUFFER *out)
385 {
386 buf_appends(out, "$remailer{\"");
387 buf_appends(out, SHORTNAME);
388 buf_appends(out, "\"} = \"<");
389 buf_appends(out, REMAILERADDR);
390 buf_appendc(out, '>');
391 if (PGP || UNENCRYPTED)
392 buf_appends(out, " cpunk max");
393 if (MIX)
394 buf_appends(out, " mix");
395 if (MIDDLEMAN)
396 buf_appends(out, " middle");
397 if (PGP)
398 buf_appends(out, " pgp");
399 if (PGP && !UNENCRYPTED)
400 buf_appends(out, " pgponly");
401 if (PGP && REPGP) {
402 if (REMIX == 1)
403 buf_appends(out, " repgp");
404 else
405 buf_appends(out, " repgp2");
406 }
407 if (REMIX == 1)
408 buf_appends(out, " remix");
409 else if (REMIX)
410 buf_appends(out, " remix2");
411 if (PGP || UNENCRYPTED)
412 buf_appends(out, " latent hash cut test");
413 if (PGP) {
414 #ifdef USE_IDEA
415 buf_appends(out, " ek");
416 #endif /* USE_IDEA */
417 buf_appends(out, " ekx");
418 }
419 #ifdef USE_IDEA
420 buf_appends(out, " esub");
421 #endif /* USE_IDEA */
422 #if 0 /* obsolete */
423 #ifdef USE_NSUB
424 buf_appends(out, " nsub");
425 #else /* end of USE_NSUB */
426 buf_appends(out, " ksub");
427 #endif /* else if not USE_NSUB */
428 #endif /* 0 */
429 if (INFLATEMAX)
430 buf_appendf(out, " inflt%d", INFLATEMAX);
431 if (MAXRANDHOPS)
432 buf_appendf(out, " rhop%d", MAXRANDHOPS);
433 if (POOLSIZE >= 5)
434 buf_appends(out, " reord");
435 if (NEWS[0])
436 buf_appends(out, " post");
437 if (SIZELIMIT)
438 buf_appendf(out, " klen%d", SIZELIMIT);
439 if (EXTFLAGS[0])
440 buf_appendf(out, " %s", EXTFLAGS);
441 buf_appends(out, "\";\n");
442 }