GNUnet  0.10.x
Data Structures | Macros | Functions
socks.c File Reference

SOCKS5 connection support. More...

#include "platform.h"
#include "gnunet_util_lib.h"
Include dependency graph for socks.c:

Go to the source code of this file.

Data Structures

struct  GNUNET_SOCKS_Handshake
 State of the SOCKS5 handshake. More...
 

Macros

#define LOG(kind, ...)   GNUNET_log_from(kind, "util-socks", __VA_ARGS__)
 
#define LOG_STRERROR(kind, syscall)   GNUNET_log_from_strerror(kind, "util-socks", syscall)
 
#define SOCKS5_AUTH_REJECT   0xFF /* No acceptable auth method */
 
#define SOCKS5_AUTH_NOAUTH   0x00 /* without authentication */
 
#define SOCKS5_AUTH_GSSAPI   0x01 /* GSSAPI */
 
#define SOCKS5_AUTH_USERPASS   0x02 /* User/Password */
 
#define SOCKS5_AUTH_CHAP   0x03 /* Challenge-Handshake Auth Proto. */
 
#define SOCKS5_AUTH_EAP   0x05 /* Extensible Authentication Proto. */
 
#define SOCKS5_AUTH_MAF   0x08 /* Multi-Authentication Framework */
 
#define SOCKS5_REP_SUCCEEDED   0x00 /* succeeded */
 
#define SOCKS5_REP_FAIL   0x01 /* general SOCKS serer failure */
 
#define SOCKS5_REP_NALLOWED   0x02 /* connection not allowed by ruleset */
 
#define SOCKS5_REP_NUNREACH   0x03 /* Network unreachable */
 
#define SOCKS5_REP_HUNREACH   0x04 /* Host unreachable */
 
#define SOCKS5_REP_REFUSED   0x05 /* connection refused */
 
#define SOCKS5_REP_EXPIRED   0x06 /* TTL expired */
 
#define SOCKS5_REP_CNOTSUP   0x07 /* Command not supported */
 
#define SOCKS5_REP_ANOTSUP   0x08 /* Address not supported */
 
#define SOCKS5_REP_INVADDR   0x09 /* Inalid address */
 
#define SOCKS5_step_greet   0
 
#define SOCKS5_step_auth   1
 
#define SOCKS5_step_cmd   2
 
#define SOCKS5_step_done   3
 
#define register_reciever_wants(ih)   ((SOCKS5_step_cmd == ih->step) ? 10 : 2)
 

Functions

const char * SOCKS5_REP_names (int rep)
 
unsigned char * SOCK5_proto_string (unsigned char *b, const char *s)
 Encode a string for the SOCKS5 protocol by prefixing it a byte stating its length and stripping the trailing zero byte. More...
 
void register_reciever (struct GNUNET_SOCKS_Handshake *ih, int want)
 Register callback to read from the SOCKS5 proxy. More...
 
struct GNUNET_CONNECTION_TransmitHandleregister_sender (struct GNUNET_SOCKS_Handshake *ih)
 Register SOCKS5 handshake sender. More...
 
void SOCKS5_handshake_done (struct GNUNET_SOCKS_Handshake *ih)
 Conclude the SOCKS5 handshake successfully. More...
 
void SOCKS5_handshake_step (struct GNUNET_SOCKS_Handshake *ih)
 Read one step in the SOCKS5 handshake. More...
 
void reciever (void *cls, const void *buf, size_t available, const struct sockaddr *addr, socklen_t addrlen, int errCode)
 Callback to read from the SOCKS5 proxy. More...
 
size_t transmit_ready (void *cls, size_t size, void *buf)
 Register SOCKS5 handshake sender. More...
 
struct GNUNET_SOCKS_HandshakeGNUNET_SOCKS_init_handshake (const char *user, const char *pass)
 Initialize a SOCKS5 handshake for authentication via username and password. More...
 
struct GNUNET_SOCKS_HandshakeGNUNET_SOCKS_init_handshake_noauth ()
 Initialize a SOCKS5 handshake without authentication, thereby possibly sharing a Tor circuit with another process. More...
 
void GNUNET_SOCKS_set_handshake_destination (struct GNUNET_SOCKS_Handshake *ih, const char *host, uint16_t port)
 Build request that the SOCKS5 proxy open a TCP/IP stream to the given host and port. More...
 
struct GNUNET_CONNECTION_HandleGNUNET_SOCKS_run_handshake (struct GNUNET_SOCKS_Handshake *ih, struct GNUNET_CONNECTION_Handle *c)
 Run a SOCKS5 handshake on an open but unused TCP connection. More...
 
int GNUNET_SOCKS_check_service (const char *service_name, const struct GNUNET_CONFIGURATION_Handle *cfg)
 Check if a SOCKS proxy is required by a service. More...
 
