GNUnet  0.20.0
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 /* Invalid 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 receiver (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__)

Definition at line 33 of file socks.c.

◆ LOG_STRERROR

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

Definition at line 35 of file socks.c.

◆ SOCKS5_AUTH_REJECT

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

Definition at line 40 of file socks.c.

◆ SOCKS5_AUTH_NOAUTH

#define SOCKS5_AUTH_NOAUTH   0x00 /* without authentication */

Definition at line 41 of file socks.c.

◆ SOCKS5_AUTH_GSSAPI

#define SOCKS5_AUTH_GSSAPI   0x01 /* GSSAPI */

Definition at line 42 of file socks.c.

◆ SOCKS5_AUTH_USERPASS

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

Definition at line 43 of file socks.c.

◆ SOCKS5_AUTH_CHAP

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

Definition at line 44 of file socks.c.

◆ SOCKS5_AUTH_EAP

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

Definition at line 45 of file socks.c.

◆ SOCKS5_AUTH_MAF

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

Definition at line 46 of file socks.c.

◆ SOCKS5_REP_SUCCEEDED

#define SOCKS5_REP_SUCCEEDED   0x00 /* succeeded */

Definition at line 50 of file socks.c.

◆ SOCKS5_REP_FAIL

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

Definition at line 51 of file socks.c.

◆ SOCKS5_REP_NALLOWED

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

Definition at line 52 of file socks.c.

◆ SOCKS5_REP_NUNREACH

#define SOCKS5_REP_NUNREACH   0x03 /* Network unreachable */

Definition at line 53 of file socks.c.

◆ SOCKS5_REP_HUNREACH

#define SOCKS5_REP_HUNREACH   0x04 /* Host unreachable */

Definition at line 54 of file socks.c.

◆ SOCKS5_REP_REFUSED

#define SOCKS5_REP_REFUSED   0x05 /* connection refused */

Definition at line 55 of file socks.c.

◆ SOCKS5_REP_EXPIRED

#define SOCKS5_REP_EXPIRED   0x06 /* TTL expired */

Definition at line 56 of file socks.c.

◆ SOCKS5_REP_CNOTSUP

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

Definition at line 57 of file socks.c.

◆ SOCKS5_REP_ANOTSUP

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

Definition at line 58 of file socks.c.

◆ SOCKS5_REP_INVADDR

#define SOCKS5_REP_INVADDR   0x09 /* Invalid address */

Definition at line 59 of file socks.c.

◆ SOCKS5_step_greet

#define SOCKS5_step_greet   0

Definition at line 128 of file socks.c.

◆ SOCKS5_step_auth

#define SOCKS5_step_auth   1

Definition at line 129 of file socks.c.

◆ SOCKS5_step_cmd

#define SOCKS5_step_cmd   2

Definition at line 130 of file socks.c.

◆ SOCKS5_step_done

#define SOCKS5_step_done   3

Definition at line 131 of file socks.c.

◆ register_reciever_wants

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

Definition at line 189 of file socks.c.

Function Documentation

◆ SOCKS5_REP_names()

const char* SOCKS5_REP_names ( int  rep)

Definition at line 62 of file socks.c.

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

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().

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 112 of file socks.c.

113 {
114  size_t l = strlen (s);
115 
116  if (l > 255)
117  {
119  "SOCKS5 cannot handle hostnames, usernames, or passwords over 255 bytes, truncating.\n");
120  l = 255;
121  }
122  *(b++) = (unsigned char) l;
123  memcpy (b, s, l);
124  return b + l;
125 }
static struct LoggingHandle * l
@ GNUNET_ERROR_TYPE_WARNING
#define LOG(kind,...)
Definition: socks.c:33

References GNUNET_ERROR_TYPE_WARNING, l, and LOG.

Referenced by GNUNET_SOCKS_init_handshake(), and GNUNET_SOCKS_set_handshake_destination().

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 354 of file socks.c.

