summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Sanders <vince@kyllikki.org>2018-08-18 23:30:12 +0100
committerVincent Sanders <vince@kyllikki.org>2018-08-18 23:30:12 +0100
commita6c595f4f305c43d9da825ad31c0011fe02d0684 (patch)
treefbf00062ed627e21d3c0217e77f6cc341078ce68
parentc938d1962bed31f0723707fc978bb65ab5a47ef2 (diff)
downloadnetsurf-a6c595f4f305c43d9da825ad31c0011fe02d0684.tar.gz
netsurf-a6c595f4f305c43d9da825ad31c0011fe02d0684.tar.bz2
add win32 http authentication dialog
-rw-r--r--frontends/windows/Makefile2
-rw-r--r--frontends/windows/about.c2
-rw-r--r--frontends/windows/about.h6
-rw-r--r--frontends/windows/gui.c71
-rw-r--r--frontends/windows/gui.h11
-rw-r--r--frontends/windows/login.c297
-rw-r--r--frontends/windows/login.h39
-rw-r--r--frontends/windows/main.c3
-rw-r--r--frontends/windows/res/resource.rc12
-rw-r--r--frontends/windows/window.c2
10 files changed, 432 insertions, 13 deletions
diff --git a/frontends/windows/Makefile b/frontends/windows/Makefile
index de01ce33a..f6995910d 100644
--- a/frontends/windows/Makefile
+++ b/frontends/windows/Makefile
@@ -50,7 +50,7 @@ S_RESOURCES := windows_resource.o
# sources purely for the windows build
S_FRONTEND := main.c window.c gui.c drawable.c plot.c findfile.c \
font.c bitmap.c about.c prefs.c download.c filetype.c file.c \
- local_history.c schedule.c windbg.c pointers.c \
+ local_history.c schedule.c windbg.c pointers.c login.c \
corewindow.c hotlist.c cookies.c global_history.c ssl_cert.c
# This is the final source build list
diff --git a/frontends/windows/about.c b/frontends/windows/about.c
index f73c0c83a..325587d8a 100644
--- a/frontends/windows/about.c
+++ b/frontends/windows/about.c
@@ -139,7 +139,7 @@ nsws_about_event_callback(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
return FALSE;
}
-void nsws_about_dialog_init(HINSTANCE hinst, HWND parent)
+void nsw32_about_dialog_init(HINSTANCE hinst, HWND parent)
{
int ret = DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUT), parent,
nsws_about_event_callback);
diff --git a/frontends/windows/about.h b/frontends/windows/about.h
index e0315b507..807c7b900 100644
--- a/frontends/windows/about.h
+++ b/frontends/windows/about.h
@@ -16,9 +16,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef _NETSURF_WINDOWS_ABOUT_H_
-#define _NETSURF_WINDOWS_ABOUT_H_
+#ifndef NETSURF_WINDOWS_ABOUT_H
+#define NETSURF_WINDOWS_ABOUT_H
-void nsws_about_dialog_init(HINSTANCE hinst, HWND parent);
+void nsw32_about_dialog_init(HINSTANCE hinst, HWND parent);
#endif
diff --git a/frontends/windows/gui.c b/frontends/windows/gui.c
index 890bfae42..674484fea 100644
--- a/frontends/windows/gui.c
+++ b/frontends/windows/gui.c
@@ -52,6 +52,74 @@ HINSTANCE hinst;
static bool win32_quit = false;
+struct dialog_list_entry {
+ struct dialog_list_entry *next;
+ HWND hwnd;
+};
+
+static struct dialog_list_entry *dlglist = NULL;
+
+/* exported interface documented in gui.h */
+nserror nsw32_add_dialog(HWND hwndDlg)
+{
+ struct dialog_list_entry *nentry;
+ nentry = malloc(sizeof(struct dialog_list_entry));
+ if (nentry == NULL) {
+ return NSERROR_NOMEM;
+ }
+
+ nentry->hwnd = hwndDlg;
+ nentry->next = dlglist;
+ dlglist = nentry;
+
+ return NSERROR_OK;
+}
+
+/* exported interface documented in gui.h */
+nserror nsw32_del_dialog(HWND hwndDlg)
+{
+ struct dialog_list_entry **prev;
+ struct dialog_list_entry *cur;
+
+ prev = &dlglist;
+ cur = *prev;
+
+ while (cur != NULL) {
+ if (cur->hwnd == hwndDlg) {
+ /* found match */
+ *prev = cur->next;
+ NSLOG(netsurf, DEBUG,
+ "removed hwnd %p entry %p", cur->hwnd, cur);
+ free(cur);
+ return NSERROR_OK;
+ }
+ prev = &cur->next;
+ cur = *prev;
+ }
+ NSLOG(netsurf, INFO, "did not find hwnd %p", hwndDlg);
+
+ return NSERROR_NOT_FOUND;
+}
+
+/**
+ * walks dialog list and attempts to process any messages for them
+ */
+static nserror handle_dialog_message(LPMSG lpMsg)
+{
+ struct dialog_list_entry *cur;
+ cur = dlglist;
+ while (cur != NULL) {
+ if (IsDialogMessage(cur->hwnd, lpMsg)) {
+ NSLOG(netsurf, DEBUG,
+ "dispatched dialog hwnd %p", cur->hwnd);
+ return NSERROR_OK;
+ }
+ cur = cur->next;
+ }
+
+ return NSERROR_NOT_FOUND;
+}
+
/* exported interface documented in gui.h */
void win32_set_quit(bool q)
{
@@ -92,7 +160,8 @@ void win32_run(void)
}
}
- if (bRet > 0) {
+ if ((bRet > 0) &&
+ (handle_dialog_message(&Msg) != NSERROR_OK)) {
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
diff --git a/frontends/windows/gui.h b/frontends/windows/gui.h
index efbf02924..5fd9decb2 100644
--- a/frontends/windows/gui.h
+++ b/frontends/windows/gui.h
@@ -56,4 +56,15 @@ void win32_set_quit(bool q);
*/
nserror win32_warning(const char *warning, const char *detail);
+/**
+ * add a modeless dialog to the special handling list
+ */
+nserror nsw32_add_dialog(HWND hwndDlg);
+
+/**
+ * remove a modeless dialog from the special handling list
+ */
+nserror nsw32_del_dialog(HWND hwndDlg);
+
+
#endif
diff --git a/frontends/windows/login.c b/frontends/windows/login.c
new file mode 100644
index 000000000..ca6c9163d
--- /dev/null
+++ b/frontends/windows/login.c
@@ -0,0 +1,297 @@
+/*
+* Copyright 2018 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
+ * This is The win32 API basic authentication login dialog implementation.
+ */
+
+#include <stdio.h>
+
+#include "utils/config.h"
+
+#include <windows.h>
+
+#include "utils/log.h"
+#include "utils/messages.h"
+#include "utils/nsurl.h"
+#include "desktop/version.h"
+
+#include "windows/gui.h"
+#include "windows/window.h"
+#include "windows/login.h"
+#include "windows/resourceid.h"
+
+#include "windbg.h"
+
+struct login_ctx {
+ char *username;
+ char *password;
+ char *description;
+ nserror (*cb)(const char *username, const char *password, void *cbctx);
+ void *cbctx;
+};
+
+
+/**
+ * free login dialog context
+ */
+static nserror
+free_loginctx(struct login_ctx *ctx)
+{
+ free(ctx->username);
+ free(ctx->password);
+ free(ctx->description);
+ free(ctx);
+
+ return NSERROR_OK;
+}
+
+
+/**
+ * generate the description of the login request
+ */
+static nserror
+get_login_description(struct nsurl *url,
+ const char *realm,
+ char **out_str)
+{
+ char *url_s;
+ size_t url_l;
+ nserror res;
+ const char *fmt = "The site %s is requesting your username and password. The realm is \"%s\"";
+ char *str = NULL;
+ int strlen;
+
+ res = nsurl_get(url, NSURL_SCHEME | NSURL_HOST, &url_s, &url_l);
+ if (res != NSERROR_OK) {
+ return res;
+ }
+
+ strlen = snprintf(str, 0, fmt, url_s, realm) + 1;
+ str = malloc(strlen);
+ if (str == NULL) {
+ res = NSERROR_NOMEM;
+ } else {
+ snprintf(str, strlen, fmt, url_s, realm);
+ *out_str = str;
+ }
+
+ free(url_s);
+
+ return res;
+}
+
+/**
+ * win32 login dialog initialisation handler
+ */
+static BOOL
+login_dialog_init(HWND hwndDlg, WPARAM wParam, LPARAM lParam)
+{
+ struct login_ctx *ctx;
+ HWND hwndOwner;
+ RECT rc, rcDlg, rcOwner;
+ ctx = (struct login_ctx *)lParam;
+
+ /* make context available in future calls */
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam);
+
+ /* set default contents */
+ SetDlgItemText(hwndDlg, IDC_LOGIN_USERNAME, ctx->username);
+ SetDlgItemText(hwndDlg, IDC_LOGIN_PASSWORD, ctx->password);
+ SetDlgItemText(hwndDlg, IDC_LOGIN_DESCRIPTION, ctx->description);
+
+ /* Get the owner window and dialog box rectangles. */
+ if ((hwndOwner = GetParent(hwndDlg)) == NULL) {
+ hwndOwner = GetDesktopWindow();
+ }
+
+ GetWindowRect(hwndOwner, &rcOwner);
+ GetWindowRect(hwndDlg, &rcDlg);
+ CopyRect(&rc, &rcOwner);
+
+ /* Offset the owner and dialog box rectangles so that right
+ * and bottom values represent the width and height, and then
+ * offset the owner again to discard space taken up by the
+ * dialog box.
+ */
+
+ OffsetRect(&rcDlg, -rcDlg.left, -rcDlg.top);
+ OffsetRect(&rc, -rc.left, -rc.top);
+ OffsetRect(&rc, -rcDlg.right, -rcDlg.bottom);
+
+ /* The new position is the sum of half the remaining space and
+ * the owner's original position.
+ */
+ SetWindowPos(hwndDlg,
+ HWND_TOP,
+ rcOwner.left + (rc.right / 2),
+ rcOwner.top + (rc.bottom / 2),
+ 0, 0, /* Ignores size arguments. */
+ SWP_NOSIZE);
+
+ /* ensure username gets focus */
+ if (GetDlgCtrlID((HWND) wParam) != IDC_LOGIN_USERNAME) {
+ SetFocus(GetDlgItem(hwndDlg, IDC_LOGIN_USERNAME));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/**
+ * win32 login dialog ok handler
+ */
+static BOOL
+login_dialog_ok(HWND hwndDlg, struct login_ctx *ctx)
+{
+ char username[255];
+ char password[255];
+
+ if (GetDlgItemText(hwndDlg,
+ IDC_LOGIN_USERNAME,
+ username,
+ sizeof(username)) == 0) {
+ username[0]=0;
+ }
+
+ if (GetDlgItemText(hwndDlg,
+ IDC_LOGIN_PASSWORD,
+ password,
+ sizeof(password)) == 0) {
+ password[0]=0;
+ }
+
+ NSLOG(netsurf, DEBUG,
+ "context %p, user:\"%s\" pw:\"%s\"", ctx, username, password);
+
+ ctx->cb(username, password, ctx->cbctx);
+
+ DestroyWindow(hwndDlg);
+
+ nsw32_del_dialog(hwndDlg);
+
+ free_loginctx(ctx);
+
+ return TRUE;
+}
+
+
+/**
+ * win32 login dialog cancel handler
+ */
+static BOOL
+login_dialog_cancel(HWND hwndDlg, struct login_ctx *ctx)
+{
+ NSLOG(netsurf, DEBUG, "context %p", ctx);
+
+ ctx->cb(NULL, NULL, ctx->cbctx);
+
+ DestroyWindow(hwndDlg);
+
+ nsw32_del_dialog(hwndDlg);
+
+ free_loginctx(ctx);
+
+ return TRUE;
+}
+
+
+/**
+ * win32 API callback for login dialog
+ */
+static BOOL CALLBACK
+login_dialog_callback(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ struct login_ctx *ctx;
+
+ LOG_WIN_MSG(hwndDlg, message, wParam, lParam);
+
+ /* obtain login dialog context */
+ ctx = (struct login_ctx *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+
+ switch (message) {
+ case WM_INITDIALOG:
+ return login_dialog_init(hwndDlg, wParam, lParam);
+
+ case WM_COMMAND:
+ switch (LOWORD(wParam)) {
+ case IDOK:
+ return login_dialog_ok(hwndDlg, ctx);
+
+ case IDCANCEL:
+ return login_dialog_cancel(hwndDlg, ctx);
+ }
+ }
+ return FALSE;
+}
+
+
+/**
+ * Request credentials for http login
+ */
+nserror
+nsw32_401login(nsurl *url,
+ const char *realm,
+ const char *username,
+ const char *password,
+ nserror (*cb)(const char *username,
+ const char *password,
+ void *cbctx),
+ void *cbctx)
+{
+ HWND hwndDlg;
+ struct login_ctx *nctx;
+ struct gui_window *gw;
+ nserror res;
+
+ /* locate parent window */
+ gw = nsws_get_gui_window(GetActiveWindow());
+ if (gw == NULL) {
+ return NSERROR_INIT_FAILED;
+ }
+
+ /* setup context for parameters */
+ nctx = calloc(1, sizeof(struct login_ctx));
+ if (nctx == NULL) {
+ return NSERROR_NOMEM;
+ }
+
+ nctx->username = strdup(username);
+ nctx->password = strdup(password);
+ nctx->cb = cb;
+ nctx->cbctx = cbctx;
+
+ res = get_login_description(url, realm, &nctx->description);
+ if (res != NSERROR_OK) {
+ free_loginctx(nctx);
+ return res;
+ }
+
+ /* create modeless dialog */
+ hwndDlg = CreateDialogParam(NULL,
+ MAKEINTRESOURCE(IDD_LOGIN),
+ gw->main,
+ login_dialog_callback,
+ (LPARAM)nctx);
+
+ nsw32_add_dialog(hwndDlg);
+
+ return NSERROR_OK;
+}
diff --git a/frontends/windows/login.h b/frontends/windows/login.h
new file mode 100644
index 000000000..411306230
--- /dev/null
+++ b/frontends/windows/login.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2018 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
+ * Basic authentication login interfaces.
+ */
+
+#ifndef NSW32_LOGIN_H
+#define NSW32_LOGIN_H
+
+/**
+ * login window request.
+ */
+extern nserror nsw32_401login(nsurl *url,
+ const char *realm,
+ const char *username,
+ const char *password,
+ nserror (*cb)(const char *username,
+ const char *password,
+ void *cbctx),
+ void *cbctx);
+
+#endif
diff --git a/frontends/windows/main.c b/frontends/windows/main.c
index a3a7c2b39..5dd1e7316 100644
--- a/frontends/windows/main.c
+++ b/frontends/windows/main.c
@@ -45,6 +45,7 @@
#include "windows/drawable.h"
#include "windows/corewindow.h"
#include "windows/ssl_cert.h"
+#include "windows/login.h"
#include "windows/download.h"
#include "windows/local_history.h"
#include "windows/window.h"
@@ -272,7 +273,9 @@ static nserror nsw32_option_init(int *pargc, char** argv)
static struct gui_misc_table win32_misc_table = {
.schedule = win32_schedule,
.warning = win32_warning,
+
.cert_verify = nsw32_cert_verify,
+ .login = nsw32_401login,
};
/**
diff --git a/frontends/windows/res/resource.rc b/frontends/windows/res/resource.rc
index fb0468a33..746888cc8 100644
--- a/frontends/windows/res/resource.rc
+++ b/frontends/windows/res/resource.rc
@@ -206,18 +206,18 @@ FONT 8, "Ms Shell Dlg"
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
-IDD_LOGIN DIALOGEX 0, 0, 200, 93
+IDD_LOGIN DIALOGEX 0, 0, 280, 93
STYLE DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYSMENU
CAPTION "Log In"
FONT 8, "Ms Shell Dlg"
{
LTEXT "Password:", 0, 7, 53, 35, 9, SS_LEFT, WS_EX_LEFT
LTEXT "User name:", 0, 7, 35, 40, 9, SS_LEFT, WS_EX_LEFT
- EDITTEXT IDC_LOGIN_PASSWORD, 49, 50, 144, 14, ES_AUTOHSCROLL, WS_EX_LEFT
- LTEXT "The site foo.bar requires authorization for a realm", IDC_LOGIN_DESCRIPTION, 49, 7, 144, 18, SS_LEFT, WS_EX_LEFT
- EDITTEXT IDC_LOGIN_USERNAME, 49, 32, 144, 14, ES_AUTOHSCROLL, WS_EX_LEFT
- PUSHBUTTON "Cancel", IDCANCEL, 143, 71, 50, 14, 0, WS_EX_LEFT
- DEFPUSHBUTTON "Log in", IDOK, 89, 71, 50, 14, 0, WS_EX_LEFT
+ LTEXT "The site foo.bar requires authorization for a realm", IDC_LOGIN_DESCRIPTION, 49, 7, 224, 18, SS_LEFT, WS_EX_LEFT
+ EDITTEXT IDC_LOGIN_USERNAME, 49, 32, 224, 14, ES_AUTOHSCROLL, WS_EX_LEFT
+ EDITTEXT IDC_LOGIN_PASSWORD, 49, 50, 224, 14, ES_AUTOHSCROLL, WS_EX_LEFT
+ DEFPUSHBUTTON "Log in", IDOK, 169, 71, 50, 14, 0, WS_EX_LEFT
+ PUSHBUTTON "Cancel", IDCANCEL, 223, 71, 50, 14, 0, WS_EX_LEFT
}
diff --git a/frontends/windows/window.c b/frontends/windows/window.c
index 90d076812..3ccf8295e 100644
--- a/frontends/windows/window.c
+++ b/frontends/windows/window.c
@@ -1274,7 +1274,7 @@ nsws_window_command(HWND hwnd,
break;
case IDM_HELP_ABOUT:
- nsws_about_dialog_init(hinst, gw->main);
+ nsw32_about_dialog_init(hinst, gw->main);
break;
case IDC_MAIN_LAUNCH_URL: