----------------------
- 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)
/*
* 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.
*/
/*
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));
}
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...
char default_username[HTTP_MAX_VALUE];
/* Default username */
- cg = _cupsGlobals();
-
if (!cg->lang_default)
cg->lang_default = cupsLangDefault();
/*
* Private definitions for CUPS.
*
+ * Copyright © 2021 by OpenPrinting.
* Copyright © 2007-2019 by Apple Inc.
* Copyright © 1997-2007 by Easy Software Products, all rights reserved.
*
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;
/*
* API definitions for CUPS.
*
+ * Copyright © 2021 by OpenPrinting.
* Copyright © 2007-2020 by Apple Inc.
* Copyright © 1997-2007 by Easy Software Products.
*
* @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@ */
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 */
}
+/*
+ * '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.
*
/*
* 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 */