From c238325b12318803a8dcc706d7d678333f82e1c8 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Mon, 5 Aug 2019 22:28:52 +0100 Subject: [PATCH] add about scheme query handlers --- content/fetchers/about.c | 335 ++++++++++++++++++++++++++++++++++++++- resources/FatMessages | 16 +- 2 files changed, 348 insertions(+), 3 deletions(-) diff --git a/content/fetchers/about.c b/content/fetchers/about.c index 4e90f3afc..7d0b3b913 100644 --- a/content/fetchers/about.c +++ b/content/fetchers/about.c @@ -31,10 +31,12 @@ #include #include +#include "utils/log.h" #include "testament.h" #include "utils/corestrings.h" #include "utils/nsoption.h" #include "utils/utils.h" +#include "utils/messages.h" #include "utils/ring.h" #include "content/fetch.h" @@ -303,7 +305,9 @@ fetch_about_imagecache_handler_aborted: return false; } -/** Handler to generate about:config page */ +/** + * Handler to generate about scheme config page + */ static bool fetch_about_config_handler(struct fetch_about_context *ctx) { fetch_msg msg; @@ -587,6 +591,321 @@ static bool fetch_about_maps_handler(struct fetch_about_context *ctx) return true; } + +/** + * generate a 500 server error respnse + */ +static bool fetch_about_srverror(struct fetch_about_context *ctx) +{ + char buffer[256]; + int slen; + fetch_msg msg; + + fetch_set_http_code(ctx->fetchh, 500); + + /* content type */ + if (fetch_about_send_header(ctx, "Content-Type: text/plain")) + return false; + + msg.type = FETCH_DATA; + msg.data.header_or_data.buf = (const uint8_t *) buffer; + slen = snprintf(buffer, sizeof buffer, "Server error 500"); + + msg.data.header_or_data.len = slen; + if (fetch_about_send_callback(&msg, ctx)) + return false; + + msg.type = FETCH_FINISHED; + fetch_about_send_callback(&msg, ctx); + + return true; +} + + +/** + * generate the description of the login request + */ +static nserror +get_login_description(struct nsurl *url, + const char *realm, + const char *username, + const char *password, + char **out_str) +{ + char *url_s; + size_t url_l; + nserror res; + char *str = NULL; + int slen; + const char *key; + + res = nsurl_get(url, NSURL_SCHEME | NSURL_HOST, &url_s, &url_l); + if (res != NSERROR_OK) { + return res; + } + + if ((*username == 0) && (*password == 0)) { + key = "LoginDescription"; + } else { + key = "LoginAgain"; + } + + str = messages_get_buff(key, url_s, realm); + NSLOG(netsurf, INFO, + "key:%s url:%s realm:%s str:%s", key, url_s, realm, str); + + if ((str != NULL) && (strcmp(key, str) != 0)) { + *out_str = str; + } else { + /* no message so fallback */ + const char *fmt = "The site %s is requesting your username and password. The realm is \"%s\""; + slen = snprintf(str, 0, fmt, url_s, realm) + 1; + str = malloc(slen); + if (str == NULL) { + res = NSERROR_NOMEM; + } else { + snprintf(str, slen, fmt, url_s, realm); + *out_str = str; + } + } + + free(url_s); + + return res; +} + + +/** + * Handler to generate about scheme authorisation query page + */ +static bool fetch_about_query_auth_handler(struct fetch_about_context *ctx) +{ + nserror res; + fetch_msg msg; + char buffer[1024]; + int slen; + char *url_s; + size_t url_l; + const char *realm = ""; + const char *username = ""; + const char *password = ""; + const char *title; + char *description = NULL; + struct nsurl *siteurl = NULL; + const struct fetch_multipart_data *curmd; /* mutipart data iterator */ + + /* extract parameters from multipart post data */ + curmd = ctx->multipart; + while (curmd != NULL) { + if (strcmp(curmd->name, "siteurl") == 0) { + res = nsurl_create(curmd->value, &siteurl); + if (res != NSERROR_OK) { + return fetch_about_srverror(ctx); + } + } else if (strcmp(curmd->name, "realm") == 0) { + realm = curmd->value; + } else if (strcmp(curmd->name, "username") == 0) { + username = curmd->value; + } else if (strcmp(curmd->name, "password") == 0) { + password = curmd->value; + } + curmd = curmd->next; + } + + if (siteurl == NULL) { + return fetch_about_srverror(ctx); + } + + /* content is going to return ok */ + fetch_set_http_code(ctx->fetchh, 200); + + /* content type */ + if (fetch_about_send_header(ctx, "Content-Type: text/html; charset=utf-8")) + goto fetch_about_query_auth_handler_aborted; + + msg.type = FETCH_DATA; + msg.data.header_or_data.buf = (const uint8_t *) buffer; + + title = messages_get("LoginTitle"); + slen = snprintf(buffer, sizeof buffer, + "\n\n" + "%s\n" + "\n" + "\n" + "\n" + "

%s

\n", + title, title); + + res = get_login_description(siteurl, + realm, + username, + password, + &description); + if (res == NSERROR_OK) { + slen += snprintf(buffer + slen, sizeof(buffer) - slen, + "

%s

