Skip to content

Commit 0bb901d

Browse files
committed
Update documentation:
- New authentication/authorization content (for OAuth esp.) - Normalize use of "argument" instead of "parameter" when describing function arguments. - Expand documentation for many functions.
1 parent 3dc8878 commit 0bb901d

12 files changed

Lines changed: 719 additions & 312 deletions

File tree

cups/cupspm.md

Lines changed: 206 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -925,7 +925,7 @@ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
925925
> **Note:**
926926
>
927927
> If we wanted to query the scheduler instead of the device, we would look
928-
> up the "printer-uri-supported" option instead of the "device-uri" value.
928+
> up the "printer-uri-supported" option instead of the "device-uri" option.
929929

930930
The [`ippAddString`](@@) function adds the "printer-uri" attribute the the IPP
931931
request. The `IPP_TAG_OPERATION` argument specifies that the attribute is part
@@ -947,15 +947,15 @@ static const char * const requested_attributes[] =
947947
};
948948
949949
ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
950-
"requested-attributes", 3, NULL,
950+
"requested-attributes", /*num_values*/3, /*language*/NULL,
951951
requested_attributes);
952952
```
953953

954954
The [`ippAddStrings`](@@) function adds an attribute with one or more strings,
955955
in this case three. The `IPP_TAG_KEYWORD` argument specifies that the strings
956956
are keyword values, which are used for attribute names. All strings use the
957-
same language (`NULL`), and the attribute will contain the three strings in the
958-
array `requested_attributes`.
957+
same language (`NULL`), and the attribute will contain the three strings from
958+
the array `requested_attributes`.
959959

960960
CUPS provides many functions to adding attributes of different types:
961961

@@ -1106,18 +1106,32 @@ Once you are done using the IPP response message, free it using the
11061106
ippDelete(response);
11071107

11081108

1109-
## Authentication
1109+
# Authentication and Authorization
11101110

1111-
CUPS normally handles authentication through the console. GUI applications
1112-
should set a password callback using the [`cupsSetPasswordCB`](@@) function:
1111+
CUPS supports authentication and authorization using HTTP Basic, HTTP Digest,
1112+
peer credentials when communicating over domain sockets, and OAuth/OpenID
1113+
Connect.
1114+
1115+
Peer credential authorization happens automatically when connected over a
1116+
domain socket. Other types of authentication requires the application to
1117+
handle `HTTP_STATUS_UNAUTHORIZED` responses beyond simply calling
1118+
[`cupsDoAuthentication`](@@).
1119+
1120+
1121+
## Authentication Using Passwords
1122+
1123+
When you call [`cupsDoAuthentication`](@@), CUPS normally requests a password
1124+
from the console. GUI applications should set a password callback using the
1125+
[`cupsSetPasswordCB`](@@) function:
11131126

11141127
```c
11151128
void
11161129
cupsSetPasswordCB(cups_password_cb_t cb, void *cb_data);
11171130
```
11181131

1119-
The password callback will be called when needed and is responsible for setting
1120-
the current user name using [`cupsSetUser`](@@) and returning a string:
1132+
The password callback is called when needed and is responsible for setting
1133+
the current user name using [`cupsSetUser`](@@) and returning a (password)
1134+
string:
11211135

11221136
```c
11231137
const char *
@@ -1143,6 +1157,189 @@ The "cb_data" argument provides the user data pointer from the
11431157
[`cupsSetPasswordCB`](@@) call.
11441158

11451159

1160+
## Authorization using OAuth/OpenID Connect
1161+
1162+
CUPS provides a generic OAuth/OpenID client for authorizing access to printers
1163+
and other network resources. The following functions are provided:
1164+
1165+
- [`cupsOAuthClearTokens`](@@): Clear all cached tokens.
1166+
- [`cupsOAuthCopyAccessToken`](@@): Copy the cached access token.
1167+
- [`cupsOAuthCopyClientId`](@@): Copy the cached client ID.
1168+
- [`cupsOAuthCopyRefreshToken`](@@): Copy the cached refresh token.
1169+
- [`cupsOAuthCopyUserId`](@@): Copy the cached user ID.
1170+
- [`cupsOAuthGetAuthorizationCode`](@@): Get an authorization code using a web
1171+
browser.
1172+
- [`cupsOAuthGetClientId`](@@): Get a client ID using dynamic client
1173+
registration.
1174+
- [`cupsOAuthGetDeviceGrant`](@@): Get a device authorization grant code.
1175+
- [`cupsOAuthGetJWKS`](@@): Get the key set for an authorization server.
1176+
- [`cupsOAuthGetMetadata`](@@): Get the metadata for an authorization server.
1177+
- [`cupsOAuthGetTokens`](@@): Get access and refresh tokens for an
1178+
authorization/grant code.
1179+
- [`cupsOAuthGetUserId`](@@): Get the user ID associated with an access token.
1180+
- [`cupsOAuthMakeAuthorizationURL`](@@): Make the URL for web browser
1181+
authorization.
1182+
- [`cupsOAuthMakeBase64Random`](@@): Make a Base64-encoded string of random
1183+
bytes.
1184+
- [`cupsOAuthSaveClientData`](@@): Save a client ID and secret for an
1185+
authorization server.
1186+
- [`cupsOAuthSaveTokens`](@@): Save access and refresh tokens for an
1187+
authorization server.
1188+
1189+
Once you have an access token you use the [`httpSetAuthString`](@@) function to
1190+
use it for a HTTP connection:
1191+
1192+
```c
1193+
http_t *http;
1194+
char *access_token;
1195+
1196+
httpSetAuthString(http, "Bearer", access_token);
1197+
```
1198+
1199+
1200+
### Authorizing Using a Web Browser
1201+
1202+
Users can authorize using their preferred web browser via the
1203+
[`cupsOAuthGetAuthorizationCode`](@@) function, which returns an authorization
1204+
grant code string. The following code gets the authorization server metadata,
1205+
authorizes access through the web browser, and then obtains a HTTP Bearer access
1206+
token:
1207+
1208+
```c
1209+
http_t *http; // HTTP connection
1210+
const char *auth_uri; // Base URL for Authorization Server
1211+
cups_json_t *metadata; // Authorization Server metadata
1212+
const char *printer_uri; // Printer URI
1213+
char *auth_code; // Authorization grant code
1214+
char *access_token; // Access token
1215+
time_t access_expires; // Date/time when access token expires
1216+
1217+
// Get the metadata for the authorization server.
1218+
metadata = cupsOAuthGetMetadata(auth_uri);
1219+
1220+
if (metadata == NULL)
1221+
{
1222+
// Handle error getting metadata from authorization server.
1223+
}
1224+
1225+
// Bring up the web browser to authorize and get an authorization code.
1226+
auth_code = cupsOAuthGetAuthorizationCode(auth_uri, metadata, printer_uri,
1227+
/*scopes*/NULL,
1228+
/*redirect_uri*/NULL);
1229+
1230+
if (auth_code == NULL)
1231+
{
1232+
// Unable to authorize.
1233+
}
1234+
1235+
// Get the access code from the authorization code.
1236+
access_token = cupsOAuthGetTokens(auth_uri, metadata, printer_uri, auth_code,
1237+
CUPS_OGRANT_AUTHORIZATION_CODE,
1238+
/*redirect_uri*/NULL, &access_expires);
1239+
1240+
if (access_token == NULL)
1241+
{
1242+
// Unable to get access token.
1243+
}
1244+
1245+
// Set the Bearer token for authorization.
1246+
httpSetAuthString(http, "Bearer", access_token);
1247+
```
1248+
1249+
1250+
### Authorizing Using a Mobile Device
1251+
1252+
Users can authorize using a mobile device via the
1253+
[`cupsOAuthGetDeviceGrant`](@@) function, which returns a JSON object with the
1254+
mobile authorization URLs, user (verification) code string, and device grant
1255+
code. The following code gets the authorization server metadata, gets the
1256+
mobile device authorization information, and then obtains a HTTP Bearer access
1257+
token:
1258+
1259+
```c
1260+
http_t *http; // HTTP connection
1261+
const char *auth_uri; // Base URL for Authorization Server
1262+
cups_json_t *metadata; // Authorization Server metadata
1263+
const char *printer_uri; // Printer URI
1264+
cups_json_t *device_grant; // Device authorization grant object
1265+
const char *device_code; // Device grant code
1266+
const char *verify_url; // Mobile device URL
1267+
const char *verify_urlc; // Mobile device URL with user code
1268+
const char *user_code; // User code
1269+
char *access_token; // Access token
1270+
time_t access_expires; // Date/time when access token expires
1271+
1272+
// Get the metadata for the authorization server.
1273+
metadata = cupsOAuthGetMetadata(auth_uri);
1274+
1275+
if (metadata == NULL)
1276+
{
1277+
// Handle error getting metadata from authorization server.
1278+
}
1279+
1280+
// Get a device authorization grant for mobile authorization.
1281+
device_grant = cupsOAuthGetDeviceGrant(auth_uri, metadata, printer_uri,
1282+
/*scopes*/NULL);
1283+
1284+
device_code = cupsJSONGetString(
1285+
cupsJSONFind(device_grant, CUPS_ODEVGRANT_DEVICE_CODE));
1286+
verify_url = cupsJSONGetString(
1287+
cupsJSONFind(device_grant, CUPS_ODEVGRANT_VERIFICATION_URI));
1288+
verify_urlc = cupsJSONGetString(
1289+
cupsJSONFind(device_grant, CUPS_ODEVGRANT_VERIFICATION_URI_COMPLETE));
1290+
user_code = cupsJSONGetString(
1291+
cupsJSONFind(device_grant, CUPS_ODEVGRANT_USER_CODE));
1292+
1293+
if (device_code == NULL || verify_url == NULL || verify_urlc == NULL ||
1294+
user_code == NULL)
1295+
{
1296+
// Unable to authorize.
1297+
}
1298+
1299+
// Show the URLs and user code to the user (links and/or QR codes).
1300+
printf("Open this URL: %s\n", verify_urlc);
1301+
1302+
// Get the access code from the authorization code.
1303+
do
1304+
{
1305+
// Delay check for several seconds.
1306+
sleep(5);
1307+
1308+
// Try getting an access token.
1309+
access_token = cupsOAuthGetTokens(auth_uri, metadata, printer_uri, device_code,
1310+
CUPS_OGRANT_DEVICE_CODE,
1311+
/*redirect_uri*/NULL, &access_expires);
1312+
}
1313+
while (access_token == NULL && access_expires > 0);
1314+
// Continue checking until we have an access token or
1315+
// the device code has expired.
1316+
1317+
if (access_token == NULL)
1318+
{
1319+
// Unable to get access token.
1320+
}
1321+
1322+
// Set the Bearer token for authorization.
1323+
httpSetAuthString(http, "Bearer", access_token);
1324+
```
1325+
1326+
1327+
### Supported OAuth Standards
1328+
1329+
The following standards are supported:
1330+
1331+
- [OpenID Connect Core v1.0](https://openid.net/specs/openid-connect-core-1_0.html)
1332+
- [RFC 6749: The OAuth 2.0 Authorization Framework](https://datatracker.ietf.org/doc/html/rfc6749)
1333+
- [RFC 6750: The OAuth 2.0 Authorization Framework: Bearer Token Usage](https://datatracker.ietf.org/doc/html/rfc6750)
1334+
- [RFC 7591: OAuth 2.0 Dynamic Client Registration Protocol](https://datatracker.ietf.org/doc/html/rfc7591)
1335+
- [RFC 7636: Proof Key for Code Exchange by OAuth Public Clients](https://datatracker.ietf.org/doc/html/rfc7636)
1336+
- [RFC 8252: OAuth 2.0 for Native Apps](https://datatracker.ietf.org/doc/html/rfc8252)
1337+
- [RFC 8414: OAuth 2.0 Authorization Server Metadata](https://datatracker.ietf.org/doc/html/rfc8414)
1338+
- [RFC 8628: OAuth 2.0 Device Authorization Grant](https://datatracker.ietf.org/doc/html/rfc8628)
1339+
- [RFC 8693: OAuth 2.0 Token Exchange](https://datatracker.ietf.org/doc/html/rfc8693)
1340+
- [RFC 9068: JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens](https://datatracker.ietf.org/doc/html/rfc9068)
1341+
1342+
11461343
# IPP Data File API
11471344

11481345
The IPP data file API provides functions to read and write IPP attributes and

cups/dest-options.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -826,7 +826,7 @@ cupsFreeDestInfo(cups_dinfo_t *dinfo) // I - Destination information
826826
// 'cupsGetDestMediaByIndex()' - Get a media name, dimension, and margins for a
827827
// specific size.
828828
//
829-
// The "flags" parameter determines which set of media are indexed. For
829+
// The "flags" argument determines which set of media are indexed. For
830830
// example, passing `CUPS_MEDIA_FLAGS_BORDERLESS` will get the Nth borderless
831831
// size supported by the printer.
832832
//
@@ -1023,7 +1023,7 @@ cupsGetDestMediaBySize(
10231023
// 'cupsGetDestMediaCount()' - Get the number of sizes supported by a
10241024
// destination.
10251025
//
1026-
// The "flags" parameter determines the set of media sizes that are counted.
1026+
// The "flags" argument determines the set of media sizes that are counted.
10271027
// For example, passing `CUPS_MEDIA_FLAGS_BORDERLESS` will return the number of
10281028
// borderless sizes.
10291029
//
@@ -1060,7 +1060,7 @@ cupsGetDestMediaCount(
10601060
//
10611061
// 'cupsGetDestMediaDefault()' - Get the default size for a destination.
10621062
//
1063-
// The "flags" parameter determines which default size is returned. For
1063+
// The "flags" argument determines which default size is returned. For
10641064
// example, passing `CUPS_MEDIA_FLAGS_BORDERLESS` will return the default
10651065
// borderless size, typically US Letter or A4, but sometimes 4x6 photo media.
10661066
//

cups/dnssd.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -548,9 +548,9 @@ cupsDNSSDBrowseNew(
548548
// 'cupsDNSSDCopyComputerName()' - Copy the current human-readable name for the system.
549549
//
550550
// This function copies the current human-readable name ("My Computer") to the
551-
// provided buffer. The "dnssd" parameter is a DNS-SD context created with
552-
// @link cupsDNSSDNew@. The "buffer" parameter points to a character array of
553-
// at least 128 bytes and the "bufsize" parameter specifies the actual size of
551+
// provided buffer. The "dnssd" argument is a DNS-SD context created with
552+
// @link cupsDNSSDNew@. The "buffer" argument points to a character array of
553+
// at least 128 bytes and the "bufsize" argument specifies the actual size of
554554
// the array.
555555
//
556556

@@ -618,9 +618,9 @@ cupsDNSSDCopyComputerName(
618618
// 'cupsDNSSDCopyHostName()' - Copy the current mDNS hostname for the system.
619619
//
620620
// This function copies the current mDNS hostname ("hostname.local") to the
621-
// provided buffer. The "dnssd" parameter is a DNS-SD context created with
622-
// @link cupsDNSSDNew@. The "buffer" parameter points to a character array of
623-
// at least 70 bytes and the "bufsize" parameter specifies the actual size of
621+
// provided buffer. The "dnssd" argument is a DNS-SD context created with
622+
// @link cupsDNSSDNew@. The "buffer" argument points to a character array of
623+
// at least 70 bytes and the "bufsize" argument specifies the actual size of
624624
// the array.
625625
//
626626

@@ -956,7 +956,7 @@ cupsDNSSDQueryGetContext(
956956
// 'cupsDNSSDQueryNew()' - Create a new query request.
957957
//
958958
// This function creates a new DNS-SD query request for the specified full
959-
// service name and DNS record type. The "fullname" parameter specifies the
959+
// service name and DNS record type. The "fullname" argument specifies the
960960
// full DNS name of the service (instance name, type, and domain) being queried.
961961
// Responses to the query are reported using the required query callback
962962
// function with the "flags" argument set to `CUPS_DNSSD_FLAGS_NONE` on success
@@ -2347,7 +2347,7 @@ mdns_strerror(
23472347
return ("Out of memory");
23482348

23492349
case kDNSServiceErr_BadParam :
2350-
return ("Bad parameter");
2350+
return ("Bad argument");
23512351

23522352
case kDNSServiceErr_BadReference :
23532353
return ("Bad service reference");

cups/file.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,7 @@ cupsFileNumber(cups_file_t *fp) // I - CUPS file
604604
//
605605
// The "filename" argument is a filename or socket address.
606606
//
607-
// The "mode" parameter can be "r" to read, "w" to write, overwriting any
607+
// The "mode" argument can be "r" to read, "w" to write, overwriting any
608608
// existing file, "a" to append to an existing file or create a new file,
609609
// or "s" to open a socket connection.
610610
//

cups/http-support.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,7 @@ httpDecode64(char *out, // I - String to write to
536536
// 'httpEncode64()' - Base64-encode a string.
537537
//
538538
// This function encodes a Base64 string as defined by RFC 4648. The "url"
539-
// parameter controls whether the original Base64 ("url" = `false`) or the
539+
// argument controls whether the original Base64 ("url" = `false`) or the
540540
// Base64url ("url" = `true`) alphabet is used.
541541
//
542542

@@ -1485,13 +1485,13 @@ _httpEncodeURI(char *dst, // I - Destination buffer
14851485
//
14861486
// This function resolves a DNS-SD URI of the form
14871487
// "scheme://service-instance-name._protocol._tcp.domain/...". The "options"
1488-
// parameter specifies a bitfield of resolution options including:
1488+
// argument specifies a bitfield of resolution options including:
14891489
//
14901490
// - `HTTP_RESOLVE_DEFAULT`: Use default options
14911491
// - `HTTP_RESOLVE_FQDN`: Resolve the fully-qualified domain name instead of an IP address
14921492
// - `HTTP_RESOLVE_FAXOUT`: Resolve the FaxOut service instead of Print (IPP/IPPS)
14931493
//
1494-
// The "cb" parameter specifies a callback that allows resolution to be
1494+
// The "cb" argument specifies a callback that allows resolution to be
14951495
// terminated. The callback is provided the "cb_data" value and returns a
14961496
// `bool` value that is `true` to continue and `false` to stop. If no callback
14971497
// is specified ("cb" is `NULL`), then this function will block up to 90 seconds

cups/http.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2955,8 +2955,8 @@ httpWrite(http_t *http, // I - HTTP connection
29552955
// 'httpWriteRequest()' - Write a HTTP request.
29562956
//
29572957
// This function writes a HTTP request to the specified connection. The
2958-
// "method" parameter specifies the HTTP method ("GET", "POST", "PUT", etc)
2959-
// while the "uri" parameter specifies the request URI. All fields must be
2958+
// "method" argument specifies the HTTP method ("GET", "POST", "PUT", etc)
2959+
// while the "uri" argument specifies the request URI. All fields must be
29602960
// set using the @link httpSetCookie@, @link httpSetField@, and
29612961
// @link httpSetLength@ functions prior to writing the request.
29622962
//

cups/ipp-support.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -834,7 +834,7 @@ ippAttributeString(
834834
// registered values are supported in addition to the CUPS IPP extension
835835
// attributes.
836836
//
837-
// The "request" parameter specifies the request message that was read from
837+
// The "request" argument specifies the request message that was read from
838838
// the client.
839839
//
840840
// `NULL` is returned if all attributes should be returned. Otherwise, the

0 commit comments

Comments
 (0)