struct GNUNET_CONNECTION_HandleGNUNET_SOCKS_do_connect (const char *service_name, const struct GNUNET_CONFIGURATION_Handle *cfg)
 Try to connect to a service configured to use a SOCKS5 proxy. More...
 

Detailed Description

SOCKS5 connection support.

Author
Jeffrey Burdges

These routines should be called only on newly active connections.

Definition in file socks.c.

Macro Definition Documentation

◆ LOG

#define LOG (   kind,
  ... 
)    GNUNET_log_from(kind, "util-socks", __VA_ARGS__)

◆ LOG_STRERROR

#define LOG_STRERROR (   kind,
  syscall 
)    GNUNET_log_from_strerror(kind, "util-socks", syscall)

Definition at line 34 of file socks.c.

◆ SOCKS5_AUTH_REJECT

#define SOCKS5_AUTH_REJECT   0xFF /* No acceptable auth method */

Definition at line 39 of file socks.c.

Referenced by SOCKS5_handshake_step().

◆ SOCKS5_AUTH_NOAUTH

#define SOCKS5_AUTH_NOAUTH   0x00 /* without authentication */

Definition at line 40 of file socks.c.

Referenced by GNUNET_SOCKS_init_handshake(), and SOCKS5_handshake_step().

◆ SOCKS5_AUTH_GSSAPI

#define SOCKS5_AUTH_GSSAPI   0x01 /* GSSAPI */

Definition at line 41 of file socks.c.

◆ SOCKS5_AUTH_USERPASS

#define SOCKS5_AUTH_USERPASS   0x02 /* User/Password */

Definition at line 42 of file socks.c.

Referenced by GNUNET_SOCKS_init_handshake(), and SOCKS5_handshake_step().

◆ SOCKS5_AUTH_CHAP

#define SOCKS5_AUTH_CHAP   0x03 /* Challenge-Handshake Auth Proto. */

Definition at line 43 of file socks.c.

◆ SOCKS5_AUTH_EAP

#define SOCKS5_AUTH_EAP   0x05 /* Extensible Authentication Proto. */

Definition at line 44 of file socks.c.

◆ SOCKS5_AUTH_MAF

#define SOCKS5_AUTH_MAF   0x08 /* Multi-Authentication Framework */

Definition at line 45 of file socks.c.

◆ SOCKS5_REP_SUCCEEDED

#define SOCKS5_REP_SUCCEEDED   0x00 /* succeeded */

Definition at line 49 of file socks.c.

Referenced by SOCKS5_REP_names().

◆ SOCKS5_REP_FAIL

#define SOCKS5_REP_FAIL   0x01 /* general SOCKS serer failure */

Definition at line 50 of file socks.c.

Referenced by SOCKS5_REP_names().

◆ SOCKS5_REP_NALLOWED

#define SOCKS5_REP_NALLOWED   0x02 /* connection not allowed by ruleset */

Definition at line 51 of file socks.c.

Referenced by SOCKS5_REP_names().

◆ SOCKS5_REP_NUNREACH

#define SOCKS5_REP_NUNREACH   0x03 /* Network unreachable */

Definition at line 52 of file socks.c.

Referenced by SOCKS5_REP_names().

◆ SOCKS5_REP_HUNREACH

#define SOCKS5_REP_HUNREACH   0x04 /* Host unreachable */

Definition at line 53 of file socks.c.

Referenced by SOCKS5_REP_names().

◆ SOCKS5_REP_REFUSED

#define SOCKS5_REP_REFUSED   0x05 /* connection refused */

Definition at line 54 of file socks.c.

Referenced by SOCKS5_REP_names().

◆ SOCKS5_REP_EXPIRED

#define SOCKS5_REP_EXPIRED   0x06 /* TTL expired */

Definition at line 55 of file socks.c.

Referenced by SOCKS5_REP_names().

◆ SOCKS5_REP_CNOTSUP

#define SOCKS5_REP_CNOTSUP   0x07 /* Command not supported */

Definition at line 56 of file socks.c.

Referenced by SOCKS5_REP_names().

◆ SOCKS5_REP_ANOTSUP

#define SOCKS5_REP_ANOTSUP   0x08 /* Address not supported */

Definition at line 57 of file socks.c.

Referenced by SOCKS5_REP_names().

◆ SOCKS5_REP_INVADDR

#define SOCKS5_REP_INVADDR   0x09 /* Inalid address */

Definition at line 58 of file socks.c.

Referenced by SOCKS5_REP_names().

◆ SOCKS5_step_greet

#define SOCKS5_step_greet   0

Definition at line 127 of file socks.c.

