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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 262 - (hide annotations) (download)
Wed Sep 18 23:26:17 2002 UTC (10 years, 8 months ago) by rabbi
File MIME type: text/plain
File size: 15485 byte(s)
Added closing comments for all #ifdef statements. All #endif's, as well as
nested braces, should be commented to reference their start.

We need to provide comments before every function as well.
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     Create nym server messages
9 rabbi 262 $Id: nym.c,v 1.4 2002/09/18 23:26:16 rabbi Exp $ */
10 rabbi 1
11    
12     #include "mix3.h"
13     #include "pgp.h"
14     #include <string.h>
15 rabbi 6 #include <time.h>
16 rabbi 1 #include <assert.h>
17    
18     int nym_config(int mode, char *nym, char *nymserver, BUFFER *pseudonym,
19     char *sendchain, int sendnumcopies, BUFFER *chains,
20     BUFFER *options)
21     {
22     #ifndef USE_PGP
23     return (-1);
24 rabbi 262 #else /* end of not USE_PGP */
25 rabbi 1 REMAILER remailer[MAXREM];
26     KEYRING *r;
27     int maxrem;
28     int chain[20];
29     char rchain[CHAINMAX];
30     BUFFER *userid, *msg, *req, *k, *line, *ek, *eklist, *key, *pubkey, *out,
31     *oldchains;
32     int latency;
33     int err = -1;
34     int status;
35     int desttype = MSG_MAIL;
36     int rblock = 0;
37     BUFFER *nymlist, *userpass, *config;
38     LOCK *nymlock;
39    
40     userid = buf_new();
41     msg = buf_new();
42     req = buf_new();
43     k = buf_new();
44     line = buf_new();
45     ek = buf_new();
46     eklist = buf_new();
47     key = buf_new();
48     pubkey = buf_new();
49     out = buf_new();
50     config = buf_new();
51     nymlist = buf_new();
52     userpass = buf_new();
53     oldchains = buf_new();
54    
55     for (;;) {
56     user_pass(userpass);
57     if (user_confirmpass(userpass))
58     break;
59     user_delpass();
60     }
61    
62     if (nymserver) {
63     maxrem = t1_rlist(remailer);
64     if (maxrem < 1)
65     return (-1);
66     if (chain_select(chain, nymserver, maxrem, remailer, 2, NULL) != 1)
67     return (-1);
68     if (chain[0] == 0)
69     chain[0] = chain_randfinal(MSG_MAIL, remailer, maxrem, 2);
70     if (chain[0] == -1)
71     return (-1);
72     assert(strchr(nym, '@') == NULL && strchr(remailer[chain[0]].addr, '@'));
73     strcatn(nym, strchr(remailer[chain[0]].addr, '@'), LINELEN);
74     buf_appends(config, remailer[chain[0]].addr);
75     } else
76     assert(strchr(nym, '@') != NULL);
77    
78     status = nymlist_getnym(nym, config->length ? NULL : config, eklist, NULL,
79     NULL, oldchains);
80     if (mode == NYM_CREATE && status == NYM_OK)
81     mode = NYM_MODIFY;
82    
83     buf_appendc(userid, '<');
84     buf_appends(userid, nym);
85     buf_appendc(userid, '>');
86    
87     buf_sets(req, "Config:\nFrom: ");
88     buf_append(req, nym, strchr(nym, '@') - nym);
89     buf_appends(req, "\nNym-Commands:");
90     if (mode == NYM_CREATE)
91     buf_appends(req, " create?");
92     if (mode == NYM_DELETE)
93     buf_appends(req, " delete");
94     else {
95     if (options && options->length > 0) {
96     if (!bufleft(options, " "))
97     buf_appendc(req, ' ');
98     buf_cat(req, options);
99     }
100     if (pseudonym && pseudonym->length > 0) {
101     buf_appends(req, " name=\"");
102     buf_cat(req, pseudonym);
103     buf_appendc(req, '\"');
104     }
105     }
106     buf_nl(req);
107     if (mode == NYM_CREATE) {
108     buf_appends(req, "Public-Key:\n");
109    
110     getkey:
111     r = pgpdb_open(NYMSECRING, userpass, 0);
112     if (r == NULL) {
113     err = -3;
114     goto end;
115     }
116     if (r->filetype == -1)
117     r->filetype = 0;
118    
119     while (pgpdb_getnext(r, key, NULL, userid) != -1)
120     if (pgp_makepubkey(key, NULL, pubkey, userpass, 0) == 0)
121     err = 0;
122     pgpdb_close(r);
123     if (err != 0) {
124     if (err == -2)
125     goto end;
126     err = -2;
127     if (pseudonym && pseudonym->length) {
128     buf_set(userid, pseudonym);
129     buf_appendc(userid, ' ');
130     } else
131     buf_clear(userid);
132     buf_appendf(userid, "<%s>", nym);
133     pgp_keygen(PGP_ES_RSA, 0, userid, userpass, NULL, NYMSECRING, 2);
134     goto getkey;
135     }
136 weaselp 182 pgp_armor(pubkey, PGP_ARMOR_NYMKEY);
137 rabbi 1 buf_cat(req, pubkey);
138     }
139     if (mode != NYM_DELETE) {
140     if (nymlist_read(nymlist) == -1) {
141     user_delpass();
142     err = -1;
143     goto end;
144     }
145     if (chains)
146     for (;;) {
147     err = buf_getheader(chains, k, line);
148     if (err == -1 && rblock == 0)
149     break;
150     if (err != 0 && rblock == 1) {
151     buf_setrnd(ek, 16);
152     if (t1_encrypt(desttype, msg, rchain, latency, ek, NULL) != 0) {
153     err = -2;
154     goto end;
155     }
156     encode(ek, 0);
157     buf_cat(eklist, ek);
158     buf_nl(eklist);
159     buf_appends(req, "Reply-Block:\n");
160     buf_cat(req, msg);
161     buf_clear(msg);
162     rblock = 0;
163     continue;
164     }
165     if (bufieq(k, "Chain"))
166     strncpy(rchain, line->data, sizeof(rchain));
167     else if (bufieq(k, "Latency"))
168     sscanf(line->data, "%d", &latency);
169     else if (bufieq(k, "Null"))
170     desttype = MSG_NULL, rblock = 1;
171     else {
172     buf_appendheader(msg, k, line);
173     if (bufieq(k, "To"))
174     desttype = MSG_MAIL, rblock = 1;
175     if (bufieq(k, "Newsgroups"))
176     desttype = MSG_POST, rblock = 1;
177     }
178     }
179     }
180     nymlock = lockfile(NYMDB);
181     if (nymlist_read(nymlist) == 0) {
182     nymlist_del(nymlist, nym);
183     nymlist_append(nymlist, nym, config, options, pseudonym,
184     chains ? chains : oldchains, eklist,
185     mode == NYM_DELETE ? NYM_DELETED :
186     (status == -1 ? NYM_WAITING : status));
187     nymlist_write(nymlist);
188     } else
189     err = -1;
190     unlockfile(nymlock);
191    
192     #ifdef DEBUG
193     buf_write(req, stderr);
194 rabbi 262 #endif /* DEBUG */
195 rabbi 1 buf_clear(line);
196     buf_appendc(line, '<');
197     buf_cat(line, config);
198     buf_appendc(line, '>');
199    
200     err = pgp_encrypt(PGP_ENCRYPT | PGP_SIGN | PGP_TEXT | PGP_REMAIL,
201     req, line, userid, userpass, NULL, NYMSECRING);
202     if (err != 0)
203     goto end;
204     #ifdef DEBUG
205     buf_write(req, stderr);
206 rabbi 262 #endif /* DEBUG */
207 rabbi 1 buf_sets(out, "To: ");
208     buf_cat(out, config);
209     buf_nl(out);
210     buf_nl(out);
211     buf_cat(out, req);
212    
213     err = mix_encrypt(desttype, out, sendchain, sendnumcopies, line);
214     if (err)
215     mix_status("%s\n", line->data);
216    
217     end:
218     if (strchr(nym, '@')) *strchr(nym, '@') = '\0';
219     buf_free(userid);
220     buf_free(msg);
221     buf_free(req);
222     buf_free(k);
223     buf_free(line);
224     buf_free(ek);
225     buf_free(eklist);
226     buf_free(key);
227     buf_free(pubkey);
228     buf_free(out);
229     buf_free(nymlist);
230     buf_free(userpass);
231     buf_free(oldchains);
232     buf_free(config);
233     return (err);
234 rabbi 262 #endif /* else if USE_PGP */
235 rabbi 1 }
236    
237     int nym_encrypt(BUFFER *msg, char *nym, int type)
238     {
239     #ifndef USE_PGP
240     return (-1);
241 rabbi 262 #else /* end of not USE_PGP */
242 rabbi 1 BUFFER *out, *userpass, *sig, *config;
243     int err = -1;
244    
245     out = buf_new();
246     userpass = buf_new();
247     sig = buf_new();
248     config = buf_new();
249    
250     if (nymlist_getnym(nym, config, NULL, NULL, NULL, NULL) == NYM_OK) {
251     buf_appends(out, "From: ");
252     buf_append(out, nym, strchr(nym, '@') - nym);
253     buf_nl(out);
254     if (type == MSG_POST) {
255     buf_appends(out, "To: ");
256     buf_appends(out, MAILtoNEWS);
257     buf_nl(out);
258     }
259     buf_cat(out, msg);
260     mail_encode(out, 0);
261     buf_appendc(sig, '<');
262     buf_appends(sig, nym);
263     buf_appendc(sig, '>');
264     #ifdef DEBUG
265     buf_write(out, stderr);
266 rabbi 262 #endif /* DEBUG */
267 rabbi 1 user_pass(userpass);
268     err = pgp_encrypt(PGP_ENCRYPT | PGP_SIGN | PGP_TEXT | PGP_REMAIL,
269     out, config, sig, userpass, NULL, NYMSECRING);
270     if (err == 0) {
271     buf_clear(msg);
272     buf_appends(msg, "To: send");
273     buf_appends(msg, strchr(nym, '@'));
274     buf_nl(msg);
275     buf_nl(msg);
276     buf_cat(msg, out);
277     }
278     }
279     buf_free(out);
280     buf_free(config);
281     buf_free(userpass);
282     buf_free(sig);
283     return (err);
284 rabbi 262 #endif /* else if USE_PGP */
285 rabbi 1 }
286    
287     int nym_decrypt(BUFFER *msg, char *thisnym, BUFFER *log)
288     {
289     #ifndef USE_PGP
290     return (-1);
291 rabbi 262 #else /* end of not USE_PGP */
292 rabbi 1 BUFFER *pgpmsg, *out, *line;
293     BUFFER *nymlist, *userpass;
294     BUFFER *decr, *sig, *mid;
295     BUFFER *name, *rblocks, *eklist, *config;
296     int decrypted = 0;
297     int err = 1;
298     long ptr;
299     char nym[LINELEN];
300     BUFFER *ek, *opt;
301     int status;
302     LOCK *nymlock;
303 rabbi 6 time_t t;
304     struct tm *tc;
305     char timeline[LINELEN];
306 rabbi 1
307     pgpmsg = buf_new();
308     out = buf_new();
309     line = buf_new();
310     nymlist = buf_new();
311     userpass = buf_new();
312     config = buf_new();
313     ek = buf_new();
314     decr = buf_new();
315     sig = buf_new();
316     mid = buf_new();
317     opt = buf_new();
318     name = buf_new();
319     rblocks = buf_new();
320     eklist = buf_new();
321    
322     if (thisnym)
323     thisnym[0] = '\0';
324     while ((ptr = msg->ptr, err = buf_getline(msg, line)) != -1) {
325     if (bufleft(line, begin_pgpmsg)) {
326     err = -1;
327     msg->ptr = ptr;
328     pgp_dearmor(msg, pgpmsg);
329     if (pgp_isconventional(pgpmsg)) {
330     user_pass(userpass);
331     nymlock = lockfile(NYMDB);
332     if (nymlist_read(nymlist) == -1)
333     user_delpass();
334     while (nymlist_get(nymlist, nym, config, eklist, opt, name,
335     rblocks, &status) >= 0) {
336     while (buf_getline(eklist, ek) == 0) {
337     decode(ek, ek);
338     if (t1_getreply(pgpmsg, ek, 20) == 0) {
339     buf_clear(out);
340     err = pgp_decrypt(pgpmsg, userpass, sig, NULL,
341     NYMSECRING);
342     buf_sets(out, "From nymserver ");
343     if (strchr(sig->data, '[') && strchr(sig->data, ']'))
344     buf_append(out, strchr(sig->data, '[') + 1,
345     strchr(sig->data, ']') -
346     strchr(sig->data, '[') - 1);
347 rabbi 6 else {
348     t = time(NULL);
349     tc = localtime(&t);
350     strftime(timeline, LINELEN, "%a %b %d %H:%M:%S %Y", tc);
351     buf_appends(out, timeline);
352     }
353 rabbi 1 buf_nl(out);
354     if (err == PGP_SIGOK &&
355     bufifind(sig, config->data)) {
356     buf_appends(out, "Nym: ");
357     if (status == NYM_WAITING)
358     buf_appends(out, "confirm ");
359     buf_appends(out, nym);
360     buf_nl(out);
361     if (thisnym && status == NYM_OK)
362     strncpy(thisnym, nym, LINELEN);
363     } else
364     buf_appends(out, "Warning: Signature verification failed!\n");
365     buf_cat(out, pgpmsg);
366     decrypted = 2;
367     if (log) {
368     digest_md5(out, mid);
369     encode(mid, 0);
370     if (buffind(log, mid->data)) {
371     decrypted = -1;
372     unlockfile(nymlock);
373     goto end;
374     } else {
375     buf_cat(log, mid);
376     buf_nl(log);
377     }
378     }
379     if (status == NYM_WAITING) {
380     nymlist_del(nymlist, nym);
381     nymlist_append(nymlist, nym, config, opt,
382     name, rblocks, eklist, NYM_OK);
383     }
384     break;
385     }
386     }
387     }
388     nymlist_write(nymlist);
389     unlockfile(nymlock);
390     }
391     if (decrypted == 0) {
392     user_pass(userpass);
393     err = pgp_decrypt(pgpmsg, userpass, sig, PGPPUBRING, PGPSECRING);
394     if (err == PGP_ERR)
395     err = pgp_decrypt(pgpmsg, userpass, sig, PGPPUBRING,
396     NYMSECRING);
397     #if 0
398     if (err == PGP_PASS || err == PGP_ERR)
399     user_delpass();
400 rabbi 262 #endif /* 0 */
401 rabbi 1 if (err != PGP_ERR && err != PGP_PASS && err != PGP_NOMSG &&
402     err != PGP_NODATA) {
403     buf_appends(out, info_beginpgp);
404     if (err == PGP_SIGOK)
405     buf_appendf(out, " (SIGNED)\n%s%b", info_pgpsig, sig);
406     buf_nl(out);
407     buf_cat(out, pgpmsg);
408     buf_appends(out, info_endpgp);
409     buf_nl(out);
410     decrypted = 1;
411     }
412     }
413     if (decrypted == 0) {
414     buf_cat(out, line);
415     buf_nl(out);
416     }
417     } else {
418     if (bufileft(line, info_beginpgp))
419     buf_appendc(out, ' '); /* escape info line in text */
420     buf_cat(out, line);
421     buf_nl(out);
422     }
423     }
424    
425     if (decrypted)
426     buf_move(msg, out);
427     else
428     buf_rewind(msg);
429     if (decrypted == 2)
430     nym_decrypt(msg, thisnym, NULL);
431     end:
432     buf_free(pgpmsg);
433     buf_free(out);
434     buf_free(line);
435     buf_free(decr);
436     buf_free(sig);
437     buf_free(mid);
438     buf_free(opt);
439     buf_free(name);
440     buf_free(config);
441     buf_free(rblocks);
442     buf_free(eklist);
443     buf_free(nymlist);
444     buf_free(userpass);
445     buf_free(ek);
446     return (decrypted);
447 rabbi 262 #endif /* else if USE_PGP */
448 rabbi 1 }
449    
450     int nymlist_read(BUFFER *list)
451     {
452     #ifdef USE_PGP
453     BUFFER *key;
454    
455 rabbi 262 #endif /* USE_PGP */
456 rabbi 1 FILE *f;
457     int err = 0;
458    
459     buf_clear(list);
460     f = mix_openfile(NYMDB, "rb");
461     if (f != NULL) {
462     buf_read(list, f);
463     fclose(f);
464     #ifdef USE_PGP
465     key = buf_new();
466     user_pass(key);
467     if (key->length)
468     if (pgp_decrypt(list, key, NULL, NULL, NULL) < 0) {
469     buf_clear(list);
470     err = -1;
471     }
472 rabbi 262 buf_free(key);
473     #endif /* USE_PGP */
474 rabbi 1 }
475     return (err);
476     }
477    
478     int nymlist_write(BUFFER *list)
479     {
480     #ifdef USE_PGP
481     BUFFER *key;
482    
483 rabbi 262 #endif /* USE_PGP */
484 rabbi 1 FILE *f;
485    
486     if (list->length == 0)
487     return (-1);
488    
489     #ifdef USE_PGP
490     key = buf_new();
491     user_pass(key);
492     if (key->length)
493     pgp_encrypt(PGP_NCONVENTIONAL | PGP_NOARMOR, list, key, NULL, NULL, NULL,
494     NULL);
495     buf_free(key);
496 rabbi 262 #endif /* USE_PGP */
497 rabbi 1 f = mix_openfile(NYMDB, "wb");
498     if (f == NULL)
499     return (-1);
500     else {
501     buf_write(list, f);
502     fclose(f);
503     }
504     return (0);
505     }
506    
507     int nymlist_get(BUFFER *list, char *nym, BUFFER *config, BUFFER *ek,
508     BUFFER *opt, BUFFER *name, BUFFER *chains, int *status)
509     {
510     BUFFER *line;
511     int err = -1;
512    
513     line = buf_new();
514     if (ek)
515     buf_clear(ek);
516     if (opt)
517     buf_clear(opt);
518     if (name)
519     buf_clear(name);
520     if (chains)
521     buf_clear(chains);
522     if (config)
523     buf_clear(config);
524    
525     for (;;) {
526     if (buf_getline(list, line) == -1)
527     goto end;
528     if (bufleft(line, "nym="))
529     break;
530     }
531     strncpy(nym, line->data + 4, LINELEN);
532    
533     for (;;) {
534     if (buf_getline(list, line) == -1)
535     break;
536     if (opt && bufleft(line, "opt="))
537     line->ptr = 4, buf_rest(opt, line);
538     if (name && bufleft(line, "name="))
539     line->ptr = 5, buf_rest(name, line);
540     if (config && bufleft(line, "config="))
541     line->ptr = 7, buf_rest(config, line);
542     if (bufeq(line, "ek=")) {
543     while (buf_getline(list, line) == 0 && !bufeq(line, "end ek"))
544     if (ek) {
545     buf_cat(ek, line);
546     buf_nl(ek);
547     }
548     }
549     if (bufeq(line, "chains=")) {
550     while (buf_getline(list, line) == 0 && !bufeq(line, "end chains"))
551     if (chains) {
552     buf_cat(chains, line);
553     buf_nl(chains);
554     }
555     }
556     if (status && bufleft(line, "status="))
557     *status = line->data[7] - '0';
558     if (bufeq(line, "end")) {
559     err = 0;
560     break;
561     }
562     }
563     end:
564     buf_free(line);
565     return (err);
566     }
567    
568     int nymlist_append(BUFFER *list, char *nym, BUFFER *config, BUFFER *opt,
569     BUFFER *name, BUFFER *rblocks, BUFFER *eklist, int status)
570     {
571     buf_appends(list, "nym=");
572     buf_appends(list, nym);
573     buf_nl(list);
574     buf_appends(list, "config=");
575     buf_cat(list, config);
576     buf_nl(list);
577     buf_appends(list, "status=");
578     buf_appendc(list, (byte) (status + '0'));
579     buf_nl(list);
580     if (name) {
581     buf_appends(list, "name=");
582     buf_cat(list, name);
583     buf_nl(list);
584     }
585     buf_appends(list, "opt=");
586     buf_cat(list, opt);
587     buf_nl(list);
588     buf_appends(list, "chains=\n");
589     buf_cat(list, rblocks);
590     buf_appends(list, "end chains\n");
591     buf_appends(list, "ek=\n");
592     buf_cat(list, eklist);
593     buf_appends(list, "end ek\n");
594     buf_appends(list, "end\n");
595     return (0);
596     }
597    
598     int nymlist_del(BUFFER *list, char *nym)
599     {
600     BUFFER *new;
601     char thisnym[LINELEN];
602     BUFFER *config, *ek, *name, *rblocks, *opt;
603     int thisstatus;
604    
605     new = buf_new();
606     config = buf_new();
607     ek = buf_new();
608     name = buf_new();
609     rblocks = buf_new();
610     opt = buf_new();
611    
612     buf_rewind(list);
613     while (nymlist_get(list, thisnym, config, ek, opt, name, rblocks,
614     &thisstatus) >= 0)
615     if (!streq(nym, thisnym))
616     nymlist_append(new, thisnym, config, opt, name, rblocks, ek,
617     thisstatus);
618    
619     buf_move(list, new);
620     buf_free(new);
621     buf_free(name);
622     buf_free(opt);
623     buf_free(rblocks);
624     buf_free(config);
625     buf_free(ek);
626     return (0);
627     }
628    
629     int nymlist_getnym(char *nym, BUFFER *config, BUFFER *ek, BUFFER *opt,
630     BUFFER *name, BUFFER *rblocks)
631     /* "nym@nymserver.domain" or "nym@" */
632     {
633     BUFFER *nymlist, *userpass;
634     char n[LINELEN];
635     int err = -1;
636     int status;
637    
638     nymlist = buf_new();
639     userpass = buf_new();
640    
641     user_pass(userpass);
642     if (nymlist_read(nymlist) != -1) {
643     while (nymlist_get(nymlist, n, config, ek, opt, name, rblocks,
644     &status) >= 0)
645     if (streq(nym, n) || (nym[strlen(nym) - 1] == '@' && strleft(n, nym))) {
646     err = status;
647     strncpy(nym, n, LINELEN);
648     break;
649     }
650     }
651     buf_free(userpass);
652     buf_free(nymlist);
653     return (err);
654     }
655    
656     int nymlist_getstatus(char *nym)
657     {
658     int status;
659    
660     if ((status = nymlist_getnym(nym, NULL, NULL, NULL, NULL, NULL)) == 0)
661     return (status);
662     else
663     return (-1);
664     }

  ViewVC Help
Powered by ViewVC 1.1.5