From fafb9504ed0af0c0f22555319f4e3a8319900f56 Mon Sep 17 00:00:00 2001 From: Michael R Sweet Date: Wed, 20 Nov 2024 13:57:49 -0500 Subject: [PATCH] Add --bearer-token and --client-name options to ipptool. --- CHANGES.md | 2 ++ doc/help/man-ipptool.html | 13 ++++++++ man/ipptool.1 | 15 ++++++++- tools/ipptool.c | 66 ++++++++++++++++++++++++++++++++++++++- 4 files changed, 94 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 026fb95a5..5d3c7eae0 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -64,6 +64,8 @@ Changes in CUPS v2.5b1 (YYYY-MM-DD) (Issue #1061) - Updated the raster functions to report more issues via `cupsRasterGetErrorString`. +- Updated the `ipptool` utility to support the `--bearer-token` and + `--client-name` options. - Deprecated the "page-border" Job Template attribute (Issue #1020) - Fixed use-after-free in `cupsdAcceptClient()` when we log warning during error handling (fixes CVE-2023-34241) diff --git a/doc/help/man-ipptool.html b/doc/help/man-ipptool.html index 340c632dc..5031b83aa 100644 --- a/doc/help/man-ipptool.html +++ b/doc/help/man-ipptool.html @@ -14,6 +14,12 @@

Synopsis

[ --help ] [ +--bearer-token +BEARER-TOKEN +] [ +--client-name +CLIENT-NAME +] [ --ippfile FILENAME ] [ @@ -96,6 +102,13 @@

Description

Options

The following options are recognized by ipptool: +

+

--bearer-token BEARER-TOKEN
+Specifies the OAuth 2.0 token to use for HTTP Bearer authentication (RFC 6750). +

+

--client-namne CLIENT-NAME
+Specifies the client name to use for the TLS client certificate. +If not specified, no client certificate is used during negotiation.

--help
Shows program help. diff --git a/man/ipptool.1 b/man/ipptool.1 index e46ecbc8d..c08a367fa 100644 --- a/man/ipptool.1 +++ b/man/ipptool.1 @@ -7,7 +7,7 @@ .\" Licensed under Apache License v2.0. See the file "LICENSE" for more .\" information. .\" -.TH ipptool 1 "CUPS" "2024-09-12" "OpenPrinting" +.TH ipptool 1 "CUPS" "2024-11-20" "OpenPrinting" .SH NAME ipptool \- perform internet printing protocol requests .SH SYNOPSIS @@ -15,6 +15,12 @@ ipptool \- perform internet printing protocol requests [ .B \-\-help ] [ +.B \-\-bearer\-token +.I BEARER-TOKEN +] [ +.B \-\-client\-name +.I CLIENT-NAME +] [ .B \-\-ippfile .I FILENAME ] [ @@ -95,6 +101,13 @@ format is described in The following options are recognized by .B ipptool: .TP 5 +\fB\-\-bearer\-token \fIBEARER-TOKEN\fR +Specifies the OAuth 2.0 token to use for HTTP Bearer authentication (RFC 6750). +.TP 5 +\fB\-\-client\-namne \fICLIENT-NAME\fR +Specifies the client name to use for the TLS client certificate. +If not specified, no client certificate is used during negotiation. +.TP 5 .B \-\-help Shows program help. .TP 5 diff --git a/tools/ipptool.c b/tools/ipptool.c index 932d6a3a3..326cfe598 100644 --- a/tools/ipptool.c +++ b/tools/ipptool.c @@ -152,6 +152,9 @@ typedef struct ipptool_test_s // Test Data bool validate_headers; // Validate HTTP headers in response? int verbosity; // Show all attributes? + char *bearer_token, // HTTP Bearer token + *client_name; // TLS client certificate name + // Test Defaults bool def_ignore_errors; // Default IGNORE-ERRORS value ipptool_transfer_t def_transfer; // Default TRANSFER value @@ -253,6 +256,7 @@ static ipp_attribute_t *print_line(ipptool_test_t *data, ipp_t *ipp, ipp_attribu static void print_xml_header(ipptool_test_t *data); static void print_xml_string(cups_file_t *outfile, const char *element, const char *s); static void print_xml_trailer(ipptool_test_t *data, int success, const char *message); +static void set_client_certificate(ipptool_test_t *data); #ifndef _WIN32 static void sigterm_handler(int sig); #endif // _WIN32 @@ -313,7 +317,33 @@ main(int argc, // I - Number of command-line args for (i = 1; i < argc; i ++) { - if (!strcmp(argv[i], "--help")) + if (!strcmp(argv[i], "--bearer-token")) + { + i ++; + + if (i >= argc) + { + cupsLangPrintf(stderr, _("%s: Missing token after '--bearer-token'."), "ipptool"); + free_data(data); + usage(); + } + + data->bearer_token = argv[i]; + } + else if (!strcmp(argv[i], "--client-name")) + { + i ++; + + if (i >= argc) + { + cupsLangPrintf(stderr, _("%s: Missing client name after '--client-name'."), "ipptool"); + free_data(data); + usage(); + } + + data->client_name = argv[i]; + } + else if (!strcmp(argv[i], "--help")) { free_data(data); usage(); @@ -958,6 +988,9 @@ connect_printer(ipptool_test_t *data) // I - Test data return (NULL); } + if (data->client_name) + set_client_certificate(data); + if (!_cups_strcasecmp(scheme, "https") || !_cups_strcasecmp(scheme, "ipps") || atoi(port) == 443) encryption = HTTP_ENCRYPTION_ALWAYS; else @@ -969,6 +1002,9 @@ connect_printer(ipptool_test_t *data) // I - Test data return (NULL); } + if (data->bearer_token) + httpSetAuthString(data->http, "Bearer", data->bearer_token); + httpSetDefaultField(data->http, HTTP_FIELD_ACCEPT_ENCODING, "deflate, gzip, identity"); if (data->timeout > 0.0) @@ -5013,6 +5049,29 @@ print_xml_trailer( } +// +// 'set_client_certificate()' - Set the client certificate and private key. +// + +static void +set_client_certificate( + ipptool_test_t *data) // I - Test data +{ + char *creds, // Public key/certificate + *key; // Private key + + + // Copy and set the client credentials for the given name... + creds = cupsCopyCredentials(/*path*/NULL, data->client_name); + key = cupsCopyCredentials(/*path*/NULL, data->client_name); + + cupsSetClientCredentials(creds, key); + + free(creds); + free(key); +} + + #ifndef _WIN32 // // 'sigterm_handler()' - Handle SIGINT and SIGTERM. @@ -6446,6 +6505,11 @@ usage(void) { _cupsLangPuts(stderr, _("Usage: ipptool [options] URI filename [ ... filenameN ]")); _cupsLangPuts(stderr, _("Options:")); + _cupsLangPuts(stderr, _("--bearer-token BEARER-TOKEN\n" + " Set the OAuth Bearer token for authentication")); + _cupsLangPuts(stderr, _("--client-name CLIENT-NAME\n" + " Set the TLS client certificate name")); + _cupsLangPuts(stderr, _("--help Show this help")); _cupsLangPuts(stderr, _("--ippserver filename Produce ippserver attribute file")); _cupsLangPuts(stderr, _("--stop-after-include-error\n" " Stop tests after a failed INCLUDE"));