355 {
357  want,
359  &receiver,
360  ih);
361 }
struct GNUNET_TIME_Relative GNUNET_TIME_relative_get_minute_(void)
Return relative time of 1 minute.
Definition: time.c:178
void receiver(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:330
struct GNUNET_CONNECTION_Handle * socks5_connection
Connection handle used for SOCKS5.
Definition: socks.c:141
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.

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

Referenced by SOCKS5_handshake_step(), and transmit_ready().

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 430 of file socks.c.

431 {
433 
435  GNUNET_assert (ih->step >= 0);
436  if (0 == ih->step)
438  unsigned char *b = ih->outstep[ih->step];
439  unsigned char *e = ih->outstep[ih->step + 1];
440  GNUNET_assert (ih->outbuf <= b && b < e && e < &ih->outbuf[1024]);
442  e - b,
443  timeout,
445  ih);
446  return ih->th;
447 }
static struct GNUNET_TIME_Relative timeout
Desired timeout for the lookup (default is no timeout).
Definition: gnunet-abd.c:61
static struct Experiment * e
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_TIME_UNIT_MINUTES
One minute.
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:484
size_t transmit_ready(void *cls, size_t size, void *buf)
Register SOCKS5 handshake sender.
Definition: socks.c:373
#define SOCKS5_step_done
Definition: socks.c:131
struct GNUNET_CONNECTION_TransmitHandle * th
Transmission handle on socks5_connection.
Definition: socks.c:151
unsigned char outbuf[1024]
Precomputed SOCKS5 handshake output buffer.
Definition: socks.c:161
unsigned char * outstep[4]
Pointers delineating protoocol steps in the output buffer.
Definition: socks.c:166
int step
Our stage in the SOCKS5 handshake.
Definition: socks.c:156
Time for relative time used by GNUnet, in microseconds.
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.

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, timeout, and transmit_ready().

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

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 204 of file socks.c.

205 {
207 }
struct GNUNET_CONNECTION_Handle * target_connection
Connection handle initially returned to client.
Definition: socks.c:146
void GNUNET_CONNECTION_acivate_proxied(struct GNUNET_CONNECTION_Handle *proxied)
Activate proxied connection and destroy initial proxy handshake connection.

References GNUNET_CONNECTION_acivate_proxied(), and GNUNET_SOCKS_Handshake::target_connection.

Referenced by SOCKS5_handshake_step().

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 216 of file socks.c.

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

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 receiver().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ receiver()

void receiver ( 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 330 of file socks.c.

336 {
337  struct GNUNET_SOCKS_Handshake *ih = cls;
338 
339  GNUNET_assert (&ih->inend[available] < &ih->inbuf[1024]);
340  GNUNET_memcpy (ih->inend, buf, available);
341  ih->inend += available;
343 }
static char buf[2048]
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
void SOCKS5_handshake_step(struct GNUNET_SOCKS_Handshake *ih)
Read one step in the SOCKS5 handshake.
Definition: socks.c:216
State of the SOCKS5 handshake.
Definition: socks.c:137
unsigned char inbuf[1024]
SOCKS5 handshake input buffer.
Definition: socks.c:171

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

Referenced by add_acks(), check_timeouts(), create_rekey(), derive_aes_key(), GCCH_handle_local_data(), get_receiver_delete_it(), GNUNET_CONNECTION_receive(), GNUNET_TRANSPORT_TESTING_send(), handle_ack(), mq_destroy_d(), mq_destroy_kx(), mq_error(), mq_init(), mq_send_d(), mq_send_kx(), receive_ready(), receiver_destroy(), register_reciever(), reschedule_receiver_timeout(), secret_destroy(), send_ack(), send_msg_with_kx(), setup_receiver_mq(), setup_shared_secret_ephemeral(), signal_receive_error(), signal_receive_timeout(), and transmit_send_continuation().

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 373 of file socks.c.

374 {
375  struct GNUNET_SOCKS_Handshake *ih = cls;
376 
377  /* connection.c has many routines that call us with buf == NULL :
378  * signal_transmit_error() - DNS, etc. active
379  * connect_fail_continuation()
380  * connect_probe_continuation() - timeout
381  * try_connect_using_address() - DNS failure/timeout
382  * transmit_timeout() - retry failed?
383  * GNUNET_CONNECTION_notify_transmit_ready() can schedule :
384  * transmit_timeout() - DNS still working
385  * connect_error() - DNS done but no socket?
386  * transmit_ready() - scheduler shutdown or timeout, or signal_transmit_error()
387  * We'd need to dig into the scheduler to guess at the reason, as
388  * connection.c tells us nothing itself, but mostly its timouts.
389  * Initially, we'll simply ignore this and leave massive timeouts, but
390  * maybe that should change for error handling pruposes. It appears that
391  * successful operations, including DNS resolution, do not use this. */if (NULL == buf)
392  {
393  if (0 == ih->step)
394  {
396  "Timeout contacting SOCKS server, retrying indefinitely, but probably hopeless.\n");
397  register_sender (ih);
398  }
399  else
400  {
402  "Timeout during mid SOCKS handshake (step %u), probably not a SOCKS server.\n",
403  ih->step);
404  GNUNET_break (0);
405  }
406  return 0;
407  }
408 
409  GNUNET_assert ((1024 >= size) && (size > 0));
410  GNUNET_assert ((SOCKS5_step_done > ih->step) && (ih->step >= 0));
411  unsigned char *b = ih->outstep[ih->step];
412  unsigned char *e = ih->outstep[ih->step + 1];
413  GNUNET_assert (e <= &ih->outbuf[1024]);
414  unsigned int l = e - b;
415  GNUNET_assert (size >= l);
416  GNUNET_memcpy (buf, b, l);
418  return l;
419 }
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
static unsigned int size
Size of the "table".
Definition: peer.c:68

