summaryrefslogtreecommitdiff
path: root/riscos/sslcert.c
diff options
context:
space:
mode:
Diffstat (limited to 'riscos/sslcert.c')
-rw-r--r--riscos/sslcert.c515
1 files changed, 206 insertions, 309 deletions
diff --git a/riscos/sslcert.c b/riscos/sslcert.c
index 5c77f31d5..990c2501c 100644
--- a/riscos/sslcert.c
+++ b/riscos/sslcert.c
@@ -1,5 +1,6 @@
/*
* Copyright 2006 John M Bell <jmb202@ecs.soton.ac.uk>
+ * Copyright 2010 Stephen Fryatt <stevef@netsurf-browser.org>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -32,9 +33,11 @@
#include "content/fetch.h"
#include "content/urldb.h"
#include "desktop/browser.h"
+#include "desktop/sslcert.h"
#include "desktop/gui.h"
#include "desktop/tree.h"
#include "riscos/dialog.h"
+#include "riscos/sslcert.h"
#include "riscos/textarea.h"
#include "riscos/treeview.h"
#include "riscos/wimp.h"
@@ -47,50 +50,36 @@
#define ICON_SSL_REJECT 3
#define ICON_SSL_ACCEPT 4
-#define ICON_CERT_VERSION 3
-#define ICON_CERT_VALID_FROM 5
-#define ICON_CERT_TYPE 7
-#define ICON_CERT_VALID_TO 9
-#define ICON_CERT_SERIAL 11
-#define ICON_CERT_ISSUER 13
-#define ICON_CERT_SUBJECT 15
-
-static wimp_window *dialog_tree_template;
-static wimp_window *dialog_cert_template;
-static wimp_window *dialog_display_template;
-
-struct session_data {
- struct session_cert *certs;
- unsigned long num;
- char *url;
- struct tree *tree;
-
- nserror (*cb)(bool proceed, void *pw);
- void *cbpw;
-};
-struct session_cert {
- char version[16], valid_from[32], valid_to[32], type[8], serial[32];
- char *issuer_t;
- char *subject_t;
- uintptr_t issuer;
- uintptr_t subject;
+static wimp_window *ro_gui_cert_dialog_template;
+static wimp_window *ro_gui_cert_tree_template;
+
+struct ro_sslcert
+{
+ wimp_w window;
+ wimp_w pane;
+ ro_treeview *tv;
+ struct sslcert_session_data *data;
};
-static bool ro_gui_cert_click(wimp_pointer *pointer);
-static void ro_gui_cert_close(wimp_w w);
-static bool ro_gui_cert_apply(wimp_w w);
+static void ro_gui_cert_accept(wimp_pointer *pointer);
+static void ro_gui_cert_reject(wimp_pointer *pointer);
+static void ro_gui_cert_close_window(wimp_w w);
+static void ro_gui_cert_release_window(struct ro_sslcert *s);
/**
- * Load the cert window template
+ * Load and initialise the certificate window template
*/
-void ro_gui_cert_init(void)
+void ro_gui_cert_preinitialise(void)
{
- dialog_tree_template = ro_gui_dialog_load_template("tree");
- dialog_cert_template = ro_gui_dialog_load_template("sslcert");
- dialog_display_template = ro_gui_dialog_load_template("ssldisplay");
+ /* Load templates for the SSL windows and adjust the tree window
+ * flags to suit.
+ */
+
+ ro_gui_cert_dialog_template = ro_gui_dialog_load_template("sslcert");
+ ro_gui_cert_tree_template = ro_gui_dialog_load_template("tree");
- dialog_tree_template->flags &= ~(wimp_WINDOW_MOVEABLE |
+ ro_gui_cert_tree_template->flags &= ~(wimp_WINDOW_MOVEABLE |
wimp_WINDOW_BACK_ICON |
wimp_WINDOW_CLOSE_ICON |
wimp_WINDOW_TITLE_ICON |
@@ -99,169 +88,169 @@ void ro_gui_cert_init(void)
}
/**
+ * Load and initialise the certificate window template
+ */
+
+void ro_gui_cert_postinitialise(void)
+{
+ /* Initialise the SSL module. */
+
+ sslcert_init();
+}
+
+/**
* Open the certificate verification dialog
+ *
+ * \param *bw The browser window owning the certificates.
+ * \param *c The content data corresponding to the
+ * certificates.
+ * \param *certs The certificate details.
+ * \param num The number of certificates included.
*/
void gui_cert_verify(const char *url,
const struct ssl_cert_info *certs, unsigned long num,
nserror (*cb)(bool proceed, void *pw), void *cbpw)
{
- wimp_w w;
- wimp_w ssl_w;
- const struct ssl_cert_info *from;
- struct session_cert *to;
- struct session_data *data;
- struct tree *tree;
- struct node *node;
- wimp_window_state state;
- wimp_icon_state istate;
- os_error *error;
- long i;
+ struct ro_sslcert *sslcert_window;
+ wimp_window_state state;
+ wimp_icon_state istate;
+ wimp_window_info info;
+ os_error *error;
+ bool set_extent;
assert(certs);
- /* copy the certificate information */
- data = calloc(1, sizeof(struct session_data));
- if (!data) {
- warn_user("NoMemory", 0);
+ sslcert_window = malloc(sizeof(struct ro_sslcert));
+ if (sslcert_window == NULL) {
+ LOG(("Failed to allocate memory for SSL Cert Dialog"));
return;
}
- data->url = strdup(url);
- if (!data->url) {
- free(data);
- warn_user("NoMemory", 0);
- return;
- }
- data->cb = cb;
- data->cbpw = cbpw;
- data->num = num;
- data->certs = calloc(num, sizeof(struct session_cert));
- if (!data->certs) {
- free(data->url);
- free(data);
- warn_user("NoMemory", 0);
- return;
- }
- for (i = 0; i < (long)num; i++) {
- to = &data->certs[i];
- from = &certs[i];
- to->subject_t = strdup(from->subject);
- to->issuer_t = strdup(from->issuer);
- if ((!to->subject_t) || (!to->issuer_t)) {
- for (; i >= 0; i--) {
- to = &data->certs[i];
- free(to->subject_t);
- free(to->issuer_t);
- }
- free(data->certs);
- free(data->url);
- free(data);
- warn_user("NoMemory", 0);
- return;
- }
- snprintf(to->version, sizeof data->certs->version, "%ld",
- from->version);
- snprintf(to->valid_from, sizeof data->certs->valid_from, "%s",
- from->not_before);
- snprintf(to->type, sizeof data->certs->type, "%d",
- from->cert_type);
- snprintf(to->valid_to, sizeof data->certs->valid_to, "%s",
- from->not_after);
- snprintf(to->serial, sizeof data->certs->serial, "%ld",
- from->serial);
- }
- /* create the SSL window */
- error = xwimp_create_window(dialog_cert_template, &ssl_w);
+ /* Create the SSL window and its pane. */
+
+ error = xwimp_create_window(ro_gui_cert_dialog_template,
+ &(sslcert_window->window));
if (error) {
- free(data->certs);
- free(data->url);
- free(data);
LOG(("xwimp_create_window: 0x%x: %s",
error->errnum, error->errmess));
+ free(sslcert_window);
return;
}
- /* automated SSL window event handling */
- ro_gui_wimp_event_set_user_data(ssl_w, data);
- ro_gui_wimp_event_register_cancel(ssl_w, ICON_SSL_REJECT);
- ro_gui_wimp_event_register_ok(ssl_w, ICON_SSL_ACCEPT, ro_gui_cert_apply);
- ro_gui_dialog_open_persistent(NULL, ssl_w, false);
-
- /* create a tree window (styled as a list) */
- error = xwimp_create_window(dialog_tree_template, &w);
+ error = xwimp_create_window(ro_gui_cert_tree_template,
+ &(sslcert_window->pane));
if (error) {
- ro_gui_cert_close(ssl_w);
LOG(("xwimp_create_window: 0x%x: %s",
error->errnum, error->errmess));
+ free(sslcert_window);
return;
}
- tree = calloc(sizeof(struct tree), 1);
- if (!tree) {
- ro_gui_cert_close(ssl_w);
- warn_user("NoMemory", 0);
+
+ /* Create the SSL data and build a tree from it. */
+
+ sslcert_window->tv = ro_treeview_create(sslcert_window->pane, NULL,
+ sslcert_get_tree_flags());
+ if (sslcert_window->tv == NULL) {
+ LOG(("Failed to allocate treeview"));
+ free(sslcert_window);
return;
}
- tree->root = tree_create_folder_node(NULL, "Root");
- if (!tree->root) {
- ro_gui_cert_close(ssl_w);
- warn_user("NoMemory", 0);
- free(tree);
- tree = NULL;
+
+ sslcert_window->data = sslcert_create_session_data(num, url, cb, cbpw);
+ sslcert_load_tree(ro_treeview_get_tree(sslcert_window->tv),
+ certs, sslcert_window->data);
+
+ tree_set_redraw(ro_treeview_get_tree(sslcert_window->tv), true);
+
+ /* Set up the certificate window event handling.
+ *
+ * (The action buttons are registered as button events, not OK and
+ * Cancel, as both need to carry out actions.)
+ */
+
+ ro_gui_wimp_event_set_user_data(sslcert_window->window, sslcert_window);
+ ro_gui_wimp_event_register_close_window(sslcert_window->window,
+ ro_gui_cert_close_window);
+ ro_gui_wimp_event_register_button(sslcert_window->window,
+ ICON_SSL_REJECT, ro_gui_cert_reject);
+ ro_gui_wimp_event_register_button(sslcert_window->window,
+ ICON_SSL_ACCEPT, ro_gui_cert_accept);
+
+ ro_gui_dialog_open_persistent(NULL, sslcert_window->window, false);
+
+ /* Nest the tree window inside the pane window. To do this, we:
+ * - Get the current pane extent,
+ * - Get the parent window position and the location of the pane-
+ * locating icon inside it,
+ * - Set the visible area of the pane to suit,
+ * - Check that the pane extents are OK for this visible area, and
+ * increase them if necessary,
+ * - Before finally opening the pane as a nested part of the parent.
+ */
+
+ info.w = sslcert_window->pane;
+ error = xwimp_get_window_info_header_only(&info);
+ if (error) {
+ ro_gui_cert_release_window(sslcert_window);
+ LOG(("xwimp_get_window_info: 0x%x: %s",
+ error->errnum, error->errmess));
return;
}
- tree->root->expanded = true;
- tree->handle = (int)w;
- tree->movable = false;
- tree->no_drag = true;
- tree->no_vscroll = true;
- tree->no_furniture = true;
- tree->single_selection = true;
- data->tree = tree;
-
- /* put the SSL names in the tree */
- for (i = 0; i < (long)num; i++) {
- node = tree_create_leaf_node(tree->root, certs[i].subject);
- if (node) {
- node->data.data = TREE_ELEMENT_SSL;
- tree_set_node_sprite(node, "small_xxx", "small_xxx");
- }
- }
-
- /* automated treeview event handling */
- ro_gui_wimp_event_set_user_data(w, tree);
- ro_gui_wimp_event_register_keypress(w, ro_gui_tree_keypress);
- ro_gui_wimp_event_register_redraw_window(w, ro_gui_tree_redraw);
- ro_gui_wimp_event_register_open_window(w, ro_gui_tree_open);
- ro_gui_wimp_event_register_close_window(w, ro_gui_wimp_event_finalise);
- ro_gui_wimp_event_register_mouse_click(w, ro_gui_cert_click);
- /* nest the tree window inside the pane window */
- state.w = ssl_w;
+ state.w = sslcert_window->window;
error = xwimp_get_window_state(&state);
if (error) {
- ro_gui_cert_close(ssl_w);
+ ro_gui_cert_release_window(sslcert_window);
LOG(("xwimp_get_window_state: 0x%x: %s",
error->errnum, error->errmess));
return;
}
- istate.w = ssl_w;
+ istate.w = sslcert_window->window;
istate.i = ICON_SSL_PANE;
error = xwimp_get_icon_state(&istate);
if (error) {
- ro_gui_cert_close(ssl_w);
+ ro_gui_cert_release_window(sslcert_window);
LOG(("xwimp_get_icon_state: 0x%x: %s",
error->errnum, error->errmess));
return;
}
- state.w = w;
+
+ state.w = sslcert_window->pane;
state.visible.x1 = state.visible.x0 + istate.icon.extent.x1 - 20 -
- ro_get_vscroll_width(w);
+ ro_get_vscroll_width(sslcert_window->pane);
state.visible.x0 += istate.icon.extent.x0 + 20;
state.visible.y0 = state.visible.y1 + istate.icon.extent.y0 + 20;
state.visible.y1 += istate.icon.extent.y1 - 32;
- error = xwimp_open_window_nested(PTR_WIMP_OPEN(&state), ssl_w,
+
+ set_extent = false;
+
+ if ((info.extent.x1 - info.extent.x0) <
+ (state.visible.x1 - state.visible.x0)) {
+ info.extent.x0 = 0;
+ info.extent.x1 = state.visible.x1 - state.visible.x0;
+ set_extent = true;
+ }
+ if ((info.extent.y1 - info.extent.y0) <
+ (state.visible.y1 - state.visible.y0)) {
+ info.extent.y1 = 0;
+ info.extent.x1 = state.visible.y0 - state.visible.y1;
+ set_extent = true;
+ }
+
+ if (set_extent) {
+ error = xwimp_set_extent(sslcert_window->pane, &(info.extent));
+ if (error) {
+ ro_gui_cert_release_window(sslcert_window);
+ LOG(("xwimp_set_extent: 0x%x: %s",
+ error->errnum, error->errmess));
+ return;
+ }
+ }
+
+ error = xwimp_open_window_nested(PTR_WIMP_OPEN(&state),
+ sslcert_window->window,
wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT
<< wimp_CHILD_XORIGIN_SHIFT |
wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT
@@ -271,192 +260,100 @@ void gui_cert_verify(const char *url,
wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT
<< wimp_CHILD_RS_EDGE_SHIFT);
if (error) {
- ro_gui_cert_close(ssl_w);
+ ro_gui_cert_release_window(sslcert_window);
LOG(("xwimp_open_window_nested: 0x%x: %s",
error->errnum, error->errmess));
+ ro_gui_cert_release_window(sslcert_window);
return;
}
- tree_initialise(tree);
}
-void ro_gui_cert_open(struct tree *tree, struct node *node)
-{
- struct node *n;
- struct session_data *data;
- struct session_cert *session;
- wimp_window_state state;
- wimp_w child;
- wimp_w parent;
- wimp_w w;
- unsigned long i;
- os_error *error;
-
- assert(tree->root);
+/**
+ * Handle acceptance of certificate via event callback.
+ *
+ * \param *pointer The wimp pointer block.
+ */
- /* firstly we need to get our node index in the list */
- for (n = tree->root->child, i = 0; n; i++, n = n->next)
- if (n == node)
- break;
- assert(n);
+void ro_gui_cert_accept(wimp_pointer *pointer)
+{
+ struct ro_sslcert *s;
- /* now we get the handle of our list window */
- child = (wimp_w)tree->handle;
- assert(child);
+ s = (struct ro_sslcert *) ro_gui_wimp_event_get_user_data(pointer->w);
- /* now we can get the linked parent handle */
- state.w = child;
- error = xwimp_get_window_state_and_nesting(&state, &parent, 0);
- if (error) {
- LOG(("xwimp_get_window_state: 0x%x: %s",
- error->errnum, error->errmess));
- warn_user("WimpError", error->errmess);
- return;
- }
- assert(parent);
-
- /* from this we can get our session data */
- data = (struct session_data *)ro_gui_wimp_event_get_user_data(parent);
- assert(data);
- assert(data->tree == tree);
-
- /* and finally the nodes session certificate data */
- session = &data->certs[i];
- assert(session);
-
- dialog_display_template->icons[ICON_CERT_VERSION].data.indirected_text.text = session->version;
- dialog_display_template->icons[ICON_CERT_VERSION].data.indirected_text.size = strlen(session->version) + 1;
- dialog_display_template->icons[ICON_CERT_VALID_FROM].data.indirected_text.text = session->valid_from;
- dialog_display_template->icons[ICON_CERT_VALID_FROM].data.indirected_text.size = strlen(session->valid_from) + 1;
- dialog_display_template->icons[ICON_CERT_TYPE].data.indirected_text.text = session->type;
- dialog_display_template->icons[ICON_CERT_TYPE].data.indirected_text.size = strlen(session->type) + 1;
- dialog_display_template->icons[ICON_CERT_VALID_TO].data.indirected_text.text = session->valid_to;
- dialog_display_template->icons[ICON_CERT_VALID_TO].data.indirected_text.size = strlen(session->valid_to) + 1;
- dialog_display_template->icons[ICON_CERT_SERIAL].data.indirected_text.text = session->serial;
- dialog_display_template->icons[ICON_CERT_SERIAL].data.indirected_text.size = strlen(session->serial) + 1;
-
- error = xwimp_create_window(dialog_display_template, &w);
- if (error) {
- LOG(("xwimp_create_window: 0x%x: %s",
- error->errnum, error->errmess));
- free(session);
- warn_user("MiscError", error->errmess);
- return;
+ if (s != NULL) {
+ sslcert_accept(s->data);
+ ro_gui_dialog_close(s->window);
+ ro_gui_cert_release_window(s);
}
- if (session->issuer)
- ro_textarea_destroy(session->issuer);
- session->issuer = ro_textarea_create(w, ICON_CERT_ISSUER,
- TEXTAREA_MULTILINE | TEXTAREA_READONLY,
- ro_gui_desktop_font_family, ro_gui_desktop_font_size,
- ro_gui_desktop_font_style);
- if (!session->issuer) {
- xwimp_delete_window(w);
- warn_user("NoMemory", 0);
- return;
- }
- if (!ro_textarea_set_text(session->issuer, session->issuer_t)) {
- ro_textarea_destroy(session->issuer);
- xwimp_delete_window(w);
- warn_user("NoMemory", 0);
- return;
- }
-
- if (session->subject)
- ro_textarea_destroy(session->subject);
- session->subject = ro_textarea_create(w, ICON_CERT_SUBJECT,
- TEXTAREA_MULTILINE | TEXTAREA_READONLY,
- ro_gui_desktop_font_family, ro_gui_desktop_font_size,
- ro_gui_desktop_font_style);
- if (!session->subject) {
- ro_textarea_destroy(session->issuer);
- xwimp_delete_window(w);
- warn_user("NoMemory", 0);
- return;
- }
- if (!ro_textarea_set_text(session->subject, session->subject_t)) {
- ro_textarea_destroy(session->subject);
- ro_textarea_destroy(session->issuer);
- xwimp_delete_window(w);
- warn_user("NoMemory", 0);
- return;
- }
- ro_gui_wimp_event_register_close_window(w, ro_gui_wimp_event_finalise);
- ro_gui_dialog_open_persistent(parent, w, false);
}
/**
- * Handle closing of certificate verification dialog
+ * Handle rejection of certificate via event callback.
+ *
+ * \param w The wimp pointer block.
*/
-void ro_gui_cert_close(wimp_w w)
-{
- struct session_data *data;
- os_error *error;
- unsigned long i;
- data = (struct session_data *)ro_gui_wimp_event_get_user_data(w);
- assert(data);
+void ro_gui_cert_reject(wimp_pointer *pointer)
+{
+ struct ro_sslcert *s;
- /* If we didn't accept the certificate, send failure response */
- if (data->cb != NULL)
- data->cb(false, data->cbpw);
+ s = (struct ro_sslcert *) ro_gui_wimp_event_get_user_data(pointer->w);
- for (i = 0; i < data->num; i++) {
- if (data->certs[i].subject)
- ro_textarea_destroy(data->certs[i].subject);
- if (data->certs[i].issuer)
- ro_textarea_destroy(data->certs[i].issuer);
- }
- free(data->certs);
- free(data->url);
- if (data->tree) {
- tree_delete_node(data->tree, data->tree->root, false);
- ro_gui_dialog_close((wimp_w)data->tree->handle);
- error = xwimp_delete_window((wimp_w)data->tree->handle);
- if (error) {
- LOG(("xwimp_delete_window: 0x%x:%s",
- error->errnum, error->errmess));
- warn_user("WimpError", error->errmess);
- }
- ro_gui_wimp_event_finalise((wimp_w)data->tree->handle);
- free(data->tree);
+ if (s != NULL) {
+ sslcert_reject(s->data);
+ ro_gui_dialog_close(s->window);
+ ro_gui_cert_release_window(s);
}
- free(data);
+}
- ro_gui_dialog_close(w);
- error = xwimp_delete_window(w);
- if (error) {
- LOG(("xwimp_delete_window: 0x%x:%s",
- error->errnum, error->errmess));
- warn_user("WimpError", error->errmess);
- }
+/**
+ * Callback to handle the closure of the SSL dialogue by other means.
+ *
+ * \param w The window being closed.
+ */
+static void ro_gui_cert_close_window(wimp_w w)
+{
+ struct ro_sslcert *s;
+
+ s = (struct ro_sslcert *) ro_gui_wimp_event_get_user_data(w);
+
+ if (s != NULL)
+ ro_gui_cert_release_window(s);
}
/**
- * Handle acceptance of certificate
+ * Handle closing of the RISC OS certificate verification dialog, deleting
+ * the windows and freeing up the treeview and data block.
+ *
+ * \param *s The data block associated with the dialogue.
*/
-bool ro_gui_cert_apply(wimp_w w)
-{
- struct session_data *session;
- session = (struct session_data *)ro_gui_wimp_event_get_user_data(w);
- assert(session);
+void ro_gui_cert_release_window(struct ro_sslcert *s)
+{
+ os_error *error;
- urldb_set_cert_permissions(session->url, true);
- session->cb(true, session->cbpw);
+ if (s == NULL)
+ return;
- /* Flag that we sent response by invalidating callback details */
- session->cb = NULL;
- session->cbpw = NULL;
+ LOG(("Releasing SSL data: 0x%x", (unsigned) s));
- return true;
-}
+ ro_gui_wimp_event_finalise(s->window);
+ ro_treeview_destroy(s->tv);
-bool ro_gui_cert_click(wimp_pointer *pointer)
-{
- struct tree *tree;
+ error = xwimp_delete_window(s->window);
+ if (error) {
+ LOG(("xwimp_delete_window: 0x%x:%s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ }
+ error = xwimp_delete_window(s->pane);
+ if (error) {
+ LOG(("xwimp_delete_window: 0x%x:%s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ }
- tree = (struct tree *)ro_gui_wimp_event_get_user_data(pointer->w);
- ro_gui_tree_click(pointer, tree);
- return true;
+ free(s);
}