[evolution-data-server] Function to connect to a SOCKS4 proxy



commit dbc72b58fddef22b3599b46dad99453985aa9695
Author: Federico Mena Quintero <federico novell com>
Date:   Tue May 25 16:18:21 2010 -0500

    Function to connect to a SOCKS4 proxy
    
    Signed-off-by: Federico Mena Quintero <federico novell com>

 camel/camel-tcp-stream-raw.c |   73 ++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 73 insertions(+), 0 deletions(-)
---
diff --git a/camel/camel-tcp-stream-raw.c b/camel/camel-tcp-stream-raw.c
index 153d008..2058afe 100644
--- a/camel/camel-tcp-stream-raw.c
+++ b/camel/camel-tcp-stream-raw.c
@@ -33,6 +33,7 @@
 #include <sys/types.h>
 
 #include "camel-file-utils.h"
+#include "camel-net-utils.h"
 #include "camel-operation.h"
 #include "camel-tcp-stream-raw.h"
 
@@ -372,6 +373,78 @@ tcp_stream_raw_close (CamelStream *stream)
 	return 0;
 }
 
+/* Returns the FD of a socket, already connected to and validated by the SOCKS4
+ * proxy that is configured in the stream.  Otherwise returns -1.  Assumes that
+ * a proxy *is* configured with camel_tcp_stream_set_socks_proxy().
+ */
+static gint
+connect_to_socks4_proxy (CamelTcpStreamRaw *raw, struct addrinfo *connect_addr)
+{
+	const gchar *host;
+	gint port;
+	struct addrinfo *ai, hints;
+	gchar serv[16];
+	gint fd;
+	gchar request[9];
+	struct sockaddr_in *sin;
+	guint32 network_address;
+	gchar reply[8];
+
+	camel_tcp_stream_peek_socks_proxy (CAMEL_TCP_STREAM (raw), &host, &port);
+
+	g_assert (host != NULL);
+
+	sprintf (serv, "%d", port);
+
+	memset (&hints, 0, sizeof (hints));
+	hints.ai_socktype = SOCK_STREAM;
+
+	ai = camel_getaddrinfo (host, serv, &hints, NULL);
+	if (!ai)
+		return -1;
+
+	fd = socket_connect (ai);
+
+	camel_freeaddrinfo (ai);
+
+	if (fd == -1)
+		goto error;
+
+	g_assert (connect_addr->ai_addr->sa_family == AF_INET); /* FIXME: what to do about IPv6?  Are we just screwed with SOCKS4? */
+	sin = (struct sockaddr_in *) connect_addr->ai_addr;
+	network_address = sin->sin_addr.s_addr;
+	network_address = htonl (network_address);
+
+	request[0] = 0x04;				/* SOCKS4 */
+	request[1] = 0x01;				/* CONNECT */
+	request[2] = sin->sin_port >> 8;		/* high byte of port */
+	request[3] = sin->sin_port & 0x00ff;		/* low byte of port */
+	memcpy (request + 4, &network_address, 4);	/* address in network byte order */
+	request[8] = 0x00;				/* terminator */
+
+	if (camel_write_socket (fd, request, sizeof (request)) != sizeof (request))
+		goto error;
+
+	if (camel_read_socket (fd, reply, sizeof (reply)) != sizeof (reply))
+		goto error;
+
+	if (!(reply[0] == 0		/* first byte of reply is 0 */
+	      && reply[1] != 90))	/* 90 means "request granted" */
+		goto error;
+
+	goto out;
+
+error:
+	if (fd != -1) {
+		SOCKET_CLOSE (fd);
+		fd = -1;
+	}
+
+out:
+
+	return fd;
+}
+
 static gint
 tcp_stream_raw_connect (CamelTcpStream *stream,
                         struct addrinfo *host)



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]