/[pkg-mixmaster]/trunk/Mix/Src/mix.c
ViewVC logotype

Contents of /trunk/Mix/Src/mix.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 219 - (hide annotations) (download)
Fri Sep 6 11:34:10 2002 UTC (10 years, 8 months ago) by weaselp
File MIME type: text/plain
File size: 28680 byte(s)
Allow setting dummy parameters
1 rabbi 1 /* Mixmaster version 3 -- (C) 1999 Anonymizer Inc.
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     Mixmaster initialization, configuration
9 weaselp 219 $Id: mix.c,v 1.25 2002/09/06 11:34:10 weaselp Exp $ */
10 rabbi 1
11    
12     #include "mix3.h"
13     #include <stdlib.h>
14     #include <stdio.h>
15     #include <string.h>
16     #include <stdarg.h>
17     #include <ctype.h>
18     #include <time.h>
19     #include <sys/types.h>
20     #include <sys/stat.h>
21     #ifdef POSIX
22 weaselp 177 #include <signal.h>
23 rabbi 1 #include <unistd.h>
24     #include <pwd.h>
25     #include <sys/utsname.h>
26     #else
27     #include <io.h>
28     #include <direct.h>
29     #endif
30     #ifdef WIN32
31     #include <windows.h>
32     #endif
33     #include <assert.h>
34     #include "menu.h"
35    
36     int buf_vappendf(BUFFER *b, char *fmt, va_list args);
37    
38 weaselp 105 /** filenames ************************************************************/
39 weaselp 177 char MIXCONF[PATHMAX];
40     char DISCLAIMFILE[PATHMAX];
41     char FROMDSCLFILE[PATHMAX];
42     char MSGFOOTERFILE[PATHMAX];
43     char POP3CONF[PATHMAX];
44     char HELPFILE[PATHMAX];
45     char ABUSEFILE[PATHMAX];
46     char REPLYFILE[PATHMAX];
47     char USAGEFILE[PATHMAX];
48     char USAGELOG[PATHMAX];
49     char BLOCKFILE[PATHMAX];
50     char ADMKEYFILE[PATHMAX];
51     char KEYFILE[PATHMAX];
52     char PGPKEY[PATHMAX];
53     char DSAPARAMS[PATHMAX];
54     char DHPARAMS[PATHMAX];
55     char MIXRAND[PATHMAX];
56     char SECRING[PATHMAX];
57     char PUBRING[PATHMAX];
58     char IDLOG[PATHMAX];
59     char STATS[PATHMAX];
60     char DESTBLOCK[PATHMAX];
61     char DESTALLOW[PATHMAX];
62     char SOURCEBLOCK[PATHMAX];
63     char HDRFILTER[PATHMAX];
64     char REGULAR[PATHMAX];
65     char POOL[PATHMAX];
66     char TYPE1LIST[PATHMAX];
67     char TYPE2REL[PATHMAX];
68     char TYPE2LIST[PATHMAX];
69 weaselp 197 char PIDFILE[PATHMAX];
70 weaselp 105
71 weaselp 177 char PGPREMPUBRING[PATHMAX];
72     char PGPREMPUBASC[PATHMAX];
73     char PGPREMSECRING[PATHMAX];
74     char NYMSECRING[PATHMAX];
75     char NYMDB[PATHMAX];
76 weaselp 105
77    
78 rabbi 1 /** config ***************************************************************/
79    
80     char MIXDIR[PATHMAX];
81     char POOLDIR[PATHMAX];
82    
83     /* programs */
84 weaselp 177 char SENDMAIL[LINELEN];
85 rabbi 1 char SENDANONMAIL[LINELEN];
86     char NEWS[LINELEN];
87     char TYPE1[LINELEN];
88    
89     /* addresses */
90 weaselp 177 char MAILtoNEWS[LINELEN];
91     char REMAILERNAME[LINELEN];
92     char ANONNAME[LINELEN];
93 rabbi 1 char REMAILERADDR[LINELEN];
94     char ANONADDR[LINELEN];
95     char COMPLAINTS[LINELEN];
96     int AUTOREPLY;
97     char SMTPRELAY[LINELEN];
98    
99     #ifdef USE_SOCK
100     char HELONAME[LINELEN];
101     char ENVFROM[LINELEN];
102 weaselp 177 int POP3DEL;
103     int POP3SIZELIMIT;
104     long POP3TIME;
105 rabbi 1
106     #endif
107    
108     char SHORTNAME[LINELEN];
109    
110     /* remailer configuration */
111 weaselp 177 int REMAIL;
112     int MIX;
113     int PGP;
114     int UNENCRYPTED;
115     int REMIX;
116     int REPGP;
117 rabbi 1
118 weaselp 177 int POOLSIZE;
119     int RATE;
120 rabbi 218 int DUMMYMAILINPROBABILITY;
121     int DUMMYMAILOUTPROBABILITY;
122 weaselp 177 int MIDDLEMAN;
123     int AUTOBLOCK;
124     char FORWARDTO[LINELEN];
125     int SIZELIMIT; /* maximal size of remailed messages */
126     int INFLATEMAX; /* maximal size of Inflate: padding */
127     int MAXRANDHOPS;
128     int BINFILTER; /* filter binary attachments? */
129 rabbi 218 int LISTSUPPORTED; /* list supported remailers in remailer-conf reply? */
130     long PACKETEXP; /* Expiration time for old packets */
131     long IDEXP; /* 0 = no ID log !! */
132 weaselp 177 long SENDPOOLTIME; /* frequency for sending pool messages */
133 weaselp 183 long MAILINTIME; /* frequency for processing MAILIN mail */
134 rabbi 1
135 weaselp 205 long KEYLIFETIME;
136 weaselp 214 long KEYOVERLAPPERIOD;
137     long KEYGRACEPERIOD;
138 weaselp 205
139 rabbi 1 char ERRLOG[LINELEN];
140     char ADDRESS[LINELEN];
141     char NAME[LINELEN];
142    
143 weaselp 177 char ORGANIZATION[LINELEN];
144     char MID[LINELEN];
145 rabbi 1
146     /* client config */
147 weaselp 177 int NUMCOPIES;
148     char CHAIN[LINELEN];
149     int VERBOSE;
150     int DISTANCE;
151     int MINREL;
152     int RELFINAL;
153     long MAXLAT;
154 rabbi 1 char PGPPUBRING[PATHMAX];
155     char PGPSECRING[PATHMAX];
156 weaselp 177 char PASSPHRASE[LINELEN];
157     char MAILIN[PATHMAX];
158     char MAILBOX[PATHMAX];
159 rabbi 1 char MAILABUSE[PATHMAX];
160     char MAILBLOCK[PATHMAX];
161 weaselp 177 char MAILUSAGE[PATHMAX];
162     char MAILANON[PATHMAX];
163     char MAILERROR[PATHMAX];
164 rabbi 1 char MAILBOUNCE[PATHMAX];
165    
166 weaselp 189 char ENTEREDPASSPHRASE[LINELEN] = "";
167    
168 weaselp 177 static int rereadconfig = 0;
169     static int terminatedaemon = 0;
170    
171 rabbi 1 #if defined(S_IFDIR) && !defined(S_ISDIR)
172     #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
173     #endif
174    
175     static int mixdir(char *d, int create)
176     {
177     int err;
178     struct stat buf;
179    
180     if (d != MIXDIR)
181     strncpy(MIXDIR, d, PATHMAX);
182 rabbi 11 if (MIXDIR[strlen(MIXDIR) - 1] == DIRSEP)
183 rabbi 1 MIXDIR[strlen(MIXDIR) - 1] = '\0';
184     err = stat(MIXDIR, &buf);
185     if (err == -1) {
186     if (create) {
187     #ifndef POSIX
188     err = mkdir(MIXDIR);
189     #else
190     err = mkdir(MIXDIR, S_IRWXU);
191     #endif
192     if (err == 0)
193     errlog(NOTICE, "Creating directory %s.\n", MIXDIR);
194     } else
195     err = 1;
196     } else if (!S_ISDIR(buf.st_mode))
197     err = -1;
198     if (err == 0)
199 rabbi 11 strcatn(MIXDIR, DIRSEPSTR, PATHMAX);
200 rabbi 1 return (err);
201     }
202    
203     void whoami(char *addr, char *defaultname)
204     {
205     char *p = NULL;
206    
207 weaselp 114 #if defined(HAVE_GETDOMAINNAME) || (defined(HAVE_GETHOSTNAME) && ! defined(HAVE_UNAME))
208 rabbi 1 char line[LINELEN];
209    
210     #endif
211     #ifdef HAVE_UNAME
212     struct utsname uts;
213    
214     #endif
215     #ifdef POSIX
216     p = getlogin();
217     #endif
218     if (p == NULL)
219     strcpy(addr, defaultname);
220     else
221     strncpy(addr, p, LINELEN);
222    
223     strcatn(addr, "@", LINELEN);
224     #ifdef HAVE_UNAME
225     if (uname(&uts) != -1)
226     strcatn(addr, uts.nodename, LINELEN);
227     #elif defined(HAVE_GETHOSTNAME)
228     if (gethostname(line, LINELEN) == 0)
229     strcatn(addr, line, LINELEN);
230     #endif
231     if (addr[strlen(addr) - 1] == '@')
232     strcatn(addr, SHORTNAME, LINELEN);
233    
234     if (strchr(strchr(addr, '@'), '.') == NULL) {
235     #ifdef HAVE_GETDOMAINNAME
236     if (getdomainname(line, LINELEN) == 0 && !streq(line, "(none)")) {
237     strcatn(addr, ".", LINELEN);
238     strcatn(addr, line, LINELEN);
239     }
240     #endif
241     }
242     }
243    
244     #define read_conf(t) readconfline(line, #t, sizeof(#t)-1, t)
245    
246     static int readconfline(char *line, char *name, int namelen, char *var)
247     {
248     if (strncmp(line, name, namelen) == 0 &&
249     (isspace(line[namelen]) || line[namelen] == '=')) {
250     line += namelen;
251     if (*line == '=')
252     line++;
253     while (isspace(*line))
254     line++;
255     if (line[0] == '\n' || line[0] == '\0') /* leave default */
256     return (1);
257     strncpy(var, line, LINELEN);
258     if (var[strlen(var) - 1] == '\n')
259     var[strlen(var) - 1] = '\0';
260     return (1);
261     } else
262     return (0);
263     }
264    
265     #define read_conf_i(t) readiconfline(line, #t, sizeof(#t)-1, &t)
266    
267     static int readiconfline(char *line, char *name, int namelen, int *var)
268     {
269     if (strncmp(line, name, namelen) == 0 &&
270     (isspace(line[namelen]) || line[namelen] == '=')) {
271     line += namelen;
272     if (*line == '=')
273     line++;
274     while (isspace(*line))
275     line++;
276     if (line[0] == '\n' || line[0] == '\0') /* leave default */
277     return (1);
278     switch (tolower(line[0])) {
279     case 'n':
280     *var = 0;
281     break;
282     case 'y':
283     *var = 1;
284     break;
285     case 'x':
286     *var = 2;
287     break;
288     default:
289     sscanf(line, "%d", var);
290     }
291     return (1);
292     } else
293     return (0);
294     }
295    
296     #define read_conf_t(t) readtconfline(line, #t, sizeof(#t)-1, &t)
297    
298     static int readtconfline(char *line, char *name, int namelen, long *var)
299     {
300     char *linenext;
301     int mod = 0;
302     long l = 0;
303     long n;
304    
305     if (strncmp(line, name, namelen) == 0 &&
306     (isspace(line[namelen]) || line[namelen] == '=')) {
307     line += namelen;
308     if (*line == '=')
309     line++;
310     for (;; line++) {
311     n = strtol(line, &linenext, 10);
312     if (linenext == line)
313     break;
314     line = linenext;
315     mod = 1;
316     assert(line != NULL);
317     while (isspace(*line))
318     line++;
319     switch (tolower(*line)) {
320 weaselp 205 case 'y': /* years */
321     l += 365 * 24 * 60 * 60 * n;
322     break;
323     case 'b': /* months */
324     l += 30 * 24 * 60 * 60 * n;
325     break;
326     case 'w': /* weeks */
327     l += 7 * 24 * 60 * 60 * n;
328     break;
329     case 'd': /* days */
330 rabbi 1 l += 24 * 60 * 60 * n;
331     break;
332 weaselp 205 case 's': /* seconds */
333     l += n;
334     break;
335     case 'm': /* minutes */
336 rabbi 1 l += 60 * n;
337     break;
338 weaselp 205 case 'h': /* hours - default */
339 rabbi 1 default:
340     l += 60 * 60 * n;
341     break;
342     }
343     }
344     if (mod)
345     *var = l;
346     return (1);
347     } else
348     return (0);
349     }
350    
351 weaselp 177 void mix_setdefaults()
352     {
353     #define strnncpy(a,b) strncpy(a, b, sizeof(a)); a[sizeof(a)-1] = '\0'
354    
355     strnncpy(MIXCONF , DEFAULT_MIXCONF);
356     strnncpy(DISCLAIMFILE , DEFAULT_DISCLAIMFILE);
357     strnncpy(FROMDSCLFILE , DEFAULT_FROMDSCLFILE);
358     strnncpy(MSGFOOTERFILE, DEFAULT_MSGFOOTERFILE);
359     strnncpy(POP3CONF , DEFAULT_POP3CONF);
360     strnncpy(HELPFILE , DEFAULT_HELPFILE);
361     strnncpy(ABUSEFILE , DEFAULT_ABUSEFILE);
362     strnncpy(REPLYFILE , DEFAULT_REPLYFILE);
363     strnncpy(USAGEFILE , DEFAULT_USAGEFILE);
364     strnncpy(USAGELOG , DEFAULT_USAGELOG);
365     strnncpy(BLOCKFILE , DEFAULT_BLOCKFILE);
366     strnncpy(ADMKEYFILE , DEFAULT_ADMKEYFILE);
367     strnncpy(KEYFILE , DEFAULT_KEYFILE);
368     strnncpy(PGPKEY , DEFAULT_PGPKEY);
369     strnncpy(DSAPARAMS , DEFAULT_DSAPARAMS);
370     strnncpy(DHPARAMS , DEFAULT_DHPARAMS);
371     strnncpy(MIXRAND , DEFAULT_MIXRAND);
372     strnncpy(SECRING , DEFAULT_SECRING);
373     strnncpy(PUBRING , DEFAULT_PUBRING);
374     strnncpy(IDLOG , DEFAULT_IDLOG);
375     strnncpy(STATS , DEFAULT_STATS);
376     strnncpy(DESTBLOCK , DEFAULT_DESTBLOCK);
377     strnncpy(DESTALLOW , DEFAULT_DESTALLOW);
378     strnncpy(SOURCEBLOCK , DEFAULT_SOURCEBLOCK);
379     strnncpy(HDRFILTER , DEFAULT_HDRFILTER);
380     strnncpy(REGULAR , DEFAULT_REGULAR);
381     strnncpy(POOL , DEFAULT_POOL);
382     strnncpy(TYPE1LIST , DEFAULT_TYPE1LIST);
383     strnncpy(TYPE2REL , DEFAULT_TYPE2REL);
384     strnncpy(TYPE2LIST , DEFAULT_TYPE2LIST);
385 weaselp 197 strnncpy(PIDFILE , DEFAULT_PIDFILE);
386 weaselp 177
387     strnncpy(PGPREMPUBRING, DEFAULT_PGPREMPUBRING);
388     strnncpy(PGPREMPUBASC , DEFAULT_PGPREMPUBASC);
389     strnncpy(PGPREMSECRING, DEFAULT_PGPREMSECRING);
390     strnncpy(NYMSECRING , DEFAULT_NYMSECRING);
391     strnncpy(NYMDB , DEFAULT_NYMDB);
392    
393    
394     strnncpy(MIXDIR , "");
395     strnncpy(POOLDIR , "");
396    
397     /* programs */
398     #ifdef WIN32
399     strnncpy(SENDMAIL , "outfile");
400     #else
401     strnncpy(SENDMAIL , "/usr/lib/sendmail -t");
402     #endif
403     strnncpy(SENDANONMAIL , "");
404     strnncpy(NEWS , "");
405     strnncpy(TYPE1 , "");
406    
407     /* addresses */
408     strnncpy(MAILtoNEWS , "mail2news@anon.lcs.mit.edu");
409     strnncpy(REMAILERNAME , "Anonymous Remailer");
410     strnncpy(ANONNAME , "Anonymous");
411     strnncpy(REMAILERADDR , "");
412     strnncpy(ANONADDR , "");
413     strnncpy(COMPLAINTS , "");
414     strnncpy(SMTPRELAY , "");
415     AUTOREPLY = 0;
416    
417     #ifdef USE_SOCK
418     strnncpy(HELONAME , "");
419     strnncpy(ENVFROM , "");
420     POP3DEL = 0;
421     POP3SIZELIMIT = 0;
422     POP3TIME = 60 * 60;
423    
424     #endif
425    
426     strnncpy(SHORTNAME , "");
427    
428     /* configuration */
429     REMAIL = 0;
430     MIX = 1;
431     PGP = 1;
432     UNENCRYPTED = 0;
433     REMIX = 1;
434     REPGP = 1;
435    
436     POOLSIZE = 0;
437     RATE = 100;
438 rabbi 218 DUMMYMAILINPROBABILITY = 20; /* add dummy messages with probability p for each message added to the pool */
439     DUMMYMAILOUTPROBABILITY = 80; /* add dummy messages with probability p each time we send from the pool */
440     MIDDLEMAN = 0; /* for both of the above: while (rnd < p) { senddummy(); } */
441 weaselp 177 AUTOBLOCK = 1;
442     strnncpy(FORWARDTO, "*");
443     SIZELIMIT = 0; /* maximal size of remailed messages */
444     INFLATEMAX = 50; /* maximal size of Inflate: padding */
445     MAXRANDHOPS = 20;
446     BINFILTER = 0; /* filter binary attachments? */
447     LISTSUPPORTED = 1; /* list supported remailers in remailer-conf reply? */
448     PACKETEXP = 7 * SECONDSPERDAY; /* Expiration time for old packets */
449     IDEXP = 7 * SECONDSPERDAY; /* 0 = no ID log !! */
450     SENDPOOLTIME = 60 * 60; /* frequency for sending pool messages */
451 weaselp 183 MAILINTIME = 5 * 60; /* frequency for processing MAILIN mail */
452 weaselp 177
453 weaselp 214 KEYLIFETIME = 8 * 30 * 24 * 60 * 60; /* expire time for keys */
454     KEYOVERLAPPERIOD = 1 * 30 * 24 * 60 * 60; /* if old keys are only still valid for that time */
455     /* create new ones with ./mix -K */
456     KEYGRACEPERIOD = 1 * 30 * 24 * 60 * 60; /* accept mail to the old one for that long after */
457     /* it has expired */
458 weaselp 205
459 weaselp 214
460 weaselp 177 strnncpy(ERRLOG , "");
461     strnncpy(ADDRESS , "");
462     strnncpy(NAME , "");
463    
464     strnncpy(ORGANIZATION, "Anonymous Posting Service");
465     strnncpy(MID , "y");
466    
467     /* client config */
468     NUMCOPIES = 1;
469     strnncpy(CHAIN, "*,*,*,*");
470     VERBOSE = 2;
471     DISTANCE = 2;
472     MINREL = 98;
473     RELFINAL = 99;
474     MAXLAT = 36 * 60 * 60;
475     strnncpy(PGPPUBRING, "");
476     strnncpy(PGPSECRING, "");
477     #ifdef COMPILEDPASS
478     strnncpy(PASSPHRASE, COMPILEDPASS);
479     #else
480     strnncpy(PASSPHRASE, "");
481     #endif
482     strnncpy(MAILIN , "");
483     strnncpy(MAILBOX , "mbox");
484     strnncpy(MAILABUSE , "");
485     strnncpy(MAILBLOCK , "");
486     #ifdef WIN32
487     strnncpy(MAILUSAGE , "nul:");
488     strnncpy(MAILANON , "nul:");
489     strnncpy(MAILERROR , "nul:");
490     #else
491     strnncpy(MAILUSAGE , "/dev/null");
492     strnncpy(MAILANON , "/dev/null");
493     strnncpy(MAILERROR , "/dev/null");
494     #endif
495     strnncpy(MAILBOUNCE, "");
496     }
497    
498 rabbi 1 int mix_configline(char *line)
499     {
500     return (read_conf(ADDRESS) || read_conf(NAME) ||
501     read_conf(SHORTNAME) || read_conf(REMAILERADDR) ||
502     read_conf(ANONADDR) || read_conf(REMAILERNAME) ||
503     read_conf(ANONNAME) || read_conf(COMPLAINTS) ||
504     read_conf_i(AUTOREPLY) || read_conf(SMTPRELAY) ||
505     #ifdef USE_SOCK
506     read_conf(HELONAME) || read_conf(ENVFROM) ||
507     #endif
508     read_conf(SENDMAIL) || read_conf(SENDANONMAIL) ||
509     read_conf_i(REMAIL) || read_conf_i(MIX) ||
510     read_conf_i(PGP) || read_conf_i(UNENCRYPTED) ||
511     read_conf_i(REMIX) || read_conf(NEWS) ||
512 rabbi 62 read_conf_i(REPGP) ||
513 rabbi 1 read_conf(MAILtoNEWS) || read_conf(ERRLOG) ||
514     read_conf(ORGANIZATION) || read_conf(MID) ||
515     read_conf(TYPE1) || read_conf_i(POOLSIZE) ||
516     read_conf_i(RATE) || read_conf_i(MIDDLEMAN) ||
517 weaselp 219 read_conf_i(DUMMYMAILINPROBABILITY) || read_conf_i(DUMMYMAILOUTPROBABILITY) ||
518 rabbi 1 read_conf_i(AUTOBLOCK) || read_conf(FORWARDTO) ||
519     read_conf_i(SIZELIMIT) || read_conf_i(INFLATEMAX) ||
520     read_conf_i(MAXRANDHOPS) || read_conf_i(BINFILTER) ||
521 weaselp 168 read_conf_i(LISTSUPPORTED) ||
522 rabbi 1 read_conf_t(PACKETEXP) || read_conf_t(IDEXP) ||
523     read_conf_t(SENDPOOLTIME) || read_conf_i(NUMCOPIES) ||
524 weaselp 183 read_conf_t(MAILINTIME) ||
525 rabbi 1 read_conf(CHAIN) || read_conf_i(VERBOSE) ||
526     read_conf_i(DISTANCE) || read_conf_i(MINREL) ||
527     read_conf_i(RELFINAL) || read_conf_t(MAXLAT) ||
528     read_conf(PGPPUBRING) || read_conf(PGPSECRING) ||
529 weaselp 205 read_conf(PASSPHRASE) || read_conf_t(KEYLIFETIME) ||
530 weaselp 214 read_conf_t(KEYGRACEPERIOD) || read_conf_t(KEYOVERLAPPERIOD) ||
531 rabbi 1 #ifdef USE_SOCK
532     read_conf_i(POP3DEL) || read_conf_i(POP3SIZELIMIT) ||
533     read_conf_t(POP3TIME) ||
534     #endif
535     read_conf(MAILBOX) || read_conf(MAILABUSE) ||
536     read_conf(MAILBLOCK) || read_conf(MAILUSAGE) ||
537     read_conf(MAILANON) || read_conf(MAILERROR) ||
538 weaselp 163 read_conf(MAILBOUNCE) || read_conf(MAILIN) ||
539 weaselp 105
540     read_conf(DISCLAIMFILE) || read_conf(FROMDSCLFILE) ||
541 weaselp 166 read_conf(MSGFOOTERFILE) ||
542 weaselp 105 read_conf(POP3CONF) || read_conf(HELPFILE) ||
543     read_conf(ABUSEFILE) || read_conf(REPLYFILE) ||
544     read_conf(USAGEFILE) || read_conf(USAGELOG) ||
545     read_conf(BLOCKFILE) || read_conf(ADMKEYFILE) ||
546     read_conf(KEYFILE) || read_conf(PGPKEY) ||
547     read_conf(DSAPARAMS) || read_conf(DHPARAMS) ||
548     read_conf(MIXRAND) || read_conf(SECRING) ||
549     read_conf(PUBRING) || read_conf(IDLOG) ||
550     read_conf(STATS) || read_conf(DESTBLOCK) ||
551     read_conf(DESTALLOW) || read_conf(SOURCEBLOCK) ||
552     read_conf(HDRFILTER) || read_conf(REGULAR) ||
553     read_conf(POOL) || read_conf(TYPE1LIST) ||
554     read_conf(TYPE2REL) || read_conf(TYPE2LIST) ||
555     read_conf(PGPREMPUBRING) || read_conf(PGPREMPUBASC) ||
556     read_conf(PGPREMSECRING) || read_conf(NYMSECRING) ||
557 weaselp 197 read_conf(NYMDB) || read_conf(PIDFILE) );
558 rabbi 1 }
559    
560     static int mix_config(void)
561     {
562     char *d;
563     FILE *f;
564     char line[PATHMAX];
565     int err = -1;
566     #ifdef POSIX
567     struct passwd *pw;
568     #endif
569     struct stat buf;
570     #ifdef HAVE_UNAME
571     struct utsname uts;
572     #endif
573     #ifdef WIN32
574     HKEY regsw, reg, regpgp;
575     DWORD type, len;
576     int rkey = 0;
577     #endif
578    
579 weaselp 177 mix_setdefaults();
580    
581 rabbi 1 #ifdef POSIX
582     pw = getpwuid(getuid());
583     #endif
584    
585     #ifdef WIN32
586     RegOpenKeyEx(HKEY_CURRENT_USER, "Software", 0, KEY_ALL_ACCESS, &regsw);
587     len=sizeof(line);
588     if (err == -1 &&
589     RegOpenKeyEx(regsw, "Mixmaster", 0, KEY_QUERY_VALUE, &reg) == 0) {
590     if (RegQueryValueEx(reg, "MixDir", 0, &type, line, &len) == 0)
591     err = mixdir(line, 1);
592     RegCloseKey(reg);
593     }
594     #endif
595    
596     if (err == -1 && (d = getenv("MIXPATH")) != NULL)
597     err = mixdir(d, 1);
598    
599     #ifdef SPOOL
600     if (err == -1 && strlen(SPOOL) > 0)
601     err = mixdir(SPOOL, 0);
602     #endif
603    
604     #ifdef POSIX
605     if (err == -1 && pw != NULL) {
606 weaselp 96 strncpy(line, pw->pw_dir, PATHMAX);
607     line[PATHMAX-1] = '\0';
608 rabbi 11 if (line[strlen(line) - 1] != DIRSEP)
609     strcatn(line, DIRSEPSTR, PATHMAX);
610 weaselp 105 strcatn(line, HOMEMIXDIR, PATHMAX);
611 rabbi 1 err = mixdir(line, 1);
612     }
613     #endif
614    
615     if (err == -1) {
616     getcwd(MIXDIR, PATHMAX);
617     mixdir(MIXDIR, 0);
618     }
619    
620 weaselp 163 mixfile(POOLDIR, POOL);
621 rabbi 11 if (POOLDIR[strlen(POOLDIR) - 1] == DIRSEP)
622 rabbi 1 POOLDIR[strlen(POOLDIR) - 1] = '\0';
623     if (stat(POOLDIR, &buf) != 0)
624     if
625     #ifndef POSIX
626     (mkdir(POOLDIR) != 0)
627     #else
628     (mkdir(POOLDIR, S_IRWXU) == -1)
629     #endif
630     strncpy(POOLDIR, MIXDIR, PATHMAX);
631    
632 weaselp 105 #ifdef GLOBALMIXCONF
633     f = mix_openfile(GLOBALMIXCONF, "r");
634     if (f != NULL) {
635     while (fgets(line, LINELEN, f) != NULL)
636     if (line[0] > ' ' && line[0] != '#')
637     mix_configline(line);
638     fclose(f);
639     }
640     #endif
641 rabbi 1 f = mix_openfile(MIXCONF, "r");
642     if (f != NULL) {
643     while (fgets(line, LINELEN, f) != NULL)
644     if (line[0] > ' ' && line[0] != '#')
645     mix_configline(line);
646     fclose(f);
647     }
648     if (IDEXP > 0 && IDEXP < 5 * SECONDSPERDAY)
649     IDEXP = 5 * SECONDSPERDAY;
650     if (MAXRANDHOPS > 20)
651     MAXRANDHOPS = 20;
652    
653     if (strchr(SHORTNAME, '.'))
654     *strchr(SHORTNAME, '.') = '\0';
655     if (strchr(SHORTNAME, ' '))
656     *strchr(SHORTNAME, ' ') = '\0';
657     #ifdef HAVE_UNAME
658     if (SHORTNAME[0] == '\0' && uname(&uts) != -1)
659     strncpy(SHORTNAME, uts.nodename, LINELEN);
660     #elif defined(HAVE_GETHOSTNAME)
661     if (SHORTNAME[0] == '\0')
662     gethostname(SHORTNAME, LINELEN);
663     #endif
664     if (SHORTNAME[0] == '\0')
665     strcpy(SHORTNAME, "unknown");
666    
667     if (ADDRESS[0] == '\0')
668     whoami(ADDRESS, "user");
669    
670     #ifdef HAVE_GECOS
671     if (NAME[0] == '\0' && pw != NULL)
672     strcatn(NAME, pw->pw_gecos, sizeof(NAME));
673     #endif
674    
675     if (REMAILERADDR[0] == '\0')
676     strncpy(REMAILERADDR, ADDRESS, LINELEN);
677    
678     if (COMPLAINTS[0] == '\0')
679     strncpy(COMPLAINTS, REMAILERADDR, LINELEN);
680    
681     if (strchr(REMAILERNAME, '@') == NULL) {
682     strcatn(REMAILERNAME, " <", LINELEN);
683     strcatn(REMAILERNAME, REMAILERADDR, LINELEN);
684     strcatn(REMAILERNAME, ">", LINELEN);
685     }
686     if (strchr(ANONNAME, '@') == NULL && ANONADDR[0] != '\0') {
687     strcatn(ANONNAME, " <", LINELEN);
688     strcatn(ANONNAME, ANONADDR, LINELEN);
689     strcatn(ANONNAME, ">", LINELEN);
690     }
691     if (strchr(ANONNAME, '@') == NULL) {
692     strcatn(ANONNAME, " <", LINELEN);
693     strcatn(ANONNAME, REMAILERADDR, LINELEN);
694     strcatn(ANONNAME, ">", LINELEN);
695     }
696     #ifndef USE_PGP
697     if (TYPE1[0] == '\0')
698     PGP = 0;
699     #endif
700     #ifndef USE_RSA
701     MIX = 0;
702     #endif
703    
704     #ifdef WIN32
705     if (RegOpenKeyEx(regsw, "PGP", 0, KEY_ALL_ACCESS, &regpgp) == 0)
706     rkey++;
707     if (rkey && RegOpenKeyEx(regpgp, "PGPlib", 0, KEY_QUERY_VALUE, &reg) == 0)
708     rkey++;
709     if (PGPPUBRING[0] == '\0' && rkey == 2) {
710     len = PATHMAX;
711     RegQueryValueEx(reg, "PubRing", 0, &type, PGPPUBRING, &len);
712     }
713     if (PGPSECRING[0] == '\0' && rkey == 2) {
714     len = PATHMAX;
715     RegQueryValueEx(reg, "SecRing", 0, &type, PGPSECRING, &len);
716     }
717     if (rkey == 2)
718     RegCloseKey(reg);
719     if (rkey)
720     RegCloseKey(regpgp);
721     RegCloseKey(regsw);
722     #endif
723    
724     if (PGPPUBRING[0] == '\0') {
725     char *d;
726    
727     if ((d = getenv("HOME")) != NULL) {
728     strcpy(PGPPUBRING, d);
729     strcatn(PGPPUBRING, "/.pgp/", PATHMAX);
730     }
731     strcatn(PGPPUBRING, "pubring.pkr", PATHMAX);
732     if (stat(PGPPUBRING, &buf) == -1)
733     strcpy(strrchr(PGPPUBRING, '.'), ".pgp");
734     }
735     if (PGPSECRING[0] == '\0') {
736     char *d;
737    
738     if ((d = getenv("HOME")) != NULL) {
739     strcpy(PGPSECRING, d);
740     strcatn(PGPSECRING, "/.pgp/", PATHMAX);
741     }
742     strcatn(PGPSECRING, "secring.skr", PATHMAX);
743     if (stat(PGPSECRING, &buf) == -1)
744     strcpy(strrchr(PGPSECRING, '.'), ".pgp");
745     }
746     if (streq(NEWS, "mail-to-news"))
747     strncpy(NEWS, MAILtoNEWS, sizeof(NEWS));
748    
749     if (f == NULL) {
750 weaselp 105 #ifndef GLOBALMIXCONF
751     /* Only write the config file in non systemwide installation */
752 rabbi 1 f = mix_openfile(MIXCONF, "w");
753     if (f == NULL)
754     errlog(WARNING, "Can't open %s%s!\n", MIXDIR, MIXCONF);
755     else {
756     fprintf(f, "# mix.cfg - mixmaster configuration file\n");
757     fprintf(f, "NAME %s\n", NAME);
758     fprintf(f, "ADDRESS %s\n", ADDRESS);
759     fprintf(f, "\n# edit to set up a remailer:\n");
760     fprintf(f, "REMAIL n\n");
761     fprintf(f, "SHORTNAME %s\n", SHORTNAME);
762     fprintf(f, "REMAILERADDR %s\n", REMAILERADDR);
763     fprintf(f, "COMPLAINTS %s\n", COMPLAINTS);
764     fclose(f);
765     }
766 weaselp 105 #endif
767 rabbi 1 REMAIL = 0;
768     }
769    
770 weaselp 198 if (ENTEREDPASSPHRASE[0] != '\0') {
771 weaselp 189 strncpy(PASSPHRASE, ENTEREDPASSPHRASE, LINELEN);
772     PASSPHRASE[LINELEN-1] = 0;
773     };
774    
775 rabbi 1 return (0);
776     }
777    
778     /** Library initialization: ******************************************/
779    
780     static int initialized = 0;
781    
782     int mix_init(char *mixdir)
783     {
784     if (!initialized) {
785     if (mixdir)
786     strncpy(MIXDIR, mixdir, LINELEN);
787     mix_config();
788     #if defined(USE_SOCK) && defined(WIN32)
789     sock_init();
790     #endif
791     /* atexit (mix_exit); */
792     initialized = 1;
793     }
794    
795     if (rnd_init() == -1)
796     rnd_seed();
797     return(0);
798     }
799    
800     void mix_exit(void)
801     {
802     if (!initialized)
803     return;
804     rnd_final();
805     #if defined(USE_SOCK) && defined(WIN32)
806     sock_exit();
807     #endif
808     initialized=0;
809     }
810    
811     int mix_regular(int force)
812     {
813     FILE *f;
814 weaselp 183 long now, tpool = 0, tpop3 = 0, tdaily = 0, tmailin = 0;
815 rabbi 1 int ret = 0;
816    
817     mix_init(NULL);
818     now = time(NULL);
819    
820     f = mix_openfile(REGULAR, "r+");
821     if (f != NULL) {
822     lock(f);
823 weaselp 183 fscanf(f, "%ld %ld %ld %ld", &tpool, &tpop3, &tdaily, &tmailin);
824 weaselp 176 if (now - tpool >= SENDPOOLTIME)
825 weaselp 183 force |= FORCE_POOL | FORCE_MAILIN;
826 rabbi 1 #ifdef USE_SOCK
827 weaselp 176 if (now - tpop3 >= POP3TIME)
828 weaselp 183 force |= FORCE_POP3 | FORCE_MAILIN;
829 rabbi 1 #endif
830 weaselp 176 if (now - tdaily >= SECONDSPERDAY)
831 rabbi 1 force |= FORCE_DAILY;
832 weaselp 183 if (now - tmailin >= MAILINTIME)
833     force |= FORCE_MAILIN;
834 rabbi 1 if (force & FORCE_POOL)
835     tpool = now;
836     if (force & FORCE_POP3)
837     tpop3 = now;
838     if (force & FORCE_DAILY)
839     tdaily = now;
840 weaselp 183 if (force & FORCE_MAILIN)
841     tmailin = now;
842 rabbi 1 rewind(f);
843 weaselp 183 fprintf(f, "%ld %ld %ld %ld\n", tpool, tpop3, tdaily, tmailin);
844 rabbi 1 unlock(f);
845     fclose(f);
846     } else {
847 weaselp 183 force = FORCE_POOL | FORCE_POP3 | FORCE_DAILY | FORCE_MAILIN;
848 rabbi 1 f = mix_openfile(REGULAR, "w+");
849     if (f != NULL) {
850     lock(f);
851 weaselp 183 fprintf(f, "%ld %ld %ld %ld\n", now, now, now, now);
852 rabbi 1 unlock(f);
853     fclose(f);
854     } else
855     errlog(ERRORMSG, "Can't create %s!\n", REGULAR);
856     }
857    
858     if (force & FORCE_DAILY)
859     mix_daily(), ret = 1;
860     #ifdef USE_SOCK
861     if (force & FORCE_POP3)
862     pop3get();
863     #endif
864 weaselp 183 if (force & FORCE_MAILIN)
865     ret = process_mailin();
866 rabbi 1 if (force & FORCE_POOL)
867     ret = pool_send();
868    
869     return (ret);
870     }
871    
872     int mix_daily(void)
873     {
874     idexp();
875     pool_packetexp();
876     stats(NULL);
877     keymgt(0);
878     return (0);
879     }
880    
881 weaselp 177 /** Handle signals SIGHUP, SIGINT, and SIGTERM
882     This signal handler gets called if the daemon
883     process receives one of SIGHUP, SIGINT, or SIGTERM.
884     It then sets either rereadconfig of terminatedaemon
885     to true depending on the signal received.
886 rabbi 30
887 weaselp 177 @author PP
888     @return nothing
889     */
890 weaselp 199 #ifdef POSIX
891 weaselp 177 void sighandler(int signal) {
892     if (signal == SIGHUP)
893     rereadconfig = 1;
894     else if (signal == SIGINT || signal == SIGTERM)
895     terminatedaemon = 1;
896     };
897 weaselp 199 #endif
898 weaselp 177
899     /** Set the signal handler for SIGHUP, SIGINT and SIGTERM
900     This function registers signal handlers so that
901     we can react on signals send by the user in daemon
902     mode. SIGHUP will instruct mixmaster to reload its
903     configuration while SIGINT and SIGTERM will instruct
904     it to shut down. Mixmaster will finish the current
905     pool run before it terminates.
906    
907     @param restart Whether or not system calls should be
908     restarted. Usually we want this, the
909     only excetion is the sleep() in the
910     daemon mail loop.
911     @author PP
912     @return -1 if calling sigaction failed, 0 on
913     no error
914     */
915     int setsignalhandler(int restart)
916     {
917     #ifdef POSIX
918     struct sigaction hdl;
919     int err = 0;
920    
921     memset(&hdl, 0, sizeof(hdl));
922     hdl.sa_handler = sighandler;
923     hdl.sa_flags = restart ? SA_RESTART : 0;
924    
925     if (sigaction(SIGHUP, &hdl, NULL))
926     err = -1;
927     if (sigaction(SIGINT, &hdl, NULL))
928     err = -1;
929     if (sigaction(SIGTERM, &hdl, NULL))
930     err = -1;
931     return (err);
932     #else /* POSIX */
933     return(0);
934     #endif /* POSIX */
935     }
936    
937 rabbi 30 #ifdef WIN32
938 rabbi 37 /* Try to detect if we are the service or not...
939     seems there is no easy reliable way */
940 rabbi 30 int is_nt_service(void)
941 rabbi 37 {
942 rabbi 30 static int issvc = -1;
943     #ifdef WIN32SERVICE
944     STARTUPINFO StartupInfo;
945     OSVERSIONINFO VersionInfo;
946     DWORD dwsize;
947    
948 rabbi 37 if (issvc != -1) /* do it only once */
949 rabbi 30 return issvc;
950    
951     VersionInfo.dwOSVersionInfoSize = sizeof(VersionInfo);
952     if (GetVersionEx(&VersionInfo))
953     if (VersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT)
954 rabbi 37 return issvc = 0; /* not NT - not the service */
955 rabbi 30
956 rabbi 37 if (!GetConsoleTitle(&VersionInfo,sizeof(VersionInfo)))
957     /* reuse VersionInfo to save memory */
958     return issvc = 1; /* have no console - we are the service probably */
959 rabbi 30
960     GetStartupInfo(&StartupInfo);
961     if (StartupInfo.lpDesktop[0] == 0)
962 rabbi 37 return issvc = 1; /* have no desktop - we are the service probably */
963 rabbi 30
964     if (_fileno(stdin) == -1 && _fileno(stdout) == -1 && _fileno(stderr) == -1)
965 rabbi 37 return issvc = 1; /* have no stdin,stderr,stdout - probably service */
966 rabbi 30 #endif // WIN32SERVICE
967    
968     return issvc = 0; // assume not the service
969     } // is_nt_service
970    
971     HANDLE hMustTerminate = NULL;
972     void set_nt_exit_event(HANDLE h_svc_exit_event)
973     {
974     hMustTerminate = h_svc_exit_event;
975     } // set_nt_exit_event
976    
977     #endif // WIN32
978    
979 rabbi 1 int mix_daemon(void)
980     {
981 weaselp 177 long t, slept;
982 weaselp 183 t = (MAILINTIME < SENDPOOLTIME && (MAILIN != NULL && (strcmp(MAILIN, "") != 0))) ? MAILINTIME : SENDPOOLTIME;
983 rabbi 1 #ifdef USE_SOCK
984     if (POP3TIME < t)
985     t = POP3TIME;
986     #endif
987 weaselp 177 slept = t;
988 rabbi 1
989 weaselp 177 setsignalhandler(1); /* set signal handlers and restart any interrupted system calls */
990 rabbi 1 for(;;) {
991 weaselp 177 if (terminatedaemon)
992 weaselp 197 break;
993 weaselp 177 if (rereadconfig) {
994     rereadconfig = 0;
995     mix_config();
996 weaselp 183 t = (MAILINTIME < SENDPOOLTIME && (MAILIN != NULL && (strcmp(MAILIN, "") != 0))) ? MAILINTIME : SENDPOOLTIME;
997 weaselp 177 #ifdef USE_SOCK
998     if (POP3TIME < t)
999     t = POP3TIME;
1000     #endif
1001     }
1002     if (slept >= t) {
1003     mix_regular(0);
1004     slept = 0;
1005     }
1006    
1007     if (!terminatedaemon && !rereadconfig) {
1008     setsignalhandler(0); /* set signal handlers; don't restart system calls */
1009 rabbi 1 #ifdef WIN32
1010 rabbi 11 #ifdef WIN32SERVICE
1011 weaselp 177 if (hMustTerminate) {
1012     if (WaitForSingleObject(hMustTerminate, t * 1000) == WAIT_OBJECT_0) {
1013     CloseHandle(hMustTerminate);
1014     return 0;
1015     }
1016     } else
1017 rabbi 11 #endif
1018 rabbi 30 Sleep(t * 1000);
1019 rabbi 1 #else
1020 weaselp 177 slept += (t - slept) - sleep(t - slept);
1021 rabbi 1 #endif
1022 weaselp 177 setsignalhandler(1); /* set signal handlers and restart any interrupted system calls */
1023     }
1024 rabbi 1 }
1025 weaselp 197 return (0);
1026 rabbi 1 }
1027    
1028     /** error ***************************************************************/
1029    
1030     void errlog(int type, char *fmt,...)
1031     {
1032     va_list args;
1033     BUFFER *msg;
1034     FILE *e = NULL;
1035     time_t t;
1036     struct tm *tc;
1037     char line[LINELEN];
1038     int p;
1039     char err[6][8] =
1040     {"", "Error", "Warning", "Notice", "Info", "Info"};
1041    
1042     if ((VERBOSE == 0 && type != ERRORMSG) || (type == LOG && VERBOSE < 2)
1043     || (type == DEBUGINFO && VERBOSE < 3))
1044     return;
1045    
1046     t = time(NULL);
1047     tc = localtime(&t);
1048     strftime(line, LINELEN, "[%Y-%m-%d %H:%M:%S] ", tc);
1049    
1050     msg = buf_new();
1051     buf_appends(msg, line);
1052     p = msg->length;
1053     buf_appendf(msg, "%s: ", err[type]);
1054     va_start(args, fmt);
1055     buf_vappendf(msg, fmt, args);
1056     va_end(args);
1057    
1058     if (streq(ERRLOG, "stdout"))
1059     e = stdout;
1060     else if (streq(ERRLOG, "stderr"))
1061     e = stderr;
1062    
1063     if (e == NULL && (ERRLOG[0] == '\0' ||
1064     (e = mix_openfile(ERRLOG, "a")) == NULL))
1065     mix_status("%s", msg->data + p);
1066     else {
1067     buf_write(msg, e);
1068     if (e != stderr && e != stdout) {
1069     fclose(e);
1070     /* duplicate the error message on screen */
1071     mix_status("%s", msg->data + p);
1072     }
1073     }
1074     buf_free(msg);
1075     }
1076    
1077     static char statusline[BUFSIZE] = "";
1078    
1079     void mix_status(char *fmt,...)
1080     {
1081     va_list args;
1082    
1083     if (fmt != NULL) {
1084     va_start(args, fmt);
1085     #ifdef _MSC
1086     _vsnprintf(statusline, sizeof(statusline) - 1, fmt, args);
1087     #else
1088     vsnprintf(statusline, sizeof(statusline) - 1, fmt, args);
1089     #endif
1090     va_end(args);
1091     }
1092     #ifdef USE_NCURSES
1093     if (menu_initialized) {
1094     cl(LINES - 2, 10);
1095     printw("%s", statusline);
1096     refresh();
1097     } else
1098     #endif
1099     {
1100     fprintf(stderr, "%s", statusline);
1101     }
1102     }
1103    
1104     void mix_genericerror(void)
1105     {
1106     if (streq(statusline, "") || strfind(statusline, "...") ||
1107     strifind(statusline, "generating"))
1108     mix_status("Failed!");
1109     else
1110     mix_status(NULL);
1111     }

  ViewVC Help
Powered by ViewVC 1.1.5