aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/util/socks.c393
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
59const char * SOCKS5_REP_names(int rep) 60const char *
61SOCKS5_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 */
86unsigned char * 100unsigned char *
87SOCK5_proto_string(unsigned char * b, 101SOCK5_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
163void 173void
164register_reciever (struct GNUNET_SOCKS_Handshake *ih, int want); 174register_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 */
183void 193void
184SOCKS5_handshake_done(struct GNUNET_SOCKS_Handshake *ih) 194SOCKS5_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)
195void 205void
196SOCKS5_handshake_step (struct GNUNET_SOCKS_Handshake *ih) 206SOCKS5_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 */
298void 310void
299reciever (void *cls, 311reciever (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 */
338size_t 352size_t
339transmit_ready (void *cls, 353transmit_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)
431struct GNUNET_SOCKS_Handshake * 440struct GNUNET_SOCKS_Handshake *
432GNUNET_SOCKS_init_handshake (const char *user, const char *pass) 441GNUNET_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)
478struct GNUNET_SOCKS_Handshake * 489struct GNUNET_SOCKS_Handshake *
479GNUNET_SOCKS_init_handshake_noauth () 490GNUNET_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 */
493void 504void
494GNUNET_SOCKS_set_handshake_destination (struct GNUNET_SOCKS_Handshake *ih, 505GNUNET_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 */
536struct GNUNET_CONNECTION_Handle * 554struct GNUNET_CONNECTION_Handle *
537GNUNET_SOCKS_run_handshake(struct GNUNET_SOCKS_Handshake *ih, 555GNUNET_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 */