Referenced by GNUNET_SOCKS_init_handshake(), and SOCKS5_handshake_step().

◆ SOCKS5_step_auth

#define SOCKS5_step_auth   1

Definition at line 128 of file socks.c.

Referenced by GNUNET_SOCKS_init_handshake(), and SOCKS5_handshake_step().

◆ SOCKS5_step_cmd

#define SOCKS5_step_cmd   2

◆ SOCKS5_step_done

#define SOCKS5_step_done   3

◆ register_reciever_wants

#define register_reciever_wants (   ih)    ((SOCKS5_step_cmd == ih->step) ? 10 : 2)

Definition at line 187 of file socks.c.

Referenced by SOCKS5_handshake_step(), and transmit_ready().

Function Documentation

◆ SOCKS5_REP_names()

const char* SOCKS5_REP_names ( int  rep)

Definition at line 61 of file socks.c.

References SOCKS5_REP_ANOTSUP, SOCKS5_REP_CNOTSUP, SOCKS5_REP_EXPIRED, SOCKS5_REP_FAIL, SOCKS5_REP_HUNREACH, SOCKS5_REP_INVADDR, SOCKS5_REP_NALLOWED, SOCKS5_REP_NUNREACH, SOCKS5_REP_REFUSED, and SOCKS5_REP_SUCCEEDED.

Referenced by SOCKS5_handshake_step().

62 {
63  switch (rep)
64  {
66  return "succeeded";
67 
68  case SOCKS5_REP_FAIL:
69  return "general SOCKS server failure";
70 
72  return "connection not allowed by ruleset";
73 
75  return "Network unreachable";
76 
78  return "Host unreachable";
79 
80  case SOCKS5_REP_REFUSED:
81  return "connection refused";
82 
83  case SOCKS5_REP_EXPIRED:
84  return "TTL expired";
85 
86  case SOCKS5_REP_CNOTSUP:
87  return "Command not supported";
88 
89  case SOCKS5_REP_ANOTSUP:
90  return "Address not supported";
91 
92  case SOCKS5_REP_INVADDR:
93  return "Invalid address";
94 
95  default:
96  return NULL;
97  }
98 };
#define SOCKS5_REP_EXPIRED
Definition: socks.c:55
#define SOCKS5_REP_FAIL
Definition: socks.c:50
#define SOCKS5_REP_NALLOWED
Definition: socks.c:51
#define SOCKS5_REP_REFUSED
Definition: socks.c:54
#define SOCKS5_REP_NUNREACH
Definition: socks.c:52
#define SOCKS5_REP_ANOTSUP
Definition: socks.c:57
#define SOCKS5_REP_SUCCEEDED
Definition: socks.c:49
#define SOCKS5_REP_HUNREACH
Definition: socks.c:53
#define SOCKS5_REP_INVADDR
Definition: socks.c:58
#define SOCKS5_REP_CNOTSUP
Definition: socks.c:56
Here is the caller graph for this function:

◆ SOCK5_proto_string()

unsigned char* SOCK5_proto_string ( unsigned char *  b,
const char *  s 
)

Encode a string for the SOCKS5 protocol by prefixing it a byte stating its length and stripping the trailing zero byte.

Truncates any string longer than 255 bytes.

Parameters
bbuffer to contain the encoded string
sstring to encode
Returns
pointer to the end of the encoded string in the buffer

Definition at line 111 of file socks.c.

References GNUNET_ERROR_TYPE_WARNING, l, and LOG.

Referenced by GNUNET_SOCKS_init_handshake(), and GNUNET_SOCKS_set_handshake_destination().

112 {
113  size_t l = strlen(s);
114 
115  if (l > 255)
116  {
118  "SOCKS5 cannot handle hostnames, usernames, or passwords over 255 bytes, truncating.\n");
119  l = 255;
120  }
121  *(b++) = (unsigned char)l;
122  memcpy(b, s, l);
123  return b + l;
124 }
static struct LoggingHandle * l
#define LOG(kind,...)
Definition: socks.c:32
Here is the caller graph for this function:

◆ register_reciever()

void register_reciever ( struct GNUNET_SOCKS_Handshake ih,
int  want 
)

Register callback to read from the SOCKS5 proxy.

Parameters
clientthe service
handlerfunction to call with the message
handler_clsclosure for handler

Definition at line 352 of file socks.c.

References GNUNET_CONNECTION_receive(), GNUNET_TIME_relative_get_minute_(), reciever(), and GNUNET_SOCKS_Handshake::socks5_connection.

Referenced by SOCKS5_handshake_step(), and transmit_ready().