References buf, 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(), size, SOCKS5_step_done, and GNUNET_SOCKS_Handshake::step.

Referenced by register_sender().

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 460 of file socks.c.

461 {
462  struct GNUNET_SOCKS_Handshake *ih =
464  unsigned char *b = ih->outbuf;
465 
466  ih->outstep[SOCKS5_step_greet] = b;
467  *(b++) = 5; /* SOCKS5 */
468  unsigned char *n = b++;
469  *n = 1; /* Number of authentication methods */
470  /* We support no authentication even when requesting authentication,
471  * but this appears harmless, given the way that Tor uses authentication.
472  * And some SOCKS5 servers might require this. */
473  *(b++) = SOCKS5_AUTH_NOAUTH;
474  if (NULL != user)
475  {
476  *(b++) = SOCKS5_AUTH_USERPASS;
477  (*n)++;
478  }
479  /* There is no apparent reason to support authentication methods beyond
480  * username and password since afaik Tor does not support them. */
481 
482  /* We authenticate with an empty username and password if the server demands
483  * them but we do not have any. */
484  if (user == NULL)
485  user = "";
486  if (pass == NULL)
487  pass = "";
488 
489  ih->outstep[SOCKS5_step_auth] = b;
490  *(b++) = 1; /* subnegotiation ver.: 1 */
491  b = SOCK5_proto_string (b, user);
492  b = SOCK5_proto_string (b, pass);
493 
494  ih->outstep[SOCKS5_step_cmd] = b;
495 
496  ih->inend = ih->instart = ih->inbuf;
497 
498  return ih;
499 }
#define GNUNET_new(type)
Allocate a struct or union of the given type.
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:112

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().

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 509 of file socks.c.

510 {
511  return GNUNET_SOCKS_init_handshake (NULL, NULL);
512 }
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:460

References GNUNET_SOCKS_init_handshake().

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
host
port

Definition at line 524 of file socks.c.

527 {
528  union
529  {
530  struct in_addr in4;
531  struct in6_addr in6;
532  } ia;
533  unsigned char *b = ih->outstep[SOCKS5_step_cmd];
534 
535  *(b++) = 5; /* SOCKS5 */
536  *(b++) = 1; /* Establish a TCP/IP stream */
537  *(b++) = 0; /* reserved */
538 
539  /* Specify destination */
540  if (1 == inet_pton (AF_INET, host, &ia.in4))
541  {
542  *(b++) = 1; /* IPv4 */
543  GNUNET_memcpy (b, &ia.in4, sizeof(struct in_addr));
544  b += sizeof(struct in_addr); /* 4 */
545  }
546  else if (1 == inet_pton (AF_INET6, host, &ia.in6))
547  {
548  *(b++) = 4; /* IPv6 */
549  GNUNET_memcpy (b, &ia.in6, sizeof(struct in6_addr));
550  b += sizeof(struct in6_addr); /* 16 */
551  }
552  else
553  {
554  *(b++) = 3; /* hostname */
555  b = SOCK5_proto_string (b, host);
556  }
557 
558  /* Specify port */
559  *(uint16_t *) b = htons (port);
560  b += 2;
561 
562  ih->outstep[SOCKS5_step_done] = b;
563 }
static uint16_t port
Port number.
Definition: gnunet-bcd.c:147

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

Referenced by GNUNET_SOCKS_do_connect().

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 574 of file socks.c.

576 {
577  ih->socks5_connection = c;
579  register_sender (ih);
580 
581  return ih->target_connection;
582 }
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.

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().

Here is the call graph for this function:
Here is the caller graph for this function: