]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
Move CUPS_SID to cgi.h and use it as the state string for OAuth.
authorMichael R Sweet <msweet@msweet.org>
Mon, 5 May 2025 12:07:52 +0000 (08:07 -0400)
committerMichael R Sweet <msweet@msweet.org>
Mon, 5 May 2025 12:07:52 +0000 (08:07 -0400)
Increase buffer sizes to allow for very large JWTs.

cgi-bin/cgi.h
cgi-bin/home.c
cgi-bin/var.c
scheduler/auth.c
scheduler/client.h
scheduler/statbuf.h

index 0f97727789e59646015652df44e29312f5013f7c..534131fe2210f2ec4e4d491a92200b6daa891db4 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * CGI support library definitions for CUPS.
  *
- * Copyright © 2020-2024 by OpenPrinting.
+ * Copyright © 2020-2025 by OpenPrinting.
  * Copyright © 2007-2019 by Apple Inc.
  * Copyright © 1997-2006 by Easy Software Products.
  *
 extern "C" {
 #  endif /* __cplusplus */
 
+
+/*
+ * Constants...
+ */
+
+#  define CUPS_SID     "org.cups.sid"  /* Session ID cookie/variable */
+
+
 /*
  * Types...
  */
index d4b781d64f7c7c535b5e19c817570c951e2b7c3e..22e8819f85e9c7af6ea22fb368c9eb2abed05cab 100644 (file)
@@ -98,13 +98,13 @@ do_login(void)
                                        // OAuth authorization server URL
                *server_name = getenv("SERVER_NAME"),
                                        // SERVER_NAME value
-               *server_port = getenv("SERVER_PORT");
+               *server_port = getenv("SERVER_PORT"),
                                        // SERVER_PORT value
+               *state = NULL;          // State string
   char         *client_id = NULL,      // Client ID value
                *code_verifier = NULL,  // Code verifier string
                *nonce = NULL,          // Nonce string
                redirect_uri[1024],     // redirect_uri value
-               *state = NULL,          // State string
                *url = NULL;            // Authorization URL
   cups_json_t  *metadata = NULL;       // OAuth metadata
 
@@ -144,7 +144,7 @@ do_login(void)
   // Make state and code verification strings...
   code_verifier = cupsOAuthMakeBase64Random(128);
   nonce         = cupsOAuthMakeBase64Random(16);
-  state         = cupsOAuthMakeBase64Random(16);
+  state         = cgiGetCookie(CUPS_SID);
 
   // Get the authorization URL
   if ((url = cupsOAuthMakeAuthorizationURL(oauth_uri, metadata, /*resource_uri*/NULL, getenv("CUPS_OAUTH_SCOPES"), client_id, code_verifier, nonce, redirect_uri, state)) == NULL)
@@ -166,7 +166,6 @@ do_login(void)
   free(code_verifier);
   cupsJSONDelete(metadata);
   free(nonce);
-  free(state);
   free(url);
 }
 
@@ -196,12 +195,23 @@ do_redirect(const char *url)              // URL or NULL for home page
   fprintf(stderr, "DEBUG2: do_redirect(url=\"%s\")\n", url);
 
   if (url && (!strncmp(url, "http://", 7) || !strncmp(url, "https://", 8)))
-    printf("Location: %s\n\n", url);
+    printf("Location: %s\n", url);
   else
-    printf("Location: %s://%s:%s%s\n\n", getenv("HTTPS") ? "https" : "http", getenv("SERVER_NAME"), getenv("SERVER_PORT"), url ? url : "/");
+    printf("Location: %s://%s:%s%s\n", getenv("HTTPS") ? "https" : "http", getenv("SERVER_NAME"), getenv("SERVER_PORT"), url ? url : "/");
 
   puts("Content-Type: text/plain\n");
   puts("Redirecting...");
+  fflush(stdout);
+
+
+  if (url && (!strncmp(url, "http://", 7) || !strncmp(url, "https://", 8)))
+    fprintf(stderr, "DEBUG2: do_redirect: Location: %s\n", url);
+  else
+    fprintf(stderr, "DEBUG2: do_redirect: Location: %s://%s:%s%s\n", getenv("HTTPS") ? "https" : "http", getenv("SERVER_NAME"), getenv("SERVER_PORT"), url ? url : "/");
+
+  fputs("DEBUG2: do_redirect: Content-Type: text/plain\n", stderr);
+  fputs("DEBUG2: do_redirect:\n", stderr);
+  fputs("DEBUG2: do_redirect: Redirecting...", stderr);
 }
 
 
@@ -233,9 +243,7 @@ finish_login(void)
                *client_id = NULL,      // Client ID value
                *error,                 // Error string
                redirect_uri[1024];     // redirect_uri value
-  const char   *code,                  // Authorization code
-               *state_cookie,          // State cookie
-               *state_var;             // State variable
+  const char   *code;                  // Authorization code
   cups_json_t  *metadata = NULL;       // OAuth metadata
   time_t       access_expires;         // When the bearer token expires
 
@@ -276,16 +284,8 @@ finish_login(void)
 
   fprintf(stderr, "DEBUG2: finish_login: client_id=\"%s\"\n", client_id);
 
-  // Get the state and code strings...
-  code         = cgiGetVariable("code");
-  state_cookie = cgiGetCookie("CUPS_OAUTH_STATE");
-  state_var    = cgiGetVariable("state");
-
-  if (!state_cookie || !state_var || strcmp(state_cookie, state_var))
-  {
-    show_error(cgiText(_("OAuth Login")), cgiText(_("Unable to authorize access")), cgiText(_("Bad client state value in response.")));
-    goto done;
-  }
+  // Get the code string...
+  code = cgiGetVariable("code");
 
   // Get the access token...
   if ((bearer = cupsOAuthGetTokens(oauth_uri, metadata, /*resource_uri*/NULL, code, CUPS_OGRANT_AUTHORIZATION_CODE, redirect_uri, &access_expires)) == NULL)
