summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2019-06-27 12:14:19 +0200
committerChristian Grothoff <christian@grothoff.org>2019-06-27 12:14:19 +0200
commit4c2a06deba76e8be4098059b860e76db3cf4ae7e (patch)
tree210bf40156160189926fa3efa10f87d7928433f7
parent62fccf2d984f8e0d537fe919d095f3776bd3369c (diff)
memcpy fits better
-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 @@
#include "gnunet_util_lib.h"
-#define LOG(kind,...) GNUNET_log_from (kind, "util-socks", __VA_ARGS__)
+#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 LOG_STRERROR(kind, syscall) \
+ GNUNET_log_from_strerror (kind, "util-socks", syscall)
/* SOCKS5 authentication methods */
@@ -56,20 +57,33 @@
#define SOCKS5_REP_ANOTSUP 0x08 /* Address not supported */
#define SOCKS5_REP_INVADDR 0x09 /* Inalid address */
-const char * SOCKS5_REP_names(int rep)
+const char *
+SOCKS5_REP_names (int rep)
{
- switch (rep) {
- case SOCKS5_REP_SUCCEEDED: return "succeeded";
- case SOCKS5_REP_FAIL: return "general SOCKS server failure";
- case SOCKS5_REP_NALLOWED: return "connection not allowed by ruleset";
- case SOCKS5_REP_NUNREACH: return "Network unreachable";
- case SOCKS5_REP_HUNREACH: return "Host unreachable";
- case SOCKS5_REP_REFUSED: return "connection refused";
- case SOCKS5_REP_EXPIRED: return "TTL expired";
- case SOCKS5_REP_CNOTSUP: return "Command not supported";
- case SOCKS5_REP_ANOTSUP: return "Address not supported";
- case SOCKS5_REP_INVADDR: return "Invalid address";
- default: return NULL;
+ switch (rep)
+ {
+ case SOCKS5_REP_SUCCEEDED:
+ return "succeeded";
+ case SOCKS5_REP_FAIL:
+ return "general SOCKS server failure";
+ case SOCKS5_REP_NALLOWED:
+ return "connection not allowed by ruleset";
+ case SOCKS5_REP_NUNREACH:
+ return "Network unreachable";
+ case SOCKS5_REP_HUNREACH:
+ return "Host unreachable";
+ case SOCKS5_REP_REFUSED:
+ return "connection refused";
+ case SOCKS5_REP_EXPIRED:
+ return "TTL expired";
+ case SOCKS5_REP_CNOTSUP:
+ return "Command not supported";
+ case SOCKS5_REP_ANOTSUP:
+ return "Address not supported";
+ case SOCKS5_REP_INVADDR:
+ return "Invalid address";
+ default:
+ return NULL;
}
};
@@ -84,30 +98,26 @@ const char * SOCKS5_REP_names(int rep)
* @return pointer to the end of the encoded string in the buffer
*/
unsigned char *
-SOCK5_proto_string(unsigned char * b,
- const char * s)
+SOCK5_proto_string (unsigned char *b, const char *s)
{
- size_t l = strlen(s);
+ size_t l = strlen (s);
if (l > 255)
{
LOG (GNUNET_ERROR_TYPE_WARNING,
"SOCKS5 cannot handle hostnames, usernames, or passwords over 255 bytes, truncating.\n");
- l=255;
+ l = 255;
}
*(b++) = (unsigned char) l;
- /*
- * intentionally use strncpy (trailing zero byte must be stripped in b)
- */
- strncpy ((char*)b, s, l);
- return b+l;
+ memcpy (b, s, l);
+ return b + l;
}
#define SOCKS5_step_greet 0
-#define SOCKS5_step_auth 1
-#define SOCKS5_step_cmd 2
-#define SOCKS5_step_done 3
+#define SOCKS5_step_auth 1
+#define SOCKS5_step_cmd 2
+#define SOCKS5_step_done 3
/**
* State of the SOCKS5 handshake.
@@ -143,7 +153,7 @@ struct GNUNET_SOCKS_Handshake
/**
* Pointers delineating protoocol steps in the outbut buffer
*/
- unsigned char * (outstep[4]);
+ unsigned char *(outstep[4]);
/**
* SOCKS5 handshake input buffer
@@ -153,8 +163,8 @@ struct GNUNET_SOCKS_Handshake
/**
* Pointers delimiting the current step in the input buffer
*/
- unsigned char * instart;
- unsigned char * inend;
+ unsigned char *instart;
+ unsigned char *inend;
};
@@ -163,7 +173,7 @@ struct GNUNET_SOCKS_Handshake
void
register_reciever (struct GNUNET_SOCKS_Handshake *ih, int want);
- /* In fact, the client sends first rule in GNUNet suggests one could take
+/* In fact, the client sends first rule in GNUNet suggests one could take
* large mac read sizes without fear of screwing up the proxied protocol,
* but we make a proper SOCKS5 client. */
#define register_reciever_wants(ih) ((SOCKS5_step_cmd == ih->step) ? 10 : 2)
@@ -181,7 +191,7 @@ register_sender (struct GNUNET_SOCKS_Handshake *ih);
* @return Connection handle that becomes usable when the handshake completes.
*/
void
-SOCKS5_handshake_done(struct GNUNET_SOCKS_Handshake *ih)
+SOCKS5_handshake_done (struct GNUNET_SOCKS_Handshake *ih)
{
GNUNET_CONNECTION_acivate_proxied (ih->target_connection);
}
@@ -195,91 +205,93 @@ SOCKS5_handshake_done(struct GNUNET_SOCKS_Handshake *ih)
void
SOCKS5_handshake_step (struct GNUNET_SOCKS_Handshake *ih)
{
- unsigned char * b = ih->instart;
+ unsigned char *b = ih->instart;
size_t available = ih->inend - b;
- int want = register_reciever_wants(ih);
- if (available < want) {
+ int want = register_reciever_wants (ih);
+ if (available < want)
+ {
register_reciever (ih, want - available);
return;
}
GNUNET_assert (SOCKS5_step_done > ih->step && ih->step >= 0);
- switch (ih->step) {
- case SOCKS5_step_greet: /* SOCKS5 server's greeting */
- if (b[0] != 5)
- {
- LOG (GNUNET_ERROR_TYPE_ERROR,
- "Not a SOCKS5 server\n");
- GNUNET_assert (0);
- }
- switch (b[1]) {
- case SOCKS5_AUTH_NOAUTH:
- ih->step=SOCKS5_step_cmd; /* no authentication to do */
- break;
- case SOCKS5_AUTH_USERPASS:
- ih->step=SOCKS5_step_auth;
- break;
- case SOCKS5_AUTH_REJECT:
- LOG (GNUNET_ERROR_TYPE_ERROR,
- "No authentication method accepted\n");
- return;
- default:
- LOG (GNUNET_ERROR_TYPE_ERROR,
- "Not a SOCKS5 server / Nonsensical authentication\n");
- return;
- }
- b += 2;
+ switch (ih->step)
+ {
+ case SOCKS5_step_greet: /* SOCKS5 server's greeting */
+ if (b[0] != 5)
+ {
+ LOG (GNUNET_ERROR_TYPE_ERROR, "Not a SOCKS5 server\n");
+ GNUNET_assert (0);
+ }
+ switch (b[1])
+ {
+ case SOCKS5_AUTH_NOAUTH:
+ ih->step = SOCKS5_step_cmd; /* no authentication to do */
break;
- case SOCKS5_step_auth: /* SOCKS5 server's responce to authentication */
- if (b[1] != 0)
- {
- LOG (GNUNET_ERROR_TYPE_ERROR,
- "SOCKS5 authentication failed\n");
- GNUNET_assert (0);
- }
- ih->step=SOCKS5_step_cmd;
- b += 2;
+ case SOCKS5_AUTH_USERPASS:
+ ih->step = SOCKS5_step_auth;
break;
- case SOCKS5_step_cmd: /* SOCKS5 server's responce to command */
- if (b[0] != 5)
- {
- LOG (GNUNET_ERROR_TYPE_ERROR,
- "SOCKS5 protocol error\n");
- GNUNET_assert (0);
- }
- if (0 != b[1]) {
- LOG (GNUNET_ERROR_TYPE_ERROR,
- "SOCKS5 connection error : %s\n",
- SOCKS5_REP_names(b[1]));
- return;
- }
- b += 3;
- /* There is no reason to verify host and port afaik. */
- switch (*(b++)) {
- case 1: /* IPv4 */
- b += sizeof(struct in_addr); /* 4 */
- break;
- case 4: /* IPv6 */
- b += sizeof(struct in6_addr); /* 16 */
- break;
- case 3: /* hostname */
- b += *b;
- break;
- }
- b += 2; /* port */
- if (b > ih->inend) {
- register_reciever (ih, b - ih->inend);
- return;
- }
- ih->step = SOCKS5_step_done;
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "SOCKS5 server : %s\n",
- SOCKS5_REP_names(b[1]));
- ih->instart = b;
- SOCKS5_handshake_done (ih);
+ case SOCKS5_AUTH_REJECT:
+ LOG (GNUNET_ERROR_TYPE_ERROR, "No authentication method accepted\n");
return;
- case SOCKS5_step_done:
+ default:
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "Not a SOCKS5 server / Nonsensical authentication\n");
+ return;
+ }
+ b += 2;
+ break;
+ case SOCKS5_step_auth: /* SOCKS5 server's responce to authentication */
+ if (b[1] != 0)
+ {
+ LOG (GNUNET_ERROR_TYPE_ERROR, "SOCKS5 authentication failed\n");
GNUNET_assert (0);
+ }
+ ih->step = SOCKS5_step_cmd;
+ b += 2;
+ break;
+ case SOCKS5_step_cmd: /* SOCKS5 server's responce to command */
+ if (b[0] != 5)
+ {
+ LOG (GNUNET_ERROR_TYPE_ERROR, "SOCKS5 protocol error\n");
+ GNUNET_assert (0);
+ }
+ if (0 != b[1])
+ {
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "SOCKS5 connection error : %s\n",
+ SOCKS5_REP_names (b[1]));
+ return;
+ }
+ b += 3;
+ /* There is no reason to verify host and port afaik. */
+ switch (*(b++))
+ {
+ case 1: /* IPv4 */
+ b += sizeof (struct in_addr); /* 4 */
+ break;
+ case 4: /* IPv6 */
+ b += sizeof (struct in6_addr); /* 16 */
+ break;
+ case 3: /* hostname */
+ b += *b;
+ break;
+ }
+ b += 2; /* port */
+ if (b > ih->inend)
+ {
+ register_reciever (ih, b - ih->inend);
+ return;
+ }
+ ih->step = SOCKS5_step_done;
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "SOCKS5 server : %s\n",
+ SOCKS5_REP_names (b[1]));
+ ih->instart = b;
+ SOCKS5_handshake_done (ih);
+ return;
+ case SOCKS5_step_done:
+ GNUNET_assert (0);
}
ih->instart = b;
/* Do not reschedule the sender unless we're done reading.
@@ -297,13 +309,15 @@ SOCKS5_handshake_step (struct GNUNET_SOCKS_Handshake *ih)
*/
void
reciever (void *cls,
- const void *buf, size_t available,
- const struct sockaddr * addr,
- socklen_t addrlen, int errCode)
+ const void *buf,
+ size_t available,
+ const struct sockaddr *addr,
+ socklen_t addrlen,
+ int errCode)
{
- struct GNUNET_SOCKS_Handshake * ih = cls;
+ struct GNUNET_SOCKS_Handshake *ih = cls;
GNUNET_assert (&ih->inend[available] < &ih->inbuf[1024]);
- GNUNET_memcpy(ih->inend, buf, available);
+ GNUNET_memcpy (ih->inend, buf, available);
ih->inend += available;
SOCKS5_handshake_step (ih);
}
@@ -336,11 +350,9 @@ register_reciever (struct GNUNET_SOCKS_Handshake *ih, int want)
* @return number of bytes written to @a buf
*/
size_t
-transmit_ready (void *cls,
- size_t size,
- void *buf)
+transmit_ready (void *cls, size_t size, void *buf)
{
- struct GNUNET_SOCKS_Handshake * ih = cls;
+ struct GNUNET_SOCKS_Handshake *ih = cls;
/* connection.c has many routines that call us with buf == NULL :
* signal_transmit_error() - DNS, etc. active
@@ -362,31 +374,28 @@ transmit_ready (void *cls,
if (0 == ih->step)
{
LOG (GNUNET_ERROR_TYPE_WARNING,
- "Timeout contacting SOCKS server, retrying indefinitely, but probably hopeless.\n");
+ "Timeout contacting SOCKS server, retrying indefinitely, but probably hopeless.\n");
register_sender (ih);
}
else
{
LOG (GNUNET_ERROR_TYPE_ERROR,
- "Timeout during mid SOCKS handshake (step %u), probably not a SOCKS server.\n",
- ih->step);
+ "Timeout during mid SOCKS handshake (step %u), probably not a SOCKS server.\n",
+ ih->step);
GNUNET_break (0);
}
return 0;
}
- GNUNET_assert ( (1024 >= size) && (size > 0) );
- GNUNET_assert ( (SOCKS5_step_done > ih->step) && (ih->step >= 0) );
- unsigned char * b = ih->outstep[ih->step];
- unsigned char * e = ih->outstep[ih->step+1];
+ GNUNET_assert ((1024 >= size) && (size > 0));
+ GNUNET_assert ((SOCKS5_step_done > ih->step) && (ih->step >= 0));
+ unsigned char *b = ih->outstep[ih->step];
+ unsigned char *e = ih->outstep[ih->step + 1];
GNUNET_assert (e <= &ih->outbuf[1024]);
unsigned int l = e - b;
GNUNET_assert (size >= l);
- GNUNET_memcpy (buf,
- b,
- l);
- register_reciever (ih,
- register_reciever_wants (ih));
+ GNUNET_memcpy (buf, b, l);
+ register_reciever (ih, register_reciever_wants (ih));
return l;
}
@@ -407,8 +416,8 @@ register_sender (struct GNUNET_SOCKS_Handshake *ih)
GNUNET_assert (ih->step >= 0);
if (0 == ih->step)
timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 3);
- unsigned char * b = ih->outstep[ih->step];
- unsigned char * e = ih->outstep[ih->step+1];
+ unsigned char *b = ih->outstep[ih->step];
+ unsigned char *e = ih->outstep[ih->step + 1];
GNUNET_assert (ih->outbuf <= b && b < e && e < &ih->outbuf[1024]);
ih->th = GNUNET_CONNECTION_notify_transmit_ready (ih->socks5_connection,
e - b,
@@ -431,18 +440,20 @@ register_sender (struct GNUNET_SOCKS_Handshake *ih)
struct GNUNET_SOCKS_Handshake *
GNUNET_SOCKS_init_handshake (const char *user, const char *pass)
{
- struct GNUNET_SOCKS_Handshake *ih = GNUNET_new (struct GNUNET_SOCKS_Handshake);
- unsigned char * b = ih->outbuf;
+ struct GNUNET_SOCKS_Handshake *ih =
+ GNUNET_new (struct GNUNET_SOCKS_Handshake);
+ unsigned char *b = ih->outbuf;
ih->outstep[SOCKS5_step_greet] = b;
*(b++) = 5; /* SOCKS5 */
- unsigned char * n = b++;
+ unsigned char *n = b++;
*n = 1; /* Number of authentication methods */
/* We support no authentication even when requesting authentication,
* but this appears harmless, given the way that Tor uses authentication.
* And some SOCKS5 servers might require this. */
*(b++) = SOCKS5_AUTH_NOAUTH;
- if (NULL != user) {
+ if (NULL != user)
+ {
*(b++) = SOCKS5_AUTH_USERPASS;
(*n)++;
}
@@ -458,8 +469,8 @@ GNUNET_SOCKS_init_handshake (const char *user, const char *pass)
ih->outstep[SOCKS5_step_auth] = b;
*(b++) = 1; /* subnegotiation ver.: 1 */
- b = SOCK5_proto_string(b,user);
- b = SOCK5_proto_string(b,pass);
+ b = SOCK5_proto_string (b, user);
+ b = SOCK5_proto_string (b, pass);
ih->outstep[SOCKS5_step_cmd] = b;
@@ -478,7 +489,7 @@ GNUNET_SOCKS_init_handshake (const char *user, const char *pass)
struct GNUNET_SOCKS_Handshake *
GNUNET_SOCKS_init_handshake_noauth ()
{
- return GNUNET_SOCKS_init_handshake (NULL,NULL);
+ return GNUNET_SOCKS_init_handshake (NULL, NULL);
}
@@ -492,34 +503,41 @@ GNUNET_SOCKS_init_handshake_noauth ()
*/
void
GNUNET_SOCKS_set_handshake_destination (struct GNUNET_SOCKS_Handshake *ih,
- const char *host, uint16_t port)
+ const char *host,
+ uint16_t port)
{
- union {
+ union
+ {
struct in_addr in4;
struct in6_addr in6;
} ia;
- unsigned char * b = ih->outstep[SOCKS5_step_cmd];
+ unsigned char *b = ih->outstep[SOCKS5_step_cmd];
- *(b++) = 5; /* SOCKS5 */
- *(b++) = 1; /* Establish a TCP/IP stream */
- *(b++) = 0; /* reserved */
+ *(b++) = 5; /* SOCKS5 */
+ *(b++) = 1; /* Establish a TCP/IP stream */
+ *(b++) = 0; /* reserved */
/* Specify destination */
- if (1 == inet_pton(AF_INET,host,&ia.in4)) {
- *(b++)= 1; /* IPv4 */
- GNUNET_memcpy (b, &ia.in4, sizeof(struct in_addr));
- b += sizeof(struct in_addr); /* 4 */
- } else if (1 == inet_pton(AF_INET6,host,&ia.in6)) {
- *(b++)= 4; /* IPv6 */
- GNUNET_memcpy (b, &ia.in6, sizeof(struct in6_addr));
- b += sizeof(struct in6_addr); /* 16 */
- } else {
- *(b++)= 3; /* hostname */
+ if (1 == inet_pton (AF_INET, host, &ia.in4))
+ {
+ *(b++) = 1; /* IPv4 */
+ GNUNET_memcpy (b, &ia.in4, sizeof (struct in_addr));
+ b += sizeof (struct in_addr); /* 4 */
+ }
+ else if (1 == inet_pton (AF_INET6, host, &ia.in6))
+ {
+ *(b++) = 4; /* IPv6 */
+ GNUNET_memcpy (b, &ia.in6, sizeof (struct in6_addr));
+ b += sizeof (struct in6_addr); /* 16 */
+ }
+ else
+ {
+ *(b++) = 3; /* hostname */
b = SOCK5_proto_string (b, host);
}
/* Specify port */
- *(uint16_t*)b = htons (port);
+ *(uint16_t *) b = htons (port);
b += 2;
ih->outstep[SOCKS5_step_done] = b;
@@ -534,10 +552,10 @@ GNUNET_SOCKS_set_handshake_destination (struct GNUNET_SOCKS_Handshake *ih,
* @return Connection handle that becomes usable when the SOCKS5 handshake completes.
*/
struct GNUNET_CONNECTION_Handle *
-GNUNET_SOCKS_run_handshake(struct GNUNET_SOCKS_Handshake *ih,
+GNUNET_SOCKS_run_handshake (struct GNUNET_SOCKS_Handshake *ih,
struct GNUNET_CONNECTION_Handle *c)
{
- ih->socks5_connection=c;
+ ih->socks5_connection = c;
ih->target_connection = GNUNET_CONNECTION_create_proxied_from_handshake (c);
register_sender (ih);
@@ -583,53 +601,51 @@ GNUNET_SOCKS_do_connect (const char *service_name,
unsigned long long port0;
unsigned long long port1;
- if (GNUNET_YES !=
- GNUNET_SOCKS_check_service (service_name, cfg))
+ if (GNUNET_YES != GNUNET_SOCKS_check_service (service_name, cfg))
return NULL;
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_number (cfg,
- service_name,
- "SOCKSPORT",
- &port0))
+ if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg,
+ service_name,
+ "SOCKSPORT",
+ &port0))
port0 = 9050;
/* A typical Tor client should usually try port 9150 for the TBB too, but
* GNUnet can probably assume a system Tor installation. */
if (port0 > 65535 || port0 <= 0)
{
LOG (GNUNET_ERROR_TYPE_WARNING,
- _("Attempting to use invalid port %d as SOCKS proxy for service `%s'.\n"),
- port0,
+ _ (
+ "Attempting to use invalid port %d as SOCKS proxy for service `%s'.\n"),
+ port0,
service_name);
return NULL;
}
- if ( (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_number (cfg,
- service_name,
- "PORT",
- &port1)) ||
- (port1 > 65535) ||
- (port1 <= 0) ||
- (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_string (cfg,
- service_name,
- "HOSTNAME",
- &host1)))
+ if ((GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg,
+ service_name,
+ "PORT",
+ &port1)) ||
+ (port1 > 65535) || (port1 <= 0) ||
+ (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg,
+ service_name,
+ "HOSTNAME",
+ &host1)))
{
LOG (GNUNET_ERROR_TYPE_WARNING,
- _("Attempting to proxy service `%s' to invalid port %d or hostname.\n"),
- service_name,
+ _ (
+ "Attempting to proxy service `%s' to invalid port %d or hostname.\n"),
+ service_name,
port1);
return NULL;
}
/* Appeared to still work after host0 corrupted, so either test case is broken, or
this whole routine is not being called. */
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_string (cfg, service_name, "SOCKSHOST", &host0))
+ if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg,
+ service_name,
+ "SOCKSHOST",
+ &host0))
host0 = NULL;
socks5 = GNUNET_CONNECTION_create_from_connect (cfg,
- (host0 != NULL)
- ? host0
- :"127.0.0.1",
+ (host0 != NULL) ? host0
+ : "127.0.0.1",
port0);
GNUNET_free_non_null (host0);
@@ -642,16 +658,13 @@ GNUNET_SOCKS_do_connect (const char *service_name,
service_name,
"SOCKSPASS",
&pass);
- ih = GNUNET_SOCKS_init_handshake(user,pass);
+ ih = GNUNET_SOCKS_init_handshake (user, pass);
GNUNET_free_non_null (user);
GNUNET_free_non_null (pass);
- GNUNET_SOCKS_set_handshake_destination (ih,
- host1,
- port1);
+ GNUNET_SOCKS_set_handshake_destination (ih, host1, port1);
GNUNET_free (host1);
- return GNUNET_SOCKS_run_handshake (ih,
- socks5);
+ return GNUNET_SOCKS_run_handshake (ih, socks5);
}
/* socks.c */