]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
Initial implementation of OAuth client callback (Issue #100) 268/head
authorMichael R Sweet <michael.r.sweet@gmail.com>
Mon, 4 Oct 2021 21:37:41 +0000 (17:37 -0400)
committerMichael R Sweet <michael.r.sweet@gmail.com>
Mon, 4 Oct 2021 21:37:41 +0000 (17:37 -0400)
CHANGES.md
cups/auth.c
cups/cups-private.h
cups/cups.h
cups/usersys.c
cups/versioning.h

index 30012b3ea1799d6355930fd1ab61d1312c134e64..7d1f214724a96eb6a4039d184ad1afa9d10f2f37 100644 (file)
@@ -5,6 +5,7 @@ CUPS v2.4-b1 (Pending)
 ----------------------
 
 - Added support for CUPS running in a Snapcraft snap.
+- Added basic OAuth 2.0 client support (Issue #100)
 - Added support for AirPrint and Mopria clients (Issue #105)
 - Added configure support for specifying systemd dependencies in the CUPS
   service file (Issue #144)
index d70622ca5fd0c58c623387338845e7d64faa2c68..177eec8ce3593d5ea04030d8e2bcecf316acb1c5 100644 (file)
@@ -1,13 +1,15 @@
 /*
  * Authentication functions for CUPS.
  *
- * Copyright 2007-2019 by Apple Inc.
- * Copyright 1997-2007 by Easy Software Products.
+ * Copyright © 2021 by OpenPrinting.
+ * Copyright © 2007-2019 by Apple Inc.
+ * Copyright © 1997-2007 by Easy Software Products.
  *
  * This file contains Kerberos support code, copyright 2006 by
  * Jelmer Vernooij.
  *
- * 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.
  */
 
 /*
@@ -115,7 +117,7 @@ cupsDoAuthentication(
   char         scheme[256],            /* Scheme name */
                prompt[1024];           /* Prompt for user */
   int          localauth;              /* Local authentication result */
-  _cups_globals_t *cg;                 /* Global data */
+  _cups_globals_t *cg = _cupsGlobals();        /* Global data */
 
 
   DEBUG_printf(("cupsDoAuthentication(http=%p, method=\"%s\", resource=\"%s\")", (void *)http, method, resource));
@@ -202,9 +204,38 @@ cupsDoAuthentication(
     }
     else
 #endif /* HAVE_GSSAPI */
-    if (_cups_strcasecmp(scheme, "Basic") &&
-       _cups_strcasecmp(scheme, "Digest") &&
-       _cups_strcasecmp(scheme, "Negotiate"))
+    if (!_cups_strcasecmp(scheme, "Bearer"))
+    {
+      // OAuth 2.0 (Bearer) authentication...
+      const char       *bearer = NULL; /* Bearer token string, if any */
+
+      if (cg->oauth_cb)
+      {
+        // Try callback...
+       char    scope[HTTP_MAX_VALUE];  /* scope="xyz" string */
+
+       cups_auth_param(schemedata, "realm", http->realm, sizeof(http->realm));
+
+       if (cups_auth_param(schemedata, "scope", scope, sizeof(scope)))
+         bearer = (cg->oauth_cb)(http, http->realm, scope, resource, cg->oauth_data);
+       else
+         bearer = (cg->oauth_cb)(http, http->realm, NULL, resource, cg->oauth_data);
+      }
+
+      if (bearer)
+      {
+        // Use this access token...
+        httpSetAuthString(http, "Bearer", bearer);
+        break;
+      }
+      else
+      {
+        // No access token, try the next scheme...
+        DEBUG_puts("2cupsDoAuthentication: No OAuth access token to provide.");
+        continue;
+      }
+    }
+    else if (_cups_strcasecmp(scheme, "Basic") && _cups_strcasecmp(scheme, "Digest") && _cups_strcasecmp(scheme, "Negotiate"))
     {
      /*
       * Other schemes not yet supported...
@@ -227,8 +258,6 @@ cupsDoAuthentication(
       char default_username[HTTP_MAX_VALUE];
                                        /* Default username */
 
-      cg = _cupsGlobals();
-
       if (!cg->lang_default)
        cg->lang_default = cupsLangDefault();
 
index 97734a539b12498f76ecac6e0fd1f74d20ebf0c0..cf2559d958decaa2efa358bf5abdf72d443a9653 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Private definitions for CUPS.
  *
+ * Copyright © 2021 by OpenPrinting.
  * Copyright © 2007-2019 by Apple Inc.
  * Copyright © 1997-2007 by Easy Software Products, all rights reserved.
  *
@@ -172,6 +173,8 @@ typedef struct _cups_globals_s              /**** CUPS global state data ****/
                        server[256],    /* Server address */
                        servername[256],/* Server hostname */
                        password[128];  /* Password for default callback */
+  cups_oauth_cb_t      oauth_cb;       /* OAuth callback */
+  void                 *oauth_data;    /* OAuth user data */
   cups_password_cb2_t  password_cb;    /* Password callback */
   void                 *password_data; /* Password user data */
   http_tls_credentials_t tls_credentials;
index 760a1a01c002c871a8ccc057064779ec15095092..9949e2ee766750d091433875fb4ef75075e9bccb 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * API definitions for CUPS.
  *
+ * Copyright © 2021 by OpenPrinting.
  * Copyright © 2007-2020 by Apple Inc.
  * Copyright © 1997-2007 by Easy Software Products.
  *
@@ -309,6 +310,9 @@ typedef int (^cups_dest_block_t)(unsigned flags, cups_dest_t *dest);
                                          * @exclude all@ */
 #  endif /* __BLOCKS__ */
 
+typedef const char *(*cups_oauth_cb_t)(http_t *http, const char *realm, const char *scope, const char *resource, void *user_data);
+                                       /* OAuth callback @since CUPS 2.4@ */
+
 typedef const char *(*cups_password_cb_t)(const char *prompt);
                                        /* Password callback @exclude all@ */
 
@@ -604,6 +608,10 @@ extern const char  *cupsHashString(const unsigned char *hash, size_t hashsize, ch
 extern int             cupsAddDestMediaOptions(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, unsigned flags, cups_size_t *size, int num_options, cups_option_t **options) _CUPS_API_2_3;
 extern ipp_attribute_t *cupsEncodeOption(ipp_t *ipp, ipp_tag_t group_tag, const char *name, const char *value) _CUPS_API_2_3;
 
+/* New in CUPS 2.4 */
+extern void            cupsSetOAuthCB(cups_oauth_cb_t cb, void *data) _CUPS_API_2_4;
+
+
 #  ifdef __cplusplus
 }
 #  endif /* __cplusplus */
index a5553ad44c6a827bf4c0bd30233686866f63331c..a9386e7f10fc35d40bbfb9c2d6457f150004ce36 100644 (file)
@@ -309,6 +309,43 @@ cupsSetEncryption(http_encryption_t e)     /* I - New encryption preference */
 }
 
 
+/*
+ * 'cupsSetOAuthCB()' - Set the OAuth 2.0 callback for CUPS.
+ *
+ * This function sets the OAuth 2.0 callback for the various CUPS APIs that
+ * send HTTP requests. Pass @code NULL@ to restore the default (console-based)
+ * callback.
+ *
+ * The OAuth callback receives the HTTP connection, realm name, scope name (if
+ * any), resource path, and the "user_data" pointer for each request that
+ * requires an OAuth access token. The function then returns either the Bearer
+ * token string or `NULL` if no authorization could be obtained.
+ *
+ * Beyond reusing the Bearer token for subsequent requests on the same HTTP
+ * connection, no caching of the token is done by the CUPS library.  The
+ * callback can determine whether to refresh a cached token by examining any
+ * existing token returned by the @link httpGetAuthString@ function.
+ *
+ * Note: The current OAuth callback is tracked separately for each thread in a
+ * program. Multi-threaded programs that override the callback need to do so in
+ * each thread for the same callback to be used.
+ *
+ * @since CUPS 2.4@
+ */
+
+void
+cupsSetOAuthCB(
+    cups_oauth_cb_t cb,                        /* I - Callback function */
+    void            *user_data)                /* I - User data pointer */
+{
+  _cups_globals_t *cg = _cupsGlobals();        /* Pointer to library globals */
+
+
+  cg->oauth_cb   = cb;
+  cg->oauth_data = user_data;
+}
+
+
 /*
  * 'cupsSetPasswordCB()' - Set the password callback for CUPS.
  *
index 2ad9879f92a2524fdddf932ffb84e34e3452f3d9..ad398ed8b1c2882fb090125f58f5d20197e16ce2 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * API versioning definitions for CUPS.
  *
+ * Copyright © 2021 by OpenPrinting.
  * Copyright © 2007-2019 by Apple Inc.
  *
  * Licensed under Apache License v2.0.  See the file "LICENSE" for more
 #    define _CUPS_API_2_2_4 _CUPS_API_AVAILABLE(macos(10.13), ios(12.0)) _CUPS_PUBLIC
 #    define _CUPS_API_2_2_7 _CUPS_API_AVAILABLE(macos(10.14), ios(13.0)) _CUPS_PUBLIC
 #    define _CUPS_API_2_3 _CUPS_API_AVAILABLE(macos(10.14), ios(13.0)) _CUPS_PUBLIC
+#    define _CUPS_API_2_4 _CUPS_PUBLIC
 #  else
 #    define _CUPS_API_1_1_19 _CUPS_PUBLIC
 #    define _CUPS_API_1_1_20 _CUPS_PUBLIC
 #    define _CUPS_API_2_2_4 _CUPS_PUBLIC
 #    define _CUPS_API_2_2_7 _CUPS_PUBLIC
 #    define _CUPS_API_2_3 _CUPS_PUBLIC
+#    define _CUPS_API_2_4 _CUPS_PUBLIC
 #  endif /* __APPLE__ && !_CUPS_SOURCE */