/[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 - (hide 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 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 189 $Id: mix.c,v 1.18 2002/08/26 19:38:51 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 189 char ENTEREDPASSPHRASE[LINELEN] = "";
160    
161 weaselp 177 static int rereadconfig = 0;
162     static int terminatedaemon = 0;
163    
164 rabbi 1 #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 rabbi 11 if (MIXDIR[strlen(MIXDIR) - 1] == DIRSEP)
176 rabbi 1 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 rabbi 11 strcatn(MIXDIR, DIRSEPSTR, PATHMAX);
193 rabbi 1 return (err);
194     }
195    
196     void whoami(char *addr, char *defaultname)
197     {
198     char *p = NULL;
199    
200 weaselp 114 #if defined(HAVE_GETDOMAINNAME) || (defined(HAVE_GETHOSTNAME) && ! defined(HAVE_UNAME))
201 rabbi 1 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 weaselp 177 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 weaselp 183 MAILINTIME = 5 * 60; /* frequency for processing MAILIN mail */
430 weaselp 177
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 rabbi 1 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 rabbi 62 read_conf_i(REPGP) ||
484 rabbi 1 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 weaselp 168 read_conf_i(LISTSUPPORTED) ||
492 rabbi 1 read_conf_t(PACKETEXP) || read_conf_t(IDEXP) ||
493     read_conf_t(SENDPOOLTIME) || read_conf_i(NUMCOPIES) ||
494 weaselp 183 read_conf_t(MAILINTIME) ||
495 rabbi 1 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 rabbi 102 read_conf(PASSPHRASE) ||
500 rabbi 1 #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 weaselp 163 read_conf(MAILBOUNCE) || read_conf(MAILIN) ||
508 weaselp 105
509     read_conf(DISCLAIMFILE) || read_conf(FROMDSCLFILE) ||
510 weaselp 166 read_conf(MSGFOOTERFILE) ||
511 weaselp 105 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 rabbi 1 }
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 weaselp 177 mix_setdefaults();
549    
550 rabbi 1 #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 weaselp 96 strncpy(line, pw->pw_dir, PATHMAX);
576     line[PATHMAX-1] = '\0';
577 rabbi 11 if (line[strlen(line) - 1] != DIRSEP)
578     strcatn(line, DIRSEPSTR, PATHMAX);
579 weaselp 105 strcatn(line, HOMEMIXDIR, PATHMAX);
580 rabbi 1 err = mixdir(line, 1);
581     }
582     #endif
583    
584     if (err == -1) {
585     getcwd(MIXDIR, PATHMAX);
586     mixdir(MIXDIR, 0);
587     }
588    
589 weaselp 163 mixfile(POOLDIR, POOL);
590 rabbi 11 if (POOLDIR[strlen(POOLDIR) - 1] == DIRSEP)
591 rabbi 1 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 weaselp 105 #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 rabbi 1 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 weaselp 105 #ifndef GLOBALMIXCONF
720     /* Only write the config file in non systemwide installation */
721 rabbi 1 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 weaselp 105 #endif
736 rabbi 1 REMAIL = 0;
737     }
738    
739 weaselp 189 if (strncmp(ENTEREDPASSPHRASE, "", LINELEN) != 0) {
740     strncpy(PASSPHRASE, ENTEREDPASSPHRASE, LINELEN);
741     PASSPHRASE[LINELEN-1] = 0;
742     };
743    
744 rabbi 1 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 weaselp 183 long now, tpool = 0, tpop3 = 0, tdaily = 0, tmailin = 0;
784 rabbi 1 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 weaselp 183 fscanf(f, "%ld %ld %ld %ld", &tpool, &tpop3, &tdaily, &tmailin);
793 weaselp 176 if (now - tpool >= SENDPOOLTIME)
794 weaselp 183 force |= FORCE_POOL | FORCE_MAILIN;
795 rabbi 1 #ifdef USE_SOCK
796 weaselp 176 if (now - tpop3 >= POP3TIME)
797 weaselp 183 force |= FORCE_POP3 | FORCE_MAILIN;
798 rabbi 1 #endif
799 weaselp 176 if (now - tdaily >= SECONDSPERDAY)
800 rabbi 1 force |= FORCE_DAILY;
801 weaselp 183 if (now - tmailin >= MAILINTIME)
802     force |= FORCE_MAILIN;
803 rabbi 1 if (force & FORCE_POOL)
804     tpool = now;
805     if (force & FORCE_POP3)
806     tpop3 = now;
807     if (force & FORCE_DAILY)
808     tdaily = now;
809 weaselp 183 if (force & FORCE_MAILIN)
810     tmailin = now;
811 rabbi 1 rewind(f);
812 weaselp 183 fprintf(f, "%ld %ld %ld %ld\n", tpool, tpop3, tdaily, tmailin);
813 rabbi 1 unlock(f);
814     fclose(f);
815     } else {
816 weaselp 183 force = FORCE_POOL | FORCE_POP3 | FORCE_DAILY | FORCE_MAILIN;
817 rabbi 1 f = mix_openfile(REGULAR, "w+");
818     if (f != NULL) {
819     lock(f);
820 weaselp 183 fprintf(f, "%ld %ld %ld %ld\n", now, now, now, now);
821 rabbi 1 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 weaselp 183 if (force & FORCE_MAILIN)
834     ret = process_mailin();
835 rabbi 1 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 weaselp 177 /** 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 rabbi 30
856 weaselp 177 @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 rabbi 30 #ifdef WIN32
905 rabbi 37 /* Try to detect if we are the service or not...
906     seems there is no easy reliable way */
907 rabbi 30 int is_nt_service(void)
908 rabbi 37 {
909 rabbi 30 static int issvc = -1;
910     #ifdef WIN32SERVICE
911     STARTUPINFO StartupInfo;
912     OSVERSIONINFO VersionInfo;
913     DWORD dwsize;
914    
915 rabbi 37 if (issvc != -1) /* do it only once */
916 rabbi 30 return issvc;
917    
918     VersionInfo.dwOSVersionInfoSize = sizeof(VersionInfo);
919     if (GetVersionEx(&VersionInfo))
920     if (VersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT)
921 rabbi 37 return issvc = 0; /* not NT - not the service */
922 rabbi 30
923 rabbi 37 if (!GetConsoleTitle(&VersionInfo,sizeof(VersionInfo)))
924     /* reuse VersionInfo to save memory */
925     return issvc = 1; /* have no console - we are the service probably */
926 rabbi 30
927     GetStartupInfo(&StartupInfo);
928     if (StartupInfo.lpDesktop[0] == 0)
929 rabbi 37 return issvc = 1; /* have no desktop - we are the service probably */
930 rabbi 30
931     if (_fileno(stdin) == -1 && _fileno(stdout) == -1 && _fileno(stderr) == -1)
932 rabbi 37 return issvc = 1; /* have no stdin,stderr,stdout - probably service */
933 rabbi 30 #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 rabbi 1 int mix_daemon(void)
947     {
948 weaselp 177 long t, slept;
949 weaselp 183 t = (MAILINTIME < SENDPOOLTIME && (MAILIN != NULL && (strcmp(MAILIN, "") != 0))) ? MAILINTIME : SENDPOOLTIME;
950 rabbi 1 #ifdef USE_SOCK
951     if (POP3TIME < t)
952     t = POP3TIME;
953     #endif
954 weaselp 177 slept = t;
955 rabbi 1
956 weaselp 177 setsignalhandler(1); /* set signal handlers and restart any interrupted system calls */
957 rabbi 1 for(;;) {
958 weaselp 177 if (terminatedaemon)
959     exit(0);
960     if (rereadconfig) {
961     rereadconfig = 0;
962     mix_config();
963 weaselp 183 t = (MAILINTIME < SENDPOOLTIME && (MAILIN != NULL && (strcmp(MAILIN, "") != 0))) ? MAILINTIME : SENDPOOLTIME;
964 weaselp 177 #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 rabbi 1 #ifdef WIN32
977 rabbi 11 #ifdef WIN32SERVICE
978 weaselp 177 if (hMustTerminate) {
979     if (WaitForSingleObject(hMustTerminate, t * 1000) == WAIT_OBJECT_0) {
980     CloseHandle(hMustTerminate);
981     return 0;
982     }
983     } else
984 rabbi 11 #endif
985 rabbi 30 Sleep(t * 1000);
986 rabbi 1 #else
987 weaselp 177 slept += (t - slept) - sleep(t - slept);
988 rabbi 1 #endif
989 weaselp 177 setsignalhandler(1); /* set signal handlers and restart any interrupted system calls */
990     }
991 rabbi 1 }
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