/[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 26 - (show annotations) (download)
Tue Dec 11 09:02:16 2001 UTC (11 years, 5 months ago) by rabbi
File MIME type: text/plain
File size: 7500 byte(s)
Scott Renfro ixed a segfault when more than 20 remailers were linked in a
chain.
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 $Id: chain.c,v 1.2 2001/12/11 09:02:16 rabbi Exp $ */
10
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 #if 0
55 else if (isdigit(chain->data[j]))
56 k = atoi(chain->data + j);
57 #endif
58 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 buf_appendf(feedback, "No such remailer: %b", selected);
78 buf_nl(feedback);
79 #if 0
80 k = 0;
81 #else
82 len = -1;
83 goto end;
84 #endif
85 }
86 hop[len++] = k;
87 if (len >= 20) { /* array passed in is has length 20 */
88 buf_appends(feedback, "Chain too long.\n");
89 break;
90 }
91 if (i > 0)
92 chain->data[i - 1] = '\0';
93 }
94 end:
95 buf_free(chain);
96 buf_free(selected);
97 buf_free(addr);
98 return len;
99 }
100
101 int chain_randfinal(int type, REMAILER *remailer, int maxrem, int rtype)
102 {
103 int num = 0;
104 int i;
105 int t;
106
107 t = rtype;
108 if (rtype == 2)
109 t = 1;
110
111 /* select a random final hop */
112 for (i = 1; i < maxrem; i++) {
113 if (((remailer[i].flags.mix && rtype == 0) ||
114 (remailer[i].flags.pgp && remailer[i].flags.ek && rtype == 1) ||
115 (remailer[i].flags.newnym && rtype == 2)) &&
116 remailer[i].info[t].reliability >= 100 * RELFINAL &&
117 remailer[i].info[t].latency <= MAXLAT &&
118 (type == MSG_NULL || !remailer[i].flags.middle) &&
119 (remailer[i].flags.post || type != MSG_POST))
120 num++;
121 }
122 if (num == 0)
123 i = -1;
124 else {
125 do
126 i = rnd_number(maxrem) + 1;
127 while (!(((remailer[i].flags.mix && rtype == 0) ||
128 (remailer[i].flags.pgp && remailer[i].flags.ek && rtype == 1) ||
129 (remailer[i].flags.newnym && rtype == 2)) &&
130 remailer[i].info[t].reliability >= 100 * RELFINAL &&
131 remailer[i].info[t].latency <= MAXLAT &&
132 (type == MSG_NULL || !remailer[i].flags.middle) &&
133 (remailer[i].flags.post || type != MSG_POST)));
134 }
135 return (i);
136 }
137
138 int chain_rand(REMAILER *remailer, int maxrem,
139 int thischain[], int chainlen, int t)
140 /* set random chain. returns 0 if not random, 1 if random, -1 on error */
141 {
142 int hop;
143 int err = 0;
144
145 assert(t == 0 || t == 1);
146
147 for (hop = 0; hop < chainlen; hop++)
148 if (thischain[hop] == 0) {
149 int select[MAXREM];
150 int randavail = 0;
151 int i;
152
153 err = 1;
154 for (i = 1; i < maxrem; i++)
155 select[i] = ((remailer[i].flags.mix && t == 0) ||
156 (remailer[i].flags.pgp && remailer[i].flags.ek && t == 1))
157 && remailer[i].info[t].reliability >= 100 * MINREL &&
158 remailer[i].info[t].latency <= MAXLAT,
159 randavail += select[i];
160
161 for (i = hop - DISTANCE; i <= hop + DISTANCE; i++)
162 if (i >= 0 && i < chainlen && select[thischain[i]])
163 select[thischain[i]] = 0, randavail--;
164
165 if (randavail < 1) {
166 err = -1;
167 goto end;
168 }
169 do
170 thischain[hop] = rnd_number(maxrem - 1) + 1;
171 while (!select[thischain[hop]]);
172 }
173 end:
174 return (err);
175 }
176
177 int mix_encrypt(int type, BUFFER *message, char *chainstr, int numcopies,
178 BUFFER *chainlist)
179 {
180 return (mix2_encrypt(type, message, chainstr, numcopies, chainlist));
181 }
182
183 /* float chain_reliablity(char *chain, int chaintype,
184 char *reliability_string);
185 *
186 * Compute reliablity of a chain.
187 *
188 * We get the reliablity of the chain by multiplying the reliablity of
189 * every remailer in the chain. The return value is the reliablity of
190 * the chain, or a negative number if the reliablity can not be
191 * calculated. There are two reasons why may not be able to calculated
192 * the reliablity: A remailer in the chain is selected randomly, or we
193 * don't have statistics about one of the remailers in the chain.
194 * remailer_type indicates the remailer type:
195 * 0 = Mixmaster, 1 = Cypherpunk
196 *
197 * If reliability_string is non-NULL, the reliability is also returned
198 * as a string in this variable. The size of the string must be at
199 * least 9 characters!
200 *
201 * This function has been added by Gerd Beuster. (gb@uni-koblenz.de)
202 *--------------------------------------------------------------------*/
203
204 float chain_reliability(char *chain, int chaintype,
205 char *reliability_string){
206
207 float acc_reliability = 1; /* Accumulated reliablity */
208 char *name_start, *name_end; /* temporary pointers used
209 in string scanning */
210 char remailer_name[20]; /* The length of the array is taken from mix3.h. */
211 int error = 0;
212 int maxrem;
213 int i;
214 REMAILER remailer[MAXREM];
215
216 /* chaintype 0=mix 1=ek 2=newnym */
217 assert((chaintype == 0) || (chaintype == 1));
218 maxrem = (chaintype == 0 ? mix2_rlist(remailer) : t1_rlist(remailer));
219
220 /* Dissect chain */
221 name_start = chain;
222 name_end = chain;
223 while(*name_end != '\0'){ /* While string not scanned completely */
224 do /* Get next remailer */
225 name_end+=sizeof(char);
226 while( (*name_end != ',') && (*name_end != '\0'));
227 strncpy(remailer_name, name_start,
228 (name_end - name_start) / sizeof(char) + 1*sizeof(char));
229 remailer_name[name_end-name_start]='\0';
230 /* Lookup reliablity for remailer remailer_name */
231 for(i=0;
232 (i < maxrem) && (strcmp(remailer[i].name, remailer_name) != 0);
233 i++);
234 if(!strcmp(remailer[i].name, remailer_name)) /* Found it! */
235 acc_reliability *=
236 ((float) remailer[i].info[chaintype].reliability) / 10000;
237 else
238 error = 1; /* Did not find this remailer. We can't calculate
239 the reliablity for the whole chain. */
240 name_start = name_end+sizeof(char);
241 }
242
243 if(error || (name_start==name_end))
244 acc_reliability = -1;
245
246 /* Convert reliability into string, if appropriate */
247 if(reliability_string){
248 if(acc_reliability < 0)
249 sprintf(reliability_string, " n/a ");
250 else{
251 sprintf(reliability_string, "%6.2f", acc_reliability*100);
252 *(reliability_string+6*sizeof(char)) = '%';
253 }
254 }
255
256 return acc_reliability;
257 }
258

  ViewVC Help
Powered by ViewVC 1.1.5