diff options
Diffstat (limited to 'riscos/sslcert.c')
-rw-r--r-- | riscos/sslcert.c | 381 |
1 files changed, 292 insertions, 89 deletions
diff --git a/riscos/sslcert.c b/riscos/sslcert.c index de83e5e20..9bf9bf1d6 100644 --- a/riscos/sslcert.c +++ b/riscos/sslcert.c @@ -23,34 +23,47 @@ #include "netsurf/content/urldb.h" #include "netsurf/desktop/browser.h" #include "netsurf/desktop/gui.h" +#include "netsurf/desktop/tree.h" #include "netsurf/riscos/dialog.h" #include "netsurf/riscos/textarea.h" +#include "netsurf/riscos/treeview.h" #include "netsurf/riscos/wimp_event.h" +#include "netsurf/riscos/wimp.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 +#define ICON_SSL_PANE 1 +#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; + struct browser_window *bw; + char *url; + struct tree *tree; +}; struct session_cert { char version[16], valid_from[32], valid_to[32], type[8], serial[32]; - char *url; + char *issuer_t; + char *subject_t; uintptr_t issuer; uintptr_t subject; - struct browser_window *bw; }; -static void ro_gui_cert_open(struct browser_window *bw, const char *url, - const struct ssl_cert_info *certdata); +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); @@ -60,7 +73,16 @@ static bool ro_gui_cert_apply(wimp_w w); void ro_gui_cert_init(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"); + + dialog_tree_template->flags &= ~(wimp_WINDOW_MOVEABLE | + wimp_WINDOW_BACK_ICON | + wimp_WINDOW_CLOSE_ICON | + wimp_WINDOW_TITLE_ICON | + wimp_WINDOW_SIZE_ICON | + wimp_WINDOW_TOGGLE_ICON); } /** @@ -70,57 +92,232 @@ void ro_gui_cert_init(void) 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; + 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; + + assert(bw && c && certs); - session = malloc(sizeof(struct session_cert)); - if (!session) { + /* copy the certificate information */ + data = calloc(1, sizeof(struct session_data)); + if (!data) { + warn_user("NoMemory", 0); + return; + } + data->url = strdup(c->url); + if (!data->url) { + free(data); warn_user("NoMemory", 0); return; } + data->bw = bw; + 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); + } - session->url = strdup(url); - if (!session->url) { - free(session); + /* create the SSL window */ + error = xwimp_create_window(dialog_cert_template, &ssl_w); + if (error) { + free(data->certs); + free(data->url); + free(data); + LOG(("xwimp_create_window: 0x%x: %s", + error->errnum, error->errmess)); + 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(bw->window->window, ssl_w, false); + + /* create a tree window (styled as a list) */ + error = xwimp_create_window(dialog_tree_template, &w); + if (error) { + ro_gui_cert_close(ssl_w); + LOG(("xwimp_create_window: 0x%x: %s", + error->errnum, error->errmess)); + return; + } + tree = calloc(sizeof(struct tree), 1); + if (!tree) { + ro_gui_cert_close(ssl_w); warn_user("NoMemory", 0); 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; + } + tree->root->expanded = true; + tree->handle = (int)w; + tree->movable = false; + 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].issuer); + 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; + error = xwimp_get_window_state(&state); + if (error) { + ro_gui_cert_close(ssl_w); + LOG(("xwimp_get_window_state: 0x%x: %s", + error->errnum, error->errmess)); + return; + } + + istate.w = ssl_w; + istate.i = ICON_SSL_PANE; + error = xwimp_get_icon_state(&istate); + if (error) { + ro_gui_cert_close(ssl_w); + LOG(("xwimp_get_icon_state: 0x%x: %s", + error->errnum, error->errmess)); + return; + } + state.w = w; + state.visible.x1 = state.visible.x0 + istate.icon.extent.x1 - 20 - + ro_get_vscroll_width(w); + 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((wimp_open *)&state, ssl_w, + wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT + << wimp_CHILD_XORIGIN_SHIFT | + wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT + << wimp_CHILD_YORIGIN_SHIFT | + wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT + << wimp_CHILD_LS_EDGE_SHIFT | + wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT + << wimp_CHILD_RS_EDGE_SHIFT); + if (error) { + ro_gui_cert_close(ssl_w); + LOG(("xwimp_open_window_nested: 0x%x: %s", + error->errnum, error->errmess)); + 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); + + /* 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); + + /* now we get the handle of our list window */ + child = (wimp_w)tree->handle; + assert(child); + + /* 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); - 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); - - 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; - - error = xwimp_create_window(dialog_cert_template, &w); + 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)); @@ -128,47 +325,41 @@ void ro_gui_cert_open(struct browser_window *bw, const char *url, warn_user("MiscError", error->errmess); return; } - + if (session->issuer) + textarea_destroy(session->issuer); session->issuer = textarea_create(w, ICON_CERT_ISSUER, TEXTAREA_MULTILINE | TEXTAREA_READONLY, NULL, 0); if (!session->issuer) { xwimp_delete_window(w); - free(session); warn_user("NoMemory", 0); return; } - if (!textarea_set_text(session->issuer, certdata->issuer)) { + if (!textarea_set_text(session->issuer, session->issuer_t)) { textarea_destroy(session->issuer); xwimp_delete_window(w); - free(session); warn_user("NoMemory", 0); return; } + if (session->subject) + textarea_destroy(session->subject); session->subject = textarea_create(w, ICON_CERT_SUBJECT, TEXTAREA_MULTILINE | TEXTAREA_READONLY, NULL, 0); if (!session->subject) { textarea_destroy(session->issuer); xwimp_delete_window(w); - free(session); warn_user("NoMemory", 0); return; } - if (!textarea_set_text(session->subject, certdata->subject)) { + if (!textarea_set_text(session->subject, session->subject_t)) { textarea_destroy(session->subject); textarea_destroy(session->issuer); xwimp_delete_window(w); - free(session); warn_user("NoMemory", 0); return; } - - 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); + ro_gui_wimp_event_register_close_window(w, ro_gui_wimp_event_finalise); + ro_gui_dialog_open_persistent(parent, w, false); } /** @@ -176,25 +367,31 @@ void ro_gui_cert_open(struct browser_window *bw, const char *url, */ 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); - - textarea_destroy(session->subject); - textarea_destroy(session->issuer); - - free(session->url); - free(session); - + struct session_data *data; + unsigned long i; + + data = (struct session_data *)ro_gui_wimp_event_get_user_data(w); + assert(data); + + for (i = 0; i < data->num; i++) { + if (data->certs[i].subject) + textarea_destroy(data->certs[i].subject); + if (data->certs[i].issuer) + textarea_destroy(data->certs[i].issuer); + } + free(data->certs); + free(data->url); + free(data); + + if (data->tree) { + tree_delete_node(data->tree, data->tree->root, false); + xwimp_delete_window((wimp_w)data->tree->handle); + free(data->tree); + } + xwimp_delete_window(w); + ro_gui_wimp_event_finalise(w); - - error = xwimp_delete_window(w); - if (error) - LOG(("xwimp_delete_window: 0x%x: %s", - error->errnum, error->errmess)); + } /** @@ -202,16 +399,22 @@ void ro_gui_cert_close(wimp_w w) */ bool ro_gui_cert_apply(wimp_w w) { - struct session_cert *session; - - session = (struct session_cert *)ro_gui_wimp_event_get_user_data(w); + struct session_data *session; + session = (struct session_data *)ro_gui_wimp_event_get_user_data(w); assert(session); urldb_set_cert_permissions(session->url, true); - browser_window_go(session->bw, session->url, 0, true); + return true; +} +bool ro_gui_cert_click(wimp_pointer *pointer) +{ + struct tree *tree; + + tree = (struct tree *)ro_gui_wimp_event_get_user_data(pointer->w); + ro_gui_tree_click(pointer, tree); return true; } |