353 {
355  want,
357  &reciever,
358  ih);
359 }
struct GNUNET_TIME_Relative GNUNET_TIME_relative_get_minute_(void)
Return relative time of 1 minute.
Definition: time.c:195
int GNUNET_CONNECTION_receive(struct GNUNET_CONNECTION_Handle *connection, size_t max, struct GNUNET_TIME_Relative timeout, GNUNET_CONNECTION_Receiver receiver, void *receiver_cls)
Receive data from the given connection.
struct GNUNET_CONNECTION_Handle * socks5_connection
Connection handle used for SOCKS5.
Definition: socks.c:139
void reciever(void *cls, const void *buf, size_t available, const struct sockaddr *addr, socklen_t addrlen, int errCode)
Callback to read from the SOCKS5 proxy.
Definition: socks.c:328
Here is the call graph for this function:
Here is the caller graph for this function:

◆ register_sender()

struct GNUNET_CONNECTION_TransmitHandle * register_sender ( struct GNUNET_SOCKS_Handshake ih)

Register SOCKS5 handshake sender.

Parameters
ihhandshake
Returns
non-NULL if the notify callback was queued, NULL if we are already going to notify someone else (busy)

Definition at line 429 of file socks.c.

References e, GNUNET_assert, GNUNET_CONNECTION_notify_transmit_ready(), GNUNET_TIME_relative_multiply(), GNUNET_TIME_UNIT_MINUTES, GNUNET_SOCKS_Handshake::outbuf, GNUNET_SOCKS_Handshake::outstep, GNUNET_SOCKS_Handshake::socks5_connection, SOCKS5_step_done, GNUNET_SOCKS_Handshake::step, GNUNET_SOCKS_Handshake::th, and transmit_ready().

Referenced by GNUNET_SOCKS_run_handshake(), SOCKS5_handshake_step(), and transmit_ready().

430 {
432 
434  GNUNET_assert(ih->step >= 0);
435  if (0 == ih->step)
437  unsigned char *b = ih->outstep[ih->step];
438  unsigned char *e = ih->outstep[ih->step + 1];
439  GNUNET_assert(ih->outbuf <= b && b < e && e < &ih->outbuf[1024]);
441  e - b,
442  timeout,
444  ih);
445  return ih->th;
446 }
unsigned char outbuf[1024]
Precomputed SOCKS5 handshake ouput buffer.
Definition: socks.c:159
#define GNUNET_TIME_UNIT_MINUTES
One minute.
#define SOCKS5_step_done
Definition: socks.c:130
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static struct Experiment * e
static struct GNUNET_TIME_Relative timeout
User defined timestamp for completing operations.
Definition: gnunet-arm.c:114
struct GNUNET_TIME_Relative GNUNET_TIME_relative_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Multiply relative time by a given factor.
Definition: time.c:440
int step
Our stage in the SOCKS5 handshake.
Definition: socks.c:154
unsigned char * outstep[4]
Pointers delineating protoocol steps in the outbut buffer.
Definition: socks.c:164
struct GNUNET_CONNECTION_TransmitHandle * th
Transmission handle on socks5_connection.
Definition: socks.c:149
size_t transmit_ready(void *cls, size_t size, void *buf)
Register SOCKS5 handshake sender.
Definition: socks.c:371
struct GNUNET_CONNECTION_TransmitHandle * GNUNET_CONNECTION_notify_transmit_ready(struct GNUNET_CONNECTION_Handle *connection, size_t size, struct GNUNET_TIME_Relative timeout, GNUNET_CONNECTION_TransmitReadyNotify notify, void *notify_cls)
Ask the connection to call us once the specified number of bytes are free in the transmission buffer...
struct GNUNET_CONNECTION_Handle * socks5_connection
Connection handle used for SOCKS5.
Definition: socks.c:139
Time for relative time used by GNUnet, in microseconds.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ SOCKS5_handshake_done()

void SOCKS5_handshake_done ( struct GNUNET_SOCKS_Handshake ih)

Conclude the SOCKS5 handshake successfully.

Parameters
ihSOCKS5 handshake, consumed here.
copen unused connection, consumed here.
Returns
Connection handle that becomes usable when the handshake completes.

Definition at line 202 of file socks.c.

References GNUNET_CONNECTION_acivate_proxied(), and GNUNET_SOCKS_Handshake::target_connection.

Referenced by SOCKS5_handshake_step().

203 {
205 }
void GNUNET_CONNECTION_acivate_proxied(struct GNUNET_CONNECTION_Handle *proxied)
Activate proxied connection and destroy initial proxy handshake connection.
struct GNUNET_CONNECTION_Handle * target_connection
Connection handle initially returned to client.
Definition: socks.c:144
Here is the call graph for this function:
Here is the caller graph for this function:

◆ SOCKS5_handshake_step()

void SOCKS5_handshake_step ( struct GNUNET_SOCKS_Handshake ih)

