diff options
Diffstat (limited to 'frontends/windows/ssl_cert.c')
-rw-r--r-- | frontends/windows/ssl_cert.c | 439 |
1 files changed, 439 insertions, 0 deletions
diff --git a/frontends/windows/ssl_cert.c b/frontends/windows/ssl_cert.c new file mode 100644 index 000000000..72d1d3b55 --- /dev/null +++ b/frontends/windows/ssl_cert.c @@ -0,0 +1,439 @@ +/* + * Copyright 2016 Vincent Sanders <vince@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** + * \file + * Implementation of win32 certificate viewing using nsw32 core windows. + */ + +#include <stdint.h> +#include <stdlib.h> +#include <windows.h> + +#include "utils/log.h" +#include "utils/nsoption.h" +#include "netsurf/keypress.h" +#include "netsurf/plotters.h" +#include "desktop/sslcert_viewer.h" + +#include "windows/windbg.h" +#include "windows/plot.h" +#include "windows/corewindow.h" +#include "windows/gui.h" +#include "windows/resourceid.h" +#include "windows/ssl_cert.h" + +/* spacing and sizes for dialog elements from + * https://msdn.microsoft.com/en-us/library/windows/desktop/dn742486(v=vs.85).aspx#sizingandspacing + */ +#define DLG_MRGN 11 +#define WRN_ICO_H 32 +#define CMD_BTN_W 75 +#define CMD_BTN_H 23 + +static const char windowclassname_sslcert[] = "nswssslcertwindow"; + +struct nsw32_sslcert_window { + struct nsw32_corewindow core; + + /** SSL certificate viewer context data */ + struct sslcert_session_data *ssl_data; + + /** dialog window handle */ + HWND hWnd; + + /** accept button handle */ + HWND hAccept; + + /** reject button handle */ + HWND hReject; + + /** warning text handle */ + HWND hTxt; + +}; + +/** + * callback for keypress on hotlist window + * + * \param nsw32_cw The nsw32 core window structure. + * \param nskey The netsurf key code + * \return NSERROR_OK on success otherwise apropriate error code + */ +static nserror +nsw32_sslcert_viewer_key(struct nsw32_corewindow *nsw32_cw, uint32_t nskey) +{ + struct nsw32_sslcert_window *crtvrfy_win; + + /* technically degenerate container of */ + crtvrfy_win = (struct nsw32_sslcert_window *)nsw32_cw; + + if (sslcert_viewer_keypress(crtvrfy_win->ssl_data, nskey)) { + return NSERROR_OK; + } + return NSERROR_NOT_IMPLEMENTED; +} + +/** + * callback for mouse action on hotlist window + * + * \param nsw32_cw The nsw32 core window structure. + * \param mouse_state netsurf mouse state on event + * \param x location of event + * \param y location of event + * \return NSERROR_OK on success otherwise apropriate error code + */ +static nserror +nsw32_sslcert_viewer_mouse(struct nsw32_corewindow *nsw32_cw, + browser_mouse_state mouse_state, + int x, int y) +{ + struct nsw32_sslcert_window *crtvrfy_win; + + /* technically degenerate container of */ + crtvrfy_win = (struct nsw32_sslcert_window *)nsw32_cw; + + sslcert_viewer_mouse_action(crtvrfy_win->ssl_data, mouse_state, x, y); + + return NSERROR_OK; +} + +/** + * callback on draw event for hotlist window + * + * \param nsw32_cw The nsw32 core window structure. + * \param r The rectangle of the window that needs updating. + * \return NSERROR_OK on success otherwise apropriate error code + */ +static nserror +nsw32_sslcert_viewer_draw(struct nsw32_corewindow *nsw32_cw, + int scrollx, + int scrolly, + struct rect *r) +{ + struct nsw32_sslcert_window *crtvrfy_win; + struct redraw_context ctx = { + .interactive = true, + .background_images = true, + .plot = &win_plotters + }; + + /* technically degenerate container of */ + crtvrfy_win = (struct nsw32_sslcert_window *)nsw32_cw; + + sslcert_viewer_redraw(crtvrfy_win->ssl_data, + -scrollx, -scrolly, + r, &ctx); + + return NSERROR_OK; +} + + +static nserror +nsw32_sslcert_viewer_close(struct nsw32_corewindow *nsw32_cw) +{ + DestroyWindow(nsw32_cw->hWnd); + + return NSERROR_OK; +} + + +/* exported interface documented in nsw32/ssl_cert.h */ +nserror nsw32_cert_verify(struct nsurl *url, + const struct ssl_cert_info *certs, + unsigned long num, + nserror (*cb)(bool proceed, void *pw), + void *cbpw) +{ + struct nsw32_sslcert_window *ncwin; + nserror res; + + ncwin = malloc(sizeof(struct nsw32_sslcert_window)); + if (ncwin == NULL) { + return NSERROR_NOMEM; + } + + /* initialise certificate viewing interface */ + res = sslcert_viewer_create_session_data(num, url, cb, cbpw, certs, + &ncwin->ssl_data); + if (res != NSERROR_OK) { + free(ncwin); + return res; + } + + LOG("creating hInstance %p SSL window", hinst); + ncwin->hWnd = CreateWindowEx(0, + windowclassname_sslcert, + "SSL Certificate viewer", + WS_OVERLAPPEDWINDOW | + WS_CLIPSIBLINGS | + WS_CLIPCHILDREN | + CS_DBLCLKS, + CW_USEDEFAULT, + CW_USEDEFAULT, + 500, + 400, + NULL, + NULL, + hinst, + NULL); + if (ncwin->hWnd == NULL) { + LOG("Window create failed"); + return NSERROR_NOMEM; + } + + ncwin->core.title = NULL; + ncwin->core.draw = nsw32_sslcert_viewer_draw; + ncwin->core.key = nsw32_sslcert_viewer_key; + ncwin->core.mouse = nsw32_sslcert_viewer_mouse; + ncwin->core.close = nsw32_sslcert_viewer_close; + + res = nsw32_corewindow_init(hinst, ncwin->hWnd, &ncwin->core); + if (res != NSERROR_OK) { + free(ncwin); + return res; + } + + res = sslcert_viewer_init(ncwin->core.cb_table, + (struct core_window *)ncwin, + ncwin->ssl_data); + if (res != NSERROR_OK) { + free(ncwin); + return res; + } + + ncwin->hAccept = CreateWindowEx(0, + "BUTTON", + "Accept", + WS_TABSTOP|WS_VISIBLE| + WS_CHILD|BS_DEFPUSHBUTTON, + CW_USEDEFAULT, + CW_USEDEFAULT, + CMD_BTN_W, + CMD_BTN_H, + ncwin->hWnd, + (HMENU)IDC_SSLCERT_BTN_ACCEPT, + hinst, + NULL); + HGDIOBJ hfDefault=GetStockObject(DEFAULT_GUI_FONT); + SendMessage(ncwin->hAccept, WM_SETFONT, (WPARAM)hfDefault, MAKELPARAM(FALSE,0)); + ncwin->hReject = CreateWindowEx(0, + "BUTTON", + "Reject", + WS_TABSTOP|WS_VISIBLE| + WS_CHILD|BS_DEFPUSHBUTTON, + CW_USEDEFAULT, + CW_USEDEFAULT, + CMD_BTN_W, + CMD_BTN_H, + ncwin->hWnd, + (HMENU)IDC_SSLCERT_BTN_REJECT, + hinst, + NULL); + SendMessage(ncwin->hReject, WM_SETFONT, (WPARAM)hfDefault, MAKELPARAM(FALSE,0)); + + CreateWindowEx(0, + "STATIC", + IDI_WARNING, + WS_VISIBLE | WS_CHILD | SS_ICON, + DLG_MRGN, + DLG_MRGN, + CMD_BTN_W, + CMD_BTN_H, + ncwin->hWnd, + NULL, + NULL, + NULL); + ncwin->hTxt = CreateWindowEx(0, + "STATIC", + "NetSurf failed to verify the authenticity of an SSL certificate. Verify the certificate details", + WS_VISIBLE | WS_CHILD | SS_LEFT, + DLG_MRGN + WRN_ICO_H + DLG_MRGN, + DLG_MRGN + 5, + 400, + WRN_ICO_H - 5, + ncwin->hWnd, + NULL, + NULL, + NULL); + SendMessage(ncwin->hTxt, WM_SETFONT, (WPARAM)hfDefault, MAKELPARAM(FALSE,0)); + + SetProp(ncwin->hWnd, TEXT("CertWnd"), (HANDLE)ncwin); + + ShowWindow(ncwin->hWnd, SW_SHOWNORMAL); + + return NSERROR_OK; +} + +/** + * position and size ssl cert window widgets. + */ +static void +nsw32_window_ssl_cert_size(HWND hwnd, struct nsw32_sslcert_window *certwin) +{ + RECT rc; + GetClientRect(hwnd, &rc); + /* position certificate drawable */ + MoveWindow(certwin->core.hWnd, + DLG_MRGN, + DLG_MRGN + WRN_ICO_H + DLG_MRGN, + rc.right - (DLG_MRGN + DLG_MRGN), + rc.bottom - (DLG_MRGN + WRN_ICO_H + DLG_MRGN + DLG_MRGN + CMD_BTN_H + DLG_MRGN), + TRUE); + /* position accept button */ + MoveWindow(certwin->hAccept, + rc.right - (DLG_MRGN + CMD_BTN_W), + rc.bottom - (DLG_MRGN + CMD_BTN_H), + CMD_BTN_W, + CMD_BTN_H, + TRUE); + /* position reject button */ + MoveWindow(certwin->hReject, + rc.right - (DLG_MRGN + CMD_BTN_W + 7 + CMD_BTN_W), + rc.bottom - (DLG_MRGN + CMD_BTN_H), + CMD_BTN_W, + CMD_BTN_H, + TRUE); + /* position text */ + MoveWindow(certwin->hTxt, + DLG_MRGN + WRN_ICO_H + DLG_MRGN, + DLG_MRGN + 5, + rc.right - (DLG_MRGN + WRN_ICO_H + DLG_MRGN + DLG_MRGN), + WRN_ICO_H - 5, + TRUE); +} + +static nserror nsw32_crtvrfy_destroy(struct nsw32_sslcert_window *crtwin) +{ + nserror res; + + res = sslcert_viewer_fini(crtwin->ssl_data); + if (res == NSERROR_OK) { + res = nsw32_corewindow_fini(&crtwin->core); + DestroyWindow(crtwin->hWnd); + free(crtwin); + } + return res; +} + +/** + * handle command message on main browser window + * + * \param hwnd The win32 window handle + * \param gw win32 gui window + * \param notification_code notifiction code + * \param identifier notification identifier + * \param ctrl_window The win32 control window handle + * \return apropriate response for command + */ +static LRESULT +nsw32_window_ssl_cert_command(HWND hwnd, + struct nsw32_sslcert_window *crtwin, + int notification_code, + int identifier, + HWND ctrl_window) +{ + LOG("notification_code %x identifier %x ctrl_window %p", + notification_code, identifier, ctrl_window); + + switch(identifier) { + case IDC_SSLCERT_BTN_ACCEPT: + sslcert_viewer_accept(crtwin->ssl_data); + nsw32_crtvrfy_destroy(crtwin); + break; + + case IDC_SSLCERT_BTN_REJECT: + sslcert_viewer_reject(crtwin->ssl_data); + nsw32_crtvrfy_destroy(crtwin); + break; + + default: + return 1; /* unhandled */ + } + return 0; /* control message handled */ +} + +/** + * callback for SSL certificate window win32 events + * + * \param hwnd The win32 window handle + * \param msg The win32 message identifier + * \param wparam The w win32 parameter + * \param lparam The l win32 parameter + */ +static LRESULT CALLBACK +nsw32_window_ssl_cert_event_callback(HWND hwnd, + UINT msg, + WPARAM wparam, + LPARAM lparam) +{ + struct nsw32_sslcert_window *crtwin; + crtwin = GetProp(hwnd, TEXT("CertWnd")); + if (crtwin != NULL) { + switch (msg) { + case WM_SIZE: + nsw32_window_ssl_cert_size(hwnd, crtwin); + break; + + case WM_COMMAND: + if (nsw32_window_ssl_cert_command(hwnd, + crtwin, + HIWORD(wparam), + LOWORD(wparam), + (HWND)lparam) == 0) { + return 0; + } + break; + + case WM_CLOSE: + sslcert_viewer_reject(crtwin->ssl_data); + nsw32_crtvrfy_destroy(crtwin); + return 0; + } + } + + return DefWindowProc(hwnd, msg, wparam, lparam); +} + +/* exported interface documented in nsw32/ssl_cert.h */ +nserror nsws_create_cert_verify_class(HINSTANCE hInstance) +{ + nserror ret = NSERROR_OK; + WNDCLASSEX wc; + + /* drawable area */ + wc.cbSize = sizeof(WNDCLASSEX); + wc.style = 0; + wc.lpfnWndProc = nsw32_window_ssl_cert_event_callback; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = NULL; + wc.hCursor = NULL; + wc.hbrBackground = (HBRUSH)(COLOR_MENU + 1); + wc.lpszMenuName = NULL; + wc.lpszClassName = windowclassname_sslcert; + wc.hIconSm = NULL; + + if (RegisterClassEx(&wc) == 0) { + win_perror("CertVerifyClass"); + ret = NSERROR_INIT_FAILED; + } + + return ret; +} |