mirror of
https://github.com/netsurf-browser/netsurf
synced 2024-12-22 20:16:54 +03:00
[project @ 2006-02-23 15:06:53 by jmb]
Handle invalid SSL certificates better - UI still needs work. Modify fetch callback data parameter type to remove compiler warnings. Constify things. Lose global ssl_verify_certificates option. Fix issue when closing a dialog without input focus. svn path=/import/netsurf/; revision=2092
This commit is contained in:
parent
70fbf97688
commit
d4d3e5ee1c
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
154
content/certdb.c
Normal file
154
content/certdb.c
Normal file
@ -0,0 +1,154 @@
|
||||
/*
|
||||
* This file is part of NetSurf, http://netsurf.sourceforge.net/
|
||||
* Licensed under the GNU General Public License,
|
||||
* http://www.opensource.org/licenses/gpl-license
|
||||
* Copyright 2006 John M Bell <jmb202@ecs.soton.ac.uk>
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* HTTPS certificate verification database (implementation)
|
||||
*
|
||||
* URLs of servers with invalid SSL certificates are stored hashed by
|
||||
* canonical root URI (absoluteURI with no abs_path part - see RFC 2617)
|
||||
* for fast lookup.
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "netsurf/utils/config.h"
|
||||
#include "netsurf/content/certdb.h"
|
||||
#define NDEBUG
|
||||
#include "netsurf/utils/log.h"
|
||||
#include "netsurf/utils/url.h"
|
||||
|
||||
#define HASH_SIZE 77
|
||||
|
||||
#ifdef WITH_SSL
|
||||
|
||||
struct cert_entry {
|
||||
char *root_url; /**< Canonical root URL */
|
||||
struct cert_entry *next;
|
||||
};
|
||||
|
||||
static struct cert_entry *cert_table[HASH_SIZE];
|
||||
|
||||
static unsigned int certdb_hash(const char *s);
|
||||
static void certdb_dump(void);
|
||||
|
||||
/**
|
||||
* Insert an entry into the database
|
||||
*
|
||||
* \param url Absolute URL to resource
|
||||
* \return true on success, false on error.
|
||||
*/
|
||||
bool certdb_insert(const char *url)
|
||||
{
|
||||
char *canon;
|
||||
unsigned int hash;
|
||||
struct cert_entry *entry;
|
||||
url_func_result ret;
|
||||
|
||||
assert(url);
|
||||
|
||||
LOG(("Adding '%s'", url));
|
||||
|
||||
ret = url_canonical_root(url, &canon);
|
||||
if (ret != URL_FUNC_OK)
|
||||
return false;
|
||||
|
||||
LOG(("'%s'", canon));
|
||||
|
||||
hash = certdb_hash(canon);
|
||||
|
||||
/* Look for existing entry */
|
||||
for (entry = cert_table[hash]; entry; entry = entry->next) {
|
||||
if (strcmp(entry->root_url, canon) == 0) {
|
||||
free(canon);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/* not found => create new */
|
||||
entry = malloc(sizeof(struct cert_entry));
|
||||
if (!entry) {
|
||||
free(canon);
|
||||
return false;
|
||||
}
|
||||
|
||||
entry->root_url = canon;
|
||||
entry->next = cert_table[hash];
|
||||
cert_table[hash] = entry;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve certificate details for an URL from the database
|
||||
*
|
||||
* \param url Absolute URL to consider
|
||||
* \return certificate details, or NULL if none found.
|
||||
*/
|
||||
const char *certdb_get(const char *url)
|
||||
{
|
||||
char *canon;
|
||||
struct cert_entry *entry;
|
||||
url_func_result ret;
|
||||
|
||||
assert(url);
|
||||
|
||||
LOG(("Searching for '%s'", url));
|
||||
|
||||
certdb_dump();
|
||||
|
||||
ret = url_canonical_root(url, &canon);
|
||||
if (ret != URL_FUNC_OK)
|
||||
return NULL;
|
||||
|
||||
/* Find cert entry */
|
||||
for (entry = cert_table[certdb_hash(canon)]; entry;
|
||||
entry = entry->next) {
|
||||
if (strcmp(entry->root_url, canon) == 0) {
|
||||
free(canon);
|
||||
return entry->root_url;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hash function for keys.
|
||||
*/
|
||||
unsigned int certdb_hash(const char *s)
|
||||
{
|
||||
unsigned int i, z = 0, m;
|
||||
if (!s)
|
||||
return 0;
|
||||
|
||||
m = strlen(s);
|
||||
|
||||
for (i = 0; i != m && s[i]; i++)
|
||||
z += s[i] & 0x1f; /* lower 5 bits, case insensitive */
|
||||
return z % HASH_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dump contents of auth db to stderr
|
||||
*/
|
||||
void certdb_dump(void)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
int i;
|
||||
struct cert_entry *e;
|
||||
|
||||
for (i = 0; i != HASH_SIZE; i++) {
|
||||
LOG(("%d:", i));
|
||||
for (e = cert_table[i]; e; e = e->next) {
|
||||
LOG(("\t%s", e->root_url));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
18
content/certdb.h
Normal file
18
content/certdb.h
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* This file is part of NetSurf, http://netsurf.sourceforge.net/
|
||||
* Licensed under the GNU General Public License,
|
||||
* http://www.opensource.org/licenses/gpl-license
|
||||
* Copyright 2006 John M Bell <jmb202@ecs.soton.ac.uk>
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* HTTPS certificate verification database (interface)
|
||||
*/
|
||||
|
||||
#ifndef _NETSURF_CONTENT_CERTDB_H_
|
||||
#define _NETSURF_CONTENT_CERTDB_H_
|
||||
|
||||
bool certdb_insert(const char *url);
|
||||
const char *certdb_get(const char *url);
|
||||
|
||||
#endif
|
@ -139,6 +139,7 @@ struct cache_data;
|
||||
struct content;
|
||||
struct fetch;
|
||||
struct object_params;
|
||||
struct ssl_cert_info;
|
||||
|
||||
|
||||
/** Used in callbacks to indicate what has occurred. */
|
||||
@ -154,7 +155,10 @@ typedef enum {
|
||||
CONTENT_MSG_NEWPTR, /**< address of structure has changed */
|
||||
CONTENT_MSG_REFRESH, /**< wants refresh */
|
||||
#ifdef WITH_AUTH
|
||||
CONTENT_MSG_AUTH /**< authentication required */
|
||||
CONTENT_MSG_AUTH, /**< authentication required */
|
||||
#endif
|
||||
#ifdef WITH_SSL
|
||||
CONTENT_MSG_SSL /**< SSL cert verify failed */
|
||||
#endif
|
||||
} content_msg;
|
||||
|
||||
@ -175,8 +179,13 @@ union content_msg_data {
|
||||
/** Dimensions to plot object with. */
|
||||
float object_width, object_height;
|
||||
} redraw;
|
||||
char *auth_realm; /**< Realm, for CONTENT_MSG_AUTH. */
|
||||
const char *auth_realm; /**< Realm, for CONTENT_MSG_AUTH. */
|
||||
int delay; /**< Minimum delay, for CONTENT_MSG_REFRESH */
|
||||
struct {
|
||||
/** Certificate chain (certs[0] == server) */
|
||||
const struct ssl_cert_info *certs;
|
||||
unsigned long num; /**< Number of certs in chain */
|
||||
} ssl;
|
||||
};
|
||||
|
||||
/** Linked list of users of a content. */
|
||||
|
229
content/fetch.c
229
content/fetch.c
@ -31,9 +31,15 @@
|
||||
#endif
|
||||
#include "curl/curl.h"
|
||||
#include "netsurf/utils/config.h"
|
||||
#ifdef WITH_SSL
|
||||
#include "openssl/ssl.h"
|
||||
#endif
|
||||
#ifdef WITH_AUTH
|
||||
#include "netsurf/content/authdb.h"
|
||||
#endif
|
||||
#ifdef WITH_SSL
|
||||
#include "netsurf/content/certdb.h"
|
||||
#endif
|
||||
#include "netsurf/content/fetch.h"
|
||||
#include "netsurf/desktop/options.h"
|
||||
#include "netsurf/render/form.h"
|
||||
@ -46,10 +52,18 @@
|
||||
|
||||
bool fetch_active; /**< Fetches in progress, please call fetch_poll(). */
|
||||
|
||||
#ifdef WITH_SSL
|
||||
/** SSL certificate info */
|
||||
struct cert_info {
|
||||
X509 *cert; /**< Pointer to certificate */
|
||||
long err; /**< OpenSSL error code */
|
||||
};
|
||||
#endif
|
||||
|
||||
/** Information for a single fetch. */
|
||||
struct fetch {
|
||||
CURL * curl_handle; /**< cURL handle if being fetched, or 0. */
|
||||
void (*callback)(fetch_msg msg, void *p, const char *data,
|
||||
void (*callback)(fetch_msg msg, void *p, const void *data,
|
||||
unsigned long size);
|
||||
/**< Callback function. */
|
||||
bool had_headers; /**< Headers have been processed. */
|
||||
@ -70,6 +84,10 @@ struct fetch {
|
||||
struct cache_data cachedata; /**< Cache control data */
|
||||
time_t last_modified; /**< If-Modified-Since time */
|
||||
time_t file_etag; /**< ETag for local objects */
|
||||
#ifdef WITH_SSL
|
||||
#define MAX_CERTS 10
|
||||
struct cert_info cert_data[MAX_CERTS]; /**< HTTPS certificate data */
|
||||
#endif
|
||||
struct fetch *queue_prev; /**< Previous fetch for this host. */
|
||||
struct fetch *queue_next; /**< Next fetch for this host. */
|
||||
struct fetch *prev; /**< Previous active fetch in ::fetch_list. */
|
||||
@ -86,6 +104,9 @@ static char fetch_progress_buffer[256]; /**< Progress buffer for cURL */
|
||||
static char fetch_proxy_userpwd[100]; /**< Proxy authentication details. */
|
||||
|
||||
static CURLcode fetch_set_options(struct fetch *f);
|
||||
#ifdef WITH_SSL
|
||||
static CURLcode fetch_sslctxfun(CURL *curl_handle, SSL_CTX *sslctx, void *p);
|
||||
#endif
|
||||
static void fetch_free(struct fetch *f);
|
||||
static void fetch_stop(struct fetch *f);
|
||||
static void fetch_done(CURL *curl_handle, CURLcode result);
|
||||
@ -98,6 +119,10 @@ static size_t fetch_curl_header(char *data, size_t size, size_t nmemb,
|
||||
static bool fetch_process_headers(struct fetch *f);
|
||||
static struct curl_httppost *fetch_post_convert(
|
||||
struct form_successful_control *control);
|
||||
#ifdef WITH_SSL
|
||||
static int fetch_verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx);
|
||||
static int fetch_cert_verify_callback(X509_STORE_CTX *x509_ctx, void *parm);
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
@ -148,14 +173,6 @@ void fetch_init(void)
|
||||
if (option_ca_bundle)
|
||||
SETOPT(CURLOPT_CAINFO, option_ca_bundle);
|
||||
|
||||
if (!option_ssl_verify_certificates) {
|
||||
/* disable verification of SSL certificates.
|
||||
* security? we've heard of it...
|
||||
*/
|
||||
SETOPT(CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
SETOPT(CURLOPT_SSL_VERIFYHOST, 0L);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
curl_easy_setopt_failed:
|
||||
@ -207,7 +224,7 @@ void fetch_quit(void)
|
||||
*/
|
||||
|
||||
struct fetch * fetch_start(char *url, char *referer,
|
||||
void (*callback)(fetch_msg msg, void *p, const char *data,
|
||||
void (*callback)(fetch_msg msg, void *p, const void *data,
|
||||
unsigned long size),
|
||||
void *p, bool only_2xx, char *post_urlenc,
|
||||
struct form_successful_control *post_multipart, bool cookies,
|
||||
@ -288,6 +305,9 @@ struct fetch * fetch_start(char *url, char *referer,
|
||||
fetch->cachedata.last_modified = 0;
|
||||
fetch->last_modified = 0;
|
||||
fetch->file_etag = 0;
|
||||
#ifdef WITH_SSL
|
||||
memset(fetch->cert_data, 0, sizeof(fetch->cert_data));
|
||||
#endif
|
||||
fetch->queue_prev = 0;
|
||||
fetch->queue_next = 0;
|
||||
fetch->prev = 0;
|
||||
@ -473,10 +493,37 @@ CURLcode fetch_set_options(struct fetch *f)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WITH_SSL
|
||||
if (certdb_get(f->url) != NULL) {
|
||||
/* Disable certificate verification */
|
||||
SETOPT(CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
SETOPT(CURLOPT_SSL_VERIFYHOST, 0L);
|
||||
} else {
|
||||
/* do verification */
|
||||
SETOPT(CURLOPT_SSL_CTX_FUNCTION, fetch_sslctxfun);
|
||||
SETOPT(CURLOPT_SSL_CTX_DATA, f);
|
||||
}
|
||||
#endif
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
||||
#ifdef WITH_SSL
|
||||
/**
|
||||
* cURL SSL setup callback
|
||||
*/
|
||||
|
||||
CURLcode fetch_sslctxfun(CURL *curl_handle, SSL_CTX *sslctx, void *parm)
|
||||
{
|
||||
SSL_CTX_set_verify(sslctx, SSL_VERIFY_PEER, fetch_verify_callback);
|
||||
SSL_CTX_set_cert_verify_callback(sslctx, fetch_cert_verify_callback,
|
||||
parm);
|
||||
return CURLE_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Abort a fetch.
|
||||
*/
|
||||
@ -577,6 +624,10 @@ void fetch_stop(struct fetch *f)
|
||||
|
||||
void fetch_free(struct fetch *f)
|
||||
{
|
||||
#ifdef WITH_SSL
|
||||
int i;
|
||||
#endif
|
||||
|
||||
if (f->curl_handle)
|
||||
curl_easy_cleanup(f->curl_handle);
|
||||
free(f->url);
|
||||
@ -590,6 +641,15 @@ void fetch_free(struct fetch *f)
|
||||
if (f->post_multipart)
|
||||
curl_formfree(f->post_multipart);
|
||||
free(f->cachedata.etag);
|
||||
|
||||
#ifdef WITH_SSL
|
||||
for (i = 0; i < MAX_CERTS && f->cert_data[i].cert; i++) {
|
||||
f->cert_data[i].cert->references--;
|
||||
if (f->cert_data[i].cert->references == 0)
|
||||
X509_free(f->cert_data[i].cert);
|
||||
}
|
||||
#endif
|
||||
|
||||
free(f);
|
||||
}
|
||||
|
||||
@ -641,13 +701,20 @@ void fetch_done(CURL *curl_handle, CURLcode result)
|
||||
{
|
||||
bool finished = false;
|
||||
bool error = false;
|
||||
#ifdef WITH_SSL
|
||||
bool cert = false;
|
||||
#endif
|
||||
bool abort;
|
||||
struct fetch *f;
|
||||
void *p;
|
||||
void (*callback)(fetch_msg msg, void *p, const char *data,
|
||||
void (*callback)(fetch_msg msg, void *p, const void *data,
|
||||
unsigned long size);
|
||||
CURLcode code;
|
||||
struct cache_data cachedata;
|
||||
#ifdef WITH_SSL
|
||||
struct cert_info certs[MAX_CERTS];
|
||||
memset(certs, 0, sizeof(certs));
|
||||
#endif
|
||||
|
||||
/* find the structure associated with this fetch */
|
||||
code = curl_easy_getinfo(curl_handle, CURLINFO_PRIVATE, &f);
|
||||
@ -669,6 +736,14 @@ void fetch_done(CURL *curl_handle, CURLcode result)
|
||||
/* CURLE_WRITE_ERROR occurs when fetch_curl_data
|
||||
* returns 0, which we use to abort intentionally */
|
||||
;
|
||||
#ifdef WITH_SSL
|
||||
else if (result == CURLE_SSL_PEER_CERTIFICATE ||
|
||||
result == CURLE_SSL_CACERT) {
|
||||
memcpy(certs, f->cert_data, sizeof(certs));
|
||||
memset(f->cert_data, 0, sizeof(f->cert_data));
|
||||
cert = true;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
error = true;
|
||||
|
||||
@ -685,9 +760,91 @@ void fetch_done(CURL *curl_handle, CURLcode result)
|
||||
if (abort)
|
||||
; /* fetch was aborted: no callback */
|
||||
else if (finished) {
|
||||
callback(FETCH_FINISHED, p, (const char *)&cachedata, 0);
|
||||
callback(FETCH_FINISHED, p, &cachedata, 0);
|
||||
free(cachedata.etag);
|
||||
}
|
||||
#ifdef WITH_SSL
|
||||
else if (cert) {
|
||||
int i;
|
||||
BIO *mem;
|
||||
BUF_MEM *buf;
|
||||
struct ssl_cert_info ssl_certs[MAX_CERTS];
|
||||
|
||||
for (i = 0; i < MAX_CERTS && certs[i].cert; i++) {
|
||||
ssl_certs[i].version =
|
||||
X509_get_version(certs[i].cert);
|
||||
|
||||
mem = BIO_new(BIO_s_mem());
|
||||
ASN1_TIME_print(mem,
|
||||
X509_get_notBefore(certs[i].cert));
|
||||
BIO_get_mem_ptr(mem, &buf);
|
||||
BIO_set_close(mem, BIO_NOCLOSE);
|
||||
BIO_free(mem);
|
||||
snprintf(ssl_certs[i].not_before,
|
||||
min(sizeof ssl_certs[i].not_before,
|
||||
(unsigned) buf->length + 1),
|
||||
"%s", buf->data);
|
||||
BUF_MEM_free(buf);
|
||||
|
||||
mem = BIO_new(BIO_s_mem());
|
||||
ASN1_TIME_print(mem,
|
||||
X509_get_notAfter(certs[i].cert));
|
||||
BIO_get_mem_ptr(mem, &buf);
|
||||
BIO_set_close(mem, BIO_NOCLOSE);
|
||||
BIO_free(mem);
|
||||
snprintf(ssl_certs[i].not_after,
|
||||
min(sizeof ssl_certs[i].not_after,
|
||||
(unsigned) buf->length + 1),
|
||||
"%s", buf->data);
|
||||
BUF_MEM_free(buf);
|
||||
|
||||
ssl_certs[i].sig_type =
|
||||
X509_get_signature_type(certs[i].cert);
|
||||
ssl_certs[i].serial =
|
||||
ASN1_INTEGER_get(
|
||||
X509_get_serialNumber(certs[i].cert));
|
||||
mem = BIO_new(BIO_s_mem());
|
||||
X509_NAME_print_ex(mem,
|
||||
X509_get_issuer_name(certs[i].cert),
|
||||
0, XN_FLAG_SEP_CPLUS_SPC |
|
||||
XN_FLAG_DN_REV | XN_FLAG_FN_NONE);
|
||||
BIO_get_mem_ptr(mem, &buf);
|
||||
BIO_set_close(mem, BIO_NOCLOSE);
|
||||
BIO_free(mem);
|
||||
snprintf(ssl_certs[i].issuer,
|
||||
min(sizeof ssl_certs[i].issuer,
|
||||
(unsigned) buf->length + 1),
|
||||
"%s", buf->data);
|
||||
BUF_MEM_free(buf);
|
||||
|
||||
mem = BIO_new(BIO_s_mem());
|
||||
X509_NAME_print_ex(mem,
|
||||
X509_get_subject_name(certs[i].cert),
|
||||
0, XN_FLAG_SEP_CPLUS_SPC |
|
||||
XN_FLAG_DN_REV | XN_FLAG_FN_NONE);
|
||||
BIO_get_mem_ptr(mem, &buf);
|
||||
BIO_set_close(mem, BIO_NOCLOSE);
|
||||
BIO_free(mem);
|
||||
snprintf(ssl_certs[i].subject,
|
||||
min(sizeof ssl_certs[i].subject,
|
||||
(unsigned) buf->length + 1),
|
||||
"%s", buf->data);
|
||||
BUF_MEM_free(buf);
|
||||
|
||||
ssl_certs[i].cert_type =
|
||||
X509_certificate_type(certs[i].cert,
|
||||
X509_get_pubkey(certs[i].cert));
|
||||
|
||||
/* and clean up */
|
||||
certs[i].cert->references--;
|
||||
if (certs[i].cert->references == 0)
|
||||
X509_free(certs[i].cert);
|
||||
}
|
||||
|
||||
callback(FETCH_CERT_ERR, p, &ssl_certs, i);
|
||||
|
||||
}
|
||||
#endif
|
||||
else if (error)
|
||||
callback(FETCH_ERROR, p, fetch_error_buffer, 0);
|
||||
}
|
||||
@ -1096,7 +1253,7 @@ bool fetch_can_fetch(const char *url)
|
||||
*/
|
||||
|
||||
void fetch_change_callback(struct fetch *fetch,
|
||||
void (*callback)(fetch_msg msg, void *p, const char *data,
|
||||
void (*callback)(fetch_msg msg, void *p, const void *data,
|
||||
unsigned long size),
|
||||
void *p)
|
||||
{
|
||||
@ -1106,6 +1263,52 @@ void fetch_change_callback(struct fetch *fetch,
|
||||
}
|
||||
|
||||
|
||||
#ifdef WITH_SSL
|
||||
/**
|
||||
* OpenSSL Certificate verification callback
|
||||
* Stores certificate details in fetch struct.
|
||||
*/
|
||||
|
||||
int fetch_verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx)
|
||||
{
|
||||
X509 *cert = X509_STORE_CTX_get_current_cert(x509_ctx);
|
||||
int depth = X509_STORE_CTX_get_error_depth(x509_ctx);
|
||||
int err = X509_STORE_CTX_get_error(x509_ctx);
|
||||
struct fetch *f = X509_STORE_CTX_get_app_data(x509_ctx);
|
||||
|
||||
/* save the certificate by incrementing the reference count and
|
||||
* keeping a pointer */
|
||||
if (depth < MAX_CERTS && !f->cert_data[depth].cert) {
|
||||
f->cert_data[depth].cert = cert;
|
||||
f->cert_data[depth].err = err;
|
||||
cert->references++;
|
||||
}
|
||||
|
||||
return preverify_ok;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* OpenSSL certificate chain verification callback
|
||||
* Verifies certificate chain, setting up context for fetch_verify_callback
|
||||
*/
|
||||
|
||||
int fetch_cert_verify_callback(X509_STORE_CTX *x509_ctx, void *parm)
|
||||
{
|
||||
int ok;
|
||||
|
||||
/* Store fetch struct in context for verify callback */
|
||||
ok = X509_STORE_CTX_set_app_data(x509_ctx, parm);
|
||||
|
||||
/* and verify the certificate chain */
|
||||
if (ok)
|
||||
ok = X509_verify_cert(x509_ctx);
|
||||
|
||||
return ok;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* testing framework
|
||||
*/
|
||||
|
@ -25,7 +25,10 @@ typedef enum {
|
||||
FETCH_REDIRECT,
|
||||
FETCH_NOTMODIFIED,
|
||||
#ifdef WITH_AUTH
|
||||
FETCH_AUTH
|
||||
FETCH_AUTH,
|
||||
#endif
|
||||
#ifdef WITH_SSL
|
||||
FETCH_CERT_ERR,
|
||||
#endif
|
||||
} fetch_msg;
|
||||
|
||||
@ -46,12 +49,25 @@ struct cache_data {
|
||||
time_t last_modified; /**< Last-Modified: response header */
|
||||
};
|
||||
|
||||
#ifdef WITH_SSL
|
||||
struct ssl_cert_info {
|
||||
long version; /**< Certificate version */
|
||||
char not_before[32]; /**< Valid from date */
|
||||
char not_after[32]; /**< Valid to date */
|
||||
int sig_type; /**< Signature type */
|
||||
long serial; /**< Serial number */
|
||||
char issuer[256]; /**< Issuer details */
|
||||
char subject[256]; /**< Subject details */
|
||||
int cert_type; /**< Certificate type */
|
||||
};
|
||||
#endif
|
||||
|
||||
extern bool fetch_active;
|
||||
extern CURLM *fetch_curl_multi;
|
||||
|
||||
void fetch_init(void);
|
||||
struct fetch * fetch_start(char *url, char *referer,
|
||||
void (*callback)(fetch_msg msg, void *p, const char *data,
|
||||
void (*callback)(fetch_msg msg, void *p, const void *data,
|
||||
unsigned long size),
|
||||
void *p, bool only_2xx, char *post_urlenc,
|
||||
struct form_successful_control *post_multipart,
|
||||
@ -63,7 +79,7 @@ const char *fetch_filetype(const char *unix_path);
|
||||
char *fetch_mimetype(const char *ro_path);
|
||||
bool fetch_can_fetch(const char *url);
|
||||
void fetch_change_callback(struct fetch *fetch,
|
||||
void (*callback)(fetch_msg msg, void *p, const char *data,
|
||||
void (*callback)(fetch_msg msg, void *p, const void *data,
|
||||
unsigned long size),
|
||||
void *p);
|
||||
|
||||
|
@ -33,13 +33,13 @@
|
||||
|
||||
static char error_page[1000];
|
||||
static regex_t re_content_type;
|
||||
static void fetchcache_callback(fetch_msg msg, void *p, const char *data,
|
||||
static void fetchcache_callback(fetch_msg msg, void *p, const void *data,
|
||||
unsigned long size);
|
||||
static char *fetchcache_parse_type(const char *s, char **params[]);
|
||||
static void fetchcache_error_page(struct content *c, const char *error);
|
||||
static void fetchcache_cache_update(struct content *c,
|
||||
const struct cache_data *data);
|
||||
static void fetchcache_notmodified(struct content *c, const char *data);
|
||||
static void fetchcache_notmodified(struct content *c, const void *data);
|
||||
|
||||
|
||||
/**
|
||||
@ -307,7 +307,7 @@ void fetchcache_go(struct content *content, char *referer,
|
||||
* This is called when the status of a fetch changes.
|
||||
*/
|
||||
|
||||
void fetchcache_callback(fetch_msg msg, void *p, const char *data,
|
||||
void fetchcache_callback(fetch_msg msg, void *p, const void *data,
|
||||
unsigned long size)
|
||||
{
|
||||
bool res;
|
||||
@ -375,7 +375,7 @@ void fetchcache_callback(fetch_msg msg, void *p, const char *data,
|
||||
break;
|
||||
|
||||
case FETCH_ERROR:
|
||||
LOG(("FETCH_ERROR, '%s'", data));
|
||||
LOG(("FETCH_ERROR, '%s'", (const char *)data));
|
||||
c->fetch = 0;
|
||||
if (c->no_error_pages) {
|
||||
c->status = CONTENT_STATUS_ERROR;
|
||||
@ -425,7 +425,7 @@ void fetchcache_callback(fetch_msg msg, void *p, const char *data,
|
||||
#ifdef WITH_AUTH
|
||||
case FETCH_AUTH:
|
||||
/* data -> string containing the Realm */
|
||||
LOG(("FETCH_AUTH, '%s'", data));
|
||||
LOG(("FETCH_AUTH, '%s'", (const char *)data));
|
||||
c->fetch = 0;
|
||||
msg_data.auth_realm = data;
|
||||
content_broadcast(c, CONTENT_MSG_AUTH, msg_data);
|
||||
@ -434,6 +434,20 @@ void fetchcache_callback(fetch_msg msg, void *p, const char *data,
|
||||
c->status = CONTENT_STATUS_ERROR;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef WITH_SSL
|
||||
case FETCH_CERT_ERR:
|
||||
c->fetch = 0;
|
||||
/* set the status to ERROR so that the content is
|
||||
* destroyed in content_clean() */
|
||||
c->status = CONTENT_STATUS_ERROR;
|
||||
|
||||
msg_data.ssl.certs = data;
|
||||
msg_data.ssl.num = size;
|
||||
content_broadcast(c, CONTENT_MSG_SSL, msg_data);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
@ -597,7 +611,7 @@ void fetchcache_cache_update(struct content *c,
|
||||
* Not modified callback handler
|
||||
*/
|
||||
|
||||
void fetchcache_notmodified(struct content *c, const char *data)
|
||||
void fetchcache_notmodified(struct content *c, const void *data)
|
||||
{
|
||||
struct content *fb;
|
||||
union content_msg_data msg_data;
|
||||
|
@ -15,7 +15,7 @@
|
||||
#ifdef WITH_AUTH
|
||||
|
||||
void gui_401login_open(struct browser_window *bw, struct content *c,
|
||||
char *realm);
|
||||
const char *realm);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -60,7 +60,7 @@ static void browser_window_stop_throbber(struct browser_window *bw);
|
||||
static void browser_window_set_status(struct browser_window *bw,
|
||||
const char *text);
|
||||
static void browser_window_set_pointer(gui_pointer_shape shape);
|
||||
static void download_window_callback(fetch_msg msg, void *p, const char *data,
|
||||
static void download_window_callback(fetch_msg msg, void *p, const void *data,
|
||||
unsigned long size);
|
||||
static void browser_window_mouse_action_html(struct browser_window *bw,
|
||||
browser_mouse_state mouse, int x, int y);
|
||||
@ -429,6 +429,24 @@ void browser_window_callback(content_msg msg, struct content *c,
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef WITH_SSL
|
||||
case CONTENT_MSG_SSL:
|
||||
gui_cert_verify(bw, c, data.ssl.certs, data.ssl.num);
|
||||
if (c == bw->loading_content)
|
||||
bw->loading_content = 0;
|
||||
else if (c == bw->current_content) {
|
||||
bw->current_content = 0;
|
||||
bw->caret_callback = NULL;
|
||||
bw->paste_callback = NULL;
|
||||
bw->scrolling_box = NULL;
|
||||
selection_init(bw->sel, NULL);
|
||||
}
|
||||
browser_window_stop_throbber(bw);
|
||||
free(bw->referer);
|
||||
bw->referer = 0;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case CONTENT_MSG_REFRESH:
|
||||
schedule(data.delay * 100,
|
||||
browser_window_refresh, bw);
|
||||
@ -689,7 +707,7 @@ void browser_window_destroy(struct browser_window *bw)
|
||||
* Callback for fetch for download window fetches.
|
||||
*/
|
||||
|
||||
void download_window_callback(fetch_msg msg, void *p, const char *data,
|
||||
void download_window_callback(fetch_msg msg, void *p, const void *data,
|
||||
unsigned long size)
|
||||
{
|
||||
struct gui_download_window *download_window = p;
|
||||
@ -713,6 +731,9 @@ void download_window_callback(fetch_msg msg, void *p, const char *data,
|
||||
case FETCH_REDIRECT:
|
||||
case FETCH_NOTMODIFIED:
|
||||
case FETCH_AUTH:
|
||||
#ifdef WITH_SSL
|
||||
case FETCH_CERT_ERR:
|
||||
#endif
|
||||
default:
|
||||
/* not possible */
|
||||
assert(0);
|
||||
|
@ -38,6 +38,7 @@ typedef enum { GUI_POINTER_DEFAULT, GUI_POINTER_POINT, GUI_POINTER_CARET,
|
||||
GUI_POINTER_MOVE } gui_pointer_shape;
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "netsurf/utils/config.h"
|
||||
#include "netsurf/content/content.h"
|
||||
#include "netsurf/desktop/browser.h"
|
||||
|
||||
@ -106,5 +107,12 @@ bool gui_search_term_highlighted(struct gui_window *g,
|
||||
unsigned start_offset, unsigned end_offset,
|
||||
unsigned *start_idx, unsigned *end_idx);
|
||||
|
||||
#ifdef WITH_SSL
|
||||
struct ssl_cert_info;
|
||||
|
||||
void gui_cert_verify(struct browser_window *bw, struct content *c,
|
||||
const struct ssl_cert_info *certs, unsigned long num);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -54,8 +54,6 @@ int option_font_size = 100;
|
||||
int option_font_min_size = 70;
|
||||
/** Accept-Language header. */
|
||||
char *option_accept_language = 0;
|
||||
/** Enable verification of SSL certificates. */
|
||||
bool option_ssl_verify_certificates = true;
|
||||
/** Preferred maximum size of memory cache / bytes. */
|
||||
int option_memory_cache_size = 2 * 1024 * 1024;
|
||||
/** Preferred expiry age of disc cache / days. */
|
||||
@ -96,7 +94,6 @@ struct {
|
||||
{ "font_size", OPTION_INTEGER, &option_font_size },
|
||||
{ "font_min_size", OPTION_INTEGER, &option_font_min_size },
|
||||
{ "accept_language", OPTION_STRING, &option_accept_language },
|
||||
{ "ssl_verify_certificates", OPTION_BOOL, &option_ssl_verify_certificates },
|
||||
{ "memory_cache_size", OPTION_INTEGER, &option_memory_cache_size },
|
||||
{ "disc_cache_age", OPTION_INTEGER, &option_disc_cache_age },
|
||||
{ "block_advertisements", OPTION_BOOL, &option_block_ads },
|
||||
|
@ -38,7 +38,6 @@ extern char *option_http_proxy_auth_pass;
|
||||
extern int option_font_size;
|
||||
extern int option_font_min_size;
|
||||
extern char *option_accept_language;
|
||||
extern bool option_ssl_verify_certificates;
|
||||
extern int option_memory_cache_size;
|
||||
extern int option_disc_cache_age;
|
||||
extern bool option_block_ads;
|
||||
|
32
makefile
32
makefile
@ -17,8 +17,8 @@
|
||||
# "riscos", "riscos_small", "ncos", and "riscos_debug" can be compiled under
|
||||
# RISC OS, or cross-compiled using GCCSDK.
|
||||
|
||||
OBJECTS_COMMON = authdb.o content.o fetch.o fetchcache.o \
|
||||
url_store.o # content/
|
||||
OBJECTS_COMMON = authdb.o certdb.o content.o fetch.o \
|
||||
fetchcache.o url_store.o # content/
|
||||
OBJECTS_COMMON += css.o css_enum.o parser.o ruleset.o scanner.o # css/
|
||||
OBJECTS_COMMON += box.o box_construct.o box_normalise.o form.o \
|
||||
html.o html_redraw.o imagemap.o layout.o list.o \
|
||||
@ -38,13 +38,15 @@ OBJECTS_RISCOS += 401login.o artworks.o assert.o awrender.o bitmap.o \
|
||||
global_history.o gui.o help.o history.o hotlist.o image.o \
|
||||
menus.o message.o mouseactions.o plotters.o plugin.o print.o \
|
||||
query.o save.o save_complete.o save_draw.o save_text.o \
|
||||
schedule.o search.o sprite.o textselection.o theme.o \
|
||||
schedule.o search.o sprite.o sslcert.o textselection.o theme.o \
|
||||
theme_install.o thumbnail.o treeview.o ucstables.o uri.o \
|
||||
url_complete.o url_protocol.o wimp.o wimp_event.o window.o # riscos/
|
||||
OBJECTS_RISCOS += con_cache.o con_fonts.o con_home.o con_image.o \
|
||||
con_inter.o con_language.o con_memory.o con_theme.o # riscos/configure/
|
||||
# OBJECTS_RISCOS += memdebug.o
|
||||
|
||||
OBJECTS_RISCOS_SMALL = $(OBJECTS_RISCOS)
|
||||
|
||||
OBJECTS_NCOS = $(OBJECTS_RISCOS)
|
||||
|
||||
OBJECTS_DEBUG = $(OBJECTS_COMMON) $(OBJECTS_IMAGE)
|
||||
@ -69,6 +71,10 @@ OBJDIR_RISCOS = arm-riscos-aof
|
||||
SOURCES_RISCOS=$(OBJECTS_RISCOS:.o=.c)
|
||||
OBJS_RISCOS=$(OBJECTS_RISCOS:%.o=$(OBJDIR_RISCOS)/%.o)
|
||||
|
||||
OBJDIR_RISCOS_SMALL = arm-riscos-aof-small
|
||||
SOURCES_RISCOS_SMALL=$(OBJECTS_RISCOS_SMALL:.o=.c)
|
||||
OBJS_RISCOS_SMALL=$(OBJECTS_RISCOS_SMALL:%.o=$(OBJDIR_RISCOS_SMALL)/%.o)
|
||||
|
||||
OBJDIR_NCOS = arm-ncos-aof
|
||||
SOURCES_NCOS=$(OBJECTS_NCOS:.o=.c)
|
||||
OBJS_NCOS=$(OBJECTS_NCOS:%.o=$(OBJDIR_NCOS)/%.o)
|
||||
@ -106,6 +112,7 @@ WARNFLAGS = -W -Wall -Wundef -Wpointer-arith -Wcast-qual \
|
||||
CFLAGS_RISCOS = -std=c9x -D_BSD_SOURCE -Driscos -DBOOL_DEFINED -O \
|
||||
$(WARNFLAGS) -I.. $(PLATFORM_CFLAGS_RISCOS) -mpoke-function-name \
|
||||
# -include netsurf/utils/memdebug.h
|
||||
CFLAGS_RISCOS_SMALL = $(CFLAGS_RISCOS) -Dsmall
|
||||
CFLAGS_NCOS = $(CFLAGS_RISCOS) -Dncos
|
||||
CFLAGS_DEBUG = -std=c9x -D_BSD_SOURCE -Ddebug $(WARNFLAGS) -I.. \
|
||||
$(PLATFORM_CFLAGS_DEBUG) -g
|
||||
@ -114,6 +121,7 @@ CFLAGS_GTK = -std=c9x -D_BSD_SOURCE -D_POSIX_C_SOURCE -Dgtk \
|
||||
`pkg-config --cflags gtk+-2.0` `xml2-config --cflags`
|
||||
|
||||
AFLAGS_RISCOS = -I..,. $(PLATFORM_AFLAGS_RISCOS)
|
||||
AFLAGS_RISCOS_SMALL = $(AFLAGS_RISCOS) -Dsmall
|
||||
AFLAGS_NCOS = $(AFLAGS_RISCOS) -Dncos
|
||||
|
||||
# targets
|
||||
@ -121,7 +129,7 @@ riscos: $(RUNIMAGE)
|
||||
$(RUNIMAGE) : $(OBJS_RISCOS)
|
||||
$(CC) -o $@ $(LDFLAGS_RISCOS) $^
|
||||
riscos_small: u!RunImage,ff8
|
||||
u!RunImage,ff8 : $(OBJS_RISCOS)
|
||||
u!RunImage,ff8 : $(OBJS_RISCOS_SMALL)
|
||||
$(CC) -o $@ $(LDFLAGS_SMALL) $^
|
||||
|
||||
ncos: $(NCRUNIMAGE)
|
||||
@ -148,6 +156,9 @@ netsurf.zip: $(RUNIMAGE)
|
||||
$(OBJDIR_RISCOS)/%.o : %.c
|
||||
@echo "==> $<"
|
||||
@$(CC) -o $@ -c $(CFLAGS_RISCOS) $<
|
||||
$(OBJDIR_RISCOS_SMALL)/%.o : %.c
|
||||
@echo "==> $<"
|
||||
@$(CC) -o $@ -c $(CFLAGS_RISCOS_SMALL) $<
|
||||
$(OBJDIR_NCOS)/%.o : %.c
|
||||
@echo "==> $<"
|
||||
@$(CC) -o $@ -c $(CFLAGS_NCOS) $<
|
||||
@ -160,10 +171,13 @@ $(OBJDIR_GTK)/%.o : %.c
|
||||
|
||||
# pattern rules for asm source
|
||||
$(OBJDIR_RISCOS)/%.o : %.s
|
||||
@echo "== $<"
|
||||
@echo "==> $<"
|
||||
$(ASM) -o $@ -c $(AFLAGS_RISCOS) $<
|
||||
$(OBJDIR_RISCOS_SMALL)/%.o : %.s
|
||||
@echo "==> $<"
|
||||
$(ASM) -o $@ -c $(AFLAGS_RISCOS_SMALL) $<
|
||||
$(OBJDIR_NCOS)/%.o : %.s
|
||||
@echo "== $<"
|
||||
@echo "==> $<"
|
||||
$(ASM) -o $@ -c $(AFLAGS_NCOS) $<
|
||||
|
||||
# special cases
|
||||
@ -184,14 +198,14 @@ utils/translit.c: transtab
|
||||
depend: */*.[ch]
|
||||
@echo "--> modified files $?"
|
||||
@echo "--> updating dependencies"
|
||||
@-mkdir -p $(OBJDIR_RISCOS) $(OBJDIR_NCOS) $(OBJDIR_DEBUG) $(OBJDIR_GTK)
|
||||
@perl scandeps netsurf $(OBJDIR_RISCOS) $(OBJDIR_NCOS) $(OBJDIR_DEBUG) $(OBJDIR_GTK) -- $^ > depend
|
||||
@-mkdir -p $(OBJDIR_RISCOS) $(OBJDIR_RISCOS_SMALL) $(OBJDIR_NCOS) $(OBJDIR_DEBUG) $(OBJDIR_GTK)
|
||||
@perl scandeps netsurf $(OBJDIR_RISCOS) $(OBJDIR_RISCOS_SMALL) $(OBJDIR_NCOS) $(OBJDIR_DEBUG) $(OBJDIR_GTK) -- $^ > depend
|
||||
|
||||
include depend
|
||||
|
||||
# remove generated files
|
||||
clean:
|
||||
-rm $(OBJDIR_RISCOS)/* $(OBJDIR_NCOS)/* \
|
||||
-rm $(OBJDIR_RISCOS)/* $(OBJDIR_RISCOS_SMALL)/* $(OBJDIR_NCOS)/* \
|
||||
$(OBJDIR_DEBUG)/* $(OBJDIR_GTK)/* \
|
||||
css/css_enum.c css/css_enum.h \
|
||||
css/parser.c css/parser.h css/scanner.c css/scanner.h
|
||||
|
@ -852,6 +852,14 @@ void html_convert_css_callback(content_msg msg, struct content *css,
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef WITH_SSL
|
||||
case CONTENT_MSG_SSL:
|
||||
c->data.html.stylesheet_content[i] = 0;
|
||||
c->active--;
|
||||
content_add_error(c, "?", 0);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
@ -1127,6 +1135,14 @@ void html_object_callback(content_msg msg, struct content *object,
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef WITH_SSL
|
||||
case CONTENT_MSG_SSL:
|
||||
c->data.html.object[i].content = 0;
|
||||
c->active--;
|
||||
content_add_error(c, "?", 0);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case CONTENT_MSG_REFRESH:
|
||||
if (object->type == CONTENT_HTML)
|
||||
/* only for HTML objects */
|
||||
|
@ -28,8 +28,8 @@
|
||||
|
||||
static void ro_gui_401login_close(wimp_w w);
|
||||
static bool ro_gui_401login_apply(wimp_w w);
|
||||
static void ro_gui_401login_open(struct browser_window *bw, char *host,
|
||||
char *realm, char *fetchurl);
|
||||
static void ro_gui_401login_open(struct browser_window *bw, const char *host,
|
||||
const char *realm, const char *fetchurl);
|
||||
|
||||
|
||||
static wimp_window *dialog_401_template;
|
||||
@ -58,7 +58,7 @@ void ro_gui_401login_init(void)
|
||||
* Open the login dialog
|
||||
*/
|
||||
void gui_401login_open(struct browser_window *bw, struct content *c,
|
||||
char *realm)
|
||||
const char *realm)
|
||||
{
|
||||
char *murl, *host;
|
||||
url_func_result res;
|
||||
@ -77,8 +77,8 @@ void gui_401login_open(struct browser_window *bw, struct content *c,
|
||||
* Open a 401 login window.
|
||||
*/
|
||||
|
||||
void ro_gui_401login_open(struct browser_window *bw, char *host, char *realm,
|
||||
char *fetchurl)
|
||||
void ro_gui_401login_open(struct browser_window *bw, const char *host,
|
||||
const char *realm, const char *fetchurl)
|
||||
{
|
||||
struct session_401 *session;
|
||||
wimp_w w;
|
||||
|
@ -91,6 +91,11 @@ void ro_gui_dialog_init(void)
|
||||
ro_gui_401login_init();
|
||||
#endif
|
||||
|
||||
/* certificate verification window */
|
||||
#ifdef WITH_SSL
|
||||
ro_gui_cert_init();
|
||||
#endif
|
||||
|
||||
/* hotlist window */
|
||||
ro_gui_hotlist_initialise();
|
||||
|
||||
@ -353,6 +358,15 @@ void ro_gui_dialog_close(wimp_w close)
|
||||
wimp_caret caret;
|
||||
os_error *error;
|
||||
|
||||
/* Check if we're a persistent window */
|
||||
for (i = 0; i < MAX_PERSISTENT; i++) {
|
||||
if (persistent_dialog[i].dialog == close) {
|
||||
/* We are => invalidate record */
|
||||
persistent_dialog[i].dialog = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Give the caret back to the parent window. This code relies on
|
||||
the fact that only tree windows and browser windows open
|
||||
persistent dialogues, as the caret gets placed to no icon.
|
||||
@ -363,24 +377,18 @@ void ro_gui_dialog_close(wimp_w close)
|
||||
error->errnum, error->errmess));
|
||||
warn_user("WimpError", error->errmess);
|
||||
} else if (caret.w == close) {
|
||||
/* Check if we are a persistent window
|
||||
*/
|
||||
for (i = 0; i < MAX_PERSISTENT; i++) {
|
||||
if (persistent_dialog[i].dialog == close) {
|
||||
persistent_dialog[i].dialog = NULL;
|
||||
error = xwimp_set_caret_position(
|
||||
persistent_dialog[i].parent,
|
||||
wimp_ICON_WINDOW, -100, -100,
|
||||
32, -1);
|
||||
/* parent may have been closed first */
|
||||
if ((error) && (error->errnum != 0x287)) {
|
||||
LOG(("xwimp_set_caret_position: "
|
||||
"0x%x: %s",
|
||||
error->errnum,
|
||||
error->errmess));
|
||||
warn_user("WimpError", error->errmess);
|
||||
}
|
||||
break;
|
||||
/* Check if we are a persistent window */
|
||||
if (i < MAX_PERSISTENT) {
|
||||
error = xwimp_set_caret_position(
|
||||
persistent_dialog[i].parent,
|
||||
wimp_ICON_WINDOW, -100, -100,
|
||||
32, -1);
|
||||
/* parent may have been closed first */
|
||||
if ((error) && (error->errnum != 0x287)) {
|
||||
LOG(("xwimp_set_caret_position: 0x%x: %s",
|
||||
error->errnum,
|
||||
error->errmess));
|
||||
warn_user("WimpError", error->errmess);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -124,6 +124,11 @@ void ro_gui_mouse_action(struct gui_window *g);
|
||||
void ro_gui_401login_init(void);
|
||||
#endif
|
||||
|
||||
/* in sslcert.c */
|
||||
#ifdef WITH_SSL
|
||||
void ro_gui_cert_init(void);
|
||||
#endif
|
||||
|
||||
/* in window.c */
|
||||
void ro_gui_window_quit(void);
|
||||
void ro_gui_window_click(struct gui_window *g, wimp_pointer *mouse);
|
||||
@ -302,7 +307,7 @@ bool ro_gui_theme_install_apply(wimp_w w);
|
||||
#define ICON_SEARCH_CANCEL 4
|
||||
#define ICON_SEARCH_STATUS 5
|
||||
#define ICON_SEARCH_MENU 8
|
||||
#define ICON_SEARCH_SHOW_ALL 9
|
||||
#define ICON_SEARCH_SHOW_ALL 9
|
||||
|
||||
#define ICON_THEME_INSTALL_MESSAGE 0
|
||||
#define ICON_THEME_INSTALL_INSTALL 1
|
||||
|
@ -164,7 +164,7 @@ static void plugin_stream_free(struct plugin_stream *p);
|
||||
static bool plugin_start_fetch(struct plugin_stream *p, const char *url);
|
||||
static void plugin_stream_callback(content_msg msg, struct content *c,
|
||||
intptr_t p1, intptr_t p2, union content_msg_data data);
|
||||
static void plugin_fetch_callback(fetch_msg msg, void *p, const char *data,
|
||||
static void plugin_fetch_callback(fetch_msg msg, void *p, const void *data,
|
||||
unsigned long size);
|
||||
|
||||
/**
|
||||
@ -1707,6 +1707,12 @@ void plugin_stream_callback(content_msg msg, struct content *c,
|
||||
/* ignore this */
|
||||
break;
|
||||
|
||||
#ifdef WITH_SSL
|
||||
case CONTENT_MSG_SSL:
|
||||
plugin_destroy_stream(p, plugin_STREAM_DESTROY_ERROR);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case CONTENT_MSG_READY:
|
||||
case CONTENT_MSG_DONE:
|
||||
case CONTENT_MSG_REFORMAT:
|
||||
@ -1721,7 +1727,7 @@ void plugin_stream_callback(content_msg msg, struct content *c,
|
||||
/**
|
||||
* Callback for plugin fetch
|
||||
*/
|
||||
void plugin_fetch_callback(fetch_msg msg, void *p, const char *data,
|
||||
void plugin_fetch_callback(fetch_msg msg, void *p, const void *data,
|
||||
unsigned long size)
|
||||
{
|
||||
struct plugin_stream *s = p;
|
||||
@ -1754,6 +1760,9 @@ void plugin_fetch_callback(fetch_msg msg, void *p, const char *data,
|
||||
case FETCH_REDIRECT:
|
||||
case FETCH_NOTMODIFIED:
|
||||
case FETCH_AUTH:
|
||||
#ifdef WITH_SSL
|
||||
case FETCH_CERT_ERR:
|
||||
#endif
|
||||
default:
|
||||
/* not possible */
|
||||
assert(0);
|
||||
|
182
riscos/sslcert.c
Normal file
182
riscos/sslcert.c
Normal file
@ -0,0 +1,182 @@
|
||||
/*
|
||||
* This file is part of NetSurf, http://netsurf.sourceforge.net/
|
||||
* Licensed under the GNU General Public License,
|
||||
* http://www.opensource.org/licenses/gpl-license
|
||||
* Copyright 2006 John M Bell <jmb202@ecs.soton.ac.uk>
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* SSL Certificate verification UI (implementation)
|
||||
*/
|
||||
|
||||
#include "netsurf/utils/config.h"
|
||||
|
||||
#ifdef WITH_SSL
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "oslib/wimp.h"
|
||||
#include "netsurf/content/certdb.h"
|
||||
#include "netsurf/content/content.h"
|
||||
#include "netsurf/content/fetch.h"
|
||||
#include "netsurf/desktop/browser.h"
|
||||
#include "netsurf/desktop/gui.h"
|
||||
#include "netsurf/riscos/dialog.h"
|
||||
#include "netsurf/riscos/wimp_event.h"
|
||||
#include "netsurf/utils/log.h"
|
||||
#include "netsurf/utils/utils.h"
|
||||
|
||||
#define ICON_CERT_VERSION 1
|
||||
#define ICON_CERT_VALID_FROM 2
|
||||
#define ICON_CERT_TYPE 3
|
||||
#define ICON_CERT_VALID_TO 4
|
||||
#define ICON_CERT_SERIAL 5
|
||||
#define ICON_CERT_ISSUER 6
|
||||
#define ICON_CERT_SUBJECT 7
|
||||
#define ICON_CERT_REJECT 8
|
||||
#define ICON_CERT_ACCEPT 9
|
||||
|
||||
static wimp_window *dialog_cert_template;
|
||||
|
||||
struct session_cert {
|
||||
char version[16], valid_from[32], valid_to[32], type[8], serial[32],
|
||||
issuer[256], subject[256];
|
||||
char *url;
|
||||
struct browser_window *bw;
|
||||
};
|
||||
|
||||
static void ro_gui_cert_open(struct browser_window *bw, const char *url,
|
||||
const struct ssl_cert_info *certdata);
|
||||
static void ro_gui_cert_close(wimp_w w);
|
||||
static bool ro_gui_cert_apply(wimp_w w);
|
||||
|
||||
/**
|
||||
* Load the cert window template
|
||||
*/
|
||||
|
||||
void ro_gui_cert_init(void)
|
||||
{
|
||||
dialog_cert_template = ro_gui_dialog_load_template("sslcert");
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the certificate verification dialog
|
||||
*/
|
||||
|
||||
void gui_cert_verify(struct browser_window *bw, struct content *c,
|
||||
const struct ssl_cert_info *certs, unsigned long num)
|
||||
{
|
||||
assert(bw && c && certs);
|
||||
|
||||
/** \todo Display entire certificate chain */
|
||||
ro_gui_cert_open(bw, c->url, certs);
|
||||
}
|
||||
|
||||
void ro_gui_cert_open(struct browser_window *bw, const char *url,
|
||||
const struct ssl_cert_info *certdata)
|
||||
{
|
||||
struct session_cert *session;
|
||||
wimp_w w;
|
||||
|
||||
session = malloc(sizeof(struct session_cert));
|
||||
if (!session) {
|
||||
warn_user("NoMemory", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
session->url = strdup(url);
|
||||
if (!session->url) {
|
||||
free(session);
|
||||
warn_user("NoMemory", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
session->bw = bw;
|
||||
|
||||
snprintf(session->version, sizeof session->version, "%ld",
|
||||
certdata->version);
|
||||
snprintf(session->valid_from, sizeof session->valid_from, "%s",
|
||||
certdata->not_before);
|
||||
snprintf(session->type, sizeof session->type, "%d",
|
||||
certdata->cert_type);
|
||||
snprintf(session->valid_to, sizeof session->valid_to, "%s",
|
||||
certdata->not_after);
|
||||
snprintf(session->serial, sizeof session->serial, "%ld",
|
||||
certdata->serial);
|
||||
snprintf(session->issuer, sizeof session->issuer, "%s",
|
||||
certdata->issuer);
|
||||
snprintf(session->subject, sizeof session->subject, "%s",
|
||||
certdata->subject);
|
||||
|
||||
dialog_cert_template->icons[ICON_CERT_VERSION].data.indirected_text.text = session->version;
|
||||
dialog_cert_template->icons[ICON_CERT_VERSION].data.indirected_text.size = strlen(session->version) + 1;
|
||||
dialog_cert_template->icons[ICON_CERT_VALID_FROM].data.indirected_text.text = session->valid_from;
|
||||
dialog_cert_template->icons[ICON_CERT_VALID_FROM].data.indirected_text.size = strlen(session->valid_from) + 1;
|
||||
dialog_cert_template->icons[ICON_CERT_TYPE].data.indirected_text.text = session->type;
|
||||
dialog_cert_template->icons[ICON_CERT_TYPE].data.indirected_text.size = strlen(session->type) + 1;
|
||||
dialog_cert_template->icons[ICON_CERT_VALID_TO].data.indirected_text.text = session->valid_to;
|
||||
dialog_cert_template->icons[ICON_CERT_VALID_TO].data.indirected_text.size = strlen(session->valid_to) + 1;
|
||||
dialog_cert_template->icons[ICON_CERT_SERIAL].data.indirected_text.text = session->serial;
|
||||
dialog_cert_template->icons[ICON_CERT_SERIAL].data.indirected_text.size = strlen(session->serial) + 1;
|
||||
dialog_cert_template->icons[ICON_CERT_ISSUER].data.indirected_text.text = session->issuer;
|
||||
dialog_cert_template->icons[ICON_CERT_ISSUER].data.indirected_text.size = strlen(session->issuer) + 1;
|
||||
dialog_cert_template->icons[ICON_CERT_SUBJECT].data.indirected_text.text = session->subject;
|
||||
dialog_cert_template->icons[ICON_CERT_SUBJECT].data.indirected_text.size = strlen(session->subject) + 1;
|
||||
|
||||
w = wimp_create_window(dialog_cert_template);
|
||||
|
||||
ro_gui_wimp_event_register_cancel(w, ICON_CERT_REJECT);
|
||||
ro_gui_wimp_event_register_ok(w, ICON_CERT_ACCEPT, ro_gui_cert_apply);
|
||||
ro_gui_wimp_event_register_close_window(w, ro_gui_cert_close);
|
||||
ro_gui_wimp_event_set_user_data(w, session);
|
||||
|
||||
ro_gui_dialog_open_persistent(bw->window->window, w, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle closing of certificate verification dialog
|
||||
*/
|
||||
void ro_gui_cert_close(wimp_w w)
|
||||
{
|
||||
os_error *error;
|
||||
struct session_cert *session;
|
||||
|
||||
session = (struct session_cert *)ro_gui_wimp_event_get_user_data(w);
|
||||
|
||||
assert(session);
|
||||
|
||||
free(session->url);
|
||||
free(session);
|
||||
|
||||
ro_gui_wimp_event_finalise(w);
|
||||
|
||||
error = xwimp_delete_window(w);
|
||||
if (error)
|
||||
LOG(("xwimp_delete_window: 0x%x: %s",
|
||||
error->errnum, error->errmess));
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle acceptance of certificate
|
||||
*/
|
||||
bool ro_gui_cert_apply(wimp_w w)
|
||||
{
|
||||
struct session_cert *session;
|
||||
|
||||
session = (struct session_cert *)ro_gui_wimp_event_get_user_data(w);
|
||||
|
||||
assert(session);
|
||||
|
||||
if (!certdb_insert(session->url)) {
|
||||
LOG(("certdb_insert failed"));
|
||||
return false;
|
||||
}
|
||||
|
||||
browser_window_go(session->bw, session->url, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
@ -22,6 +22,11 @@
|
||||
/* Cookies */
|
||||
#define WITH_COOKIES
|
||||
|
||||
/* SSL */
|
||||
#if !defined(small)
|
||||
#define WITH_SSL
|
||||
#endif
|
||||
|
||||
/* Image renderering modules */
|
||||
#define WITH_JPEG
|
||||
#define WITH_MNG
|
||||
|
Loading…
Reference in New Issue
Block a user