Read one step in the SOCKS5 handshake.

Parameters
ihSOCKS5 Handshake

Definition at line 214 of file socks.c.

References GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_SOCKS_Handshake::inend, GNUNET_SOCKS_Handshake::instart, LOG, register_reciever(), register_reciever_wants, register_sender(), SOCKS5_AUTH_NOAUTH, SOCKS5_AUTH_REJECT, SOCKS5_AUTH_USERPASS, SOCKS5_handshake_done(), SOCKS5_REP_names(), SOCKS5_step_auth, SOCKS5_step_cmd, SOCKS5_step_done, SOCKS5_step_greet, and GNUNET_SOCKS_Handshake::step.

Referenced by reciever().

215 {
216  unsigned char *b = ih->instart;
217  size_t available = ih->inend - b;
218 
219  int want = register_reciever_wants(ih);
220 
221  if (available < want)
222  {
223  register_reciever(ih, want - available);
224  return;
225  }
226  GNUNET_assert(SOCKS5_step_done > ih->step && ih->step >= 0);
227  switch (ih->step)
228  {
229  case SOCKS5_step_greet: /* SOCKS5 server's greeting */
230  if (b[0] != 5)
231  {
232  LOG(GNUNET_ERROR_TYPE_ERROR, "Not a SOCKS5 server\n");
233  GNUNET_assert(0);
234  }
235  switch (b[1])
236  {
237  case SOCKS5_AUTH_NOAUTH:
238  ih->step = SOCKS5_step_cmd; /* no authentication to do */
239  break;
240 
242  ih->step = SOCKS5_step_auth;
243  break;
244 
245  case SOCKS5_AUTH_REJECT:
246  LOG(GNUNET_ERROR_TYPE_ERROR, "No authentication method accepted\n");
247  return;
248 
249  default:
251  "Not a SOCKS5 server / Nonsensical authentication\n");
252  return;
253  }
254  b += 2;
255  break;
256 
257  case SOCKS5_step_auth: /* SOCKS5 server's responce to authentication */
258  if (b[1] != 0)
259  {
260  LOG(GNUNET_ERROR_TYPE_ERROR, "SOCKS5 authentication failed\n");
261  GNUNET_assert(0);
262  }
263  ih->step = SOCKS5_step_cmd;
264  b += 2;
265  break;
266 
267  case SOCKS5_step_cmd: /* SOCKS5 server's responce to command */
268  if (b[0] != 5)
269  {
270  LOG(GNUNET_ERROR_TYPE_ERROR, "SOCKS5 protocol error\n");
271  GNUNET_assert(0);
272  }
273  if (0 != b[1])
274  {
276  "SOCKS5 connection error : %s\n",
277  SOCKS5_REP_names(b[1]));
278  return;
279  }
280  b += 3;
281  /* There is no reason to verify host and port afaik. */
282  switch (*(b++))
283  {
284  case 1: /* IPv4 */
285  b += sizeof(struct in_addr); /* 4 */
286  break;
287 
288  case 4: /* IPv6 */
289  b += sizeof(struct in6_addr); /* 16 */
290  break;
291 
292  case 3: /* hostname */
293  b += *b;
294  break;
295  }
296  b += 2; /* port */
297  if (b > ih->inend)
298  {
299  register_reciever(ih, b - ih->inend);
300  return;
301  }
302  ih->step = SOCKS5_step_done;
304  "SOCKS5 server : %s\n",
305  SOCKS5_REP_names(b[1]));
306  ih->instart = b;
308  return;
309 
310  case SOCKS5_step_done:
311  GNUNET_assert(0);
312  }
313  ih->instart = b;
314  /* Do not reschedule the sender unless we're done reading.
315  * I imagine this lets us avoid ever cancelling the transmit handle. */
316  register_sender(ih);
317 }
#define SOCKS5_AUTH_NOAUTH
Definition: socks.c:40
#define SOCKS5_step_done
Definition: socks.c:130
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
unsigned char * inend
Definition: socks.c:175
#define SOCKS5_AUTH_USERPASS
Definition: socks.c:42
#define SOCKS5_step_cmd
Definition: socks.c:129
#define register_reciever_wants(ih)
Definition: socks.c:187
#define SOCKS5_step_greet
Definition: socks.c:127
struct GNUNET_CONNECTION_TransmitHandle * register_sender(struct GNUNET_SOCKS_Handshake *ih)
Register SOCKS5 handshake sender.
Definition: socks.c:429
void SOCKS5_handshake_done(struct GNUNET_SOCKS_Handshake *ih)
Conclude the SOCKS5 handshake successfully.
Definition: socks.c:202
int step
Our stage in the SOCKS5 handshake.
Definition: socks.c:154
void register_reciever(struct GNUNET_SOCKS_Handshake *ih, int want)
Register callback to read from the SOCKS5 proxy.
Definition: socks.c:352
#define LOG(kind,...)
Definition: socks.c:32
const char * SOCKS5_REP_names(int rep)
Definition: socks.c:61
#define SOCKS5_AUTH_REJECT
Definition: socks.c:39
unsigned char * instart
Pointers delimiting the current step in the input buffer.
Definition: socks.c:174
#define SOCKS5_step_auth
Definition: socks.c:128
Here is the call graph for this function:
Here is the caller graph for this function:

