From: Michael R Sweet Date: Mon, 15 Apr 2019 21:22:25 +0000 (-0400) Subject: Add UserAgentTokens config directive (Issue #5555) X-Git-Tag: v2.3b8~54 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=59cd12c6d2cea932f3133e6cb2bf710262be3f57;p=thirdparty%2Fcups.git Add UserAgentTokens config directive (Issue #5555) cups/cups-private.h: - Add enum and value for UserAgentTokens directive. cups/usersys.c: - _cups_finalize_conf(): Copy UserAgentTokens value to globals. - _cups_init_conf(): Set default UserAgentTokens value and grab prefs. - _cups_read_conf(): Look for UserAgentTokens value. - _cups_set_uatokens(): Set UserAgentTokens value. - cupsSetUserAgent(): Support UserAgentTokens values. --- diff --git a/CHANGES.md b/CHANGES.md index 37a5d0fe2f..ae874c2b5b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -15,6 +15,7 @@ Changes in CUPS v2.3b8 for the print filters (Issue #5558) - The `cupsCheckDestSupported` function did not check octetString values correctly (Issue #5557) +- Added support for `UserAgentTokens` directive in "client.conf" (Issue #5555) - Updated the systemd service file for cupsd (Issue #5551) - The `ippValidateAttribute` function did not catch all instances of invalid UTF-8 strings (Issue #5509) diff --git a/cups/cups-private.h b/cups/cups-private.h index 2b363e6d63..f1b052a307 100644 --- a/cups/cups-private.h +++ b/cups/cups-private.h @@ -1,7 +1,7 @@ /* * Private definitions for CUPS. * - * Copyright © 2007-2018 by Apple Inc. + * Copyright © 2007-2019 by Apple Inc. * Copyright © 1997-2007 by Easy Software Products, all rights reserved. * * Licensed under Apache License v2.0. See the file "LICENSE" for more @@ -57,6 +57,17 @@ typedef struct _cups_raster_error_s /**** Error buffer structure ****/ *end; /* End of buffer */ } _cups_raster_error_t; +typedef enum _cups_uatokens_e /**** UserAgentTokens values */ +{ + _CUPS_UATOKENS_NONE, /* Do not send User-Agent */ + _CUPS_UATOKENS_PRODUCT_ONLY, /* CUPS IPP */ + _CUPS_UATOKENS_MAJOR, /* CUPS/major IPP/2 */ + _CUPS_UATOKENS_MINOR, /* CUPS/major.minor IPP/2.1 */ + _CUPS_UATOKENS_MINIMAL, /* CUPS/major.minor.patch IPP/2.1 */ + _CUPS_UATOKENS_OS, /* CUPS/major.minor.patch (osname osversion) IPP/2.1 */ + _CUPS_UATOKENS_FULL /* CUPS/major.minor.patch (osname osversion; architecture) IPP/2.1 */ +} _cups_uatokens_t; + typedef struct _cups_globals_s /**** CUPS global state data ****/ { /* Multiple places... */ @@ -146,6 +157,7 @@ typedef struct _cups_globals_s /**** CUPS global state data ****/ char tempfile[1024]; /* cupsTempFd/File buffer */ /* usersys.c */ + _cups_uatokens_t uatokens; /* UserAgentTokens setting */ http_encryption_t encryption; /* Encryption setting */ char user[65], /* User name */ user_agent[256],/* User-Agent string */ diff --git a/cups/usersys.c b/cups/usersys.c index 6b2833766d..497681e274 100644 --- a/cups/usersys.c +++ b/cups/usersys.c @@ -40,6 +40,7 @@ # define kCUPSPrintingPrefs CFSTR(".GlobalPreferences") # define kPREFIX "AirPrint" # endif /* TARGET_OS_OSX */ +# define kUserAgentTokensKey CFSTR(kPREFIX "UserAgentTokens") # define kAllowAnyRootKey CFSTR(kPREFIX "AllowAnyRoot") # define kAllowExpiredCertsKey CFSTR(kPREFIX "AllowExpiredCerts") # define kEncryptionKey CFSTR(kPREFIX "Encryption") @@ -62,6 +63,7 @@ typedef struct _cups_client_conf_s /**** client.conf config data ****/ { + _cups_uatokens_t uatokens; /* UserAgentTokens values */ #ifdef HAVE_SSL int ssl_options, /* SSLOptions values */ ssl_min_version,/* Minimum SSL/TLS version */ @@ -103,6 +105,7 @@ static void cups_set_server_name(_cups_client_conf_t *cc, const char *value); #ifdef HAVE_SSL static void cups_set_ssl_options(_cups_client_conf_t *cc, const char *value); #endif /* HAVE_SSL */ +static void cups_set_uatokens(_cups_client_conf_t *cc, const char *value); static void cups_set_user(_cups_client_conf_t *cc, const char *value); @@ -518,6 +521,29 @@ cupsSetUserAgent(const char *user_agent)/* I - User-Agent string or @code NULL@ return; } + if (cg->uatokens < _CUPS_UATOKENS_OS) + { + switch (cg->uatokens) + { + default : + case _CUPS_UATOKENS_NONE : + cg->user_agent[0] = '\0'; + break; + case _CUPS_UATOKENS_PRODUCT_ONLY : + strlcpy(cg->user_agent, "CUPS IPP", sizeof(cg->user_agent)); + break; + case _CUPS_UATOKENS_MAJOR : + snprintf(cg->user_agent, sizeof(cg->user_agent), "CUPS/%d IPP/2", CUPS_VERSION_MAJOR); + break; + case _CUPS_UATOKENS_MINOR : + snprintf(cg->user_agent, sizeof(cg->user_agent), "CUPS/%d.%d IPP/2.1", CUPS_VERSION_MAJOR, CUPS_VERSION_MINOR); + break; + case _CUPS_UATOKENS_MINIMAL : + strlcpy(cg->user_agent, CUPS_MINIMAL " IPP/2.1", sizeof(cg->user_agent)); + break; + } + } + #ifdef _WIN32 /* * Gather Windows version information for the User-Agent string... @@ -550,7 +576,10 @@ cupsSetUserAgent(const char *user_agent)/* I - User-Agent string or @code NULL@ break; } - snprintf(cg->user_agent, sizeof(cg->user_agent), CUPS_MINIMAL " (Windows %d.%d; %s) IPP/2.0", version.dwMajorVersion, version.dwMinorVersion, machine); + if (cg->uatokens == _CUPS_UATOKENS_OS) + snprintf(cg->user_agent, sizeof(cg->user_agent), CUPS_MINIMAL " (Windows %d.%d) IPP/2.0", version.dwMajorVersion, version.dwMinorVersion); + else + snprintf(cg->user_agent, sizeof(cg->user_agent), CUPS_MINIMAL " (Windows %d.%d; %s) IPP/2.0", version.dwMajorVersion, version.dwMinorVersion, machine); #elif defined(__APPLE__) /* @@ -566,9 +595,16 @@ cupsSetUserAgent(const char *user_agent)/* I - User-Agent string or @code NULL@ strlcpy(version, "unknown", sizeof(version)); # if TARGET_OS_OSX - snprintf(cg->user_agent, sizeof(cg->user_agent), CUPS_MINIMAL " (macOS %s; %s) IPP/2.0", version, name.machine); + if (cg->uatokens == _CUPS_UATOKENS_OS) + snprintf(cg->user_agent, sizeof(cg->user_agent), CUPS_MINIMAL " (macOS %s) IPP/2.0", version); + else + snprintf(cg->user_agent, sizeof(cg->user_agent), CUPS_MINIMAL " (macOS %s; %s) IPP/2.0", version, name.machine); + # else - snprintf(cg->user_agent, sizeof(cg->user_agent), CUPS_MINIMAL " (iOS %s; %s) IPP/2.0", version, name.machine); + if (cg->uatokens == _CUPS_UATOKENS_OS) + snprintf(cg->user_agent, sizeof(cg->user_agent), CUPS_MINIMAL " (iOS %s) IPP/2.0", version); + else + snprintf(cg->user_agent, sizeof(cg->user_agent), CUPS_MINIMAL " (iOS %s; %s) IPP/2.0", version, name.machine); # endif /* TARGET_OS_OSX */ #else @@ -578,7 +614,10 @@ cupsSetUserAgent(const char *user_agent)/* I - User-Agent string or @code NULL@ uname(&name); - snprintf(cg->user_agent, sizeof(cg->user_agent), CUPS_MINIMAL " (%s %s; %s) IPP/2.0", name.sysname, name.release, name.machine); + if (cg->uatokens == _CUPS_UATOKENS_OS) + snprintf(cg->user_agent, sizeof(cg->user_agent), CUPS_MINIMAL " (%s %s) IPP/2.0", name.sysname, name.release); + else + snprintf(cg->user_agent, sizeof(cg->user_agent), CUPS_MINIMAL " (%s %s; %s) IPP/2.0", name.sysname, name.release, name.machine); #endif /* _WIN32 */ } @@ -980,6 +1019,8 @@ _cupsSetDefaults(void) cups_finalize_client_conf(&cc); + cg->uatokens = cc.uatokens; + if (cg->encryption == (http_encryption_t)-1) cg->encryption = cc.encryption; @@ -1222,6 +1263,8 @@ cups_init_client_conf( memset(cc, 0, sizeof(_cups_client_conf_t)); + cc->uatokens = _CUPS_UATOKENS_MINIMAL; + #if defined(__APPLE__) && !TARGET_OS_OSX cups_set_user(cc, "mobile"); #endif /* __APPLE__ && !TARGET_OS_OSX */ @@ -1241,8 +1284,9 @@ cups_init_client_conf( * everything...) */ -#if defined(__APPLE__) && defined(HAVE_SSL) +#if defined(__APPLE__) char sval[1024]; /* String value */ +# ifdef HAVE_SSL int bval; /* Boolean value */ if (cups_apple_get_boolean(kAllowAnyRootKey, &bval)) @@ -1278,7 +1322,13 @@ cups_init_client_conf( if (cups_apple_get_boolean(kValidateCertsKey, &bval)) cc->validate_certs = bval; -#endif /* __APPLE__ && HAVE_SSL */ +# endif /* HAVE_SSL */ + + if (cups_apple_get_string(kUserAgentTokensKey, sval, sizeof(sval))) + { + cups_set_uatokens(cc, sval); + } +#endif /* __APPLE__ */ } @@ -1315,6 +1365,8 @@ cups_read_client_conf( #endif /* !__APPLE__ */ else if (!_cups_strcasecmp(line, "User") && value) cups_set_user(cc, value); + else if (!_cups_strcasecmp(line, "UserAgentTokens") && value) + cups_set_uatokens(cc, value); else if (!_cups_strcasecmp(line, "TrustOnFirstUse") && value) cc->trust_first = cups_boolean_value(value); else if (!_cups_strcasecmp(line, "AllowAnyRoot") && value) @@ -1484,6 +1536,38 @@ cups_set_ssl_options( #endif /* HAVE_SSL */ +/* + * 'cups_set_uatokens()' - Set the UserAgentTokens value. + */ + +static void +cups_set_uatokens( + _cups_client_conf_t *cc, /* I - client.conf values */ + const char *value) /* I - Value */ +{ + int i; /* Looping var */ + static const char * const uatokens[] =/* UserAgentTokens values */ + { + "NONE", + "PRODUCTONLY", + "MAJOR", + "MINOR", + "MINIMAL", + "OS", + "FULL" + }; + + for (i = 0; i < (int)(sizeof(uatokens) / sizeof(uatokens[0])); i ++) + { + if (!_cups_strcasecmp(value, uatokens[i])) + { + cc->uatokens = (_cups_uatokens_t)i; + return; + } + } +} + + /* * 'cups_set_user()' - Set the User value. */ diff --git a/man/client.conf.man.in b/man/client.conf.man.in index cb93160fcc..f30f0a7fe3 100644 --- a/man/client.conf.man.in +++ b/man/client.conf.man.in @@ -6,7 +6,7 @@ .\" .\" Licensed under Apache License v2.0. See the file "LICENSE" for more information. .\" -.TH client.conf 5 "CUPS" "3 November 2017" "Apple Inc." +.TH client.conf 5 "CUPS" "15 April 2019" "Apple Inc." .SH NAME client.conf \- client configuration file for cups .SH DESCRIPTION @@ -76,6 +76,30 @@ The default is "Yes". .TP 5 \fBUser \fIname\fR Specifies the default user name to use for requests. +.\"#UserAgentTokens +.TP 5 +\fBUserAgentTokens None\fR +.TP 5 +\fBUserAgentTokens ProductOnly\fR +.TP 5 +\fBUserAgentTokens Major\fR +.TP 5 +\fBUserAgentTokens Minor\fR +.TP 5 +\fBUserAgentTokens Minimal\fR +.TP 5 +\fBUserAgentTokens OS\fR +.TP 5 +\fBUserAgentTokens Full\fR +Specifies what information is included in the User-Agent header of HTTP requests. +"None" disables the User-Agent header. +"ProductOnly" reports "CUPS". +"Major" reports "CUPS/major IPP/2". +"Minor" reports "CUPS/major.minor IPP/2.1". +"Minimal" reports "CUPS/major.minor.patch IPP/2.1". +"OS" reports "CUPS/major.minor.path (osname osversion) IPP/2.1". +"Full" reports "CUPS/major.minor.path (osname osversion; architecture) IPP/2.1". +The default is "Minimal". .TP 5 \fBValidateCerts Yes\fR .TP 5 diff --git a/man/cupsd.conf.man.in b/man/cupsd.conf.man.in index c9b5a287b3..cea1cbdbe9 100644 --- a/man/cupsd.conf.man.in +++ b/man/cupsd.conf.man.in @@ -7,7 +7,7 @@ .\" Licensed under Apache License v2.0. See the file "LICENSE" for more .\" information. .\" -.TH cupsd.conf 5 "CUPS" "8 November 2018" "Apple Inc." +.TH cupsd.conf 5 "CUPS" "15 April 2019" "Apple Inc." .SH NAME cupsd.conf \- server configuration file for cups .SH DESCRIPTION @@ -418,13 +418,11 @@ command. Specifies what information is included in the Server header of HTTP responses. "None" disables the Server header. "ProductOnly" reports "CUPS". -"Major" reports "CUPS 2". -"Minor" reports "CUPS 2.0". -"Minimal" reports "CUPS 2.0.0". -"OS" reports "CUPS 2.0.0 (UNAME)" where UNAME is the output of the -.BR uname (1) -command. -"Full" reports "CUPS 2.0.0 (UNAME) IPP/2.0". +"Major" reports "CUPS/major IPP/2". +"Minor" reports "CUPS/major.minor IPP/2.1". +"Minimal" reports "CUPS/major.minor.patch IPP/2.1". +"OS" reports "CUPS/major.minor.path (osname osversion) IPP/2.1". +"Full" reports "CUPS/major.minor.path (osname osversion; architecture) IPP/2.1". The default is "Minimal". .\"#SSLListen .TP 5