URI: 
       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 }