/[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 183 - (hide annotations) (download)
Mon Aug 26 18:08:05 2002 UTC (10 years, 9 months ago) by weaselp
File MIME type: text/plain
File size: 27119 byte(s)
Previosly when we ran Mixmaster in daemon mode and injected mail either
via pop3 or the MAILIN method (reading a Maildir or an mbox), Mixmaster
only processed remailer-xxx requests at SENDPOOLTIME intervalls.

It might be in the interest of an operator to have a high SENDPOOLTIME -
like say an hour or two - to provide better security to their user.

However it is also important to answer remailer-xxx requests in a timely
manner.

This conflict of interests can be solved by adding yet another config
option: MAILINTIME.

MAILINTIME specifies the amount of time between reading MAILIN and
processing those mails (as well as those injected via POP3). Processing
here means to answer -xxx requests and to add remailer mails to the
pool.

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

  ViewVC Help
Powered by ViewVC 1.1.5