", + description); + free(description); + } + + slen += snprintf(buffer + slen, sizeof(buffer) - slen, + "
"); + + slen += snprintf(buffer + slen, sizeof(buffer) - slen, + "
" + "" + "" + "
", + messages_get("Username"), username); + + slen += snprintf(buffer + slen, sizeof(buffer) - slen, + "
" + "" + "" + "
", + messages_get("Password"), password); + + slen += snprintf(buffer + slen, sizeof(buffer) - slen, + "
" + "" + "" + "
", + messages_get("Cancel"), + messages_get("Login")); + + res = nsurl_get(siteurl, NSURL_COMPLETE, &url_s, &url_l); + if (res != NSERROR_OK) { + url_s = strdup(""); + } + slen += snprintf(buffer + slen, sizeof(buffer) - slen, + "", + url_s); + free(url_s); + + slen += snprintf(buffer + slen, sizeof(buffer) - slen, + "", + realm); + + slen += snprintf(buffer + slen, sizeof(buffer) - slen, + "
\n\n"); + + msg.data.header_or_data.len = slen; + if (fetch_about_send_callback(&msg, ctx)) + goto fetch_about_query_auth_handler_aborted; + + msg.type = FETCH_FINISHED; + fetch_about_send_callback(&msg, ctx); + + return true; + +fetch_about_query_auth_handler_aborted: + return false; +} + +/** + * Handler to generate about scheme ssl query page + */ +static bool fetch_about_query_ssl_handler(struct fetch_about_context *ctx) +{ + nserror res; + fetch_msg msg; + char buffer[1024]; + int slen; + char *url_s; + size_t url_l; + const char *reason = ""; + const char *title; + struct nsurl *siteurl = NULL; + const struct fetch_multipart_data *curmd; /* mutipart data iterator */ + + /* extract parameters from multipart post data */ + curmd = ctx->multipart; + while (curmd != NULL) { + if (strcmp(curmd->name, "siteurl") == 0) { + res = nsurl_create(curmd->value, &siteurl); + if (res != NSERROR_OK) { + return fetch_about_srverror(ctx); + } + } else if (strcmp(curmd->name, "reason") == 0) { + reason = curmd->value; + } + curmd = curmd->next; + } + + if (siteurl == NULL) { + return fetch_about_srverror(ctx); + } + + /* content is going to return ok */ + fetch_set_http_code(ctx->fetchh, 200); + + /* content type */ + if (fetch_about_send_header(ctx, "Content-Type: text/html; charset=utf-8")) + goto fetch_about_query_ssl_handler_aborted; + + msg.type = FETCH_DATA; + msg.data.header_or_data.buf = (const uint8_t *) buffer; + + title = messages_get("PrivacyTitle"); + slen = snprintf(buffer, sizeof buffer, + "\n\n" + "%s\n" + "\n" + "\n" + "\n" + "

%s

\n", + title, title); + + slen += snprintf(buffer + slen, sizeof(buffer) - slen, + "

%s

", + reason); + + slen += snprintf(buffer + slen, sizeof(buffer) - slen, + "
"); + + + slen += snprintf(buffer + slen, sizeof(buffer) - slen, + "
" + "" + "" + "
", + messages_get("Backtosafety"), + messages_get("Proceed")); + + res = nsurl_get(siteurl, NSURL_COMPLETE, &url_s, &url_l); + if (res != NSERROR_OK) { + url_s = strdup(""); + } + slen += snprintf(buffer + slen, sizeof(buffer) - slen, + "", + url_s); + free(url_s); + + slen += snprintf(buffer + slen, sizeof(buffer) - slen, + "
\n\n"); + + msg.data.header_or_data.len = slen; + if (fetch_about_send_callback(&msg, ctx)) + goto fetch_about_query_ssl_handler_aborted; + + msg.type = FETCH_FINISHED; + fetch_about_send_callback(&msg, ctx); + + return true; + +fetch_about_query_ssl_handler_aborted: + return false; +} + + /* Forward declaration because this handler requires the handler table. */ static bool fetch_about_about_handler(struct fetch_about_context *ctx); @@ -679,6 +998,20 @@ struct about_handlers about_handler_list[] = { NULL, fetch_about_blank_handler, true + }, + { + "query/auth", + SLEN("query/auth"), + NULL, + fetch_about_query_auth_handler, + true + }, + { + "query/ssl", + SLEN("query/ssl"), + NULL, + fetch_about_query_ssl_handler, + true } }; diff --git a/resources/FatMessages b/resources/FatMessages index 6ac665c3a..3c6ca4893 100644 --- a/resources/FatMessages +++ b/resources/FatMessages @@ -2740,8 +2740,12 @@ nl.all.CaseSens:Hoofdlettergevoelig # This section contains tokens which are used in the 401 login # (authentication) dialog box. # +en.all.LoginTitle:Authentication Requested +fr.all.LoginTitle:Authentification demandée en.all.LoginDescription:The site %s with realm "%s" is requesting credentials for access. +fr.all.LoginDescription:Le site %s avec le royaume "%s" demande des informations d'identification pour l'accès. en.all.LoginAgain:The credentials for the site %s and realm "%s" were rejected. +fr.all.LoginAgain:Les identifiants pour le site %s et le royaume "%s" ont été rejetés. en.all.LoginLabel:A website is requesting credentials for access. en.all.Host:Host de.all.Host:Host @@ -2775,8 +2779,16 @@ it.all.Cancel:Annulla nl.all.Cancel:Annuleer -# SSL certificate verification -# ============================ +# Privacy error interface +# ======================= +# + +en.all.PrivacyTitle:Privacy error +en.all.Proceed:Proceed +en.all.Backtosafety:Back to safety + +# SSL certificate viewer +# ====================== # # This section contains tokens which are used in the # SSL certificate verification dialog box.