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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 493 - (hide annotations) (download)
Wed Apr 2 13:14:13 2003 UTC (10 years, 1 month ago) by weaselp
File MIME type: text/plain
File size: 7688 byte(s)
Check that feedback buffer is not null before operating on it in chain_select(). Closes #631353
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     Prepare messages for remailer chain
9 weaselp 493 $Id: chain.c,v 1.6 2003/04/02 13:14:13 weaselp Exp $ */
10 rabbi 1
11    
12     #include "mix3.h"
13     #include <string.h>
14     #include <ctype.h>
15     #include <assert.h>
16     #include <stdlib.h>
17    
18     void clienterr(BUFFER *msgbuf, char *err)
19     {
20     if (msgbuf) {
21     buf_sets(msgbuf, "Error: ");
22     buf_appends(msgbuf, err);
23     } else
24     errlog(ERRORMSG, "%s\n", err);
25     }
26    
27     int chain_select(int hop[], char *chainstr, int maxrem, REMAILER *remailer,
28     int type, BUFFER *feedback)
29     {
30     int len = 0;
31     int i, j, k;
32     BUFFER *chain, *selected, *addr;
33     chain = buf_new();
34     selected = buf_new();
35     addr = buf_new();
36    
37     if (chainstr == NULL || chainstr[0] == '\0')
38     buf_sets(chain, CHAIN);
39     else
40     buf_sets(chain, chainstr);
41    
42     /* put the chain backwards: final hop is in hop[0] */
43    
44     for (i = chain->length; i >= 0; i--)
45     if (i == 0 || chain->data[i - 1] <= ' ' || chain->data[i - 1] == ','
46     || chain->data[i - 1] == ';' || chain->data[i - 1] == ':') {
47     for (j = i; isspace(chain->data[j]);) /* ignore whitespace */
48     j++;
49     if (chain->data[j] == '\0')
50     break;
51    
52     if (chain->data[j] == '*')
53     k = 0;
54 weaselp 332 #if 0
55 rabbi 1 else if (isdigit(chain->data[j]))
56     k = atoi(chain->data + j);
57 rabbi 262 #endif /* 0 */
58 rabbi 1 else {
59     buf_sets(selected, chain->data + j);
60     rfc822_addr(selected, addr);
61     buf_clear(selected);
62     buf_getline(addr, selected);
63     if (!selected->length)
64     buf_sets(selected, chain->data + j);
65    
66     for (k = 0; k < maxrem; k++)
67     if (((remailer[k].flags.mix && type == 0) ||
68     (remailer[k].flags.cpunk && type == 1) ||
69     (remailer[k].flags.newnym && type == 2)) &&
70     (streq(remailer[k].name, selected->data) ||
71     strieq(remailer[k].addr, selected->data) ||
72     (selected->data[0] == '@' && strifind(remailer[k].addr,
73     selected->data))))
74     break;
75     }
76     if (k < 0 || k >= maxrem) {
77 weaselp 493 if (feedback != NULL) {
78     buf_appendf(feedback, "No such remailer: %b", selected);
79     buf_nl(feedback);
80     }
81 weaselp 332 #if 0
82 rabbi 1 k = 0;
83 rabbi 262 #else /* end of 0 */
84 rabbi 1 len = -1;
85     goto end;
86 rabbi 262 #endif /* else not 0 */
87 rabbi 1 }
88     hop[len++] = k;
89 rabbi 26 if (len >= 20) { /* array passed in is has length 20 */
90 weaselp 493 if (feedback != NULL) {
91     buf_appends(feedback, "Chain too long.\n");
92     }
93 rabbi 1 break;
94     }
95     if (i > 0)
96     chain->data[i - 1] = '\0';
97     }
98     end:
99     buf_free(chain);
100     buf_free(selected);
101     buf_free(addr);
102     return len;
103     }
104    
105     int chain_randfinal(int type, REMAILER *remailer, int maxrem, int rtype)
106     {
107     int num = 0;
108     int i;
109     int t;
110    
111     t = rtype;
112     if (rtype == 2)
113     t = 1;
114    
115     /* select a random final hop */
116     for (i = 1; i < maxrem; i++) {
117     if (((remailer[i].flags.mix && rtype == 0) ||
118     (remailer[i].flags.pgp && remailer[i].flags.ek && rtype == 1) ||
119     (remailer[i].flags.newnym && rtype == 2)) &&
120     remailer[i].info[t].reliability >= 100 * RELFINAL &&
121     remailer[i].info[t].latency <= MAXLAT &&
122     (type == MSG_NULL || !remailer[i].flags.middle) &&
123 weaselp 387 !remailer[i].flags.star_ex &&
124 rabbi 1 (remailer[i].flags.post || type != MSG_POST))
125     num++;
126     }
127     if (num == 0)
128     i = -1;
129     else {
130     do
131     i = rnd_number(maxrem) + 1;
132     while (!(((remailer[i].flags.mix && rtype == 0) ||
133     (remailer[i].flags.pgp && remailer[i].flags.ek && rtype == 1) ||
134     (remailer[i].flags.newnym && rtype == 2)) &&
135     remailer[i].info[t].reliability >= 100 * RELFINAL &&
136     remailer[i].info[t].latency <= MAXLAT &&
137     (type == MSG_NULL || !remailer[i].flags.middle) &&
138 weaselp 387 !remailer[i].flags.star_ex &&
139 rabbi 1 (remailer[i].flags.post || type != MSG_POST)));
140     }
141     return (i);
142     }
143    
144     int chain_rand(REMAILER *remailer, int maxrem,
145     int thischain[], int chainlen, int t)
146     /* set random chain. returns 0 if not random, 1 if random, -1 on error */
147     {
148     int hop;
149     int err = 0;
150    
151     assert(t == 0 || t == 1);
152    
153     for (hop = 0; hop < chainlen; hop++)
154     if (thischain[hop] == 0) {
155     int select[MAXREM];
156     int randavail = 0;
157     int i;
158    
159     err = 1;
160     for (i = 1; i < maxrem; i++)
161     select[i] = ((remailer[i].flags.mix && t == 0) ||
162     (remailer[i].flags.pgp && remailer[i].flags.ek && t == 1))
163     && remailer[i].info[t].reliability >= 100 * MINREL &&
164 weaselp 387 !remailer[i].flags.star_ex &&
165 rabbi 1 remailer[i].info[t].latency <= MAXLAT,
166     randavail += select[i];
167    
168     for (i = hop - DISTANCE; i <= hop + DISTANCE; i++)
169     if (i >= 0 && i < chainlen && select[thischain[i]])
170     select[thischain[i]] = 0, randavail--;
171    
172     if (randavail < 1) {
173     err = -1;
174     goto end;
175     }
176     do
177     thischain[hop] = rnd_number(maxrem - 1) + 1;
178     while (!select[thischain[hop]]);
179     }
180     end:
181     return (err);
182     }
183    
184     int mix_encrypt(int type, BUFFER *message, char *chainstr, int numcopies,
185     BUFFER *chainlist)
186     {
187     return (mix2_encrypt(type, message, chainstr, numcopies, chainlist));
188     }
189    
190     /* float chain_reliablity(char *chain, int chaintype,
191 weaselp 332 char *reliability_string);
192 rabbi 1 *
193     * Compute reliablity of a chain.
194     *
195     * We get the reliablity of the chain by multiplying the reliablity of
196     * every remailer in the chain. The return value is the reliablity of
197     * the chain, or a negative number if the reliablity can not be
198     * calculated. There are two reasons why may not be able to calculated
199     * the reliablity: A remailer in the chain is selected randomly, or we
200     * don't have statistics about one of the remailers in the chain.
201     * remailer_type indicates the remailer type:
202     * 0 = Mixmaster, 1 = Cypherpunk
203     *
204     * If reliability_string is non-NULL, the reliability is also returned
205     * as a string in this variable. The size of the string must be at
206     * least 9 characters!
207     *
208     * This function has been added by Gerd Beuster. (gb@uni-koblenz.de)
209     *--------------------------------------------------------------------*/
210    
211     float chain_reliability(char *chain, int chaintype,
212     char *reliability_string){
213 weaselp 332
214 rabbi 1 float acc_reliability = 1; /* Accumulated reliablity */
215     char *name_start, *name_end; /* temporary pointers used
216     in string scanning */
217     char remailer_name[20]; /* The length of the array is taken from mix3.h. */
218     int error = 0;
219     int maxrem;
220     int i;
221     REMAILER remailer[MAXREM];
222    
223     /* chaintype 0=mix 1=ek 2=newnym */
224     assert((chaintype == 0) || (chaintype == 1));
225     maxrem = (chaintype == 0 ? mix2_rlist(remailer) : t1_rlist(remailer));
226    
227     /* Dissect chain */
228     name_start = chain;
229     name_end = chain;
230     while(*name_end != '\0'){ /* While string not scanned completely */
231     do /* Get next remailer */
232     name_end+=sizeof(char);
233     while( (*name_end != ',') && (*name_end != '\0'));
234     strncpy(remailer_name, name_start,
235     (name_end - name_start) / sizeof(char) + 1*sizeof(char));
236     remailer_name[name_end-name_start]='\0';
237     /* Lookup reliablity for remailer remailer_name */
238     for(i=0;
239     (i < maxrem) && (strcmp(remailer[i].name, remailer_name) != 0);
240     i++);
241     if(!strcmp(remailer[i].name, remailer_name)) /* Found it! */
242     acc_reliability *=
243     ((float) remailer[i].info[chaintype].reliability) / 10000;
244     else
245     error = 1; /* Did not find this remailer. We can't calculate
246     the reliablity for the whole chain. */
247     name_start = name_end+sizeof(char);
248     }
249    
250     if(error || (name_start==name_end))
251     acc_reliability = -1;
252    
253     /* Convert reliability into string, if appropriate */
254     if(reliability_string){
255     if(acc_reliability < 0)
256     sprintf(reliability_string, " n/a ");
257     else{
258     sprintf(reliability_string, "%6.2f", acc_reliability*100);
259     *(reliability_string+6*sizeof(char)) = '%';
260     }
261     }
262 weaselp 332
263 rabbi 1 return acc_reliability;
264     }
265 weaselp 332

  ViewVC Help
Powered by ViewVC 1.1.5