diff options
author | Federico Mena Quintero <federico@novell.com> | 2010-09-20 10:37:57 -0500 |
---|---|---|
committer | Federico Mena Quintero <federico@novell.com> | 2010-09-20 11:07:51 -0500 |
commit | 64d7b241dd29e17b30896781a5fa5f5bb818b519 (patch) | |
tree | 099c61bb55ed61345b852968b65e0207a2f812bf | |
parent | 00af4564a58e672d34765f011cab592876d5951f (diff) | |
download | evolution-data-server-64d7b241dd29e17b30896781a5fa5f5bb818b519.tar.gz |
Sanitize error handling in the SOCKS5/SOCKS4 code paths
Provide more detailed errors based on the replies of the SOCKS server.
Don't leak some GErrors in case of retries.
Signed-off-by: Federico Mena Quintero <federico@novell.com>
-rw-r--r-- | camel/camel-tcp-stream-raw.c | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/camel/camel-tcp-stream-raw.c b/camel/camel-tcp-stream-raw.c index f8954042f..4f5ec49ad 100644 --- a/camel/camel-tcp-stream-raw.c +++ b/camel/camel-tcp-stream-raw.c @@ -674,10 +674,10 @@ connect_to_socks4_proxy (CamelTcpStreamRaw *raw, const gchar *proxy_host, gint p PRFileDesc *fd; gchar request[9]; struct sockaddr_in *sin; - gchar reply[8]; + gchar reply[8]; /* note that replies are 8 bytes, even if only the first 2 are used */ gint save_errno; - g_assert (connect_addr->ai_addr->sa_family == AF_INET); /* FMQ: check for AF_INET in the caller */ + g_assert (connect_addr->ai_addr->sa_family == AF_INET); fd = connect_to_proxy (raw, proxy_host, proxy_port, error); if (!fd) @@ -700,17 +700,31 @@ connect_to_socks4_proxy (CamelTcpStreamRaw *raw, const gchar *proxy_host, gint p d (g_print (" reading SOCKS4 reply\n")); if (read_from_prfd (fd, reply, sizeof (reply), error) != sizeof (reply)) { d (g_print (" failed: %d\n", errno)); + g_set_error (error, CAMEL_PROXY_ERROR, CAMEL_PROXY_ERROR_PROXY_NOT_SUPPORTED, + _("The proxy host does not support SOCKS4")); goto error; } - if (!(reply[0] == 0 /* first byte of reply is 0 */ - && reply[1] == 90)) { /* 90 means "request granted" */ + if (reply[0] != 0) { /* version of reply code is 0 */ #ifdef G_OS_WIN32 errno = WSAECONNREFUSED; #else errno = ECONNREFUSED; #endif - _set_g_error_from_errno (error, FALSE); + g_set_error (error, CAMEL_PROXY_ERROR, CAMEL_PROXY_ERROR_PROXY_NOT_SUPPORTED, + _("The proxy host does not support SOCKS4")); + goto error; + } + + if (reply[1] != 90)) { /* 90 means "request granted" */ +#ifdef G_OS_WIN32 + errno = WSAECONNREFUSED; +#else + errno = ECONNREFUSED; +#endif + g_set_error (error, CAMEL_PROXY_ERROR, CAMEL_PROXY_ERROR_CANT_AUTHENTICATE, + _("The proxy host denied our request: code %d"), + reply[1]); goto error; } @@ -796,6 +810,7 @@ socks5_initiate_and_request_authentication (CamelTcpStreamRaw *raw, PRFileDesc * d (g_print (" reading SOCKS5 reply\n")); if (read_from_prfd (fd, reply, sizeof (reply), error) != sizeof (reply)) { d (g_print (" failed: %d\n", errno)); + g_clear_error (error); g_set_error (error, CAMEL_PROXY_ERROR, CAMEL_PROXY_ERROR_PROXY_NOT_SUPPORTED, _("The proxy host does not support SOCKS5")); return FALSE; @@ -876,6 +891,7 @@ socks5_consume_reply_address (CamelTcpStreamRaw *raw, PRFileDesc *fd, GError **e incomplete_reply: g_free (address_and_port); + g_clear_error (error); g_set_error (error, CAMEL_SERVICE_ERROR, CAMEL_SERVICE_ERROR_NOT_CONNECTED, _("Incomplete reply from SOCKS server")); return FALSE; } @@ -1062,6 +1078,9 @@ tcp_stream_raw_connect (CamelTcpStream *stream, goto out; } + if (ai->next != NULL) + g_clear_error (error); /* Only preserve the error from the last try, in case no tries are successful */ + ai = ai->ai_next; } |