@@ -294,12 +294,16 @@ finish_login(void)
     goto done;
   }
 
+  fprintf(stderr, "DEBUG2: finish_login: access_token=\"%s\", access_expires=%ld\n", bearer, (long)access_expires);
+
   // Save it as a cookie...
   cgiSetCookie("CUPS_BEARER", bearer, /*path*/NULL, /*domain*/NULL, access_expires, /*secure*/0);
 
   // Redirect...
   do_redirect(cgiGetCookie("CUPS_REFERRER"));
 
+  fputs("DEBUG2: finish_login: After redirect.\n", stderr);
+
   done:
 
   // Free memory...
index 66a5a8e70bd0275a0c1768e3d6bd34a625c77f0b..e5443499d5e46b5cf490f8adc652c6ffbefb6120 100644 (file)
 #include <cups/http.h>
 
 
-/*
- * Session ID name
- */
-
-#define CUPS_SID       "org.cups.sid"
-
-
 /*
  * Data structure to hold all the CGI form variables and arrays...
  */
@@ -394,8 +387,10 @@ cgiInitialize(void)
     else if (!cgi_initialize_post())
       return (0);
 
-    if ((cups_sid_form = cgiGetVariable(CUPS_SID)) == NULL ||
-       strcmp(cups_sid_cookie, cups_sid_form))
+    if ((cups_sid_form = cgiGetVariable(CUPS_SID)) == NULL)
+      cups_sid_form = cgiGetVariable("state");
+
+    if (!cups_sid_form || strcmp(cups_sid_cookie, cups_sid_form))
     {
       if (cups_sid_form)
        fprintf(stderr, "DEBUG: " CUPS_SID " form variable is \"%s\"\n",
@@ -505,6 +500,8 @@ cgiSetCookie(const char *name,              /* I - Name */
             time_t     expires,        /* I - Expiration date (0 for session) */
             int        secure)         /* I - Require SSL */
 {
+  fprintf(stderr, "DEBUG2: cgiSetCookie(name=\"%s\", value=\"%s\", path=\"%s\", domain=\"%s\", expires=%ld, secure=%d)\n", name, value, path, domain, (long)expires, secure);
+
   num_cookies = cupsAddOption(name, value, num_cookies, &cookies);
 
   printf("Set-Cookie: %s=%s;", name, value);
index 1702d1f8c8c142ac3404cea5652018ffa886c81b..08252844c15a99692a1a2ecb94b932e1cd03aaf8 100644 (file)
@@ -317,7 +317,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
   int          type;                   /* Authentication type */
   const char   *authorization;         /* Pointer into Authorization string */
   char         *ptr,                   /* Pointer into string */
-               bearer[2048],           /* CUPS_BEARER cookie string */
+               bearer[4096],           /* CUPS_BEARER cookie string */
                username[HTTP_MAX_VALUE],
                                        /* Username string */
                password[HTTP_MAX_VALUE];
@@ -351,7 +351,9 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
 
   authorization = httpGetField(con->http, HTTP_FIELD_AUTHORIZATION);
 
-  if (!*authorization && type == CUPSD_AUTH_BEARER && httpGetCookieValue(con->http, "CUPS_BEARER", bearer, sizeof(bearer)) && bearer[0])
+  cupsdLogClient(con, CUPSD_LOG_DEBUG2, "cookie=\"%s\"", httpGetCookie(con->http));
+
+  if (!*authorization && httpGetCookieValue(con->http, "CUPS_BEARER", bearer, sizeof(bearer)) && bearer[0])
     authorization = "Bearer COOKIE";
 
   username[0] = '\0';
index 33b2f6ec96dd416dfc2553f89cee5a033d8d3568..0db5e8f4977d221dfe1ab6cd632196522d53733a 100644 (file)
@@ -54,7 +54,7 @@ struct cupsd_client_s
   int                  sent_header,    /* Non-zero if sent HTTP header */
                        got_fields,     /* Non-zero if all fields seen */
                        header_used;    /* Number of header bytes used */
-  char                 header[2048];   /* Header from CGI program */
+  char                 header[4096];   /* Header from CGI program */
   cups_lang_t          *language;      /* Language to use */
   int                  auto_ssl;       /* Automatic test for SSL/TLS */
   http_addr_t          clientaddr;     /* Client's server address */
index 45fa904b8f0c6cb8d66207fc52c608b3a06e8816..d0f7f67ae4e53c615a944743d142c3de3ce4f426 100644 (file)
@@ -1,11 +1,12 @@
 /*
  * Status buffer definitions for the CUPS scheduler.
  *
- * Copyright © 2020-2024 by OpenPrinting.
- * Copyright 2007-2010 by Apple Inc.
- * Copyright 1997-2005 by Easy Software Products, all rights reserved.
+ * Copyright © 2020-2025 by OpenPrinting.
+ * Copyright © 2007-2010 by Apple Inc.
+ * Copyright © 1997-2005 by Easy Software Products, all rights reserved.
  *
- * Licensed under Apache License v2.0.  See the file "LICENSE" for more information.
+ * Licensed under Apache License v2.0.  See the file "LICENSE" for more
+ * information.
  */
 
 
@@ -13,7 +14,7 @@
  * Constants...
  */
 
-#define CUPSD_SB_BUFFER_SIZE   2048    /* Bytes for job status buffer */
+#define CUPSD_SB_BUFFER_SIZE   4096    /* Bytes for job status buffer */
 
 
 /*