diff options
author | Christian Grothoff <christian@grothoff.org> | 2019-06-27 12:14:19 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2019-06-27 12:14:19 +0200 |
commit | 4c2a06deba76e8be4098059b860e76db3cf4ae7e (patch) | |
tree | 210bf40156160189926fa3efa10f87d7928433f7 /src/util | |
parent | 62fccf2d984f8e0d537fe919d095f3776bd3369c (diff) | |
download | gnunet-4c2a06deba76e8be4098059b860e76db3cf4ae7e.tar.gz gnunet-4c2a06deba76e8be4098059b860e76db3cf4ae7e.zip |
memcpy fits better
Diffstat (limited to 'src/util')
-rw-r--r-- | src/util/socks.c | 393 |
1 files changed, 203 insertions, 190 deletions
diff --git a/src/util/socks.c b/src/util/socks.c index 9e974e6bb..0e8583afa 100644 --- a/src/util/socks.c +++ b/src/util/socks.c | |||
@@ -29,9 +29,10 @@ | |||
29 | #include "gnunet_util_lib.h" | 29 | #include "gnunet_util_lib.h" |
30 | 30 | ||
31 | 31 | ||
32 | #define LOG(kind,...) GNUNET_log_from (kind, "util-socks", __VA_ARGS__) | 32 | #define LOG(kind, ...) GNUNET_log_from (kind, "util-socks", __VA_ARGS__) |
33 | 33 | ||
34 | #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util-socks", syscall) | 34 | #define LOG_STRERROR(kind, syscall) \ |
35 | GNUNET_log_from_strerror (kind, "util-socks", syscall) | ||
35 | 36 | ||
36 | 37 | ||
37 | /* SOCKS5 authentication methods */ | 38 | /* SOCKS5 authentication methods */ |
@@ -56,20 +57,33 @@ | |||
56 | #define SOCKS5_REP_ANOTSUP 0x08 /* Address not supported */ | 57 | #define SOCKS5_REP_ANOTSUP 0x08 /* Address not supported */ |
57 | #define SOCKS5_REP_INVADDR 0x09 /* Inalid address */ | 58 | #define SOCKS5_REP_INVADDR 0x09 /* Inalid address */ |
58 | 59 | ||
59 | const char * SOCKS5_REP_names(int rep) | 60 | const char * |
61 | SOCKS5_REP_names (int rep) | ||
60 | { | 62 | { |
61 | switch (rep) { | 63 | switch (rep) |
62 | case SOCKS5_REP_SUCCEEDED: return "succeeded"; | 64 | { |
63 | case SOCKS5_REP_FAIL: return "general SOCKS server failure"; | 65 | case SOCKS5_REP_SUCCEEDED: |
64 | case SOCKS5_REP_NALLOWED: return "connection not allowed by ruleset"; | 66 | return "succeeded"; |
65 | case SOCKS5_REP_NUNREACH: return "Network unreachable"; | 67 | case SOCKS5_REP_FAIL: |
66 | case SOCKS5_REP_HUNREACH: return "Host unreachable"; | 68 | return "general SOCKS server failure"; |
67 | case SOCKS5_REP_REFUSED: return "connection refused"; | 69 | case SOCKS5_REP_NALLOWED: |
68 | case SOCKS5_REP_EXPIRED: return "TTL expired"; | 70 | return "connection not allowed by ruleset"; |
69 | case SOCKS5_REP_CNOTSUP: return "Command not supported"; | 71 | case SOCKS5_REP_NUNREACH: |
70 | case SOCKS5_REP_ANOTSUP: return "Address not supported"; | 72 | return "Network unreachable"; |
71 | case SOCKS5_REP_INVADDR: return "Invalid address"; | 73 | case SOCKS5_REP_HUNREACH: |
72 | default: return NULL; | 74 | return "Host unreachable"; |
75 | case SOCKS5_REP_REFUSED: | ||
76 | return "connection refused"; | ||
77 | case SOCKS5_REP_EXPIRED: | ||
78 | return "TTL expired"; | ||
79 | case SOCKS5_REP_CNOTSUP: | ||
80 | return "Command not supported"; | ||
81 | case SOCKS5_REP_ANOTSUP: | ||
82 | return "Address not supported"; | ||
83 | case SOCKS5_REP_INVADDR: | ||
84 | return "Invalid address"; | ||
85 | default: | ||
86 | return NULL; | ||
73 | } | 87 | } |
74 | }; | 88 | }; |
75 | 89 | ||
@@ -84,30 +98,26 @@ const char * SOCKS5_REP_names(int rep) | |||
84 | * @return pointer to the end of the encoded string in the buffer | 98 | * @return pointer to the end of the encoded string in the buffer |
85 | */ | 99 | */ |
86 | unsigned char * | 100 | unsigned char * |
87 | SOCK5_proto_string(unsigned char * b, | 101 | SOCK5_proto_string (unsigned char *b, const char *s) |
88 | const char * s) | ||
89 | { | 102 | { |
90 | size_t l = strlen(s); | 103 | size_t l = strlen (s); |
91 | 104 | ||
92 | if (l > 255) | 105 | if (l > 255) |
93 | { | 106 | { |
94 | LOG (GNUNET_ERROR_TYPE_WARNING, | 107 | LOG (GNUNET_ERROR_TYPE_WARNING, |
95 | "SOCKS5 cannot handle hostnames, usernames, or passwords over 255 bytes, truncating.\n"); | 108 | "SOCKS5 cannot handle hostnames, usernames, or passwords over 255 bytes, truncating.\n"); |
96 | l=255; | 109 | l = 255; |
97 | } | 110 | } |
98 | *(b++) = (unsigned char) l; | 111 | *(b++) = (unsigned char) l; |
99 | /* | 112 | memcpy (b, s, l); |
100 | * intentionally use strncpy (trailing zero byte must be stripped in b) | 113 | return b + l; |
101 | */ | ||
102 | strncpy ((char*)b, s, l); | ||
103 | return b+l; | ||
104 | } | 114 | } |
105 | 115 | ||
106 | 116 | ||
107 | #define SOCKS5_step_greet 0 | 117 | #define SOCKS5_step_greet 0 |
108 | #define SOCKS5_step_auth 1 | 118 | #define SOCKS5_step_auth 1 |
109 | #define SOCKS5_step_cmd 2 | 119 | #define SOCKS5_step_cmd 2 |
110 | #define SOCKS5_step_done 3 | 120 | #define SOCKS5_step_done 3 |
111 | 121 | ||
112 | /** | 122 | /** |
113 | * State of the SOCKS5 handshake. | 123 | * State of the SOCKS5 handshake. |
@@ -143,7 +153,7 @@ struct GNUNET_SOCKS_Handshake | |||
143 | /** | 153 | /** |
144 | * Pointers delineating protoocol steps in the outbut buffer | 154 | * Pointers delineating protoocol steps in the outbut buffer |
145 | */ | 155 | */ |
146 | unsigned char * (outstep[4]); | 156 | unsigned char *(outstep[4]); |
147 | 157 | ||
148 | /** | 158 | /** |
149 | * SOCKS5 handshake input buffer | 159 | * SOCKS5 handshake input buffer |
@@ -153,8 +163,8 @@ struct GNUNET_SOCKS_Handshake | |||
153 | /** | 163 | /** |
154 | * Pointers delimiting the current step in the input buffer | 164 | * Pointers delimiting the current step in the input buffer |
155 | */ | 165 | */ |
156 | unsigned char * instart; | 166 | unsigned char *instart; |
157 | unsigned char * inend; | 167 | unsigned char *inend; |
158 | }; | 168 | }; |
159 | 169 | ||
160 | 170 | ||
@@ -163,7 +173,7 @@ struct GNUNET_SOCKS_Handshake | |||
163 | void | 173 | void |
164 | register_reciever (struct GNUNET_SOCKS_Handshake *ih, int want); | 174 | register_reciever (struct GNUNET_SOCKS_Handshake *ih, int want); |
165 | 175 | ||
166 | /* In fact, the client sends first rule in GNUNet suggests one could take | 176 | /* In fact, the client sends first rule in GNUNet suggests one could take |
167 | * large mac read sizes without fear of screwing up the proxied protocol, | 177 | * large mac read sizes without fear of screwing up the proxied protocol, |
168 | * but we make a proper SOCKS5 client. */ | 178 | * but we make a proper SOCKS5 client. */ |
169 | #define register_reciever_wants(ih) ((SOCKS5_step_cmd == ih->step) ? 10 : 2) | 179 | #define register_reciever_wants(ih) ((SOCKS5_step_cmd == ih->step) ? 10 : 2) |
@@ -181,7 +191,7 @@ register_sender (struct GNUNET_SOCKS_Handshake *ih); | |||
181 | * @return Connection handle that becomes usable when the handshake completes. | 191 | * @return Connection handle that becomes usable when the handshake completes. |
182 | */ | 192 | */ |
183 | void | 193 | void |
184 | SOCKS5_handshake_done(struct GNUNET_SOCKS_Handshake *ih) | 194 | SOCKS5_handshake_done (struct GNUNET_SOCKS_Handshake *ih) |
185 | { | 195 | { |
186 | GNUNET_CONNECTION_acivate_proxied (ih->target_connection); | 196 | GNUNET_CONNECTION_acivate_proxied (ih->target_connection); |
187 | } | 197 | } |
@@ -195,91 +205,93 @@ SOCKS5_handshake_done(struct GNUNET_SOCKS_Handshake *ih) | |||
195 | void | 205 | void |
196 | SOCKS5_handshake_step (struct GNUNET_SOCKS_Handshake *ih) | 206 | SOCKS5_handshake_step (struct GNUNET_SOCKS_Handshake *ih) |
197 | { | 207 | { |
198 | unsigned char * b = ih->instart; | 208 | unsigned char *b = ih->instart; |
199 | size_t available = ih->inend - b; | 209 | size_t available = ih->inend - b; |
200 | 210 | ||
201 | int want = register_reciever_wants(ih); | 211 | int want = register_reciever_wants (ih); |
202 | if (available < want) { | 212 | if (available < want) |
213 | { | ||
203 | register_reciever (ih, want - available); | 214 | register_reciever (ih, want - available); |
204 | return; | 215 | return; |
205 | } | 216 | } |
206 | GNUNET_assert (SOCKS5_step_done > ih->step && ih->step >= 0); | 217 | GNUNET_assert (SOCKS5_step_done > ih->step && ih->step >= 0); |
207 | switch (ih->step) { | 218 | switch (ih->step) |
208 | case SOCKS5_step_greet: /* SOCKS5 server's greeting */ | 219 | { |
209 | if (b[0] != 5) | 220 | case SOCKS5_step_greet: /* SOCKS5 server's greeting */ |
210 | { | 221 | if (b[0] != 5) |
211 | LOG (GNUNET_ERROR_TYPE_ERROR, | 222 | { |
212 | "Not a SOCKS5 server\n"); | 223 | LOG (GNUNET_ERROR_TYPE_ERROR, "Not a SOCKS5 server\n"); |
213 | GNUNET_assert (0); | 224 | GNUNET_assert (0); |
214 | } | 225 | } |
215 | switch (b[1]) { | 226 | switch (b[1]) |
216 | case SOCKS5_AUTH_NOAUTH: | 227 | { |
217 | ih->step=SOCKS5_step_cmd; /* no authentication to do */ | 228 | case SOCKS5_AUTH_NOAUTH: |
218 | break; | 229 | ih->step = SOCKS5_step_cmd; /* no authentication to do */ |
219 | case SOCKS5_AUTH_USERPASS: | ||
220 | ih->step=SOCKS5_step_auth; | ||
221 | break; | ||
222 | case SOCKS5_AUTH_REJECT: | ||
223 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
224 | "No authentication method accepted\n"); | ||
225 | return; | ||
226 | default: | ||
227 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
228 | "Not a SOCKS5 server / Nonsensical authentication\n"); | ||
229 | return; | ||
230 | } | ||
231 | b += 2; | ||
232 | break; | 230 | break; |
233 | case SOCKS5_step_auth: /* SOCKS5 server's responce to authentication */ | 231 | case SOCKS5_AUTH_USERPASS: |
234 | if (b[1] != 0) | 232 | ih->step = SOCKS5_step_auth; |
235 | { | ||
236 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
237 | "SOCKS5 authentication failed\n"); | ||
238 | GNUNET_assert (0); | ||
239 | } | ||
240 | ih->step=SOCKS5_step_cmd; | ||
241 | b += 2; | ||
242 | break; | 233 | break; |
243 | case SOCKS5_step_cmd: /* SOCKS5 server's responce to command */ | 234 | case SOCKS5_AUTH_REJECT: |
244 | if (b[0] != 5) | 235 | LOG (GNUNET_ERROR_TYPE_ERROR, "No authentication method accepted\n"); |
245 | { | ||
246 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
247 | "SOCKS5 protocol error\n"); | ||
248 | GNUNET_assert (0); | ||
249 | } | ||
250 | if (0 != b[1]) { | ||
251 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
252 | "SOCKS5 connection error : %s\n", | ||
253 | SOCKS5_REP_names(b[1])); | ||
254 | return; | ||
255 | } | ||
256 | b += 3; | ||
257 | /* There is no reason to verify host and port afaik. */ | ||
258 | switch (*(b++)) { | ||
259 | case 1: /* IPv4 */ | ||
260 | b += sizeof(struct in_addr); /* 4 */ | ||
261 | break; | ||
262 | case 4: /* IPv6 */ | ||
263 | b += sizeof(struct in6_addr); /* 16 */ | ||
264 | break; | ||
265 | case 3: /* hostname */ | ||
266 | b += *b; | ||
267 | break; | ||
268 | } | ||
269 | b += 2; /* port */ | ||
270 | if (b > ih->inend) { | ||
271 | register_reciever (ih, b - ih->inend); | ||
272 | return; | ||
273 | } | ||
274 | ih->step = SOCKS5_step_done; | ||
275 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
276 | "SOCKS5 server : %s\n", | ||
277 | SOCKS5_REP_names(b[1])); | ||
278 | ih->instart = b; | ||
279 | SOCKS5_handshake_done (ih); | ||
280 | return; | 236 | return; |
281 | case SOCKS5_step_done: | 237 | default: |
238 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
239 | "Not a SOCKS5 server / Nonsensical authentication\n"); | ||
240 | return; | ||
241 | } | ||
242 | b += 2; | ||
243 | break; | ||
244 | case SOCKS5_step_auth: /* SOCKS5 server's responce to authentication */ | ||
245 | if (b[1] != 0) | ||
246 | { | ||
247 | LOG (GNUNET_ERROR_TYPE_ERROR, "SOCKS5 authentication failed\n"); | ||
282 | GNUNET_assert (0); | 248 | GNUNET_assert (0); |
249 | } | ||
250 | ih->step = SOCKS5_step_cmd; | ||
251 | b += 2; | ||
252 | break; | ||
253 | case SOCKS5_step_cmd: /* SOCKS5 server's responce to command */ | ||
254 | if (b[0] != 5) | ||
255 | { | ||
256 | LOG (GNUNET_ERROR_TYPE_ERROR, "SOCKS5 protocol error\n"); | ||
257 | GNUNET_assert (0); | ||
258 | } | ||
259 | if (0 != b[1]) | ||
260 | { | ||
261 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
262 | "SOCKS5 connection error : %s\n", | ||
263 | SOCKS5_REP_names (b[1])); | ||
264 | return; | ||
265 | } | ||
266 | b += 3; | ||
267 | /* There is no reason to verify host and port afaik. */ | ||
268 | switch (*(b++)) | ||
269 | { | ||
270 | case 1: /* IPv4 */ | ||
271 | b += sizeof (struct in_addr); /* 4 */ | ||
272 | break; | ||
273 | case 4: /* IPv6 */ | ||
274 | b += sizeof (struct in6_addr); /* 16 */ | ||
275 | break; | ||
276 | case 3: /* hostname */ | ||
277 | b += *b; | ||
278 | break; | ||
279 | } | ||
280 | b += 2; /* port */ | ||
281 | if (b > ih->inend) | ||
282 | { | ||
283 | register_reciever (ih, b - ih->inend); | ||
284 | return; | ||
285 | } | ||
286 | ih->step = SOCKS5_step_done; | ||
287 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
288 | "SOCKS5 server : %s\n", | ||
289 | SOCKS5_REP_names (b[1])); | ||
290 | ih->instart = b; | ||
291 | SOCKS5_handshake_done (ih); | ||
292 | return; | ||
293 | case SOCKS5_step_done: | ||
294 | GNUNET_assert (0); | ||
283 | } | 295 | } |
284 | ih->instart = b; | 296 | ih->instart = b; |
285 | /* Do not reschedule the sender unless we're done reading. | 297 | /* Do not reschedule the sender unless we're done reading. |
@@ -297,13 +309,15 @@ SOCKS5_handshake_step (struct GNUNET_SOCKS_Handshake *ih) | |||
297 | */ | 309 | */ |
298 | void | 310 | void |
299 | reciever (void *cls, | 311 | reciever (void *cls, |
300 | const void *buf, size_t available, | 312 | const void *buf, |
301 | const struct sockaddr * addr, | 313 | size_t available, |
302 | socklen_t addrlen, int errCode) | 314 | const struct sockaddr *addr, |
315 | socklen_t addrlen, | ||
316 | int errCode) | ||
303 | { | 317 | { |
304 | struct GNUNET_SOCKS_Handshake * ih = cls; | 318 | struct GNUNET_SOCKS_Handshake *ih = cls; |
305 | GNUNET_assert (&ih->inend[available] < &ih->inbuf[1024]); | 319 | GNUNET_assert (&ih->inend[available] < &ih->inbuf[1024]); |
306 | GNUNET_memcpy(ih->inend, buf, available); | 320 | GNUNET_memcpy (ih->inend, buf, available); |
307 | ih->inend += available; | 321 | ih->inend += available; |
308 | SOCKS5_handshake_step (ih); | 322 | SOCKS5_handshake_step (ih); |
309 | } | 323 | } |
@@ -336,11 +350,9 @@ register_reciever (struct GNUNET_SOCKS_Handshake *ih, int want) | |||
336 | * @return number of bytes written to @a buf | 350 | * @return number of bytes written to @a buf |
337 | */ | 351 | */ |
338 | size_t | 352 | size_t |
339 | transmit_ready (void *cls, | 353 | transmit_ready (void *cls, size_t size, void *buf) |
340 | size_t size, | ||
341 | void *buf) | ||
342 | { | 354 | { |
343 | struct GNUNET_SOCKS_Handshake * ih = cls; | 355 | struct GNUNET_SOCKS_Handshake *ih = cls; |
344 | 356 | ||
345 | /* connection.c has many routines that call us with buf == NULL : | 357 | /* connection.c has many routines that call us with buf == NULL : |
346 | * signal_transmit_error() - DNS, etc. active | 358 | * signal_transmit_error() - DNS, etc. active |
@@ -362,31 +374,28 @@ transmit_ready (void *cls, | |||
362 | if (0 == ih->step) | 374 | if (0 == ih->step) |
363 | { | 375 | { |
364 | LOG (GNUNET_ERROR_TYPE_WARNING, | 376 | LOG (GNUNET_ERROR_TYPE_WARNING, |
365 | "Timeout contacting SOCKS server, retrying indefinitely, but probably hopeless.\n"); | 377 | "Timeout contacting SOCKS server, retrying indefinitely, but probably hopeless.\n"); |
366 | register_sender (ih); | 378 | register_sender (ih); |
367 | } | 379 | } |
368 | else | 380 | else |
369 | { | 381 | { |
370 | LOG (GNUNET_ERROR_TYPE_ERROR, | 382 | LOG (GNUNET_ERROR_TYPE_ERROR, |
371 | "Timeout during mid SOCKS handshake (step %u), probably not a SOCKS server.\n", | 383 | "Timeout during mid SOCKS handshake (step %u), probably not a SOCKS server.\n", |
372 | ih->step); | 384 | ih->step); |
373 | GNUNET_break (0); | 385 | GNUNET_break (0); |
374 | } | 386 | } |
375 | return 0; | 387 | return 0; |
376 | } | 388 | } |
377 | 389 | ||
378 | GNUNET_assert ( (1024 >= size) && (size > 0) ); | 390 | GNUNET_assert ((1024 >= size) && (size > 0)); |
379 | GNUNET_assert ( (SOCKS5_step_done > ih->step) && (ih->step >= 0) ); | 391 | GNUNET_assert ((SOCKS5_step_done > ih->step) && (ih->step >= 0)); |
380 | unsigned char * b = ih->outstep[ih->step]; | 392 | unsigned char *b = ih->outstep[ih->step]; |
381 | unsigned char * e = ih->outstep[ih->step+1]; | 393 | unsigned char *e = ih->outstep[ih->step + 1]; |
382 | GNUNET_assert (e <= &ih->outbuf[1024]); | 394 | GNUNET_assert (e <= &ih->outbuf[1024]); |
383 | unsigned int l = e - b; | 395 | unsigned int l = e - b; |
384 | GNUNET_assert (size >= l); | 396 | GNUNET_assert (size >= l); |
385 | GNUNET_memcpy (buf, | 397 | GNUNET_memcpy (buf, b, l); |
386 | b, | 398 | register_reciever (ih, register_reciever_wants (ih)); |
387 | l); | ||
388 | register_reciever (ih, | ||
389 | register_reciever_wants (ih)); | ||
390 | return l; | 399 | return l; |
391 | } | 400 | } |
392 | 401 | ||
@@ -407,8 +416,8 @@ register_sender (struct GNUNET_SOCKS_Handshake *ih) | |||
407 | GNUNET_assert (ih->step >= 0); | 416 | GNUNET_assert (ih->step >= 0); |
408 | if (0 == ih->step) | 417 | if (0 == ih->step) |
409 | timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 3); | 418 | timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 3); |
410 | unsigned char * b = ih->outstep[ih->step]; | 419 | unsigned char *b = ih->outstep[ih->step]; |
411 | unsigned char * e = ih->outstep[ih->step+1]; | 420 | unsigned char *e = ih->outstep[ih->step + 1]; |
412 | GNUNET_assert (ih->outbuf <= b && b < e && e < &ih->outbuf[1024]); | 421 | GNUNET_assert (ih->outbuf <= b && b < e && e < &ih->outbuf[1024]); |
413 | ih->th = GNUNET_CONNECTION_notify_transmit_ready (ih->socks5_connection, | 422 | ih->th = GNUNET_CONNECTION_notify_transmit_ready (ih->socks5_connection, |
414 | e - b, | 423 | e - b, |
@@ -431,18 +440,20 @@ register_sender (struct GNUNET_SOCKS_Handshake *ih) | |||
431 | struct GNUNET_SOCKS_Handshake * | 440 | struct GNUNET_SOCKS_Handshake * |
432 | GNUNET_SOCKS_init_handshake (const char *user, const char *pass) | 441 | GNUNET_SOCKS_init_handshake (const char *user, const char *pass) |
433 | { | 442 | { |
434 | struct GNUNET_SOCKS_Handshake *ih = GNUNET_new (struct GNUNET_SOCKS_Handshake); | 443 | struct GNUNET_SOCKS_Handshake *ih = |
435 | unsigned char * b = ih->outbuf; | 444 | GNUNET_new (struct GNUNET_SOCKS_Handshake); |
445 | unsigned char *b = ih->outbuf; | ||
436 | 446 | ||
437 | ih->outstep[SOCKS5_step_greet] = b; | 447 | ih->outstep[SOCKS5_step_greet] = b; |
438 | *(b++) = 5; /* SOCKS5 */ | 448 | *(b++) = 5; /* SOCKS5 */ |
439 | unsigned char * n = b++; | 449 | unsigned char *n = b++; |
440 | *n = 1; /* Number of authentication methods */ | 450 | *n = 1; /* Number of authentication methods */ |
441 | /* We support no authentication even when requesting authentication, | 451 | /* We support no authentication even when requesting authentication, |
442 | * but this appears harmless, given the way that Tor uses authentication. | 452 | * but this appears harmless, given the way that Tor uses authentication. |
443 | * And some SOCKS5 servers might require this. */ | 453 | * And some SOCKS5 servers might require this. */ |
444 | *(b++) = SOCKS5_AUTH_NOAUTH; | 454 | *(b++) = SOCKS5_AUTH_NOAUTH; |
445 | if (NULL != user) { | 455 | if (NULL != user) |
456 | { | ||
446 | *(b++) = SOCKS5_AUTH_USERPASS; | 457 | *(b++) = SOCKS5_AUTH_USERPASS; |
447 | (*n)++; | 458 | (*n)++; |
448 | } | 459 | } |
@@ -458,8 +469,8 @@ GNUNET_SOCKS_init_handshake (const char *user, const char *pass) | |||
458 | 469 | ||
459 | ih->outstep[SOCKS5_step_auth] = b; | 470 | ih->outstep[SOCKS5_step_auth] = b; |
460 | *(b++) = 1; /* subnegotiation ver.: 1 */ | 471 | *(b++) = 1; /* subnegotiation ver.: 1 */ |
461 | b = SOCK5_proto_string(b,user); | 472 | b = SOCK5_proto_string (b, user); |
462 | b = SOCK5_proto_string(b,pass); | 473 | b = SOCK5_proto_string (b, pass); |
463 | 474 | ||
464 | ih->outstep[SOCKS5_step_cmd] = b; | 475 | ih->outstep[SOCKS5_step_cmd] = b; |
465 | 476 | ||
@@ -478,7 +489,7 @@ GNUNET_SOCKS_init_handshake (const char *user, const char *pass) | |||
478 | struct GNUNET_SOCKS_Handshake * | 489 | struct GNUNET_SOCKS_Handshake * |
479 | GNUNET_SOCKS_init_handshake_noauth () | 490 | GNUNET_SOCKS_init_handshake_noauth () |
480 | { | 491 | { |
481 | return GNUNET_SOCKS_init_handshake (NULL,NULL); | 492 | return GNUNET_SOCKS_init_handshake (NULL, NULL); |
482 | } | 493 | } |
483 | 494 | ||
484 | 495 | ||
@@ -492,34 +503,41 @@ GNUNET_SOCKS_init_handshake_noauth () | |||
492 | */ | 503 | */ |
493 | void | 504 | void |
494 | GNUNET_SOCKS_set_handshake_destination (struct GNUNET_SOCKS_Handshake *ih, | 505 | GNUNET_SOCKS_set_handshake_destination (struct GNUNET_SOCKS_Handshake *ih, |
495 | const char *host, uint16_t port) | 506 | const char *host, |
507 | uint16_t port) | ||
496 | { | 508 | { |
497 | union { | 509 | union |
510 | { | ||
498 | struct in_addr in4; | 511 | struct in_addr in4; |
499 | struct in6_addr in6; | 512 | struct in6_addr in6; |
500 | } ia; | 513 | } ia; |
501 | unsigned char * b = ih->outstep[SOCKS5_step_cmd]; | 514 | unsigned char *b = ih->outstep[SOCKS5_step_cmd]; |
502 | 515 | ||
503 | *(b++) = 5; /* SOCKS5 */ | 516 | *(b++) = 5; /* SOCKS5 */ |
504 | *(b++) = 1; /* Establish a TCP/IP stream */ | 517 | *(b++) = 1; /* Establish a TCP/IP stream */ |
505 | *(b++) = 0; /* reserved */ | 518 | *(b++) = 0; /* reserved */ |
506 | 519 | ||
507 | /* Specify destination */ | 520 | /* Specify destination */ |
508 | if (1 == inet_pton(AF_INET,host,&ia.in4)) { | 521 | if (1 == inet_pton (AF_INET, host, &ia.in4)) |
509 | *(b++)= 1; /* IPv4 */ | 522 | { |
510 | GNUNET_memcpy (b, &ia.in4, sizeof(struct in_addr)); | 523 | *(b++) = 1; /* IPv4 */ |
511 | b += sizeof(struct in_addr); /* 4 */ | 524 | GNUNET_memcpy (b, &ia.in4, sizeof (struct in_addr)); |
512 | } else if (1 == inet_pton(AF_INET6,host,&ia.in6)) { | 525 | b += sizeof (struct in_addr); /* 4 */ |
513 | *(b++)= 4; /* IPv6 */ | 526 | } |
514 | GNUNET_memcpy (b, &ia.in6, sizeof(struct in6_addr)); | 527 | else if (1 == inet_pton (AF_INET6, host, &ia.in6)) |
515 | b += sizeof(struct in6_addr); /* 16 */ | 528 | { |
516 | } else { | 529 | *(b++) = 4; /* IPv6 */ |
517 | *(b++)= 3; /* hostname */ | 530 | GNUNET_memcpy (b, &ia.in6, sizeof (struct in6_addr)); |
531 | b += sizeof (struct in6_addr); /* 16 */ | ||
532 | } | ||
533 | else | ||
534 | { | ||
535 | *(b++) = 3; /* hostname */ | ||
518 | b = SOCK5_proto_string (b, host); | 536 | b = SOCK5_proto_string (b, host); |
519 | } | 537 | } |
520 | 538 | ||
521 | /* Specify port */ | 539 | /* Specify port */ |
522 | *(uint16_t*)b = htons (port); | 540 | *(uint16_t *) b = htons (port); |
523 | b += 2; | 541 | b += 2; |
524 | 542 | ||
525 | ih->outstep[SOCKS5_step_done] = b; | 543 | ih->outstep[SOCKS5_step_done] = b; |
@@ -534,10 +552,10 @@ GNUNET_SOCKS_set_handshake_destination (struct GNUNET_SOCKS_Handshake *ih, | |||
534 | * @return Connection handle that becomes usable when the SOCKS5 handshake completes. | 552 | * @return Connection handle that becomes usable when the SOCKS5 handshake completes. |
535 | */ | 553 | */ |
536 | struct GNUNET_CONNECTION_Handle * | 554 | struct GNUNET_CONNECTION_Handle * |
537 | GNUNET_SOCKS_run_handshake(struct GNUNET_SOCKS_Handshake *ih, | 555 | GNUNET_SOCKS_run_handshake (struct GNUNET_SOCKS_Handshake *ih, |
538 | struct GNUNET_CONNECTION_Handle *c) | 556 | struct GNUNET_CONNECTION_Handle *c) |
539 | { | 557 | { |
540 | ih->socks5_connection=c; | 558 | ih->socks5_connection = c; |
541 | ih->target_connection = GNUNET_CONNECTION_create_proxied_from_handshake (c); | 559 | ih->target_connection = GNUNET_CONNECTION_create_proxied_from_handshake (c); |
542 | register_sender (ih); | 560 | register_sender (ih); |
543 | 561 | ||
@@ -583,53 +601,51 @@ GNUNET_SOCKS_do_connect (const char *service_name, | |||
583 | unsigned long long port0; | 601 | unsigned long long port0; |
584 | unsigned long long port1; | 602 | unsigned long long port1; |
585 | 603 | ||
586 | if (GNUNET_YES != | 604 | if (GNUNET_YES != GNUNET_SOCKS_check_service (service_name, cfg)) |
587 | GNUNET_SOCKS_check_service (service_name, cfg)) | ||
588 | return NULL; | 605 | return NULL; |
589 | if (GNUNET_OK != | 606 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg, |
590 | GNUNET_CONFIGURATION_get_value_number (cfg, | 607 | service_name, |
591 | service_name, | 608 | "SOCKSPORT", |
592 | "SOCKSPORT", | 609 | &port0)) |
593 | &port0)) | ||
594 | port0 = 9050; | 610 | port0 = 9050; |
595 | /* A typical Tor client should usually try port 9150 for the TBB too, but | 611 | /* A typical Tor client should usually try port 9150 for the TBB too, but |
596 | * GNUnet can probably assume a system Tor installation. */ | 612 | * GNUnet can probably assume a system Tor installation. */ |
597 | if (port0 > 65535 || port0 <= 0) | 613 | if (port0 > 65535 || port0 <= 0) |
598 | { | 614 | { |
599 | LOG (GNUNET_ERROR_TYPE_WARNING, | 615 | LOG (GNUNET_ERROR_TYPE_WARNING, |
600 | _("Attempting to use invalid port %d as SOCKS proxy for service `%s'.\n"), | 616 | _ ( |
601 | port0, | 617 | "Attempting to use invalid port %d as SOCKS proxy for service `%s'.\n"), |
618 | port0, | ||
602 | service_name); | 619 | service_name); |
603 | return NULL; | 620 | return NULL; |
604 | } | 621 | } |
605 | if ( (GNUNET_OK != | 622 | if ((GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg, |
606 | GNUNET_CONFIGURATION_get_value_number (cfg, | 623 | service_name, |
607 | service_name, | 624 | "PORT", |
608 | "PORT", | 625 | &port1)) || |
609 | &port1)) || | 626 | (port1 > 65535) || (port1 <= 0) || |
610 | (port1 > 65535) || | 627 | (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, |
611 | (port1 <= 0) || | 628 | service_name, |
612 | (GNUNET_OK != | 629 | "HOSTNAME", |
613 | GNUNET_CONFIGURATION_get_value_string (cfg, | 630 | &host1))) |
614 | service_name, | ||
615 | "HOSTNAME", | ||
616 | &host1))) | ||
617 | { | 631 | { |
618 | LOG (GNUNET_ERROR_TYPE_WARNING, | 632 | LOG (GNUNET_ERROR_TYPE_WARNING, |
619 | _("Attempting to proxy service `%s' to invalid port %d or hostname.\n"), | 633 | _ ( |
620 | service_name, | 634 | "Attempting to proxy service `%s' to invalid port %d or hostname.\n"), |
635 | service_name, | ||
621 | port1); | 636 | port1); |
622 | return NULL; | 637 | return NULL; |
623 | } | 638 | } |
624 | /* Appeared to still work after host0 corrupted, so either test case is broken, or | 639 | /* Appeared to still work after host0 corrupted, so either test case is broken, or |
625 | this whole routine is not being called. */ | 640 | this whole routine is not being called. */ |
626 | if (GNUNET_OK != | 641 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, |
627 | GNUNET_CONFIGURATION_get_value_string (cfg, service_name, "SOCKSHOST", &host0)) | 642 | service_name, |
643 | "SOCKSHOST", | ||
644 | &host0)) | ||
628 | host0 = NULL; | 645 | host0 = NULL; |
629 | socks5 = GNUNET_CONNECTION_create_from_connect (cfg, | 646 | socks5 = GNUNET_CONNECTION_create_from_connect (cfg, |
630 | (host0 != NULL) | 647 | (host0 != NULL) ? host0 |
631 | ? host0 | 648 | : "127.0.0.1", |
632 | :"127.0.0.1", | ||
633 | port0); | 649 | port0); |
634 | GNUNET_free_non_null (host0); | 650 | GNUNET_free_non_null (host0); |
635 | 651 | ||
@@ -642,16 +658,13 @@ GNUNET_SOCKS_do_connect (const char *service_name, | |||
642 | service_name, | 658 | service_name, |
643 | "SOCKSPASS", | 659 | "SOCKSPASS", |
644 | &pass); | 660 | &pass); |
645 | ih = GNUNET_SOCKS_init_handshake(user,pass); | 661 | ih = GNUNET_SOCKS_init_handshake (user, pass); |
646 | GNUNET_free_non_null (user); | 662 | GNUNET_free_non_null (user); |
647 | GNUNET_free_non_null (pass); | 663 | GNUNET_free_non_null (pass); |
648 | 664 | ||
649 | GNUNET_SOCKS_set_handshake_destination (ih, | 665 | GNUNET_SOCKS_set_handshake_destination (ih, host1, port1); |
650 | host1, | ||
651 | port1); | ||
652 | GNUNET_free (host1); | 666 | GNUNET_free (host1); |
653 | return GNUNET_SOCKS_run_handshake (ih, | 667 | return GNUNET_SOCKS_run_handshake (ih, socks5); |
654 | socks5); | ||
655 | } | 668 | } |
656 | 669 | ||
657 | /* socks.c */ | 670 | /* socks.c */ |