◆ reciever()

void reciever ( void *  cls,
const void *  buf,
size_t  available,
const struct sockaddr *  addr,
socklen_t  addrlen,
int  errCode 
)

Callback to read from the SOCKS5 proxy.

Parameters
clientthe service
handlerfunction to call with the message
handler_clsclosure for handler

Definition at line 328 of file socks.c.

References GNUNET_assert, GNUNET_memcpy, GNUNET_SOCKS_Handshake::inbuf, GNUNET_SOCKS_Handshake::inend, and SOCKS5_handshake_step().

Referenced by register_reciever().

334 {
335  struct GNUNET_SOCKS_Handshake *ih = cls;
336 
337  GNUNET_assert(&ih->inend[available] < &ih->inbuf[1024]);
338  GNUNET_memcpy(ih->inend, buf, available);
339  ih->inend += available;
341 }
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
unsigned char * inend
Definition: socks.c:175
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
static char buf[2048]
void SOCKS5_handshake_step(struct GNUNET_SOCKS_Handshake *ih)
Read one step in the SOCKS5 handshake.
Definition: socks.c:214
unsigned char inbuf[1024]
SOCKS5 handshake input buffer.
Definition: socks.c:169
State of the SOCKS5 handshake.
Definition: socks.c:135
Here is the call graph for this function:
Here is the caller graph for this function:

◆ transmit_ready()

size_t transmit_ready ( void *  cls,
size_t  size,
void *  buf 
)

Register SOCKS5 handshake sender.

Parameters
clsclosure (SOCKS handshake)
sizenumber of bytes available in buf
bufwhere the callee should write the message
Returns
number of bytes written to buf

Definition at line 371 of file socks.c.

References e, GNUNET_assert, GNUNET_break, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_WARNING, GNUNET_memcpy, l, LOG, GNUNET_SOCKS_Handshake::outbuf, GNUNET_SOCKS_Handshake::outstep, register_reciever(), register_reciever_wants, register_sender(), SOCKS5_step_done, and GNUNET_SOCKS_Handshake::step.

Referenced by register_sender().

372 {
373  struct GNUNET_SOCKS_Handshake *ih = cls;
374 
375  /* connection.c has many routines that call us with buf == NULL :
376  * signal_transmit_error() - DNS, etc. active
377  * connect_fail_continuation()
378  * connect_probe_continuation() - timeout
379  * try_connect_using_address() - DNS failure/timeout
380  * transmit_timeout() - retry failed?
381  * GNUNET_CONNECTION_notify_transmit_ready() can schedule :
382  * transmit_timeout() - DNS still working
383  * connect_error() - DNS done but no socket?
384  * transmit_ready() - scheduler shutdown or timeout, or signal_transmit_error()
385  * We'd need to dig into the scheduler to guess at the reason, as
386  * connection.c tells us nothing itself, but mostly its timouts.
387  * Initially, we'll simply ignore this and leave massive timeouts, but
388  * maybe that should change for error handling pruposes. It appears that
389  * successful operations, including DNS resolution, do not use this. */
390  if (NULL == buf)
391  {
392  if (0 == ih->step)
393  {
395  "Timeout contacting SOCKS server, retrying indefinitely, but probably hopeless.\n");
396  register_sender(ih);
397  }
398  else
399  {
401  "Timeout during mid SOCKS handshake (step %u), probably not a SOCKS server.\n",
402  ih->step);
403  GNUNET_break(0);
404  }
405  return 0;
406  }
407 
408  GNUNET_assert((1024 >= size) && (size > 0));
409  GNUNET_assert((SOCKS5_step_done > ih->step) && (ih->step >= 0));
410  unsigned char *b = ih->outstep[ih->step];
411  unsigned char *e = ih->outstep[ih->step + 1];
412  GNUNET_assert(e <= &ih->outbuf[1024]);
413  unsigned int l = e - b;
414  GNUNET_assert(size >= l);
415  GNUNET_memcpy(buf, b, l);
417  return l;
418 }
unsigned char outbuf[1024]
Precomputed SOCKS5 handshake ouput buffer.
Definition: socks.c:159
#define SOCKS5_step_done
Definition: socks.c:130
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
static struct Experiment * e
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static struct LoggingHandle * l
#define register_reciever_wants(ih)
Definition: socks.c:187
struct GNUNET_CONNECTION_TransmitHandle * register_sender(struct GNUNET_SOCKS_Handshake *ih)
Register SOCKS5 handshake sender.
Definition: socks.c:429
static char buf[2048]
int step
Our stage in the SOCKS5 handshake.
Definition: socks.c:154
static unsigned int size
Size of the "table".
Definition: peer.c:66
unsigned char * outstep[4]
Pointers delineating protoocol steps in the outbut buffer.
Definition: socks.c:164
void register_reciever(struct GNUNET_SOCKS_Handshake *ih, int want)
Register callback to read from the SOCKS5 proxy.
Definition: socks.c:352
#define LOG(kind,...)
Definition: socks.c:32
State of the SOCKS5 handshake.
Definition: socks.c:135
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_SOCKS_init_handshake()

