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

  ViewVC Help
Powered by ViewVC 1.1.5