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

  ViewVC Help
Powered by ViewVC 1.1.5