struct GNUNET_SOCKS_Handshake* GNUNET_SOCKS_init_handshake ( const char *  user,
const char *  pass 
)

Initialize a SOCKS5 handshake for authentication via username and password.

Tor uses SOCKS username and password authentication to assign programs unique circuits.

Parameters
userusername for the proxy
passpassword for the proxy
Returns
Valid SOCKS5 hanbdshake handle

Definition at line 459 of file socks.c.

References GNUNET_new, GNUNET_SOCKS_Handshake::inbuf, GNUNET_SOCKS_Handshake::inend, GNUNET_SOCKS_Handshake::instart, GNUNET_SOCKS_Handshake::outbuf, GNUNET_SOCKS_Handshake::outstep, SOCK5_proto_string(), SOCKS5_AUTH_NOAUTH, SOCKS5_AUTH_USERPASS, SOCKS5_step_auth, SOCKS5_step_cmd, and SOCKS5_step_greet.

Referenced by GNUNET_SOCKS_do_connect(), and GNUNET_SOCKS_init_handshake_noauth().

460 {
461  struct GNUNET_SOCKS_Handshake *ih =
463  unsigned char *b = ih->outbuf;
464 
465  ih->outstep[SOCKS5_step_greet] = b;
466  *(b++) = 5; /* SOCKS5 */
467  unsigned char *n = b++;
468  *n = 1; /* Number of authentication methods */
469  /* We support no authentication even when requesting authentication,
470  * but this appears harmless, given the way that Tor uses authentication.
471  * And some SOCKS5 servers might require this. */
472  *(b++) = SOCKS5_AUTH_NOAUTH;
473  if (NULL != user)
474  {
475  *(b++) = SOCKS5_AUTH_USERPASS;
476  (*n)++;
477  }
478  /* There is no apperent reason to support authentication methods beyond
479  * username and password since afaik Tor does not support them. */
480 
481  /* We authenticate with an empty username and password if the server demands
482  * them but we do not have any. */
483  if (user == NULL)
484  user = "";
485  if (pass == NULL)
486  pass = "";
487 
488  ih->outstep[SOCKS5_step_auth] = b;
489  *(b++) = 1; /* subnegotiation ver.: 1 */
490  b = SOCK5_proto_string(b, user);
491  b = SOCK5_proto_string(b, pass);
492 
493  ih->outstep[SOCKS5_step_cmd] = b;
494 
495  ih->inend = ih->instart = ih->inbuf;
496 
497  return ih;
498 }
#define SOCKS5_AUTH_NOAUTH
Definition: socks.c:40
unsigned char outbuf[1024]
Precomputed SOCKS5 handshake ouput buffer.
Definition: socks.c:159
unsigned char * inend
Definition: socks.c:175
#define SOCKS5_AUTH_USERPASS
Definition: socks.c:42
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define SOCKS5_step_cmd
Definition: socks.c:129
#define SOCKS5_step_greet
Definition: socks.c:127
unsigned char * outstep[4]
Pointers delineating protoocol steps in the outbut buffer.
Definition: socks.c:164
unsigned char * SOCK5_proto_string(unsigned char *b, const char *s)
Encode a string for the SOCKS5 protocol by prefixing it a byte stating its length and stripping the t...
Definition: socks.c:111
unsigned char inbuf[1024]
SOCKS5 handshake input buffer.
Definition: socks.c:169
unsigned char * instart
Pointers delimiting the current step in the input buffer.
Definition: socks.c:174
State of the SOCKS5 handshake.
Definition: socks.c:135
#define SOCKS5_step_auth
Definition: socks.c:128
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_SOCKS_init_handshake_noauth()

struct GNUNET_SOCKS_Handshake* GNUNET_SOCKS_init_handshake_noauth ( )

