Use a dedicated cgi handler to deal with tag-toggle requests
authorFabian Keil <fk@fabiankeil.de>
Mon, 23 Jan 2017 13:04:58 +0000 (13:04 +0000)
committerFabian Keil <fk@fabiankeil.de>
Mon, 23 Jan 2017 13:04:58 +0000 (13:04 +0000)
As a result the /client-tags page is now safe to reach without
trusted Referer header which makes bookmarking or linking to
it more convenient.

Finally, refreshing the /client-tags page to show the
current state can no longer unintentionally repeat the
previous toggle request.

cgi.c
cgisimple.c
cgisimple.h

diff --git a/cgi.c b/cgi.c
index fca27d7..63eff59 100644 (file)
--- a/cgi.c
+++ b/cgi.c
@@ -1,4 +1,4 @@
-const char cgi_rcs[] = "$Id: cgi.c,v 1.165 2016/05/03 13:22:30 fabiankeil Exp $";
+const char cgi_rcs[] = "$Id: cgi.c,v 1.166 2017/01/23 13:02:45 fabiankeil Exp $";
 /*********************************************************************
  *
  * File        :  $Source: /cvsroot/ijbswa/current/cgi.c,v $
@@ -101,10 +101,15 @@ static const struct cgi_dispatcher cgi_dispatchers[] = {
          "View the source code version numbers",
           TRUE },
 #ifdef FEATURE_CLIENT_TAGS
+   /*
+    * This is marked as harmless because despite the description
+    * used in the menu the actual toggling is done through another
+    * path ("/toggle-client-tag").
+    */
    { "client-tags",
          cgi_show_client_tags,
          "View or toggle the tags that can be set based on the clients address",
-          FALSE },
+         TRUE },
 #endif
    { "show-request",
          cgi_show_request,
@@ -120,6 +125,12 @@ static const struct cgi_dispatcher cgi_dispatchers[] = {
          "Toggle Privoxy on or off",
          FALSE },
 #endif /* def FEATURE_TOGGLE */
+#ifdef FEATURE_CLIENT_TAGS
+   { "toggle-client-tag",
+         cgi_toggle_client_tag,
+         NULL,
+         FALSE },
+#endif
 #ifdef FEATURE_CGI_EDIT_ACTIONS
    { "edit-actions", /* Edit the actions list */
          cgi_edit_actions,
index c196089..3f6ee17 100644 (file)
@@ -1,4 +1,4 @@
-const char cgisimple_rcs[] = "$Id: cgisimple.c,v 1.142 2016/05/22 12:43:07 fabiankeil Exp $";
+const char cgisimple_rcs[] = "$Id: cgisimple.c,v 1.143 2016/09/27 22:48:28 ler762 Exp $";
 /*********************************************************************
  *
  * File        :  $Source: /cvsroot/ijbswa/current/cgisimple.c,v $
@@ -310,7 +310,7 @@ static void cgi_create_client_tag_form(char *form, size_t size,
    }
 
    snprintf(form, size,
-      "<form method=\"GET\" action=\"client-tags\" style=\"display: inline\">\n"
+      "<form method=\"GET\" action=\"toggle-client-tag\" style=\"display: inline\">\n"
       " <input type=\"hidden\" name=\"tag\" value=\"%s\">\n"
       " <input type=\"hidden\" name=\"toggle-state\" value=\"%u\">\n"
       " <input type=\"hidden\" name=\"expires\" value=\"%u\">\n"
@@ -343,10 +343,6 @@ jb_err cgi_show_client_tags(struct client_state *csp,
    struct map *exports;
    struct client_tag_spec *this_tag;
    jb_err err = JB_ERR_OK;
-   const char *toggled_tag;
-   const char *toggle_state;
-   const char *tag_expires;
-   time_t time_to_live;
    char *client_tag_status;
    char buf[1000];
 
@@ -359,28 +355,7 @@ jb_err cgi_show_client_tags(struct client_state *csp,
       return JB_ERR_MEMORY;
    }
    assert(csp->client_address != NULL);
-   toggled_tag = lookup(parameters, "tag");
-   if (*toggled_tag != '\0')
-   {
-      tag_expires = lookup(parameters, "expires");
-      if (*tag_expires == '0')
-      {
-         time_to_live = 0;
-      }
-      else
-      {
-         time_to_live = csp->config->client_tag_lifetime;
-      }
-      toggle_state = lookup(parameters, "toggle-state");
-      if (*toggle_state == '1')
-      {
-         enable_client_specific_tag(csp, toggled_tag, time_to_live);
-      }
-      else
-      {
-         disable_client_specific_tag(csp, toggled_tag);
-      }
-   }
+
    this_tag = csp->config->client_tags;
    if (this_tag->name == NULL)
    {
@@ -437,6 +412,78 @@ jb_err cgi_show_client_tags(struct client_state *csp,
 
    return template_fill_for_cgi(csp, "client-tags", exports, rsp);
 }
+
+
+/*********************************************************************
+ *
+ * Function    :  cgi_toggle_client_tag
+ *
+ * Description :  Toggles a client tag and redirects to the show-tags
+ *                page
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  rsp = http_response data structure for output
+ *          3  :  parameters = map of cgi parameters
+ *
+ * CGI Parameters : none
+ *          1  :  tag = Name of the tag to enable or disable
+ *          2  :  toggle-state = How to toggle the tag (0/1)
+ *          3  :  expires = Set to 1 if the tag should be enabled
+ *                          temporarily, otherwise set to 0
+ *
+ * Returns     :  JB_ERR_OK on success
+ *                JB_ERR_MEMORY on out-of-memory error.
+ *
+ *********************************************************************/
+jb_err cgi_toggle_client_tag(struct client_state *csp,
+                             struct http_response *rsp,
+                             const struct map *parameters)
+{
+   const char *toggled_tag;
+   const char *toggle_state;
+   const char *tag_expires;
+   time_t time_to_live;
+
+   assert(csp);
+   assert(rsp);
+   assert(parameters);
+
+   toggled_tag = lookup(parameters, "tag");
+   if (*toggled_tag == '\0')
+   {
+      log_error(LOG_LEVEL_ERROR, "Received tag toggle request without tag");
+   }
+   else
+   {
+      tag_expires = lookup(parameters, "expires");
+      if (*tag_expires == '0')
+      {
+         time_to_live = 0;
+      }
+      else
+      {
+         time_to_live = csp->config->client_tag_lifetime;
+      }
+      toggle_state = lookup(parameters, "toggle-state");
+      if (*toggle_state == '1')
+      {
+         enable_client_specific_tag(csp, toggled_tag, time_to_live);
+      }
+      else
+      {
+         disable_client_specific_tag(csp, toggled_tag);
+      }
+   }
+   rsp->status = strdup_or_die("302 Done dealing with toggle request");
+   if (enlist_unique_header(rsp->headers,
+         "Location", CGI_PREFIX "client-tags"))
+   {
+         return JB_ERR_MEMORY;
+   }
+   return JB_ERR_OK;
+
+}
 #endif /* def FEATURE_CLIENT_TAGS */
 
 
index d9fe33e..f65a300 100644 (file)
@@ -1,6 +1,6 @@
 #ifndef CGISIMPLE_H_INCLUDED
 #define CGISIMPLE_H_INCLUDED
-#define CGISIMPLE_H_VERSION "$Id: cgisimple.h,v 1.20 2016/03/17 10:40:53 fabiankeil Exp $"
+#define CGISIMPLE_H_VERSION "$Id: cgisimple.h,v 1.21 2017/01/23 13:02:45 fabiankeil Exp $"
 /*********************************************************************
  *
  * File        :  $Source: /cvsroot/ijbswa/current/cgisimple.h,v $
@@ -72,6 +72,9 @@ extern jb_err cgi_show_request (struct client_state *csp,
 extern jb_err cgi_show_client_tags(struct client_state *csp,
                                    struct http_response *rsp,
                                    const struct map *parameters);
+extern jb_err cgi_toggle_client_tag(struct client_state *csp,
+                                    struct http_response *rsp,
+                                    const struct map *parameters);
 #endif
 extern jb_err cgi_transparent_image (struct client_state *csp,
                                      struct http_response *rsp,