Esempio n. 1
0
static void set_proxy_auth(gboolean use_proxy_auth)
{
    char *auth_user;
    char *auth_pw;

    auth_user =
	gconf_client_get_string(gl_client, KEY_GCONF_HTTP_AUTH_USER, NULL);
    auth_pw =
	gconf_client_get_string(gl_client, KEY_GCONF_HTTP_AUTH_PW, NULL);

    if (use_proxy_auth) {
	/* Christian Kellner: Here are the only changes I made to the proxy sub-
	 * system 
	 */
	proxy_username = (auth_user != NULL ? g_strdup(auth_user) : NULL);
	proxy_password = (auth_pw != NULL ? g_strdup(auth_pw) : NULL);
	DEBUG_HTTP(("New HTTP proxy auth user: '******'", auth_user));
    } else {
	if (proxy_username != NULL)
	    g_free(proxy_username);

	if (proxy_password != NULL)
	    g_free(proxy_password);

	proxy_username = proxy_password = NULL;

	DEBUG_HTTP(("HTTP proxy auth unset"));
    }

    g_free(auth_user);
    g_free(auth_pw);
}
Esempio n. 2
0
void proxy_init(void)
{
    GError *gconf_error = NULL;
    gboolean use_proxy;
    gboolean use_proxy_auth;

    gl_client = gconf_client_get_default();
    gl_mutex = g_mutex_new();

    gconf_client_add_dir(gl_client, PATH_GCONF_GNOME_VFS,
			 GCONF_CLIENT_PRELOAD_ONELEVEL, &gconf_error);
    if (gconf_error) {
	DEBUG_HTTP(("GConf error during client_add_dir '%s'",
		    gconf_error->message));
	g_error_free(gconf_error);
	gconf_error = NULL;
    }

    gconf_client_notify_add(gl_client, PATH_GCONF_GNOME_VFS,
			    notify_gconf_value_changed, NULL, NULL,
			    &gconf_error);
    if (gconf_error) {
	DEBUG_HTTP(("GConf error during notify_error '%s'",
		    gconf_error->message));
	g_error_free(gconf_error);
	gconf_error = NULL;
    }

    /* Load the http proxy setting */
    use_proxy =
	gconf_client_get_bool(gl_client, KEY_GCONF_USE_HTTP_PROXY,
			      &gconf_error);

    if (gconf_error != NULL) {
	DEBUG_HTTP(("GConf error during client_get_bool '%s'",
		    gconf_error->message));
	g_error_free(gconf_error);
	gconf_error = NULL;
    } else {
	construct_gl_http_proxy(use_proxy);
    }

    use_proxy_auth =
	gconf_client_get_bool(gl_client, KEY_GCONF_HTTP_USE_AUTH,
			      &gconf_error);

    if (gconf_error != NULL) {
	DEBUG_HTTP(("GConf error during client_get_bool '%s'",
		    gconf_error->message));
	g_error_free(gconf_error);
	gconf_error = NULL;
    } else {
	set_proxy_auth(use_proxy_auth);
    }
}
Esempio n. 3
0
static void construct_gl_http_proxy(gboolean use_proxy)
{
    g_free(gl_http_proxy);
    gl_http_proxy = NULL;

    g_slist_foreach(gl_ignore_hosts, (GFunc) g_free, NULL);
    g_slist_free(gl_ignore_hosts);
    gl_ignore_hosts = NULL;
    g_slist_foreach(gl_ignore_addrs, (GFunc) g_free, NULL);
    g_slist_free(gl_ignore_addrs);
    gl_ignore_addrs = NULL;

    if (use_proxy) {
	char *proxy_host;
	int proxy_port;
	GSList *ignore;

	proxy_host =
	    gconf_client_get_string(gl_client,
				    KEY_GCONF_HTTP_PROXY_HOST, NULL);
	proxy_port =
	    gconf_client_get_int(gl_client,
				 KEY_GCONF_HTTP_PROXY_PORT, NULL);

	if (proxy_host && proxy_host[0] != '\0') {
	    if (0 != proxy_port && 0xffff >= (unsigned) proxy_port) {
		gl_http_proxy =
		    g_strdup_printf("%s:%u", proxy_host, (unsigned)
				    proxy_port);
	    } else {
		gl_http_proxy =
		    g_strdup_printf("%s:%u", proxy_host, (unsigned)
				    DEFAULT_HTTP_PROXY_PORT);
	    }
	    DEBUG_HTTP(("New HTTP proxy: '%s'", gl_http_proxy));
	} else {
	    DEBUG_HTTP(("HTTP proxy unset"));
	}

	g_free(proxy_host);
	proxy_host = NULL;

	ignore = gconf_client_get_list(gl_client,
				       KEY_GCONF_HTTP_PROXY_IGNORE_HOSTS,
				       GCONF_VALUE_STRING, NULL);
	g_slist_foreach(ignore, (GFunc) parse_ignore_host, NULL);
	g_slist_foreach(ignore, (GFunc) g_free, NULL);
	g_slist_free(ignore);
	ignore = NULL;
    }
}
Esempio n. 4
0
bool BaseHTTPProtocol::HandleChunkedContent(IOBuffer &buffer) {
	//2. We cycle until we don't have any complete chunks anymore
	//or we hit the 0 bytes chunks (end of chunked content)
	uint8_t *pBuffer = NULL;
	uint32_t chunkSize = 0;
	uint32_t chunkSizeSize = 0;
	while (GETAVAILABLEBYTESCOUNT(buffer) >= 3) {
		//1. Get the raw pointer. We need it almost everywhere
		pBuffer = GETIBPOINTER(buffer);
		//FINEST("%s", STR(buffer));

		chunkSizeSize = 0;
		//3. Read the string which represents the number of bytes in the chunk
		for (uint32_t i = 0; i < GETAVAILABLEBYTESCOUNT(buffer) - 1; i++) {
			//5. Are we at the end of chunk size string?
			if ((pBuffer[i] == 0x0d) && (pBuffer[i + 1] == 0x0a)) {
				chunkSizeSize = i + 2;
				break;
			}

			//4. If the chunk size string has more than 10 bytes, we drop it like
			//is hot! Also test each char to be a hex number.
			//This is a bogus request/response
			if (i >= 10 || (!(((pBuffer[i] >= '0') && (pBuffer[i] <= '9'))
					|| ((pBuffer[i] >= 'a') && (pBuffer[i] <= 'f'))
					|| ((pBuffer[i] >= 'A') && (pBuffer[i] <= 'F'))))) {
				FATAL("Unable to read chunk size length:\n%s", STR(buffer));
				return false;
			}
		}
		//7. Test the newly extracted chunk size
		if (chunkSizeSize == 0) {
			return true;
		}

		//8. Get its actual value and test it as well
		chunkSize = strtol((char *) pBuffer, NULL, 16);
		if (chunkSize > HTTP_MAX_CHUNK_SIZE) {
			FATAL("Chunk size too large. Maximum allowed is %" PRIu32 " and we got %" PRIu32,
					(uint32_t) HTTP_MAX_CHUNK_SIZE, chunkSize);
			return false;
		}

		//9. Now, we know the chunk size... do we have enough data?
		if (GETAVAILABLEBYTESCOUNT(buffer) <
				chunkSizeSize //length of the chunk size string
				- 2 //substract the 0x particle
				+ 2 //the \r\n that follows the chunk size string
				+ chunkSize //chunk size itself
				+ 2 //the \r\n that follows the data chunk
				) {
			return true;
		}

		//10. Update the session decoded bytes count and decoded bytes count
		_sessionDecodedBytesCount += chunkSize;
		_decodedBytesCount += chunkSize;

		if (chunkSize != 0) {
			//11. Make the copy
			_contentLength += chunkSize;
			_inputBuffer.ReadFromBuffer(GETIBPOINTER(buffer) + chunkSizeSize - 2 + 2, chunkSize);
		} else {
			//12. This was the last chunk (0 bytes size)
			_lastChunk = true;
		}

		//12. Call the near protocol
		if (!_pNearProtocol->SignalInputData(_inputBuffer)) {
			FATAL("Unable to call the next protocol in stack");
			return false;
		}

		//13. Ignore the bytes from the input buffer
		DEBUG_HTTP("available bytes before ignore: %" PRIu32, GETAVAILABLEBYTESCOUNT(buffer));
		//				if (GETAVAILABLEBYTESCOUNT(buffer) == ((uint32_t) chunkSizeSize - 2 + 2 + chunkSize + 2)) {
		//					DEBUG_HTTP("%s", STR(buffer));
		//				}
		buffer.Ignore((uint32_t) chunkSizeSize - 2 + 2 + chunkSize + 2);
		DEBUG_HTTP("available bytes  after ignore: %" PRIu32, GETAVAILABLEBYTESCOUNT(buffer));

		//14. reset the state if necessary
		if (TransferCompleted()) {
			_headers.Reset();
			_chunkedContent = false;
			_lastChunk = false;
			_contentLength = 0;
			_state = HTTP_STATE_HEADERS;
			_sessionDecodedBytesCount = 0;
			return true;
		}
	}
	return true;
}
Esempio n. 5
0
bool BaseHTTPProtocol::SignalInputData(IOBuffer &buffer) {
	DEBUG_HTTP("-------------------");
	DEBUG_HTTP("%s", STR(*this));
	DEBUG_HTTP("_state: %s", (_state == HTTP_STATE_HEADERS) ? "HTTP_STATE_HEADERS" : (_state == HTTP_STATE_PAYLOAD) ? "HTTP_STATE_PAYLOAD" : "UNKNOWN");
	//1. Get the first line and the headers if necessary
	if (_state == HTTP_STATE_HEADERS) {
		DEBUG_HTTP("Parse the headers");
		if (!ParseHeaders(buffer)) {
			FATAL("Unable to read response headers: %s", STR(*this));
			return false;
		}
	}

	DEBUG_HTTP("_continueAfterParseHeaders: %d", _continueAfterParseHeaders);
	if (!_continueAfterParseHeaders)
		return true;

	//2. Are we still in the "get headers state"? If so, wait for more data
	DEBUG_HTTP("new value of _state: %s", (_state == HTTP_STATE_HEADERS) ? "HTTP_STATE_HEADERS" : (_state == HTTP_STATE_PAYLOAD) ? "HTTP_STATE_PAYLOAD" : "UNKNOWN");
	if (_state != HTTP_STATE_PAYLOAD) {
		return true;
	}

	DEBUG_HTTP("_chunkedContent: %d", _chunkedContent);
	//3. Turning point in processing
	if (_chunkedContent) {
		//4. We deal with chunked content
		DEBUG_HTTP("begin chunk content handling");
		if (!HandleChunkedContent(buffer)) {
			FATAL("Unable to handle chunked content: %s", STR(*this));
			return false;
		}
	} else {
		//5. We deal with length-specified type of content
		DEBUG_HTTP("begin fixed length content handling");
		if (!HandleFixedLengthContent(buffer)) {
			FATAL("Unable to handle fixed length content: %s", STR(*this));
			return false;
		}
	}

	//6. Are we in the get headers state? if so, we might have a new request
	//on the pipe.
	DEBUG_HTTP("brand new value of _state: %s", (_state == HTTP_STATE_HEADERS) ? "HTTP_STATE_HEADERS" : (_state == HTTP_STATE_PAYLOAD) ? "HTTP_STATE_PAYLOAD" : "UNKNOWN");
	if (_state == HTTP_STATE_HEADERS) {
		DEBUG_HTTP("Call SignalInputData again");
		//7. So, get to work again...
		return SignalInputData(buffer);
	} else {
		//8 We are done :)
		DEBUG_HTTP("Done");
		return true;
	}
}
Esempio n. 6
0
static void parse_ignore_host(gpointer data, gpointer user_data)
{
    gchar *hostname, *input, *netmask;
    gboolean ip_addr = FALSE, has_error = FALSE;
    struct in_addr host;
#ifdef ENABLE_IPV6
    struct in6_addr host6, mask6;
    gint i;
#endif
    ProxyHostAddr *elt;

    input = (gchar *) data;
    elt = g_new0(ProxyHostAddr, 1);
    if ((netmask = strchr(input, '/')) != NULL) {
	hostname = g_strndup(input, netmask - input);
	++netmask;
    } else {
	hostname = g_ascii_strdown(input, -1);
    }
    if (inet_pton(AF_INET, hostname, &host) > 0) {
	ip_addr = TRUE;
	elt->type = PROXY_IPv4;
	elt->addr.s_addr = host.s_addr;
	if (netmask) {
	    gchar *endptr;
	    gint width = strtol(netmask, &endptr, 10);

	    if (*endptr != '\0' || width < 0 || width > 32) {
		has_error = TRUE;
	    }
	    elt->mask.s_addr = htonl(~0 << width);
	    elt->addr.s_addr &= elt->mask.s_addr;
	} else {
	    elt->mask.s_addr = 0xffffffff;
	}
    }
#ifdef ENABLE_IPV6
    else if (have_ipv6() && inet_pton(AF_INET6, hostname, &host6) > 0) {
	ip_addr = TRUE;
	elt->type = PROXY_IPv6;
	for (i = 0; i < 16; ++i) {
	    elt->addr6.s6_addr[i] = host6.s6_addr[i];
	}
	if (netmask) {
	    gchar *endptr;
	    gint width = strtol(netmask, &endptr, 10);

	    if (*endptr != '\0' || width < 0 || width > 128) {
		has_error = TRUE;
	    }
	    for (i = 0; i < 16; ++i) {
		elt->mask6.s6_addr[i] = 0;
	    }
	    for (i = 0; i < width / 8; i++) {
		elt->mask6.s6_addr[i] = 0xff;
	    }
	    elt->mask6.s6_addr[i] = (0xff << (8 - width % 8)) & 0xff;
	    ipv6_network_addr(&elt->addr6, &mask6, &elt->addr6);
	} else {
	    for (i = 0; i < 16; ++i) {
		elt->mask6.s6_addr[i] = 0xff;
	    }
	}
    }
#endif

    if (ip_addr) {
	if (!has_error) {
	    gchar *dst = g_new0(gchar, INET_ADDRSTRLEN);

	    gl_ignore_addrs = g_slist_append(gl_ignore_addrs, elt);
	    DEBUG_HTTP(("Host %s/%s does not go through proxy.",
			hostname, inet_ntop(AF_INET, &elt->mask,
					    dst, INET_ADDRSTRLEN)));
	    g_free(dst);
	}
	g_free(hostname);
    } else {
	/* It is a hostname. */
	gl_ignore_hosts = g_slist_append(gl_ignore_hosts, hostname);
	DEBUG_HTTP(("Host %s does not go through proxy.", hostname));
	g_free(elt);
    }
}
Esempio n. 7
0
static gboolean proxy_should_for_hostname(const char *hostname)
{
#ifdef ENABLE_IPV6
    struct in6_addr in6, net6;
#endif
    struct in_addr in;
    GSList *elt;
    ProxyHostAddr *addr;


    /* IPv4 address */
    if (inet_pton(AF_INET, hostname, &in) > 0) {
	for (elt = gl_ignore_addrs; elt; elt = g_slist_next(elt)) {
	    addr = (ProxyHostAddr *) (elt->data);
	    if (addr->type == PROXY_IPv4
		&& (in.s_addr & addr->mask.s_addr) == addr->addr.s_addr) {
		DEBUG_HTTP(("Host %s using direct connection.", hostname));
		return FALSE;
	    }
	}
    }
#ifdef ENABLE_IPV6
    else if (have_ipv6() && inet_pton(AF_INET6, hostname, &in6)) {
	for (elt = gl_ignore_addrs; elt; elt = g_slist_next(elt)) {
	    addr = (ProxyHostAddr *) (elt->data);
	    ipv6_network_addr(&in6, &addr->mask6, &net6);
	    if (addr->type == PROXY_IPv6
		&& IN6_ARE_ADDR_EQUAL(&net6, &addr->addr6)) {
		DEBUG_HTTP(("Host %s using direct connection.", hostname));
		return FALSE;
	    }
	    /* Handle IPv6-wrapped IPv4 addresses. */
	    else if (addr->type == PROXY_IPv4
		     && IN6_IS_ADDR_V4MAPPED(&net6)) {
		guint32 v4addr;

		v4addr = net6.s6_addr[12] << 24 | net6.
		    s6_addr[13] << 16 | net6.
		    s6_addr[14] << 8 | net6.s6_addr[15];
		if ((v4addr & addr->mask.s_addr) != addr->addr.s_addr) {
		    DEBUG_HTTP(("Host %s using direct connection.",
				hostname));
		    return FALSE;
		}
	    }
	}
    }
#endif
    /* All hostnames (foo.bar.com) -- independent of IPv4 or IPv6 */

    /* If there are IPv6 addresses in the ignore_hosts list but we do not
     * have IPv6 available at runtime, then those addresses will also fall
     * through to here (and harmlessly fail to match). */
    else {
	gchar *hn = g_ascii_strdown(hostname, -1);

	for (elt = gl_ignore_hosts; elt; elt = g_slist_next(elt)) {
	    if (*(gchar *) (elt->data) == '*') {
		if (g_str_has_suffix(hn, (gchar *) (elt->data) + 1)) {
		    DEBUG_HTTP(("Host %s using direct connection.", hn));
		    g_free(hn);
		    return FALSE;
		}
	    } else if (strcmp(hn, elt->data) == 0) {
		DEBUG_HTTP(("Host %s using direct connection.", hn));
		g_free(hn);
		return FALSE;
	    }
	}
	g_free(hn);
    }

    return TRUE;
}