Initialize a SOCKS5 handshake without authentication, thereby possibly sharing a Tor circuit with another process.

Returns
Valid SOCKS5 hanbdshake handle

Definition at line 508 of file socks.c.

References GNUNET_SOCKS_init_handshake().

509 {
510  return GNUNET_SOCKS_init_handshake(NULL, NULL);
511 }
struct GNUNET_SOCKS_Handshake * GNUNET_SOCKS_init_handshake(const char *user, const char *pass)
Initialize a SOCKS5 handshake for authentication via username and password.
Definition: socks.c:459
Here is the call graph for this function:

◆ GNUNET_SOCKS_set_handshake_destination()

void GNUNET_SOCKS_set_handshake_destination ( struct GNUNET_SOCKS_Handshake ih,
const char *  host,
uint16_t  port 
)

Build request that the SOCKS5 proxy open a TCP/IP stream to the given host and port.

Parameters
ihSOCKS5 handshake
hostname
port

Definition at line 523 of file socks.c.

References GNUNET_memcpy, GNUNET_SOCKS_Handshake::outstep, SOCK5_proto_string(), SOCKS5_step_cmd, and SOCKS5_step_done.

Referenced by GNUNET_SOCKS_do_connect().

526 {
527  union {
528  struct in_addr in4;
529  struct in6_addr in6;
530  } ia;
531  unsigned char *b = ih->outstep[SOCKS5_step_cmd];
532 
533  *(b++) = 5; /* SOCKS5 */
534  *(b++) = 1; /* Establish a TCP/IP stream */
535  *(b++) = 0; /* reserved */
536 
537  /* Specify destination */
538  if (1 == inet_pton(AF_INET, host, &ia.in4))
539  {
540  *(b++) = 1; /* IPv4 */
541  GNUNET_memcpy(b, &ia.in4, sizeof(struct in_addr));
542  b += sizeof(struct in_addr); /* 4 */
543  }
544  else if (1 == inet_pton(AF_INET6, host, &ia.in6))
545  {
546  *(b++) = 4; /* IPv6 */
547  GNUNET_memcpy(b, &ia.in6, sizeof(struct in6_addr));
548  b += sizeof(struct in6_addr); /* 16 */
549  }
550  else
551  {
552  *(b++) = 3; /* hostname */
553  b = SOCK5_proto_string(b, host);
554  }
555 
556  /* Specify port */
557  *(uint16_t *)b = htons(port);
558  b += 2;
559 
560  ih->outstep[SOCKS5_step_done] = b;
561 }
#define SOCKS5_step_done
Definition: socks.c:130
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define SOCKS5_step_cmd
Definition: socks.c:129
unsigned char * outstep[4]
Pointers delineating protoocol steps in the outbut buffer.
Definition: socks.c:164
unsigned char * SOCK5_proto_string(unsigned char *b, const char *s)
Encode a string for the SOCKS5 protocol by prefixing it a byte stating its length and stripping the t...
Definition: socks.c:111
static uint16_t port
Port number.
Definition: gnunet-bcd.c:81
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_SOCKS_run_handshake()

struct GNUNET_CONNECTION_Handle* GNUNET_SOCKS_run_handshake ( struct GNUNET_SOCKS_Handshake ih,
struct GNUNET_CONNECTION_Handle c 
)

Run a SOCKS5 handshake on an open but unused TCP connection.

Parameters
ihSOCKS5 handshake, consumed here.
copen unused connection, consumed here.
Returns
Connection handle that becomes usable when the SOCKS5 handshake completes.

Definition at line 572 of file socks.c.

References GNUNET_CONNECTION_create_proxied_from_handshake(), register_sender(), GNUNET_SOCKS_Handshake::socks5_connection, and GNUNET_SOCKS_Handshake::target_connection.

Referenced by GNUNET_SOCKS_do_connect().

574 {
575  ih->socks5_connection = c;
577  register_sender(ih);
578 
579  return ih->target_connection;
580 }
struct GNUNET_CONNECTION_TransmitHandle * register_sender(struct GNUNET_SOCKS_Handshake *ih)
Register SOCKS5 handshake sender.
Definition: socks.c:429
struct GNUNET_CONNECTION_Handle * target_connection
Connection handle initially returned to client.
Definition: socks.c:144
struct GNUNET_CONNECTION_Handle * GNUNET_CONNECTION_create_proxied_from_handshake(struct GNUNET_CONNECTION_Handle *cph)
Create a connection to be proxied using a given connection.
struct GNUNET_CONNECTION_Handle * socks5_connection
Connection handle used for SOCKS5.
Definition: socks.c:139
Here is the call graph for this function:
Here is the caller graph for this function: