]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
Cookie handling support:
authorMichael R Sweet <msweet@msweet.org>
Thu, 1 May 2025 18:27:38 +0000 (14:27 -0400)
committerMichael R Sweet <msweet@msweet.org>
Thu, 1 May 2025 18:27:38 +0000 (14:27 -0400)
- Add httpGetCookieValue API.
- Increase CGI cookie value size limit to 2k.

CHANGES.md
cgi-bin/var.c
cups/http.c
cups/http.h

index cc60b6b9be766fff9e406c47634ae4b78af0c2f4..cc21aaa9db12c1fc40dffa233a53380eef054805 100644 (file)
@@ -7,9 +7,8 @@ Changes in CUPS v2.5b1 (YYYY-MM-DD)
 - Added multiple language support for IPP Everywhere.
 - Added `cupsConcatString`, `cupsCopyString`, and `cupsFormatString` string
   APIs.
-- Added new `cupsRasterInitHeader` API.
-- Added `httpConnectURI` API.
-- Added `httpGetSecurity` API.
+- Added `cupsRasterInitHeader` API.
+- Added `httpConnectURI`, `httpGetCookieValue`, and `httpGetSecurity` APIs.
 - Added `ippAddCredentialsString`, `ippGetFirstAttribute`,
   `ippGetNextAttribute`, `ippRestore`, and `ippSave` APIs.
 - Added new DNS-SD APIs.
@@ -33,8 +32,8 @@ Changes in CUPS v2.5b1 (YYYY-MM-DD)
 - Added a systemd slice to the systemd services included with the scheduler
 - Added localizations for deprecated IPP attributes/options (Issue #1020)
 - Added support for specifying permissions with the `cupsFileOpen` API.
-- Added new `cupsGetClock` API.
-- Added new `cupsParseOptions2` API with "end" argument.
+- Added `cupsGetClock` API.
+- Added `cupsParseOptions2` API with "end" argument.
 - Added `cups-oauth` and `cups-x509` utilities (Issue #1184)
 - Added `DNSSDComputerName` directive to "cupsd.conf" and updated cupsd to
   correctly update the mDNS hostname only if the `DNSSDHostName` directive is
index 8bb70513ee7b314474c26204f25649fcbb47ff90..ff13e9f719db7db456cb406759952326c0ce7b42 100644 (file)
@@ -708,7 +708,7 @@ cgi_initialize_cookies(void)
 {
   const char   *cookie;                /* HTTP_COOKIE environment variable */
   char         name[128],              /* Name string */
-               value[512],             /* Value string */
+               value[2048],            /* Value string */
                *ptr;                   /* Pointer into name/value */
 
 
@@ -733,6 +733,7 @@ cgi_initialize_cookies(void)
     */
 
     for (ptr = name; *cookie && *cookie != '=';)
+    {
       if (ptr < (name + sizeof(name) - 1))
       {
         *ptr++ = *cookie++;
@@ -742,6 +743,7 @@ cgi_initialize_cookies(void)
         skip = 1;
        cookie ++;
       }
+    }
 
     if (*cookie != '=')
       break;
@@ -756,6 +758,7 @@ cgi_initialize_cookies(void)
     if (*cookie == '\"')
     {
       for (cookie ++, ptr = value; *cookie && *cookie != '\"';)
+      {
         if (ptr < (value + sizeof(value) - 1))
        {
          *ptr++ = *cookie++;
@@ -765,6 +768,7 @@ cgi_initialize_cookies(void)
          skip = 1;
          cookie ++;
        }
+      }
 
       if (*cookie == '\"')
         cookie ++;
@@ -774,6 +778,7 @@ cgi_initialize_cookies(void)
     else
     {
       for (ptr = value; *cookie && *cookie != ';';)
+      {
         if (ptr < (value + sizeof(value) - 1))
        {
          *ptr++ = *cookie++;
@@ -783,6 +788,7 @@ cgi_initialize_cookies(void)
          skip = 1;
          cookie ++;
        }
+      }
     }
 
     if (*cookie == ';')
index e16c9ac01aefda56a9e6ea702214c774aa32548c..71cb1d97b81017641da1a3137f78576bf47336ca 100644 (file)
@@ -1030,7 +1030,11 @@ httpGetContentEncoding(http_t *http)     // I - HTTP connection
 
 
 //
-// 'httpGetCookie()' - Get any cookie data from the response.
+// 'httpGetCookie()' - Get "Cookie:" data from the HTTP connection.
+//
+// This function returns any HTTP "Cookie:" header data for the given HTTP
+// connection as described in RFC 6265.  Use the @link httpGetCookieValue@ to
+// get the value of a named cookie.
 //
 // @since CUPS 1.1.19@
 //
@@ -1042,6 +1046,107 @@ httpGetCookie(http_t *http)             // I - HTTP connection
 }
 
 
+//
+// 'httpGetCookieValue()' - Get the value of a named cookie from the HTTP connection.
+//
+// This function copies the value of a named cookie in the HTTP "Cookie:" header
+// for the given HTTP connection as described in RFC 6265.  Use the
+// @link httpGetCookie@ function to get the original "Cookie:" string.
+//
+// @since CUPS 2.5@
+//
+
+char *                                 // O - Cookie value or `NULL` if not present
+httpGetCookieValue(http_t     *http,   // I - HTTP connection
+                   const char *name,   // I - Cookie name
+                   char       *buffer, // I - Value buffer
+                   size_t     bufsize) // I - Size of value buffer
+{
+  const char   *cookie;                // Cookie: header value
+  char         current[128],           // Current name string
+               *ptr,                   // Pointer into name/buffer
+               *end;                   // End of name/buffer
+  bool         match;                  // Does the current name match?
+
+
+  // Range check input...
+  if (buffer)
+    *buffer = '\0';
+
+  if (!http || !http->cookie || !name || !buffer || bufsize < 2)
+    return (NULL);
+
+  // Loop through the cookie string...
+  for (cookie = http->cookie; *cookie;)
+  {
+    // Skip leading whitespace...
+    while (isspace(*cookie & 255))
+      cookie ++;
+    if (!*cookie)
+      break;
+
+    // Copy the name...
+    for (ptr = current, end = current + sizeof(current) - 1; *cookie && *cookie != '=';)
+    {
+      if (ptr < end)
+        *ptr++ = *cookie++;
+      else
+       cookie ++;
+    }
+
+    if (*cookie != '=')
+      break;
+
+    *ptr = '\0';
+    match = !strcmp(current, name);
+    cookie ++;
+
+    // Then the value...
+    if (*cookie == '\"')
+    {
+      // Copy quoted value...
+      for (cookie ++, ptr = buffer, end = buffer + bufsize - 1; *cookie && *cookie != '\"';)
+      {
+        if (match && ptr < end)
+         *ptr++ = *cookie++;
+       else
+         cookie ++;
+      }
+
+      if (*cookie == '\"')
+        cookie ++;
+      else
+        match = false;
+    }
+    else
+    {
+      // Copy unquoted value...
+      for (ptr = buffer, end = buffer + bufsize - 1; *cookie && *cookie != ';';)
+      {
+        if (match && ptr < end)
+         *ptr++ = *cookie++;
+       else
+         cookie ++;
+      }
+    }
+
+    if (match)
+    {
+      // Got the value we were looking for, nul-terminate and return...
+      *ptr = '\0';
+      return (buffer);
+    }
+
+    // Skip over separator...
+    if (*cookie == ';')
+      cookie ++;
+  }
+
+  // If we get here then we never found the cookie...
+  return (NULL);
+}
+
+
 //
 // 'httpGetEncryption()' - Get the current encryption mode of a connection.
 //
index d8aa2e7e5c9fad6582dd5c1114b1af92a49b4351..bb6815608dd042519cfb53c588308179b58cbe1b 100644 (file)
@@ -438,6 +438,7 @@ extern char         *httpGetAuthString(http_t *http) _CUPS_PUBLIC;
 extern int             httpGetBlocking(http_t *http) _CUPS_PUBLIC;
 extern const char      *httpGetContentEncoding(http_t *http) _CUPS_PUBLIC;
 extern const char      *httpGetCookie(http_t *http) _CUPS_PUBLIC;
+extern char            *httpGetCookieValue(http_t *http, const char *name, char *buffer, size_t bufsize) _CUPS_PUBLIC;
 extern const char      *httpGetDateString(time_t t) _CUPS_PUBLIC;
 extern const char      *httpGetDateString2(time_t t, char *s, int slen) _CUPS_PUBLIC;
 extern time_t          httpGetDateTime(const char *s) _CUPS_PUBLIC;