From: Jaroslav Kysela Date: Mon, 24 Apr 2017 10:34:52 +0000 (+0200) Subject: http: rework the logout mechanism to make things more clear X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c9768cd9e0898f751beb2fbe5bd66d8eb974dd31;p=thirdparty%2Ftvheadend.git http: rework the logout mechanism to make things more clear --- diff --git a/src/http.c b/src/http.c index 6b0420473..5b17503d6 100644 --- a/src/http.c +++ b/src/http.c @@ -388,13 +388,6 @@ http_send_header(http_connection_t *hc, int rc, const char *content, htsbuf_append_str(&hdrs, "\"\r\n"); } } - if (hc->hc_logout_cookie == 1) { - htsbuf_qprintf(&hdrs, "Set-Cookie: logout=1; Path=\"%s/logout\"\r\n", - tvheadend_webroot ? tvheadend_webroot : ""); - } else if (hc->hc_logout_cookie == 2) { - htsbuf_qprintf(&hdrs, "Set-Cookie: logout=0; Path=\"%s/logout'\"; expires=Thu, 01 Jan 1970 00:00:00 GMT\r\n", - tvheadend_webroot ? tvheadend_webroot : ""); - } if (hc->hc_version != RTSP_VERSION_1_0) htsbuf_qprintf(&hdrs, "Connection: %s\r\n", @@ -555,6 +548,7 @@ void http_error(http_connection_t *hc, int error) { const char *errtxt = http_rc2str(error); + const char *lang; int level; if (!atomic_get(&http_server_running)) return; @@ -581,9 +575,15 @@ http_error(http_connection_t *hc, int error) "

%d %s

\r\n", error, errtxt, error, errtxt); - if (error == HTTP_STATUS_UNAUTHORIZED) - htsbuf_qprintf(&hc->hc_reply, "

Default Login

", - tvheadend_webroot ? tvheadend_webroot : ""); + if (error == HTTP_STATUS_UNAUTHORIZED) { + lang = tvh_gettext_get_lang(hc->hc_access ? hc->hc_access->aa_lang_ui : NULL); + htsbuf_qprintf(&hc->hc_reply, "

%s

", + tvheadend_webroot ? tvheadend_webroot : "", + tvh_gettext_lang(lang, N_("Default login"))); + htsbuf_qprintf(&hc->hc_reply, "

%s

", + tvheadend_webroot ? tvheadend_webroot : "", + tvh_gettext_lang(lang, N_("New login"))); + } htsbuf_append_str(&hc->hc_reply, "\r\n"); @@ -925,10 +925,15 @@ http_exec(http_connection_t *hc, http_path_t *hp, char *remain) { int err; - if(http_access_verify(hc, hp->hp_accessmask)) - err = HTTP_STATUS_UNAUTHORIZED; - else - err = hp->hp_callback(hc, remain, hp->hp_opaque); + if ((hc->hc_username && hc->hc_username[0] == '\0') || + http_access_verify(hc, hp->hp_accessmask)) { + if (!hp->hp_no_verification) { + err = HTTP_STATUS_UNAUTHORIZED; + goto destroy; + } + } + err = hp->hp_callback(hc, remain, hp->hp_opaque); +destroy: access_destroy(hc->hc_access); hc->hc_access = NULL; @@ -1163,12 +1168,15 @@ process_request(http_connection_t *hc, htsbuf_queue_t *spill) http_deescape(hc->hc_username); http_deescape(hc->hc_password); // No way to actually track this + } else { + http_error(hc, HTTP_STATUS_UNAUTHORIZED); + return -1; } } else if (strcasecmp(argv[0], "digest") == 0) { v = http_get_header_value(argv[1], "nonce"); if (v == NULL || !http_nonce_exists(v)) { - http_error(hc, HTTP_STATUS_UNAUTHORIZED); free(v); + http_error(hc, HTTP_STATUS_UNAUTHORIZED); return -1; } free(hc->hc_nonce); @@ -1338,6 +1346,7 @@ http_path_add_modify(const char *path, void *opaque, http_callback_t *callback, hp->hp_callback = callback; hp->hp_accessmask = accessmask; hp->hp_path_modify = path_modify; + hp->hp_no_verification = 0; pthread_mutex_lock(&http_paths_mutex); LIST_INSERT_HEAD(&http_paths, hp, hp_link); pthread_mutex_unlock(&http_paths_mutex); @@ -1562,8 +1571,6 @@ http_serve_requests(http_connection_t *hc) if (r) break; - hc->hc_logout_cookie = 0; - } while(hc->hc_keep_alive && atomic_get(&http_server_running)); error: diff --git a/src/http.h b/src/http.h index 65ac665ec..67749f8ae 100644 --- a/src/http.h +++ b/src/http.h @@ -156,7 +156,6 @@ typedef struct http_connection { struct config_head *hc_user_config; int hc_no_output; - int hc_logout_cookie; int hc_shutdown; uint64_t hc_cseq; char *hc_session; @@ -227,6 +226,7 @@ typedef struct http_path { void *hp_opaque; http_callback_t *hp_callback; int hp_len; + int hp_no_verification; uint32_t hp_accessmask; http_path_modify_t *hp_path_modify; } http_path_t; diff --git a/src/webui/webui.c b/src/webui/webui.c index ef25b3911..993d2d232 100644 --- a/src/webui/webui.c +++ b/src/webui/webui.c @@ -185,27 +185,59 @@ page_login(http_connection_t *hc, const char *remain, void *opaque) static int page_logout(http_connection_t *hc, const char *remain, void *opaque) { - if (hc->hc_access == NULL || - hc->hc_access->aa_username == NULL || - hc->hc_access->aa_username == '\0') { -redirect: - http_redirect(hc, "/", &hc->hc_req_args, 0); - return 0; - } else { - const char *s = http_arg_get(&hc->hc_args, "Cookie"); - if (s) { - while (*s && *s != ';') - s++; - if (*s) s++; - while (*s && *s <= ' ') s++; - if (!strncmp(s, "logout=1", 8)) { - hc->hc_logout_cookie = 2; - goto redirect; - } - hc->hc_logout_cookie = 1; - } + const char *username, *busername, *lang, *title, *text, *logout; + char url[512]; + + username = hc->hc_access ? hc->hc_access->aa_username : NULL; + busername = hc->hc_username ? hc->hc_username : NULL; + + tvhtrace(LS_HTTP, "logout: username '%s', busername '%s'\n", username, busername); + + if (http_arg_get(&hc->hc_req_args, "_logout")) return HTTP_STATUS_UNAUTHORIZED; - } + + if (!http_arg_get(&hc->hc_args, "Authorization")) + return HTTP_STATUS_UNAUTHORIZED; + + lang = tvh_gettext_get_lang(hc->hc_access ? hc->hc_access->aa_lang_ui : NULL); + title = tvh_gettext_lang(lang, N_("Logout")); + htsbuf_qprintf(&hc->hc_reply, + "\r\n" + "\r\n" + "%s\r\n" + "\r\n" + "

%s

\r\n" + "

", + title, title); + + text = tvh_gettext_lang(lang, N_("Authenticated user")); + htsbuf_qprintf(&hc->hc_reply, "

%s: %s

\r\n", text, username ?: "---"); + + text = tvh_gettext_lang(lang, N_("\ +Please, follow %s link and cancel the next authorization to correctly clear \ +the cached browser credentals (login and password cache). Then click to \ +the 'Default login' (anonymous access) or 'New login' link in the error page \ +to reauthenticate.")); + logout = tvh_gettext_lang(lang, N_("logout")); + + snprintf(url, sizeof(url), "%s", + tvheadend_webroot ? tvheadend_webroot : "", logout); + + htsbuf_qprintf(&hc->hc_reply, text, url); + + snprintf(url, sizeof(url), "%s", + tvheadend_webroot ? tvheadend_webroot : "", logout); + + text = tvh_gettext_lang(lang, N_("return")); + + htsbuf_qprintf(&hc->hc_reply, "

\r\n" + "

%s

\r\n" + "

%s

\r\n" + "\r\n", + url, tvheadend_webroot ? tvheadend_webroot : "", text); + http_output_html(hc); + return 0; } /** @@ -1852,6 +1884,7 @@ void webui_init(int xspf) { const char *s; + http_path_t *hp; webui_xspf = xspf; @@ -1866,7 +1899,8 @@ webui_init(int xspf) http_path_add("", NULL, page_root2, ACCESS_WEB_INTERFACE); http_path_add("/", NULL, page_root, ACCESS_WEB_INTERFACE); http_path_add("/login", NULL, page_login, ACCESS_WEB_INTERFACE); - http_path_add("/logout", NULL, page_logout, ACCESS_WEB_INTERFACE); + hp = http_path_add("/logout", NULL, page_logout, ACCESS_WEB_INTERFACE); + hp->hp_no_verification = 1; #if CONFIG_SATIP_SERVER http_path_add("/satip_server", NULL, satip_server_http_page, ACCESS_ANONYMOUS);