diff options
author | Michael R Sweet <michael.r.sweet@gmail.com> | 2021-04-05 15:57:50 -0400 |
---|---|---|
committer | Michael R Sweet <michael.r.sweet@gmail.com> | 2021-04-05 15:57:50 -0400 |
commit | 064e50fb06e83e6c1756e2a81c2fcbd4d6fca8e6 (patch) | |
tree | 45145c8db9a634af861cb1ed87a7378837e72763 /cups | |
parent | 6918883fba4942931dc455b32545d6edf18dec5c (diff) | |
download | cups-064e50fb06e83e6c1756e2a81c2fcbd4d6fca8e6.tar.gz |
Import all of the bug fixes from the OpenPrinting CUPS repository.
Import the improvements to ippeveprinter from OpenPrinting/ippsample.
Import the improvements to ippfind and ipptool from OpenPrinting/ippsample.
Diffstat (limited to 'cups')
-rw-r--r-- | cups/auth.c | 28 | ||||
-rw-r--r-- | cups/cups.h | 6 | ||||
-rw-r--r-- | cups/dest.c | 11 | ||||
-rw-r--r-- | cups/getifaddrs-internal.h | 1 | ||||
-rw-r--r-- | cups/hash.c | 2 | ||||
-rw-r--r-- | cups/http-addr.c | 2 | ||||
-rw-r--r-- | cups/http-addrlist.c | 10 | ||||
-rw-r--r-- | cups/http-support.c | 7 | ||||
-rw-r--r-- | cups/ipp-support.c | 4 | ||||
-rw-r--r-- | cups/ipp-vars.c | 20 | ||||
-rw-r--r-- | cups/ipp.c | 12 | ||||
-rw-r--r-- | cups/ppd-cache.c | 82 | ||||
-rw-r--r-- | cups/ppd-mark.c | 2 | ||||
-rw-r--r-- | cups/ppd-private.h | 2 | ||||
-rw-r--r-- | cups/ppd.c | 83 | ||||
-rw-r--r-- | cups/request.c | 4 | ||||
-rw-r--r-- | cups/snprintf.c | 9 | ||||
-rw-r--r-- | cups/testclient.c | 53 | ||||
-rw-r--r-- | cups/testdest.c | 5 | ||||
-rw-r--r-- | cups/tls-gnutls.c | 2 | ||||
-rw-r--r-- | cups/tls-sspi.c | 91 |
21 files changed, 292 insertions, 144 deletions
diff --git a/cups/auth.c b/cups/auth.c index db45bbba6..b6fec6b98 100644 --- a/cups/auth.c +++ b/cups/auth.c @@ -90,6 +90,7 @@ static void cups_gss_printf(OM_uint32 major_status, OM_uint32 minor_status, # define cups_gss_printf(major, minor, message) # endif /* DEBUG */ #endif /* HAVE_GSSAPI */ +static int cups_is_local_connection(http_t *http); static int cups_local_auth(http_t *http); @@ -174,10 +175,10 @@ cupsDoAuthentication( DEBUG_printf(("2cupsDoAuthentication: Trying scheme \"%s\"...", scheme)); #ifdef HAVE_GSSAPI - if (!_cups_strcasecmp(scheme, "Negotiate")) + if (!_cups_strcasecmp(scheme, "Negotiate") && !cups_is_local_connection(http)) { /* - * Kerberos authentication... + * Kerberos authentication to remote server... */ int gss_status; /* Auth status */ @@ -201,7 +202,9 @@ cupsDoAuthentication( } else #endif /* HAVE_GSSAPI */ - if (_cups_strcasecmp(scheme, "Basic") && _cups_strcasecmp(scheme, "Digest")) + if (_cups_strcasecmp(scheme, "Basic") && + _cups_strcasecmp(scheme, "Digest") && + _cups_strcasecmp(scheme, "Negotiate")) { /* * Other schemes not yet supported... @@ -215,7 +218,7 @@ cupsDoAuthentication( * See if we should retry the current username:password... */ - if ((http->digest_tries > 1 || !http->userpass[0]) && (!_cups_strcasecmp(scheme, "Basic") || (!_cups_strcasecmp(scheme, "Digest")))) + if (http->digest_tries > 1 || !http->userpass[0]) { /* * Nope - get a new password from the user... @@ -295,7 +298,7 @@ cupsDoAuthentication( } } - if (http->authstring) + if (http->authstring && http->authstring[0]) { DEBUG_printf(("1cupsDoAuthentication: authstring=\"%s\".", http->authstring)); @@ -916,6 +919,14 @@ cups_gss_printf(OM_uint32 major_status,/* I - Major status code */ # endif /* DEBUG */ #endif /* HAVE_GSSAPI */ +static int /* O - 0 if not a local connection */ + /* 1 if local connection */ +cups_is_local_connection(http_t *http) /* I - HTTP connection to server */ +{ + if (!httpAddrLocalhost(http->hostaddr) && _cups_strcasecmp(http->hostname, "localhost") != 0) + return 0; + return 1; +} /* * 'cups_local_auth()' - Get the local authorization certificate if @@ -958,7 +969,7 @@ cups_local_auth(http_t *http) /* I - HTTP connection to server */ * See if we are accessing localhost... */ - if (!httpAddrLocalhost(http->hostaddr) && _cups_strcasecmp(http->hostname, "localhost") != 0) + if (!cups_is_local_connection(http)) { DEBUG_puts("8cups_local_auth: Not a local connection!"); return (1); @@ -1032,11 +1043,6 @@ cups_local_auth(http_t *http) /* I - HTTP connection to server */ } # endif /* HAVE_AUTHORIZATION_H */ -# ifdef HAVE_GSSAPI - if (cups_auth_find(www_auth, "Negotiate")) - return (1); -# endif /* HAVE_GSSAPI */ - # if defined(SO_PEERCRED) && defined(AF_LOCAL) /* * See if we can authenticate using the peer credentials provided over a diff --git a/cups/cups.h b/cups/cups.h index 3793dfbe8..826e600bc 100644 --- a/cups/cups.h +++ b/cups/cups.h @@ -1,7 +1,7 @@ /* * API definitions for CUPS. * - * Copyright © 2007-2020 by Apple Inc. + * Copyright © 2007-2021 by Apple Inc. * Copyright © 1997-2007 by Easy Software Products. * * Licensed under Apache License v2.0. See the file "LICENSE" for more @@ -42,10 +42,10 @@ extern "C" { * Constants... */ -# define CUPS_VERSION 2.0304 +# define CUPS_VERSION 2.0305 # define CUPS_VERSION_MAJOR 2 # define CUPS_VERSION_MINOR 3 -# define CUPS_VERSION_PATCH 4 +# define CUPS_VERSION_PATCH 5 # define CUPS_BC_FD 3 /* Back-channel file descriptor for diff --git a/cups/dest.c b/cups/dest.c index cde987a09..4d0c25032 100644 --- a/cups/dest.c +++ b/cups/dest.c @@ -1839,7 +1839,10 @@ cupsGetNamedDest(http_t *http, /* I - Connection to server or @code CUPS_HTT cupsEnumDests(0, 1000, NULL, 0, 0, (cups_dest_cb_t)cups_name_cb, &data); if (!data.dest) + { + _cupsSetError(IPP_STATUS_ERROR_NOT_FOUND, _("The printer or class does not exist."), 1); return (NULL); + } dest = data.dest; } @@ -4366,5 +4369,13 @@ cups_queue_name( *nameptr++ = '_'; } + /* + * Remove an underscore if it is the last character and isn't the only + * character in the name... + */ + + if (nameptr > (name + 1) && nameptr[-1] == '_') + nameptr --; + *nameptr = '\0'; } diff --git a/cups/getifaddrs-internal.h b/cups/getifaddrs-internal.h index 35e98be77..4e20f73d9 100644 --- a/cups/getifaddrs-internal.h +++ b/cups/getifaddrs-internal.h @@ -25,6 +25,7 @@ # include <unistd.h> # include <fcntl.h> # include <sys/socket.h> +# include <netinet/in.h> # define CUPS_SOCAST # endif /* _WIN32 */ diff --git a/cups/hash.c b/cups/hash.c index 4fbb443db..c153c6655 100644 --- a/cups/hash.c +++ b/cups/hash.c @@ -199,7 +199,7 @@ cupsHashData(const char *algorithm, /* I - Algorithm name */ goto too_small; _cupsMD5Init(&state); - _cupsMD5Append(&state, data, datalen); + _cupsMD5Append(&state, data, (int)datalen); _cupsMD5Finish(&state, hash); return (16); diff --git a/cups/http-addr.c b/cups/http-addr.c index 86749c848..8e81c6f7d 100644 --- a/cups/http-addr.c +++ b/cups/http-addr.c @@ -243,7 +243,7 @@ httpAddrListen(http_addr_t *addr, /* I - Address to bind to */ * Listen... */ - if (listen(fd, 5)) + if (listen(fd, 128)) { _cupsSetHTTPError(HTTP_STATUS_ERROR); diff --git a/cups/http-addrlist.c b/cups/http-addrlist.c index 485c6f43d..89b3d92fb 100644 --- a/cups/http-addrlist.c +++ b/cups/http-addrlist.c @@ -238,7 +238,14 @@ httpAddrConnect2( } if (!addrlist && nfds == 0) + { +#ifdef _WIN32 + errno = WSAEHOSTDOWN; +#else + errno = EHOSTDOWN; +#endif // _WIN32 break; + } /* * See if we can connect to any of the addresses so far... @@ -369,6 +376,9 @@ httpAddrConnect2( remaining -= 250; } + if (remaining <= 0) + errno = ETIMEDOUT; + while (nfds > 0) { nfds --; diff --git a/cups/http-support.c b/cups/http-support.c index 63175145e..49557300e 100644 --- a/cups/http-support.c +++ b/cups/http-support.c @@ -841,6 +841,13 @@ httpGetDateTime(const char *s) /* I - Date/time string */ "min=%d, sec=%d", day, mon, year, hour, min, sec)); /* + * Check for invalid year (RFC 7231 says it's 4DIGIT) + */ + + if (year > 9999) + return (0); + + /* * Convert the month name to a number from 0 to 11. */ diff --git a/cups/ipp-support.c b/cups/ipp-support.c index bfb9dff09..d9e900649 100644 --- a/cups/ipp-support.c +++ b/cups/ipp-support.c @@ -2262,7 +2262,7 @@ ippErrorString(ipp_status_t error) /* I - Error status */ * No, build an "0xxxxx" error string... */ - sprintf(cg->ipp_unknown, "0x%04x", error); + snprintf(cg->ipp_unknown, sizeof(cg->ipp_unknown), "0x%04x", error); return (cg->ipp_unknown); } @@ -2339,7 +2339,7 @@ ippOpString(ipp_op_t op) /* I - Operation ID */ * No, build an "0xxxxx" operation string... */ - sprintf(cg->ipp_unknown, "0x%04x", op); + snprintf(cg->ipp_unknown, sizeof(cg->ipp_unknown), "0x%04x", op); return (cg->ipp_unknown); } diff --git a/cups/ipp-vars.c b/cups/ipp-vars.c index 395b0ebf3..69efbd9aa 100644 --- a/cups/ipp-vars.c +++ b/cups/ipp-vars.c @@ -12,7 +12,7 @@ * Include necessary headers... */ -#include <cups/cups.h> +#include "cups-private.h" #include "ipp-private.h" #include "string-private.h" #include "debug-internal.h" @@ -220,10 +220,22 @@ _ippVarsSet(_ipp_vars_t *v, /* I - IPP variables */ { if (!strcmp(name, "uri")) { - char uri[1024]; /* New printer URI */ - http_uri_status_t uri_status; /* URI status */ + char uri[1024]; /* New printer URI */ + char resolved[1024]; /* Resolved mDNS URI */ - if ((uri_status = httpSeparateURI(HTTP_URI_CODING_ALL, value, v->scheme, sizeof(v->scheme), v->username, sizeof(v->username), v->host, sizeof(v->host), &(v->port), v->resource, sizeof(v->resource))) < HTTP_URI_STATUS_OK) + if (strstr(value, "._tcp")) + { + /* + * Resolve URI... + */ + + if (!_httpResolveURI(value, resolved, sizeof(resolved), _HTTP_RESOLVE_DEFAULT, NULL, NULL)) + return (0); + + value = resolved; + } + + if (httpSeparateURI(HTTP_URI_CODING_ALL, value, v->scheme, sizeof(v->scheme), v->username, sizeof(v->username), v->host, sizeof(v->host), &(v->port), v->resource, sizeof(v->resource)) < HTTP_URI_STATUS_OK) return (0); if (v->username[0]) diff --git a/cups/ipp.c b/cups/ipp.c index f19747d61..94a2264a6 100644 --- a/cups/ipp.c +++ b/cups/ipp.c @@ -1,7 +1,7 @@ /* * Internet Printing Protocol functions for CUPS. * - * Copyright © 2007-2020 by Apple Inc. + * Copyright © 2007-2021 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 @@ -2867,7 +2867,7 @@ ippReadIO(void *src, /* I - Data source */ string[IPP_MAX_TEXT], /* Small string buffer */ *bufptr, /* Pointer into buffer */ - *bufptrEnd; /* Pointer after valid buffer range */ + *bufend; /* End of buffer */ ipp_attribute_t *attr; /* Current attribute */ ipp_tag_t tag; /* Current tag */ ipp_tag_t value_tag; /* Current value tag */ @@ -3442,7 +3442,7 @@ ippReadIO(void *src, /* I - Data source */ } bufptr = buffer; - bufptrEnd = &buffer[n]; + bufend = buffer + n; /* @@ -3457,7 +3457,7 @@ ippReadIO(void *src, /* I - Data source */ n = (bufptr[0] << 8) | bufptr[1]; - if ((bufptr + 2 + n) > bufptrEnd || n >= (int)sizeof(string)) + if ((bufptr + 2 + n) >= bufend || n >= (int)sizeof(string)) { _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("IPP language length overflows value."), 1); @@ -3481,10 +3481,10 @@ ippReadIO(void *src, /* I - Data source */ value->string.language = _cupsStrAlloc((char *)string); - bufptr += 2 + n; + bufptr += 2 + n; n = (bufptr[0] << 8) | bufptr[1]; - if ((bufptr + 2 + n) > bufptrEnd) + if ((bufptr + 2 + n) > bufend) { _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("IPP string length overflows value."), 1); diff --git a/cups/ppd-cache.c b/cups/ppd-cache.c index 5965e382b..2c47d5995 100644 --- a/cups/ppd-cache.c +++ b/cups/ppd-cache.c @@ -3228,7 +3228,7 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */ cupsFilePuts(fp, "*cupsFilter2: \"application/vnd.cups-pdf application/pdf 10 -\"\n"); } else - cupsFilePuts(fp, "*cupsManualCopies: true\n"); + cupsFilePuts(fp, "*cupsManualCopies: True\n"); if (is_apple) cupsFilePuts(fp, "*cupsFilter2: \"image/urf image/urf 100 -\"\n"); if (is_pwg) @@ -3620,10 +3620,12 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */ if ((attr = ippFindAttribute(ippGetCollection(defattr, 0), "media-source", IPP_TAG_ZERO)) != NULL) pwg_ppdize_name(ippGetString(attr, 0, NULL), ppdname, sizeof(ppdname)); else - strlcpy(ppdname, "Unknown", sizeof(ppdname)); + ppdname[0] = '\0'; if ((attr = ippFindAttribute(response, "media-source-supported", IPP_TAG_ZERO)) != NULL && (count = ippGetCount(attr)) > 1) { + int have_default = ppdname[0] != '\0'; + /* Do we have a default InputSlot? */ static const char * const sources[] = { /* Standard "media-source" strings */ "auto", @@ -3678,21 +3680,31 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */ "roll-10" }; - cupsFilePrintf(fp, "*OpenUI *InputSlot: PickOne\n" - "*OrderDependency: 10 AnySetup *InputSlot\n" - "*DefaultInputSlot: %s\n", ppdname); - for (i = 0, count = ippGetCount(attr); i < count; i ++) + cupsFilePuts(fp, "*OpenUI *InputSlot: PickOne\n" + "*OrderDependency: 10 AnySetup *InputSlot\n"); + if (have_default) + cupsFilePrintf(fp, "*DefaultInputSlot: %s\n", ppdname); + + for (i = 0; i < count; i ++) { keyword = ippGetString(attr, i, NULL); pwg_ppdize_name(keyword, ppdname, sizeof(ppdname)); + if (i == 0 && !have_default) + cupsFilePrintf(fp, "*DefaultInputSlot: %s\n", ppdname); + for (j = 0; j < (int)(sizeof(sources) / sizeof(sources[0])); j ++) if (!strcmp(sources[j], keyword)) { snprintf(msgid, sizeof(msgid), "media-source.%s", keyword); + + if ((msgstr = _cupsLangString(lang, msgid)) == msgid || !strcmp(msgid, msgstr)) + if ((msgstr = _cupsMessageLookup(strings, msgid)) == msgid) + msgstr = keyword; + cupsFilePrintf(fp, "*InputSlot %s: \"<</MediaPosition %d>>setpagedevice\"\n", ppdname, j); - cupsFilePrintf(fp, "*%s.InputSlot %s/%s: \"\"\n", lang->language, ppdname, _cupsLangString(lang, msgid)); + cupsFilePrintf(fp, "*%s.InputSlot %s/%s: \"\"\n", lang->language, ppdname, msgstr); break; } } @@ -3744,6 +3756,8 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */ int wrote_color = 0; const char *default_color = NULL; /* Default */ + cupsFilePrintf(fp, "*%% ColorModel from %s\n", ippGetName(attr)); + for (i = 0, count = ippGetCount(attr); i < count; i ++) { keyword = ippGetString(attr, i, NULL); @@ -3790,6 +3804,11 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */ PRINTF_COLOROPTION("RGB", _("Color"), CUPS_CSPACE_SRGB, 8) default_color = "RGB"; + + // Apparently some printers only advertise color support, so make sure + // we also do grayscale for these printers... + if (!ippContainsString(attr, "sgray_8") && !ippContainsString(attr, "black_1") && !ippContainsString(attr, "black_8") && !ippContainsString(attr, "W8") && !ippContainsString(attr, "W8-16")) + PRINTF_COLOROPTION("Gray", _("GrayScale"), CUPS_CSPACE_SW, 8) } else if (!strcasecmp(keyword, "adobe-rgb_16") || !strcmp(keyword, "ADOBERGB48") || !strcmp(keyword, "ADOBERGB24-48")) { @@ -3924,7 +3943,7 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */ else strlcpy(ppdname, "Unknown", sizeof(ppdname)); - if ((attr = ippFindAttribute(response, "output-bin-supported", IPP_TAG_ZERO)) != NULL && (count = ippGetCount(attr)) > 1) + if ((attr = ippFindAttribute(response, "output-bin-supported", IPP_TAG_ZERO)) != NULL && (count = ippGetCount(attr)) > 0) { ipp_attribute_t *trays = ippFindAttribute(response, "printer-output-tray", IPP_TAG_STRING); /* printer-output-tray attribute, if any */ @@ -5140,6 +5159,8 @@ pwg_unppdize_name(const char *ppd, /* I - PPD keyword */ { char *ptr, /* Pointer into name buffer */ *end; /* End of name buffer */ + int nodash = 1; /* Next char in IPP name cannot be a + dash (first char or after a dash) */ if (_cups_islower(*ppd)) @@ -5151,7 +5172,9 @@ pwg_unppdize_name(const char *ppd, /* I - PPD keyword */ const char *ppdptr; /* Pointer into PPD keyword */ for (ppdptr = ppd + 1; *ppdptr; ppdptr ++) - if (_cups_isupper(*ppdptr) || strchr(dashchars, *ppdptr)) + if (_cups_isupper(*ppdptr) || strchr(dashchars, *ppdptr) || + (*ppdptr == '-' && *(ppdptr - 1) == '-') || + (*ppdptr == '-' && *(ppdptr + 1) == '\0')) break; if (!*ppdptr) @@ -5163,19 +5186,44 @@ pwg_unppdize_name(const char *ppd, /* I - PPD keyword */ for (ptr = name, end = name + namesize - 1; *ppd && ptr < end; ppd ++) { - if (_cups_isalnum(*ppd) || *ppd == '-') + if (_cups_isalnum(*ppd)) + { *ptr++ = (char)tolower(*ppd & 255); - else if (strchr(dashchars, *ppd)) - *ptr++ = '-'; + nodash = 0; + } + else if (*ppd == '-' || strchr(dashchars, *ppd)) + { + if (nodash == 0) + { + *ptr++ = '-'; + nodash = 1; + } + } else + { *ptr++ = *ppd; + nodash = 0; + } - if (!_cups_isupper(*ppd) && _cups_isalnum(*ppd) && - _cups_isupper(ppd[1]) && ptr < end) - *ptr++ = '-'; - else if (!isdigit(*ppd & 255) && isdigit(ppd[1] & 255)) - *ptr++ = '-'; + if (nodash == 0) + { + if (!_cups_isupper(*ppd) && _cups_isalnum(*ppd) && + _cups_isupper(ppd[1]) && ptr < end) + { + *ptr++ = '-'; + nodash = 1; + } + else if (!isdigit(*ppd & 255) && isdigit(ppd[1] & 255)) + { + *ptr++ = '-'; + nodash = 1; + } + } } + /* Remove trailing dashes */ + while (ptr > name && *(ptr - 1) == '-') + ptr --; + *ptr = '\0'; } diff --git a/cups/ppd-mark.c b/cups/ppd-mark.c index 7ec0df473..25797b376 100644 --- a/cups/ppd-mark.c +++ b/cups/ppd-mark.c @@ -307,7 +307,7 @@ cupsMarkOptions( * Look it up in the PPD file... */ - sprintf(s, "%d", j); + snprintf(s, sizeof(s), "%d", j); if ((attr = ppdFindAttr(ppd, "cupsIPPFinishings", s)) == NULL) continue; diff --git a/cups/ppd-private.h b/cups/ppd-private.h index 7b406c971..11ddae366 100644 --- a/cups/ppd-private.h +++ b/cups/ppd-private.h @@ -35,7 +35,7 @@ extern "C" { * Constants... */ -# define _PPD_CACHE_VERSION 9 /* Version number in cache file */ +# define _PPD_CACHE_VERSION 10 /* Version number in cache file */ /* diff --git a/cups/ppd.c b/cups/ppd.c index cf84833a4..ac5dbc62b 100644 --- a/cups/ppd.c +++ b/cups/ppd.c @@ -125,6 +125,7 @@ ppdClose(ppd_file_t *ppd) /* I - PPD file record */ free(ppd->lang_encoding); free(ppd->nickname); free(ppd->patches); + free(ppd->emulations); free(ppd->jcl_begin); free(ppd->jcl_end); free(ppd->jcl_ps); @@ -871,15 +872,15 @@ _ppdOpen( ppd_decode(ppd->jcl_ps); /* Decode quoted string */ } else if (!strcmp(keyword, "AccurateScreensSupport")) - ppd->accurate_screens = !strcmp(string, "True"); + ppd->accurate_screens = !strcasecmp(string, "True"); else if (!strcmp(keyword, "ColorDevice")) - ppd->color_device = !strcmp(string, "True"); + ppd->color_device = !strcasecmp(string, "True"); else if (!strcmp(keyword, "ContoneOnly")) - ppd->contone_only = !strcmp(string, "True"); + ppd->contone_only = !strcasecmp(string, "True"); else if (!strcmp(keyword, "cupsFlipDuplex")) - ppd->flip_duplex = !strcmp(string, "True"); + ppd->flip_duplex = !strcasecmp(string, "True"); else if (!strcmp(keyword, "cupsManualCopies")) - ppd->manual_copies = !strcmp(string, "True"); + ppd->manual_copies = !strcasecmp(string, "True"); else if (!strcmp(keyword, "cupsModelNumber")) ppd->model_number = atoi(string); else if (!strcmp(keyword, "cupsColorProfile")) @@ -1496,6 +1497,27 @@ _ppdOpen( goto error; } + if (option && (!_cups_strcasecmp(option->defchoice, "custom") || !_cups_strncasecmp(option->defchoice, "custom.", 7))) + { + /* + * "*DefaultOption: Custom..." may set the default to a custom value + * or (for a very small number of incompatible PPD files) select a + * standard choice for the option, which CUPS renames to "_Custom..." + * to avoid compatibility issues. See which this is... + */ + + char tchoice[PPD_MAX_NAME]; /* Temporary choice name */ + + snprintf(tchoice, sizeof(tchoice), "_%s", option->defchoice); + + if (ppdFindChoice(option, tchoice)) + { + strlcpy(option->defchoice, tchoice, sizeof(option->defchoice)); + + DEBUG_printf(("2_ppdOpen: Reset Default%s to %s...", option->keyword, tchoice)); + } + } + option = NULL; free(string); @@ -1510,6 +1532,27 @@ _ppdOpen( goto error; } + if (option && (!_cups_strcasecmp(option->defchoice, "custom") || !_cups_strncasecmp(option->defchoice, "custom.", 7))) + { + /* + * "*DefaultOption: Custom..." may set the default to a custom value + * or (for a very small number of incompatible PPD files) select a + * standard choice for the option, which CUPS renames to "_Custom..." + * to avoid compatibility issues. See which this is... + */ + + char tchoice[PPD_MAX_NAME]; /* Temporary choice name */ + + snprintf(tchoice, sizeof(tchoice), "_%s", option->defchoice); + + if (ppdFindChoice(option, tchoice)) + { + strlcpy(option->defchoice, tchoice, sizeof(option->defchoice)); + + DEBUG_printf(("2_ppdOpen: Reset Default%s to %s...", option->keyword, tchoice)); + } + } + option = NULL; free(string); @@ -1668,11 +1711,9 @@ _ppdOpen( * Set the default as part of the current option... */ - DEBUG_printf(("2_ppdOpen: Setting %s to %s...", keyword, string)); + strlcpy(option->defchoice, string, sizeof(option->defchoice)); - strlcpy(option->defchoice, string, sizeof(option->defchoice)); - - DEBUG_printf(("2_ppdOpen: %s is now %s...", keyword, option->defchoice)); + DEBUG_printf(("2_ppdOpen: Set %s to %s...", keyword, option->defchoice)); } else { @@ -1682,11 +1723,27 @@ _ppdOpen( ppd_option_t *toption; /* Temporary option */ - if ((toption = ppdFindOption(ppd, keyword + 7)) != NULL) { - DEBUG_printf(("2_ppdOpen: Setting %s to %s...", keyword, string)); - strlcpy(toption->defchoice, string, sizeof(toption->defchoice)); + if (!_cups_strcasecmp(string, "custom") || !_cups_strncasecmp(string, "custom.", 7)) + { + /* + * "*DefaultOption: Custom..." may set the default to a custom value + * or (for a very small number of incompatible PPD files) select a + * standard choice for the option, which CUPS renames to "_Custom..." + * to avoid compatibility issues. See which this is... + */ + + snprintf(toption->defchoice, sizeof(toption->defchoice), "_%s", string); + if (!ppdFindChoice(toption, toption->defchoice)) + strlcpy(toption->defchoice, string, sizeof(toption->defchoice)); + } + else + { + strlcpy(toption->defchoice, string, sizeof(toption->defchoice)); + } + + DEBUG_printf(("2_ppdOpen: Set %s to %s...", keyword, toption->defchoice)); } } } @@ -2847,7 +2904,7 @@ ppd_hash_option(ppd_option_t *option) /* I - Option */ for (hash = option->keyword[0], k = option->keyword + 1; *k;) - hash = 33 * hash + *k++; + hash = (int)(33U * (unsigned)hash) + *k++; return (hash & 511); } diff --git a/cups/request.c b/cups/request.c index 69a780137..ff967f05a 100644 --- a/cups/request.c +++ b/cups/request.c @@ -395,7 +395,7 @@ cupsGetResponse(http_t *http, /* I - Connection to server or @code CUPS_HTTP ippDelete(response); response = NULL; - http->status = status = HTTP_STATUS_ERROR; + http->status = HTTP_STATUS_ERROR; http->error = EINVAL; } } @@ -422,7 +422,7 @@ cupsGetResponse(http_t *http, /* I - Connection to server or @code CUPS_HTTP if (!cupsDoAuthentication(http, "POST", resource)) httpReconnect2(http, 30000, NULL); else - http->status = status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED; + http->status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED; } #ifdef HAVE_SSL diff --git a/cups/snprintf.c b/cups/snprintf.c index 49652e2c4..3c4685718 100644 --- a/cups/snprintf.c +++ b/cups/snprintf.c @@ -81,7 +81,8 @@ _cups_vsnprintf(char *buffer, /* O - Output buffer */ format ++; width = va_arg(ap, int); - snprintf(tptr, sizeof(tformat) - (tptr - tformat), "%d", width); + /* Note: Can't use snprintf here since we are implementing this function... */ + sprintf(tptr, "%d", width); tptr += strlen(tptr); } else @@ -113,7 +114,8 @@ _cups_vsnprintf(char *buffer, /* O - Output buffer */ format ++; prec = va_arg(ap, int); - snprintf(tptr, sizeof(tformat) - (tptr - tformat), "%d", prec); + /* Note: Can't use snprintf here since we are implementing this function... */ + sprintf(tptr, "%d", prec); tptr += strlen(tptr); } else @@ -171,6 +173,7 @@ _cups_vsnprintf(char *buffer, /* O - Output buffer */ if ((width + 2) > sizeof(temp)) break; + /* Note: Can't use snprintf here since we are implementing this function... */ sprintf(temp, tformat, va_arg(ap, double)); templen = strlen(temp); @@ -202,6 +205,7 @@ _cups_vsnprintf(char *buffer, /* O - Output buffer */ if ((width + 2) > sizeof(temp)) break; + /* Note: Can't use snprintf here since we are implementing this function... */ sprintf(temp, tformat, va_arg(ap, int)); templen = strlen(temp); @@ -226,6 +230,7 @@ _cups_vsnprintf(char *buffer, /* O - Output buffer */ if ((width + 2) > sizeof(temp)) break; + /* Note: Can't use snprintf here since we are implementing this function... */ sprintf(temp, tformat, va_arg(ap, void *)); templen = strlen(temp); diff --git a/cups/testclient.c b/cups/testclient.c index cf945df98..16ac40db7 100644 --- a/cups/testclient.c +++ b/cups/testclient.c @@ -24,7 +24,7 @@ * Constants... */ -#define MAX_CLIENTS 16 /* Maximum number of client threads */ +#define MAX_CLIENTS 100 /* Maximum number of client threads */ /* @@ -44,12 +44,12 @@ typedef struct _client_data_s int grayscale, /* Force grayscale? */ keepfile; /* Keep temporary file? */ ipp_pstate_t printer_state; /* Current printer state */ - char printer_state_reasons[1024]; - /* Current printer-state-reasons */ + char printer_state_reasons[1024]; + /* Current printer-state-reasons */ int job_id; /* Job ID for submitted job */ ipp_jstate_t job_state; /* Current job state */ - char job_state_reasons[1024]; - /* Current job-state-reasons */ + char job_state_reasons[1024]; + /* Current job-state-reasons */ } _client_data_t; @@ -66,12 +66,12 @@ static int verbosity = 0; * Local functions... */ -static const char *make_raster_file(ipp_t *response, int grayscale, char *tempname, size_t tempsize, const char **format); -static void *monitor_printer(_client_data_t *data); +static const char *make_raster_file(ipp_t *response, int grayscale, char *tempname, size_t tempsize, const char **format); +static void *monitor_printer(_client_data_t *data); static void *run_client(_client_data_t *data); -static void show_attributes(const char *title, int request, ipp_t *ipp); -static void show_capabilities(ipp_t *response); -static void usage(void); +static void show_attributes(const char *title, int request, ipp_t *ipp); +static void show_capabilities(ipp_t *response); +static void usage(void); /* @@ -396,15 +396,7 @@ make_raster_file(ipp_t *response, /* I - Printer attributes */ * Figure out the the media, resolution, and color mode... */ - if ((attr = ippFindAttribute(response, "media-default", IPP_TAG_KEYWORD)) != NULL) - { - /* - * Use default media... - */ - - media = pwgMediaForPWG(ippGetString(attr, 0, NULL)); - } - else if ((attr = ippFindAttribute(response, "media-ready", IPP_TAG_KEYWORD)) != NULL) + if ((attr = ippFindAttribute(response, "media-ready", IPP_TAG_KEYWORD)) != NULL) { /* * Use ready media... @@ -417,6 +409,14 @@ make_raster_file(ipp_t *response, /* I - Printer attributes */ else media = pwgMediaForPWG(ippGetString(attr, 0, NULL)); } + else if ((attr = ippFindAttribute(response, "media-default", IPP_TAG_KEYWORD)) != NULL) + { + /* + * Use default media... + */ + + media = pwgMediaForPWG(ippGetString(attr, 0, NULL)); + } else { puts("No default or ready media reported by printer, aborting."); @@ -486,15 +486,15 @@ make_raster_file(ipp_t *response, /* I - Printer attributes */ header.cupsInteger[CUPS_RASTER_PWG_TotalPageCount] = 1; - if (header.cupsWidth > (4 * header.HWResolution[0])) + if (header.cupsWidth > (2 * header.HWResolution[0])) { xoff = header.HWResolution[0] / 2; yoff = header.HWResolution[1] / 2; } else { - xoff = 0; - yoff = 0; + xoff = header.HWResolution[0] / 4; + yoff = header.HWResolution[1] / 4; } xrep = (header.cupsWidth - 2 * xoff) / 140; @@ -603,6 +603,8 @@ make_raster_file(ipp_t *response, /* I - Printer attributes */ for (y = 0; y < header.cupsHeight; y ++) cupsRasterWritePixels(ras, line, header.cupsBytesPerLine); + free(line); + cupsRasterClose(ras); close(fd); @@ -768,11 +770,8 @@ run_client( ipp_attribute_t *attr; /* Attribute in response */ static const char * const pattrs[] = /* Printer attributes we are interested in */ { - "job-template", - "printer-defaults", - "printer-description", - "media-col-database", - "media-col-ready" + "all", + "media-col-database" }; diff --git a/cups/testdest.c b/cups/testdest.c index a65e09960..9b07e7771 100644 --- a/cups/testdest.c +++ b/cups/testdest.c @@ -410,7 +410,6 @@ print_file(http_t *http, /* I - Connection to destination */ { cups_file_t *fp; /* File to print */ int job_id; /* Job ID */ - ipp_status_t status; /* Submission status */ const char *title; /* Title of job */ char buffer[32768]; /* File buffer */ ssize_t bytes; /* Bytes read/to write */ @@ -427,7 +426,7 @@ print_file(http_t *http, /* I - Connection to destination */ else title = filename; - if ((status = cupsCreateDestJob(http, dest, dinfo, &job_id, title, num_options, options)) > IPP_STATUS_OK_IGNORED_OR_SUBSTITUTED) + if (cupsCreateDestJob(http, dest, dinfo, &job_id, title, num_options, options) > IPP_STATUS_OK_IGNORED_OR_SUBSTITUTED) { printf("Unable to create job: %s\n", cupsLastErrorString()); cupsFileClose(fp); @@ -454,7 +453,7 @@ print_file(http_t *http, /* I - Connection to destination */ cupsFileClose(fp); - if ((status = cupsFinishDestDocument(http, dest, dinfo)) > IPP_STATUS_OK_IGNORED_OR_SUBSTITUTED) + if (cupsFinishDestDocument(http, dest, dinfo) > IPP_STATUS_OK_IGNORED_OR_SUBSTITUTED) { printf("Unable to send document: %s\n", cupsLastErrorString()); return; diff --git a/cups/tls-gnutls.c b/cups/tls-gnutls.c index 329cc0eb4..25adbdfb2 100644 --- a/cups/tls-gnutls.c +++ b/cups/tls-gnutls.c @@ -939,7 +939,7 @@ http_gnutls_default_path(char *buffer,/* I - Path buffer */ /* Pointer to library globals */ - if (cg->home) + if (cg->home && getuid()) { snprintf(buffer, bufsize, "%s/.cups", cg->home); if (access(buffer, 0)) diff --git a/cups/tls-sspi.c b/cups/tls-sspi.c index ccbdf8aaf..52ded5f21 100644 --- a/cups/tls-sspi.c +++ b/cups/tls-sspi.c @@ -1332,8 +1332,6 @@ http_sspi_client(http_t *http, /* I - Client connection */ SecBufferDesc outBuffer; /* Array of SecBuffer structs */ SecBuffer outBuffers[1]; /* Security package buffer */ int ret = 0; /* Return value */ - char username[1024], /* Current username */ - common_name[1024]; /* CN=username */ DEBUG_printf(("4http_sspi_client(http=%p, hostname=\"%s\")", http, hostname)); @@ -1349,16 +1347,11 @@ http_sspi_client(http_t *http, /* I - Client connection */ * Lookup the client certificate... */ - dwSize = sizeof(username); - GetUserNameA(username, &dwSize); - snprintf(common_name, sizeof(common_name), "CN=%s", username); - - if (!http_sspi_find_credentials(http, L"ClientContainer", common_name)) - if (!http_sspi_make_credentials(http->tls, L"ClientContainer", common_name, _HTTP_MODE_CLIENT, 10)) - { - DEBUG_puts("5http_sspi_client: Unable to get client credentials."); - return (-1); - } + if (!http_sspi_find_credentials(http, L"ClientContainer", NULL)) + { + DEBUG_puts("5http_sspi_client: Unable to get client credentials."); + return (-1); + } /* * Initiate a ClientHello message and generate a token. @@ -1711,48 +1704,55 @@ http_sspi_find_credentials( goto cleanup; } - dwSize = 0; - - if (!CertStrToNameA(X509_ASN_ENCODING, common_name, CERT_OID_NAME_STR, NULL, NULL, &dwSize, NULL)) + if (common_name) { - DEBUG_printf(("5http_sspi_find_credentials: CertStrToName failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), GetLastError()))); - ok = FALSE; - goto cleanup; - } + dwSize = 0; - p = (PBYTE)malloc(dwSize); + if (!CertStrToNameA(X509_ASN_ENCODING, common_name, CERT_OID_NAME_STR, NULL, NULL, &dwSize, NULL)) + { + DEBUG_printf(("5http_sspi_find_credentials: CertStrToName failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), GetLastError()))); + ok = FALSE; + goto cleanup; + } - if (!p) - { - DEBUG_printf(("5http_sspi_find_credentials: malloc failed for %d bytes.", dwSize)); - ok = FALSE; - goto cleanup; - } + p = (PBYTE)malloc(dwSize); - if (!CertStrToNameA(X509_ASN_ENCODING, common_name, CERT_OID_NAME_STR, NULL, p, &dwSize, NULL)) - { - DEBUG_printf(("5http_sspi_find_credentials: CertStrToName failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), GetLastError()))); - ok = FALSE; - goto cleanup; - } + if (!p) + { + DEBUG_printf(("5http_sspi_find_credentials: malloc failed for %d bytes.", dwSize)); + ok = FALSE; + goto cleanup; + } - sib.cbData = dwSize; - sib.pbData = p; + if (!CertStrToNameA(X509_ASN_ENCODING, common_name, CERT_OID_NAME_STR, NULL, p, &dwSize, NULL)) + { + DEBUG_printf(("5http_sspi_find_credentials: CertStrToName failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), GetLastError()))); + ok = FALSE; + goto cleanup; + } - storedContext = CertFindCertificateInStore(store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_NAME, &sib, NULL); + sib.cbData = dwSize; + sib.pbData = p; - if (!storedContext) - { - DEBUG_printf(("5http_sspi_find_credentials: Unable to find credentials for \"%s\".", common_name)); - ok = FALSE; - goto cleanup; + storedContext = CertFindCertificateInStore(store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_NAME, &sib, NULL); + + if (!storedContext) + { + DEBUG_printf(("5http_sspi_find_credentials: Unable to find credentials for \"%s\".", common_name)); + ok = FALSE; + goto cleanup; + } } ZeroMemory(&SchannelCred, sizeof(SchannelCred)); SchannelCred.dwVersion = SCHANNEL_CRED_VERSION; - SchannelCred.cCreds = 1; - SchannelCred.paCred = &storedContext; + + if (common_name) + { + SchannelCred.cCreds = 1; + SchannelCred.paCred = &storedContext; + } /* * Set supported protocols (can also be overriden in the registry...) @@ -2018,13 +2018,6 @@ http_sspi_make_credentials( SchannelCred.paCred = &storedContext; /* - * SSPI doesn't seem to like it if grbitEnabledProtocols is set for a client. - */ - - if (mode == _HTTP_MODE_SERVER) - SchannelCred.grbitEnabledProtocols = SP_PROT_SSL3TLS1; - - /* * Create an SSPI credential. */ |