示例#1
0
文件: hsts.c 项目: vlampreia/vimb
/**
 * Checks if given host is a known https host according to RFC 6797 8.2f
 */
static inline gboolean should_secure_host(HSTSProvider *provider,
    const char *host)
{
    HSTSProviderPrivate *priv = HSTS_PROVIDER_GET_PRIVATE(provider);
    HSTSEntry *entry;
    char *canonical, *p;
    gboolean result = false, is_subdomain = false;

    /* ip is not allowed for hsts */
    if (g_hostname_is_ip_address(host)) {
        return false;
    }

    canonical = g_hostname_to_ascii(host);
    /* don't match empty host */
    if (*canonical) {
        p = canonical;
        /* Try to find the whole congruent matching host in hash table - if
         * not found strip of the first label and try to find a superdomain
         * match. Specified is a from right to left comparison 8.3, but in the
         * end this should be lead to the same result. */
        while (p != NULL) {
            entry = g_hash_table_lookup(priv->whitelist, p);
            if (entry != NULL) {
                /* remove expired entries RFC 6797 8.1.1 */
                if (soup_date_is_past(entry->expires_at)) {
                    remove_host_entry(provider, p);
                } else if(!is_subdomain || entry->include_sub_domains) {
                    result = true;
                    break;
                }
            }

            is_subdomain = true;
            /* test without the first domain part */
            if ((p = strchr(p, '.'))) {
                p++;
            }
        }
    }
    g_free(canonical);

    return result;
}
示例#2
0
static void
print_request (SoupLogger *logger, SoupMessage *msg,
	       SoupSession *session, SoupSocket *socket,
	       gboolean restarted)
{
	SoupLoggerPrivate *priv = SOUP_LOGGER_GET_PRIVATE (logger);
	SoupLoggerLogLevel log_level;
	SoupMessageHeadersIter iter;
	const char *name, *value;
	SoupURI *uri;

	if (priv->request_filter) {
		log_level = priv->request_filter (logger, msg,
						  priv->request_filter_data);
	} else
		log_level = priv->level;

	if (log_level == SOUP_LOGGER_LOG_NONE)
		return;

	uri = soup_message_get_uri (msg);
	if (msg->method == SOUP_METHOD_CONNECT) {
		soup_logger_print (logger, SOUP_LOGGER_LOG_MINIMAL, '>',
				   "CONNECT %s:%u HTTP/1.%d",
				   uri->host, uri->port,
				   soup_message_get_http_version (msg));
	} else {
		soup_logger_print (logger, SOUP_LOGGER_LOG_MINIMAL, '>',
				   "%s %s%s%s HTTP/1.%d",
				   msg->method, uri->path,
				   uri->query ? "?" : "",
				   uri->query ? uri->query : "",
				   soup_message_get_http_version (msg));
	}

	soup_logger_print (logger, SOUP_LOGGER_LOG_MINIMAL, '>',
			   "Soup-Debug-Timestamp: %lu",
			   (unsigned long)time (0));
	soup_logger_print (logger, SOUP_LOGGER_LOG_MINIMAL, '>',
			   "Soup-Debug: %s %u (%p), %s %u (%p), %s %u (%p)%s",
			   g_type_name_from_instance ((GTypeInstance *)session),
			   soup_logger_get_id (logger, session), session,
			   g_type_name_from_instance ((GTypeInstance *)msg),
			   soup_logger_get_id (logger, msg), msg,
			   g_type_name_from_instance ((GTypeInstance *)socket),
			   soup_logger_get_id (logger, socket), socket,
			   restarted ? ", restarted" : "");

	if (log_level == SOUP_LOGGER_LOG_MINIMAL)
		return;

	if (!soup_message_headers_get_one (msg->request_headers, "Host")) {
		char *uri_host;

		if (strchr (uri->host, ':'))
			uri_host = g_strdup_printf ("[%s]", uri->host);
		else if (g_hostname_is_non_ascii (uri->host))
			uri_host = g_hostname_to_ascii (uri->host);
		else
			uri_host = uri->host;

		soup_logger_print (logger, SOUP_LOGGER_LOG_HEADERS, '>',
				   "Host: %s%c%u", uri_host,
				   soup_uri_uses_default_port (uri) ? '\0' : ':',
				   uri->port);

		if (uri_host != uri->host)
			g_free (uri_host);
	}
	soup_message_headers_iter_init (&iter, msg->request_headers);
	while (soup_message_headers_iter_next (&iter, &name, &value)) {
		if (!g_ascii_strcasecmp (name, "Authorization") &&
		    !g_ascii_strncasecmp (value, "Basic ", 6))
			soup_logger_print_basic_auth (logger, value);
		else {
			soup_logger_print (logger, SOUP_LOGGER_LOG_HEADERS, '>',
					   "%s: %s", name, value);
		}
	}
	if (log_level == SOUP_LOGGER_LOG_HEADERS)
		return;

	if (msg->request_body->length &&
	    soup_message_body_get_accumulate (msg->request_body)) {
		SoupBuffer *request;

		request = soup_message_body_flatten (msg->request_body);
		g_return_if_fail (request != NULL);
		soup_buffer_free (request);

		if (soup_message_headers_get_expectations (msg->request_headers) != SOUP_EXPECTATION_CONTINUE) {
			soup_logger_print (logger, SOUP_LOGGER_LOG_BODY, '>',
					   "\n%s", msg->request_body->data);
		}
	}
}
示例#3
0
/* "Add domain"-button was pressed */
static void _nojs_preferences_on_add_domain_clicked(NoJSPreferences *self,
														gpointer *inUserData)
{
	NoJSPreferencesPrivate	*priv=self->priv;
	gchar					*domain;
	const gchar				*domainStart, *domainEnd;
	gchar					*realDomain;
	GtkTreeIter				policyIter;

	g_return_if_fail(priv->database);

	/* Get domain name entered */
	domain=g_hostname_to_ascii(gtk_entry_get_text(GTK_ENTRY(priv->addDomainEntry)));

	/* Trim whitespaces from start and end of entered domain name */
	domainStart=domain;
	while(*domainStart && g_ascii_isspace(*domainStart)) domainStart++;

	domainEnd=domain+strlen(domain)-1;
	while(*domainEnd && g_ascii_isspace(*domainEnd)) domainEnd--;
	if(domainEnd<=domainStart) return;

	/* Seperate domain name from whitespaces */
	realDomain=g_strndup(domain, domainEnd-domainStart+1);
	if(!realDomain) return;

	/* Get policy from combo box */
	if(gtk_combo_box_get_active_iter(GTK_COMBO_BOX(priv->addDomainPolicyCombo), &policyIter))
	{
		gchar	*sql;
		gchar	*error=NULL;
		gint	success;
		gint	policy;
		gchar	*policyName;

		/* Get policy value to set for domain */
		gtk_tree_model_get(gtk_combo_box_get_model(GTK_COMBO_BOX(priv->addDomainPolicyCombo)),
													&policyIter,
													0, &policy,
													1, &policyName,
													-1);

		/* Add domain name and the selected policy to database */
		sql=sqlite3_mprintf("INSERT OR REPLACE INTO policies (site, value) VALUES ('%q', %d);",
								realDomain,
								policy);
		success=sqlite3_exec(priv->database, sql, NULL, NULL, &error);

		/* Show error message if any */
		if(success==SQLITE_OK)
		{
			gtk_list_store_append(priv->listStore, &policyIter);
			gtk_list_store_set(priv->listStore,
								&policyIter,
								DOMAIN_COLUMN, realDomain,
								POLICY_COLUMN, policyName,
								-1);
		}
			else g_warning(_("SQL fails: %s"), error);


		if(error) sqlite3_free(error);

		/* Free allocated resources */
		sqlite3_free(sql);
	}

	/* Free allocated resources */
	g_free(realDomain);
	g_free(domain);
}
示例#4
0
/* Entry containing domain name which may be added to list has changed */
static void _nojs_preferences_on_add_domain_entry_changed(NoJSPreferences *self,
															GtkEditable *inEditable)
{
	NoJSPreferencesPrivate	*priv=self->priv;
	gchar					*asciiDomain, *checkAsciiDomain;
	gchar					*asciiDomainStart, *asciiDomainEnd;
	gint					dots;
	gboolean				isValid=FALSE;

	/* Get ASCII representation of domain name entered */
	asciiDomain=g_hostname_to_ascii(gtk_entry_get_text(GTK_ENTRY(priv->addDomainEntry)));

	/* Trim whitespaces from start and end of entered domain name */
	asciiDomainStart=asciiDomain;
	while(*asciiDomainStart && g_ascii_isspace(*asciiDomainStart)) asciiDomainStart++;

	asciiDomainEnd=asciiDomain+strlen(asciiDomain)-1;
	while(*asciiDomainEnd && g_ascii_isspace(*asciiDomainEnd)) asciiDomainEnd--;

	/* We allow only domain names and not cookie domain name so entered name
	 * must not start with a dot
	 */
	checkAsciiDomain=asciiDomainStart;
	isValid=(*asciiDomainStart!='.' && *asciiDomainEnd!='.');

	/* Now check if ASCII domain name is valid (very very simple check)
	 * and contains a hostname besides TLD
	 */
	dots=0;

	while(*checkAsciiDomain &&
			checkAsciiDomain<=asciiDomainEnd &&
			isValid)
	{
		/* Check for dot as (at least the first one) seperates hostname from TLD */
		if(*checkAsciiDomain=='.') dots++;
			else
			{
				/* Check for valid characters in domain name.
				 * Valid domain name can only contain ASCII alphabetic letters,
				 * digits (0-9) and hyphens ('-')
				 */
				isValid=(g_ascii_isalpha(*checkAsciiDomain) ||
							g_ascii_isdigit(*checkAsciiDomain) ||
							*checkAsciiDomain=='-');
			}

		checkAsciiDomain++;
	}

	/* If we have not reached the trimmed end of string something must have gone wrong 
	 * and domain entered is invalid. If domain name entered excluding dots is longer
	 * than 255 character it is also invalid.
	 */
	if(checkAsciiDomain<asciiDomainEnd) isValid=FALSE;
		else if((checkAsciiDomain-asciiDomainStart-dots)>255) isValid=FALSE;

	/* We need at least one dot in domain name (minimum number of dots to seperate
	 * hostname from TLD)
	 */
	isValid=(isValid && dots>0);

	/* Activate "add" button if hostname (equal to domain name here) is valid */
	gtk_widget_set_sensitive(priv->addDomainButton, isValid);

	/* Free allocated resources */
	g_free(asciiDomain);
}
示例#5
0
static void
get_request_headers (SoupMessage *req, GString *header,
		     SoupEncoding *encoding, gpointer user_data)
{
	SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (req);
	SoupMessageQueueItem *item = user_data;
	SoupURI *uri = soup_message_get_uri (req);
	char *uri_host;
	char *uri_string;
	SoupMessageHeadersIter iter;
	const char *name, *value;

	if (strchr (uri->host, ':'))
		uri_host = g_strdup_printf ("[%s]", uri->host);
	else if (g_hostname_is_non_ascii (uri->host))
		uri_host = g_hostname_to_ascii (uri->host);
	else
		uri_host = uri->host;

	if (req->method == SOUP_METHOD_CONNECT) {
		/* CONNECT URI is hostname:port for tunnel destination */
		uri_string = g_strdup_printf ("%s:%d", uri_host, uri->port);
	} else {
		gboolean proxy = soup_connection_is_via_proxy (item->conn);

		/* Proxy expects full URI to destination. Otherwise
		 * just the path.
		 */
		uri_string = soup_uri_to_string (uri, !proxy);

		if (proxy && uri->fragment) {
			/* Strip fragment */
			char *fragment = strchr (uri_string, '#');
			if (fragment)
				*fragment = '\0';
		}
	}

	if (priv->http_version == SOUP_HTTP_1_0) {
		g_string_append_printf (header, "%s %s HTTP/1.0\r\n",
					req->method, uri_string);
	} else {
		g_string_append_printf (header, "%s %s HTTP/1.1\r\n",
					req->method, uri_string);
		if (!soup_message_headers_get_one (req->request_headers, "Host")) {
			if (soup_uri_uses_default_port (uri)) {
				g_string_append_printf (header, "Host: %s\r\n",
							uri_host);
			} else {
				g_string_append_printf (header, "Host: %s:%d\r\n",
							uri_host, uri->port);
			}
		}
	}
	g_free (uri_string);
	if (uri_host != uri->host)
		g_free (uri_host);

	*encoding = soup_message_headers_get_encoding (req->request_headers);
	if ((*encoding == SOUP_ENCODING_CONTENT_LENGTH ||
	     *encoding == SOUP_ENCODING_NONE) &&
	    (req->request_body->length > 0 ||
	     soup_message_headers_get_one (req->request_headers, "Content-Type")) &&
	    !soup_message_headers_get_content_length (req->request_headers)) {
		*encoding = SOUP_ENCODING_CONTENT_LENGTH;
		soup_message_headers_set_content_length (req->request_headers,
							 req->request_body->length);
	}

	soup_message_headers_iter_init (&iter, req->request_headers);
	while (soup_message_headers_iter_next (&iter, &name, &value))
		g_string_append_printf (header, "%s: %s\r\n", name, value);
	g_string_append (header, "\r\n");
}