aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBryan Ferris <bferris@google.com>2019-06-21 10:49:26 -0700
committerHuizi Yang <yanghuiz@google.com>2019-10-08 14:05:51 -0700
commit2ccb2eaf277e9f184c8225cd80d341d1e70a6d68 (patch)
treeaedb3a476f3355dd099cf82d961ee2f2a67d51d0
parent05b0b189a65a1d52cbfa5ae6d35e2a16b201e706 (diff)
downloadplatform_external_libcups-2ccb2eaf277e9f184c8225cd80d341d1e70a6d68.tar.gz
platform_external_libcups-2ccb2eaf277e9f184c8225cd80d341d1e70a6d68.tar.bz2
platform_external_libcups-2ccb2eaf277e9f184c8225cd80d341d1e70a6d68.zip
Bug: 111210196 Test: adb shell am instrument -w android.print.cts/androidx.test.runner.AndroidJUnitRunner Change-Id: I5170f3629dabbfa3af5e5af037261986e7bfe2f6 Merged-In: Iefafb654fcb0764bba0f17731e469db595a6b36e (cherry picked from commit 5fb2ccdf3347f61b570c8e340f90db5cd28b29bc)
-rw-r--r--config.h4
-rw-r--r--cups/Makefile38
-rw-r--r--cups/adminutil.c16
-rw-r--r--cups/api-ppd.shtml4
-rw-r--r--cups/auth.c516
-rw-r--r--cups/backchannel.c12
-rw-r--r--cups/cups.h13
-rw-r--r--cups/debug-private.h27
-rw-r--r--cups/debug.c10
-rw-r--r--cups/dest.c12
-rw-r--r--cups/dir.c10
-rw-r--r--cups/file-private.h34
-rw-r--r--cups/file.c95
-rw-r--r--cups/file.h10
-rw-r--r--cups/getputfile.c70
-rw-r--r--cups/globals.c32
-rw-r--r--cups/hash.c91
-rw-r--r--cups/http-addr.c8
-rw-r--r--cups/http-addrlist.c41
-rw-r--r--cups/http-private.h55
-rw-r--r--cups/http-support.c169
-rw-r--r--cups/http.c470
-rw-r--r--cups/http.h19
-rw-r--r--cups/ipp-support.c20
-rw-r--r--cups/ipp.c283
-rw-r--r--cups/ipp.h10
-rw-r--r--cups/language-private.h16
-rw-r--r--cups/language.c4
-rw-r--r--cups/libcups2.def23
-rw-r--r--cups/md5.c170
-rw-r--r--cups/md5passwd.c52
-rw-r--r--cups/ppd-cache.c232
-rw-r--r--cups/ppd-conflicts.c5
-rw-r--r--cups/ppd-emit.c8
-rw-r--r--cups/ppd-localize.c4
-rw-r--r--cups/ppd-util.c135
-rw-r--r--cups/ppd.c47
-rw-r--r--cups/ppd.h2
-rw-r--r--cups/raster-private.h14
-rw-r--r--cups/request.c38
-rw-r--r--cups/sidechannel.c8
-rw-r--r--cups/snmp.c4
-rw-r--r--cups/string-private.h9
-rw-r--r--cups/tempfile.c52
-rw-r--r--cups/testarray.c4
-rw-r--r--cups/testdest.c4
-rw-r--r--cups/testfile.c21
-rw-r--r--cups/testhttp.c70
-rw-r--r--cups/testipp.c4
-rw-r--r--cups/testppd.c12
-rw-r--r--cups/testsnmp.c4
-rw-r--r--cups/thread-private.h2
-rw-r--r--cups/thread.c30
-rw-r--r--cups/tls-boringssl.c12
-rw-r--r--cups/tls-darwin.c89
-rw-r--r--cups/tls-gnutls.c102
-rw-r--r--cups/tls-sspi.c45
-rw-r--r--cups/tls.c6
-rw-r--r--cups/tlscheck.c27
-rw-r--r--cups/usersys.c72
-rw-r--r--cups/util.c60
-rw-r--r--cups/versioning.h307
-rw-r--r--filter/Makefile31
-rw-r--r--filter/pstops.c9
-rw-r--r--filter/raster.c276
-rw-r--r--filter/rastertoepson.c4
-rw-r--r--filter/rastertolabel.c4
-rw-r--r--filter/spec-ppd.shtml27
-rw-r--r--libcups_version2
69 files changed, 2630 insertions, 1486 deletions
diff --git a/config.h b/config.h
index 28fe0344..03e12da6 100644
--- a/config.h
+++ b/config.h
@@ -17,8 +17,8 @@
#ifndef _CUPS_CONFIG_H_
#define _CUPS_CONFIG_H_
-#define CUPS_SVERSION "CUPS v2.2.6"
-#define CUPS_MINIMAL "CUPS/2.2.6"
+#define CUPS_SVERSION "CUPS v2.2.9"
+#define CUPS_MINIMAL "CUPS/2.2.9"
#define CUPS_DEFAULT_PRINTOPERATOR_AUTH "@SYSTEM"
#define CUPS_DEFAULT_LOG_LEVEL "warn"
#define CUPS_DEFAULT_BROWSE_LOCAL_PROTOCOLS "dnssd"
diff --git a/cups/Makefile b/cups/Makefile
index 9a220c85..f83c937c 100644
--- a/cups/Makefile
+++ b/cups/Makefile
@@ -1,8 +1,8 @@
#
# Library Makefile for CUPS.
#
-# Copyright 2007-2017 by Apple Inc.
-# Copyright 1997-2006 by Easy Software Products, all rights reserved.
+# Copyright © 2007-2018 by Apple Inc.
+# Copyright © 1997-2006 by Easy Software Products, all rights reserved.
#
# These coded instructions, statements, and computer programs are the
# property of Apple Inc. and are protected by Federal copyright
@@ -312,8 +312,9 @@ uninstall:
libcups.so.2: $(LIBOBJS)
echo Linking $@...
- $(DSO) $(ARCHFLAGS) $(DSOFLAGS) -o $@ $(LIBOBJS) $(LIBGSSAPI) \
+ $(DSO) $(ARCHFLAGS) $(LDFLAGS) $(DSOFLAGS) -o $@ $(LIBOBJS) $(LIBGSSAPI) \
$(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ)
+ $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@
$(RM) `basename $@ .2`
$(LN) $@ `basename $@ .2`
@@ -329,13 +330,14 @@ libcups.2.dylib: $(LIBOBJS) $(LIBCUPSORDER)
grep -v -E -e '^(_cupsConnect|_cupsCharset|_cupsEncodingName|_cupsSetDefaults|_cupsSetHTTPError|_cupsUserDefault)$$' | \
sort >t.exp
echo Linking $@...
- $(DSO) $(ARCHFLAGS) $(DSOFLAGS) -o $@ \
+ $(DSO) $(ARCHFLAGS) $(LDFLAGS) $(DSOFLAGS) -o $@ \
-install_name $(libdir)/$@ \
- -current_version 2.12.0 \
+ -current_version 2.13.0 \
-compatibility_version 2.0.0 \
-exported_symbols_list t.exp \
$(LIBOBJS) $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) \
$(COMMONLIBS) $(LIBZ)
+ $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@
$(RM) libcups.dylib t.exp
$(LN) $@ libcups.dylib
@@ -346,8 +348,8 @@ libcups.2.dylib: $(LIBOBJS) $(LIBCUPSORDER)
libcups.la: $(LIBOBJS)
echo Linking $@...
- $(LD_CC) $(ARCHFLAGS) $(DSOFLAGS) -o $@ $(LIBOBJS:.o=.lo) \
- -rpath $(LIBDIR) -version-info 2:12 $(LIBGSSAPI) $(SSLLIBS) \
+ $(LD_CC) $(ARCHFLAGS) $(LDFLAGS) $(DSOFLAGS) -o $@ $(LIBOBJS:.o=.lo) \
+ -rpath $(LIBDIR) -version-info 2:13 $(LIBGSSAPI) $(SSLLIBS) \
$(DNSSDLIBS) $(COMMONLIBS) $(LIBZ)
@@ -369,12 +371,12 @@ libcups.a: $(LIBOBJS)
libcups2.def: $(LIBOBJS) Makefile
echo Generating $@...
echo "LIBRARY libcups2" >libcups2.def
- echo "VERSION 2.12" >>libcups2.def
+ echo "VERSION 2.13" >>libcups2.def
echo "EXPORTS" >>libcups2.def
(nm $(LIBOBJS) 2>/dev/null | grep "T _" | awk '{print $$3}'; \
echo __cups_strcpy; echo __cups_strlcat; echo __cups_strlcpy) | \
grep -v -E \
- -e 'cups_debug|Apple|BackChannel|Backend|FileCheck|Filter|GSSService|SetNegotiate|SideChannel' \
+ -e 'cups_debug|Apple|BackChannel|Backend|FileCheck|Filter|GSSService|SetNegotiate|SideChannel|SNMP' \
-e 'Block$$' | \
sed -e '1,$$s/^_//' | sort >>libcups2.def
@@ -387,6 +389,7 @@ testadmin: testadmin.o $(LIBCUPSSTATIC)
echo Linking $@...
$(LD_CC) $(LDFLAGS) -o $@ testadmin.o $(LIBCUPSSTATIC) \
$(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ)
+ $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@
#
@@ -397,6 +400,7 @@ testarray: testarray.o $(LIBCUPSSTATIC)
echo Linking $@...
$(LD_CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testarray.o $(LIBCUPSSTATIC) \
$(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ)
+ $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@
echo Running array API tests...
./testarray
@@ -409,6 +413,7 @@ testcache: testcache.o $(LIBCUPSSTATIC)
echo Linking $@...
$(LD_CC) $(LDFLAGS) -o $@ testcache.o $(LIBCUPSSTATIC) \
$(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ)
+ $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@
#
@@ -419,6 +424,7 @@ testconflicts: testconflicts.o $(LIBCUPSSTATIC)
echo Linking $@...
$(LD_CC) $(LDFLAGS) -o $@ testconflicts.o $(LIBCUPSSTATIC) \
$(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ)
+ $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@
#
@@ -429,6 +435,7 @@ testcreds: testcreds.o $(LIBCUPSSTATIC)
echo Linking $@...
$(LD_CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testcreds.o $(LIBCUPSSTATIC) \
$(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ)
+ $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@
#
@@ -439,6 +446,7 @@ testcups: testcups.o $(LIBCUPSSTATIC)
echo Linking $@...
$(LD_CC) $(LDFLAGS) -o $@ testcups.o $(LIBCUPSSTATIC) \
$(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ)
+ $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@
#
@@ -449,6 +457,7 @@ testdest: testdest.o $(LIBCUPSSTATIC)
echo Linking $@...
$(LD_CC) $(LDFLAGS) -o $@ testdest.o $(LIBCUPSSTATIC) \
$(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ)
+ $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@
#
@@ -459,6 +468,7 @@ testfile: testfile.o $(LIBCUPSSTATIC)
echo Linking $@...
$(LD_CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testfile.o $(LIBCUPSSTATIC) \
$(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ)
+ $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@
echo Running file API tests...
./testfile
@@ -471,6 +481,7 @@ testgetdests: testgetdests.o $(LIBCUPSSTATIC)
echo Linking $@...
$(LD_CC) $(LDFLAGS) -o $@ testgetdests.o $(LIBCUPSSTATIC) \
$(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ)
+ $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@
#
@@ -481,6 +492,7 @@ testhttp: testhttp.o $(LIBCUPSSTATIC)
echo Linking $@...
$(LD_CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testhttp.o $(LIBCUPSSTATIC) \
$(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ)
+ $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@
echo Running HTTP API tests...
./testhttp
@@ -493,6 +505,7 @@ testipp: testipp.o $(LIBCUPSSTATIC)
echo Linking $@...
$(LD_CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testipp.o $(LIBCUPSSTATIC) \
$(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ)
+ $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@
echo Running IPP API tests...
./testipp
@@ -505,6 +518,7 @@ testi18n: testi18n.o $(LIBCUPSSTATIC)
echo Linking $@...
$(LD_CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testi18n.o $(LIBCUPSSTATIC) \
$(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ)
+ $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@
echo Running internationalization API tests...
./testi18n
@@ -517,6 +531,7 @@ testlang: testlang.o $(LIBCUPSSTATIC)
echo Linking $@...
$(LD_CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testlang.o $(LIBCUPSSTATIC) \
$(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ)
+ $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@
echo Creating locale directory structure...
$(RM) -r locale
$(MKDIR) locale/en
@@ -541,6 +556,7 @@ testoptions: testoptions.o $(LIBCUPSSTATIC)
echo Linking $@...
$(LD_CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testoptions.o $(LIBCUPSSTATIC) \
$(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ)
+ $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@
echo Running option API tests...
./testoptions
@@ -553,6 +569,7 @@ testppd: testppd.o $(LIBCUPSSTATIC) test.ppd test2.ppd
echo Linking $@...
$(LD_CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testppd.o $(LIBCUPSSTATIC) \
$(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ)
+ $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@
echo Running PPD API tests...
./testppd
@@ -565,6 +582,7 @@ testpwg: testpwg.o $(LIBCUPSSTATIC) test.ppd
echo Linking $@...
$(LD_CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testpwg.o $(LIBCUPSSTATIC) \
$(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ)
+ $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@
echo Running PWG API tests...
./testpwg test.ppd
@@ -577,6 +595,7 @@ testsnmp: testsnmp.o $(LIBCUPSSTATIC)
echo Linking $@...
$(LD_CC) $(LDFLAGS) -o $@ testsnmp.o $(LIBCUPSSTATIC) \
$(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ)
+ $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@
#
@@ -587,6 +606,7 @@ tlscheck: tlscheck.o $(LIBCUPSSTATIC)
echo Linking $@...
$(LD_CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ tlscheck.o $(LIBCUPSSTATIC) \
$(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ)
+ $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@
#
diff --git a/cups/adminutil.c b/cups/adminutil.c
index adb1f7ae..375b9054 100644
--- a/cups/adminutil.c
+++ b/cups/adminutil.c
@@ -22,11 +22,11 @@
#include "adminutil.h"
#include <fcntl.h>
#include <sys/stat.h>
-#ifdef WIN32
+#ifdef _WIN32
#else
# include <unistd.h>
# include <sys/wait.h>
-#endif /* WIN32 */
+#endif /* _WIN32 */
/*
@@ -2087,7 +2087,7 @@ do_samba_command(const char *command, /* I - Command to run */
const char *authfile, /* I - Samba authentication file */
FILE *logfile) /* I - Optional log file */
{
-#ifdef WIN32
+#ifdef _WIN32
return (1); /* Always fail on Windows... */
#else
@@ -2154,7 +2154,7 @@ do_samba_command(const char *command, /* I - Command to run */
return (WEXITSTATUS(status));
else
return (-WTERMSIG(status));
-#endif /* WIN32 */
+#endif /* _WIN32 */
}
@@ -2172,9 +2172,9 @@ get_cupsd_conf(
int *remote) /* O - Remote file? */
{
int fd; /* Temporary file descriptor */
-#ifndef WIN32
+#ifndef _WIN32
struct stat info; /* cupsd.conf file information */
-#endif /* WIN32 */
+#endif /* _WIN32 */
http_status_t status; /* Status of getting cupsd.conf */
char host[HTTP_MAX_HOST]; /* Hostname for connection */
@@ -2191,7 +2191,7 @@ get_cupsd_conf(
snprintf(name, namesize, "%s/cupsd.conf", cg->cups_serverroot);
*remote = 0;
-#ifndef WIN32
+#ifndef _WIN32
if (!_cups_strcasecmp(host, "localhost") && !access(name, R_OK))
{
/*
@@ -2218,7 +2218,7 @@ get_cupsd_conf(
status = HTTP_STATUS_OK;
}
else
-#endif /* !WIN32 */
+#endif /* !_WIN32 */
{
/*
* Read cupsd.conf via a HTTP GET request...
diff --git a/cups/api-ppd.shtml b/cups/api-ppd.shtml
index 50c48500..49409462 100644
--- a/cups/api-ppd.shtml
+++ b/cups/api-ppd.shtml
@@ -1,7 +1,7 @@
<!--
PPD API introduction for CUPS.
- Copyright 2007-2012 by Apple Inc.
+ Copyright 2007-2018 by Apple Inc.
Copyright 1997-2006 by Easy Software Products, all rights reserved.
These coded instructions, statements, and computer programs are the
@@ -13,7 +13,7 @@
<h2 class='title'><a name='OVERVIEW'>Overview</a></h2>
-<blockquote>The PPD API is deprecated starting in CUPS 1.6/macOS 10.8. Please use the new Job Ticket APIs in the <a href="api-cups.html">CUPS API</a> documentation. These functions will be removed in a future release of CUPS.</blockquote>
+<blockquote>The PPD API is deprecated starting in CUPS 1.6/macOS 10.8. Please use the new Job Ticket APIs in the <a href="cupspm.html">CUPS API</a> documentation. These functions will be removed in a future release of CUPS.</blockquote>
<p>The CUPS PPD API provides read-only access the data in PostScript Printer
Description ("PPD") files which are used for all printers with a driver. With
diff --git a/cups/auth.c b/cups/auth.c
index c051c86b..a1f50423 100644
--- a/cups/auth.c
+++ b/cups/auth.c
@@ -1,8 +1,8 @@
/*
* Authentication functions for CUPS.
*
- * Copyright 2007-2016 by Apple Inc.
- * Copyright 1997-2007 by Easy Software Products.
+ * Copyright © 2007-2018 by Apple Inc.
+ * Copyright © 1997-2007 by Easy Software Products.
*
* This file contains Kerberos support code, copyright 2006 by
* Jelmer Vernooij.
@@ -23,11 +23,11 @@
#include "cups-private.h"
#include <fcntl.h>
#include <sys/stat.h>
-#if defined(WIN32) || defined(__EMX__)
+#if defined(_WIN32) || defined(__EMX__)
# include <io.h>
#else
# include <unistd.h>
-#endif /* WIN32 || __EMX__ */
+#endif /* _WIN32 || __EMX__ */
#if HAVE_AUTHORIZATION_H
# include <Security/Authorization.h>
@@ -47,6 +47,10 @@ extern const char *cssmErrorString(int error);
* Local functions...
*/
+static const char *cups_auth_find(const char *www_authenticate, const char *scheme);
+static const char *cups_auth_param(const char *scheme, const char *name, char *value, size_t valsize);
+static const char *cups_auth_scheme(const char *www_authenticate, char *scheme, size_t schemesize);
+
#ifdef HAVE_GSSAPI
# ifdef HAVE_GSS_ACQUIRE_CRED_EX_F
# ifdef HAVE_GSS_GSSAPI_SPI_H
@@ -112,10 +116,10 @@ cupsDoAuthentication(
const char *resource) /* I - Resource path */
{
const char *password, /* Password string */
- *www_auth; /* WWW-Authenticate header */
- char prompt[1024], /* Prompt for user */
- realm[HTTP_MAX_VALUE], /* realm="xyz" string */
- nonce[HTTP_MAX_VALUE]; /* nonce="xyz" string */
+ *www_auth, /* WWW-Authenticate header */
+ *schemedata; /* Scheme-specific data */
+ char scheme[256], /* Scheme name */
+ prompt[1024]; /* Prompt for user */
int localauth; /* Local authentication result */
_cups_globals_t *cg; /* Global data */
@@ -163,122 +167,129 @@ cupsDoAuthentication(
}
/*
- * Nope, see if we should retry the current username:password...
+ * Nope, loop through the authentication schemes to find the first we support.
*/
- www_auth = http->fields[HTTP_FIELD_WWW_AUTHENTICATE];
+ www_auth = httpGetField(http, HTTP_FIELD_WWW_AUTHENTICATE);
- if ((http->digest_tries > 1 || !http->userpass[0]) &&
- (!_cups_strncasecmp(www_auth, "Basic", 5) ||
- !_cups_strncasecmp(www_auth, "Digest", 6)))
+ for (schemedata = cups_auth_scheme(www_auth, scheme, sizeof(scheme)); schemedata; schemedata = cups_auth_scheme(schemedata + strlen(scheme), scheme, sizeof(scheme)))
{
/*
- * Nope - get a new password from the user...
+ * Check the scheme name...
*/
- char default_username[HTTP_MAX_VALUE];
- /* Default username */
+#ifdef HAVE_GSSAPI
+ if (!_cups_strcasecmp(scheme, "Negotiate"))
+ {
+ /*
+ * Kerberos authentication...
+ */
- cg = _cupsGlobals();
+ if (_cupsSetNegotiateAuthString(http, method, resource))
+ {
+ http->status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED;
+ return (-1);
+ }
- if (!cg->lang_default)
- cg->lang_default = cupsLangDefault();
+ break;
+ }
+ else
+#endif /* HAVE_GSSAPI */
+ if (_cups_strcasecmp(scheme, "Basic") && _cups_strcasecmp(scheme, "Digest"))
+ continue; /* Not supported (yet) */
- if (httpGetSubField(http, HTTP_FIELD_WWW_AUTHENTICATE, "username",
- default_username))
- cupsSetUser(default_username);
+ /*
+ * See if we should retry the current username:password...
+ */
- snprintf(prompt, sizeof(prompt),
- _cupsLangString(cg->lang_default, _("Password for %s on %s? ")),
- cupsUser(),
- http->hostname[0] == '/' ? "localhost" : http->hostname);
+ if ((http->digest_tries > 1 || !http->userpass[0]) && (!_cups_strcasecmp(scheme, "Basic") || (!_cups_strcasecmp(scheme, "Digest"))))
+ {
+ /*
+ * Nope - get a new password from the user...
+ */
- http->digest_tries = _cups_strncasecmp(www_auth, "Digest", 6) != 0;
- http->userpass[0] = '\0';
+ char default_username[HTTP_MAX_VALUE];
+ /* Default username */
- if ((password = cupsGetPassword2(prompt, http, method, resource)) == NULL)
- {
- http->status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED;
- return (-1);
- }
+ cg = _cupsGlobals();
- snprintf(http->userpass, sizeof(http->userpass), "%s:%s", cupsUser(),
- password);
- }
- else if (http->status == HTTP_STATUS_UNAUTHORIZED)
- http->digest_tries ++;
+ if (!cg->lang_default)
+ cg->lang_default = cupsLangDefault();
- if (http->status == HTTP_STATUS_UNAUTHORIZED && http->digest_tries >= 3)
- {
- DEBUG_printf(("1cupsDoAuthentication: Too many authentication tries (%d)",
- http->digest_tries));
+ if (cups_auth_param(schemedata, "username", default_username, sizeof(default_username)))
+ cupsSetUser(default_username);
- http->status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED;
- return (-1);
- }
+ snprintf(prompt, sizeof(prompt), _cupsLangString(cg->lang_default, _("Password for %s on %s? ")), cupsUser(), http->hostname[0] == '/' ? "localhost" : http->hostname);
- /*
- * Got a password; encode it for the server...
- */
+ http->digest_tries = _cups_strncasecmp(scheme, "Digest", 6) != 0;
+ http->userpass[0] = '\0';
-#ifdef HAVE_GSSAPI
- if (!_cups_strncasecmp(www_auth, "Negotiate", 9))
- {
- /*
- * Kerberos authentication...
- */
+ if ((password = cupsGetPassword2(prompt, http, method, resource)) == NULL)
+ {
+ http->status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED;
+ return (-1);
+ }
- if (_cupsSetNegotiateAuthString(http, method, resource))
+ snprintf(http->userpass, sizeof(http->userpass), "%s:%s", cupsUser(), password);
+ }
+ else if (http->status == HTTP_STATUS_UNAUTHORIZED)
+ http->digest_tries ++;
+
+ if (http->status == HTTP_STATUS_UNAUTHORIZED && http->digest_tries >= 3)
{
+ DEBUG_printf(("1cupsDoAuthentication: Too many authentication tries (%d)", http->digest_tries));
+
http->status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED;
return (-1);
}
- }
- else
-#endif /* HAVE_GSSAPI */
- if (!_cups_strncasecmp(www_auth, "Basic", 5))
- {
+
/*
- * Basic authentication...
+ * Got a password; encode it for the server...
*/
- char encode[256]; /* Base64 buffer */
+ if (!_cups_strcasecmp(scheme, "Basic"))
+ {
+ /*
+ * Basic authentication...
+ */
+ char encode[256]; /* Base64 buffer */
- httpEncode64_2(encode, sizeof(encode), http->userpass,
- (int)strlen(http->userpass));
- httpSetAuthString(http, "Basic", encode);
- }
- else if (!_cups_strncasecmp(www_auth, "Digest", 6))
- {
- /*
- * Digest authentication...
- */
+ httpEncode64_2(encode, sizeof(encode), http->userpass, (int)strlen(http->userpass));
+ httpSetAuthString(http, "Basic", encode);
+ break;
+ }
+ else if (!_cups_strcasecmp(scheme, "Digest"))
+ {
+ /*
+ * Digest authentication...
+ */
- char encode[33], /* MD5 buffer */
- digest[1024]; /* Digest auth data */
+ char nonce[HTTP_MAX_VALUE]; /* nonce="xyz" string */
- httpGetSubField(http, HTTP_FIELD_WWW_AUTHENTICATE, "realm", realm);
- httpGetSubField(http, HTTP_FIELD_WWW_AUTHENTICATE, "nonce", nonce);
+ cups_auth_param(schemedata, "algorithm", http->algorithm, sizeof(http->algorithm));
+ cups_auth_param(schemedata, "opaque", http->opaque, sizeof(http->opaque));
+ cups_auth_param(schemedata, "nonce", nonce, sizeof(nonce));
+ cups_auth_param(schemedata, "realm", http->realm, sizeof(http->realm));
- httpMD5(cupsUser(), realm, strchr(http->userpass, ':') + 1, encode);
- httpMD5Final(nonce, method, resource, encode);
- snprintf(digest, sizeof(digest),
- "username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", "
- "response=\"%s\"", cupsUser(), realm, nonce, resource, encode);
- httpSetAuthString(http, "Digest", digest);
+ if (_httpSetDigestAuthString(http, nonce, method, resource))
+ break;
+ }
+ }
+
+ if (http->authstring)
+ {
+ DEBUG_printf(("1cupsDoAuthentication: authstring=\"%s\"", http->authstring));
+
+ return (0);
}
else
{
- DEBUG_printf(("1cupsDoAuthentication: Unknown auth type: \"%s\"",
- www_auth));
+ DEBUG_printf(("1cupsDoAuthentication: Unknown auth type: \"%s\"", www_auth));
http->status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED;
+
return (-1);
}
-
- DEBUG_printf(("1cupsDoAuthentication: authstring=\"%s\"", http->authstring));
-
- return (0);
}
@@ -336,7 +347,7 @@ _cupsSetNegotiateAuthString(
GSS_C_NO_BUFFER, &http->gssmech,
&output_token, NULL, NULL);
-#ifdef HAVE_GSS_ACQUIRE_CRED_EX_F
+# ifdef HAVE_GSS_ACQUIRE_CRED_EX_F
if (major_status == GSS_S_NO_CRED)
{
/*
@@ -412,7 +423,7 @@ _cupsSetNegotiateAuthString(
}
}
}
-#endif /* HAVE_GSS_ACQUIRED_CRED_EX_F */
+# endif /* HAVE_GSS_ACQUIRED_CRED_EX_F */
if (GSS_ERROR(major_status))
{
@@ -422,11 +433,11 @@ _cupsSetNegotiateAuthString(
return (-1);
}
-#ifdef DEBUG
+# ifdef DEBUG
else if (major_status == GSS_S_CONTINUE_NEEDED)
cups_gss_printf(major_status, minor_status,
"_cupsSetNegotiateAuthString: Continuation needed!");
-#endif /* DEBUG */
+# endif /* DEBUG */
if (output_token.length > 0 && output_token.length <= 65536)
{
@@ -464,8 +475,259 @@ _cupsSetNegotiateAuthString(
return (0);
}
+#endif /* HAVE_GSSAPI */
+
+
+/*
+ * 'cups_auth_find()' - Find the named WWW-Authenticate scheme.
+ *
+ * The "www_authenticate" parameter points to the current position in the header.
+ *
+ * Returns @code NULL@ if the auth scheme is not present.
+ */
+
+static const char * /* O - Start of matching scheme or @code NULL@ if not found */
+cups_auth_find(const char *www_authenticate, /* I - Pointer into WWW-Authenticate header */
+ const char *scheme) /* I - Authentication scheme */
+{
+ size_t schemelen = strlen(scheme); /* Length of scheme */
+
+
+ DEBUG_printf(("8cups_auth_find(www_authenticate=\"%s\", scheme=\"%s\"(%d))", www_authenticate, scheme, (int)schemelen));
+
+ while (*www_authenticate)
+ {
+ /*
+ * Skip leading whitespace and commas...
+ */
+
+ DEBUG_printf(("9cups_auth_find: Before whitespace: \"%s\"", www_authenticate));
+ while (isspace(*www_authenticate & 255) || *www_authenticate == ',')
+ www_authenticate ++;
+ DEBUG_printf(("9cups_auth_find: After whitespace: \"%s\"", www_authenticate));
+
+ /*
+ * See if this is "Scheme" followed by whitespace or the end of the string.
+ */
+
+ if (!strncmp(www_authenticate, scheme, schemelen) && (isspace(www_authenticate[schemelen] & 255) || www_authenticate[schemelen] == ',' || !www_authenticate[schemelen]))
+ {
+ /*
+ * Yes, this is the start of the scheme-specific information...
+ */
+
+ DEBUG_printf(("9cups_auth_find: Returning \"%s\".", www_authenticate));
+
+ return (www_authenticate);
+ }
+
+ /*
+ * Skip the scheme name or param="value" string...
+ */
+
+ while (!isspace(*www_authenticate & 255) && *www_authenticate)
+ {
+ if (*www_authenticate == '\"')
+ {
+ /*
+ * Skip quoted value...
+ */
+
+ www_authenticate ++;
+ while (*www_authenticate && *www_authenticate != '\"')
+ www_authenticate ++;
+
+ DEBUG_printf(("9cups_auth_find: After quoted: \"%s\"", www_authenticate));
+ }
+
+ www_authenticate ++;
+ }
+
+ DEBUG_printf(("9cups_auth_find: After skip: \"%s\"", www_authenticate));
+ }
+
+ DEBUG_puts("9cups_auth_find: Returning NULL.");
+
+ return (NULL);
+}
+/*
+ * 'cups_auth_param()' - Copy the value for the named authentication parameter,
+ * if present.
+ */
+
+static const char * /* O - Parameter value or @code NULL@ if not present */
+cups_auth_param(const char *scheme, /* I - Pointer to auth data */
+ const char *name, /* I - Name of parameter */
+ char *value, /* I - Value buffer */
+ size_t valsize) /* I - Size of value buffer */
+{
+ char *valptr = value, /* Pointer into value buffer */
+ *valend = value + valsize - 1; /* Pointer to end of buffer */
+ size_t namelen = strlen(name); /* Name length */
+ int param; /* Is this a parameter? */
+
+
+ DEBUG_printf(("8cups_auth_param(scheme=\"%s\", name=\"%s\", value=%p, valsize=%d)", scheme, name, (void *)value, (int)valsize));
+
+ while (!isspace(*scheme & 255) && *scheme)
+ scheme ++;
+
+ while (*scheme)
+ {
+ while (isspace(*scheme & 255) || *scheme == ',')
+ scheme ++;
+
+ if (!strncmp(scheme, name, namelen) && scheme[namelen] == '=')
+ {
+ /*
+ * Found the parameter, copy the value...
+ */
+
+ scheme += namelen + 1;
+ if (*scheme == '\"')
+ {
+ scheme ++;
+
+ while (*scheme && *scheme != '\"')
+ {
+ if (valptr < valend)
+ *valptr++ = *scheme;
+
+ scheme ++;
+ }
+ }
+ else
+ {
+ while (*scheme && strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~+/=", *scheme))
+ {
+ if (valptr < valend)
+ *valptr++ = *scheme;
+
+ scheme ++;
+ }
+ }
+
+ *valptr = '\0';
+
+ DEBUG_printf(("9cups_auth_param: Returning \"%s\".", value));
+
+ return (value);
+ }
+
+ /*
+ * Skip the param=value string...
+ */
+
+ param = 0;
+
+ while (!isspace(*scheme & 255) && *scheme)
+ {
+ if (*scheme == '=')
+ param = 1;
+ else if (*scheme == '\"')
+ {
+ /*
+ * Skip quoted value...
+ */
+
+ scheme ++;
+ while (*scheme && *scheme != '\"')
+ scheme ++;
+ }
+
+ scheme ++;
+ }
+
+ /*
+ * If this wasn't a parameter, we are at the end of this scheme's
+ * parameters...
+ */
+
+ if (!param)
+ break;
+ }
+
+ *value = '\0';
+
+ DEBUG_puts("9cups_auth_param: Returning NULL.");
+
+ return (NULL);
+}
+
+
+/*
+ * 'cups_auth_scheme()' - Get the (next) WWW-Authenticate scheme.
+ *
+ * The "www_authenticate" parameter points to the current position in the header.
+ *
+ * Returns @code NULL@ if there are no (more) auth schemes present.
+ */
+
+static const char * /* O - Start of scheme or @code NULL@ if not found */
+cups_auth_scheme(const char *www_authenticate, /* I - Pointer into WWW-Authenticate header */
+ char *scheme, /* I - Scheme name buffer */
+ size_t schemesize) /* I - Size of buffer */
+{
+ const char *start; /* Start of scheme data */
+ char *sptr = scheme, /* Pointer into scheme buffer */
+ *send = scheme + schemesize - 1;/* End of scheme buffer */
+ int param; /* Is this a parameter? */
+
+
+ DEBUG_printf(("8cups_auth_scheme(www_authenticate=\"%s\", scheme=%p, schemesize=%d)", www_authenticate, (void *)scheme, (int)schemesize));
+
+ while (*www_authenticate)
+ {
+ /*
+ * Skip leading whitespace and commas...
+ */
+
+ while (isspace(*www_authenticate & 255) || *www_authenticate == ',')
+ www_authenticate ++;
+
+ /*
+ * Parse the scheme name or param="value" string...
+ */
+
+ for (sptr = scheme, start = www_authenticate, param = 0; *www_authenticate && *www_authenticate != ',' && !isspace(*www_authenticate & 255); www_authenticate ++)
+ {
+ if (*www_authenticate == '=')
+ param = 1;
+ else if (!param && sptr < send)
+ *sptr++ = *www_authenticate;
+ else if (*www_authenticate == '\"')
+ {
+ /*
+ * Skip quoted value...
+ */
+
+ www_authenticate ++;
+ while (*www_authenticate && *www_authenticate != '\"')
+ www_authenticate ++;
+ }
+ }
+
+ if (sptr > scheme && !param)
+ {
+ *sptr = '\0';
+
+ DEBUG_printf(("9cups_auth_scheme: Returning \"%s\".", start));
+
+ return (start);
+ }
+ }
+
+ *scheme = '\0';
+
+ DEBUG_puts("9cups_auth_scheme: Returning NULL.");
+
+ return (NULL);
+}
+
+
+#ifdef HAVE_GSSAPI
# ifdef HAVE_GSS_ACQUIRE_CRED_EX_F
/*
* 'cups_gss_acquire()' - Kerberos credentials callback.
@@ -639,9 +901,9 @@ static int /* O - 0 if available */
/* -1 error */
cups_local_auth(http_t *http) /* I - HTTP connection to server */
{
-#if defined(WIN32) || defined(__EMX__)
+#if defined(_WIN32) || defined(__EMX__)
/*
- * Currently WIN32 and OS-2 do not support the CUPS server...
+ * Currently _WIN32 and OS-2 do not support the CUPS server...
*/
return (1);
@@ -650,6 +912,8 @@ cups_local_auth(http_t *http) /* I - HTTP connection to server */
FILE *fp; /* Certificate file */
char trc[16], /* Try Root Certificate parameter */
filename[1024]; /* Certificate filename */
+ const char *www_auth, /* WWW-Authenticate header */
+ *schemedata; /* Data for the named auth scheme */
_cups_globals_t *cg = _cupsGlobals(); /* Global data */
# if defined(HAVE_AUTHORIZATION_H)
OSStatus status; /* Status */
@@ -668,13 +932,14 @@ 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 (!httpAddrLocalhost(http->hostaddr) && _cups_strcasecmp(http->hostname, "localhost") != 0)
{
DEBUG_puts("8cups_local_auth: Not a local connection!");
return (1);
}
+ www_auth = httpGetField(http, HTTP_FIELD_WWW_AUTHENTICATE);
+
# if defined(HAVE_AUTHORIZATION_H)
/*
* Delete any previous authorization reference...
@@ -686,12 +951,9 @@ cups_local_auth(http_t *http) /* I - HTTP connection to server */
http->auth_ref = NULL;
}
- if (!getenv("GATEWAY_INTERFACE") &&
- httpGetSubField2(http, HTTP_FIELD_WWW_AUTHENTICATE, "authkey",
- auth_key, sizeof(auth_key)))
+ if (!getenv("GATEWAY_INTERFACE") && (schemedata = cups_auth_find(www_auth, "AuthRef")) != NULL && cups_auth_param(schemedata, "key", auth_key, sizeof(auth_key)))
{
- status = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment,
- kAuthorizationFlagDefaults, &http->auth_ref);
+ status = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &http->auth_ref);
if (status != errAuthorizationSuccess)
{
DEBUG_printf(("8cups_local_auth: AuthorizationCreate() returned %d (%s)",
@@ -745,6 +1007,11 @@ 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
@@ -752,16 +1019,9 @@ cups_local_auth(http_t *http) /* I - HTTP connection to server */
* information...
*/
- if (
-# ifdef HAVE_GSSAPI
- _cups_strncasecmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Negotiate", 9) &&
-# endif /* HAVE_GSSAPI */
-# ifdef HAVE_AUTHORIZATION_H
- !httpGetSubField2(http, HTTP_FIELD_WWW_AUTHENTICATE, "authkey",
- auth_key, sizeof(auth_key)) &&
-# endif /* HAVE_AUTHORIZATION_H */
- http->hostaddr->addr.sa_family == AF_LOCAL &&
- !getenv("GATEWAY_INTERFACE")) /* Not via CGI programs... */
+ if (http->hostaddr->addr.sa_family == AF_LOCAL &&
+ !getenv("GATEWAY_INTERFACE") && /* Not via CGI programs... */
+ cups_auth_find(www_auth, "PeerCred"))
{
/*
* Verify that the current cupsUser() matches the current UID...
@@ -784,6 +1044,9 @@ cups_local_auth(http_t *http) /* I - HTTP connection to server */
}
# endif /* SO_PEERCRED && AF_LOCAL */
+ if ((schemedata = cups_auth_find(www_auth, "Local")) == NULL)
+ return (1);
+
/*
* Try opening a certificate file for this PID. If that fails,
* try the root certificate...
@@ -797,33 +1060,9 @@ cups_local_auth(http_t *http) /* I - HTTP connection to server */
* No certificate for this PID; see if we can get the root certificate...
*/
- DEBUG_printf(("9cups_local_auth: Unable to open file %s: %s",
- filename, strerror(errno)));
+ DEBUG_printf(("9cups_local_auth: Unable to open file \"%s\": %s", filename, strerror(errno)));
-# ifdef HAVE_GSSAPI
- if (!_cups_strncasecmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Negotiate", 9))
- {
- /*
- * Kerberos required, don't try the root certificate...
- */
-
- return (1);
- }
-# endif /* HAVE_GSSAPI */
-
-# ifdef HAVE_AUTHORIZATION_H
- if (httpGetSubField2(http, HTTP_FIELD_WWW_AUTHENTICATE, "authkey",
- auth_key, sizeof(auth_key)))
- {
- /*
- * Don't use the root certificate as a replacement for an authkey...
- */
-
- return (1);
- }
-# endif /* HAVE_AUTHORIZATION_H */
- if (!httpGetSubField2(http, HTTP_FIELD_WWW_AUTHENTICATE, "trc", trc,
- sizeof(trc)))
+ if (!cups_auth_param(schemedata, "trc", trc, sizeof(trc)))
{
/*
* Scheduler doesn't want us to use the root certificate...
@@ -833,7 +1072,8 @@ cups_local_auth(http_t *http) /* I - HTTP connection to server */
}
snprintf(filename, sizeof(filename), "%s/certs/0", cg->cups_statedir);
- fp = fopen(filename, "r");
+ if ((fp = fopen(filename, "r")) == NULL)
+ DEBUG_printf(("9cups_local_auth: Unable to open file \"%s\": %s", filename, strerror(errno)));
}
if (fp)
@@ -864,5 +1104,5 @@ cups_local_auth(http_t *http) /* I - HTTP connection to server */
}
return (1);
-#endif /* WIN32 || __EMX__ */
+#endif /* _WIN32 || __EMX__ */
}
diff --git a/cups/backchannel.c b/cups/backchannel.c
index e804d45b..bca04dc3 100644
--- a/cups/backchannel.c
+++ b/cups/backchannel.c
@@ -19,12 +19,12 @@
#include "cups.h"
#include <errno.h>
-#ifdef WIN32
+#ifdef _WIN32
# include <io.h>
# include <fcntl.h>
#else
# include <sys/time.h>
-#endif /* WIN32 */
+#endif /* _WIN32 */
/*
@@ -77,11 +77,11 @@ cupsBackChannelRead(char *buffer, /* I - Buffer to read into */
* Read bytes from the pipe...
*/
-#ifdef WIN32
+#ifdef _WIN32
return ((ssize_t)_read(3, buffer, (unsigned)bytes));
#else
return (read(3, buffer, bytes));
-#endif /* WIN32 */
+#endif /* _WIN32 */
}
@@ -139,11 +139,11 @@ cupsBackChannelWrite(
* Write bytes to the pipe...
*/
-#ifdef WIN32
+#ifdef _WIN32
count = (ssize_t)_write(3, buffer, (unsigned)(bytes - total));
#else
count = write(3, buffer, bytes - total);
-#endif /* WIN32 */
+#endif /* _WIN32 */
if (count < 0)
{
diff --git a/cups/cups.h b/cups/cups.h
index 8f5c818f..cf3be127 100644
--- a/cups/cups.h
+++ b/cups/cups.h
@@ -1,7 +1,7 @@
/*
* API definitions for CUPS.
*
- * Copyright 2007-2017 by Apple Inc.
+ * Copyright 2007-2018 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
@@ -21,12 +21,12 @@
*/
# include <sys/types.h>
-# if defined(WIN32) && !defined(__CUPS_SSIZE_T_DEFINED)
+# if defined(_WIN32) && !defined(__CUPS_SSIZE_T_DEFINED)
# define __CUPS_SSIZE_T_DEFINED
# include <stddef.h>
/* Windows does not support the ssize_t type, so map it to long... */
typedef long ssize_t; /* @private@ */
-# endif /* WIN32 && !__CUPS_SSIZE_T_DEFINED */
+# endif /* _WIN32 && !__CUPS_SSIZE_T_DEFINED */
# include "file.h"
# include "ipp.h"
@@ -47,10 +47,10 @@ extern "C" {
* Constants...
*/
-# define CUPS_VERSION 2.0206
+# define CUPS_VERSION 2.0209
# define CUPS_VERSION_MAJOR 2
# define CUPS_VERSION_MINOR 2
-# define CUPS_VERSION_PATCH 6
+# define CUPS_VERSION_PATCH 9
# define CUPS_BC_FD 3
/* Back-channel file descriptor for
@@ -606,6 +606,9 @@ extern ssize_t cupsHashData(const char *algorithm, const void *data, size_t dat
extern int cupsAddIntegerOption(const char *name, int value, int num_options, cups_option_t **options) _CUPS_API_2_2_4;
extern int cupsGetIntegerOption(const char *name, int num_options, cups_option_t *options) _CUPS_API_2_2_4;
+/* New in CUPS 2.2.7 */
+extern const char *cupsHashString(const unsigned char *hash, size_t hashsize, char *buffer, size_t bufsize) _CUPS_API_2_2_7;
+
# ifdef __cplusplus
}
# endif /* __cplusplus */
diff --git a/cups/debug-private.h b/cups/debug-private.h
index 23a0ae17..dc9fe4eb 100644
--- a/cups/debug-private.h
+++ b/cups/debug-private.h
@@ -1,7 +1,7 @@
/*
* Private debugging macros for CUPS.
*
- * Copyright 2007-2012 by Apple Inc.
+ * Copyright 2007-2018 by Apple Inc.
* Copyright 1997-2005 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
@@ -67,20 +67,10 @@ extern "C" {
*/
# ifdef DEBUG
-# ifdef WIN32
-# ifdef LIBCUPS2_EXPORTS
-# define DLLExport __declspec(dllexport)
-# else
-# define DLLExport
-# endif /* LIBCUPS2_EXPORTS */
-# else
-# define DLLExport
-# endif /* WIN32 */
# define DEBUG_puts(x) _cups_debug_puts(x)
# define DEBUG_printf(x) _cups_debug_printf x
# define DEBUG_set(logfile,level,filter) _cups_debug_set(logfile,level,filter,1)
# else
-# define DLLExport
# define DEBUG_puts(x)
# define DEBUG_printf(x)
# define DEBUG_set(logfile,level,filter)
@@ -93,16 +83,13 @@ extern "C" {
extern int _cups_debug_fd;
extern int _cups_debug_level;
-extern void DLLExport _cups_debug_printf(const char *format, ...)
- __attribute__ ((__format__ (__printf__, 1, 2)));
-extern void DLLExport _cups_debug_puts(const char *s);
-extern void DLLExport _cups_debug_set(const char *logfile,
- const char *level, const char *filter,
- int force);
-# ifdef WIN32
-extern int _cups_gettimeofday(struct timeval *tv, void *tz);
+extern void _cups_debug_printf(const char *format, ...) _CUPS_FORMAT(1, 2);
+extern void _cups_debug_puts(const char *s);
+extern void _cups_debug_set(const char *logfile, const char *level, const char *filter, int force) _CUPS_PRIVATE;
+# ifdef _WIN32
+extern int _cups_gettimeofday(struct timeval *tv, void *tz) _CUPS_PRIVATE;
# define gettimeofday(a,b) _cups_gettimeofday(a, b)
-# endif /* WIN32 */
+# endif /* _WIN32 */
# ifdef __cplusplus
}
diff --git a/cups/debug.c b/cups/debug.c
index bd244fe7..b68f5edb 100644
--- a/cups/debug.c
+++ b/cups/debug.c
@@ -18,7 +18,7 @@
#include "cups-private.h"
#include "thread-private.h"
-#ifdef WIN32
+#ifdef _WIN32
# include <sys/timeb.h>
# include <time.h>
# include <io.h>
@@ -36,7 +36,7 @@ _cups_gettimeofday(struct timeval *tv, /* I - Timeval struct */
#else
# include <sys/time.h>
# include <unistd.h>
-#endif /* WIN32 */
+#endif /* _WIN32 */
#include <regex.h>
#include <fcntl.h>
@@ -83,7 +83,7 @@ debug_thread_id(void)
* '_cups_debug_printf()' - Write a formatted line to the log.
*/
-void DLLExport
+void
_cups_debug_printf(const char *format, /* I - Printf-style format string */
...) /* I - Additional arguments as needed */
{
@@ -168,7 +168,7 @@ _cups_debug_printf(const char *format, /* I - Printf-style format string */
* '_cups_debug_puts()' - Write a single line to the log.
*/
-void DLLExport
+void
_cups_debug_puts(const char *s) /* I - String to output */
{
struct timeval curtime; /* Current time */
@@ -248,7 +248,7 @@ _cups_debug_puts(const char *s) /* I - String to output */
* '_cups_debug_set()' - Enable or disable debug logging.
*/
-void DLLExport
+void
_cups_debug_set(const char *logfile, /* I - Log file or NULL */
const char *level, /* I - Log level or NULL */
const char *filter, /* I - Filter string or NULL */
diff --git a/cups/dest.c b/cups/dest.c
index 57a8dc95..7ef85a1b 100644
--- a/cups/dest.c
+++ b/cups/dest.c
@@ -2090,9 +2090,9 @@ cupsSetDests2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_
cups_option_t *option; /* Current option */
_ipp_option_t *match; /* Matching attribute for option */
FILE *fp; /* File pointer */
-#ifndef WIN32
+#ifndef _WIN32
const char *home; /* HOME environment variable */
-#endif /* WIN32 */
+#endif /* _WIN32 */
char filename[1024]; /* lpoptions file */
int num_temps; /* Number of temporary destinations */
cups_dest_t *temps = NULL, /* Temporary destinations */
@@ -2126,7 +2126,7 @@ cupsSetDests2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_
snprintf(filename, sizeof(filename), "%s/lpoptions", cg->cups_serverroot);
-#ifndef WIN32
+#ifndef _WIN32
if (getuid())
{
/*
@@ -2152,7 +2152,7 @@ cupsSetDests2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_
snprintf(filename, sizeof(filename), "%s/.cups/lpoptions", home);
}
}
-#endif /* !WIN32 */
+#endif /* !_WIN32 */
/*
* Try to open the file...
@@ -2164,7 +2164,7 @@ cupsSetDests2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_
return (-1);
}
-#ifndef WIN32
+#ifndef _WIN32
/*
* Set the permissions to 0644 when saving to the /etc/cups/lpoptions
* file...
@@ -2172,7 +2172,7 @@ cupsSetDests2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_
if (!getuid())
fchmod(fileno(fp), 0644);
-#endif /* !WIN32 */
+#endif /* !_WIN32 */
/*
* Write each printer; each line looks like:
diff --git a/cups/dir.c b/cups/dir.c
index b7cd400c..6b377784 100644
--- a/cups/dir.c
+++ b/cups/dir.c
@@ -26,7 +26,7 @@
* Windows implementation...
*/
-#ifdef WIN32
+#ifdef _WIN32
# include <windows.h>
/*
@@ -145,7 +145,7 @@ cupsDirOpen(const char *directory) /* I - Directory name */
cups_dentry_t * /* O - Directory entry or @code NULL@ if there are no more */
cupsDirRead(cups_dir_t *dp) /* I - Directory pointer */
{
- WIN32_FIND_DATA entry; /* Directory entry data */
+ WIN32_FIND_DATAA entry; /* Directory entry data */
/*
@@ -165,11 +165,11 @@ cupsDirRead(cups_dir_t *dp) /* I - Directory pointer */
* No, find the first file...
*/
- dp->dir = FindFirstFile(dp->directory, &entry);
+ dp->dir = FindFirstFileA(dp->directory, &entry);
if (dp->dir == INVALID_HANDLE_VALUE)
return (NULL);
}
- else if (!FindNextFile(dp->dir, &entry))
+ else if (!FindNextFileA(dp->dir, &entry))
return (NULL);
/*
@@ -422,4 +422,4 @@ cupsDirRewind(cups_dir_t *dp) /* I - Directory pointer */
rewinddir(dp->dir);
}
-#endif /* WIN32 */
+#endif /* _WIN32 */
diff --git a/cups/file-private.h b/cups/file-private.h
index 1f4db798..6789283e 100644
--- a/cups/file-private.h
+++ b/cups/file-private.h
@@ -6,7 +6,7 @@
* our own file functions allows us to provide transparent support of
* different line endings, gzip'd print files, PPD files, etc.
*
- * Copyright 2007-2017 by Apple Inc.
+ * Copyright 2007-2018 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
@@ -31,13 +31,10 @@
# include <stdarg.h>
# include <fcntl.h>
-# ifdef HAVE_LIBZ
-# include <zlib.h>
-# endif /* HAVE_LIBZ */
-# ifdef WIN32
+# ifdef _WIN32
# include <io.h>
# include <sys/locking.h>
-# endif /* WIN32 */
+# endif /* _WIN32 */
/*
@@ -88,30 +85,6 @@ typedef enum /**** _cupsFileCheck file type values ****/
typedef void (*_cups_fc_func_t)(void *context, _cups_fc_result_t result,
const char *message);
-struct _cups_file_s /**** CUPS file structure... ****/
-
-{
- int fd; /* File descriptor */
- char mode, /* Mode ('r' or 'w') */
- compressed, /* Compression used? */
- is_stdio, /* stdin/out/err? */
- eof, /* End of file? */
- buf[4096], /* Buffer */
- *ptr, /* Pointer into buffer */
- *end; /* End of buffer data */
- off_t pos, /* Position in file */
- bufpos; /* File position for start of buffer */
-
-#ifdef HAVE_LIBZ
- z_stream stream; /* (De)compression stream */
- Bytef cbuf[4096]; /* (De)compression buffer */
- uLong crc; /* (De)compression CRC */
-#endif /* HAVE_LIBZ */
-
- char *printf_buffer; /* cupsFilePrintf buffer */
- size_t printf_size; /* Size of cupsFilePrintf buffer */
-};
-
/*
* Prototypes...
@@ -125,6 +98,7 @@ extern _cups_fc_result_t _cupsFileCheck(const char *filename,
extern void _cupsFileCheckFilter(void *context,
_cups_fc_result_t result,
const char *message);
+extern int _cupsFilePeekAhead(cups_file_t *fp, int ch);
# ifdef __cplusplus
}
diff --git a/cups/file.c b/cups/file.c
index 5d150540..5c9ddf8f 100644
--- a/cups/file.c
+++ b/cups/file.c
@@ -6,7 +6,7 @@
* our own file functions allows us to provide transparent support of
* different line endings, gzip'd print files, PPD files, etc.
*
- * Copyright 2007-2017 by Apple Inc.
+ * Copyright 2007-2018 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
@@ -26,6 +26,39 @@
#include <sys/stat.h>
#include <sys/types.h>
+# ifdef HAVE_LIBZ
+# include <zlib.h>
+# endif /* HAVE_LIBZ */
+
+
+/*
+ * Internal structures...
+ */
+
+struct _cups_file_s /**** CUPS file structure... ****/
+
+{
+ int fd; /* File descriptor */
+ char mode, /* Mode ('r' or 'w') */
+ compressed, /* Compression used? */
+ is_stdio, /* stdin/out/err? */
+ eof, /* End of file? */
+ buf[4096], /* Buffer */
+ *ptr, /* Pointer into buffer */
+ *end; /* End of buffer data */
+ off_t pos, /* Position in file */
+ bufpos; /* File position for start of buffer */
+
+#ifdef HAVE_LIBZ
+ z_stream stream; /* (De)compression stream */
+ Bytef cbuf[4096]; /* (De)compression buffer */
+ uLong crc; /* (De)compression CRC */
+#endif /* HAVE_LIBZ */
+
+ char *printf_buffer; /* cupsFilePrintf buffer */
+ size_t printf_size; /* Size of cupsFilePrintf buffer */
+};
+
/*
* Local functions...
@@ -40,7 +73,7 @@ static ssize_t cups_read(cups_file_t *fp, char *buf, size_t bytes);
static ssize_t cups_write(cups_file_t *fp, const char *buf, size_t bytes);
-#ifndef WIN32
+#ifndef _WIN32
/*
* '_cupsFileCheck()' - Check the permissions of the given filename.
*/
@@ -306,7 +339,7 @@ _cupsFileCheckFilter(
fprintf(stderr, "%s: %s\n", prefix, message);
}
-#endif /* !WIN32 */
+#endif /* !_WIN32 */
/*
@@ -526,22 +559,22 @@ cupsFileFind(const char *filename, /* I - File to find */
while (*path)
{
-#ifdef WIN32
+#ifdef _WIN32
if (*path == ';' || (*path == ':' && ((bufptr - buffer) > 1 || !isalpha(buffer[0] & 255))))
#else
if (*path == ';' || *path == ':')
-#endif /* WIN32 */
+#endif /* _WIN32 */
{
if (bufptr > buffer && bufptr[-1] != '/' && bufptr < bufend)
*bufptr++ = '/';
strlcpy(bufptr, filename, (size_t)(bufend - bufptr));
-#ifdef WIN32
+#ifdef _WIN32
if (!access(buffer, 0))
#else
if (!access(buffer, executable ? X_OK : 0))
-#endif /* WIN32 */
+#endif /* _WIN32 */
{
DEBUG_printf(("1cupsFileFind: Returning \"%s\"", buffer));
return (buffer);
@@ -992,11 +1025,11 @@ cupsFileLock(cups_file_t *fp, /* I - CUPS file */
* Try the lock...
*/
-#ifdef WIN32
+#ifdef _WIN32
return (_locking(fp->fd, block ? _LK_LOCK : _LK_NBLCK, 0));
#else
return (lockf(fp->fd, block ? F_LOCK : F_TLOCK, 0));
-#endif /* WIN32 */
+#endif /* _WIN32 */
}
@@ -1084,11 +1117,11 @@ cupsFileOpen(const char *filename, /* I - Name of file */
}
if (fd >= 0)
-#ifdef WIN32
+#ifdef _WIN32
_chsize(fd, 0);
#else
ftruncate(fd, 0);
-#endif /* WIN32 */
+#endif /* _WIN32 */
break;
case 's' : /* Read/write socket */
@@ -1255,15 +1288,27 @@ cupsFileOpenFd(int fd, /* I - File descriptor */
* Don't pass this file to child processes...
*/
-#ifndef WIN32
+#ifndef _WIN32
fcntl(fp->fd, F_SETFD, fcntl(fp->fd, F_GETFD) | FD_CLOEXEC);
-#endif /* !WIN32 */
+#endif /* !_WIN32 */
return (fp);
}
/*
+ * '_cupsFilePeekAhead()' - See if the requested character is buffered up.
+ */
+
+int /* O - 1 if present, 0 otherwise */
+_cupsFilePeekAhead(cups_file_t *fp, /* I - CUPS file */
+ int ch) /* I - Character */
+{
+ return (fp && fp->ptr && memchr(fp->ptr, ch, (size_t)(fp->end - fp->ptr)));
+}
+
+
+/*
* 'cupsFilePeekChar()' - Peek at the next character from a file.
*
* @since CUPS 1.2/macOS 10.5@
@@ -2019,11 +2064,11 @@ cupsFileUnlock(cups_file_t *fp) /* I - CUPS file */
* Unlock...
*/
-#ifdef WIN32
+#ifdef _WIN32
return (_locking(fp->fd, _LK_UNLCK, 0));
#else
return (lockf(fp->fd, F_ULOCK, 0));
-#endif /* WIN32 */
+#endif /* _WIN32 */
}
@@ -2553,9 +2598,9 @@ cups_open(const char *filename, /* I - Filename */
{
int fd; /* File descriptor */
struct stat fileinfo; /* File information */
-#ifndef WIN32
+#ifndef _WIN32
struct stat linkinfo; /* Link information */
-#endif /* !WIN32 */
+#endif /* !_WIN32 */
/*
@@ -2583,18 +2628,18 @@ cups_open(const char *filename, /* I - Filename */
return (-1);
}
-#ifdef WIN32
+#ifdef _WIN32
if (fileinfo.st_mode & _S_IFDIR)
#else
if (S_ISDIR(fileinfo.st_mode))
-#endif /* WIN32 */
+#endif /* _WIN32 */
{
close(fd);
errno = EISDIR;
return (-1);
}
-#ifndef WIN32
+#ifndef _WIN32
/*
* Then use lstat to determine whether the filename is a symlink...
*/
@@ -2622,7 +2667,7 @@ cups_open(const char *filename, /* I - Filename */
errno = EPERM;
return (-1);
}
-#endif /* !WIN32 */
+#endif /* !_WIN32 */
return (fd);
}
@@ -2648,7 +2693,7 @@ cups_read(cups_file_t *fp, /* I - CUPS file */
for (;;)
{
-#ifdef WIN32
+#ifdef _WIN32
if (fp->mode == 's')
total = (ssize_t)recv(fp->fd, buf, (unsigned)bytes, 0);
else
@@ -2658,7 +2703,7 @@ cups_read(cups_file_t *fp, /* I - CUPS file */
total = recv(fp->fd, buf, bytes, 0);
else
total = read(fp->fd, buf, bytes);
-#endif /* WIN32 */
+#endif /* _WIN32 */
DEBUG_printf(("9cups_read: total=" CUPS_LLFMT, CUPS_LLCAST total));
@@ -2705,7 +2750,7 @@ cups_write(cups_file_t *fp, /* I - CUPS file */
total = 0;
while (bytes > 0)
{
-#ifdef WIN32
+#ifdef _WIN32
if (fp->mode == 's')
count = (ssize_t)send(fp->fd, buf, (unsigned)bytes, 0);
else
@@ -2715,7 +2760,7 @@ cups_write(cups_file_t *fp, /* I - CUPS file */
count = send(fp->fd, buf, bytes, 0);
else
count = write(fp->fd, buf, bytes);
-#endif /* WIN32 */
+#endif /* _WIN32 */
DEBUG_printf(("9cups_write: count=" CUPS_LLFMT, CUPS_LLCAST count));
diff --git a/cups/file.h b/cups/file.h
index 42abe208..0d3a2e5d 100644
--- a/cups/file.h
+++ b/cups/file.h
@@ -6,7 +6,7 @@
* our own file functions allows us to provide transparent support of
* different line endings, gzip'd print files, PPD files, etc.
*
- * Copyright 2007-2017 by Apple Inc.
+ * Copyright 2007-2018 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
@@ -29,11 +29,11 @@
# include "versioning.h"
# include <stddef.h>
# include <sys/types.h>
-# if defined(WIN32) && !defined(__CUPS_SSIZE_T_DEFINED)
+# if defined(_WIN32) && !defined(__CUPS_SSIZE_T_DEFINED)
# define __CUPS_SSIZE_T_DEFINED
/* Windows does not support the ssize_t type, so map it to off_t... */
typedef off_t ssize_t; /* @private@ */
-# endif /* WIN32 && !__CUPS_SSIZE_T_DEFINED */
+# endif /* _WIN32 && !__CUPS_SSIZE_T_DEFINED */
/*
@@ -85,9 +85,7 @@ extern cups_file_t *cupsFileOpen(const char *filename, const char *mode)
_CUPS_API_1_2;
extern cups_file_t *cupsFileOpenFd(int fd, const char *mode) _CUPS_API_1_2;
extern int cupsFilePeekChar(cups_file_t *fp) _CUPS_API_1_2;
-extern int cupsFilePrintf(cups_file_t *fp, const char *format, ...)
- __attribute__((__format__ (__printf__, 2, 3)))
- _CUPS_API_1_2;
+extern int cupsFilePrintf(cups_file_t *fp, const char *format, ...) _CUPS_FORMAT(2, 3) _CUPS_API_1_2;
extern int cupsFilePutChar(cups_file_t *fp, int c) _CUPS_API_1_2;
extern ssize_t cupsFilePutConf(cups_file_t *fp, const char *directive,
const char *value) _CUPS_API_1_4;
diff --git a/cups/getputfile.c b/cups/getputfile.c
index ae33bc59..7749ae0a 100644
--- a/cups/getputfile.c
+++ b/cups/getputfile.c
@@ -1,7 +1,7 @@
/*
* Get/put file functions for CUPS.
*
- * Copyright 2007-2014 by Apple Inc.
+ * Copyright 2007-2018 by Apple Inc.
* Copyright 1997-2006 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
@@ -20,11 +20,11 @@
#include "cups-private.h"
#include <fcntl.h>
#include <sys/stat.h>
-#if defined(WIN32) || defined(__EMX__)
+#if defined(_WIN32) || defined(__EMX__)
# include <io.h>
#else
# include <unistd.h>
-#endif /* WIN32 || __EMX__ */
+#endif /* _WIN32 || __EMX__ */
/*
@@ -45,6 +45,8 @@ cupsGetFd(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFA
http_status_t status; /* HTTP status from server */
char if_modified_since[HTTP_MAX_VALUE];
/* If-Modified-Since header */
+ int new_auth = 0; /* Using new auth information? */
+ int digest; /* Are we using Digest authentication? */
/*
@@ -85,9 +87,33 @@ cupsGetFd(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFA
}
httpClearFields(http);
- httpSetField(http, HTTP_FIELD_AUTHORIZATION, http->authstring);
httpSetField(http, HTTP_FIELD_IF_MODIFIED_SINCE, if_modified_since);
+ digest = http->authstring && !strncmp(http->authstring, "Digest ", 7);
+
+ if (digest && !new_auth)
+ {
+ /*
+ * Update the Digest authentication string...
+ */
+
+ _httpSetDigestAuthString(http, http->nextnonce, "GET", resource);
+ }
+
+#ifdef HAVE_GSSAPI
+ if (http->authstring && !strncmp(http->authstring, "Negotiate", 9) && !new_auth)
+ {
+ /*
+ * Do not use cached Kerberos credentials since they will look like a
+ * "replay" attack...
+ */
+
+ _cupsSetNegotiateAuthString(http, "GET", resource);
+ }
+#endif /* HAVE_GSSAPI */
+
+ httpSetField(http, HTTP_FIELD_AUTHORIZATION, http->authstring);
+
if (httpGet(http, resource))
{
if (httpReconnect2(http, 30000, NULL))
@@ -102,6 +128,8 @@ cupsGetFd(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFA
}
}
+ new_auth = 0;
+
while ((status = httpUpdate(http)) == HTTP_STATUS_CONTINUE);
if (status == HTTP_STATUS_UNAUTHORIZED)
@@ -116,6 +144,8 @@ cupsGetFd(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFA
* See if we can do authentication...
*/
+ new_auth = 1;
+
if (cupsDoAuthentication(http, "GET", resource))
{
status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED;
@@ -267,6 +297,8 @@ cupsPutFd(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFA
int retries; /* Number of retries */
char buffer[8192]; /* Buffer for file */
http_status_t status; /* HTTP status from server */
+ int new_auth = 0; /* Using new auth information? */
+ int digest; /* Are we using Digest authentication? */
/*
@@ -309,10 +341,34 @@ cupsPutFd(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFA
http->authstring));
httpClearFields(http);
- httpSetField(http, HTTP_FIELD_AUTHORIZATION, http->authstring);
httpSetField(http, HTTP_FIELD_TRANSFER_ENCODING, "chunked");
httpSetExpect(http, HTTP_STATUS_CONTINUE);
+ digest = http->authstring && !strncmp(http->authstring, "Digest ", 7);
+
+ if (digest && !new_auth)
+ {
+ /*
+ * Update the Digest authentication string...
+ */
+
+ _httpSetDigestAuthString(http, http->nextnonce, "PUT", resource);
+ }
+
+#ifdef HAVE_GSSAPI
+ if (http->authstring && !strncmp(http->authstring, "Negotiate", 9) && !new_auth)
+ {
+ /*
+ * Do not use cached Kerberos credentials since they will look like a
+ * "replay" attack...
+ */
+
+ _cupsSetNegotiateAuthString(http, "PUT", resource);
+ }
+#endif /* HAVE_GSSAPI */
+
+ httpSetField(http, HTTP_FIELD_AUTHORIZATION, http->authstring);
+
if (httpPut(http, resource))
{
if (httpReconnect2(http, 30000, NULL))
@@ -383,6 +439,8 @@ cupsPutFd(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFA
DEBUG_printf(("2cupsPutFd: status=%d", status));
+ new_auth = 0;
+
if (status == HTTP_STATUS_UNAUTHORIZED)
{
/*
@@ -395,6 +453,8 @@ cupsPutFd(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFA
* See if we can do authentication...
*/
+ new_auth = 1;
+
if (cupsDoAuthentication(http, "PUT", resource))
{
status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED;
diff --git a/cups/globals.c b/cups/globals.c
index 8a05c3eb..28c993be 100644
--- a/cups/globals.c
+++ b/cups/globals.c
@@ -34,23 +34,23 @@ static _cups_threadkey_t cups_globals_key = _CUPS_THREADKEY_INITIALIZER;
static pthread_once_t cups_globals_key_once = PTHREAD_ONCE_INIT;
/* One-time initialization object */
#endif /* HAVE_PTHREAD_H */
-#if defined(HAVE_PTHREAD_H) || defined(WIN32)
+#if defined(HAVE_PTHREAD_H) || defined(_WIN32)
static _cups_mutex_t cups_global_mutex = _CUPS_MUTEX_INITIALIZER;
/* Global critical section */
-#endif /* HAVE_PTHREAD_H || WIN32 */
+#endif /* HAVE_PTHREAD_H || _WIN32 */
/*
* Local functions...
*/
-#ifdef WIN32
+#ifdef _WIN32
static void cups_fix_path(char *path);
-#endif /* WIN32 */
+#endif /* _WIN32 */
static _cups_globals_t *cups_globals_alloc(void);
-#if defined(HAVE_PTHREAD_H) || defined(WIN32)
+#if defined(HAVE_PTHREAD_H) || defined(_WIN32)
static void cups_globals_free(_cups_globals_t *g);
-#endif /* HAVE_PTHREAD_H || WIN32 */
+#endif /* HAVE_PTHREAD_H || _WIN32 */
#ifdef HAVE_PTHREAD_H
static void cups_globals_init(void);
#endif /* HAVE_PTHREAD_H */
@@ -65,7 +65,7 @@ _cupsGlobalLock(void)
{
#ifdef HAVE_PTHREAD_H
pthread_mutex_lock(&cups_global_mutex);
-#elif defined(WIN32)
+#elif defined(_WIN32)
EnterCriticalSection(&cups_global_mutex.m_criticalSection);
#endif /* HAVE_PTHREAD_H */
}
@@ -120,13 +120,13 @@ _cupsGlobalUnlock(void)
{
#ifdef HAVE_PTHREAD_H
pthread_mutex_unlock(&cups_global_mutex);
-#elif defined(WIN32)
+#elif defined(_WIN32)
LeaveCriticalSection(&cups_global_mutex.m_criticalSection);
#endif /* HAVE_PTHREAD_H */
}
-#ifdef WIN32
+#ifdef _WIN32
/*
* 'DllMain()' - Main entry for library.
*/
@@ -170,7 +170,7 @@ DllMain(HINSTANCE hinst, /* I - DLL module handle */
return (TRUE);
}
-#endif /* WIN32 */
+#endif /* _WIN32 */
/*
@@ -182,13 +182,13 @@ cups_globals_alloc(void)
{
_cups_globals_t *cg = malloc(sizeof(_cups_globals_t));
/* Pointer to global data */
-#ifdef WIN32
+#ifdef _WIN32
HKEY key; /* Registry key */
DWORD size; /* Size of string */
static char installdir[1024] = "", /* Install directory */
confdir[1024] = "", /* Server root directory */
localedir[1024] = ""; /* Locale directory */
-#endif /* WIN32 */
+#endif /* _WIN32 */
if (!cg)
@@ -219,7 +219,7 @@ cups_globals_alloc(void)
* Then set directories as appropriate...
*/
-#ifdef WIN32
+#ifdef _WIN32
if (!installdir[0])
{
/*
@@ -315,7 +315,7 @@ cups_globals_alloc(void)
if ((cg->localedir = getenv("LOCALEDIR")) == NULL)
cg->localedir = CUPS_LOCALEDIR;
}
-#endif /* WIN32 */
+#endif /* _WIN32 */
return (cg);
}
@@ -325,7 +325,7 @@ cups_globals_alloc(void)
* 'cups_globals_free()' - Free global data.
*/
-#if defined(HAVE_PTHREAD_H) || defined(WIN32)
+#if defined(HAVE_PTHREAD_H) || defined(_WIN32)
static void
cups_globals_free(_cups_globals_t *cg) /* I - Pointer to global data */
{
@@ -360,7 +360,7 @@ cups_globals_free(_cups_globals_t *cg) /* I - Pointer to global data */
free(cg);
}
-#endif /* HAVE_PTHREAD_H || WIN32 */
+#endif /* HAVE_PTHREAD_H || _WIN32 */
#ifdef HAVE_PTHREAD_H
diff --git a/cups/hash.c b/cups/hash.c
index ede54616..50dc5fb3 100644
--- a/cups/hash.c
+++ b/cups/hash.c
@@ -1,7 +1,7 @@
/*
* Hashing function for CUPS.
*
- * Copyright 2015-2016 by Apple Inc.
+ * Copyright © 2015-2018 by Apple Inc.
*
* These coded instructions, statements, and computer programs are the
* property of Apple Inc. and are protected by Federal copyright
@@ -21,6 +21,8 @@
# include <CommonCrypto/CommonDigest.h>
#elif defined(HAVE_GNUTLS)
# include <gnutls/crypto.h>
+#else
+# include "md5-private.h"
#endif /* __APPLE__ */
@@ -53,7 +55,24 @@ cupsHashData(const char *algorithm, /* I - Algorithm name */
}
#ifdef __APPLE__
- if (!strcmp(algorithm, "sha"))
+ if (!strcmp(algorithm, "md5"))
+ {
+ /*
+ * MD5 (deprecated but widely used...)
+ */
+
+ CC_MD5_CTX ctx; /* MD5 context */
+
+ if (hashsize < CC_MD5_DIGEST_LENGTH)
+ goto too_small;
+
+ CC_MD5_Init(&ctx);
+ CC_MD5_Update(&ctx, data, (CC_LONG)datalen);
+ CC_MD5_Final(hash, &ctx);
+
+ return (CC_MD5_DIGEST_LENGTH);
+ }
+ else if (!strcmp(algorithm, "sha"))
{
/*
* SHA-1...
@@ -171,7 +190,9 @@ cupsHashData(const char *algorithm, /* I - Algorithm name */
unsigned char temp[64]; /* Temporary hash buffer */
size_t tempsize = 0; /* Truncate to this size? */
- if (!strcmp(algorithm, "sha"))
+ if (!strcmp(algorithm, "md5"))
+ alg = GNUTLS_DIG_MD5;
+ else if (!strcmp(algorithm, "sha"))
alg = GNUTLS_DIG_SHA1;
else if (!strcmp(algorithm, "sha2-224"))
alg = GNUTLS_DIG_SHA224;
@@ -219,10 +240,20 @@ cupsHashData(const char *algorithm, /* I - Algorithm name */
#else
/*
- * No hash support without CommonCrypto or GNU TLS...
+ * No hash support beyond MD5 without CommonCrypto or GNU TLS...
*/
- if (hashsize < 64)
+ if (!strcmp(algorithm, "md5"))
+ {
+ _cups_md5_state_t state; /* MD5 state info */
+
+ _cupsMD5Init(&state);
+ _cupsMD5Append(&state, data, datalen);
+ _cupsMD5Finish(&state, hash);
+
+ return (16);
+ }
+ else if (hashsize < 64)
goto too_small;
#endif /* __APPLE__ */
@@ -243,3 +274,53 @@ cupsHashData(const char *algorithm, /* I - Algorithm name */
_cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Hash buffer too small."), 1);
return (-1);
}
+
+
+/*
+ * 'cupsHashString()' - Format a hash value as a hexadecimal string.
+ *
+ * The passed buffer must be at least 2 * hashsize + 1 characters in length.
+ *
+ * @since CUPS 2.2.7@
+ */
+
+const char * /* O - Formatted string */
+cupsHashString(
+ const unsigned char *hash, /* I - Hash */
+ size_t hashsize, /* I - Size of hash */
+ char *buffer, /* I - String buffer */
+ size_t bufsize) /* I - Size of string buffer */
+{
+ char *bufptr = buffer; /* Pointer into buffer */
+ static const char *hex = "0123456789abcdef";
+ /* Hex characters (lowercase!) */
+
+
+ /*
+ * Range check input...
+ */
+
+ if (!hash || hashsize < 1 || !buffer || bufsize < (2 * hashsize + 1))
+ {
+ if (buffer)
+ *buffer = '\0';
+ return (NULL);
+ }
+
+ /*
+ * Loop until we've converted the whole hash...
+ */
+
+ while (hashsize > 0)
+ {
+ *bufptr++ = hex[*hash >> 4];
+ *bufptr++ = hex[*hash & 15];
+
+ hash ++;
+ hashsize --;
+ }
+
+ *bufptr = '\0';
+
+ return (buffer);
+}
diff --git a/cups/http-addr.c b/cups/http-addr.c
index 61c86384..f8b8131c 100644
--- a/cups/http-addr.c
+++ b/cups/http-addr.c
@@ -69,11 +69,11 @@ int /* O - 0 on success, -1 on failure */
httpAddrClose(http_addr_t *addr, /* I - Listen address or @code NULL@ */
int fd) /* I - Socket file descriptor */
{
-#ifdef WIN32
+#ifdef _WIN32
if (closesocket(fd))
#else
if (close(fd))
-#endif /* WIN32 */
+#endif /* _WIN32 */
return (-1);
#ifdef AF_LOCAL
@@ -258,9 +258,9 @@ httpAddrListen(http_addr_t *addr, /* I - Address to bind to */
* Close on exec...
*/
-#ifndef WIN32
+#ifndef _WIN32
fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
-#endif /* !WIN32 */
+#endif /* !_WIN32 */
#ifdef SO_NOSIGPIPE
/*
diff --git a/cups/http-addrlist.c b/cups/http-addrlist.c
index e5fc940e..d9a96c4e 100644
--- a/cups/http-addrlist.c
+++ b/cups/http-addrlist.c
@@ -1,7 +1,7 @@
/*
* HTTP address list routines for CUPS.
*
- * Copyright 2007-2017 by Apple Inc.
+ * Copyright 2007-2018 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
@@ -24,9 +24,9 @@
#ifdef HAVE_POLL
# include <poll.h>
#endif /* HAVE_POLL */
-#ifndef WIN32
+#ifndef _WIN32
# include <fcntl.h>
-#endif /* WIN32 */
+#endif /* _WIN32 */
/*
@@ -61,14 +61,14 @@ httpAddrConnect2(
int *cancel) /* I - Pointer to "cancel" variable */
{
int val; /* Socket option value */
-#ifndef WIN32
- int flags; /* Socket flags */
-#endif /* !WIN32 */
- int remaining; /* Remaining timeout */
+#ifndef _WIN32
int i, j, /* Looping vars */
- nfds, /* Number of file descriptors */
- fds[100], /* Socket file descriptors */
+ flags, /* Socket flags */
result; /* Result from select() or poll() */
+#endif /* !_WIN32 */
+ int remaining; /* Remaining timeout */
+ int nfds, /* Number of file descriptors */
+ fds[100]; /* Socket file descriptors */
http_addrlist_t *addrs[100]; /* Addresses */
#ifndef HAVE_POLL
int max_fd = -1; /* Highest file descriptor */
@@ -84,8 +84,10 @@ httpAddrConnect2(
# endif /* HAVE_POLL */
#endif /* O_NONBLOCK */
#ifdef DEBUG
+# ifndef _WIN32
socklen_t len; /* Length of value */
http_addr_t peer; /* Peer address */
+# endif /* !_WIN32 */
char temp[256]; /* Temporary address string */
#endif /* DEBUG */
@@ -213,11 +215,11 @@ httpAddrConnect2(
return (addrlist);
}
-#ifdef WIN32
+#ifdef _WIN32
if (WSAGetLastError() != WSAEINPROGRESS && WSAGetLastError() != WSAEWOULDBLOCK)
#else
if (errno != EINPROGRESS && errno != EWOULDBLOCK)
-#endif /* WIN32 */
+#endif /* _WIN32 */
{
DEBUG_printf(("1httpAddrConnect2: Unable to connect to %s:%d: %s", httpAddrString(&(addrlist->addr), temp, sizeof(temp)), httpAddrPort(&(addrlist->addr)), strerror(errno)));
httpAddrClose(NULL, fds[nfds]);
@@ -225,9 +227,9 @@ httpAddrConnect2(
continue;
}
-#ifndef WIN32
+#ifndef _WIN32
fcntl(fds[nfds], F_SETFL, flags);
-#endif /* !WIN32 */
+#endif /* !_WIN32 */
#ifndef HAVE_POLL
if (fds[nfds] > max_fd)
@@ -296,11 +298,11 @@ httpAddrConnect2(
DEBUG_printf(("1httpAddrConnect2: select() returned %d (%d)", result, errno));
# endif /* HAVE_POLL */
}
-# ifdef WIN32
+# ifdef _WIN32
while (result < 0 && (WSAGetLastError() == WSAEINTR || WSAGetLastError() == WSAEWOULDBLOCK));
# else
while (result < 0 && (errno == EINTR || errno == EAGAIN));
-# endif /* WIN32 */
+# endif /* _WIN32 */
if (result > 0)
{
@@ -377,11 +379,11 @@ httpAddrConnect2(
httpAddrClose(NULL, fds[nfds]);
}
-#ifdef WIN32
+#ifdef _WIN32
_cupsSetError(IPP_STATUS_ERROR_SERVICE_UNAVAILABLE, "Connection failed", 0);
#else
_cupsSetError(IPP_STATUS_ERROR_SERVICE_UNAVAILABLE, strerror(errno), 0);
-#endif /* WIN32 */
+#endif /* _WIN32 */
return (NULL);
}
@@ -618,6 +620,7 @@ httpAddrGetList(const char *hostname, /* I - Hostname, IP address, or NULL for p
if (!temp)
{
httpAddrFreeList(first);
+ freeaddrinfo(results);
_cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
return (NULL);
}
@@ -848,11 +851,11 @@ httpAddrGetList(const char *hostname, /* I - Hostname, IP address, or NULL for p
temp->addr.ipv6.sin6_family = AF_INET6;
temp->addr.ipv6.sin6_port = htons(portnum);
-# ifdef WIN32
+# ifdef _WIN32
temp->addr.ipv6.sin6_addr.u.Byte[15] = 1;
# else
temp->addr.ipv6.sin6_addr.s6_addr32[3] = htonl(1);
-# endif /* WIN32 */
+# endif /* _WIN32 */
if (!first)
first = temp;
diff --git a/cups/http-private.h b/cups/http-private.h
index f71e564b..32cb9ea5 100644
--- a/cups/http-private.h
+++ b/cups/http-private.h
@@ -1,7 +1,7 @@
/*
* Private HTTP definitions for CUPS.
*
- * Copyright 2007-2017 by Apple Inc.
+ * Copyright 2007-2018 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
@@ -30,7 +30,7 @@
# endif /* __sun */
# include <limits.h>
-# ifdef WIN32
+# ifdef _WIN32
# include <io.h>
# include <winsock2.h>
# define CUPS_SOCAST (const char *)
@@ -39,7 +39,7 @@
# include <fcntl.h>
# include <sys/socket.h>
# define CUPS_SOCAST
-# endif /* WIN32 */
+# endif /* _WIN32 */
# ifdef HAVE_GSSAPI
# ifdef HAVE_GSS_GSSAPI_H
@@ -68,7 +68,6 @@ typedef int socklen_t;
# endif /* __APPLE__ && !_SOCKLEN_T */
# include <cups/http.h>
-# include "md5-private.h"
# include "ipp-private.h"
# ifdef HAVE_GNUTLS
@@ -141,7 +140,7 @@ extern SecIdentityRef SecIdentityCreate(CFAllocatorRef allocator, SecCertificate
# include <sspi.h>
# endif /* HAVE_GNUTLS */
-# ifndef WIN32
+# ifndef _WIN32
# include <net/if.h>
# include <resolv.h>
# ifdef HAVE_GETIFADDRS
@@ -152,11 +151,7 @@ extern SecIdentityRef SecIdentityCreate(CFAllocatorRef allocator, SecCertificate
# include <sys/sockio.h>
# endif /* HAVE_SYS_SOCKIO_H */
# endif /* HAVE_GETIFADDRS */
-# endif /* !WIN32 */
-
-# ifdef HAVE_LIBZ
-# include <zlib.h>
-# endif /* HAVE_LIBZ */
+# endif /* !_WIN32 */
/*
@@ -180,13 +175,17 @@ extern "C" {
# define _HTTP_TLS_NONE 0 /* No TLS options */
# define _HTTP_TLS_ALLOW_RC4 1 /* Allow RC4 cipher suites */
-# define _HTTP_TLS_ALLOW_SSL3 2 /* Allow SSL 3.0 */
-# define _HTTP_TLS_ALLOW_DH 4 /* Allow DH/DHE key negotiation */
-# define _HTTP_TLS_DENY_TLS10 16 /* Deny TLS 1.0 */
-# define _HTTP_TLS_DENY_CBC 32 /* Deny CBC cipher suites */
-# define _HTTP_TLS_ONLY_TLS10 64 /* Only use TLS 1.0 */
+# define _HTTP_TLS_ALLOW_DH 2 /* Allow DH/DHE key negotiation */
+# define _HTTP_TLS_DENY_CBC 4 /* Deny CBC cipher suites */
# define _HTTP_TLS_SET_DEFAULT 128 /* Setting the default TLS options */
+# define _HTTP_TLS_SSL3 0 /* Min/max version is SSL/3.0 */
+# define _HTTP_TLS_1_0 1 /* Min/max version is TLS/1.0 */
+# define _HTTP_TLS_1_1 2 /* Min/max version is TLS/1.1 */
+# define _HTTP_TLS_1_2 3 /* Min/max version is TLS/1.2 */
+# define _HTTP_TLS_1_3 4 /* Min/max version is TLS/1.3 */
+# define _HTTP_TLS_MAX 5 /* Highest known TLS version */
+
/*
* Types and functions for SSL support...
@@ -297,10 +296,10 @@ struct _http_s /**** HTTP connection structure ****/
char buffer[HTTP_MAX_BUFFER];
/* Buffer for incoming data */
int _auth_type; /* Authentication in use (deprecated) */
- _cups_md5_state_t md5_state; /* MD5 state */
+ unsigned char _md5_state[88]; /* MD5 state (deprecated) */
char nonce[HTTP_MAX_VALUE];
/* Nonce value */
- int nonce_count; /* Nonce count */
+ unsigned nonce_count; /* Nonce count */
http_tls_t tls; /* TLS state information */
http_encryption_t encryption; /* Encryption requirements */
@@ -361,9 +360,20 @@ struct _http_s /**** HTTP connection structure ****/
/* Default field values */
# ifdef HAVE_LIBZ
_http_coding_t coding; /* _HTTP_CODING_xxx */
- z_stream stream; /* (De)compression stream */
- Bytef *sbuffer; /* (De)compression buffer */
+ void *stream; /* (De)compression stream */
+ unsigned char *sbuffer; /* (De)compression buffer */
# endif /* HAVE_LIBZ */
+
+ /**** New in CUPS 2.2.9 ****/
+ char *authentication_info,
+ /* Authentication-Info header */
+ algorithm[65], /* Algorithm from WWW-Authenticate */
+ nextnonce[HTTP_MAX_VALUE],
+ /* Next nonce value from Authentication-Info */
+ opaque[HTTP_MAX_VALUE],
+ /* Opaque value from WWW-Authenticate */
+ realm[HTTP_MAX_VALUE];
+ /* Realm from WWW-Authenticate */
};
# endif /* !_HTTP_NO_PRIVATE */
@@ -382,7 +392,7 @@ extern const char *_cups_hstrerror(int error);
* Some OS's don't have getifaddrs() and freeifaddrs()...
*/
-# if !defined(WIN32) && !defined(HAVE_GETIFADDRS)
+# if !defined(_WIN32) && !defined(HAVE_GETIFADDRS)
# ifdef ifa_dstaddr
# undef ifa_dstaddr
# endif /* ifa_dstaddr */
@@ -417,7 +427,7 @@ extern int _cups_getifaddrs(struct ifaddrs **addrs);
# define getifaddrs _cups_getifaddrs
extern void _cups_freeifaddrs(struct ifaddrs *addrs);
# define freeifaddrs _cups_freeifaddrs
-# endif /* !WIN32 && !HAVE_GETIFADDRS */
+# endif /* !_WIN32 && !HAVE_GETIFADDRS */
/*
@@ -437,12 +447,13 @@ extern const char *_httpResolveURI(const char *uri, char *resolved_uri,
size_t resolved_size, int options,
int (*cb)(void *context),
void *context);
+extern int _httpSetDigestAuthString(http_t *http, const char *nonce, const char *method, const char *resource);
extern const char *_httpStatus(cups_lang_t *lang, http_status_t status);
extern void _httpTLSInitialize(void);
extern size_t _httpTLSPending(http_t *http);
extern int _httpTLSRead(http_t *http, char *buf, int len);
extern int _httpTLSSetCredentials(http_t *http);
-extern void _httpTLSSetOptions(int options);
+extern void _httpTLSSetOptions(int options, int min_version, int max_version);
extern int _httpTLSStart(http_t *http);
extern void _httpTLSStop(http_t *http);
extern int _httpTLSWrite(http_t *http, const char *buf, int len);
diff --git a/cups/http-support.c b/cups/http-support.c
index 76dbb7db..767fbf68 100644
--- a/cups/http-support.c
+++ b/cups/http-support.c
@@ -1,7 +1,7 @@
/*
* HTTP support routines for CUPS.
*
- * Copyright 2007-2017 by Apple Inc.
+ * Copyright 2007-2018 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
@@ -20,13 +20,13 @@
#include "cups-private.h"
#ifdef HAVE_DNSSD
# include <dns_sd.h>
-# ifdef WIN32
+# ifdef _WIN32
# include <io.h>
# elif defined(HAVE_POLL)
# include <poll.h>
# else
# include <sys/select.h>
-# endif /* WIN32 */
+# endif /* _WIN32 */
#elif defined(HAVE_AVAHI)
# include <avahi-client/client.h>
# include <avahi-client/lookup.h>
@@ -502,7 +502,6 @@ httpAssembleUUID(const char *server, /* I - Server name */
size_t bufsize) /* I - Size of buffer */
{
char data[1024]; /* Source string for MD5 */
- _cups_md5_state_t md5state; /* MD5 state */
unsigned char md5sum[16]; /* MD5 digest/sum */
@@ -517,9 +516,7 @@ httpAssembleUUID(const char *server, /* I - Server name */
port, name ? name : server, number,
(unsigned)CUPS_RAND() & 0xffff, (unsigned)CUPS_RAND() & 0xffff);
- _cupsMD5Init(&md5state);
- _cupsMD5Append(&md5state, (unsigned char *)data, (int)strlen(data));
- _cupsMD5Finish(&md5state, md5sum);
+ cupsHashData("md5", (unsigned char *)data, strlen(data), md5sum, sizeof(md5sum));
/*
* Generate the UUID from the MD5...
@@ -1035,7 +1032,7 @@ httpSeparateURI(
*ptr = '\0';
- if (*uri != ':')
+ if (*uri != ':' || *scheme == '.' || !*scheme)
{
*scheme = '\0';
return (HTTP_URI_STATUS_BAD_SCHEME);
@@ -1306,6 +1303,152 @@ httpSeparateURI(
/*
+ * '_httpSetDigestAuthString()' - Calculate a Digest authentication response
+ * using the appropriate RFC 2068/2617/7616
+ * algorithm.
+ */
+
+int /* O - 1 on success, 0 on failure */
+_httpSetDigestAuthString(
+ http_t *http, /* I - HTTP connection */
+ const char *nonce, /* I - Nonce value */
+ const char *method, /* I - HTTP method */
+ const char *resource) /* I - HTTP resource path */
+{
+ char kd[65], /* Final MD5/SHA-256 digest */
+ ha1[65], /* Hash of username:realm:password */
+ ha2[65], /* Hash of method:request-uri */
+ username[HTTP_MAX_VALUE],
+ /* username:password */
+ *password, /* Pointer to password */
+ temp[1024], /* Temporary string */
+ digest[1024]; /* Digest auth data */
+ unsigned char hash[32]; /* Hash buffer */
+ size_t hashsize; /* Size of hash */
+
+
+ DEBUG_printf(("2_httpSetDigestAuthString(http=%p, nonce=\"%s\", method=\"%s\", resource=\"%s\")", http, nonce, method, resource));
+
+ if (nonce && *nonce && strcmp(nonce, http->nonce))
+ {
+ strlcpy(http->nonce, nonce, sizeof(http->nonce));
+
+ if (nonce == http->nextnonce)
+ http->nextnonce[0] = '\0';
+
+ http->nonce_count = 1;
+ }
+ else
+ http->nonce_count ++;
+
+ strlcpy(username, http->userpass, sizeof(username));
+ if ((password = strchr(username, ':')) != NULL)
+ *password++ = '\0';
+ else
+ return (0);
+
+ if (http->algorithm[0])
+ {
+ /*
+ * Follow RFC 2617/7616...
+ */
+
+ int i; /* Looping var */
+ char cnonce[65]; /* cnonce value */
+ const char *hashalg; /* Hashing algorithm */
+
+ for (i = 0; i < 64; i ++)
+ cnonce[i] = "0123456789ABCDEF"[CUPS_RAND() & 15];
+ cnonce[64] = '\0';
+
+ if (!_cups_strcasecmp(http->algorithm, "MD5"))
+ {
+ /*
+ * RFC 2617 Digest with MD5
+ */
+
+ hashalg = "md5";
+ }
+ else if (!_cups_strcasecmp(http->algorithm, "SHA-256"))
+ {
+ /*
+ * RFC 7616 Digest with SHA-256
+ */
+
+ hashalg = "sha2-256";
+ }
+ else
+ {
+ /*
+ * Some other algorithm we don't support, skip this one...
+ */
+
+ return (0);
+ }
+
+ /*
+ * Calculate digest value...
+ */
+
+ /* H(A1) = H(username:realm:password) */
+ snprintf(temp, sizeof(temp), "%s:%s:%s", username, http->realm, password);
+ hashsize = (size_t)cupsHashData(hashalg, (unsigned char *)temp, strlen(temp), hash, sizeof(hash));
+ cupsHashString(hash, hashsize, ha1, sizeof(ha1));
+
+ /* H(A2) = H(method:uri) */
+ snprintf(temp, sizeof(temp), "%s:%s", method, resource);
+ hashsize = (size_t)cupsHashData(hashalg, (unsigned char *)temp, strlen(temp), hash, sizeof(hash));
+ cupsHashString(hash, hashsize, ha2, sizeof(ha2));
+
+ /* KD = H(H(A1):nonce:nc:cnonce:qop:H(A2)) */
+ snprintf(temp, sizeof(temp), "%s:%s:%08x:%s:%s:%s", ha1, http->nonce, http->nonce_count, cnonce, "auth", ha2);
+ hashsize = (size_t)cupsHashData(hashalg, (unsigned char *)temp, strlen(temp), hash, sizeof(hash));
+ cupsHashString(hash, hashsize, kd, sizeof(kd));
+
+ /*
+ * Pass the RFC 2617/7616 WWW-Authenticate header...
+ */
+
+ if (http->opaque[0])
+ snprintf(digest, sizeof(digest), "username=\"%s\", realm=\"%s\", nonce=\"%s\", algorithm=%s, qop=auth, opaque=\"%s\", cnonce=\"%s\", nc=%08x, uri=\"%s\", response=\"%s\"", cupsUser(), http->realm, http->nonce, http->algorithm, http->opaque, cnonce, http->nonce_count, resource, kd);
+ else
+ snprintf(digest, sizeof(digest), "username=\"%s\", realm=\"%s\", nonce=\"%s\", algorithm=%s, qop=auth, cnonce=\"%s\", nc=%08x, uri=\"%s\", response=\"%s\"", username, http->realm, http->nonce, http->algorithm, cnonce, http->nonce_count, resource, kd);
+ }
+ else
+ {
+ /*
+ * Use old RFC 2069 Digest method...
+ */
+
+ /* H(A1) = H(username:realm:password) */
+ snprintf(temp, sizeof(temp), "%s:%s:%s", username, http->realm, password);
+ hashsize = (size_t)cupsHashData("md5", (unsigned char *)temp, strlen(temp), hash, sizeof(hash));
+ cupsHashString(hash, hashsize, ha1, sizeof(ha1));
+
+ /* H(A2) = H(method:uri) */
+ snprintf(temp, sizeof(temp), "%s:%s", method, resource);
+ hashsize = (size_t)cupsHashData("md5", (unsigned char *)temp, strlen(temp), hash, sizeof(hash));
+ cupsHashString(hash, hashsize, ha2, sizeof(ha2));
+
+ /* KD = H(H(A1):nonce:H(A2)) */
+ snprintf(temp, sizeof(temp), "%s:%s:%s", ha1, http->nonce, ha2);
+ hashsize = (size_t)cupsHashData("md5", (unsigned char *)temp, strlen(temp), hash, sizeof(hash));
+ cupsHashString(hash, hashsize, kd, sizeof(kd));
+
+ /*
+ * Pass the old RFC 2069 WWW-Authenticate header...
+ */
+
+ snprintf(digest, sizeof(digest), "username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", response=\"%s\"", username, http->realm, http->nonce, resource, kd);
+ }
+
+ httpSetAuthString(http, "Digest", digest);
+
+ return (1);
+}
+
+
+/*
* 'httpStateString()' - Return the string describing a HTTP state value.
*
* @since CUPS 2.0/OS 10.10@
@@ -1360,6 +1503,9 @@ _httpStatus(cups_lang_t *lang, /* I - Language */
case HTTP_STATUS_MOVED_PERMANENTLY :
s = _("Moved Permanently");
break;
+ case HTTP_STATUS_FOUND :
+ s = _("Found");
+ break;
case HTTP_STATUS_SEE_OTHER :
s = _("See Other");
break;
@@ -1622,9 +1768,6 @@ _httpResolveURI(
_http_uribuf_t uribuf; /* URI buffer */
int offline = 0; /* offline-report state set? */
# ifdef HAVE_DNSSD
-# ifdef WIN32
-# pragma comment(lib, "dnssd.lib")
-# endif /* WIN32 */
DNSServiceRef ref, /* DNS-SD master service reference */
domainref = NULL,/* DNS-SD service reference for domain */
ippref = NULL, /* DNS-SD service reference for network IPP */
@@ -1753,11 +1896,11 @@ _httpResolveURI(
FD_ZERO(&input_set);
FD_SET(DNSServiceRefSockFD(ref), &input_set);
-# ifdef WIN32
+# ifdef _WIN32
stimeout.tv_sec = (long)timeout;
# else
stimeout.tv_sec = timeout;
-# endif /* WIN32 */
+# endif /* _WIN32 */
stimeout.tv_usec = 0;
fds = select(DNSServiceRefSockFD(ref)+1, &input_set, NULL, NULL,
diff --git a/cups/http.c b/cups/http.c
index 61b88c9d..5c14ef68 100644
--- a/cups/http.c
+++ b/cups/http.c
@@ -1,7 +1,7 @@
/*
* HTTP routines for CUPS.
*
- * Copyright 2007-2017 by Apple Inc.
+ * Copyright 2007-2018 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* This file contains Kerberos support code, copyright 2006 by
@@ -23,22 +23,26 @@
#include "cups-private.h"
#include <fcntl.h>
#include <math.h>
-#ifdef WIN32
+#ifdef _WIN32
# include <tchar.h>
#else
# include <signal.h>
# include <sys/time.h>
# include <sys/resource.h>
-#endif /* WIN32 */
+#endif /* _WIN32 */
#ifdef HAVE_POLL
# include <poll.h>
#endif /* HAVE_POLL */
+# ifdef HAVE_LIBZ
+# include <zlib.h>
+# endif /* HAVE_LIBZ */
/*
* Local functions...
*/
+static void http_add_field(http_t *http, http_field_t field, const char *value, int append);
#ifdef HAVE_LIBZ
static void http_content_coding_finish(http_t *http);
static void http_content_coding_start(http_t *http,
@@ -105,7 +109,8 @@ static const char * const http_fields[] =
"WWW-Authenticate",
"Accept-Encoding",
"Allow",
- "Server"
+ "Server",
+ "Authentication-Info"
};
@@ -325,6 +330,12 @@ httpClearFields(http_t *http) /* I - HTTP connection */
http->server = NULL;
}
+ if (http->authentication_info)
+ {
+ _cupsStrFree(http->authentication_info);
+ http->authentication_info = NULL;
+ }
+
http->expect = (http_status_t)0;
}
}
@@ -969,11 +980,14 @@ httpGetField(http_t *http, /* I - HTTP connection */
case HTTP_FIELD_SERVER :
return (http->server);
+ case HTTP_FIELD_AUTHENTICATION_INFO :
+ return (http->authentication_info);
+
case HTTP_FIELD_AUTHORIZATION :
if (http->field_authorization)
{
/*
- * Special case for WWW-Authenticate: as its contents can be
+ * Special case for Authorization: as its contents can be
* longer than HTTP_MAX_VALUE...
*/
@@ -1183,11 +1197,11 @@ httpGets(char *line, /* I - Line to read into */
* Pre-load the buffer as needed...
*/
-#ifdef WIN32
+#ifdef _WIN32
WSASetLastError(0);
#else
errno = 0;
-#endif /* WIN32 */
+#endif /* _WIN32 */
while (http->used == 0)
{
@@ -1201,11 +1215,11 @@ httpGets(char *line, /* I - Line to read into */
continue;
DEBUG_puts("3httpGets: Timed out!");
-#ifdef WIN32
+#ifdef _WIN32
http->error = WSAETIMEDOUT;
#else
http->error = ETIMEDOUT;
-#endif /* WIN32 */
+#endif /* _WIN32 */
return (NULL);
}
@@ -1219,7 +1233,7 @@ httpGets(char *line, /* I - Line to read into */
* Nope, can't get a line this time...
*/
-#ifdef WIN32
+#ifdef _WIN32
DEBUG_printf(("3httpGets: recv() error %d!", WSAGetLastError()));
if (WSAGetLastError() == WSAEINTR)
@@ -1256,7 +1270,7 @@ httpGets(char *line, /* I - Line to read into */
http->error = errno;
continue;
}
-#endif /* WIN32 */
+#endif /* _WIN32 */
return (NULL);
}
@@ -1523,9 +1537,9 @@ void
httpInitialize(void)
{
static int initialized = 0; /* Have we been called before? */
-#ifdef WIN32
+#ifdef _WIN32
WSADATA winsockdata; /* WinSock data */
-#endif /* WIN32 */
+#endif /* _WIN32 */
_cupsGlobalLock();
@@ -1535,7 +1549,7 @@ httpInitialize(void)
return;
}
-#ifdef WIN32
+#ifdef _WIN32
WSAStartup(MAKEWORD(2,2), &winsockdata);
#elif !defined(SO_NOSIGPIPE)
@@ -1557,7 +1571,7 @@ httpInitialize(void)
# else
signal(SIGPIPE, SIG_IGN);
# endif /* !SO_NOSIGPIPE */
-#endif /* WIN32 */
+#endif /* _WIN32 */
# ifdef HAVE_SSL
_httpTLSInitialize();
@@ -1713,7 +1727,7 @@ httpPeek(http_t *http, /* I - HTTP connection */
#ifdef HAVE_LIBZ
if (http->used == 0 &&
(http->coding == _HTTP_CODING_IDENTITY ||
- (http->coding >= _HTTP_CODING_GUNZIP && http->stream.avail_in == 0)))
+ (http->coding >= _HTTP_CODING_GUNZIP && ((z_stream *)http->stream)->avail_in == 0)))
#else
if (http->used == 0)
#endif /* HAVE_LIBZ */
@@ -1762,16 +1776,16 @@ httpPeek(http_t *http, /* I - HTTP connection */
int zerr; /* Decompressor error */
z_stream stream; /* Copy of decompressor stream */
- if (http->used > 0 && http->stream.avail_in < HTTP_MAX_BUFFER)
+ if (http->used > 0 && ((z_stream *)http->stream)->avail_in < HTTP_MAX_BUFFER)
{
- size_t buflen = buflen = HTTP_MAX_BUFFER - http->stream.avail_in;
+ size_t buflen = buflen = HTTP_MAX_BUFFER - ((z_stream *)http->stream)->avail_in;
/* Number of bytes to copy */
- if (http->stream.avail_in > 0 &&
- http->stream.next_in > http->sbuffer)
- memmove(http->sbuffer, http->stream.next_in, http->stream.avail_in);
+ if (((z_stream *)http->stream)->avail_in > 0 &&
+ ((z_stream *)http->stream)->next_in > http->sbuffer)
+ memmove(http->sbuffer, ((z_stream *)http->stream)->next_in, ((z_stream *)http->stream)->avail_in);
- http->stream.next_in = http->sbuffer;
+ ((z_stream *)http->stream)->next_in = http->sbuffer;
if (buflen > (size_t)http->data_remaining)
buflen = (size_t)http->data_remaining;
@@ -1782,8 +1796,8 @@ httpPeek(http_t *http, /* I - HTTP connection */
DEBUG_printf(("1httpPeek: Copying %d more bytes of data into "
"decompression buffer.", (int)buflen));
- memcpy(http->sbuffer + http->stream.avail_in, http->buffer, buflen);
- http->stream.avail_in += buflen;
+ memcpy(http->sbuffer + ((z_stream *)http->stream)->avail_in, http->buffer, buflen);
+ ((z_stream *)http->stream)->avail_in += buflen;
http->used -= (int)buflen;
http->data_remaining -= (off_t)buflen;
@@ -1792,9 +1806,9 @@ httpPeek(http_t *http, /* I - HTTP connection */
}
DEBUG_printf(("2httpPeek: length=%d, avail_in=%d", (int)length,
- (int)http->stream.avail_in));
+ (int)((z_stream *)http->stream)->avail_in));
- if (inflateCopy(&stream, &(http->stream)) != Z_OK)
+ if (inflateCopy(&stream, (z_stream *)http->stream) != Z_OK)
{
DEBUG_puts("2httpPeek: Unable to copy decompressor stream.");
http->error = ENOMEM;
@@ -1811,14 +1825,14 @@ httpPeek(http_t *http, /* I - HTTP connection */
{
DEBUG_printf(("2httpPeek: zerr=%d", zerr));
#ifdef DEBUG
- http_debug_hex("2httpPeek", (char *)http->sbuffer, (int)http->stream.avail_in);
+ http_debug_hex("2httpPeek", (char *)http->sbuffer, (int)((z_stream *)http->stream)->avail_in);
#endif /* DEBUG */
http->error = EIO;
return (-1);
}
- bytes = (ssize_t)(length - http->stream.avail_out);
+ bytes = (ssize_t)(length - ((z_stream *)http->stream)->avail_out);
# else
DEBUG_puts("2httpPeek: No inflateCopy on this platform, httpPeek does not "
@@ -1845,7 +1859,7 @@ httpPeek(http_t *http, /* I - HTTP connection */
if (bytes < 0)
{
-#ifdef WIN32
+#ifdef _WIN32
if (WSAGetLastError() == WSAEINTR || WSAGetLastError() == WSAEWOULDBLOCK)
bytes = 0;
else
@@ -1855,7 +1869,7 @@ httpPeek(http_t *http, /* I - HTTP connection */
bytes = 0;
else
http->error = errno;
-#endif /* WIN32 */
+#endif /* _WIN32 */
}
else if (bytes == 0)
{
@@ -1985,31 +1999,31 @@ httpRead2(http_t *http, /* I - HTTP connection */
{
do
{
- if (http->stream.avail_in > 0)
+ if (((z_stream *)http->stream)->avail_in > 0)
{
int zerr; /* Decompressor error */
DEBUG_printf(("2httpRead2: avail_in=%d, avail_out=%d",
- (int)http->stream.avail_in, (int)length));
+ (int)((z_stream *)http->stream)->avail_in, (int)length));
- http->stream.next_out = (Bytef *)buffer;
- http->stream.avail_out = (uInt)length;
+ ((z_stream *)http->stream)->next_out = (Bytef *)buffer;
+ ((z_stream *)http->stream)->avail_out = (uInt)length;
- if ((zerr = inflate(&(http->stream), Z_SYNC_FLUSH)) < Z_OK)
+ if ((zerr = inflate((z_stream *)http->stream, Z_SYNC_FLUSH)) < Z_OK)
{
DEBUG_printf(("2httpRead2: zerr=%d", zerr));
#ifdef DEBUG
- http_debug_hex("2httpRead2", (char *)http->sbuffer, (int)http->stream.avail_in);
+ http_debug_hex("2httpRead2", (char *)http->sbuffer, (int)((z_stream *)http->stream)->avail_in);
#endif /* DEBUG */
http->error = EIO;
return (-1);
}
- bytes = (ssize_t)(length - http->stream.avail_out);
+ bytes = (ssize_t)(length - ((z_stream *)http->stream)->avail_out);
DEBUG_printf(("2httpRead2: avail_in=%d, avail_out=%d, bytes=%d",
- http->stream.avail_in, http->stream.avail_out,
+ ((z_stream *)http->stream)->avail_in, ((z_stream *)http->stream)->avail_out,
(int)bytes));
}
else
@@ -2017,16 +2031,16 @@ httpRead2(http_t *http, /* I - HTTP connection */
if (bytes == 0)
{
- ssize_t buflen = HTTP_MAX_BUFFER - (ssize_t)http->stream.avail_in;
+ ssize_t buflen = HTTP_MAX_BUFFER - (ssize_t)((z_stream *)http->stream)->avail_in;
/* Additional bytes for buffer */
if (buflen > 0)
{
- if (http->stream.avail_in > 0 &&
- http->stream.next_in > http->sbuffer)
- memmove(http->sbuffer, http->stream.next_in, http->stream.avail_in);
+ if (((z_stream *)http->stream)->avail_in > 0 &&
+ ((z_stream *)http->stream)->next_in > http->sbuffer)
+ memmove(http->sbuffer, ((z_stream *)http->stream)->next_in, ((z_stream *)http->stream)->avail_in);
- http->stream.next_in = http->sbuffer;
+ ((z_stream *)http->stream)->next_in = http->sbuffer;
DEBUG_printf(("1httpRead2: Reading up to %d more bytes of data into "
"decompression buffer.", (int)buflen));
@@ -2036,10 +2050,10 @@ httpRead2(http_t *http, /* I - HTTP connection */
if (buflen > http->data_remaining)
buflen = (ssize_t)http->data_remaining;
- bytes = http_read_buffered(http, (char *)http->sbuffer + http->stream.avail_in, (size_t)buflen);
+ bytes = http_read_buffered(http, (char *)http->sbuffer + ((z_stream *)http->stream)->avail_in, (size_t)buflen);
}
else if (http->data_encoding == HTTP_ENCODING_CHUNKED)
- bytes = http_read_chunk(http, (char *)http->sbuffer + http->stream.avail_in, (size_t)buflen);
+ bytes = http_read_chunk(http, (char *)http->sbuffer + ((z_stream *)http->stream)->avail_in, (size_t)buflen);
else
bytes = 0;
@@ -2052,7 +2066,7 @@ httpRead2(http_t *http, /* I - HTTP connection */
"decompression buffer.", CUPS_LLCAST bytes));
http->data_remaining -= bytes;
- http->stream.avail_in += (uInt)bytes;
+ ((z_stream *)http->stream)->avail_in += (uInt)bytes;
if (http->data_remaining <= 0 &&
http->data_encoding == HTTP_ENCODING_CHUNKED)
@@ -2131,7 +2145,7 @@ httpRead2(http_t *http, /* I - HTTP connection */
if (
#ifdef HAVE_LIBZ
(http->coding == _HTTP_CODING_IDENTITY ||
- (http->coding >= _HTTP_CODING_GUNZIP && http->stream.avail_in == 0)) &&
+ (http->coding >= _HTTP_CODING_GUNZIP && ((z_stream *)http->stream)->avail_in == 0)) &&
#endif /* HAVE_LIBZ */
((http->data_remaining <= 0 &&
http->data_encoding == HTTP_ENCODING_LENGTH) ||
@@ -2416,11 +2430,11 @@ httpReconnect2(http_t *http, /* I - HTTP connection */
* Unable to connect...
*/
-#ifdef WIN32
+#ifdef _WIN32
http->error = WSAGetLastError();
#else
http->error = errno;
-#endif /* WIN32 */
+#endif /* _WIN32 */
http->status = HTTP_STATUS_ERROR;
DEBUG_printf(("1httpReconnect2: httpAddrConnect failed: %s",
@@ -2659,105 +2673,7 @@ httpSetField(http_t *http, /* I - HTTP connection */
value == NULL)
return;
- switch (field)
- {
- case HTTP_FIELD_ACCEPT_ENCODING :
- if (http->accept_encoding)
- _cupsStrFree(http->accept_encoding);
-
- http->accept_encoding = _cupsStrAlloc(value);
- break;
-
- case HTTP_FIELD_ALLOW :
- if (http->allow)
- _cupsStrFree(http->allow);
-
- http->allow = _cupsStrAlloc(value);
- break;
-
- case HTTP_FIELD_SERVER :
- if (http->server)
- _cupsStrFree(http->server);
-
- http->server = _cupsStrAlloc(value);
- break;
-
- case HTTP_FIELD_WWW_AUTHENTICATE :
- /* CUPS STR #4503 - don't override WWW-Authenticate for unknown auth schemes */
- if (http->fields[HTTP_FIELD_WWW_AUTHENTICATE][0] &&
- _cups_strncasecmp(value, "Basic ", 6) &&
- _cups_strncasecmp(value, "Digest ", 7) &&
- _cups_strncasecmp(value, "Negotiate ", 10))
- {
- DEBUG_printf(("1httpSetField: Ignoring unknown auth scheme in \"%s\".", value));
- return;
- }
-
- /* Fall through to copy */
-
- default :
- strlcpy(http->fields[field], value, HTTP_MAX_VALUE);
- break;
- }
-
- if (field == HTTP_FIELD_AUTHORIZATION)
- {
- /*
- * Special case for Authorization: as its contents can be
- * longer than HTTP_MAX_VALUE
- */
-
- if (http->field_authorization)
- free(http->field_authorization);
-
- http->field_authorization = strdup(value);
- }
- else if (field == HTTP_FIELD_HOST)
- {
- /*
- * Special-case for Host: as we don't want a trailing "." on the hostname and
- * need to bracket IPv6 numeric addresses.
- */
-
- char *ptr = strchr(value, ':');
-
- if (value[0] != '[' && ptr && strchr(ptr + 1, ':'))
- {
- /*
- * Bracket IPv6 numeric addresses...
- *
- * This is slightly inefficient (basically copying twice), but is an edge
- * case and not worth optimizing...
- */
-
- snprintf(http->fields[HTTP_FIELD_HOST],
- sizeof(http->fields[HTTP_FIELD_HOST]), "[%s]", value);
- }
- else
- {
- /*
- * Check for a trailing dot on the hostname...
- */
-
- ptr = http->fields[HTTP_FIELD_HOST];
-
- if (*ptr)
- {
- ptr += strlen(ptr) - 1;
-
- if (*ptr == '.')
- *ptr = '\0';
- }
- }
- }
-#ifdef HAVE_LIBZ
- else if (field == HTTP_FIELD_CONTENT_ENCODING &&
- http->data_encoding != HTTP_ENCODING_FIELDS)
- {
- DEBUG_puts("1httpSetField: Calling http_content_coding_start.");
- http_content_coding_start(http, value);
- }
-#endif /* HAVE_LIBZ */
+ http_add_field(http, field, value, 0);
}
@@ -2855,11 +2771,11 @@ httpShutdown(http_t *http) /* I - HTTP connection */
_httpTLSStop(http);
#endif /* HAVE_SSL */
-#ifdef WIN32
+#ifdef _WIN32
shutdown(http->fd, SD_RECEIVE); /* Microsoft-ism... */
#else
shutdown(http->fd, SHUT_RD);
-#endif /* WIN32 */
+#endif /* _WIN32 */
}
@@ -3035,7 +2951,12 @@ _httpUpdate(http_t *http, /* I - HTTP connection */
httpSetCookie(http, value);
}
else if ((field = httpFieldValue(line)) != HTTP_FIELD_UNKNOWN)
- httpSetField(http, field, value);
+ {
+ http_add_field(http, field, value, 1);
+
+ if (field == HTTP_FIELD_AUTHENTICATION_INFO)
+ httpGetSubField2(http, HTTP_FIELD_AUTHENTICATION_INFO, "nextnonce", http->nextnonce, (int)sizeof(http->nextnonce));
+ }
#ifdef DEBUG
else
DEBUG_printf(("1_httpUpdate: unknown field %s seen!", line));
@@ -3188,12 +3109,12 @@ _httpWait(http_t *http, /* I - HTTP connection */
DEBUG_printf(("6_httpWait: select() returned %d...", nfds));
}
-# ifdef WIN32
+# ifdef _WIN32
while (nfds < 0 && (WSAGetLastError() == WSAEINTR ||
WSAGetLastError() == WSAEWOULDBLOCK));
# else
while (nfds < 0 && (errno == EINTR || errno == EAGAIN));
-# endif /* WIN32 */
+# endif /* _WIN32 */
#endif /* HAVE_POLL */
DEBUG_printf(("5_httpWait: returning with nfds=%d, errno=%d...", nfds,
@@ -3229,7 +3150,7 @@ httpWait(http_t *http, /* I - HTTP connection */
}
#ifdef HAVE_LIBZ
- if (http->coding >= _HTTP_CODING_GUNZIP && http->stream.avail_in > 0)
+ if (http->coding >= _HTTP_CODING_GUNZIP && ((z_stream *)http->stream)->avail_in > 0)
{
DEBUG_puts("3httpWait: Returning 1 since there is buffered data ready.");
return (1);
@@ -3325,17 +3246,17 @@ httpWrite2(http_t *http, /* I - HTTP connection */
size_t slen; /* Bytes to write */
ssize_t sret; /* Bytes written */
- http->stream.next_in = (Bytef *)buffer;
- http->stream.avail_in = (uInt)length;
+ ((z_stream *)http->stream)->next_in = (Bytef *)buffer;
+ ((z_stream *)http->stream)->avail_in = (uInt)length;
- while (deflate(&(http->stream), Z_NO_FLUSH) == Z_OK)
+ while (deflate((z_stream *)http->stream, Z_NO_FLUSH) == Z_OK)
{
- DEBUG_printf(("1httpWrite2: avail_out=%d", http->stream.avail_out));
+ DEBUG_printf(("1httpWrite2: avail_out=%d", ((z_stream *)http->stream)->avail_out));
- if (http->stream.avail_out > 0)
+ if (((z_stream *)http->stream)->avail_out > 0)
continue;
- slen = _HTTP_MAX_SBUFFER - http->stream.avail_out;
+ slen = _HTTP_MAX_SBUFFER - ((z_stream *)http->stream)->avail_out;
DEBUG_printf(("1httpWrite2: Writing intermediate chunk, len=%d", (int)slen));
@@ -3352,8 +3273,8 @@ httpWrite2(http_t *http, /* I - HTTP connection */
return (-1);
}
- http->stream.next_out = (Bytef *)http->sbuffer;
- http->stream.avail_out = (uInt)_HTTP_MAX_SBUFFER;
+ ((z_stream *)http->stream)->next_out = (Bytef *)http->sbuffer;
+ ((z_stream *)http->stream)->avail_out = (uInt)_HTTP_MAX_SBUFFER;
}
bytes = (ssize_t)length;
@@ -3689,6 +3610,125 @@ httpWriteResponse(http_t *http, /* I - HTTP connection */
}
+/*
+ * 'http_add_field()' - Add a value for a HTTP field, appending if needed.
+ */
+
+static void
+http_add_field(http_t *http, /* I - HTTP connection */
+ http_field_t field, /* I - HTTP field */
+ const char *value, /* I - Value string */
+ int append) /* I - Append value? */
+{
+ char newvalue[1024]; /* New value string */
+ const char *oldvalue; /* Old field value */
+
+
+
+ /*
+ * Optionally append the new value to the existing one...
+ */
+
+ if (append && field != HTTP_FIELD_ACCEPT_ENCODING && field != HTTP_FIELD_ACCEPT_LANGUAGE && field != HTTP_FIELD_ACCEPT_RANGES && field != HTTP_FIELD_ALLOW && field != HTTP_FIELD_LINK && field != HTTP_FIELD_TRANSFER_ENCODING && field != HTTP_FIELD_UPGRADE && field != HTTP_FIELD_WWW_AUTHENTICATE)
+ append = 0;
+
+ if (field == HTTP_FIELD_HOST)
+ {
+ /*
+ * Special-case for Host: as we don't want a trailing "." on the hostname and
+ * need to bracket IPv6 numeric addresses.
+ */
+
+ char *ptr = strchr(value, ':');
+
+ if (value[0] != '[' && ptr && strchr(ptr + 1, ':'))
+ {
+ /*
+ * Bracket IPv6 numeric addresses...
+ */
+
+ snprintf(newvalue, sizeof(newvalue), "[%s]", value);
+ value = newvalue;
+ }
+ else if (*value && value[strlen(value) - 1] == '.')
+ {
+ /*
+ * Strip the trailing dot on the hostname...
+ */
+
+ strlcpy(newvalue, value, sizeof(newvalue));
+ newvalue[strlen(newvalue) - 1] = '\0';
+ value = newvalue;
+ }
+ }
+ else if (append && *value && (oldvalue = httpGetField(http, field)) != NULL && *oldvalue)
+ {
+ snprintf(newvalue, sizeof(newvalue), "%s, %s", oldvalue, value);
+ value = newvalue;
+ }
+
+ /*
+ * Save the new value...
+ */
+
+ switch (field)
+ {
+ case HTTP_FIELD_ACCEPT_ENCODING :
+ if (http->accept_encoding)
+ _cupsStrFree(http->accept_encoding);
+
+ http->accept_encoding = _cupsStrAlloc(value);
+ break;
+
+ case HTTP_FIELD_ALLOW :
+ if (http->allow)
+ _cupsStrFree(http->allow);
+
+ http->allow = _cupsStrAlloc(value);
+ break;
+
+ case HTTP_FIELD_SERVER :
+ if (http->server)
+ _cupsStrFree(http->server);
+
+ http->server = _cupsStrAlloc(value);
+ break;
+
+ case HTTP_FIELD_AUTHENTICATION_INFO :
+ if (http->authentication_info)
+ _cupsStrFree(http->authentication_info);
+
+ http->authentication_info = _cupsStrAlloc(value);
+ break;
+
+ default :
+ strlcpy(http->fields[field], value, HTTP_MAX_VALUE);
+ break;
+ }
+
+ if (field == HTTP_FIELD_AUTHORIZATION)
+ {
+ /*
+ * Special case for Authorization: as its contents can be
+ * longer than HTTP_MAX_VALUE
+ */
+
+ if (http->field_authorization)
+ free(http->field_authorization);
+
+ http->field_authorization = strdup(value);
+ }
+#ifdef HAVE_LIBZ
+ else if (field == HTTP_FIELD_CONTENT_ENCODING &&
+ http->data_encoding != HTTP_ENCODING_FIELDS)
+ {
+ DEBUG_puts("1http_add_field: Calling http_content_coding_start.");
+ http_content_coding_start(http, value);
+ }
+#endif /* HAVE_LIBZ */
+}
+
+
#ifdef HAVE_LIBZ
/*
* 'http_content_coding_finish()' - Finish doing any content encoding.
@@ -3710,13 +3750,13 @@ http_content_coding_finish(
{
case _HTTP_CODING_DEFLATE :
case _HTTP_CODING_GZIP :
- http->stream.next_in = dummy;
- http->stream.avail_in = 0;
+ ((z_stream *)http->stream)->next_in = dummy;
+ ((z_stream *)http->stream)->avail_in = 0;
do
{
- zerr = deflate(&(http->stream), Z_FINISH);
- bytes = _HTTP_MAX_SBUFFER - http->stream.avail_out;
+ zerr = deflate((z_stream *)http->stream, Z_FINISH);
+ bytes = _HTTP_MAX_SBUFFER - ((z_stream *)http->stream)->avail_out;
if (bytes > 0)
{
@@ -3728,15 +3768,18 @@ http_content_coding_finish(
http_write(http, (char *)http->sbuffer, bytes);
}
- http->stream.next_out = (Bytef *)http->sbuffer;
- http->stream.avail_out = (uInt)_HTTP_MAX_SBUFFER;
+ ((z_stream *)http->stream)->next_out = (Bytef *)http->sbuffer;
+ ((z_stream *)http->stream)->avail_out = (uInt)_HTTP_MAX_SBUFFER;
}
while (zerr == Z_OK);
- deflateEnd(&(http->stream));
+ deflateEnd((z_stream *)http->stream);
free(http->sbuffer);
+ free(http->stream);
+
http->sbuffer = NULL;
+ http->stream = NULL;
if (http->wused)
httpFlushWrite(http);
@@ -3744,9 +3787,13 @@ http_content_coding_finish(
case _HTTP_CODING_INFLATE :
case _HTTP_CODING_GUNZIP :
- inflateEnd(&(http->stream));
+ inflateEnd((z_stream *)http->stream);
+
free(http->sbuffer);
+ free(http->stream);
+
http->sbuffer = NULL;
+ http->stream = NULL;
break;
default :
@@ -3816,8 +3863,6 @@ http_content_coding_start(
return;
}
- memset(&(http->stream), 0, sizeof(http->stream));
-
switch (coding)
{
case _HTTP_CODING_DEFLATE :
@@ -3838,18 +3883,30 @@ http_content_coding_start(
* documentation.
*/
- if ((zerr = deflateInit2(&(http->stream), Z_DEFAULT_COMPRESSION,
- Z_DEFLATED,
- coding == _HTTP_CODING_DEFLATE ? -11 : 27, 7,
- Z_DEFAULT_STRATEGY)) < Z_OK)
+ if ((http->stream = calloc(1, sizeof(z_stream))) == NULL)
+ {
+ free(http->sbuffer);
+
+ http->sbuffer = NULL;
+ http->status = HTTP_STATUS_ERROR;
+ http->error = errno;
+ return;
+ }
+
+ if ((zerr = deflateInit2((z_stream *)http->stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, coding == _HTTP_CODING_DEFLATE ? -11 : 27, 7, Z_DEFAULT_STRATEGY)) < Z_OK)
{
- http->status = HTTP_STATUS_ERROR;
- http->error = zerr == Z_MEM_ERROR ? ENOMEM : EINVAL;
+ free(http->sbuffer);
+ free(http->stream);
+
+ http->sbuffer = NULL;
+ http->stream = NULL;
+ http->status = HTTP_STATUS_ERROR;
+ http->error = zerr == Z_MEM_ERROR ? ENOMEM : EINVAL;
return;
}
- http->stream.next_out = (Bytef *)http->sbuffer;
- http->stream.avail_out = (uInt)_HTTP_MAX_SBUFFER;
+ ((z_stream *)http->stream)->next_out = (Bytef *)http->sbuffer;
+ ((z_stream *)http->stream)->avail_out = (uInt)_HTTP_MAX_SBUFFER;
break;
case _HTTP_CODING_INFLATE :
@@ -3866,19 +3923,30 @@ http_content_coding_start(
* -15 is raw inflate, 31 is gunzip, per ZLIB documentation.
*/
- if ((zerr = inflateInit2(&(http->stream),
- coding == _HTTP_CODING_INFLATE ? -15 : 31))
- < Z_OK)
+ if ((http->stream = calloc(1, sizeof(z_stream))) == NULL)
+ {
+ free(http->sbuffer);
+
+ http->sbuffer = NULL;
+ http->status = HTTP_STATUS_ERROR;
+ http->error = errno;
+ return;
+ }
+
+ if ((zerr = inflateInit2((z_stream *)http->stream, coding == _HTTP_CODING_INFLATE ? -15 : 31)) < Z_OK)
{
free(http->sbuffer);
+ free(http->stream);
+
http->sbuffer = NULL;
+ http->stream = NULL;
http->status = HTTP_STATUS_ERROR;
http->error = zerr == Z_MEM_ERROR ? ENOMEM : EINVAL;
return;
}
- http->stream.avail_in = 0;
- http->stream.next_in = http->sbuffer;
+ ((z_stream *)http->stream)->avail_in = 0;
+ ((z_stream *)http->stream)->next_in = http->sbuffer;
break;
default :
@@ -3944,7 +4012,7 @@ http_create(
if ((http = calloc(sizeof(http_t), 1)) == NULL)
{
_cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
- httpAddrFreeList(addrlist);
+ httpAddrFreeList(myaddrlist);
return (NULL);
}
@@ -4056,7 +4124,7 @@ http_read(http_t *http, /* I - HTTP connection */
DEBUG_printf(("http_read(http=%p, buffer=%p, length=" CUPS_LLFMT ")", (void *)http, (void *)buffer, CUPS_LLCAST length));
- if (!http->blocking)
+ if (!http->blocking || http->timeout_value > 0.0)
{
while (!httpWait(http, http->wait_value))
{
@@ -4081,7 +4149,7 @@ http_read(http_t *http, /* I - HTTP connection */
if (bytes < 0)
{
-#ifdef WIN32
+#ifdef _WIN32
if (WSAGetLastError() != WSAEINTR)
{
http->error = WSAGetLastError();
@@ -4117,7 +4185,7 @@ http_read(http_t *http, /* I - HTTP connection */
http->error = errno;
return (-1);
}
-#endif /* WIN32 */
+#endif /* _WIN32 */
}
}
while (bytes < 0);
@@ -4131,7 +4199,7 @@ http_read(http_t *http, /* I - HTTP connection */
if (bytes < 0)
{
-#ifdef WIN32
+#ifdef _WIN32
if (WSAGetLastError() == WSAEINTR)
bytes = 0;
else
@@ -4141,7 +4209,7 @@ http_read(http_t *http, /* I - HTTP connection */
bytes = 0;
else
http->error = errno;
-#endif /* WIN32 */
+#endif /* _WIN32 */
}
else if (bytes == 0)
{
@@ -4505,7 +4573,7 @@ static void
http_set_timeout(int fd, /* I - File descriptor */
double timeout) /* I - Timeout in seconds */
{
-#ifdef WIN32
+#ifdef _WIN32
DWORD tv = (DWORD)(timeout * 1000);
/* Timeout in milliseconds */
@@ -4520,7 +4588,7 @@ http_set_timeout(int fd, /* I - File descriptor */
setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, CUPS_SOCAST &tv, sizeof(tv));
setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, CUPS_SOCAST &tv, sizeof(tv));
-#endif /* WIN32 */
+#endif /* _WIN32 */
}
@@ -4651,7 +4719,7 @@ http_write(http_t *http, /* I - HTTP connection */
{
DEBUG_printf(("3http_write: About to write %d bytes.", (int)length));
- if (http->timeout_cb)
+ if (http->timeout_value > 0.0)
{
#ifdef HAVE_POLL
struct pollfd pfd; /* Polled file descriptor */
@@ -4682,12 +4750,12 @@ http_write(http_t *http, /* I - HTTP connection */
nfds = select(http->fd + 1, NULL, &output_set, NULL, &timeout);
}
-# ifdef WIN32
+# ifdef _WIN32
while (nfds < 0 && (WSAGetLastError() == WSAEINTR ||
WSAGetLastError() == WSAEWOULDBLOCK));
# else
while (nfds < 0 && (errno == EINTR || errno == EAGAIN));
-# endif /* WIN32 */
+# endif /* _WIN32 */
#endif /* HAVE_POLL */
if (nfds < 0)
@@ -4695,13 +4763,13 @@ http_write(http_t *http, /* I - HTTP connection */
http->error = errno;
return (-1);
}
- else if (nfds == 0 && !(*http->timeout_cb)(http, http->timeout_data))
+ else if (nfds == 0 && (!http->timeout_cb || !(*http->timeout_cb)(http, http->timeout_data)))
{
-#ifdef WIN32
+#ifdef _WIN32
http->error = WSAEWOULDBLOCK;
#else
http->error = EWOULDBLOCK;
-#endif /* WIN32 */
+#endif /* _WIN32 */
return (-1);
}
}
@@ -4720,7 +4788,7 @@ http_write(http_t *http, /* I - HTTP connection */
if (bytes < 0)
{
-#ifdef WIN32
+#ifdef _WIN32
if (WSAGetLastError() == WSAEINTR)
continue;
else if (WSAGetLastError() == WSAEWOULDBLOCK)
@@ -4754,7 +4822,7 @@ http_write(http_t *http, /* I - HTTP connection */
http->error = errno;
continue;
}
-#endif /* WIN32 */
+#endif /* _WIN32 */
DEBUG_printf(("3http_write: error writing data (%s).",
strerror(http->error)));
diff --git a/cups/http.h b/cups/http.h
index c61a79ee..e94adae3 100644
--- a/cups/http.h
+++ b/cups/http.h
@@ -1,7 +1,7 @@
/*
* Hyper-Text Transport Protocol definitions for CUPS.
*
- * Copyright 2007-2017 by Apple Inc.
+ * Copyright 2007-2018 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
@@ -25,7 +25,7 @@
# include <string.h>
# include <time.h>
# include <sys/types.h>
-# ifdef WIN32
+# ifdef _WIN32
# ifndef __CUPS_SSIZE_T_DEFINED
# define __CUPS_SSIZE_T_DEFINED
/* Windows does not support the ssize_t type, so map it to off_t... */
@@ -54,7 +54,7 @@ typedef off_t ssize_t; /* @private@ */
# if defined(LOCAL_PEERCRED) && !defined(SO_PEERCRED)
# define SO_PEERCRED LOCAL_PEERCRED
# endif /* LOCAL_PEERCRED && !SO_PEERCRED */
-# endif /* WIN32 */
+# endif /* _WIN32 */
/*
@@ -85,7 +85,7 @@ extern "C" {
# define s6_addr32 _S6_un._S6_u32
# elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__)|| defined(__DragonFly__)
# define s6_addr32 __u6_addr.__u6_addr32
-# elif defined(WIN32)
+# elif defined(_WIN32)
/*
* Windows only defines byte and 16-bit word members of the union and
* requires special casing of all raw address code...
@@ -181,6 +181,7 @@ typedef enum http_field_e /**** HTTP field names ****/
HTTP_FIELD_ACCEPT_ENCODING, /* Accepting-Encoding field @since CUPS 1.7/macOS 10.9@ */
HTTP_FIELD_ALLOW, /* Allow field @since CUPS 1.7/macOS 10.9@ */
HTTP_FIELD_SERVER, /* Server field @since CUPS 1.7/macOS 10.9@ */
+ HTTP_FIELD_AUTHENTICATION_INFO, /* Authentication-Info field (@since CUPS 2.2.9) */
HTTP_FIELD_MAX /* Maximum field index */
} http_field_t;
@@ -248,10 +249,11 @@ typedef enum http_status_e /**** HTTP status codes ****/
HTTP_STATUS_MULTIPLE_CHOICES = 300, /* Multiple files match request */
HTTP_STATUS_MOVED_PERMANENTLY, /* Document has moved permanently */
- HTTP_STATUS_MOVED_TEMPORARILY, /* Document has moved temporarily */
- HTTP_STATUS_SEE_OTHER, /* See this other link... */
+ HTTP_STATUS_FOUND, /* Document was found at a different URI */
+ HTTP_STATUS_SEE_OTHER, /* See this other link */
HTTP_STATUS_NOT_MODIFIED, /* File not modified */
HTTP_STATUS_USE_PROXY, /* Must use a proxy to access this URI */
+ HTTP_STATUS_TEMPORARY_REDIRECT = 307, /* Temporary redirection */
HTTP_STATUS_BAD_REQUEST = 400, /* Bad request */
HTTP_STATUS_UNAUTHORIZED, /* Unauthorized to access host */
@@ -285,6 +287,8 @@ typedef enum http_status_e /**** HTTP status codes ****/
HTTP_STATUS_CUPS_PKI_ERROR, /* Error negotiating a secure connection @since CUPS 1.5/macOS 10.7@ */
HTTP_STATUS_CUPS_WEBIF_DISABLED /* Web interface is disabled @private@ */
+# define HTTP_STATUS_MOVED_TEMPORARILY HTTP_STATUS_FOUND /* Renamed in RFC 7231 */
+
# ifndef _CUPS_NO_DEPRECATED
/* Old names for this enumeration */
# define HTTP_ERROR HTTP_STATUS_ERROR
@@ -476,8 +480,7 @@ extern int httpHead(http_t *http, const char *uri);
extern void httpInitialize(void);
extern int httpOptions(http_t *http, const char *uri);
extern int httpPost(http_t *http, const char *uri);
-extern int httpPrintf(http_t *http, const char *format, ...)
- __attribute__ ((__format__ (__printf__, 2, 3)));
+extern int httpPrintf(http_t *http, const char *format, ...) _CUPS_FORMAT(2, 3);
extern int httpPut(http_t *http, const char *uri);
extern int httpRead(http_t *http, char *buffer, int length) _CUPS_DEPRECATED_MSG("Use httpRead2 instead.");
extern int httpReconnect(http_t *http) _CUPS_DEPRECATED_1_6_MSG("Use httpReconnect2 instead.");
diff --git a/cups/ipp-support.c b/cups/ipp-support.c
index 675e5f38..d1ad65c8 100644
--- a/cups/ipp-support.c
+++ b/cups/ipp-support.c
@@ -1,8 +1,8 @@
/*
* Internet Printing Protocol support functions for CUPS.
*
- * Copyright 2007-2017 by Apple Inc.
- * Copyright 1997-2007 by Easy Software Products, all rights reserved.
+ * Copyright © 2007-2018 by Apple Inc.
+ * Copyright © 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
* property of Apple Inc. and are protected by Federal copyright
@@ -960,9 +960,12 @@ ippCreateRequestedArray(ipp_t *request) /* I - IPP request */
"feed-orientation-supported",
"finishings",
"finishings-col",
+ "finishings-col-database",
"finishings-col-default",
+ "finishings-col-ready",
"finishings-col-supported",
"finishings-default",
+ "finishings-ready",
"finishings-supported",
"font-name-requested",
"font-name-requested-default",
@@ -1001,6 +1004,7 @@ ippCreateRequestedArray(ipp_t *request) /* I - IPP request */
"media-bottom-margin-supported",
"media-col",
"media-col-default",
+ "media-col-ready",
"media-col-supported",
"media-color-supported",
"media-default",
@@ -1015,6 +1019,7 @@ ippCreateRequestedArray(ipp_t *request) /* I - IPP request */
"media-left-margin-supported",
"media-order-count-supported",
"media-pre-printed-supported",
+ "media-ready",
"media-recycled-supported",
"media-right-margin-supported",
"media-size-supported",
@@ -1277,9 +1282,12 @@ ippCreateRequestedArray(ipp_t *request) /* I - IPP request */
"feed-orientation-supported",
"finishings",
"finishings-col",
+ "finishings-col-database",
"finishings-col-default",
+ "finishings-col-ready",
"finishings-col-supported",
"finishings-default",
+ "finishings-ready",
"finishings-supported",
"font-name-requested",
"font-name-requested-default",
@@ -1383,6 +1391,7 @@ ippCreateRequestedArray(ipp_t *request) /* I - IPP request */
"media-bottom-margin-supported",
"media-col",
"media-col-default",
+ "media-col-ready",
"media-col-supported",
"media-color-supported",
"media-default",
@@ -1397,6 +1406,7 @@ ippCreateRequestedArray(ipp_t *request) /* I - IPP request */
"media-left-margin-supported",
"media-order-count-supported",
"media-pre-printed-supported",
+ "media-ready",
"media-recycled-supported",
"media-right-margin-supported",
"media-size-supported",
@@ -1582,10 +1592,12 @@ ippCreateRequestedArray(ipp_t *request) /* I - IPP request */
"job-page-limit", /* CUPS extension */
"job-password-encryption-supported",
"job-password-supported",
+ "job-presets-supported", /* IPP Presets */
"job-quota-period", /* CUPS extension */
"job-resolvers-supported",
"job-settable-attributes-supported",
"job-spooling-supported",
+ "job-triggers-supported", /* IPP Presets */
"jpeg-k-octets-supported", /* CUPS extension */
"jpeg-x-dimension-supported", /* CUPS extension */
"jpeg-y-dimension-supported", /* CUPS extension */
@@ -1599,8 +1611,6 @@ ippCreateRequestedArray(ipp_t *request) /* I - IPP request */
"marker-message", /* CUPS extension */
"marker-names", /* CUPS extension */
"marker-types", /* CUPS extension */
- "media-col-ready",
- "media-ready",
"member-names", /* CUPS extension */
"member-uris", /* CUPS extension */
"multiple-destination-uris-supported",/* IPP FaxOut */
@@ -1623,6 +1633,8 @@ ippCreateRequestedArray(ipp_t *request) /* I - IPP request */
"printer-charge-info",
"printer-charge-info-uri",
"printer-commands", /* CUPS extension */
+ "printer-config-change-date-time",
+ "printer-config-change-time",
"printer-current-time",
"printer-detailed-status-messages",
"printer-device-id",
diff --git a/cups/ipp.c b/cups/ipp.c
index fd8988fd..cc9c6af5 100644
--- a/cups/ipp.c
+++ b/cups/ipp.c
@@ -1,8 +1,8 @@
/*
* Internet Printing Protocol functions for CUPS.
*
- * Copyright 2007-2017 by Apple Inc.
- * Copyright 1997-2007 by Easy Software Products, all rights reserved.
+ * Copyright © 2007-2018 by Apple Inc.
+ * Copyright © 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
* property of Apple Inc. and are protected by Federal copyright
@@ -19,9 +19,9 @@
#include "cups-private.h"
#include <regex.h>
-#ifdef WIN32
+#ifdef _WIN32
# include <io.h>
-#endif /* WIN32 */
+#endif /* _WIN32 */
/*
@@ -33,12 +33,8 @@ static ipp_attribute_t *ipp_add_attr(ipp_t *ipp, const char *name,
int num_values);
static void ipp_free_values(ipp_attribute_t *attr, int element,
int count);
-static char *ipp_get_code(const char *locale, char *buffer,
- size_t bufsize)
- __attribute__((nonnull(1,2)));
-static char *ipp_lang_code(const char *locale, char *buffer,
- size_t bufsize)
- __attribute__((nonnull(1,2)));
+static char *ipp_get_code(const char *locale, char *buffer, size_t bufsize) _CUPS_NONNULL((1, 2));
+static char *ipp_lang_code(const char *locale, char *buffer, size_t bufsize) _CUPS_NONNULL((1, 2));
static size_t ipp_length(ipp_t *ipp, int collection);
static ssize_t ipp_read_http(http_t *http, ipp_uchar_t *buffer,
size_t length);
@@ -1483,6 +1479,7 @@ ippCopyAttribute(
int quickcopy) /* I - 1 for a referenced copy, 0 for normal */
{
int i; /* Looping var */
+ ipp_tag_t srctag; /* Source value tag */
ipp_attribute_t *dstattr; /* Destination attribute */
_ipp_value_t *srcval, /* Source value */
*dstval; /* Destination value */
@@ -1501,9 +1498,10 @@ ippCopyAttribute(
* Copy it...
*/
- quickcopy = quickcopy ? IPP_TAG_CUPS_CONST : 0;
+ quickcopy = (quickcopy && (srcattr->value_tag & IPP_TAG_CUPS_CONST)) ? IPP_TAG_CUPS_CONST : 0;
+ srctag = srcattr->value_tag & IPP_TAG_CUPS_MASK;
- switch (srcattr->value_tag & ~IPP_TAG_CUPS_CONST)
+ switch (srctag)
{
case IPP_TAG_ZERO :
dstattr = ippAddSeparator(dst);
@@ -1516,139 +1514,70 @@ ippCopyAttribute(
case IPP_TAG_NOTSETTABLE :
case IPP_TAG_DELETEATTR :
case IPP_TAG_ADMINDEFINE :
- dstattr = ippAddOutOfBand(dst, srcattr->group_tag, srcattr->value_tag & ~IPP_TAG_CUPS_CONST, srcattr->name);
+ dstattr = ippAddOutOfBand(dst, srcattr->group_tag, srctag, srcattr->name);
break;
case IPP_TAG_INTEGER :
case IPP_TAG_ENUM :
- dstattr = ippAddIntegers(dst, srcattr->group_tag, srcattr->value_tag,
- srcattr->name, srcattr->num_values, NULL);
- if (!dstattr)
- break;
-
- for (i = srcattr->num_values, srcval = srcattr->values, dstval = dstattr->values;
- i > 0;
- i --, srcval ++, dstval ++)
- dstval->integer = srcval->integer;
- break;
-
case IPP_TAG_BOOLEAN :
- dstattr = ippAddBooleans(dst, srcattr->group_tag, srcattr->name,
- srcattr->num_values, NULL);
- if (!dstattr)
- break;
-
- for (i = srcattr->num_values, srcval = srcattr->values, dstval = dstattr->values;
- i > 0;
- i --, srcval ++, dstval ++)
- dstval->boolean = srcval->boolean;
+ case IPP_TAG_DATE :
+ case IPP_TAG_RESOLUTION :
+ case IPP_TAG_RANGE :
+ if ((dstattr = ipp_add_attr(dst, srcattr->name, srcattr->group_tag, srctag, srcattr->num_values)) != NULL)
+ memcpy(dstattr->values, srcattr->values, (size_t)srcattr->num_values * sizeof(_ipp_value_t));
break;
case IPP_TAG_TEXT :
case IPP_TAG_NAME :
+ case IPP_TAG_RESERVED_STRING :
case IPP_TAG_KEYWORD :
case IPP_TAG_URI :
case IPP_TAG_URISCHEME :
case IPP_TAG_CHARSET :
case IPP_TAG_LANGUAGE :
case IPP_TAG_MIMETYPE :
- dstattr = ippAddStrings(dst, srcattr->group_tag,
- (ipp_tag_t)(srcattr->value_tag | quickcopy),
- srcattr->name, srcattr->num_values, NULL, NULL);
- if (!dstattr)
+ if ((dstattr = ippAddStrings(dst, srcattr->group_tag, (ipp_tag_t)(srctag | quickcopy), srcattr->name, srcattr->num_values, NULL, NULL)) == NULL)
break;
if (quickcopy)
{
- for (i = srcattr->num_values, srcval = srcattr->values,
- dstval = dstattr->values;
- i > 0;
- i --, srcval ++, dstval ++)
- dstval->string.text = srcval->string.text;
+ /*
+ * Can safely quick-copy these string values...
+ */
+
+ memcpy(dstattr->values, srcattr->values, (size_t)srcattr->num_values * sizeof(_ipp_value_t));
}
- else if (srcattr->value_tag & IPP_TAG_CUPS_CONST)
- {
- for (i = srcattr->num_values, srcval = srcattr->values,
- dstval = dstattr->values;
- i > 0;
- i --, srcval ++, dstval ++)
- dstval->string.text = _cupsStrAlloc(srcval->string.text);
- }
else
{
- for (i = srcattr->num_values, srcval = srcattr->values,
- dstval = dstattr->values;
- i > 0;
- i --, srcval ++, dstval ++)
- dstval->string.text = _cupsStrRetain(srcval->string.text);
- }
- break;
-
- case IPP_TAG_DATE :
- if (srcattr->num_values != 1)
- return (NULL);
-
- dstattr = ippAddDate(dst, srcattr->group_tag, srcattr->name,
- srcattr->values[0].date);
- break;
-
- case IPP_TAG_RESOLUTION :
- dstattr = ippAddResolutions(dst, srcattr->group_tag, srcattr->name,
- srcattr->num_values, IPP_RES_PER_INCH,
- NULL, NULL);
- if (!dstattr)
- break;
-
- for (i = srcattr->num_values, srcval = srcattr->values, dstval = dstattr->values;
- i > 0;
- i --, srcval ++, dstval ++)
- {
- dstval->resolution.xres = srcval->resolution.xres;
- dstval->resolution.yres = srcval->resolution.yres;
- dstval->resolution.units = srcval->resolution.units;
- }
- break;
-
- case IPP_TAG_RANGE :
- dstattr = ippAddRanges(dst, srcattr->group_tag, srcattr->name,
- srcattr->num_values, NULL, NULL);
- if (!dstattr)
- break;
+ /*
+ * Otherwise do a normal reference counted copy...
+ */
- for (i = srcattr->num_values, srcval = srcattr->values, dstval = dstattr->values;
- i > 0;
- i --, srcval ++, dstval ++)
- {
- dstval->range.lower = srcval->range.lower;
- dstval->range.upper = srcval->range.upper;
+ for (i = srcattr->num_values, srcval = srcattr->values, dstval = dstattr->values; i > 0; i --, srcval ++, dstval ++)
+ dstval->string.text = _cupsStrAlloc(srcval->string.text);
}
break;
case IPP_TAG_TEXTLANG :
case IPP_TAG_NAMELANG :
- dstattr = ippAddStrings(dst, srcattr->group_tag,
- (ipp_tag_t)(srcattr->value_tag | quickcopy),
- srcattr->name, srcattr->num_values, NULL, NULL);
- if (!dstattr)
+ if ((dstattr = ippAddStrings(dst, srcattr->group_tag, (ipp_tag_t)(srctag | quickcopy), srcattr->name, srcattr->num_values, NULL, NULL)) == NULL)
break;
if (quickcopy)
{
- for (i = srcattr->num_values, srcval = srcattr->values,
- dstval = dstattr->values;
- i > 0;
- i --, srcval ++, dstval ++)
- {
- dstval->string.language = srcval->string.language;
- dstval->string.text = srcval->string.text;
- }
+ /*
+ * Can safely quick-copy these string values...
+ */
+
+ memcpy(dstattr->values, srcattr->values, (size_t)srcattr->num_values * sizeof(_ipp_value_t));
}
else if (srcattr->value_tag & IPP_TAG_CUPS_CONST)
{
- for (i = srcattr->num_values, srcval = srcattr->values,
- dstval = dstattr->values;
- i > 0;
- i --, srcval ++, dstval ++)
+ /*
+ * Otherwise do a normal reference counted copy...
+ */
+
+ for (i = srcattr->num_values, srcval = srcattr->values, dstval = dstattr->values; i > 0; i --, srcval ++, dstval ++)
{
if (srcval == srcattr->values)
dstval->string.language = _cupsStrAlloc(srcval->string.language);
@@ -1658,32 +1587,13 @@ ippCopyAttribute(
dstval->string.text = _cupsStrAlloc(srcval->string.text);
}
}
- else
- {
- for (i = srcattr->num_values, srcval = srcattr->values,
- dstval = dstattr->values;
- i > 0;
- i --, srcval ++, dstval ++)
- {
- if (srcval == srcattr->values)
- dstval->string.language = _cupsStrRetain(srcval->string.language);
- else
- dstval->string.language = dstattr->values[0].string.language;
-
- dstval->string.text = _cupsStrRetain(srcval->string.text);
- }
- }
break;
case IPP_TAG_BEGIN_COLLECTION :
- dstattr = ippAddCollections(dst, srcattr->group_tag, srcattr->name,
- srcattr->num_values, NULL);
- if (!dstattr)
+ if ((dstattr = ippAddCollections(dst, srcattr->group_tag, srcattr->name, srcattr->num_values, NULL)) == NULL)
break;
- for (i = srcattr->num_values, srcval = srcattr->values, dstval = dstattr->values;
- i > 0;
- i --, srcval ++, dstval ++)
+ for (i = srcattr->num_values, srcval = srcattr->values, dstval = dstattr->values; i > 0; i --, srcval ++, dstval ++)
{
dstval->collection = srcval->collection;
srcval->collection->use ++;
@@ -1692,15 +1602,10 @@ ippCopyAttribute(
case IPP_TAG_STRING :
default :
- /* TODO: Implement quick copy for unknown/octetString values */
- dstattr = ippAddIntegers(dst, srcattr->group_tag, srcattr->value_tag,
- srcattr->name, srcattr->num_values, NULL);
- if (!dstattr)
+ if ((dstattr = ipp_add_attr(dst, srcattr->name, srcattr->group_tag, srctag, srcattr->num_values)) == NULL)
break;
- for (i = srcattr->num_values, srcval = srcattr->values, dstval = dstattr->values;
- i > 0;
- i --, srcval ++, dstval ++)
+ for (i = srcattr->num_values, srcval = srcattr->values, dstval = dstattr->values; i > 0; i --, srcval ++, dstval ++)
{
dstval->unknown.length = srcval->unknown.length;
@@ -3089,6 +2994,13 @@ ippReadIO(void *src, /* I - Data source */
ipp->state = IPP_STATE_DATA;
break;
}
+ else if (tag == IPP_TAG_ZERO || (tag == IPP_TAG_OPERATION && ipp->curtag != IPP_TAG_ZERO))
+ {
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Invalid group tag."), 1);
+ DEBUG_printf(("1ippReadIO: bad tag 0x%02x.", tag));
+ _cupsBufferRelease((char *)buffer);
+ return (IPP_STATE_ERROR);
+ }
else if (tag < IPP_TAG_UNSUPPORTED_VALUE)
{
/*
@@ -3386,7 +3298,10 @@ ippReadIO(void *src, /* I - Data source */
value->boolean = (char)buffer[0];
break;
- case IPP_TAG_NOVALUE :
+ case IPP_TAG_UNSUPPORTED_VALUE :
+ case IPP_TAG_DEFAULT :
+ case IPP_TAG_UNKNOWN :
+ case IPP_TAG_NOVALUE :
case IPP_TAG_NOTSETTABLE :
case IPP_TAG_DELETEATTR :
case IPP_TAG_ADMINDEFINE :
@@ -3406,6 +3321,7 @@ ippReadIO(void *src, /* I - Data source */
case IPP_TAG_TEXT :
case IPP_TAG_NAME :
+ case IPP_TAG_RESERVED_STRING :
case IPP_TAG_KEYWORD :
case IPP_TAG_URI :
case IPP_TAG_URISCHEME :
@@ -4306,17 +4222,21 @@ ippSetString(ipp_t *ipp, /* I - IPP message */
{
char *temp; /* Temporary string */
_ipp_value_t *value; /* Current value */
+ ipp_tag_t value_tag; /* Value tag */
/*
* Range check input...
*/
+ if (attr && *attr)
+ value_tag = (*attr)->value_tag & IPP_TAG_CUPS_MASK;
+ else
+ value_tag = IPP_TAG_ZERO;
+
if (!ipp || !attr || !*attr ||
- ((*attr)->value_tag != IPP_TAG_TEXTLANG &&
- (*attr)->value_tag != IPP_TAG_NAMELANG &&
- ((*attr)->value_tag < IPP_TAG_TEXT ||
- (*attr)->value_tag > IPP_TAG_MIMETYPE)) ||
+ (value_tag < IPP_TAG_TEXT && value_tag != IPP_TAG_TEXTLANG &&
+ value_tag != IPP_TAG_NAMELANG) || value_tag > IPP_TAG_MIMETYPE ||
element < 0 || element > (*attr)->num_values || !strvalue)
return (0);
@@ -4803,21 +4723,6 @@ ippValidateAttribute(
ipp_attribute_t *colattr; /* Collection attribute */
regex_t re; /* Regular expression */
ipp_uchar_t *date; /* Current date value */
- static const char * const uri_status_strings[] =
- { /* URI status strings */
- "URI too large",
- "Bad arguments to function",
- "Bad resource in URI",
- "Bad port number in URI",
- "Bad hostname/address in URI",
- "Bad username in URI",
- "Bad scheme in URI",
- "Bad/empty URI",
- "OK",
- "Missing scheme in URI",
- "Unknown scheme in URI",
- "Missing resource in URI"
- };
/*
@@ -5092,16 +4997,23 @@ ippValidateAttribute(
}
else if (*ptr & 0x80)
break;
+ else if ((*ptr < ' ' && *ptr != '\n' && *ptr != '\r' && *ptr != '\t') || *ptr == 0x7f)
+ break;
}
- if (*ptr)
- {
- ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST,
- _("\"%s\": Bad text value \"%s\" - bad UTF-8 "
- "sequence (RFC 8011 section 5.1.2)."), attr->name,
- attr->values[i].string.text);
- return (0);
- }
+ if (*ptr)
+ {
+ if (*ptr < ' ' || *ptr == 0x7f)
+ {
+ ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad text value \"%s\" - bad control character (PWG 5100.14 section 8.3)."), attr->name, attr->values[i].string.text);
+ return (0);
+ }
+ else
+ {
+ ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad text value \"%s\" - bad UTF-8 sequence (RFC 8011 section 5.1.2)."), attr->name, attr->values[i].string.text);
+ return (0);
+ }
+ }
if ((ptr - attr->values[i].string.text) > (IPP_MAX_TEXT - 1))
{
@@ -5150,16 +5062,23 @@ ippValidateAttribute(
}
else if (*ptr & 0x80)
break;
+ else if (*ptr < ' ' || *ptr == 0x7f)
+ break;
}
if (*ptr)
{
- ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST,
- _("\"%s\": Bad name value \"%s\" - bad UTF-8 "
- "sequence (RFC 8011 section 5.1.3)."), attr->name,
- attr->values[i].string.text);
- return (0);
- }
+ if (*ptr < ' ' || *ptr == 0x7f)
+ {
+ ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad name value \"%s\" - bad control character (PWG 5100.14 section 8.1)."), attr->name, attr->values[i].string.text);
+ return (0);
+ }
+ else
+ {
+ ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad name value \"%s\" - bad UTF-8 sequence (RFC 8011 section 5.1.3)."), attr->name, attr->values[i].string.text);
+ return (0);
+ }
+ }
if ((ptr - attr->values[i].string.text) > (IPP_MAX_NAME - 1))
{
@@ -5214,12 +5133,7 @@ ippValidateAttribute(
if (uri_status < HTTP_URI_STATUS_OK)
{
- ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST,
- _("\"%s\": Bad URI value \"%s\" - %s "
- "(RFC 8011 section 5.1.6)."), attr->name,
- attr->values[i].string.text,
- uri_status_strings[uri_status -
- HTTP_URI_STATUS_OVERFLOW]);
+ ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad URI value \"%s\" - %s (RFC 8011 section 5.1.6)."), attr->name, attr->values[i].string.text, httpURIStatusString(uri_status));
return (0);
}
@@ -6497,6 +6411,7 @@ ipp_free_values(ipp_attribute_t *attr, /* I - Attribute to free values from */
}
break;
+ case IPP_TAG_UNSUPPORTED_VALUE :
case IPP_TAG_DEFAULT :
case IPP_TAG_UNKNOWN :
case IPP_TAG_NOVALUE :
@@ -6838,14 +6753,14 @@ ipp_read_http(http_t *http, /* I - Client connection */
if ((bytes = httpRead2(http, (char *)buffer, length - (size_t)tbytes)) < 0)
{
-#ifdef WIN32
+#ifdef _WIN32
break;
#else
if (errno != EAGAIN && errno != EINTR)
break;
bytes = 0;
-#endif /* WIN32 */
+#endif /* _WIN32 */
}
else if (bytes == 0)
break;
@@ -6873,11 +6788,11 @@ ipp_read_file(int *fd, /* I - File descriptor */
ipp_uchar_t *buffer, /* O - Read buffer */
size_t length) /* I - Number of bytes to read */
{
-#ifdef WIN32
+#ifdef _WIN32
return ((ssize_t)read(*fd, buffer, (unsigned)length));
#else
return (read(*fd, buffer, length));
-#endif /* WIN32 */
+#endif /* _WIN32 */
}
@@ -7045,9 +6960,9 @@ ipp_write_file(int *fd, /* I - File descriptor */
ipp_uchar_t *buffer, /* I - Data to write */
size_t length) /* I - Number of bytes to write */
{
-#ifdef WIN32
+#ifdef _WIN32
return ((ssize_t)write(*fd, buffer, (unsigned)length));
#else
return (write(*fd, buffer, length));
-#endif /* WIN32 */
+#endif /* _WIN32 */
}
diff --git a/cups/ipp.h b/cups/ipp.h
index 2a4f546c..2ee5f1d0 100644
--- a/cups/ipp.h
+++ b/cups/ipp.h
@@ -79,11 +79,11 @@ extern "C" {
typedef enum ipp_dstate_e /**** Document states @exclude all@ ****/
{
- IPP_DOCUMENT_PENDING = 3, /* Document is pending */
- IPP_DOCUMENT_PROCESSING = 5, /* Document is processing */
- IPP_DOCUMENT_CANCELED = 7, /* Document is canceled */
- IPP_DOCUMENT_ABORTED, /* Document is aborted */
- IPP_DOCUMENT_COMPLETED /* Document is completed */
+ IPP_DSTATE_PENDING = 3, /* Document is pending */
+ IPP_DSTATE_PROCESSING = 5, /* Document is processing */
+ IPP_DSTATE_CANCELED = 7, /* Document is canceled */
+ IPP_DSTATE_ABORTED, /* Document is aborted */
+ IPP_DSTATE_COMPLETED /* Document is completed */
# ifndef _CUPS_NO_DEPRECATED
# define IPP_DOCUMENT_PENDING IPP_DSTATE_PENDING
diff --git a/cups/language-private.h b/cups/language-private.h
index 49e4b713..f447ef92 100644
--- a/cups/language-private.h
+++ b/cups/language-private.h
@@ -1,7 +1,7 @@
/*
* Private localization support for CUPS.
*
- * Copyright 2007-2017 by Apple Inc.
+ * Copyright 2007-2018 by Apple Inc.
* Copyright 1997-2006 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
@@ -20,6 +20,7 @@
* Include necessary headers...
*/
+# include "config.h"
# include <stdio.h>
# include <cups/transcode.h>
# ifdef __APPLE__
@@ -59,16 +60,11 @@ extern const char *_cupsAppleLocale(CFStringRef languageName, char *locale, size
# endif /* __APPLE__ */
extern void _cupsCharmapFlush(void);
extern const char *_cupsEncodingName(cups_encoding_t encoding);
-extern void _cupsLangPrintError(const char *prefix,
- const char *message);
-extern int _cupsLangPrintFilter(FILE *fp, const char *prefix,
- const char *message, ...)
- __attribute__ ((__format__ (__printf__, 3, 4)));
-extern int _cupsLangPrintf(FILE *fp, const char *message, ...)
- __attribute__ ((__format__ (__printf__, 2, 3)));
+extern void _cupsLangPrintError(const char *prefix, const char *message);
+extern int _cupsLangPrintFilter(FILE *fp, const char *prefix, const char *message, ...) _CUPS_FORMAT(3, 4);
+extern int _cupsLangPrintf(FILE *fp, const char *message, ...) _CUPS_FORMAT(2, 3);
extern int _cupsLangPuts(FILE *fp, const char *message);
-extern const char *_cupsLangString(cups_lang_t *lang,
- const char *message);
+extern const char *_cupsLangString(cups_lang_t *lang, const char *message);
extern void _cupsMessageFree(cups_array_t *a);
extern cups_array_t *_cupsMessageLoad(const char *filename, int unquote);
extern const char *_cupsMessageLookup(cups_array_t *a, const char *m);
diff --git a/cups/language.c b/cups/language.c
index e6d2d44a..61280c0f 100644
--- a/cups/language.c
+++ b/cups/language.c
@@ -21,11 +21,11 @@
#ifdef HAVE_LANGINFO_H
# include <langinfo.h>
#endif /* HAVE_LANGINFO_H */
-#ifdef WIN32
+#ifdef _WIN32
# include <io.h>
#else
# include <unistd.h>
-#endif /* WIN32 */
+#endif /* _WIN32 */
#ifdef HAVE_COREFOUNDATION_H
# include <CoreFoundation/CoreFoundation.h>
#endif /* HAVE_COREFOUNDATION_H */
diff --git a/cups/libcups2.def b/cups/libcups2.def
index a7be679f..fa4aaa3b 100644
--- a/cups/libcups2.def
+++ b/cups/libcups2.def
@@ -1,5 +1,5 @@
LIBRARY libcups2
-VERSION 2.12
+VERSION 2.13
EXPORTS
_cupsArrayAddStrings
_cupsArrayNewStrings
@@ -13,6 +13,7 @@ _cupsConnect
_cupsConvertOptions
_cupsCreateDest
_cupsEncodingName
+_cupsFilePeekAhead
_cupsGet1284Values
_cupsGetDestResource
_cupsGetDests
@@ -24,9 +25,6 @@ _cupsLangPrintError
_cupsLangPrintf
_cupsLangPuts
_cupsLangString
-_cupsMD5Append
-_cupsMD5Finish
-_cupsMD5Init
_cupsMessageFree
_cupsMessageLoad
_cupsMessageLookup
@@ -39,18 +37,6 @@ _cupsRWInit
_cupsRWLockRead
_cupsRWLockWrite
_cupsRWUnlock
-_cupsSNMPClose
-_cupsSNMPCopyOID
-_cupsSNMPDefaultCommunity
-_cupsSNMPIsOID
-_cupsSNMPIsOIDPrefixed
-_cupsSNMPOIDToString
-_cupsSNMPOpen
-_cupsSNMPRead
-_cupsSNMPSetDebug
-_cupsSNMPStringToOID
-_cupsSNMPWalk
-_cupsSNMPWrite
_cupsSetDefaults
_cupsSetError
_cupsSetHTTPError
@@ -65,6 +51,7 @@ _cupsStrScand
_cupsStrStatistics
_cupsThreadCancel
_cupsThreadCreate
+_cupsThreadDetach
_cupsThreadWait
_cupsUserDefault
_cups_safe_vsnprintf
@@ -81,6 +68,7 @@ _httpDisconnect
_httpEncodeURI
_httpFreeCredentials
_httpResolveURI
+_httpSetDigestAuthString
_httpStatus
_httpTLSInitialize
_httpTLSPending
@@ -124,6 +112,7 @@ _pwgMediaTable
_pwgMediaTypeForType
_pwgPageSizeForMedia
cupsAddDest
+cupsAddIntegerOption
cupsAddOption
cupsAdminCreateWindowsPPD
cupsAdminExportSamba
@@ -227,6 +216,7 @@ cupsGetDests2
cupsGetDevices
cupsGetFd
cupsGetFile
+cupsGetIntegerOption
cupsGetJobs
cupsGetJobs2
cupsGetNamedDest
@@ -240,6 +230,7 @@ cupsGetPrinters
cupsGetResponse
cupsGetServerPPD
cupsHashData
+cupsHashString
cupsLangDefault
cupsLangEncoding
cupsLangFlush
diff --git a/cups/md5.c b/cups/md5.c
index c0f5dd73..d5057bf1 100644
--- a/cups/md5.c
+++ b/cups/md5.c
@@ -1,7 +1,7 @@
/*
* Private MD5 implementation for CUPS.
*
- * Copyright 2007-2014 by Apple Inc.
+ * Copyright 2007-2017 by Apple Inc.
* Copyright 2005 by Easy Software Products
* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
*
@@ -43,70 +43,71 @@
#include "md5-private.h"
#include "string-private.h"
-#define T1 0xd76aa478
-#define T2 0xe8c7b756
-#define T3 0x242070db
-#define T4 0xc1bdceee
-#define T5 0xf57c0faf
-#define T6 0x4787c62a
-#define T7 0xa8304613
-#define T8 0xfd469501
-#define T9 0x698098d8
-#define T10 0x8b44f7af
-#define T11 0xffff5bb1
-#define T12 0x895cd7be
-#define T13 0x6b901122
-#define T14 0xfd987193
-#define T15 0xa679438e
-#define T16 0x49b40821
-#define T17 0xf61e2562
-#define T18 0xc040b340
-#define T19 0x265e5a51
-#define T20 0xe9b6c7aa
-#define T21 0xd62f105d
-#define T22 0x02441453
-#define T23 0xd8a1e681
-#define T24 0xe7d3fbc8
-#define T25 0x21e1cde6
-#define T26 0xc33707d6
-#define T27 0xf4d50d87
-#define T28 0x455a14ed
-#define T29 0xa9e3e905
-#define T30 0xfcefa3f8
-#define T31 0x676f02d9
-#define T32 0x8d2a4c8a
-#define T33 0xfffa3942
-#define T34 0x8771f681
-#define T35 0x6d9d6122
-#define T36 0xfde5380c
-#define T37 0xa4beea44
-#define T38 0x4bdecfa9
-#define T39 0xf6bb4b60
-#define T40 0xbebfbc70
-#define T41 0x289b7ec6
-#define T42 0xeaa127fa
-#define T43 0xd4ef3085
-#define T44 0x04881d05
-#define T45 0xd9d4d039
-#define T46 0xe6db99e5
-#define T47 0x1fa27cf8
-#define T48 0xc4ac5665
-#define T49 0xf4292244
-#define T50 0x432aff97
-#define T51 0xab9423a7
-#define T52 0xfc93a039
-#define T53 0x655b59c3
-#define T54 0x8f0ccc92
-#define T55 0xffeff47d
-#define T56 0x85845dd1
-#define T57 0x6fa87e4f
-#define T58 0xfe2ce6e0
-#define T59 0xa3014314
-#define T60 0x4e0811a1
-#define T61 0xf7537e82
-#define T62 0xbd3af235
-#define T63 0x2ad7d2bb
-#define T64 0xeb86d391
+#if !defined(__APPLE__) && !defined(HAVE_GNUTLS)
+# define T1 0xd76aa478
+# define T2 0xe8c7b756
+# define T3 0x242070db
+# define T4 0xc1bdceee
+# define T5 0xf57c0faf
+# define T6 0x4787c62a
+# define T7 0xa8304613
+# define T8 0xfd469501
+# define T9 0x698098d8
+# define T10 0x8b44f7af
+# define T11 0xffff5bb1
+# define T12 0x895cd7be
+# define T13 0x6b901122
+# define T14 0xfd987193
+# define T15 0xa679438e
+# define T16 0x49b40821
+# define T17 0xf61e2562
+# define T18 0xc040b340
+# define T19 0x265e5a51
+# define T20 0xe9b6c7aa
+# define T21 0xd62f105d
+# define T22 0x02441453
+# define T23 0xd8a1e681
+# define T24 0xe7d3fbc8
+# define T25 0x21e1cde6
+# define T26 0xc33707d6
+# define T27 0xf4d50d87
+# define T28 0x455a14ed
+# define T29 0xa9e3e905
+# define T30 0xfcefa3f8
+# define T31 0x676f02d9
+# define T32 0x8d2a4c8a
+# define T33 0xfffa3942
+# define T34 0x8771f681
+# define T35 0x6d9d6122
+# define T36 0xfde5380c
+# define T37 0xa4beea44
+# define T38 0x4bdecfa9
+# define T39 0xf6bb4b60
+# define T40 0xbebfbc70
+# define T41 0x289b7ec6
+# define T42 0xeaa127fa
+# define T43 0xd4ef3085
+# define T44 0x04881d05
+# define T45 0xd9d4d039
+# define T46 0xe6db99e5
+# define T47 0x1fa27cf8
+# define T48 0xc4ac5665
+# define T49 0xf4292244
+# define T50 0x432aff97
+# define T51 0xab9423a7
+# define T52 0xfc93a039
+# define T53 0x655b59c3
+# define T54 0x8f0ccc92
+# define T55 0xffeff47d
+# define T56 0x85845dd1
+# define T57 0x6fa87e4f
+# define T58 0xfe2ce6e0
+# define T59 0xa3014314
+# define T60 0x4e0811a1
+# define T61 0xf7537e82
+# define T62 0xbd3af235
+# define T63 0x2ad7d2bb
+# define T64 0xeb86d391
static void
_cups_md5_process(_cups_md5_state_t *pms, const unsigned char *data /*[64]*/)
@@ -116,10 +117,10 @@ _cups_md5_process(_cups_md5_state_t *pms, const unsigned char *data /*[64]*/)
c = pms->abcd[2], d = pms->abcd[3];
unsigned int t;
-#ifndef ARCH_IS_BIG_ENDIAN
-# define ARCH_IS_BIG_ENDIAN 1 /* slower, default implementation */
-#endif
-#if ARCH_IS_BIG_ENDIAN
+# ifndef ARCH_IS_BIG_ENDIAN
+# define ARCH_IS_BIG_ENDIAN 1 /* slower, default implementation */
+# endif
+# if ARCH_IS_BIG_ENDIAN
/*
* On big-endian machines, we must arrange the bytes in the right
@@ -133,7 +134,7 @@ _cups_md5_process(_cups_md5_state_t *pms, const unsigned char *data /*[64]*/)
X[i] = (unsigned)xp[0] + ((unsigned)xp[1] << 8) +
((unsigned)xp[2] << 16) + ((unsigned)xp[3] << 24);
-#else /* !ARCH_IS_BIG_ENDIAN */
+# else /* !ARCH_IS_BIG_ENDIAN */
/*
* On little-endian machines, we can process properly aligned data
@@ -150,15 +151,15 @@ _cups_md5_process(_cups_md5_state_t *pms, const unsigned char *data /*[64]*/)
memcpy(xbuf, data, 64);
X = xbuf;
}
-#endif
+# endif
-#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
+# define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
/* Round 1. */
/* Let [abcd k s i] denote the operation
a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
-#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
-#define SET(a, b, c, d, k, s, Ti)\
+# define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
+# define SET(a, b, c, d, k, s, Ti)\
t = a + F(b,c,d) + X[k] + Ti;\
a = ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
@@ -178,13 +179,13 @@ _cups_md5_process(_cups_md5_state_t *pms, const unsigned char *data /*[64]*/)
SET(d, a, b, c, 13, 12, T14);
SET(c, d, a, b, 14, 17, T15);
SET(b, c, d, a, 15, 22, T16);
-#undef SET
+# undef SET
/* Round 2. */
/* Let [abcd k s i] denote the operation
a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
-#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
-#define SET(a, b, c, d, k, s, Ti)\
+# define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
+# define SET(a, b, c, d, k, s, Ti)\
t = a + G(b,c,d) + X[k] + Ti;\
a = ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
@@ -204,13 +205,13 @@ _cups_md5_process(_cups_md5_state_t *pms, const unsigned char *data /*[64]*/)
SET(d, a, b, c, 2, 9, T30);
SET(c, d, a, b, 7, 14, T31);
SET(b, c, d, a, 12, 20, T32);
-#undef SET
+# undef SET
/* Round 3. */
/* Let [abcd k s t] denote the operation
a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
-#define H(x, y, z) ((x) ^ (y) ^ (z))
-#define SET(a, b, c, d, k, s, Ti)\
+# define H(x, y, z) ((x) ^ (y) ^ (z))
+# define SET(a, b, c, d, k, s, Ti)\
t = a + H(b,c,d) + X[k] + Ti;\
a = ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
@@ -230,13 +231,13 @@ _cups_md5_process(_cups_md5_state_t *pms, const unsigned char *data /*[64]*/)
SET(d, a, b, c, 12, 11, T46);
SET(c, d, a, b, 15, 16, T47);
SET(b, c, d, a, 2, 23, T48);
-#undef SET
+# undef SET
/* Round 4. */
/* Let [abcd k s t] denote the operation
a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
-#define I(x, y, z) ((y) ^ ((x) | ~(z)))
-#define SET(a, b, c, d, k, s, Ti)\
+# define I(x, y, z) ((y) ^ ((x) | ~(z)))
+# define SET(a, b, c, d, k, s, Ti)\
t = a + I(b,c,d) + X[k] + Ti;\
a = ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
@@ -256,7 +257,7 @@ _cups_md5_process(_cups_md5_state_t *pms, const unsigned char *data /*[64]*/)
SET(d, a, b, c, 11, 10, T62);
SET(c, d, a, b, 2, 15, T63);
SET(b, c, d, a, 9, 21, T64);
-#undef SET
+# undef SET
/* Then perform the following additions. (That is increment each
of the four registers by the value it had before this block
@@ -337,3 +338,4 @@ _cupsMD5Finish(_cups_md5_state_t *pms, unsigned char digest[16])
for (i = 0; i < 16; ++i)
digest[i] = (unsigned char)(pms->abcd[i >> 2] >> ((i & 3) << 3));
}
+#endif /* !__APPLE__ && !HAVE_GNUTLS */
diff --git a/cups/md5passwd.c b/cups/md5passwd.c
index a9817aaa..49add7d7 100644
--- a/cups/md5passwd.c
+++ b/cups/md5passwd.c
@@ -1,7 +1,7 @@
/*
- * MD5 password support for CUPS.
+ * MD5 password support for CUPS (deprecated).
*
- * Copyright 2007-2010 by Apple Inc.
+ * Copyright 2007-2017 by Apple Inc.
* Copyright 1997-2005 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
@@ -17,12 +17,15 @@
* Include necessary headers...
*/
+#include <cups/cups.h>
#include "http-private.h"
#include "string-private.h"
/*
* 'httpMD5()' - Compute the MD5 sum of the username:group:password.
+ *
+ * @deprecated@
*/
char * /* O - MD5 sum */
@@ -31,7 +34,6 @@ httpMD5(const char *username, /* I - User name */
const char *passwd, /* I - Password string */
char md5[33]) /* O - MD5 string */
{
- _cups_md5_state_t state; /* MD5 state info */
unsigned char sum[16]; /* Sum data */
char line[256]; /* Line to sum */
@@ -41,15 +43,13 @@ httpMD5(const char *username, /* I - User name */
*/
snprintf(line, sizeof(line), "%s:%s:%s", username, realm, passwd);
- _cupsMD5Init(&state);
- _cupsMD5Append(&state, (unsigned char *)line, (int)strlen(line));
- _cupsMD5Finish(&state, sum);
+ cupsHashData("md5", (unsigned char *)line, strlen(line), sum, sizeof(sum));
/*
* Return the sum...
*/
- return (httpMD5String(sum, md5));
+ return ((char *)cupsHashString(sum, sizeof(sum), md5, 33));
}
@@ -57,6 +57,8 @@ httpMD5(const char *username, /* I - User name */
* 'httpMD5Final()' - Combine the MD5 sum of the username, group, and password
* with the server-supplied nonce value, method, and
* request-uri.
+ *
+ * @deprecated@
*/
char * /* O - New sum */
@@ -65,7 +67,6 @@ httpMD5Final(const char *nonce, /* I - Server nonce value */
const char *resource, /* I - Resource path */
char md5[33]) /* IO - MD5 sum */
{
- _cups_md5_state_t state; /* MD5 state info */
unsigned char sum[16]; /* Sum data */
char line[1024]; /* Line of data */
char a2[33]; /* Hash of method and resource */
@@ -76,10 +77,8 @@ httpMD5Final(const char *nonce, /* I - Server nonce value */
*/
snprintf(line, sizeof(line), "%s:%s", method, resource);
- _cupsMD5Init(&state);
- _cupsMD5Append(&state, (unsigned char *)line, (int)strlen(line));
- _cupsMD5Finish(&state, sum);
- httpMD5String(sum, a2);
+ cupsHashData("md5", (unsigned char *)line, strlen(line), sum, sizeof(sum));
+ cupsHashString(sum, sizeof(sum), a2, sizeof(a2));
/*
* Then combine A1 (MD5 of username, realm, and password) with the nonce
@@ -88,17 +87,16 @@ httpMD5Final(const char *nonce, /* I - Server nonce value */
*/
snprintf(line, sizeof(line), "%s:%s:%s", md5, nonce, a2);
+ cupsHashData("md5", (unsigned char *)line, strlen(line), sum, sizeof(sum));
- _cupsMD5Init(&state);
- _cupsMD5Append(&state, (unsigned char *)line, (int)strlen(line));
- _cupsMD5Finish(&state, sum);
-
- return (httpMD5String(sum, md5));
+ return ((char *)cupsHashString(sum, sizeof(sum), md5, 33));
}
/*
* 'httpMD5String()' - Convert an MD5 sum to a character string.
+ *
+ * @deprecated@
*/
char * /* O - MD5 sum in hex */
@@ -106,23 +104,5 @@ httpMD5String(const unsigned char *sum, /* I - MD5 sum data */
char md5[33])
/* O - MD5 sum in hex */
{
- int i; /* Looping var */
- char *md5ptr; /* Pointer into MD5 string */
- static const char hex[] = "0123456789abcdef";
- /* Hex digits */
-
-
- /*
- * Convert the MD5 sum to hexadecimal...
- */
-
- for (i = 16, md5ptr = md5; i > 0; i --, sum ++)
- {
- *md5ptr++ = hex[*sum >> 4];
- *md5ptr++ = hex[*sum & 15];
- }
-
- *md5ptr = '\0';
-
- return (md5);
+ return ((char *)cupsHashString(sum, 16, md5, 33));
}
diff --git a/cups/ppd-cache.c b/cups/ppd-cache.c
index 925ab805..9ed946e6 100644
--- a/cups/ppd-cache.c
+++ b/cups/ppd-cache.c
@@ -1,7 +1,7 @@
/*
* PPD cache implementation for CUPS.
*
- * Copyright 2010-2017 by Apple Inc.
+ * Copyright © 2010-2018 by Apple Inc.
*
* These coded instructions, statements, and computer programs are the
* property of Apple Inc. and are protected by Federal copyright
@@ -3105,8 +3105,8 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
cupsFilePrintf(fp, "*Manufacturer: \"%s\"\n", make);
cupsFilePrintf(fp, "*ModelName: \"%s\"\n", model);
cupsFilePrintf(fp, "*Product: \"(%s)\"\n", model);
- cupsFilePrintf(fp, "*NickName: \"%s\"\n", model);
- cupsFilePrintf(fp, "*ShortNickName: \"%s\"\n", model);
+ cupsFilePrintf(fp, "*NickName: \"%s - IPP Everywhere\"\n", model);
+ cupsFilePrintf(fp, "*ShortNickName: \"%s - IPP Everywhere\"\n", model);
if ((attr = ippFindAttribute(response, "color-supported", IPP_TAG_BOOLEAN)) != NULL && ippGetBoolean(attr, 0))
cupsFilePuts(fp, "*ColorDevice: True\n");
@@ -3118,6 +3118,41 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
cupsFilePuts(fp, "*cupsLanguages: \"en\"\n");
/*
+ * Password/PIN printing...
+ */
+
+ if ((attr = ippFindAttribute(response, "job-password-supported", IPP_TAG_INTEGER)) != NULL)
+ {
+ char pattern[33]; /* Password pattern */
+ int maxlen = ippGetInteger(attr, 0);
+ /* Maximum length */
+ const char *repertoire = ippGetString(ippFindAttribute(response, "job-password-repertoire-configured", IPP_TAG_KEYWORD), 0, NULL);
+ /* Type of password */
+
+ if (maxlen > (int)(sizeof(pattern) - 1))
+ maxlen = (int)sizeof(pattern) - 1;
+
+ if (!repertoire || !strcmp(repertoire, "iana_us-ascii_digits"))
+ memset(pattern, '1', (size_t)maxlen);
+ else if (!strcmp(repertoire, "iana_us-ascii_letters"))
+ memset(pattern, 'A', (size_t)maxlen);
+ else if (!strcmp(repertoire, "iana_us-ascii_complex"))
+ memset(pattern, 'C', (size_t)maxlen);
+ else if (!strcmp(repertoire, "iana_us-ascii_any"))
+ memset(pattern, '.', (size_t)maxlen);
+ else if (!strcmp(repertoire, "iana_utf-8_digits"))
+ memset(pattern, 'N', (size_t)maxlen);
+ else if (!strcmp(repertoire, "iana_utf-8_letters"))
+ memset(pattern, 'U', (size_t)maxlen);
+ else
+ memset(pattern, '*', (size_t)maxlen);
+
+ pattern[maxlen] = '\0';
+
+ cupsFilePrintf(fp, "*cupsPassword: \"%s\"\n", pattern);
+ }
+
+ /*
* Filters...
*/
@@ -3125,24 +3160,28 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
{
is_apple = ippContainsString(attr, "image/urf");
is_pdf = ippContainsString(attr, "application/pdf");
- is_pwg = ippContainsString(attr, "image/pwg-raster");
+ is_pwg = ippContainsString(attr, "image/pwg-raster") && !is_apple;
- for (i = 0, count = ippGetCount(attr); i < count; i ++)
+ if (ippContainsString(attr, "image/jpeg"))
+ cupsFilePuts(fp, "*cupsFilter2: \"image/jpeg image/jpeg 0 -\"\n");
+ if (ippContainsString(attr, "image/png"))
+ cupsFilePuts(fp, "*cupsFilter2: \"image/png image/png 0 -\"\n");
+ if (is_pdf)
{
- const char *format = ippGetString(attr, i, NULL);
- /* PDL */
-
/*
- * Write cupsFilter2 lines for supported formats...
+ * Don't locally filter PDF content when printing to a CUPS shared
+ * printer, otherwise the options will be applied twice...
*/
- if (!_cups_strcasecmp(format, "application/pdf"))
+ if (ippContainsString(attr, "application/vnd.cups-pdf"))
+ cupsFilePuts(fp, "*cupsFilter2: \"application/pdf application/pdf 0 -\"\n");
+ else
cupsFilePuts(fp, "*cupsFilter2: \"application/vnd.cups-pdf application/pdf 10 -\"\n");
- else if (!_cups_strcasecmp(format, "image/jpeg") || !_cups_strcasecmp(format, "image/png"))
- cupsFilePrintf(fp, "*cupsFilter2: \"%s %s 0 -\"\n", format, format);
- else if (!_cups_strcasecmp(format, "image/pwg-raster") || !_cups_strcasecmp(format, "image/urf"))
- cupsFilePrintf(fp, "*cupsFilter2: \"%s %s 100 -\"\n", format, format);
}
+ if (is_apple)
+ cupsFilePuts(fp, "*cupsFilter2: \"image/urf image/urf 100 -\"\n");
+ if (is_pwg)
+ cupsFilePuts(fp, "*cupsFilter2: \"image/pwg-raster image/pwg-raster 100 -\"\n");
}
if (!is_apple && !is_pdf && !is_pwg)
@@ -3414,7 +3453,8 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
for (j = 0; j < (int)(sizeof(sources) / sizeof(sources[0])); j ++)
if (!strcmp(sources[j][0], ppdname))
{
- cupsFilePrintf(fp, "*InputSlot %s/%s: \"<</MediaPosition %d>>setpagedevice\"\n", ppdname, _cupsLangString(lang, sources[j][1]), j);
+ cupsFilePrintf(fp, "*InputSlot %s: \"<</MediaPosition %d>>setpagedevice\"\n", ppdname, j);
+ cupsFilePrintf(fp, "*%s.InputSlot %s/%s: \"\"\n", lang->language, ppdname, _cupsLangString(lang, sources[j][1]));
break;
}
}
@@ -3590,9 +3630,14 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
break;
if (j < (int)(sizeof(media_types) / sizeof(media_types[0])))
- cupsFilePrintf(fp, "*MediaType %s/%s: \"<</MediaType(%s)>>setpagedevice\"\n", ppdname, _cupsLangString(lang, media_types[j][1]), ppdname);
+ {
+ cupsFilePrintf(fp, "*MediaType %s: \"<</MediaType(%s)>>setpagedevice\"\n", ppdname, ppdname);
+ cupsFilePrintf(fp, "*%s.MediaType %s/%s: \"\"\n", lang->language, ppdname, _cupsLangString(lang, media_types[j][1]));
+ }
else
+ {
cupsFilePrintf(fp, "*MediaType %s/%s: \"<</MediaType(%s)>>setpagedevice\"\n", ppdname, keyword, ppdname);
+ }
}
cupsFilePuts(fp, "*CloseUI: *MediaType\n");
}
@@ -3618,10 +3663,11 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
if (!strcasecmp(keyword, "black_1") || !strcmp(keyword, "bi-level") || !strcmp(keyword, "process-bi-level"))
{
if (!default_color)
- cupsFilePrintf(fp, "*OpenUI *ColorModel/%s: PickOne\n"
- "*OrderDependency: 10 AnySetup *ColorModel\n", _cupsLangString(lang, _("Color Mode")));
+ cupsFilePrintf(fp, "*OpenUI *ColorModel: PickOne\n"
+ "*OrderDependency: 10 AnySetup *ColorModel\n"
+ "*%s.Translation ColorModel/%s: \"\"\n", lang->language, _cupsLangString(lang, _("Color Mode")));
- cupsFilePrintf(fp, "*ColorModel FastGray/%s: \"<</cupsColorSpace 3/cupsBitsPerColor 1/cupsColorOrder 0/cupsCompression 0>>setpagedevice\"\n", _cupsLangString(lang, _("Fast Grayscale")));
+ cupsFilePrintf(fp, "*ColorModel FastGray: \"<</cupsColorSpace 3/cupsBitsPerColor 1/cupsColorOrder 0/cupsCompression 0>>setpagedevice\"\n*%s.ColorModel FastGray/%s: \"\"\n", lang->language, _cupsLangString(lang, _("Fast Grayscale")));
if (!default_color)
default_color = "FastGray";
@@ -3629,10 +3675,11 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
else if (!strcasecmp(keyword, "sgray_8") || !strcmp(keyword, "W8") || !strcmp(keyword, "monochrome") || !strcmp(keyword, "process-monochrome"))
{
if (!default_color)
- cupsFilePrintf(fp, "*OpenUI *ColorModel/%s: PickOne\n"
- "*OrderDependency: 10 AnySetup *ColorModel\n", _cupsLangString(lang, _("Color Mode")));
+ cupsFilePrintf(fp, "*OpenUI *ColorModel: PickOne\n"
+ "*OrderDependency: 10 AnySetup *ColorModel\n"
+ "*%s.Translation ColorModel/%s: \"\"\n", lang->language, _cupsLangString(lang, _("Color Mode")));
- cupsFilePrintf(fp, "*ColorModel Gray/%s: \"<</cupsColorSpace 18/cupsBitsPerColor 8/cupsColorOrder 0/cupsCompression 0>>setpagedevice\"\n", _cupsLangString(lang, _("Grayscale")));
+ cupsFilePrintf(fp, "*ColorModel Gray: \"<</cupsColorSpace 18/cupsBitsPerColor 8/cupsColorOrder 0/cupsCompression 0>>setpagedevice\"\n*%s.ColorModel Gray/%s: \"\"\n", lang->language, _cupsLangString(lang, _("Grayscale")));
if (!default_color || !strcmp(default_color, "FastGray"))
default_color = "Gray";
@@ -3640,20 +3687,22 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
else if (!strcasecmp(keyword, "srgb_8") || !strcmp(keyword, "SRGB24") || !strcmp(keyword, "color"))
{
if (!default_color)
- cupsFilePrintf(fp, "*OpenUI *ColorModel/%s: PickOne\n"
- "*OrderDependency: 10 AnySetup *ColorModel\n", _cupsLangString(lang, _("Color Mode")));
+ cupsFilePrintf(fp, "*OpenUI *ColorModel: PickOne\n"
+ "*OrderDependency: 10 AnySetup *ColorModel\n"
+ "*%s.Translation ColorModel/%s: \"\"\n", lang->language, _cupsLangString(lang, _("Color Mode")));
- cupsFilePrintf(fp, "*ColorModel RGB/%s: \"<</cupsColorSpace 19/cupsBitsPerColor 8/cupsColorOrder 0/cupsCompression 0>>setpagedevice\"\n", _cupsLangString(lang, _("Color")));
+ cupsFilePrintf(fp, "*ColorModel RGB: \"<</cupsColorSpace 19/cupsBitsPerColor 8/cupsColorOrder 0/cupsCompression 0>>setpagedevice\"\n*%s.ColorModel RGB/%s: \"\"\n", lang->language, _cupsLangString(lang, _("Color")));
default_color = "RGB";
}
else if (!strcasecmp(keyword, "adobe-rgb_16") || !strcmp(keyword, "ADOBERGB48"))
{
if (!default_color)
- cupsFilePrintf(fp, "*OpenUI *ColorModel/%s: PickOne\n"
- "*OrderDependency: 10 AnySetup *ColorModel\n", _cupsLangString(lang, _("Color Mode")));
+ cupsFilePrintf(fp, "*OpenUI *ColorModel: PickOne\n"
+ "*OrderDependency: 10 AnySetup *ColorModel\n"
+ "*%s.Translation ColorModel/%s: \"\"\n", lang->language, _cupsLangString(lang, _("Color Mode")));
- cupsFilePrintf(fp, "*ColorModel AdobeRGB/%s: \"<</cupsColorSpace 20/cupsBitsPerColor 16/cupsColorOrder 0/cupsCompression 0>>setpagedevice\"\n", _cupsLangString(lang, _("Deep Color")));
+ cupsFilePrintf(fp, "*ColorModel AdobeRGB: \"<</cupsColorSpace 20/cupsBitsPerColor 16/cupsColorOrder 0/cupsCompression 0>>setpagedevice\"\n*%s.ColorModel AdobeRGB/%s: \"\"\n", lang->language, _cupsLangString(lang, _("Deep Color")));
if (!default_color)
default_color = "AdobeRGB";
@@ -3673,13 +3722,17 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
if ((attr = ippFindAttribute(response, "sides-supported", IPP_TAG_KEYWORD)) != NULL && ippContainsString(attr, "two-sided-long-edge"))
{
- cupsFilePrintf(fp, "*OpenUI *Duplex/%s: PickOne\n"
+ cupsFilePrintf(fp, "*OpenUI *Duplex: PickOne\n"
"*OrderDependency: 10 AnySetup *Duplex\n"
+ "*%s.Translation Duplex/%s: \"\"\n"
"*DefaultDuplex: None\n"
- "*Duplex None/%s: \"<</Duplex false>>setpagedevice\"\n"
- "*Duplex DuplexNoTumble/%s: \"<</Duplex true/Tumble false>>setpagedevice\"\n"
- "*Duplex DuplexTumble/%s: \"<</Duplex true/Tumble true>>setpagedevice\"\n"
- "*CloseUI: *Duplex\n", _cupsLangString(lang, _("2-Sided Printing")), _cupsLangString(lang, _("Off (1-Sided)")), _cupsLangString(lang, _("Long-Edge (Portrait)")), _cupsLangString(lang, _("Short-Edge (Landscape)")));
+ "*Duplex None: \"<</Duplex false>>setpagedevice\"\n"
+ "*%s.Duplex None/%s: \"\"\n"
+ "*Duplex DuplexNoTumble: \"<</Duplex true/Tumble false>>setpagedevice\"\n"
+ "*%s.Duplex DuplexNoTumble/%s: \"\"\n"
+ "*Duplex DuplexTumble: \"<</Duplex true/Tumble true>>setpagedevice\"\n"
+ "*%s.Duplex DuplexTumble/%s: \"\"\n"
+ "*CloseUI: *Duplex\n", lang->language, _cupsLangString(lang, _("2-Sided Printing")), lang->language, _cupsLangString(lang, _("Off (1-Sided)")), lang->language, _cupsLangString(lang, _("Long-Edge (Portrait)")), lang->language, _cupsLangString(lang, _("Short-Edge (Landscape)")));
if ((attr = ippFindAttribute(response, "urf-supported", IPP_TAG_KEYWORD)) != NULL)
{
@@ -3737,6 +3790,12 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
if ((attr = ippFindAttribute(response, "output-bin-supported", IPP_TAG_ZERO)) != NULL && (count = ippGetCount(attr)) > 1)
{
+ ipp_attribute_t *trays = ippFindAttribute(response, "printer-output-tray", IPP_TAG_STRING);
+ /* printer-output-tray attribute, if any */
+ const char *tray_ptr; /* printer-output-tray value */
+ int tray_len; /* Len of printer-output-tray value */
+ char tray[IPP_MAX_OCTETSTRING];
+ /* printer-output-tray string value */
static const char * const output_bins[][2] =
{ /* "output-bin" strings */
{ "auto", _("Automatic") },
@@ -3787,6 +3846,11 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
cupsFilePrintf(fp, "*OpenUI *OutputBin: PickOne\n"
"*OrderDependency: 10 AnySetup *OutputBin\n"
"*DefaultOutputBin: %s\n", ppdname);
+ if (!strcmp(ppdname, "FaceUp"))
+ cupsFilePuts(fp, "*DefaultOutputOrder: Reverse\n");
+ else
+ cupsFilePuts(fp, "*DefaultOutputOrder: Normal\n");
+
for (i = 0; i < (int)(sizeof(output_bins) / sizeof(output_bins[0])); i ++)
{
if (!ippContainsString(attr, output_bins[i][0]))
@@ -3794,7 +3858,26 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
pwg_ppdize_name(output_bins[i][0], ppdname, sizeof(ppdname));
- cupsFilePrintf(fp, "*OutputBin %s/%s: \"\"\n", ppdname, _cupsLangString(lang, output_bins[i][1]));
+ cupsFilePrintf(fp, "*OutputBin %s: \"\"\n", ppdname);
+ cupsFilePrintf(fp, "*%s.OutputBin %s/%s: \"\"\n", lang->language, ppdname, _cupsLangString(lang, output_bins[i][1]));
+
+ if ((tray_ptr = ippGetOctetString(trays, i, &tray_len)) != NULL)
+ {
+ if (tray_len >= (int)sizeof(tray))
+ tray_len = (int)sizeof(tray) - 1;
+
+ memcpy(tray, tray_ptr, (size_t)tray_len);
+ tray[tray_len] = '\0';
+
+ if (strstr(tray, "stackingorder=lastToFirst;"))
+ cupsFilePrintf(fp, "*PageStackOrder %s: Reverse\n", ppdname);
+ else
+ cupsFilePrintf(fp, "*PageStackOrder %s: Normal\n", ppdname);
+ }
+ else if (!strcmp(ppdname, "FaceUp"))
+ cupsFilePrintf(fp, "*PageStackOrder %s: Reverse\n", ppdname);
+ else
+ cupsFilePrintf(fp, "*PageStackOrder %s: Normal\n", ppdname);
}
cupsFilePuts(fp, "*CloseUI: *OutputBin\n");
}
@@ -3832,10 +3915,12 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
if (i < count)
{
- cupsFilePrintf(fp, "*OpenUI *StapleLocation/%s: PickOne\n", _cupsLangString(lang, _("Staple")));
+ cupsFilePuts(fp, "*OpenUI *StapleLocation: PickOne\n");
cupsFilePuts(fp, "*OrderDependency: 10 AnySetup *StapleLocation\n");
+ cupsFilePrintf(fp, "*%s.Translation StapleLocation/%s: \"\"\n", lang->language, _cupsLangString(lang, _("Staple")));
cupsFilePuts(fp, "*DefaultStapleLocation: None\n");
- cupsFilePrintf(fp, "*StapleLocation None/%s: \"\"\n", _cupsLangString(lang, _("None")));
+ cupsFilePuts(fp, "*StapleLocation None: \"\"\n");
+ cupsFilePrintf(fp, "*%s.StapleLocation None/%s: \"\"\n", lang->language, _cupsLangString(lang, _("None")));
for (; i < count; i ++)
{
@@ -3854,7 +3939,8 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
{
if (!strcmp(finishings[j][0], name))
{
- cupsFilePrintf(fp, "*StapleLocation %s/%s: \"\"\n", name, _cupsLangString(lang, finishings[j][1]));
+ cupsFilePrintf(fp, "*StapleLocation %s: \"\"\n", name);
+ cupsFilePrintf(fp, "*%s.StapleLocation %s/%s: \"\"\n", lang->language, name, _cupsLangString(lang, finishings[j][1]));
cupsFilePrintf(fp, "*cupsIPPFinishings %d/%s: \"*StapleLocation %s\"\n", value, name, name);
break;
}
@@ -3879,10 +3965,12 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
if (i < count)
{
- cupsFilePrintf(fp, "*OpenUI *FoldType/%s: PickOne\n", _cupsLangString(lang, _("Fold")));
+ cupsFilePuts(fp, "*OpenUI *FoldType: PickOne\n");
cupsFilePuts(fp, "*OrderDependency: 10 AnySetup *FoldType\n");
+ cupsFilePrintf(fp, "*%s.Translation FoldType/%s: \"\"\n", lang->language, _cupsLangString(lang, _("Fold")));
cupsFilePuts(fp, "*DefaultFoldType: None\n");
- cupsFilePrintf(fp, "*FoldType None/%s: \"\"\n", _cupsLangString(lang, _("None")));
+ cupsFilePuts(fp, "*FoldType None: \"\"\n");
+ cupsFilePrintf(fp, "*%s.FoldType None/%s: \"\"\n", lang->language, _cupsLangString(lang, _("None")));
for (; i < count; i ++)
{
@@ -3901,7 +3989,8 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
{
if (!strcmp(finishings[j][0], name))
{
- cupsFilePrintf(fp, "*FoldType %s/%s: \"\"\n", name, _cupsLangString(lang, finishings[j][1]));
+ cupsFilePrintf(fp, "*FoldType %s: \"\"\n", name);
+ cupsFilePrintf(fp, "*%s.FoldType %s/%s: \"\"\n", lang->language, name, _cupsLangString(lang, finishings[j][1]));
cupsFilePrintf(fp, "*cupsIPPFinishings %d/%s: \"*FoldType %s\"\n", value, name, name);
break;
}
@@ -3926,10 +4015,12 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
if (i < count)
{
- cupsFilePrintf(fp, "*OpenUI *PunchMedia/%s: PickOne\n", _cupsLangString(lang, _("Punch")));
+ cupsFilePuts(fp, "*OpenUI *PunchMedia: PickOne\n");
cupsFilePuts(fp, "*OrderDependency: 10 AnySetup *PunchMedia\n");
+ cupsFilePrintf(fp, "*%s.Translation PunchMedia/%s: \"\"\n", lang->language, _cupsLangString(lang, _("Punch")));
cupsFilePuts(fp, "*DefaultPunchMedia: None\n");
- cupsFilePrintf(fp, "*PunchMedia None/%s: \"\"\n", _cupsLangString(lang, _("None")));
+ cupsFilePuts(fp, "*PunchMedia None: \"\"\n");
+ cupsFilePrintf(fp, "*%s.PunchMedia None/%s: \"\"\n", lang->language, _cupsLangString(lang, _("None")));
for (i = 0; i < count; i ++)
{
@@ -3948,7 +4039,8 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
{
if (!strcmp(finishings[j][0], name))
{
- cupsFilePrintf(fp, "*PunchMedia %s/%s: \"\"\n", name, _cupsLangString(lang, finishings[j][1]));
+ cupsFilePrintf(fp, "*PunchMedia %s: \"\"\n", name);
+ cupsFilePrintf(fp, "*%s.PunchMedia %s/%s: \"\"\n", lang->language, name, _cupsLangString(lang, finishings[j][1]));
cupsFilePrintf(fp, "*cupsIPPFinishings %d/%s: \"*PunchMedia %s\"\n", value, name, name);
break;
}
@@ -3964,8 +4056,9 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
if (ippContainsInteger(attr, IPP_FINISHINGS_BOOKLET_MAKER))
{
- cupsFilePrintf(fp, "*OpenUI *Booklet/%s: Boolean\n", _cupsLangString(lang, _("Booklet")));
+ cupsFilePuts(fp, "*OpenUI *Booklet: Boolean\n");
cupsFilePuts(fp, "*OrderDependency: 10 AnySetup *Booklet\n");
+ cupsFilePrintf(fp, "*%s.Translation Booklet/%s: \"\"\n", lang->language, _cupsLangString(lang, _("Booklet")));
cupsFilePuts(fp, "*DefaultBooklet: False\n");
cupsFilePuts(fp, "*Booklet False: \"\"\n");
cupsFilePuts(fp, "*Booklet True: \"\"\n");
@@ -4018,16 +4111,19 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
cupsFilePrintf(fp, "*DefaultResolution: %ddpi\n", lowdpi);
- cupsFilePrintf(fp, "*OpenUI *cupsPrintQuality/%s: PickOne\n"
- "*OrderDependency: 10 AnySetup *cupsPrintQuality\n"
- "*DefaultcupsPrintQuality: Normal\n", _cupsLangString(lang, _("Print Quality")));
+ cupsFilePrintf(fp, "*OpenUI *cupsPrintQuality: PickOne\n"
+ "*OrderDependency: 10 AnySetup *cupsPrintQuality\n"
+ "*%s.Translation cupsPrintQuality/%s: \"\"\n"
+ "*DefaultcupsPrintQuality: Normal\n", lang->language, _cupsLangString(lang, _("Print Quality")));
if ((lowdpi & 1) == 0)
- cupsFilePrintf(fp, "*cupsPrintQuality Draft/%s: \"<</HWResolution[%d %d]>>setpagedevice\"\n", _cupsLangString(lang, _("Draft")), lowdpi, lowdpi / 2);
+ cupsFilePrintf(fp, "*cupsPrintQuality Draft: \"<</HWResolution[%d %d]>>setpagedevice\"\n*%s.cupsPrintQuality Draft/%s: \"\"\n", lowdpi, lowdpi / 2, lang->language, _cupsLangString(lang, _("Draft")));
else if (ippContainsInteger(quality, IPP_QUALITY_DRAFT))
- cupsFilePrintf(fp, "*cupsPrintQuality Draft/%s: \"<</HWResolution[%d %d]>>setpagedevice\"\n", _cupsLangString(lang, _("Draft")), lowdpi, lowdpi);
- cupsFilePrintf(fp, "*cupsPrintQuality Normal/%s: \"<</HWResolution[%d %d]>>setpagedevice\"\n", _cupsLangString(lang, _("Normal")), lowdpi, lowdpi);
+ cupsFilePrintf(fp, "*cupsPrintQuality Draft: \"<</HWResolution[%d %d]>>setpagedevice\"\n*%s.cupsPrintQuality Draft/%s: \"\"\n", lowdpi, lowdpi, lang->language, _cupsLangString(lang, _("Draft")));
+
+ cupsFilePrintf(fp, "*cupsPrintQuality Normal: \"<</HWResolution[%d %d]>>setpagedevice\"\n*%s.cupsPrintQuality Normal/%s: \"\"\n", lowdpi, lowdpi, lang->language, _cupsLangString(lang, _("Normal")));
+
if (hidpi > lowdpi || ippContainsInteger(quality, IPP_QUALITY_HIGH))
- cupsFilePrintf(fp, "*cupsPrintQuality High/%s: \"<</HWResolution[%d %d]>>setpagedevice\"\n", _cupsLangString(lang, _("High")), hidpi, hidpi);
+ cupsFilePrintf(fp, "*cupsPrintQuality High: \"<</HWResolution[%d %d]>>setpagedevice\"\n*%s.cupsPrintQuality High/%s: \"\"\n", hidpi, hidpi, lang->language, _cupsLangString(lang, _("High")));
cupsFilePuts(fp, "*CloseUI: *cupsPrintQuality\n");
}
}
@@ -4041,7 +4137,8 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
if (count > (int)(sizeof(resolutions) / sizeof(resolutions[0])))
count = (int)(sizeof(resolutions) / sizeof(resolutions[0]));
- for (i = 0; i < count; i ++)
+ resolutions[0] = 0; /* Not in loop to silence Clang static analyzer... */
+ for (i = 1; i < count; i ++)
resolutions[i] = i;
for (i = 0; i < (count - 1); i ++)
@@ -4076,20 +4173,26 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
pwg_ppdize_resolution(attr, resolutions[count / 2], &xres, &yres, ppdname, sizeof(ppdname));
cupsFilePrintf(fp, "*DefaultResolution: %s\n", ppdname);
- cupsFilePrintf(fp, "*OpenUI *cupsPrintQuality/%s: PickOne\n"
- "*OrderDependency: 10 AnySetup *cupsPrintQuality\n"
- "*DefaultcupsPrintQuality: Normal\n", _cupsLangString(lang, _("Print Quality")));
+ cupsFilePrintf(fp, "*OpenUI *cupsPrintQuality: PickOne\n"
+ "*OrderDependency: 10 AnySetup *cupsPrintQuality\n"
+ "*%s.Translation cupsPrintQuality/%s: \"\"\n"
+ "*DefaultcupsPrintQuality: Normal\n", lang->language, _cupsLangString(lang, _("Print Quality")));
if (count > 2 || ippContainsInteger(quality, IPP_QUALITY_DRAFT))
{
pwg_ppdize_resolution(attr, resolutions[0], &xres, &yres, NULL, 0);
- cupsFilePrintf(fp, "*cupsPrintQuality Draft/%s: \"<</HWResolution[%d %d]>>setpagedevice\"\n", _cupsLangString(lang, _("Draft")), xres, yres);
+ cupsFilePrintf(fp, "*cupsPrintQuality Draft: \"<</HWResolution[%d %d]>>setpagedevice\"\n", xres, yres);
+ cupsFilePrintf(fp, "*%s.cupsPrintQuality Draft/%s: \"\"\n", lang->language, _cupsLangString(lang, _("Draft")));
}
+
pwg_ppdize_resolution(attr, resolutions[count / 2], &xres, &yres, NULL, 0);
- cupsFilePrintf(fp, "*cupsPrintQuality Normal/%s: \"<</HWResolution[%d %d]>>setpagedevice\"\n", _cupsLangString(lang, _("Normal")), xres, yres);
+ cupsFilePrintf(fp, "*cupsPrintQuality Normal: \"<</HWResolution[%d %d]>>setpagedevice\"\n", xres, yres);
+ cupsFilePrintf(fp, "*%s.cupsPrintQuality Normal/%s: \"\"\n", lang->language, _cupsLangString(lang, _("Normal")));
+
if (count > 1 || ippContainsInteger(quality, IPP_QUALITY_HIGH))
{
pwg_ppdize_resolution(attr, resolutions[count - 1], &xres, &yres, NULL, 0);
- cupsFilePrintf(fp, "*cupsPrintQuality High/%s: \"<</HWResolution[%d %d]>>setpagedevice\"\n", _cupsLangString(lang, _("High")), xres, yres);
+ cupsFilePrintf(fp, "*cupsPrintQuality High: \"<</HWResolution[%d %d]>>setpagedevice\"\n", xres, yres);
+ cupsFilePrintf(fp, "*%s.cupsPrintQuality High/%s: \"\"\n", lang->language, _cupsLangString(lang, _("High")));
}
cupsFilePuts(fp, "*CloseUI: *cupsPrintQuality\n");
@@ -4110,14 +4213,17 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
cupsFilePrintf(fp, "*DefaultResolution: %s\n", ppdname);
- cupsFilePrintf(fp, "*OpenUI *cupsPrintQuality/%s: PickOne\n"
+ cupsFilePrintf(fp, "*OpenUI *cupsPrintQuality: PickOne\n"
"*OrderDependency: 10 AnySetup *cupsPrintQuality\n"
- "*DefaultcupsPrintQuality: Normal\n", _cupsLangString(lang, _("Print Quality")));
+ "*%s.Translation cupsPrintQuality/%s: \"\"\n"
+ "*DefaultcupsPrintQuality: Normal\n", lang->language, _cupsLangString(lang, _("Print Quality")));
if (ippContainsInteger(quality, IPP_QUALITY_DRAFT))
- cupsFilePrintf(fp, "*cupsPrintQuality Draft/%s: \"<</HWResolution[%d %d]>>setpagedevice\"\n", _cupsLangString(lang, _("Draft")), xres, yres);
- cupsFilePrintf(fp, "*cupsPrintQuality Normal/%s: \"<</HWResolution[%d %d]>>setpagedevice\"\n", _cupsLangString(lang, _("Normal")), xres, yres);
+ cupsFilePrintf(fp, "*cupsPrintQuality Draft: \"<</HWResolution[%d %d]>>setpagedevice\"\n*%s.cupsPrintQuality Draft/%s: \"\"\n", xres, yres, lang->language, _cupsLangString(lang, _("Draft")));
+
+ cupsFilePrintf(fp, "*cupsPrintQuality Normal: \"<</HWResolution[%d %d]>>setpagedevice\"\n*%s.cupsPrintQuality Normal/%s: \"\"\n", xres, yres, lang->language, _cupsLangString(lang, _("Normal")));
+
if (ippContainsInteger(quality, IPP_QUALITY_HIGH))
- cupsFilePrintf(fp, "*cupsPrintQuality High/%s: \"<</HWResolution[%d %d]>>setpagedevice\"\n", _cupsLangString(lang, _("High")), xres, yres);
+ cupsFilePrintf(fp, "*cupsPrintQuality High: \"<</HWResolution[%d %d]>>setpagedevice\"\n*%s.cupsPrintQuality High/%s: \"\"\n", xres, yres, lang->language, _cupsLangString(lang, _("High")));
cupsFilePuts(fp, "*CloseUI: *cupsPrintQuality\n");
}
diff --git a/cups/ppd-conflicts.c b/cups/ppd-conflicts.c
index 8f875a57..24330ecb 100644
--- a/cups/ppd-conflicts.c
+++ b/cups/ppd-conflicts.c
@@ -1,7 +1,7 @@
/*
* Option conflict management routines for CUPS.
*
- * Copyright 2007-2015 by Apple Inc.
+ * Copyright 2007-2018 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
@@ -29,7 +29,6 @@
enum
{
- _PPD_NORMAL_CONSTRAINTS,
_PPD_OPTION_CONSTRAINTS,
_PPD_INSTALLABLE_CONSTRAINTS,
_PPD_ALL_CONSTRAINTS
@@ -998,7 +997,7 @@ ppd_test_constraints(
if (!consts->installable && which == _PPD_INSTALLABLE_CONSTRAINTS)
continue; /* Skip non-installable option constraint */
- if (which == _PPD_OPTION_CONSTRAINTS && option)
+ if ((which == _PPD_OPTION_CONSTRAINTS || which == _PPD_INSTALLABLE_CONSTRAINTS) && option)
{
/*
* Skip constraints that do not involve the current option...
diff --git a/cups/ppd-emit.c b/cups/ppd-emit.c
index 36e5bcaf..4b153aca 100644
--- a/cups/ppd-emit.c
+++ b/cups/ppd-emit.c
@@ -21,11 +21,11 @@
#include "cups-private.h"
#include "ppd.h"
-#if defined(WIN32) || defined(__EMX__)
+#if defined(_WIN32) || defined(__EMX__)
# include <io.h>
#else
# include <unistd.h>
-#endif /* WIN32 || __EMX__ */
+#endif /* _WIN32 || __EMX__ */
/*
@@ -328,11 +328,11 @@ ppdEmitFd(ppd_file_t *ppd, /* I - PPD file record */
while (buflength > 0)
{
-#ifdef WIN32
+#ifdef _WIN32
if ((bytes = (ssize_t)write(fd, bufptr, (unsigned)buflength)) < 0)
#else
if ((bytes = write(fd, bufptr, buflength)) < 0)
-#endif /* WIN32 */
+#endif /* _WIN32 */
{
if (errno == EAGAIN || errno == EINTR)
continue;
diff --git a/cups/ppd-localize.c b/cups/ppd-localize.c
index ed75bf86..9537ef5b 100644
--- a/cups/ppd-localize.c
+++ b/cups/ppd-localize.c
@@ -1,7 +1,7 @@
/*
* PPD localization routines for CUPS.
*
- * Copyright 2007-2017 by Apple Inc.
+ * Copyright 2007-2018 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
@@ -277,7 +277,7 @@ ppdLocalizeIPPReason(
if (!locattr)
{
- if (lang && (!scheme || !strcmp(scheme, "text")))
+ if (lang && (!scheme || !strcmp(scheme, "text")) && strcmp(reason, "none"))
{
/*
* Try to localize a standard printer-state-reason keyword...
diff --git a/cups/ppd-util.c b/cups/ppd-util.c
index d0194c80..0974bae9 100644
--- a/cups/ppd-util.c
+++ b/cups/ppd-util.c
@@ -1,8 +1,8 @@
/*
* PPD utilities for CUPS.
*
- * Copyright 2007-2015 by Apple Inc.
- * Copyright 1997-2006 by Easy Software Products.
+ * Copyright © 2007-2018 by Apple Inc.
+ * Copyright © 1997-2006 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
* property of Apple Inc. and are protected by Federal copyright
@@ -21,11 +21,11 @@
#include "ppd-private.h"
#include <fcntl.h>
#include <sys/stat.h>
-#if defined(WIN32) || defined(__EMX__)
+#if defined(_WIN32) || defined(__EMX__)
# include <io.h>
#else
# include <unistd.h>
-#endif /* WIN32 || __EMX__ */
+#endif /* _WIN32 || __EMX__ */
/*
@@ -171,7 +171,7 @@ cupsGetPPD3(http_t *http, /* I - HTTP connection or @code CUPS_HTTP_DEFAUL
return (HTTP_STATUS_NOT_ACCEPTABLE);
}
-#ifndef WIN32
+#ifndef _WIN32
/*
* See if the PPD file is available locally...
*/
@@ -216,6 +216,27 @@ cupsGetPPD3(http_t *http, /* I - HTTP connection or @code CUPS_HTTP_DEFAUL
const char *tmpdir; /* TMPDIR environment variable */
struct timeval curtime; /* Current time */
+#ifdef __APPLE__
+ /*
+ * On macOS and iOS, the TMPDIR environment variable is not always the
+ * best location to place temporary files due to sandboxing. Instead,
+ * the confstr function should be called to get the proper per-user,
+ * per-process TMPDIR value.
+ */
+
+ char tmppath[1024]; /* Temporary directory */
+
+ if ((tmpdir = getenv("TMPDIR")) != NULL && access(tmpdir, W_OK))
+ tmpdir = NULL;
+
+ if (!tmpdir)
+ {
+ if (confstr(_CS_DARWIN_USER_TEMP_DIR, tmppath, sizeof(tmppath)))
+ tmpdir = tmppath;
+ else
+ tmpdir = "/private/tmp"; /* This should never happen */
+ }
+#else
/*
* Previously we put root temporary files in the default CUPS temporary
* directory under /var/spool/cups. However, since the scheduler cleans
@@ -224,11 +245,8 @@ cupsGetPPD3(http_t *http, /* I - HTTP connection or @code CUPS_HTTP_DEFAUL
*/
if ((tmpdir = getenv("TMPDIR")) == NULL)
-# ifdef __APPLE__
- tmpdir = "/private/tmp"; /* /tmp is a symlink to /private/tmp */
-# else
- tmpdir = "/tmp";
-# endif /* __APPLE__ */
+ tmpdir = "/tmp";
+#endif /* __APPLE__ */
/*
* Make the temporary name using the specified directory...
@@ -280,7 +298,7 @@ cupsGetPPD3(http_t *http, /* I - HTTP connection or @code CUPS_HTTP_DEFAUL
}
}
}
-#endif /* !WIN32 */
+#endif /* !_WIN32 */
/*
* Try finding a printer URI for this printer...
@@ -511,23 +529,16 @@ cups_get_printer_uri(
int depth) /* I - Depth of query */
{
int i; /* Looping var */
- int http_port; /* Port number */
- http_t *http2; /* Alternate HTTP connection */
ipp_t *request, /* IPP request */
*response; /* IPP response */
ipp_attribute_t *attr; /* Current attribute */
char uri[HTTP_MAX_URI], /* printer-uri attribute */
scheme[HTTP_MAX_URI], /* Scheme name */
- username[HTTP_MAX_URI], /* Username:password */
- classname[255], /* Temporary class name */
- http_hostname[HTTP_MAX_HOST];
- /* Hostname associated with connection */
+ username[HTTP_MAX_URI]; /* Username:password */
static const char * const requested_attrs[] =
{ /* Requested attributes */
- "device-uri",
"member-uris",
- "printer-uri-supported",
- "printer-type"
+ "printer-uri-supported"
};
@@ -550,15 +561,6 @@ cups_get_printer_uri(
DEBUG_printf(("5cups_get_printer_uri: printer-uri=\"%s\"", uri));
/*
- * Get the hostname and port number we are connected to...
- */
-
- httpGetHostname(http, http_hostname, sizeof(http_hostname));
- http_port = httpAddrPort(http->hostaddr);
-
- DEBUG_printf(("5cups_get_printer_uri: http_hostname=\"%s\"", http_hostname));
-
- /*
* Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following
* attributes:
*
@@ -582,31 +584,7 @@ cups_get_printer_uri(
if ((response = cupsDoRequest(http, request, resource)) != NULL)
{
- const char *device_uri = NULL; /* device-uri value */
-
- if ((attr = ippFindAttribute(response, "device-uri", IPP_TAG_URI)) != NULL)
- {
- device_uri = attr->values[0].string.text;
- DEBUG_printf(("5cups_get_printer_uri: device-uri=\"%s\"", device_uri));
- }
-
- if (device_uri &&
- (((!strncmp(device_uri, "ipp://", 6) || !strncmp(device_uri, "ipps://", 7)) &&
- (strstr(device_uri, "/printers/") != NULL || strstr(device_uri, "/classes/") != NULL)) ||
- ((strstr(device_uri, "._ipp.") != NULL || strstr(device_uri, "._ipps.") != NULL) &&
- !strcmp(device_uri + strlen(device_uri) - 5, "/cups"))))
- {
- /*
- * Statically-configured shared printer.
- */
-
- httpSeparateURI(HTTP_URI_CODING_ALL, _httpResolveURI(device_uri, uri, sizeof(uri), _HTTP_RESOLVE_DEFAULT, NULL, NULL), scheme, sizeof(scheme), username, sizeof(username), host, hostsize, port, resource, resourcesize);
- ippDelete(response);
-
- DEBUG_printf(("5cups_get_printer_uri: Resolved to host=\"%s\", port=%d, resource=\"%s\"", host, *port, resource));
- return (1);
- }
- else if ((attr = ippFindAttribute(response, "member-uris", IPP_TAG_URI)) != NULL)
+ if ((attr = ippFindAttribute(response, "member-uris", IPP_TAG_URI)) != NULL)
{
/*
* Get the first actual printer name in the class...
@@ -631,55 +609,6 @@ cups_get_printer_uri(
return (1);
}
}
-
- /*
- * No printers in this class - try recursively looking for a printer,
- * but not more than 3 levels deep...
- */
-
- if (depth < 3)
- {
- for (i = 0; i < attr->num_values; i ++)
- {
- httpSeparateURI(HTTP_URI_CODING_ALL, attr->values[i].string.text,
- scheme, sizeof(scheme), username, sizeof(username),
- host, hostsize, port, resource, resourcesize);
- if (!strncmp(resource, "/classes/", 9))
- {
- /*
- * Found a class! Connect to the right server...
- */
-
- if (!_cups_strcasecmp(http_hostname, host) && *port == http_port)
- http2 = http;
- else if ((http2 = httpConnect2(host, *port, NULL, AF_UNSPEC, cupsEncryption(), 1, 30000, NULL)) == NULL)
- {
- DEBUG_puts("8cups_get_printer_uri: Unable to connect to server");
-
- continue;
- }
-
- /*
- * Look up printers on that server...
- */
-
- strlcpy(classname, resource + 9, sizeof(classname));
-
- cups_get_printer_uri(http2, classname, host, hostsize, port,
- resource, resourcesize, depth + 1);
-
- /*
- * Close the connection as needed...
- */
-
- if (http2 != http)
- httpClose(http2);
-
- if (*host)
- return (1);
- }
- }
- }
}
else if ((attr = ippFindAttribute(response, "printer-uri-supported", IPP_TAG_URI)) != NULL)
{
diff --git a/cups/ppd.c b/cups/ppd.c
index 5bd839d1..5f27484a 100644
--- a/cups/ppd.c
+++ b/cups/ppd.c
@@ -1,7 +1,7 @@
/*
* PPD file routines for CUPS.
*
- * Copyright 2007-2017 by Apple Inc.
+ * Copyright 2007-2018 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
@@ -94,9 +94,9 @@ static ppd_group_t *ppd_get_group(ppd_file_t *ppd, const char *name,
cups_encoding_t encoding);
static ppd_option_t *ppd_get_option(ppd_group_t *group, const char *name);
static _ppd_globals_t *ppd_globals_alloc(void);
-#if defined(HAVE_PTHREAD_H) || defined(WIN32)
+#if defined(HAVE_PTHREAD_H) || defined(_WIN32)
static void ppd_globals_free(_ppd_globals_t *g);
-#endif /* HAVE_PTHREAD_H || WIN32 */
+#endif /* HAVE_PTHREAD_H || _WIN32 */
#ifdef HAVE_PTHREAD_H
static void ppd_globals_init(void);
#endif /* HAVE_PTHREAD_H */
@@ -333,7 +333,9 @@ ppdErrorString(ppd_status_t status) /* I - PPD status */
_("Bad custom parameter"),
_("Missing option keyword"),
_("Bad value string"),
- _("Missing CloseGroup")
+ _("Missing CloseGroup"),
+ _("Bad CloseUI/JCLCloseUI"),
+ _("Missing CloseUI/JCLCloseUI")
};
@@ -1542,8 +1544,29 @@ _ppdOpen(
choice->code = _cupsStrRetain(custom_attr->value);
}
}
- else if (!strcmp(keyword, "CloseUI") || !strcmp(keyword, "JCLCloseUI"))
+ else if (!strcmp(keyword, "CloseUI"))
{
+ if ((!option || option->section == PPD_ORDER_JCL) && pg->ppd_conform == PPD_CONFORM_STRICT)
+ {
+ pg->ppd_status = PPD_BAD_CLOSE_UI;
+
+ goto error;
+ }
+
+ option = NULL;
+
+ _cupsStrFree(string);
+ string = NULL;
+ }
+ else if (!strcmp(keyword, "JCLCloseUI"))
+ {
+ if ((!option || option->section != PPD_ORDER_JCL) && pg->ppd_conform == PPD_CONFORM_STRICT)
+ {
+ pg->ppd_status = PPD_BAD_CLOSE_UI;
+
+ goto error;
+ }
+
option = NULL;
_cupsStrFree(string);
@@ -2007,6 +2030,16 @@ _ppdOpen(
}
/*
+ * Check for a missing CloseUI/JCLCloseUI...
+ */
+
+ if (option && pg->ppd_conform == PPD_CONFORM_STRICT)
+ {
+ pg->ppd_status = PPD_MISSING_CLOSE_UI;
+ goto error;
+ }
+
+ /*
* Check for a missing CloseGroup...
*/
@@ -2804,13 +2837,13 @@ ppd_globals_alloc(void)
* 'ppd_globals_free()' - Free global data.
*/
-#if defined(HAVE_PTHREAD_H) || defined(WIN32)
+#if defined(HAVE_PTHREAD_H) || defined(_WIN32)
static void
ppd_globals_free(_ppd_globals_t *pg) /* I - Pointer to global data */
{
free(pg);
}
-#endif /* HAVE_PTHREAD_H || WIN32 */
+#endif /* HAVE_PTHREAD_H || _WIN32 */
#ifdef HAVE_PTHREAD_H
diff --git a/cups/ppd.h b/cups/ppd.h
index fb33c08b..6e628cb6 100644
--- a/cups/ppd.h
+++ b/cups/ppd.h
@@ -132,6 +132,8 @@ typedef enum ppd_status_e /**** Status Codes @since CUPS 1.1.19/macOS 10.3@ ***
PPD_MISSING_OPTION_KEYWORD, /* Missing option keyword */
PPD_BAD_VALUE, /* Bad value string */
PPD_MISSING_CLOSE_GROUP, /* Missing CloseGroup */
+ PPD_BAD_CLOSE_UI, /* Bad CloseUI/JCLCloseUI */
+ PPD_MISSING_CLOSE_UI, /* Missing CloseUI/JCLCloseUI */
PPD_MAX_STATUS /* @private@ */
} ppd_status_t;
diff --git a/cups/raster-private.h b/cups/raster-private.h
index 38135815..94dd951c 100644
--- a/cups/raster-private.h
+++ b/cups/raster-private.h
@@ -1,7 +1,7 @@
/*
* Private image library definitions for CUPS.
*
- * Copyright 2007-2015 by Apple Inc.
+ * Copyright 2007-2018 by Apple Inc.
* Copyright 1993-2006 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
@@ -24,13 +24,13 @@
# include <cups/cups.h>
# include <cups/debug-private.h>
# include <cups/string-private.h>
-# ifdef WIN32
+# ifdef _WIN32
# include <io.h>
# include <winsock2.h> /* for htonl() definition */
# else
# include <unistd.h>
# include <fcntl.h>
-# endif /* WIN32 */
+# endif /* _WIN32 */
/*
@@ -49,12 +49,8 @@
* Prototypes...
*/
-extern int _cupsRasterExecPS(cups_page_header2_t *h,
- int *preferred_bits,
- const char *code)
- __attribute__((nonnull(3)));
-extern void _cupsRasterAddError(const char *f, ...)
- __attribute__((__format__(__printf__, 1, 2)));
+extern int _cupsRasterExecPS(cups_page_header2_t *h, int *preferred_bits, const char *code) _CUPS_NONNULL((3));
+extern void _cupsRasterAddError(const char *f, ...) _CUPS_FORMAT(1,2);
extern void _cupsRasterClearError(void);
#endif /* !_CUPS_RASTER_PRIVATE_H_ */
diff --git a/cups/request.c b/cups/request.c
index efbc06eb..a4e4b905 100644
--- a/cups/request.c
+++ b/cups/request.c
@@ -20,11 +20,11 @@
#include "cups-private.h"
#include <fcntl.h>
#include <sys/stat.h>
-#if defined(WIN32) || defined(__EMX__)
+#if defined(_WIN32) || defined(__EMX__)
# include <io.h>
#else
# include <unistd.h>
-#endif /* WIN32 || __EMX__ */
+#endif /* _WIN32 || __EMX__ */
#ifndef O_BINARY
# define O_BINARY 0
#endif /* O_BINARY */
@@ -156,11 +156,11 @@ cupsDoIORequest(http_t *http, /* I - Connection to server or @code CUPS_HTTP
return (NULL);
}
-#ifdef WIN32
+#ifdef _WIN32
if (fileinfo.st_mode & _S_IFDIR)
#else
if (S_ISDIR(fileinfo.st_mode))
-#endif /* WIN32 */
+#endif /* _WIN32 */
{
/*
* Can't send a directory...
@@ -172,11 +172,11 @@ cupsDoIORequest(http_t *http, /* I - Connection to server or @code CUPS_HTTP
return (NULL);
}
-#ifndef WIN32
+#ifndef _WIN32
if (!S_ISREG(fileinfo.st_mode))
length = 0; /* Chunk when piping */
else
-#endif /* !WIN32 */
+#endif /* !_WIN32 */
length = ippLength(request) + (size_t)fileinfo.st_size;
}
else
@@ -215,9 +215,9 @@ cupsDoIORequest(http_t *http, /* I - Connection to server or @code CUPS_HTTP
* Send the file with the request...
*/
-#ifndef WIN32
+#ifndef _WIN32
if (S_ISREG(fileinfo.st_mode))
-#endif /* WIN32 */
+#endif /* _WIN32 */
lseek(infile, 0, SEEK_SET);
while ((bytes = read(infile, buffer, sizeof(buffer))) > 0)
@@ -591,7 +591,8 @@ cupsSendRequest(http_t *http, /* I - Connection to server or @code CUPS_HTTP
int got_status; /* Did we get the status? */
ipp_state_t state; /* State of IPP processing */
http_status_t expect; /* Expect: header to use */
- char date[256]; /* Date: header value */
+ char date[256]; /* Date: header value */
+ int digest; /* Are we using Digest authentication? */
DEBUG_printf(("cupsSendRequest(http=%p, request=%p(%s), resource=\"%s\", length=" CUPS_LLFMT ")", (void *)http, (void *)request, request ? ippOpString(request->request.op.operation_id) : "?", resource, CUPS_LLCAST length));
@@ -683,6 +684,17 @@ cupsSendRequest(http_t *http, /* I - Connection to server or @code CUPS_HTTP
httpSetField(http, HTTP_FIELD_DATE, httpGetDateString2(time(NULL), date, (int)sizeof(date)));
httpSetLength(http, length);
+ digest = http->authstring && !strncmp(http->authstring, "Digest ", 7);
+
+ if (digest)
+ {
+ /*
+ * Update the Digest authentication string...
+ */
+
+ _httpSetDigestAuthString(http, http->nextnonce, "POST", resource);
+ }
+
#ifdef HAVE_GSSAPI
if (http->authstring && !strncmp(http->authstring, "Negotiate", 9))
{
@@ -767,9 +779,9 @@ cupsSendRequest(http_t *http, /* I - Connection to server or @code CUPS_HTTP
* Wait up to 1 second to get the 100-continue response as needed...
*/
- if (!got_status)
+ if (!got_status || (digest && status == HTTP_STATUS_CONTINUE))
{
- if (expect == HTTP_STATUS_CONTINUE)
+ if (expect == HTTP_STATUS_CONTINUE || digest)
{
DEBUG_puts("2cupsSendRequest: Waiting for 100-continue...");
@@ -1016,13 +1028,13 @@ _cupsConnect(void)
char ch; /* Connection check byte */
ssize_t n; /* Number of bytes */
-#ifdef WIN32
+#ifdef _WIN32
if ((n = recv(cg->http->fd, &ch, 1, MSG_PEEK)) == 0 ||
(n < 0 && WSAGetLastError() != WSAEWOULDBLOCK))
#else
if ((n = recv(cg->http->fd, &ch, 1, MSG_PEEK | MSG_DONTWAIT)) == 0 ||
(n < 0 && errno != EWOULDBLOCK))
-#endif /* WIN32 */
+#endif /* _WIN32 */
{
/*
* Nope, close the connection...
diff --git a/cups/sidechannel.c b/cups/sidechannel.c
index a4cd960a..f2dbabd6 100644
--- a/cups/sidechannel.c
+++ b/cups/sidechannel.c
@@ -19,15 +19,15 @@
#include "sidechannel.h"
#include "cups-private.h"
-#ifdef WIN32
+#ifdef _WIN32
# include <io.h>
#else
# include <unistd.h>
-#endif /* WIN32 */
-#ifndef WIN32
+#endif /* _WIN32 */
+#ifndef _WIN32
# include <sys/select.h>
# include <sys/time.h>
-#endif /* !WIN32 */
+#endif /* !_WIN32 */
#ifdef HAVE_POLL
# include <poll.h>
#endif /* HAVE_POLL */
diff --git a/cups/snmp.c b/cups/snmp.c
index 7958b93e..8437528d 100644
--- a/cups/snmp.c
+++ b/cups/snmp.c
@@ -395,11 +395,11 @@ _cupsSNMPRead(int fd, /* I - SNMP socket file descriptor */
ready = select(fd + 1, &input_set, NULL, NULL, &stimeout);
}
-# ifdef WIN32
+# ifdef _WIN32
while (ready < 0 && WSAGetLastError() == WSAEINTR);
# else
while (ready < 0 && (errno == EINTR || errno == EAGAIN));
-# endif /* WIN32 */
+# endif /* _WIN32 */
#endif /* HAVE_POLL */
/*
diff --git a/cups/string-private.h b/cups/string-private.h
index e8448d17..ced24923 100644
--- a/cups/string-private.h
+++ b/cups/string-private.h
@@ -1,7 +1,7 @@
/*
* Private string definitions for CUPS.
*
- * Copyright 2007-2015 by Apple Inc.
+ * Copyright 2007-2018 by Apple Inc.
* Copyright 1997-2006 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
@@ -42,12 +42,12 @@
# include <bstring.h>
# endif /* HAVE_BSTRING_H */
-# if defined(WIN32) && !defined(__CUPS_SSIZE_T_DEFINED)
+# if defined(_WIN32) && !defined(__CUPS_SSIZE_T_DEFINED)
# define __CUPS_SSIZE_T_DEFINED
# include <stddef.h>
/* Windows does not support the ssize_t type, so map it to long... */
typedef long ssize_t; /* @private@ */
-# endif /* WIN32 && !__CUPS_SSIZE_T_DEFINED */
+# endif /* _WIN32 && !__CUPS_SSIZE_T_DEFINED */
/*
@@ -175,8 +175,7 @@ extern size_t _cups_strlcpy(char *, const char *, size_t);
# endif /* !HAVE_STRLCPY */
# ifndef HAVE_SNPRINTF
-extern int _cups_snprintf(char *, size_t, const char *, ...)
- __attribute__ ((__format__ (__printf__, 3, 4)));
+extern int _cups_snprintf(char *, size_t, const char *, ...) _CUPS_FORMAT(3, 4);
# define snprintf _cups_snprintf
# endif /* !HAVE_SNPRINTF */
diff --git a/cups/tempfile.c b/cups/tempfile.c
index da705a94..7b341e13 100644
--- a/cups/tempfile.c
+++ b/cups/tempfile.c
@@ -1,8 +1,8 @@
/*
* Temp file utilities for CUPS.
*
- * Copyright 2007-2014 by Apple Inc.
- * Copyright 1997-2006 by Easy Software Products.
+ * Copyright © 2007-2018 by Apple Inc.
+ * Copyright © 1997-2006 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
* property of Apple Inc. and are protected by Federal copyright
@@ -21,11 +21,11 @@
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
-#if defined(WIN32) || defined(__EMX__)
+#if defined(_WIN32) || defined(__EMX__)
# include <io.h>
#else
# include <unistd.h>
-#endif /* WIN32 || __EMX__ */
+#endif /* _WIN32 || __EMX__ */
/*
@@ -42,24 +42,46 @@ cupsTempFd(char *filename, /* I - Pointer to buffer */
int fd; /* File descriptor for temp file */
int tries; /* Number of tries */
const char *tmpdir; /* TMPDIR environment var */
-#ifdef WIN32
- char tmppath[1024]; /* Windows temporary directory */
+#if defined(__APPLE__) || defined(_WIN32)
+ char tmppath[1024]; /* Temporary directory */
+#endif /* __APPLE__ || _WIN32 */
+#ifdef _WIN32
DWORD curtime; /* Current time */
#else
struct timeval curtime; /* Current time */
-#endif /* WIN32 */
+#endif /* _WIN32 */
/*
* See if TMPDIR is defined...
*/
-#ifdef WIN32
+#ifdef _WIN32
if ((tmpdir = getenv("TEMP")) == NULL)
{
GetTempPath(sizeof(tmppath), tmppath);
tmpdir = tmppath;
}
+
+#elif defined(__APPLE__)
+ /*
+ * On macOS and iOS, the TMPDIR environment variable is not always the best
+ * location to place temporary files due to sandboxing. Instead, the confstr
+ * function should be called to get the proper per-user, per-process TMPDIR
+ * value.
+ */
+
+ if ((tmpdir = getenv("TMPDIR")) != NULL && access(tmpdir, W_OK))
+ tmpdir = NULL;
+
+ if (!tmpdir)
+ {
+ if (confstr(_CS_DARWIN_USER_TEMP_DIR, tmppath, sizeof(tmppath)))
+ tmpdir = tmppath;
+ else
+ tmpdir = "/private/tmp"; /* This should never happen */
+ }
+
#else
/*
* Previously we put root temporary files in the default CUPS temporary
@@ -69,12 +91,8 @@ cupsTempFd(char *filename, /* I - Pointer to buffer */
*/
if ((tmpdir = getenv("TMPDIR")) == NULL)
-# if defined(__APPLE__) && !TARGET_OS_IOS
- tmpdir = "/private/tmp"; /* /tmp is a symlink to /private/tmp */
-# else
tmpdir = "/tmp";
-# endif /* __APPLE__ && !TARGET_OS_IOS */
-#endif /* WIN32 */
+#endif /* _WIN32 */
/*
* Make the temporary name using the specified directory...
@@ -84,7 +102,7 @@ cupsTempFd(char *filename, /* I - Pointer to buffer */
do
{
-#ifdef WIN32
+#ifdef _WIN32
/*
* Get the current time of day...
*/
@@ -108,21 +126,21 @@ cupsTempFd(char *filename, /* I - Pointer to buffer */
*/
snprintf(filename, (size_t)len - 1, "%s/%05x%08x", tmpdir, (unsigned)getpid(), (unsigned)(curtime.tv_sec + curtime.tv_usec + tries));
-#endif /* WIN32 */
+#endif /* _WIN32 */
/*
* Open the file in "exclusive" mode, making sure that we don't
* stomp on an existing file or someone's symlink crack...
*/
-#ifdef WIN32
+#ifdef _WIN32
fd = open(filename, _O_CREAT | _O_RDWR | _O_TRUNC | _O_BINARY,
_S_IREAD | _S_IWRITE);
#elif defined(O_NOFOLLOW)
fd = open(filename, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW, 0600);
#else
fd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600);
-#endif /* WIN32 */
+#endif /* _WIN32 */
if (fd < 0 && errno != EEXIST)
break;
diff --git a/cups/testarray.c b/cups/testarray.c
index 6164ffc6..892e3250 100644
--- a/cups/testarray.c
+++ b/cups/testarray.c
@@ -494,7 +494,7 @@ main(void)
* 'get_seconds()' - Get the current time in seconds...
*/
-#ifdef WIN32
+#ifdef _WIN32
# include <windows.h>
@@ -515,7 +515,7 @@ get_seconds(void)
gettimeofday(&curtime, NULL);
return (curtime.tv_sec + 0.000001 * curtime.tv_usec);
}
-#endif /* WIN32 */
+#endif /* _WIN32 */
/*
diff --git a/cups/testdest.c b/cups/testdest.c
index c5c20528..9eab8d2e 100644
--- a/cups/testdest.c
+++ b/cups/testdest.c
@@ -1,7 +1,7 @@
/*
* CUPS destination API test program for CUPS.
*
- * Copyright 2012-2017 by Apple Inc.
+ * Copyright 2012-2018 by Apple Inc.
*
* These coded instructions, statements, and computer programs are the
* property of Apple Inc. and are protected by Federal copyright
@@ -32,7 +32,7 @@ static void show_conflicts(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo,
static void show_default(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, const char *option);
static void show_media(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, unsigned flags, const char *name);
static void show_supported(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, const char *option, const char *value);
-static void usage(const char *arg) __attribute__((noreturn));
+static void usage(const char *arg) _CUPS_NORETURN;
/*
diff --git a/cups/testfile.c b/cups/testfile.c
index b2ec8cd5..1473a4a0 100644
--- a/cups/testfile.c
+++ b/cups/testfile.c
@@ -1,7 +1,7 @@
/*
* File test program for CUPS.
*
- * Copyright 2007-2015 by Apple Inc.
+ * Copyright 2007-2018 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
@@ -22,14 +22,11 @@
#include "file.h"
#include <stdlib.h>
#include <time.h>
-#ifdef HAVE_LIBZ
-# include <zlib.h>
-#endif /* HAVE_LIBZ */
-#ifdef WIN32
+#ifdef _WIN32
# include <io.h>
#else
# include <unistd.h>
-#endif /* WIN32 */
+#endif /* _WIN32 */
#include <fcntl.h>
@@ -53,10 +50,10 @@ main(int argc, /* I - Number of command-line arguments */
int status; /* Exit status */
char filename[1024]; /* Filename buffer */
cups_file_t *fp; /* File pointer */
-#ifndef WIN32
+#ifndef _WIN32
int fds[2]; /* Open file descriptors */
cups_file_t *fdfile; /* File opened with cupsFileOpenFd() */
-#endif /* !WIN32 */
+#endif /* !_WIN32 */
int count; /* Number of lines in file */
@@ -84,7 +81,7 @@ main(int argc, /* I - Number of command-line arguments */
status += random_tests();
-#ifndef WIN32
+#ifndef _WIN32
/*
* Test fdopen and close without reading...
*/
@@ -118,7 +115,7 @@ main(int argc, /* I - Number of command-line arguments */
puts("PASS");
}
-#endif /* !WIN32 */
+#endif /* !_WIN32 */
/*
* Count lines in psglyphs, rewind, then count again.
@@ -174,13 +171,13 @@ main(int argc, /* I - Number of command-line arguments */
*/
fputs("\ncupsFileFind: ", stdout);
-#ifdef WIN32
+#ifdef _WIN32
if (cupsFileFind("notepad.exe", "C:/WINDOWS", 1, filename, sizeof(filename)) &&
cupsFileFind("notepad.exe", "C:/WINDOWS;C:/WINDOWS/SYSTEM32", 1, filename, sizeof(filename)))
#else
if (cupsFileFind("cat", "/bin", 1, filename, sizeof(filename)) &&
cupsFileFind("cat", "/bin:/usr/bin", 1, filename, sizeof(filename)))
-#endif /* WIN32 */
+#endif /* _WIN32 */
printf("PASS (%s)\n", filename);
else
{
diff --git a/cups/testhttp.c b/cups/testhttp.c
index 376d71f6..7d8ec06d 100644
--- a/cups/testhttp.c
+++ b/cups/testhttp.c
@@ -1,8 +1,8 @@
/*
* HTTP test program for CUPS.
*
- * Copyright 2007-2014 by Apple Inc.
- * Copyright 1997-2006 by Easy Software Products.
+ * Copyright © 2007-2018 by Apple Inc.
+ * Copyright © 1997-2006 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
* property of Apple Inc. and are protected by Federal copyright
@@ -120,6 +120,9 @@ static uri_test_t uri_tests[] = /* URI test data */
{ HTTP_URI_STATUS_OK, "ipp://%22%23%2F%3A%3C%3E%3F%40%5B%5C%5D%5E%60%7B%7C%7D/",
"ipp", "", "\"#/:<>?@[\\]^`{|}", "/", 631, 0,
HTTP_URI_CODING_MOST },
+ { HTTP_URI_STATUS_UNKNOWN_SCHEME, "smb://server/Some%20Printer",
+ "smb", "", "server", "/Some Printer", 0, 0,
+ HTTP_URI_CODING_ALL },
/* Missing scheme */
{ HTTP_URI_STATUS_MISSING_SCHEME, "/path/to/file/index.html",
@@ -148,6 +151,9 @@ static uri_test_t uri_tests[] = /* URI test data */
HTTP_URI_CODING_MOST },
/* Bad scheme */
+ { HTTP_URI_STATUS_BAD_SCHEME, "://server/ipp",
+ "", "", "", "", 0, 0,
+ HTTP_URI_CODING_MOST },
{ HTTP_URI_STATUS_BAD_SCHEME, "bad_scheme://server/resource",
"", "", "", "", 0, 0,
HTTP_URI_CODING_MOST },
@@ -180,6 +186,9 @@ static uri_test_t uri_tests[] = /* URI test data */
HTTP_URI_CODING_MOST },
/* Bad resource */
+ { HTTP_URI_STATUS_BAD_RESOURCE, "mailto:\r\nbla",
+ "mailto", "", "", "", 0, 0,
+ HTTP_URI_CODING_MOST },
{ HTTP_URI_STATUS_BAD_RESOURCE, "http://server/index.html%",
"http", "", "server", "", 80, 0,
HTTP_URI_CODING_MOST },
@@ -332,6 +341,40 @@ main(int argc, /* I - Number of command-line arguments */
if (!j)
puts("PASS");
+#if 0
+ /*
+ * _httpDigest()
+ */
+
+ fputs("_httpDigest(MD5): ", stdout);
+ if (!_httpDigest(buffer, sizeof(buffer), "MD5", "Mufasa", "http-auth@example.org", "Circle of Life", "7ypf/xlj9XXwfDPEoM4URrv/xwf94BcCAzFZH4GiTo0v", 1, "f2/wE4q74E6zIJEtWaHKaf5wv/H5QzzpXusqGemxURZJ", "auth", "GET", "/dir/index.html"))
+ {
+ failures ++;
+ puts("FAIL (unable to calculate hash)");
+ }
+ else if (strcmp(buffer, "8ca523f5e9506fed4657c9700eebdbec"))
+ {
+ failures ++;
+ printf("FAIL (got \"%s\", expected \"8ca523f5e9506fed4657c9700eebdbec\")\n", buffer);
+ }
+ else
+ puts("PASS");
+
+ fputs("_httpDigest(SHA-256): ", stdout);
+ if (!_httpDigest(buffer, sizeof(buffer), "SHA-256", "Mufasa", "http-auth@example.org", "Circle of Life", "7ypf/xlj9XXwfDPEoM4URrv/xwf94BcCAzFZH4GiTo0v", 1, "f2/wE4q74E6zIJEtWaHKaf5wv/H5QzzpXusqGemxURZJ", "auth", "GET", "/dir/index.html"))
+ {
+ failures ++;
+ puts("FAIL (unable to calculate hash)");
+ }
+ else if (strcmp(buffer, "753927fa0e85d155564e2e272a28d1802ca10daf4496794697cf8db5856cb6c1"))
+ {
+ failures ++;
+ printf("FAIL (got \"%s\", expected \"753927fa0e85d155564e2e272a28d1802ca10daf4496794697cf8db5856cb6c1\")\n", buffer);
+ }
+ else
+ puts("PASS");
+#endif /* 0 */
+
/*
* httpGetHostname()
*/
@@ -590,6 +633,8 @@ main(int argc, /* I - Number of command-line arguments */
for (i = 1; i < argc; i ++)
{
+ int new_auth;
+
if (!strcmp(argv[i], "-o"))
{
i ++;
@@ -673,6 +718,8 @@ main(int argc, /* I - Number of command-line arguments */
printf("Checking file \"%s\"...\n", resource);
+ new_auth = 0;
+
do
{
if (!_cups_strcasecmp(httpGetField(http, HTTP_FIELD_CONNECTION), "close"))
@@ -685,9 +732,13 @@ main(int argc, /* I - Number of command-line arguments */
}
}
+ if (http->authstring && !strncmp(http->authstring, "Digest ", 7) && !new_auth)
+ _httpSetDigestAuthString(http, http->nextnonce, "HEAD", resource);
+
httpClearFields(http);
httpSetField(http, HTTP_FIELD_AUTHORIZATION, httpGetAuthString(http));
httpSetField(http, HTTP_FIELD_ACCEPT_LANGUAGE, "en");
+
if (httpHead(http, resource))
{
if (httpReconnect2(http, 30000, NULL))
@@ -704,6 +755,8 @@ main(int argc, /* I - Number of command-line arguments */
while ((status = httpUpdate(http)) == HTTP_STATUS_CONTINUE);
+ new_auth = 0;
+
if (status == HTTP_STATUS_UNAUTHORIZED)
{
/*
@@ -716,7 +769,9 @@ main(int argc, /* I - Number of command-line arguments */
* See if we can do authentication...
*/
- if (cupsDoAuthentication(http, "GET", resource))
+ new_auth = 1;
+
+ if (cupsDoAuthentication(http, "HEAD", resource))
{
status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED;
break;
@@ -764,6 +819,8 @@ main(int argc, /* I - Number of command-line arguments */
printf("Requesting file \"%s\" (Accept-Encoding: %s)...\n", resource,
encoding ? encoding : "identity");
+ new_auth = 0;
+
do
{
if (!_cups_strcasecmp(httpGetField(http, HTTP_FIELD_CONNECTION), "close"))
@@ -776,6 +833,9 @@ main(int argc, /* I - Number of command-line arguments */
}
}
+ if (http->authstring && !strncmp(http->authstring, "Digest ", 7) && !new_auth)
+ _httpSetDigestAuthString(http, http->nextnonce, "GET", resource);
+
httpClearFields(http);
httpSetField(http, HTTP_FIELD_AUTHORIZATION, httpGetAuthString(http));
httpSetField(http, HTTP_FIELD_ACCEPT_LANGUAGE, "en");
@@ -797,6 +857,8 @@ main(int argc, /* I - Number of command-line arguments */
while ((status = httpUpdate(http)) == HTTP_STATUS_CONTINUE);
+ new_auth = 0;
+
if (status == HTTP_STATUS_UNAUTHORIZED)
{
/*
@@ -809,6 +871,8 @@ main(int argc, /* I - Number of command-line arguments */
* See if we can do authentication...
*/
+ new_auth = 1;
+
if (cupsDoAuthentication(http, "GET", resource))
{
status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED;
diff --git a/cups/testipp.c b/cups/testipp.c
index ea8f9d78..2ef2496e 100644
--- a/cups/testipp.c
+++ b/cups/testipp.c
@@ -20,12 +20,12 @@
#include "file.h"
#include "string-private.h"
#include "ipp-private.h"
-#ifdef WIN32
+#ifdef _WIN32
# include <io.h>
#else
# include <unistd.h>
# include <fcntl.h>
-#endif /* WIN32 */
+#endif /* _WIN32 */
/*
diff --git a/cups/testppd.c b/cups/testppd.c
index e1b51564..a127a794 100644
--- a/cups/testppd.c
+++ b/cups/testppd.c
@@ -21,12 +21,12 @@
#include "cups-private.h"
#include "ppd-private.h"
#include <sys/stat.h>
-#ifdef WIN32
+#ifdef _WIN32
# include <io.h>
#else
# include <unistd.h>
# include <fcntl.h>
-#endif /* WIN32 */
+#endif /* _WIN32 */
#include <math.h>
@@ -876,6 +876,13 @@ main(int argc, /* I - Number of command-line arguments */
host[256], /* Hostname */
resource[256]; /* Resource path */
int port; /* Port number */
+ static const char * const pattrs[] =/* Requested printer attributes */
+ {
+ "job-template",
+ "printer-defaults",
+ "printer-description",
+ "media-col-database"
+ };
if (httpSeparateURI(HTTP_URI_CODING_ALL, argv[1], scheme, sizeof(scheme), userpass, sizeof(userpass), host, sizeof(host), &port, resource, sizeof(resource)) < HTTP_URI_STATUS_OK)
{
@@ -892,6 +899,7 @@ main(int argc, /* I - Number of command-line arguments */
request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, argv[1]);
+ ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", sizeof(pattrs) / sizeof(pattrs[0]), NULL, pattrs);
response = cupsDoRequest(http, request, resource);
if (_ppdCreateFromIPP(buffer, sizeof(buffer), response))
diff --git a/cups/testsnmp.c b/cups/testsnmp.c
index 4026a28b..9e168ab7 100644
--- a/cups/testsnmp.c
+++ b/cups/testsnmp.c
@@ -1,7 +1,7 @@
/*
* SNMP test program for CUPS.
*
- * Copyright 2008-2014 by Apple Inc.
+ * Copyright 2008-2018 by Apple Inc.
*
* These coded instructions, statements, and computer programs are the
* property of Apple Inc. and are protected by Federal copyright
@@ -27,7 +27,7 @@
static void print_packet(cups_snmp_t *packet, void *data);
static int show_oid(int fd, const char *community,
http_addr_t *addr, const char *s, int walk);
-static void usage(void) __attribute__((noreturn));
+static void usage(void) _CUPS_NORETURN;
/*
diff --git a/cups/thread-private.h b/cups/thread-private.h
index 79d24386..ae8163d1 100644
--- a/cups/thread-private.h
+++ b/cups/thread-private.h
@@ -46,7 +46,7 @@ typedef pthread_key_t _cups_threadkey_t;
# define _cupsThreadGetData(k) pthread_getspecific(k)
# define _cupsThreadSetData(k,p) pthread_setspecific(k,p)
-# elif defined(WIN32) /* Windows threading */
+# elif defined(_WIN32) /* Windows threading */
# include <winsock2.h>
# include <windows.h>
typedef void *(__stdcall *_cups_thread_func_t)(void *arg);
diff --git a/cups/thread.c b/cups/thread.c
index 65257aa1..7ffc2ec0 100644
--- a/cups/thread.c
+++ b/cups/thread.c
@@ -1,7 +1,7 @@
/*
* Threading primitives for CUPS.
*
- * Copyright 2009-2017 by Apple Inc.
+ * Copyright © 2009-2018 by Apple Inc.
*
* These coded instructions, statements, and computer programs are the
* property of Apple Inc. and are protected by Federal copyright
@@ -56,8 +56,16 @@ _cupsCondWait(_cups_cond_t *cond, /* I - Condition */
{
struct timespec abstime; /* Timeout */
- abstime.tv_sec = (long)timeout;
- abstime.tv_nsec = (long)(1000000000 * (timeout - (long)timeout));
+ clock_gettime(CLOCK_REALTIME, &abstime);
+
+ abstime.tv_sec += (long)timeout;
+ abstime.tv_nsec += (long)(1000000000 * (timeout - (long)timeout));
+
+ while (abstime.tv_nsec >= 1000000000)
+ {
+ abstime.tv_nsec -= 1000000000;
+ abstime.tv_sec ++;
+ };
pthread_cond_timedwait(cond, mutex, &abstime);
}
@@ -200,7 +208,7 @@ _cupsThreadWait(_cups_thread_t thread) /* I - Thread ID */
}
-#elif defined(WIN32)
+#elif defined(_WIN32)
# include <process.h>
@@ -513,8 +521,7 @@ _cupsThreadCreate(
_cups_thread_func_t func, /* I - Entry point */
void *arg) /* I - Entry point context */
{
- fputs("DEBUG: CUPS was compiled without threading support, no thread "
- "created.\n", stderr);
+ fputs("DEBUG: CUPS was compiled without threading support, no thread created.\n", stderr);
(void)func;
(void)arg;
@@ -524,6 +531,17 @@ _cupsThreadCreate(
/*
+ * '_cupsThreadDetach()' - Tell the OS that the thread is running independently.
+ */
+
+void
+_cupsThreadDetach(_cups_thread_t thread)/* I - Thread ID */
+{
+ (void)thread;
+}
+
+
+/*
* '_cupsThreadWait()' - Wait for a thread to exit.
*/
diff --git a/cups/tls-boringssl.c b/cups/tls-boringssl.c
index a8b7de54..c3f9abc4 100644
--- a/cups/tls-boringssl.c
+++ b/cups/tls-boringssl.c
@@ -29,7 +29,9 @@
static char *tls_keypath = NULL;
/* Server cert keychain path */
-static int tls_options = -1;/* Options for TLS connections */
+static int tls_options = -1,/* Options for TLS connections */
+ tls_min_version = _HTTP_TLS_1_0,
+ tls_max_version = _HTTP_TLS_MAX;
/*
@@ -309,9 +311,11 @@ _httpTLSRead(http_t *http, /* I - Connection to server */
*/
void
-_httpTLSSetOptions(int options) /* I - Options */
+_httpTLSSetOptions(int options, int min_version, int max_version) /* I - Options */
{
tls_options = options;
+ tls_min_version = min_version;
+ tls_max_version = max_version;
}
@@ -349,8 +353,8 @@ _httpTLSStart(http_t *http) /* I - Connection to server */
}
context = SSL_CTX_new(TLS_method());
- if (tls_options & _HTTP_TLS_DENY_TLS10)
- SSL_CTX_set_min_proto_version(context, TLS1_1_VERSION);
+ SSL_CTX_set_min_proto_version(context, tls_min_version);
+ SSL_CTX_set_max_proto_version(context, tls_max_version);
bio = BIO_new(_httpBIOMethods());
BIO_ctrl(bio, BIO_C_SET_FILE_PTR, 0, (char *)http);
diff --git a/cups/tls-darwin.c b/cups/tls-darwin.c
index 92430aca..c4f0ccb2 100644
--- a/cups/tls-darwin.c
+++ b/cups/tls-darwin.c
@@ -1,8 +1,8 @@
/*
* TLS support code for CUPS on macOS.
*
- * Copyright 2007-2017 by Apple Inc.
- * Copyright 1997-2007 by Easy Software Products, all rights reserved.
+ * Copyright © 2007-2018 by Apple Inc.
+ * Copyright © 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
* property of Apple Inc. and are protected by Federal copyright
@@ -53,7 +53,9 @@ static char *tls_keypath = NULL;
/* Server cert keychain path */
static _cups_mutex_t tls_mutex = _CUPS_MUTEX_INITIALIZER;
/* Mutex for keychain/certs */
-static int tls_options = -1;/* Options for TLS connections */
+static int tls_options = -1,/* Options for TLS connections */
+ tls_min_version = _HTTP_TLS_1_0,
+ tls_max_version = _HTTP_TLS_MAX;
/*
@@ -807,7 +809,6 @@ httpCredentialsString(
CFStringRef cf_name; /* CF common name string */
char name[256]; /* Common name associated with cert */
time_t expiration; /* Expiration date of cert */
- _cups_md5_state_t md5_state; /* MD5 state */
unsigned char md5_digest[16]; /* MD5 result */
if ((cf_name = SecCertificateCopySubjectSummary(secCert)) != NULL)
@@ -820,9 +821,7 @@ httpCredentialsString(
expiration = (time_t)(SecCertificateNotValidAfter(secCert) + kCFAbsoluteTimeIntervalSince1970);
- _cupsMD5Init(&md5_state);
- _cupsMD5Append(&md5_state, first->data, (int)first->datalen);
- _cupsMD5Finish(&md5_state, md5_digest);
+ cupsHashData("md5", first->data, first->datalen, md5_digest, sizeof(md5_digest));
snprintf(buffer, bufsize, "%s / %s / %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", name, httpGetDateString(expiration), md5_digest[0], md5_digest[1], md5_digest[2], md5_digest[3], md5_digest[4], md5_digest[5], md5_digest[6], md5_digest[7], md5_digest[8], md5_digest[9], md5_digest[10], md5_digest[11], md5_digest[12], md5_digest[13], md5_digest[14], md5_digest[15]);
@@ -1139,10 +1138,16 @@ _httpTLSRead(http_t *http, /* I - HTTP connection */
*/
void
-_httpTLSSetOptions(int options) /* I - Options */
+_httpTLSSetOptions(int options, /* I - Options */
+ int min_version, /* I - Minimum TLS version */
+ int max_version) /* I - Maximum TLS version */
{
if (!(options & _HTTP_TLS_SET_DEFAULT) || tls_options < 0)
- tls_options = options;
+ {
+ tls_options = options;
+ tls_min_version = min_version;
+ tls_max_version = max_version;
+ }
}
@@ -1174,7 +1179,7 @@ _httpTLSStart(http_t *http) /* I - HTTP connection */
{
DEBUG_puts("4_httpTLSStart: Setting defaults.");
_cupsSetDefaults();
- DEBUG_printf(("4_httpTLSStart: tls_options=%x", tls_options));
+ DEBUG_printf(("4_httpTLSStart: tls_options=%x, tls_min_version=%d, tls_max_version=%d", tls_options, tls_min_version, tls_max_version));
}
#ifdef HAVE_SECKEYCHAINOPEN
@@ -1217,22 +1222,25 @@ _httpTLSStart(http_t *http) /* I - HTTP connection */
if (!error)
{
- SSLProtocol minProtocol;
-
- if (tls_options & _HTTP_TLS_DENY_TLS10)
- minProtocol = kTLSProtocol11;
- else if (tls_options & _HTTP_TLS_ALLOW_SSL3)
- minProtocol = kSSLProtocol3;
- else
- minProtocol = kTLSProtocol1;
-
- error = SSLSetProtocolVersionMin(http->tls, minProtocol);
- DEBUG_printf(("4_httpTLSStart: SSLSetProtocolVersionMin(%d), error=%d", minProtocol, (int)error));
+ static const SSLProtocol protocols[] = /* Min/max protocol versions */
+ {
+ kSSLProtocol3,
+ kTLSProtocol1,
+ kTLSProtocol11,
+ kTLSProtocol12,
+ kTLSProtocol13
+ };
+
+ if (tls_min_version < _HTTP_TLS_MAX)
+ {
+ error = SSLSetProtocolVersionMin(http->tls, protocols[tls_min_version]);
+ DEBUG_printf(("4_httpTLSStart: SSLSetProtocolVersionMin(%d), error=%d", protocols[tls_min_version], (int)error));
+ }
- if (!error && (tls_options & _HTTP_TLS_ONLY_TLS10))
+ if (!error && tls_max_version < _HTTP_TLS_MAX)
{
- error = SSLSetProtocolVersionMax(http->tls, kTLSProtocol1);
- DEBUG_printf(("4_httpTLSStart: SSLSetProtocolVersionMax(kTLSProtocol1), error=%d", (int)error));
+ error = SSLSetProtocolVersionMax(http->tls, protocols[tls_max_version]);
+ DEBUG_printf(("4_httpTLSStart: SSLSetProtocolVersionMax(%d), error=%d", protocols[tls_max_version], (int)error));
}
}
@@ -1532,7 +1540,28 @@ _httpTLSStart(http_t *http) /* I - HTTP connection */
if (!error)
{
- int done = 0; /* Are we done yet? */
+ int done = 0; /* Are we done yet? */
+ double old_timeout; /* Old timeout value */
+ http_timeout_cb_t old_cb; /* Old timeout callback */
+ void *old_data; /* Old timeout data */
+
+ /*
+ * Enforce a minimum timeout of 10 seconds for the TLS handshake...
+ */
+
+ old_timeout = http->timeout_value;
+ old_cb = http->timeout_cb;
+ old_data = http->timeout_data;
+
+ if (!old_cb || old_timeout < 10.0)
+ {
+ DEBUG_puts("4_httpTLSStart: Setting timeout to 10 seconds.");
+ httpSetTimeout(http, 10.0, NULL, NULL);
+ }
+
+ /*
+ * Do the TLS handshake...
+ */
while (!error && !done)
{
@@ -1653,6 +1682,12 @@ _httpTLSStart(http_t *http) /* I - HTTP connection */
break;
}
}
+
+ /*
+ * Restore the previous timeout settings...
+ */
+
+ httpSetTimeout(http, old_timeout, old_cb, old_data);
}
if (error)
@@ -1864,7 +1899,9 @@ http_cdsa_copy_server(
DEBUG_printf(("4http_cdsa_copy_server: Returning %p.", (void *)certificates));
return (certificates);
+
#else
+ (void)common_name;
if (!tls_selfsigned)
return (NULL);
@@ -2085,7 +2122,7 @@ http_cdsa_read(
http = (http_t *)connection;
- if (!http->blocking)
+ if (!http->blocking || http->timeout_value > 0.0)
{
/*
* Make sure we have data before we read...
diff --git a/cups/tls-gnutls.c b/cups/tls-gnutls.c
index 2dcb7fe3..606b45af 100644
--- a/cups/tls-gnutls.c
+++ b/cups/tls-gnutls.c
@@ -1,8 +1,8 @@
/*
* TLS support code for CUPS using GNU TLS.
*
- * Copyright 2007-2017 by Apple Inc.
- * Copyright 1997-2007 by Easy Software Products, all rights reserved.
+ * Copyright © 2007-2018 by Apple Inc.
+ * Copyright © 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
* property of Apple Inc. and are protected by Federal copyright
@@ -35,7 +35,9 @@ static char *tls_keypath = NULL;
/* Server cert keychain path */
static _cups_mutex_t tls_mutex = _CUPS_MUTEX_INITIALIZER;
/* Mutex for keychain/certs */
-static int tls_options = -1;/* Options for TLS connections */
+static int tls_options = -1,/* Options for TLS connections */
+ tls_min_version = _HTTP_TLS_1_0,
+ tls_max_version = _HTTP_TLS_MAX;
/*
@@ -646,7 +648,6 @@ httpCredentialsString(
char name[256]; /* Common name associated with cert */
size_t namelen; /* Length of name */
time_t expiration; /* Expiration date of cert */
- _cups_md5_state_t md5_state; /* MD5 state */
unsigned char md5_digest[16]; /* MD5 result */
namelen = sizeof(name) - 1;
@@ -657,9 +658,7 @@ httpCredentialsString(
expiration = gnutls_x509_crt_get_expiration_time(cert);
- _cupsMD5Init(&md5_state);
- _cupsMD5Append(&md5_state, first->data, (int)first->datalen);
- _cupsMD5Finish(&md5_state, md5_digest);
+ cupsHashData("md5", first->data, first->datalen, md5_digest, sizeof(md5_digest));
snprintf(buffer, bufsize, "%s / %s / %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", name, httpGetDateString(expiration), md5_digest[0], md5_digest[1], md5_digest[2], md5_digest[3], md5_digest[4], md5_digest[5], md5_digest[6], md5_digest[7], md5_digest[8], md5_digest[9], md5_digest[10], md5_digest[11], md5_digest[12], md5_digest[13], md5_digest[14], md5_digest[15]);
@@ -1094,7 +1093,7 @@ http_gnutls_read(
http = (http_t *)ptr;
- if (!http->blocking)
+ if (!http->blocking || http->timeout_value > 0.0)
{
/*
* Make sure we have data before we read...
@@ -1224,10 +1223,16 @@ _httpTLSSetCredentials(http_t *http) /* I - Connection to server */
*/
void
-_httpTLSSetOptions(int options) /* I - Options */
+_httpTLSSetOptions(int options, /* I - Options */
+ int min_version, /* I - Minimum TLS version */
+ int max_version) /* I - Maximum TLS version */
{
if (!(options & _HTTP_TLS_SET_DEFAULT) || tls_options < 0)
- tls_options = options;
+ {
+ tls_options = options;
+ tls_min_version = min_version;
+ tls_max_version = max_version;
+ }
}
@@ -1245,6 +1250,19 @@ _httpTLSStart(http_t *http) /* I - Connection to server */
/* TLS credentials */
char priority_string[2048];
/* Priority string */
+ int version; /* Current version */
+ double old_timeout; /* Old timeout value */
+ http_timeout_cb_t old_cb; /* Old timeout callback */
+ void *old_data; /* Old timeout data */
+ static const char * const versions[] =/* SSL/TLS versions */
+ {
+ "VERS-SSL3.0",
+ "VERS-TLS1.0",
+ "VERS-TLS1.1",
+ "VERS-TLS1.2",
+ "VERS-TLS1.3",
+ "VERS-TLS-ALL"
+ };
DEBUG_printf(("3_httpTLSStart(http=%p)", http));
@@ -1506,14 +1524,40 @@ _httpTLSStart(http_t *http) /* I - Connection to server */
strlcpy(priority_string, "NORMAL", sizeof(priority_string));
- if (tls_options & _HTTP_TLS_DENY_TLS10)
- strlcat(priority_string, ":+VERS-TLS-ALL:-VERS-TLS1.0:-VERS-SSL3.0", sizeof(priority_string));
- else if (tls_options & _HTTP_TLS_ALLOW_SSL3)
+ if (tls_max_version < _HTTP_TLS_MAX)
+ {
+ /*
+ * Require specific TLS versions...
+ */
+
+ strlcat(priority_string, ":-VERS-TLS-ALL", sizeof(priority_string));
+ for (version = tls_min_version; version <= tls_max_version; version ++)
+ {
+ strlcat(priority_string, ":+", sizeof(priority_string));
+ strlcat(priority_string, versions[version], sizeof(priority_string));
+ }
+ }
+ else if (tls_min_version == _HTTP_TLS_SSL3)
+ {
+ /*
+ * Allow all versions of TLS and SSL/3.0...
+ */
+
strlcat(priority_string, ":+VERS-TLS-ALL:+VERS-SSL3.0", sizeof(priority_string));
- else if (tls_options & _HTTP_TLS_ONLY_TLS10)
- strlcat(priority_string, ":-VERS-TLS-ALL:-VERS-SSL3.0:+VERS-TLS1.0", sizeof(priority_string));
+ }
else
- strlcat(priority_string, ":+VERS-TLS-ALL:-VERS-SSL3.0", sizeof(priority_string));
+ {
+ /*
+ * Require a minimum version...
+ */
+
+ strlcat(priority_string, ":+VERS-TLS-ALL", sizeof(priority_string));
+ for (version = 0; version < tls_min_version; version ++)
+ {
+ strlcat(priority_string, ":-", sizeof(priority_string));
+ strlcat(priority_string, versions[version], sizeof(priority_string));
+ }
+ }
if (tls_options & _HTTP_TLS_ALLOW_RC4)
strlcat(priority_string, ":+ARCFOUR-128", sizeof(priority_string));
@@ -1543,6 +1587,24 @@ _httpTLSStart(http_t *http) /* I - Connection to server */
#endif /* HAVE_GNUTLS_TRANSPORT_SET_PULL_TIMEOUT_FUNCTION */
gnutls_transport_set_push_function(http->tls, http_gnutls_write);
+ /*
+ * Enforce a minimum timeout of 10 seconds for the TLS handshake...
+ */
+
+ old_timeout = http->timeout_value;
+ old_cb = http->timeout_cb;
+ old_data = http->timeout_data;
+
+ if (!old_cb || old_timeout < 10.0)
+ {
+ DEBUG_puts("4_httpTLSStart: Setting timeout to 10 seconds.");
+ httpSetTimeout(http, 10.0, NULL, NULL);
+ }
+
+ /*
+ * Do the TLS handshake...
+ */
+
while ((status = gnutls_handshake(http->tls)) != GNUTLS_E_SUCCESS)
{
DEBUG_printf(("5_httpStartTLS: gnutls_handshake returned %d (%s)",
@@ -1560,10 +1622,18 @@ _httpTLSStart(http_t *http) /* I - Connection to server */
free(credentials);
http->tls = NULL;
+ httpSetTimeout(http, old_timeout, old_cb, old_data);
+
return (-1);
}
}
+ /*
+ * Restore the previous timeout settings...
+ */
+
+ httpSetTimeout(http, old_timeout, old_cb, old_data);
+
http->tls_credentials = credentials;
return (0);
diff --git a/cups/tls-sspi.c b/cups/tls-sspi.c
index 6eaec4c8..ea3fb007 100644
--- a/cups/tls-sspi.c
+++ b/cups/tls-sspi.c
@@ -2,7 +2,7 @@
* TLS support for CUPS on Windows using the Security Support Provider
* Interface (SSPI).
*
- * Copyright 2010-2017 by Apple Inc.
+ * Copyright 2010-2018 by Apple Inc.
*
* These coded instructions, statements, and computer programs are the
* property of Apple Inc. and are protected by Federal copyright
@@ -52,7 +52,9 @@
* Local globals...
*/
-static int tls_options = -1;/* Options for TLS connections */
+static int tls_options = -1,/* Options for TLS connections */
+ tls_min_version = _HTTP_TLS_1_0,
+ tls_max_version = _HTTP_TLS_MAX;
/*
@@ -351,7 +353,6 @@ httpCredentialsString(
SYSTEMTIME systime; /* System time */
struct tm tm; /* UNIX date/time */
time_t expiration; /* Expiration date of cert */
- _cups_md5_state_t md5_state; /* MD5 state */
unsigned char md5_digest[16]; /* MD5 result */
FileTimeToSystemTime(&(cert->pCertInfo->NotAfter), &systime);
@@ -378,9 +379,7 @@ httpCredentialsString(
else
strlcpy(cert_name, "unknown", sizeof(cert_name));
- _cupsMD5Init(&md5_state);
- _cupsMD5Append(&md5_state, first->data, (int)first->datalen);
- _cupsMD5Finish(&md5_state, md5_digest);
+ cupsHashData("md5", first->data, first->datalen, md5_digest, sizeof(md5_digest));
snprintf(buffer, bufsize, "%s / %s / %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", cert_name, httpGetDateString(expiration), md5_digest[0], md5_digest[1], md5_digest[2], md5_digest[3], md5_digest[4], md5_digest[5], md5_digest[6], md5_digest[7], md5_digest[8], md5_digest[9], md5_digest[10], md5_digest[11], md5_digest[12], md5_digest[13], md5_digest[14], md5_digest[15]);
@@ -911,10 +910,16 @@ _httpTLSRead(http_t *http, /* I - HTTP connection */
*/
void
-_httpTLSSetOptions(int options) /* I - Options */
+_httpTLSSetOptions(int options, /* I - Options */
+ int min_version, /* I - Minimum TLS version */
+ int max_version) /* I - Maximum TLS version */
{
if (!(options & _HTTP_TLS_SET_DEFAULT) || tls_options < 0)
- tls_options = options;
+ {
+ tls_options = options;
+ tls_min_version = min_version;
+ tls_max_version = max_version;
+ }
}
@@ -1762,34 +1767,38 @@ http_sspi_find_credentials(
#ifdef SP_PROT_TLS1_2_SERVER
if (http->mode == _HTTP_MODE_SERVER)
{
- if (tls_options & _HTTP_TLS_DENY_TLS10)
- SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_2_SERVER | SP_PROT_TLS1_1_SERVER;
- else if (tls_options & _HTTP_TLS_ALLOW_SSL3)
+ if (tls_min_version == _HTTP_TLS_SSL3)
SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_2_SERVER | SP_PROT_TLS1_1_SERVER | SP_PROT_TLS1_0_SERVER | SP_PROT_SSL3_SERVER;
- else
+ else if (tls_min_version == _HTTP_TLS_1_0)
SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_2_SERVER | SP_PROT_TLS1_1_SERVER | SP_PROT_TLS1_0_SERVER;
+ else if (tls_min_version == _HTTP_TLS_1_1)
+ SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_2_SERVER | SP_PROT_TLS1_1_SERVER;
+ else
+ SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_2_SERVER;
}
else
{
- if (tls_options & _HTTP_TLS_DENY_TLS10)
- SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_2_CLIENT | SP_PROT_TLS1_1_CLIENT;
- else if (tls_options & _HTTP_TLS_ALLOW_SSL3)
+ if (tls_min_version == _HTTP_TLS_SSL3)
SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_2_CLIENT | SP_PROT_TLS1_1_CLIENT | SP_PROT_TLS1_0_CLIENT | SP_PROT_SSL3_CLIENT;
- else
+ else if (tls_min_version == _HTTP_TLS_1_0)
SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_2_CLIENT | SP_PROT_TLS1_1_CLIENT | SP_PROT_TLS1_0_CLIENT;
+ else if (tls_min_version == _HTTP_TLS_1_1)
+ SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_2_CLIENT | SP_PROT_TLS1_1_CLIENT;
+ else
+ SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_2_CLIENT;
}
#else
if (http->mode == _HTTP_MODE_SERVER)
{
- if (tls_options & _HTTP_TLS_ALLOW_SSL3)
+ if (tls_min_version == _HTTP_TLS_SSL3)
SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_SERVER | SP_PROT_SSL3_SERVER;
else
SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_SERVER;
}
else
{
- if (tls_options & _HTTP_TLS_ALLOW_SSL3)
+ if (tls_min_version == _HTTP_TLS_SSL3)
SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_CLIENT | SP_PROT_SSL3_CLIENT;
else
SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_CLIENT;
diff --git a/cups/tls.c b/cups/tls.c
index 36d484c3..2539a090 100644
--- a/cups/tls.c
+++ b/cups/tls.c
@@ -23,20 +23,20 @@
#include "cups-private.h"
#include <fcntl.h>
#include <math.h>
-#ifdef WIN32
+#ifdef _WIN32
# include <tchar.h>
#else
# include <signal.h>
# include <sys/time.h>
# include <sys/resource.h>
-#endif /* WIN32 */
+#endif /* _WIN32 */
#ifdef HAVE_POLL
# include <poll.h>
#endif /* HAVE_POLL */
/*
- * Local functions...
+ * Include platform-specific TLS code...
*/
#ifdef HAVE_SSL
diff --git a/cups/tlscheck.c b/cups/tlscheck.c
index 997e7aaf..d16bf1e4 100644
--- a/cups/tlscheck.c
+++ b/cups/tlscheck.c
@@ -54,6 +54,8 @@ main(int argc, /* I - Number of command-line arguments */
int af = AF_UNSPEC, /* Address family */
tls_options = _HTTP_TLS_NONE,
/* TLS options */
+ tls_min_version = _HTTP_TLS_1_0,
+ tls_max_version = _HTTP_TLS_MAX,
verbose = 0; /* Verbosity */
ipp_t *request, /* IPP Get-Printer-Attributes request */
*response; /* IPP Get-Printer-Attributes response */
@@ -88,11 +90,27 @@ main(int argc, /* I - Number of command-line arguments */
}
else if (!strcmp(argv[i], "--no-tls10"))
{
- tls_options |= _HTTP_TLS_DENY_TLS10;
+ tls_min_version = _HTTP_TLS_1_1;
}
else if (!strcmp(argv[i], "--tls10"))
{
- tls_options |= _HTTP_TLS_ONLY_TLS10;
+ tls_min_version = _HTTP_TLS_1_0;
+ tls_max_version = _HTTP_TLS_1_0;
+ }
+ else if (!strcmp(argv[i], "--tls11"))
+ {
+ tls_min_version = _HTTP_TLS_1_1;
+ tls_max_version = _HTTP_TLS_1_1;
+ }
+ else if (!strcmp(argv[i], "--tls12"))
+ {
+ tls_min_version = _HTTP_TLS_1_2;
+ tls_max_version = _HTTP_TLS_1_2;
+ }
+ else if (!strcmp(argv[i], "--tls13"))
+ {
+ tls_min_version = _HTTP_TLS_1_3;
+ tls_max_version = _HTTP_TLS_1_3;
}
else if (!strcmp(argv[i], "--rc4"))
{
@@ -148,7 +166,7 @@ main(int argc, /* I - Number of command-line arguments */
if (!port)
port = 631;
- _httpTLSSetOptions(tls_options);
+ _httpTLSSetOptions(tls_options, tls_min_version, tls_max_version);
http = httpConnect2(server, port, NULL, af, HTTP_ENCRYPTION_ALWAYS, 1, 30000, NULL);
if (!http)
@@ -741,6 +759,9 @@ usage(void)
puts(" --no-tls10 Disable TLS/1.0");
puts(" --rc4 Allow RC4 encryption");
puts(" --tls10 Only use TLS/1.0");
+ puts(" --tls11 Only use TLS/1.1");
+ puts(" --tls12 Only use TLS/1.2");
+ puts(" --tls13 Only use TLS/1.3");
puts(" --verbose Be verbose");
puts(" -4 Connect using IPv4 addresses only");
puts(" -6 Connect using IPv6 addresses only");
diff --git a/cups/usersys.c b/cups/usersys.c
index 2a004b54..781f27bb 100644
--- a/cups/usersys.c
+++ b/cups/usersys.c
@@ -20,13 +20,13 @@
#include "cups-private.h"
#include <stdlib.h>
#include <sys/stat.h>
-#ifdef WIN32
+#ifdef _WIN32
# include <windows.h>
#else
# include <pwd.h>
# include <termios.h>
# include <sys/utsname.h>
-#endif /* WIN32 */
+#endif /* _WIN32 */
/*
@@ -54,7 +54,9 @@
typedef struct _cups_client_conf_s /**** client.conf config data ****/
{
#ifdef HAVE_SSL
- int ssl_options; /* SSLOptions values */
+ int ssl_options, /* SSLOptions values */
+ ssl_min_version,/* Minimum SSL/TLS version */
+ ssl_max_version;/* Maximum SSL/TLS version */
#endif /* HAVE_SSL */
int trust_first, /* Trust on first use? */
any_root, /* Allow any (e.g., self-signed) root */
@@ -488,12 +490,12 @@ cupsSetUserAgent(const char *user_agent)/* I - User-Agent string or @code NULL@
{
_cups_globals_t *cg = _cupsGlobals();
/* Thread globals */
-#ifdef WIN32
+#ifdef _WIN32
SYSTEM_INFO sysinfo; /* System information */
OSVERSIONINFO version; /* OS version info */
#else
struct utsname name; /* uname info */
-#endif /* WIN32 */
+#endif /* _WIN32 */
if (user_agent)
@@ -502,7 +504,7 @@ cupsSetUserAgent(const char *user_agent)/* I - User-Agent string or @code NULL@
return;
}
-#ifdef WIN32
+#ifdef _WIN32
version.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&version);
GetNativeSystemInfo(&sysinfo);
@@ -526,7 +528,7 @@ cupsSetUserAgent(const char *user_agent)/* I - User-Agent string or @code NULL@
snprintf(cg->user_agent, sizeof(cg->user_agent),
CUPS_MINIMAL " (%s %s; %s) IPP/2.0",
name.sysname, name.release, name.machine);
-#endif /* WIN32 */
+#endif /* _WIN32 */
}
@@ -578,7 +580,7 @@ cupsUserAgent(void)
const char * /* O - Password or @code NULL@ if none */
_cupsGetPassword(const char *prompt) /* I - Prompt string */
{
-#ifdef WIN32
+#ifdef _WIN32
HANDLE tty; /* Console handle */
DWORD mode; /* Console mode */
char passch, /* Current key press */
@@ -844,7 +846,7 @@ _cupsGetPassword(const char *prompt) /* I - Prompt string */
memset(cg->password, 0, sizeof(cg->password));
return (NULL);
}
-#endif /* WIN32 */
+#endif /* _WIN32 */
}
@@ -903,7 +905,7 @@ _cupsSetDefaults(void)
# ifdef HAVE_GETEUID
if ((geteuid() == getuid() || !getuid()) && getegid() == getgid() && (home = getenv("HOME")) != NULL)
-# elif !defined(WIN32)
+# elif !defined(_WIN32)
if (getuid() && (home = getenv("HOME")) != NULL)
# else
if ((home = getenv("HOME")) != NULL)
@@ -957,7 +959,7 @@ _cupsSetDefaults(void)
cg->validate_certs = cc.validate_certs;
#ifdef HAVE_SSL
- _httpTLSSetOptions(cc.ssl_options | _HTTP_TLS_SET_DEFAULT);
+ _httpTLSSetOptions(cc.ssl_options | _HTTP_TLS_SET_DEFAULT, cc.ssl_min_version, cc.ssl_max_version);
#endif /* HAVE_SSL */
}
@@ -1099,7 +1101,7 @@ cups_finalize_client_conf(
if (!cc->user[0])
{
-#ifdef WIN32
+#ifdef _WIN32
/*
* Get the current user name from the OS...
*/
@@ -1135,7 +1137,7 @@ cups_finalize_client_conf(
if (pw)
strlcpy(cc->user, pw->pw_name, sizeof(cc->user));
else
-#endif /* WIN32 */
+#endif /* _WIN32 */
{
/*
* Use the default "unknown" user name...
@@ -1164,11 +1166,15 @@ cups_init_client_conf(
memset(cc, 0, sizeof(_cups_client_conf_t));
- cc->encryption = (http_encryption_t)-1;
- cc->trust_first = -1;
- cc->any_root = -1;
- cc->expired_certs = -1;
- cc->validate_certs = -1;
+#ifdef HAVE_SSL
+ cc->ssl_min_version = _HTTP_TLS_1_0;
+ cc->ssl_max_version = _HTTP_TLS_MAX;
+#endif /* HAVE_SSL */
+ cc->encryption = (http_encryption_t)-1;
+ cc->trust_first = -1;
+ cc->any_root = -1;
+ cc->expired_certs = -1;
+ cc->validate_certs = -1;
/*
* Load settings from the org.cups.PrintingPrefs plist (which trump
@@ -1336,7 +1342,9 @@ cups_set_ssl_options(
* SSLOptions [AllowRC4] [AllowSSL3] [AllowDH] [DenyTLS1.0] [None]
*/
- int options = _HTTP_TLS_NONE; /* SSL/TLS options */
+ int options = _HTTP_TLS_NONE, /* SSL/TLS options */
+ min_version = _HTTP_TLS_1_0, /* Minimum SSL/TLS version */
+ max_version = _HTTP_TLS_MAX; /* Maximum SSL/TLS version */
char temp[256], /* Copy of value */
*start, /* Start of option */
*end; /* End of option */
@@ -1364,20 +1372,38 @@ cups_set_ssl_options(
if (!_cups_strcasecmp(start, "AllowRC4"))
options |= _HTTP_TLS_ALLOW_RC4;
else if (!_cups_strcasecmp(start, "AllowSSL3"))
- options |= _HTTP_TLS_ALLOW_SSL3;
+ min_version = _HTTP_TLS_SSL3;
else if (!_cups_strcasecmp(start, "AllowDH"))
options |= _HTTP_TLS_ALLOW_DH;
else if (!_cups_strcasecmp(start, "DenyCBC"))
options |= _HTTP_TLS_DENY_CBC;
else if (!_cups_strcasecmp(start, "DenyTLS1.0"))
- options |= _HTTP_TLS_DENY_TLS10;
+ min_version = _HTTP_TLS_1_1;
+ else if (!_cups_strcasecmp(start, "MaxTLS1.0"))
+ max_version = _HTTP_TLS_1_0;
+ else if (!_cups_strcasecmp(start, "MaxTLS1.1"))
+ max_version = _HTTP_TLS_1_1;
+ else if (!_cups_strcasecmp(start, "MaxTLS1.2"))
+ max_version = _HTTP_TLS_1_2;
+ else if (!_cups_strcasecmp(start, "MaxTLS1.3"))
+ max_version = _HTTP_TLS_1_3;
+ else if (!_cups_strcasecmp(start, "MinTLS1.0"))
+ min_version = _HTTP_TLS_1_0;
+ else if (!_cups_strcasecmp(start, "MinTLS1.1"))
+ min_version = _HTTP_TLS_1_1;
+ else if (!_cups_strcasecmp(start, "MinTLS1.2"))
+ min_version = _HTTP_TLS_1_2;
+ else if (!_cups_strcasecmp(start, "MinTLS1.3"))
+ min_version = _HTTP_TLS_1_3;
else if (!_cups_strcasecmp(start, "None"))
options = _HTTP_TLS_NONE;
}
- cc->ssl_options = options;
+ cc->ssl_options = options;
+ cc->ssl_max_version = max_version;
+ cc->ssl_min_version = min_version;
- DEBUG_printf(("4cups_set_ssl_options(cc=%p, value=\"%s\") options=%x", (void *)cc, value, options));
+ DEBUG_printf(("4cups_set_ssl_options(cc=%p, value=\"%s\") options=%x, min_version=%d, max_version=%d", (void *)cc, value, options, min_version, max_version));
}
#endif /* HAVE_SSL */
diff --git a/cups/util.c b/cups/util.c
index 2f5ebdf4..ef1709c5 100644
--- a/cups/util.c
+++ b/cups/util.c
@@ -1,8 +1,8 @@
/*
* Printing utilities for CUPS.
*
- * Copyright 2007-2017 by Apple Inc.
- * Copyright 1997-2006 by Easy Software Products.
+ * Copyright © 2007-2018 by Apple Inc.
+ * Copyright © 1997-2006 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
* property of Apple Inc. and are protected by Federal copyright
@@ -20,24 +20,11 @@
#include "cups-private.h"
#include <fcntl.h>
#include <sys/stat.h>
-#if defined(WIN32) || defined(__EMX__)
+#if defined(_WIN32) || defined(__EMX__)
# include <io.h>
#else
# include <unistd.h>
-#endif /* WIN32 || __EMX__ */
-
-
-/*
- * Enumeration data and callback...
- */
-
-typedef struct _cups_createdata_s
-{
- const char *name; /* Destination name */
- cups_dest_t *dest; /* Matching destination */
-} _cups_createdata_t;
-
-static int cups_create_cb(_cups_createdata_t *data, unsigned flags, cups_dest_t *dest);
+#endif /* _WIN32 || __EMX__ */
/*
@@ -174,7 +161,7 @@ cupsCreateJob(
{
int job_id = 0; /* job-id value */
ipp_status_t status; /* Create-Job status */
- _cups_createdata_t data; /* Enumeration data */
+ cups_dest_t *dest; /* Destination */
cups_dinfo_t *info; /* Destination information */
@@ -194,12 +181,7 @@ cupsCreateJob(
* Lookup the destination...
*/
- data.name = name;
- data.dest = NULL;
-
- cupsEnumDests(0, 1000, NULL, 0, 0, (cups_dest_cb_t)cups_create_cb, &data);
-
- if (!data.dest)
+ if ((dest = cupsGetNamedDest(http, name, NULL)) == NULL)
{
DEBUG_puts("1cupsCreateJob: Destination not found.");
_cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(ENOENT), 0);
@@ -211,18 +193,18 @@ cupsCreateJob(
*/
DEBUG_puts("1cupsCreateJob: Querying destination info.");
- if ((info = cupsCopyDestInfo(http, data.dest)) == NULL)
+ if ((info = cupsCopyDestInfo(http, dest)) == NULL)
{
DEBUG_puts("1cupsCreateJob: Query failed.");
- cupsFreeDests(1, data.dest);
+ cupsFreeDests(1, dest);
return (0);
}
- status = cupsCreateDestJob(http, data.dest, info, &job_id, title, num_options, options);
+ status = cupsCreateDestJob(http, dest, info, &job_id, title, num_options, options);
DEBUG_printf(("1cupsCreateJob: cupsCreateDestJob returned %04x (%s)", status, ippErrorString(status)));
cupsFreeDestInfo(info);
- cupsFreeDests(1, data.dest);
+ cupsFreeDests(1, dest);
/*
* Return the job...
@@ -974,25 +956,3 @@ cupsStartDocument(
return (status);
}
-
-/*
- * 'cups_create_cb()' - Find the destination for printing.
- */
-
-static int /* O - 0 on match */
-cups_create_cb(
- _cups_createdata_t *data, /* I - Data from cupsCreateJob call */
- unsigned flags, /* I - Enumeration flags */
- cups_dest_t *dest) /* I - Destination */
-{
- DEBUG_printf(("2cups_create_cb(data=%p(%s), flags=%08x, dest=%p(%s))", (void *)data, data->name, flags, (void *)dest, dest->name));
-
- (void)flags;
-
- if (dest->instance || strcasecmp(data->name, dest->name))
- return (1);
-
- cupsCopyDest(dest, 0, &data->dest);
-
- return (0);
-}
diff --git a/cups/versioning.h b/cups/versioning.h
index 5a000c05..620396f7 100644
--- a/cups/versioning.h
+++ b/cups/versioning.h
@@ -1,7 +1,7 @@
/*
* API versioning definitions for CUPS.
*
- * Copyright 2007-2017 by Apple Inc.
+ * Copyright © 2007-2018 by Apple Inc.
*
* These coded instructions, statements, and computer programs are the
* property of Apple Inc. and are protected by Federal copyright
@@ -16,83 +16,41 @@
# define _CUPS_VERSIONING_H_
/*
- * This header defines several constants - _CUPS_DEPRECATED,
- * _CUPS_DEPRECATED_MSG, _CUPS_INTERNAL_MSG, _CUPS_API_major_minor, and
- * _CUPS_API_major_minor_patch - which add compiler-specific attributes that
- * flag functions that are deprecated, added in particular releases, or internal
- * to CUPS.
+ * This header defines several macros that add compiler-specific attributes for
+ * functions:
*
- * On macOS, the _CUPS_API_* constants are defined based on the values of
- * the MAC_OS_X_VERSION_MIN_ALLOWED and MAC_OS_X_VERSION_MAX_ALLOWED constants
- * provided by the compiler.
+ * - _CUPS_API_major_minor[_patch]: Specifies when an API became available by
+ * CUPS version.
+ * - _CUPS_DEPRECATED: Function is deprecated with no replacement.
+ * - _CUPS_DEPRECATED_MSG("message"): Function is deprecated and has a
+ * replacement.
+ * - _CUPS_FORMAT(format-index, additional-args-index): Function has a
+ * printf-style format argument followed by zero or more additional
+ * arguments. Indices start at 1.
+ * - _CUPS_INTERNAL: Function is internal with no replacement API.
+ * - _CUPS_INTERNAL_MSG("msg"): Function is internal - use specified API
+ * instead.
+ * - _CUPS_NONNULL((arg list)): Specifies the comma-separated argument indices
+ * are assumed non-NULL. Indices start at 1.
+ * - _CUPS_NORETURN: Specifies the function does not return.
+ * - _CUPS_PRIVATE: Specifies the function is private to CUPS.
+ * - _CUPS_PUBLIC: Specifies the function is public API.
*/
-# if defined(__APPLE__) && !defined(_CUPS_SOURCE) && !TARGET_OS_IOS
-# include <AvailabilityMacros.h>
-# ifndef AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER
-# define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER __attribute__((unavailable))
-# endif /* !AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER */
-# ifndef AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER
-# define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER __attribute__((unavailable))
-# endif /* !AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER */
-# ifndef AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER
-# define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER __attribute__((unavailable))
-# endif /* !AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER */
-# ifndef AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER
-# define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER __attribute__((unavailable))
-# endif /* !AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER */
-# ifndef AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER
-# define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER __attribute__((unavailable))
-# endif /* !AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER */
-# ifndef AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER
-# define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER __attribute__((unavailable))
-# endif /* !AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER */
-# ifndef AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER
-# define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER __attribute__((unavailable))
-# endif /* !AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER */
-# ifndef AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER
-# define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER __attribute__((unavailable))
-# endif /* !AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER */
-# ifndef AVAILABLE_MAC_OS_X_VERSION_10_12_AND_LATER
-# define AVAILABLE_MAC_OS_X_VERSION_10_12_AND_LATER __attribute__((unavailable))
-# endif /* !AVAILABLE_MAC_OS_X_VERSION_10_12_AND_LATER */
-# ifndef AVAILABLE_MAC_OS_X_VERSION_10_13_AND_LATER
-# define AVAILABLE_MAC_OS_X_VERSION_10_13_AND_LATER __attribute__((unavailable))
-# endif /* !AVAILABLE_MAC_OS_X_VERSION_10_13_AND_LATER */
-# define _CUPS_API_1_1_19 AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER
-# define _CUPS_API_1_1_20 AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER
-# define _CUPS_API_1_1_21 AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER
-# define _CUPS_API_1_2 AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER
-# define _CUPS_API_1_3 AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER
-# define _CUPS_API_1_4 AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER
-# define _CUPS_API_1_5 AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER
-# define _CUPS_API_1_6 AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER
-# define _CUPS_API_1_7 AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER
-# define _CUPS_API_2_0 AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER
-# define _CUPS_API_2_2 AVAILABLE_MAC_OS_X_VERSION_10_12_AND_LATER
-# define _CUPS_API_2_2_4 AVAILABLE_MAC_OS_X_VERSION_10_13_AND_LATER
-# else
-# define _CUPS_API_1_1_19
-# define _CUPS_API_1_1_20
-# define _CUPS_API_1_1_21
-# define _CUPS_API_1_2
-# define _CUPS_API_1_3
-# define _CUPS_API_1_4
-# define _CUPS_API_1_5
-# define _CUPS_API_1_6
-# define _CUPS_API_1_7
-# define _CUPS_API_2_0
-# define _CUPS_API_2_2
-# define _CUPS_API_2_2_4
-# endif /* __APPLE__ && !_CUPS_SOURCE */
-
/*
- * With GCC and Clang we can mark old APIs as "deprecated" or "unavailable" with
- * messages so you get warnings/errors are compile-time...
+ * Determine which compiler is being used and what annotation features are
+ * available...
*/
+# ifdef __APPLE__
+# include <os/availability.h>
+# endif /* __APPLE__ */
+
# ifdef __has_extension /* Clang */
# define _CUPS_HAS_DEPRECATED
+# define _CUPS_HAS_FORMAT
+# define _CUPS_HAS_NORETURN
+# define _CUPS_HAS_VISIBILITY
# if __has_extension(attribute_deprecated_with_message)
# define _CUPS_HAS_DEPRECATED_WITH_MESSAGE
# endif
@@ -102,6 +60,9 @@
# elif defined(__GNUC__) /* GCC and compatible */
# if __GNUC__ >= 3 /* GCC 3.0 or higher */
# define _CUPS_HAS_DEPRECATED
+# define _CUPS_HAS_FORMAT
+# define _CUPS_HAS_NORETURN
+# define _CUPS_HAS_VISIBILITY
# endif /* __GNUC__ >= 3 */
# if __GNUC__ >= 5 /* GCC 5.x */
# define _CUPS_HAS_DEPRECATED_WITH_MESSAGE
@@ -109,61 +70,197 @@
/* GCC 4.5 or higher */
# define _CUPS_HAS_DEPRECATED_WITH_MESSAGE
# endif /* __GNUC__ >= 5 */
+# elif defined(_WIN32)
+# define __attribute__(...)
# endif /* __has_extension */
+
+/*
+ * Define _CUPS_INTERNAL, _CUPS_PRIVATE, and _CUPS_PUBLIC visibilty macros for
+ * internal/private/public functions...
+ */
+
+# ifdef _CUPS_HAS_VISIBILITY
+# define _CUPS_INTERNAL __attribute__ ((visibility("hidden")))
+# define _CUPS_PRIVATE __attribute__ ((visibility("default")))
+# define _CUPS_PUBLIC __attribute__ ((visibility("default")))
+# else
+# define _CUPS_INTERNAL
+# define _CUPS_PRIVATE
+# define _CUPS_PUBLIC
+# endif /* _CUPS_HAS_VISIBILITY */
+
+
+/*
+ * Define _CUPS_API_major_minor[_patch] availability macros for CUPS.
+ *
+ * Note: Using any of the _CUPS_API macros automatically adds _CUPS_PUBLIC.
+ */
+
+# if defined(__APPLE__) && !defined(_CUPS_SOURCE) && !TARGET_OS_IOS
+/*
+ * On Apple operating systems, the _CUPS_API_* constants are defined using the
+ * API_ macros in <os/availability.h>.
+ *
+ * On iOS, we don't actually have libcups available directly, but the supplied
+ * libcups_static target in the Xcode project supports building on iOS 11.0 and
+ * later.
+ */
+# define _CUPS_API_1_1_19 API_AVAILABLE(macos(10.3), ios(11.0)) _CUPS_PUBLIC
+# define _CUPS_API_1_1_20 API_AVAILABLE(macos(10.4), ios(11.0)) _CUPS_PUBLIC
+# define _CUPS_API_1_1_21 API_AVAILABLE(macos(10.4), ios(11.0)) _CUPS_PUBLIC
+# define _CUPS_API_1_2 API_AVAILABLE(macos(10.5), ios(11.0)) _CUPS_PUBLIC
+# define _CUPS_API_1_3 API_AVAILABLE(macos(10.5), ios(11.0)) _CUPS_PUBLIC
+# define _CUPS_API_1_4 API_AVAILABLE(macos(10.6), ios(11.0)) _CUPS_PUBLIC
+# define _CUPS_API_1_5 API_AVAILABLE(macos(10.7), ios(11.0)) _CUPS_PUBLIC
+# define _CUPS_API_1_6 API_AVAILABLE(macos(10.8), ios(11.0)) _CUPS_PUBLIC
+# define _CUPS_API_1_7 API_AVAILABLE(macos(10.9), ios(11.0)) _CUPS_PUBLIC
+# define _CUPS_API_2_0 API_AVAILABLE(macos(10.10), ios(11.0)) _CUPS_PUBLIC
+# define _CUPS_API_2_2 API_AVAILABLE(macos(10.12), ios(11.0)) _CUPS_PUBLIC
+# define _CUPS_API_2_2_4 API_AVAILABLE(macos(10.13), ios(11.0)) _CUPS_PUBLIC
+# define _CUPS_API_2_2_7 API_AVAILABLE(macos(10.14), ios(11.0)) _CUPS_PUBLIC
+# else
+# define _CUPS_API_1_1_19 _CUPS_PUBLIC
+# define _CUPS_API_1_1_20 _CUPS_PUBLIC
+# define _CUPS_API_1_1_21 _CUPS_PUBLIC
+# define _CUPS_API_1_2 _CUPS_PUBLIC
+# define _CUPS_API_1_3 _CUPS_PUBLIC
+# define _CUPS_API_1_4 _CUPS_PUBLIC
+# define _CUPS_API_1_5 _CUPS_PUBLIC
+# define _CUPS_API_1_6 _CUPS_PUBLIC
+# define _CUPS_API_1_7 _CUPS_PUBLIC
+# define _CUPS_API_2_0 _CUPS_PUBLIC
+# define _CUPS_API_2_2 _CUPS_PUBLIC
+# define _CUPS_API_2_2_4 _CUPS_PUBLIC
+# define _CUPS_API_2_2_7 _CUPS_PUBLIC
+# endif /* __APPLE__ && !_CUPS_SOURCE */
+
+
+/*
+ * Define _CUPS_DEPRECATED and _CUPS_INTERNAL macros to mark old APIs as
+ * "deprecated" or "unavailable" with messages so you get warnings/errors are
+ * compile-time...
+ *
+ * Note: Using any of the _CUPS_DEPRECATED macros automatically adds
+ * _CUPS_PUBLIC.
+ */
+
# if !defined(_CUPS_HAS_DEPRECATED) || (defined(_CUPS_SOURCE) && !defined(_CUPS_NO_DEPRECATED))
/*
* Don't mark functions deprecated if the compiler doesn't support it
* or we are building CUPS source that doesn't care.
*/
-# define _CUPS_DEPRECATED
-# define _CUPS_DEPRECATED_MSG(m)
-# define _CUPS_DEPRECATED_1_6_MSG(m)
-# define _CUPS_DEPRECATED_1_7_MSG(m)
-# define _CUPS_INTERNAL_MSG(m)
+# define _CUPS_DEPRECATED _CUPS_PUBLIC
+# define _CUPS_DEPRECATED_MSG(m) _CUPS_PUBLIC
+# define _CUPS_DEPRECATED_1_2_MSG(m) _CUPS_PUBLIC
+# define _CUPS_DEPRECATED_1_6_MSG(m) _CUPS_PUBLIC
+# define _CUPS_DEPRECATED_1_7_MSG(m) _CUPS_PUBLIC
+# define _CUPS_DEPRECATED_2_2_MSG(m) _CUPS_PUBLIC
+# elif defined(__APPLE__) && defined(_CUPS_NO_DEPRECATED)
+ /*
+ * Compiler supports the unavailable attribute, so use it when the code
+ * wants to exclude the use of deprecated API.
+ */
+# define _CUPS_DEPRECATED __attribute__ ((unavailable)) _CUPS_PUBLIC
+# define _CUPS_DEPRECATED_MSG(m) __attribute__ ((unavailable(m))) _CUPS_PUBLIC
+# define _CUPS_DEPRECATED_1_2_MSG(m) API_DEPRECATED(m, macos(10.2,10.5)) API_UNAVAILABLE(ios) _CUPS_PUBLIC
+# define _CUPS_DEPRECATED_1_6_MSG(m) API_DEPRECATED(m, macos(10.2,10.8)) API_UNAVAILABLE(ios) _CUPS_PUBLIC
+# define _CUPS_DEPRECATED_1_7_MSG(m) API_DEPRECATED(m, macos(10.2,10.9)) API_UNAVAILABLE(ios) _CUPS_PUBLIC
+# define _CUPS_DEPRECATED_2_2_MSG(m) API_DEPRECATED(m, macos(10.2,10.12)) API_UNAVAILABLE(ios) _CUPS_PUBLIC
+
+# elif defined(__APPLE__)
+ /*
+ * Just mark things as deprecated...
+ */
+# define _CUPS_DEPRECATED __attribute__ ((deprecated)) _CUPS_PUBLIC
+# define _CUPS_DEPRECATED_MSG(m) __attribute__ ((deprecated(m))) _CUPS_PUBLIC
+# define _CUPS_DEPRECATED_1_2_MSG(m) API_DEPRECATED(m, macos(10.2,10.5)) API_UNAVAILABLE(ios) _CUPS_PUBLIC
+# define _CUPS_DEPRECATED_1_6_MSG(m) API_DEPRECATED(m, macos(10.2,10.8)) API_UNAVAILABLE(ios) _CUPS_PUBLIC
+# define _CUPS_DEPRECATED_1_7_MSG(m) API_DEPRECATED(m, macos(10.2,10.9)) API_UNAVAILABLE(ios) _CUPS_PUBLIC
+# define _CUPS_DEPRECATED_2_2_MSG(m) API_DEPRECATED(m, macos(10.2,10.12)) API_UNAVAILABLE(ios) _CUPS_PUBLIC
+
# elif defined(_CUPS_HAS_UNAVAILABLE_WITH_MESSAGE) && defined(_CUPS_NO_DEPRECATED)
/*
* Compiler supports the unavailable attribute, so use it when the code
* wants to exclude the use of deprecated API.
*/
-# define _CUPS_DEPRECATED __attribute__ ((unavailable))
-# define _CUPS_DEPRECATED_MSG(m) __attribute__ ((unavailable(m)))
-# define _CUPS_DEPRECATED_1_6_MSG(m) __attribute__ ((unavailable(m)))
-# define _CUPS_DEPRECATED_1_7_MSG(m) __attribute__ ((unavailable(m)))
-# define _CUPS_INTERNAL_MSG(m) __attribute__ ((unavailable(m)))
+# define _CUPS_DEPRECATED __attribute__ ((unavailable)) _CUPS_PUBLIC
+# define _CUPS_DEPRECATED_MSG(m) __attribute__ ((unavailable(m))) _CUPS_PUBLIC
+# define _CUPS_DEPRECATED_1_2_MSG(m) __attribute__ ((unavailable(m))) _CUPS_PUBLIC
+# define _CUPS_DEPRECATED_1_6_MSG(m) __attribute__ ((unavailable(m))) _CUPS_PUBLIC
+# define _CUPS_DEPRECATED_1_7_MSG(m) __attribute__ ((unavailable(m))) _CUPS_PUBLIC
+# define _CUPS_DEPRECATED_2_2_MSG(m) __attribute__ ((unavailable(m))) _CUPS_PUBLIC
# else
/*
* Compiler supports the deprecated attribute, so use it.
*/
-# define _CUPS_DEPRECATED __attribute__ ((deprecated))
+# define _CUPS_DEPRECATED __attribute__ ((deprecated)) _CUPS_PUBLIC
# ifdef _CUPS_HAS_DEPRECATED_WITH_MESSAGE
-# define _CUPS_DEPRECATED_MSG(m) __attribute__ ((deprecated(m)))
+# define _CUPS_DEPRECATED_MSG(m) __attribute__ ((deprecated(m))) _CUPS_PUBLIC
+# define _CUPS_DEPRECATED_1_2_MSG(m) __attribute__ ((deprecated(m))) _CUPS_PUBLIC
+# define _CUPS_DEPRECATED_1_6_MSG(m) __attribute__ ((deprecated(m))) _CUPS_PUBLIC
+# define _CUPS_DEPRECATED_1_7_MSG(m) __attribute__ ((deprecated(m))) _CUPS_PUBLIC
+# define _CUPS_DEPRECATED_2_2_MSG(m) __attribute__ ((deprecated(m))) _CUPS_PUBLIC
# else
-# define _CUPS_DEPRECATED_MSG(m) __attribute__ ((deprecated))
+# define _CUPS_DEPRECATED_MSG(m) __attribute__ ((deprecated)) _CUPS_PUBLIC
+# define _CUPS_DEPRECATED_1_2_MSG(m) __attribute__ ((deprecated)) _CUPS_PUBLIC
+# define _CUPS_DEPRECATED_1_6_MSG(m) __attribute__ ((deprecated)) _CUPS_PUBLIC
+# define _CUPS_DEPRECATED_1_7_MSG(m) __attribute__ ((deprecated)) _CUPS_PUBLIC
+# define _CUPS_DEPRECATED_2_2_MSG(m) __attribute__ ((deprecated)) _CUPS_PUBLIC
# endif /* _CUPS_HAS_DEPRECATED_WITH_MESSAGE */
-# if defined(MAC_OS_X_VERSION_10_8) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_8
-# define _CUPS_DEPRECATED_1_6_MSG(m) _CUPS_DEPRECATED_MSG(m)
-# else
-# define _CUPS_DEPRECATED_1_6_MSG(m)
-# endif /* MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_8 */
-# if defined(MAC_OS_X_VERSION_10_9) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9
-# define _CUPS_DEPRECATED_1_7_MSG(m) _CUPS_DEPRECATED_MSG(m)
-# else
-# define _CUPS_DEPRECATED_1_7_MSG(m)
-# endif /* MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_9 */
-# ifdef _CUPS_SOURCE
-# define _CUPS_INTERNAL_MSG(m)
-# elif defined(_CUPS_HAS_UNAVAILABLE_WITH_MESSAGE)
-# define _CUPS_INTERNAL_MSG(m) __attribute__ ((unavailable(m)))
-# elif defined(_CUPS_HAS_DEPRECATED_WITH_MESSAGE)
-# define _CUPS_INTERNAL_MSG(m) __attribute__ ((deprecated(m)))
-# else
-# define _CUPS_INTERNAL_MSG(m) __attribute__ ((deprecated))
-# endif /* _CUPS_SOURCE */
# endif /* !_CUPS_HAS_DEPRECATED || (_CUPS_SOURCE && !_CUPS_NO_DEPRECATED) */
-# ifndef __GNUC__
-# define __attribute__(x)
-# endif /* !__GNUC__ */
+
+/*
+ * Define _CUPS_FORMAT macro for printf-style functions...
+ */
+
+# ifdef _CUPS_HAS_FORMAT
+# define _CUPS_FORMAT(a,b) __attribute__ ((__format__(__printf__, a,b)))
+# else
+# define _CUPS_FORMAT(a,b)
+# endif /* _CUPS_HAS_FORMAT */
+
+
+/*
+ * Define _CUPS_INTERNAL_MSG macro for private APIs that have (historical)
+ * public visibility.
+ *
+ * Note: Using the _CUPS_INTERNAL_MSG macro automatically adds _CUPS_PUBLIC.
+ */
+
+# ifdef _CUPS_SOURCE
+# define _CUPS_INTERNAL_MSG(m) _CUPS_PUBLIC
+# elif defined(_CUPS_HAS_UNAVAILABLE_WITH_MESSAGE)
+# define _CUPS_INTERNAL_MSG(m) __attribute__ ((unavailable(m))) _CUPS_PUBLIC
+# elif defined(_CUPS_HAS_DEPRECATED_WITH_MESSAGE)
+# define _CUPS_INTERNAL_MSG(m) __attribute__ ((deprecated(m))) _CUPS_PUBLIC
+# else
+# define _CUPS_INTERNAL_MSG(m) __attribute__ ((deprecated)) _CUPS_PUBLIC
+# endif /* _CUPS_SOURCE */
+
+
+/*
+ * Define _CUPS_NONNULL macro for functions that don't expect non-null
+ * arguments...
+ */
+
+# ifdef _CUPS_HAS_NONNULL
+# define _CUPS_NONNULL(...) __attribute__ ((nonnull(__VA_ARGS__)))
+# else
+# define _CUPS_NONNULL(...)
+# endif /* _CUPS_HAS_FORMAT */
+
+
+/*
+ * Define _CUPS_NORETURN macro for functions that don't return.
+ */
+
+# ifdef _CUPS_HAS_NORETURN
+# define _CUPS_NORETURN __attribute__ ((noreturn))
+# else
+# define _CUPS_NORETURN
+# endif /* _CUPS_HAS_NORETURN */
+
#endif /* !_CUPS_VERSIONING_H_ */
diff --git a/filter/Makefile b/filter/Makefile
index 02aab14d..74fd46f4 100644
--- a/filter/Makefile
+++ b/filter/Makefile
@@ -218,6 +218,7 @@ apihelp:
commandtops: commandtops.o ../cups/$(LIBCUPS)
echo Linking $@...
$(LD_CC) $(LDFLAGS) -o $@ commandtops.o $(LIBS)
+ $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@
#
@@ -227,6 +228,7 @@ commandtops: commandtops.o ../cups/$(LIBCUPS)
gziptoany: gziptoany.o ../Makedefs ../cups/$(LIBCUPS)
echo Linking $@...
$(LD_CC) $(LDFLAGS) -o $@ gziptoany.o $(LIBZ) $(LIBS)
+ $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@
#
@@ -235,8 +237,9 @@ gziptoany: gziptoany.o ../Makedefs ../cups/$(LIBCUPS)
libcupsimage.so.2 libcupsimage.sl.2: $(IMAGEOBJS)
echo Linking $@...
- $(DSO) $(ARCHFLAGS) $(DSOFLAGS) -o $@ $(IMAGEOBJS) $(DSOLIBS) \
+ $(DSO) $(ARCHFLAGS) $(LDFLAGS) $(DSOFLAGS) -o $@ $(IMAGEOBJS) $(DSOLIBS) \
-L../cups $(LINKCUPS)
+ $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@
$(RM) `basename $@ .2`
$(LN) $@ `basename $@ .2`
@@ -247,34 +250,23 @@ libcupsimage.so.2 libcupsimage.sl.2: $(IMAGEOBJS)
libcupsimage.2.dylib: $(IMAGEOBJS) $(LIBCUPSIMAGEORDER)
echo Linking $@...
- $(DSO) $(ARCHFLAGS) $(DSOFLAGS) -o $@ \
+ $(DSO) $(ARCHFLAGS) $(LDFLAGS) $(DSOFLAGS) -o $@ \
-install_name $(libdir)/$@ \
-current_version 2.3.0 \
-compatibility_version 2.0.0 \
$(IMAGEOBJS) $(DSOLIBS) -L../cups $(LINKCUPS)
+ $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@
$(RM) libcupsimage.dylib
$(LN) $@ libcupsimage.dylib
#
-# libcupsimage_s.a
-#
-
-libcupsimage_s.a: $(IMAGEOBJS) libcupsimage_s.exp
- echo Linking $@...
- $(DSO) $(DSOFLAGS) -Wl,-berok,-bexport:libcupsimage_s.exp \
- -o libcupsimage_s.o $(IMAGEOBJS) $(DSOLIBS)
- $(RM) $@
- $(AR) $(ARFLAGS) $@ libcupsimage_s.o
-
-
-#
# libcupsimage.la
#
libcupsimage.la: $(IMAGEOBJS)
echo Linking $@...
- $(DSO) $(ARCHFLAGS) $(DSOFLAGS) -o $@ $(IMAGEOBJS:.o=.lo) $(DSOLIBS) \
+ $(DSO) $(ARCHFLAGS) $(LDFLAGS) $(DSOFLAGS) -o $@ $(IMAGEOBJS:.o=.lo) $(DSOLIBS) \
-L../cups $(LINKCUPS) \
-rpath $(LIBDIR) -version-info 2:3
@@ -297,6 +289,7 @@ libcupsimage.a: $(IMAGEOBJS)
pstops: pstops.o common.o ../cups/$(LIBCUPS)
echo Linking $@...
$(LD_CC) $(LDFLAGS) -o $@ pstops.o common.o $(LIBS)
+ $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@
#
@@ -306,6 +299,7 @@ pstops: pstops.o common.o ../cups/$(LIBCUPS)
rastertoepson: rastertoepson.o ../cups/$(LIBCUPS) $(LIBCUPSIMAGE)
echo Linking $@...
$(LD_CC) $(LDFLAGS) -o $@ rastertoepson.o $(LINKCUPSIMAGE) $(IMGLIBS) $(LIBS)
+ $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@
#
@@ -315,6 +309,7 @@ rastertoepson: rastertoepson.o ../cups/$(LIBCUPS) $(LIBCUPSIMAGE)
rastertohp: rastertohp.o ../cups/$(LIBCUPS) $(LIBCUPSIMAGE)
echo Linking $@...
$(LD_CC) $(LDFLAGS) -o $@ rastertohp.o $(LINKCUPSIMAGE) $(IMGLIBS) $(LIBS)
+ $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@
#
@@ -324,6 +319,7 @@ rastertohp: rastertohp.o ../cups/$(LIBCUPS) $(LIBCUPSIMAGE)
rastertolabel: rastertolabel.o ../cups/$(LIBCUPS) $(LIBCUPSIMAGE)
echo Linking $@...
$(LD_CC) $(LDFLAGS) -o $@ rastertolabel.o $(LINKCUPSIMAGE) $(IMGLIBS) $(LIBS)
+ $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@
#
@@ -333,12 +329,14 @@ rastertolabel: rastertolabel.o ../cups/$(LIBCUPS) $(LIBCUPSIMAGE)
rastertopwg: rastertopwg.o ../cups/$(LIBCUPS) $(LIBCUPSIMAGE)
echo Linking $@...
$(LD_CC) $(LDFLAGS) -o $@ rastertopwg.o $(LINKCUPSIMAGE) $(IMGLIBS) $(LIBS)
+ $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@
rastertopwg-static: rastertopwg.o ../cups/$(LIBCUPSSTATIC) libcupsimage.a
echo Linking $@...
$(LD_CC) $(LDFLAGS) -o $@ rastertopwg.o libcupsimage.a \
../cups/$(LIBCUPSSTATIC) $(IMGLIBS) $(DSOLIBS) $(COMMONLIBS) \
$(SSLLIBS) $(DNSSDLIBS) $(LIBGSSAPI)
+ $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@
#
@@ -350,6 +348,7 @@ testclient: testclient.o ../cups/$(LIBCUPSSTATIC) libcupsimage.a
$(LD_CC) $(LDFLAGS) -o $@ testclient.o \
libcupsimage.a ../cups/$(LIBCUPSSTATIC) \
$(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ)
+ $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@
#
@@ -361,6 +360,7 @@ testraster: testraster.o ../cups/$(LIBCUPSSTATIC) libcupsimage.a
$(LD_CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testraster.o libcupsimage.a \
../cups/$(LIBCUPSSTATIC) $(IMGLIBS) $(DSOLIBS) $(COMMONLIBS) \
$(SSLLIBS) $(DNSSDLIBS) $(LIBGSSAPI)
+ $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@
echo Running raster API tests...
./testraster
@@ -372,6 +372,7 @@ testraster: testraster.o ../cups/$(LIBCUPSSTATIC) libcupsimage.a
rasterbench: rasterbench.o libcupsimage.a
echo Linking $@...
$(LD_CC) $(LDFLAGS) -o $@ rasterbench.o libcupsimage.a $(LIBS)
+ $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@
#
diff --git a/filter/pstops.c b/filter/pstops.c
index 072356e2..fab60d93 100644
--- a/filter/pstops.c
+++ b/filter/pstops.c
@@ -1,8 +1,8 @@
/*
* PostScript filter for CUPS.
*
- * Copyright 2007-2015 by Apple Inc.
- * Copyright 1993-2007 by Easy Software Products.
+ * Copyright © 2007-2018 by Apple Inc.
+ * Copyright © 1993-2007 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
* property of Apple Inc. and are protected by Federal copyright
@@ -162,8 +162,7 @@ static ssize_t copy_trailer(cups_file_t *fp, pstops_doc_t *doc,
ssize_t linelen, size_t linesize);
static void do_prolog(pstops_doc_t *doc, ppd_file_t *ppd);
static void do_setup(pstops_doc_t *doc, ppd_file_t *ppd);
-static void doc_printf(pstops_doc_t *doc, const char *format, ...)
- __attribute__ ((__format__ (__printf__, 2, 3)));
+static void doc_printf(pstops_doc_t *doc, const char *format, ...) _CUPS_FORMAT(2, 3);
static void doc_puts(pstops_doc_t *doc, const char *s);
static void doc_write(pstops_doc_t *doc, const char *s, size_t len);
static void end_nup(pstops_doc_t *doc, int number);
@@ -2235,7 +2234,7 @@ parse_text(const char *start, /* I - Start of text value */
bufptr = buffer;
bufend = buffer + bufsize - 1;
- while (bufptr < bufend)
+ while (*start && bufptr < bufend)
{
if (isspace(*start & 255) && !level)
break;
diff --git a/filter/raster.c b/filter/raster.c
index bacf5ba7..3ff03008 100644
--- a/filter/raster.c
+++ b/filter/raster.c
@@ -1,7 +1,7 @@
/*
* Raster file routines for CUPS.
*
- * Copyright 2007-2016 by Apple Inc.
+ * Copyright 2007-2018 by Apple Inc.
* Copyright 1997-2006 by Easy Software Products.
*
* This file is part of the CUPS Imaging library.
@@ -50,11 +50,96 @@ struct _cups_raster_s /**** Raster stream data ****/
*bufend; /* End of current (read) buffer */
size_t bufsize; /* Buffer size */
#ifdef DEBUG
- size_t iocount; /* Number of bytes read/written */
+ size_t iostart, /* Start of read/write buffer */
+ iocount; /* Number of bytes read/written */
#endif /* DEBUG */
unsigned apple_page_count;/* Apple raster page count */
};
+typedef void (*_cups_copyfunc_t)(void *dst, const void *src, size_t bytes);
+
+
+/*
+ * Local globals...
+ */
+
+#ifdef DEBUG
+ static const char * const cups_color_spaces[] =
+ { /* Color spaces */
+ "CUPS_CSPACE_W",
+ "CUPS_CSPACE_RGB",
+ "CUPS_CSPACE_RGBA",
+ "CUPS_CSPACE_K",
+ "CUPS_CSPACE_CMY",
+ "CUPS_CSPACE_YMC",
+ "CUPS_CSPACE_CMYK",
+ "CUPS_CSPACE_YMCK",
+ "CUPS_CSPACE_KCMY",
+ "CUPS_CSPACE_KCMYcm",
+ "CUPS_CSPACE_GMCK",
+ "CUPS_CSPACE_GMCS",
+ "CUPS_CSPACE_WHITE",
+ "CUPS_CSPACE_GOLD",
+ "CUPS_CSPACE_SILVER",
+ "CUPS_CSPACE_CIEXYZ",
+ "CUPS_CSPACE_CIELab",
+ "CUPS_CSPACE_RGBW",
+ "CUPS_CSPACE_SW",
+ "CUPS_CSPACE_SRGB",
+ "CUPS_CSPACE_ADOBERGB",
+ "21",
+ "22",
+ "23",
+ "24",
+ "25",
+ "26",
+ "27",
+ "28",
+ "29",
+ "30",
+ "31",
+ "CUPS_CSPACE_ICC1",
+ "CUPS_CSPACE_ICC2",
+ "CUPS_CSPACE_ICC3",
+ "CUPS_CSPACE_ICC4",
+ "CUPS_CSPACE_ICC5",
+ "CUPS_CSPACE_ICC6",
+ "CUPS_CSPACE_ICC7",
+ "CUPS_CSPACE_ICC8",
+ "CUPS_CSPACE_ICC9",
+ "CUPS_CSPACE_ICCA",
+ "CUPS_CSPACE_ICCB",
+ "CUPS_CSPACE_ICCC",
+ "CUPS_CSPACE_ICCD",
+ "CUPS_CSPACE_ICCE",
+ "CUPS_CSPACE_ICCF",
+ "47",
+ "CUPS_CSPACE_DEVICE1",
+ "CUPS_CSPACE_DEVICE2",
+ "CUPS_CSPACE_DEVICE3",
+ "CUPS_CSPACE_DEVICE4",
+ "CUPS_CSPACE_DEVICE5",
+ "CUPS_CSPACE_DEVICE6",
+ "CUPS_CSPACE_DEVICE7",
+ "CUPS_CSPACE_DEVICE8",
+ "CUPS_CSPACE_DEVICE9",
+ "CUPS_CSPACE_DEVICEA",
+ "CUPS_CSPACE_DEVICEB",
+ "CUPS_CSPACE_DEVICEC",
+ "CUPS_CSPACE_DEVICED",
+ "CUPS_CSPACE_DEVICEE",
+ "CUPS_CSPACE_DEVICEF"
+ };
+ static const char * const cups_modes[] =
+ { /* Open modes */
+ "CUPS_RASTER_READ",
+ "CUPS_RASTER_WRITE",
+ "CUPS_RASTER_WRITE_COMPRESSED",
+ "CUPS_RASTER_WRITE_PWG",
+ "CUPS_RASTER_WRITE_APPLE"
+ };
+#endif /* DEBUG */
+
/*
* Local functions...
@@ -62,13 +147,12 @@ struct _cups_raster_s /**** Raster stream data ****/
static ssize_t cups_raster_io(cups_raster_t *r, unsigned char *buf, size_t bytes);
static unsigned cups_raster_read_header(cups_raster_t *r);
-static ssize_t cups_raster_read(cups_raster_t *r, unsigned char *buf,
- size_t bytes);
+static ssize_t cups_raster_read(cups_raster_t *r, unsigned char *buf, size_t bytes);
static int cups_raster_update(cups_raster_t *r);
-static ssize_t cups_raster_write(cups_raster_t *r,
- const unsigned char *pixels);
+static ssize_t cups_raster_write(cups_raster_t *r, const unsigned char *pixels);
static ssize_t cups_read_fd(void *ctx, unsigned char *buf, size_t bytes);
static void cups_swap(unsigned char *buf, size_t bytes);
+static void cups_swap_copy(unsigned char *dst, const unsigned char *src, size_t bytes);
static ssize_t cups_write_fd(void *ctx, unsigned char *buf, size_t bytes);
@@ -356,6 +440,8 @@ cupsRasterOpen(int fd, /* I - File descriptor */
@code CUPS_RASTER_WRITE_COMPRESSED@,
or @code CUPS_RASTER_WRITE_PWG@ */
{
+ DEBUG_printf(("cupsRasterOpen(fd=%d, mode=%s)", fd, cups_modes[mode]));
+
if (mode == CUPS_RASTER_READ)
return (cupsRasterOpenIO(cups_read_fd, (void *)((intptr_t)fd), mode));
else
@@ -387,12 +473,15 @@ cupsRasterOpenIO(
cups_raster_t *r; /* New stream */
+ DEBUG_printf(("cupsRasterOpenIO(iocb=%p, ctx=%p, mode=%s)", (void *)iocb, ctx, cups_modes[mode]));
+
_cupsRasterClearError();
if ((r = calloc(sizeof(cups_raster_t), 1)) == NULL)
{
_cupsRasterAddError("Unable to allocate memory for raster stream: %s\n",
strerror(errno));
+ DEBUG_puts("1cupsRasterOpenIO: Returning NULL.");
return (NULL);
}
@@ -412,6 +501,7 @@ cupsRasterOpenIO(
_cupsRasterAddError("Unable to read header from raster stream: %s\n",
strerror(errno));
free(r);
+ DEBUG_puts("1cupsRasterOpenIO: Unable to read header, returning NULL.");
return (NULL);
}
@@ -426,6 +516,7 @@ cupsRasterOpenIO(
{
_cupsRasterAddError("Unknown raster format %08x!\n", r->sync);
free(r);
+ DEBUG_puts("1cupsRasterOpenIO: Unknown format, returning NULL.");
return (NULL);
}
@@ -435,6 +526,8 @@ cupsRasterOpenIO(
r->sync == CUPS_RASTER_REVSYNCapple)
r->compressed = 1;
+ DEBUG_printf(("1cupsRasterOpenIO: sync=%08x", r->sync));
+
if (r->sync == CUPS_RASTER_REVSYNC ||
r->sync == CUPS_RASTER_REVSYNCv1 ||
r->sync == CUPS_RASTER_REVSYNCv2 ||
@@ -452,12 +545,14 @@ cupsRasterOpenIO(
_cupsRasterAddError("Unable to read header from raster stream: %s\n",
strerror(errno));
free(r);
+ DEBUG_puts("1cupsRasterOpenIO: Unable to read header, returning NULL.");
return (NULL);
}
-
}
- DEBUG_printf(("1cupsRasterOpenIO: r->swapped=%d, r->sync=%08x\n", r->swapped, r->sync));
+#ifdef DEBUG
+ r->iostart = r->iocount;
+#endif /* DEBUG */
}
else
{
@@ -496,10 +591,13 @@ cupsRasterOpenIO(
_cupsRasterAddError("Unable to write raster stream header: %s\n",
strerror(errno));
free(r);
+ DEBUG_puts("1cupsRasterOpenIO: Unable to write header, returning NULL.");
return (NULL);
}
}
+ DEBUG_printf(("1cupsRasterOpenIO: compressed=%d, swapped=%d, returning %p", r->compressed, r->swapped, (void *)r));
+
return (r);
}
@@ -522,6 +620,8 @@ cupsRasterReadHeader(
cups_raster_t *r, /* I - Raster stream */
cups_page_header_t *h) /* I - Pointer to header data */
{
+ DEBUG_printf(("cupsRasterReadHeader(r=%p, h=%p)", (void *)r, (void *)h));
+
/*
* Get the raster header...
*/
@@ -529,6 +629,7 @@ cupsRasterReadHeader(
if (!cups_raster_read_header(r))
{
memset(h, 0, sizeof(cups_page_header_t));
+ DEBUG_puts("1cupsRasterReadHeader: Unable to read page header, returning 0.");
return (0);
}
@@ -538,6 +639,14 @@ cupsRasterReadHeader(
memcpy(h, &(r->header), sizeof(cups_page_header_t));
+ DEBUG_printf(("1cupsRasterReadHeader: cupsColorSpace=%s", cups_color_spaces[h->cupsColorSpace]));
+ DEBUG_printf(("1cupsRasterReadHeader: cupsBitsPerColor=%u", h->cupsBitsPerColor));
+ DEBUG_printf(("1cupsRasterReadHeader: cupsBitsPerPixel=%u", h->cupsBitsPerPixel));
+ DEBUG_printf(("1cupsRasterReadHeader: cupsBytesPerLine=%u", h->cupsBytesPerLine));
+ DEBUG_printf(("1cupsRasterReadHeader: cupsWidth=%u", h->cupsWidth));
+ DEBUG_printf(("1cupsRasterReadHeader: cupsHeight=%u", h->cupsHeight));
+
+ DEBUG_puts("1cupsRasterReadHeader: Returning 1.");
return (1);
}
@@ -563,6 +672,7 @@ cupsRasterReadHeader2(
if (!cups_raster_read_header(r))
{
memset(h, 0, sizeof(cups_page_header2_t));
+ DEBUG_puts("1cupsRasterReadHeader2: Unable to read header, returning 0.");
return (0);
}
@@ -572,6 +682,14 @@ cupsRasterReadHeader2(
memcpy(h, &(r->header), sizeof(cups_page_header2_t));
+ DEBUG_printf(("1cupsRasterReadHeader2: cupsColorSpace=%s", cups_color_spaces[h->cupsColorSpace]));
+ DEBUG_printf(("1cupsRasterReadHeader2: cupsBitsPerColor=%u", h->cupsBitsPerColor));
+ DEBUG_printf(("1cupsRasterReadHeader2: cupsBitsPerPixel=%u", h->cupsBitsPerPixel));
+ DEBUG_printf(("1cupsRasterReadHeader2: cupsBytesPerLine=%u", h->cupsBytesPerLine));
+ DEBUG_printf(("1cupsRasterReadHeader2: cupsWidth=%u", h->cupsWidth));
+ DEBUG_printf(("1cupsRasterReadHeader2: cupsHeight=%u", h->cupsHeight));
+
+ DEBUG_puts("1cupsRasterReadHeader2: Returning 1.");
return (1);
}
@@ -777,7 +895,10 @@ cupsRasterReadPixels(cups_raster_t *r, /* I - Raster stream */
r->header.cupsBitsPerPixel == 12 ||
r->header.cupsBitsPerPixel == 16) &&
r->swapped)
- cups_swap(ptr, (size_t)bytes);
+ {
+ DEBUG_puts("1cupsRasterReadPixels: Swapping bytes.");
+ cups_swap(ptr, (size_t)cupsBytesPerLine);
+ }
/*
* Update pointers...
@@ -847,8 +968,20 @@ cupsRasterWriteHeader(
cups_raster_t *r, /* I - Raster stream */
cups_page_header_t *h) /* I - Raster page header */
{
+ DEBUG_printf(("cupsRasterWriteHeader(r=%p, h=%p)", (void *)r, (void *)h));
+
if (r == NULL || r->mode == CUPS_RASTER_READ)
+ {
+ DEBUG_puts("1cupsRasterWriteHeader: Returning 0.");
return (0);
+ }
+
+ DEBUG_printf(("1cupsRasterWriteHeader: cupsColorSpace=%s", cups_color_spaces[h->cupsColorSpace]));
+ DEBUG_printf(("1cupsRasterWriteHeader: cupsBitsPerColor=%u", h->cupsBitsPerColor));
+ DEBUG_printf(("1cupsRasterWriteHeader: cupsBitsPerPixel=%u", h->cupsBitsPerPixel));
+ DEBUG_printf(("1cupsRasterWriteHeader: cupsBytesPerLine=%u", h->cupsBytesPerLine));
+ DEBUG_printf(("1cupsRasterWriteHeader: cupsWidth=%u", h->cupsWidth));
+ DEBUG_printf(("1cupsRasterWriteHeader: cupsHeight=%u", h->cupsHeight));
/*
* Make a copy of the header, and compute the number of raster
@@ -859,7 +992,20 @@ cupsRasterWriteHeader(
memcpy(&(r->header), h, sizeof(cups_page_header_t));
if (!cups_raster_update(r))
+ {
+ DEBUG_puts("1cupsRasterWriteHeader: Unable to update parameters, returning 0.");
return (0);
+ }
+
+ if (r->mode == CUPS_RASTER_WRITE_APPLE)
+ {
+ r->rowheight = h->HWResolution[0] / h->HWResolution[1];
+
+ if (h->HWResolution[0] != (r->rowheight * h->HWResolution[1]))
+ return (0);
+ }
+ else
+ r->rowheight = 1;
/*
* Write the raster header...
@@ -1019,8 +1165,20 @@ cupsRasterWriteHeader2(
cups_raster_t *r, /* I - Raster stream */
cups_page_header2_t *h) /* I - Raster page header */
{
+ DEBUG_printf(("cupsRasterWriteHeader(r=%p, h=%p)", (void *)r, (void *)h));
+
if (r == NULL || r->mode == CUPS_RASTER_READ)
+ {
+ DEBUG_puts("1cupsRasterWriteHeader2: Returning 0.");
return (0);
+ }
+
+ DEBUG_printf(("1cupsRasterWriteHeader2: cupsColorSpace=%s", cups_color_spaces[h->cupsColorSpace]));
+ DEBUG_printf(("1cupsRasterWriteHeader2: cupsBitsPerColor=%u", h->cupsBitsPerColor));
+ DEBUG_printf(("1cupsRasterWriteHeader2: cupsBitsPerPixel=%u", h->cupsBitsPerPixel));
+ DEBUG_printf(("1cupsRasterWriteHeader2: cupsBytesPerLine=%u", h->cupsBytesPerLine));
+ DEBUG_printf(("1cupsRasterWriteHeader2: cupsWidth=%u", h->cupsWidth));
+ DEBUG_printf(("1cupsRasterWriteHeader2: cupsHeight=%u", h->cupsHeight));
/*
* Make a copy of the header, and compute the number of raster
@@ -1030,7 +1188,10 @@ cupsRasterWriteHeader2(
memcpy(&(r->header), h, sizeof(cups_page_header2_t));
if (!cups_raster_update(r))
+ {
+ DEBUG_puts("1cupsRasterWriteHeader: Unable to update parameters, returning 0.");
return (0);
+ }
if (r->mode == CUPS_RASTER_WRITE_APPLE)
{
@@ -1202,7 +1363,6 @@ cupsRasterWritePixels(cups_raster_t *r, /* I - Raster stream */
r->header.cupsBitsPerPixel == 16))
{
unsigned char *bufptr; /* Pointer into write buffer */
- unsigned count; /* Remaining count */
/*
* Allocate a write buffer as needed...
@@ -1223,21 +1383,10 @@ cupsRasterWritePixels(cups_raster_t *r, /* I - Raster stream */
}
/*
- * Byte swap the pixels...
+ * Byte swap the pixels and write them...
*/
- for (bufptr = r->buffer, count = len; count > 1; count -= 2, bufptr += 2)
- {
- bufptr[1] = *p++;
- bufptr[0] = *p++;
- }
-
- if (count) /* This should never happen... */
- *bufptr = *p;
-
- /*
- * Write the byte-swapped buffer...
- */
+ cups_swap_copy(r->buffer, p, len);
bytes = cups_raster_io(r, r->buffer, len);
}
@@ -1368,7 +1517,7 @@ cups_raster_read_header(
size_t len; /* Length for read/swap */
- DEBUG_printf(("3cups_raster_read_header(r=%p), r->mode=%d", (void *)r, r ? r->mode : 0));
+ DEBUG_printf(("3cups_raster_read_header(r=%p), r->mode=%s", (void *)r, r ? cups_modes[r->mode] : ""));
if (r == NULL || r->mode != CUPS_RASTER_READ)
return (0);
@@ -1523,10 +1672,7 @@ cups_raster_io(cups_raster_t *r, /* I - Raster stream */
DEBUG_printf(("6cups_raster_io: count=%d, total=%d", (int)count, (int)total));
if (count == 0)
- {
- DEBUG_puts("6cups_raster_io: Returning 0.");
- return (0);
- }
+ break;
else if (count < 0)
{
DEBUG_puts("6cups_raster_io: Returning -1 on error.");
@@ -1538,6 +1684,7 @@ cups_raster_io(cups_raster_t *r, /* I - Raster stream */
#endif /* DEBUG */
}
+ DEBUG_printf(("6cups_raster_io: iocount=" CUPS_LLFMT, CUPS_LLCAST r->iocount));
DEBUG_printf(("6cups_raster_io: Returning " CUPS_LLFMT ".", CUPS_LLCAST total));
return (total);
@@ -1558,7 +1705,7 @@ cups_raster_read(cups_raster_t *r, /* I - Raster stream */
total; /* Total bytes read */
- DEBUG_printf(("5cups_raster_read(r=%p, buf=%p, bytes=" CUPS_LLFMT ")", (void *)r, (void *)buf, CUPS_LLCAST bytes));
+ DEBUG_printf(("4cups_raster_read(r=%p, buf=%p, bytes=" CUPS_LLFMT "), offset=" CUPS_LLFMT, (void *)r, (void *)buf, CUPS_LLCAST bytes, CUPS_LLCAST (r->iostart + r->bufptr - r->buffer)));
if (!r->compressed)
return (cups_raster_io(r, buf, bytes));
@@ -1602,7 +1749,7 @@ cups_raster_read(cups_raster_t *r, /* I - Raster stream */
{
count = (ssize_t)bytes - total;
- DEBUG_printf(("6cups_raster_read: count=" CUPS_LLFMT ", remaining=" CUPS_LLFMT ", buf=%p, bufptr=%p, bufend=%p", CUPS_LLCAST count, CUPS_LLCAST remaining, (void *)buf, (void *)r->bufptr, (void *)r->bufend));
+ DEBUG_printf(("5cups_raster_read: count=" CUPS_LLFMT ", remaining=" CUPS_LLFMT ", buf=%p, bufptr=%p, bufend=%p", CUPS_LLCAST count, CUPS_LLCAST remaining, (void *)buf, (void *)r->bufptr, (void *)r->bufend));
if (remaining == 0)
{
@@ -1612,6 +1759,10 @@ cups_raster_read(cups_raster_t *r, /* I - Raster stream */
* Read into the raster buffer and then copy...
*/
+#ifdef DEBUG
+ r->iostart += (size_t)(r->bufend - r->buffer);
+#endif /* DEBUG */
+
remaining = (*r->iocb)(r->ctx, r->buffer, r->bufsize);
if (remaining <= 0)
return (0);
@@ -1635,6 +1786,7 @@ cups_raster_read(cups_raster_t *r, /* I - Raster stream */
return (0);
#ifdef DEBUG
+ r->iostart += (size_t)count;
r->iocount += (size_t)count;
#endif /* DEBUG */
@@ -1687,7 +1839,7 @@ cups_raster_read(cups_raster_t *r, /* I - Raster stream */
}
}
- DEBUG_printf(("6cups_raster_read: Returning %ld", (long)total));
+ DEBUG_printf(("5cups_raster_read: Returning %ld", (long)total));
return (total);
}
@@ -1850,11 +2002,24 @@ cups_raster_write(
unsigned char *wptr; /* Pointer into write buffer */
unsigned bpp, /* Bytes per pixel */
count; /* Count */
+ _cups_copyfunc_t cf; /* Copy function */
DEBUG_printf(("3cups_raster_write(r=%p, pixels=%p)", (void *)r, (void *)pixels));
/*
+ * Determine whether we need to swap bytes...
+ */
+
+ if (r->swapped && (r->header.cupsBitsPerColor == 16 || r->header.cupsBitsPerPixel == 12 || r->header.cupsBitsPerPixel == 16))
+ {
+ DEBUG_puts("4cups_raster_write: Swapping bytes when writing.");
+ cf = (_cups_copyfunc_t)cups_swap_copy;
+ }
+ else
+ cf = (_cups_copyfunc_t)memcpy;
+
+ /*
* Allocate a write buffer as needed...
*/
@@ -1905,8 +2070,8 @@ cups_raster_write(
*/
*wptr++ = 0;
- for (count = bpp; count > 0; count --)
- *wptr++ = *start++;
+ (*cf)(wptr, start, bpp);
+ wptr += bpp;
}
else if (!memcmp(start, ptr, bpp))
{
@@ -1919,8 +2084,9 @@ cups_raster_write(
break;
*wptr++ = (unsigned char)(count - 1);
- for (count = bpp; count > 0; count --)
- *wptr++ = *ptr++;
+ (*cf)(wptr, ptr, bpp);
+ wptr += bpp;
+ ptr += bpp;
}
else
{
@@ -1941,7 +2107,7 @@ cups_raster_write(
*wptr++ = (unsigned char)(257 - count);
count *= bpp;
- memcpy(wptr, start, count);
+ (*cf)(wptr, start, count);
wptr += count;
}
}
@@ -1966,18 +2132,18 @@ cups_read_fd(void *ctx, /* I - File descriptor as pointer */
ssize_t count; /* Number of bytes read */
-#ifdef WIN32 /* Sigh */
+#ifdef _WIN32 /* Sigh */
while ((count = read(fd, buf, (unsigned)bytes)) < 0)
#else
while ((count = read(fd, buf, bytes)) < 0)
-#endif /* WIN32 */
+#endif /* _WIN32 */
if (errno != EINTR && errno != EAGAIN)
{
- DEBUG_printf(("4cups_read_fd: %s", strerror(errno)));
+ DEBUG_printf(("8cups_read_fd: %s", strerror(errno)));
return (-1);
}
- DEBUG_printf(("4cups_read_fd: Returning %d bytes.", (int)count));
+ DEBUG_printf(("8cups_read_fd: Returning %d bytes.", (int)count));
return (count);
}
@@ -2010,6 +2176,30 @@ cups_swap(unsigned char *buf, /* I - Buffer to swap */
/*
+ * 'cups_swap_copy()' - Copy and swap bytes in raster data...
+ */
+
+static void
+cups_swap_copy(
+ unsigned char *dst, /* I - Destination */
+ const unsigned char *src, /* I - Source */
+ size_t bytes) /* I - Number of bytes to swap */
+{
+ bytes /= 2;
+
+ while (bytes > 0)
+ {
+ dst[0] = src[1];
+ dst[1] = src[0];
+
+ dst += 2;
+ src += 2;
+ bytes --;
+ }
+}
+
+
+/*
* 'cups_write_fd()' - Write bytes to a file.
*/
@@ -2023,14 +2213,14 @@ cups_write_fd(void *ctx, /* I - File descriptor pointer */
ssize_t count; /* Number of bytes written */
-#ifdef WIN32 /* Sigh */
+#ifdef _WIN32 /* Sigh */
while ((count = write(fd, buf, (unsigned)bytes)) < 0)
#else
while ((count = write(fd, buf, bytes)) < 0)
-#endif /* WIN32 */
+#endif /* _WIN32 */
if (errno != EINTR && errno != EAGAIN)
{
- DEBUG_printf(("4cups_write_fd: %s", strerror(errno)));
+ DEBUG_printf(("8cups_write_fd: %s", strerror(errno)));
return (-1);
}
diff --git a/filter/rastertoepson.c b/filter/rastertoepson.c
index 4efe6692..3de491f9 100644
--- a/filter/rastertoepson.c
+++ b/filter/rastertoepson.c
@@ -1,7 +1,7 @@
/*
* EPSON ESC/P and ESC/P2 filter for CUPS.
*
- * Copyright 2007-2015 by Apple Inc.
+ * Copyright 2007-2018 by Apple Inc.
* Copyright 1993-2007 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
@@ -307,7 +307,7 @@ StartPage(
if (DotBytes)
{
- if ((LineBuffers[0] = calloc((size_t)DotBytes, header->cupsWidth * (size_t)(Shingling + 1))) == NULL)
+ if ((LineBuffers[0] = calloc((size_t)DotBytes, (header->cupsWidth + 7) * (size_t)(Shingling + 1))) == NULL)
{
fputs("ERROR: Unable to allocate memory\n", stderr);
exit(1);
diff --git a/filter/rastertolabel.c b/filter/rastertolabel.c
index 4e491811..6ad6c625 100644
--- a/filter/rastertolabel.c
+++ b/filter/rastertolabel.c
@@ -305,7 +305,7 @@ StartPage(ppd_file_t *ppd, /* I - PPD file */
header->HWResolution[1], header->cupsHeight,
header->NumCopies);
printf("PAGE-WIDTH %u\r\n", header->cupsWidth);
- printf("PAGE-HEIGHT %u\r\n", header->cupsWidth);
+ printf("PAGE-HEIGHT %u\r\n", header->cupsHeight);
break;
case INTELLITECH_PCL :
@@ -374,7 +374,7 @@ StartPage(ppd_file_t *ppd, /* I - PPD file */
if (header->cupsCompression != ~0U)
/* inPrintDensity */
- printf("\033&d%uA", 30 * header->cupsCompression / 100 - 15);
+ printf("\033&d%dA", 30 * header->cupsCompression / 100 - 15);
if ((choice = ppdFindMarkedChoice(ppd, "inPrintMode")) != NULL)
{
diff --git a/filter/spec-ppd.shtml b/filter/spec-ppd.shtml
index 3b754308..53494ade 100644
--- a/filter/spec-ppd.shtml
+++ b/filter/spec-ppd.shtml
@@ -1297,7 +1297,20 @@ http://www.vendor.com/help"
<p class='summary'>*cupsJobPassword: "format"</p>
-<p>This keyword defines the format of the job-password IPP attribute, if supported by the printer. Currently the only supported format is "1111" indicating a 4-digit PIN code.</p>
+<p>This keyword defines the format of the "job-password" IPP attribute, if supported by the printer. The following format characters are supported:</p>
+
+<ul>
+ <li><code>1</code>: US ASCII digits.</li>
+ <li><code>A</code>: US ASCII letters.</li>
+ <li><code>C</code>: US ASCII letters, numbers, and punctuation.</li>
+ <li><code>.</code>: Any US ASCII printable character (0x20 to 0x7e).</li>
+ <li><code>N</code>: Any Unicode digit character.</li>
+ <li><code>U</code>: Any Unicode letter character.</li>
+ <li><code>*</code>: Any Unicode (utf-8) character.</li>
+</ul>
+
+<p>The format characters are repeated to indicate the length of the
+password string. For example, "1111" indicated a 4-digit US ASCII PIN code.</p>
<p>Example:</p>
@@ -1581,7 +1594,7 @@ PPD file extensions was used. Currently it must be the string
<h2 class='title'><a name='MACOSX'>macOS Attributes</a></h2>
-<h3><span class='info'>macOS 10.3</span><a name='APDialogExtension'>APDialogExtension</a></h3>
+<h3><span class='info'>Deprecated</span><a name='APDialogExtension'>APDialogExtension</a></h3>
<p class='summary'>*APDialogExtension: "/Library/Printers/vendor/filename.plugin"</p>
@@ -1593,9 +1606,13 @@ plug-ins.</p>
<blockquote><b>Note:</b>
-<p>Starting with macOS 10.5, each plug-in must be compiled "4-way fat"
-(32-bit and 64-bit for both PowerPC and Intel) with garbage collection enabled
-in order to be usable with all applications.</p>
+<p>Since 2010, AirPrint has enabled the printing of full quality photos and
+documents from the Mac without requiring driver software. Starting with macOS
+10.12, system level security features prevent print dialog plug-ins from being
+loaded into applications that have enabled the library validation security
+feature. As of macOS 10.14 the <code>APDialogExtension</code> attribute used to
+create macOS print drivers is deprecated. All new printer models should support
+AirPrint moving forward.</p>
</blockquote>
diff --git a/libcups_version b/libcups_version
index 437a354a..2a644933 100644
--- a/libcups_version
+++ b/libcups_version
@@ -1 +1 @@
-v2.2.6
+v2.2.9