]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
http: rework the logout mechanism to make things more clear
authorJaroslav Kysela <perex@perex.cz>
Mon, 24 Apr 2017 10:34:52 +0000 (12:34 +0200)
committerJaroslav Kysela <perex@perex.cz>
Mon, 24 Apr 2017 14:55:42 +0000 (16:55 +0200)
src/http.c
src/http.h
src/webui/webui.c

index 6b0420473a95aee7d3e5f8cc8b4a077ad1a25a19..5b17503d6fddf3ebf0db186ecb5828cd24d1962a 100644 (file)
@@ -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)
                    "<H1>%d %s</H1>\r\n",
                    error, errtxt, error, errtxt);
 
-    if (error == HTTP_STATUS_UNAUTHORIZED)
-      htsbuf_qprintf(&hc->hc_reply, "<P><A HREF=\"%s/logout\">Default Login</A></P>",
-                     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, "<P STYLE=\"text-align: center; margin: 2em\"><A HREF=\"%s/\" STYLE=\"border: 1px solid; border-radius: 4px; padding: .6em\">%s</A></P>",
+                     tvheadend_webroot ? tvheadend_webroot : "",
+                     tvh_gettext_lang(lang, N_("Default login")));
+      htsbuf_qprintf(&hc->hc_reply, "<P STYLE=\"text-align: center; margin: 2em\"><A HREF=\"%s/login\" STYLE=\"border: 1px solid; border-radius: 4px; padding: .6em\">%s</A></P>",
+                     tvheadend_webroot ? tvheadend_webroot : "",
+                     tvh_gettext_lang(lang, N_("New login")));
+    }
 
     htsbuf_append_str(&hc->hc_reply, "</BODY></HTML>\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:
index 65ac665ec3fb1c883c77e957a87f8470ed1b7418..67749f8aeb854ac355b30064ad876014ed7288cf 100644 (file)
@@ -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;
index ef25b39119a63dcd506a8b791854724d5c487e33..993d2d2324a464280a4dc3a5365ce05155a9db28 100644 (file)
@@ -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,
+                 "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n"
+                 "<HTML><HEAD>\r\n"
+                 "<TITLE>%s</TITLE>\r\n"
+                 "</HEAD><BODY>\r\n"
+                 "<H1>%s</H1>\r\n"
+                 "<P>",
+                 title, title);
+
+  text = tvh_gettext_lang(lang, N_("Authenticated user"));
+  htsbuf_qprintf(&hc->hc_reply, "<P>%s: %s</P>\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), "<A HREF=\"%s/logout?_logout=1\">%s</A>",
+                             tvheadend_webroot ? tvheadend_webroot : "", logout);
+
+  htsbuf_qprintf(&hc->hc_reply, text, url);
+
+  snprintf(url, sizeof(url), "<A HREF=\"%s/logout?_logout=1\" "
+                             "STYLE=\"border: 1px solid; border-radius: 4px; padding: .6em\">%s</A>",
+                             tvheadend_webroot ? tvheadend_webroot : "", logout);
+
+  text = tvh_gettext_lang(lang, N_("return"));
+
+  htsbuf_qprintf(&hc->hc_reply, "</P>\r\n"
+                                "<P STYLE=\"text-align: center; margin: 2em\">%s</P>\r\n"
+                                "<P STYLE=\"text-align: center; margin: 2em\"><A HREF=\"%s/\" STYLE=\"border: 1px solid; border-radius: 4px; padding: .6em\">%s</A></P>\r\n"
+                                "</BODY></HTML>\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);