-CHANGES.txt - 2.2b1 - 2016-05-16
+CHANGES.txt - 2.2b1 - 2016-05-18
--------------------------------
CHANGES IN CUPS V2.2b1
+ - Encrypted printing can now be limited to only trusted printers and
+ servers (<rdar://problem/25711658>)
- The scheduler now advertises PWG Raster attributes for IPP Everywhere
clients (Issue #4428)
- The scheduler now logs informational messages for jobs at LogLevel
void *server_cert_data;
/* Server certificate user data */
int server_version, /* Server IPP version */
+ trust_first, /* Trust on first use? */
any_root, /* Allow any (e.g., self-signed) root */
expired_certs, /* Allow expired certs */
validate_certs; /* Validate certificates */
memset(cg, 0, sizeof(_cups_globals_t));
cg->encryption = (http_encryption_t)-1;
cg->password_cb = (cups_password_cb2_t)_cupsGetPassword;
+ cg->trust_first = -1;
cg->any_root = -1;
cg->expired_certs = -1;
cg->validate_certs = -1;
* credentials and allow if the new ones have a later expiration...
*/
- if (httpCredentialsGetExpiration(credentials) <= httpCredentialsGetExpiration(tcreds) ||
- !httpCredentialsAreValidForName(credentials, common_name))
+ if (!cg->trust_first)
+ {
+ /*
+ * Do not trust certificates on first use...
+ */
+
+ trust = HTTP_TRUST_INVALID;
+ }
+ else if (httpCredentialsGetExpiration(credentials) <= httpCredentialsGetExpiration(tcreds) || !httpCredentialsAreValidForName(credentials, common_name))
{
/*
* Either the new credentials are not newly issued, or the common name
trust = HTTP_TRUST_EXPIRED;
else if (!cg->any_root && cupsArrayCount(credentials) == 1)
trust = HTTP_TRUST_INVALID;
+ else if (!cg->trust_first)
+ trust = HTTP_TRUST_INVALID;
CFRelease(secCert);
/*
* TLS support code for CUPS using GNU TLS.
*
- * Copyright 2007-2015 by Apple Inc.
+ * Copyright 2007-2016 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
/* Auto-create self-signed certs? */
static char *tls_common_name = NULL;
/* Default common name */
+static gnutls_x509_crl_t tls_crl = NULL;/* Certificate revocation list */
static char *tls_keypath = NULL;
/* Server cert keychain path */
static _cups_mutex_t tls_mutex = _CUPS_MUTEX_INITIALIZER;
static gnutls_x509_crt_t http_gnutls_create_credential(http_credential_t *credential);
static const char *http_gnutls_default_path(char *buffer, size_t bufsize);
+static void http_gnutls_load_crl(void);
static const char *http_gnutls_make_path(char *buffer, size_t bufsize, const char *dirname, const char *filename, const char *ext);
static ssize_t http_gnutls_read(gnutls_transport_ptr_t ptr, void *data, size_t length);
static ssize_t http_gnutls_write(gnutls_transport_ptr_t ptr, const void *data, size_t length);
if (cert)
{
result = gnutls_x509_crt_check_hostname(cert, common_name) != 0;
+
+ if (result)
+ {
+ int i, /* Looping var */
+ count; /* Number of revoked certificates */
+ unsigned char cserial[1024], /* Certificate serial number */
+ rserial[1024]; /* Revoked serial number */
+ size_t cserial_size, /* Size of cert serial number */
+ rserial_size; /* Size of revoked serial number */
+
+ _cupsMutexLock(&tls_mutex);
+
+ count = gnutls_x509_crl_get_crt_count(tls_crl);
+
+ if (count > 0)
+ {
+ cserial_size = sizeof(cserial);
+ gnutls_x509_crt_get_serial(cert, cserial, &cserial_size);
+
+ for (i = 0; i < count; i ++)
+ {
+ rserial_size = sizeof(rserial);
+ if (!gnutls_x509_crl_get_crt_serial(tls_crl, i, rserial, sizeof(rserial)) && cserial_size == rserial_size && !memcmp(cserial, rserial, rserial_size))
+ {
+ result = 0;
+ break;
+ }
+ }
+ }
+
+ _cupsMutexUnlock(&tls_mutex);
+ }
+
gnutls_x509_crt_deinit(cert);
}
return (HTTP_TRUST_UNKNOWN);
if (cg->any_root < 0)
+ {
_cupsSetDefaults();
+ http_gnutls_load_crl();
+ }
/*
* Look this common name up in the default keychains...
* credentials and allow if the new ones have a later expiration...
*/
- if (httpCredentialsGetExpiration(credentials) <= httpCredentialsGetExpiration(tcreds) ||
- !httpCredentialsAreValidForName(credentials, common_name))
+ if (!cg->trust_first)
+ {
+ /*
+ * Do not trust certificates on first use...
+ */
+
+ trust = HTTP_TRUST_INVALID;
+ }
+ else if (httpCredentialsGetExpiration(credentials) <= httpCredentialsGetExpiration(tcreds) || !httpCredentialsAreValidForName(credentials, common_name))
{
/*
* Either the new credentials are not newly issued, or the common name
}
+/*
+ * 'http_gnutls_load_crl()' - Load the certificate revocation list, if any.
+ */
+
+static void
+http_gnutls_load_crl(void)
+{
+ _cupsMutexLock(&tls_mutex);
+
+ if (!gnutls_x509_crl_init(&tls_crl))
+ {
+ cups_file_t *fp; /* CRL file */
+ char filename[1024], /* site.crl */
+ line[256]; /* Base64-encoded line */
+ unsigned char *data = NULL; /* Buffer for cert data */
+ size_t alloc_data = 0, /* Bytes allocated */
+ num_data = 0; /* Bytes used */
+ int decoded; /* Bytes decoded */
+ gnutls_datum_t datum; /* Data record */
+
+
+ http_gnutls_make_path(filename, sizeof(filename), CUPS_SERVERROOT, "site", "crl");
+
+ if ((fp = cupsFileOpen(filename, "r")) != NULL)
+ {
+ while (cupsFileGets(fp, line, sizeof(line)))
+ {
+ if (!strcmp(line, "-----BEGIN X509 CRL-----"))
+ {
+ if (num_data)
+ {
+ /*
+ * Missing END X509 CRL...
+ */
+
+ break;
+ }
+ }
+ else if (!strcmp(line, "-----END X509 CRL-----"))
+ {
+ if (!num_data)
+ {
+ /*
+ * Missing data...
+ */
+
+ break;
+ }
+
+ datum.data = data;
+ datum.size = num_data;
+
+ gnutls_x509_crl_import(tls_crl, &datum, GNUTLS_X509_FORMAT_PEM);
+
+ num_data = 0;
+ }
+ else
+ {
+ if (alloc_data == 0)
+ {
+ data = malloc(2048);
+ alloc_data = 2048;
+
+ if (!data)
+ break;
+ }
+ else if ((num_data + strlen(line)) >= alloc_data)
+ {
+ unsigned char *tdata = realloc(data, alloc_data + 1024);
+ /* Expanded buffer */
+
+ if (!tdata)
+ {
+ httpFreeCredentials(*credentials);
+ *credentials = NULL;
+ break;
+ }
+
+ data = tdata;
+ alloc_data += 1024;
+ }
+
+ decoded = alloc_data - num_data;
+ httpDecode64_2((char *)data + num_data, &decoded, line);
+ num_data += (size_t)decoded;
+ }
+ }
+
+ cupsFileClose(fp);
+
+ if (data)
+ free(data);
+ }
+ }
+
+ _cupsMutexUnlock(&tls_mutex);
+}
+
+
/*
* 'http_gnutls_make_path()' - Format a filename for a certificate or key file.
*/
* Local constants...
*/
+#ifdef __APPLE__
+# define kCUPSPrintingPrefs CFSTR("org.cups.PrintingPrefs")
+# define kAllowAnyRootKey CFSTR("AllowAnyRoot")
+# define kAllowExpiredCertsKey CFSTR("AllowExpiredCerts")
+# define kEncryptionKey CFSTR("Encryption")
+# define kGSSServiceNameKey CFSTR("GSSServiceName")
+# define kSSLOptionsKey CFSTR("SSLOptions")
+# define kTrustOnFirstUseKey CFSTR("TrustOnFirstUse")
+# define kValidateCertsKey CFSTR("ValidateCerts")
+#endif /* __APPLE__ */
+
#define _CUPS_PASSCHAR '*' /* Character that is echoed for password */
#ifdef HAVE_SSL
int ssl_options; /* SSLOptions values */
#endif /* HAVE_SSL */
- int any_root, /* Allow any (e.g., self-signed) root */
+ int trust_first, /* Trust on first use? */
+ any_root, /* Allow any (e.g., self-signed) root */
expired_certs, /* Allow expired certs */
validate_certs; /* Validate certificates */
http_encryption_t encryption; /* Encryption setting */
* Local functions...
*/
+#ifdef __APPLE__
+static int cups_apple_get_boolean(CFStringRef key, int *value);
+static int cups_apple_get_string(CFStringRef key, char *value, size_t valsize);
+#endif /* __APPLE__ */
+static int cups_boolean_value(const char *value);
static void cups_finalize_client_conf(_cups_client_conf_t *cc);
static void cups_init_client_conf(_cups_client_conf_t *cc);
static void cups_read_client_conf(cups_file_t *fp, _cups_client_conf_t *cc);
strlcpy(cg->gss_service_name, cc.gss_service_name, sizeof(cg->gss_service_name));
#endif /* HAVE_GSSAPI */
+ if (cg->trust_first < 0)
+ cg->trust_first = cc.trust_first;
+
if (cg->any_root < 0)
cg->any_root = cc.any_root;
}
+#ifdef __APPLE__
+/*
+ * 'cups_apple_get_boolean()' - Get a boolean setting from the CUPS preferences.
+ */
+
+static int /* O - 1 if set, 0 otherwise */
+cups_apple_get_boolean(
+ CFStringRef key, /* I - Key (name) */
+ int *value) /* O - Boolean value */
+{
+ Boolean bval, /* Preference value */
+ bval_set; /* Value is set? */
+
+
+ bval = CFPreferencesGetAppBooleanValue(key, kCUPSPrintingPrefs, &bval_set);
+
+ if (bval_set)
+ *value = (int)bval;
+
+ return ((int)bval_set);
+}
+
+
+/*
+ * 'cups_apple_get_string()' - Get a string setting from the CUPS preferences.
+ */
+
+static int /* O - 1 if set, 0 otherwise */
+cups_apple_get_string(
+ CFStringRef key, /* I - Key (name) */
+ char *value, /* O - String value */
+ size_t valsize) /* I - Size of value buffer */
+{
+ CFStringRef sval; /* String value */
+
+
+ if ((sval = CFPreferencesCopyAppValue(key, kCUPSPrintingPrefs)) != NULL)
+ {
+ Boolean result = CFStringGetCString(sval, value, (CFIndex)valsize, kCFStringEncodingUTF8);
+
+ CFRelease(sval);
+
+ if (result)
+ return (1);
+ }
+
+ return (0);
+}
+#endif /* __APPLE__ */
+
+
/*
* 'cups_boolean_value()' - Convert a string to a boolean value.
*/
const char *value; /* Environment variable */
+ if ((value = getenv("CUPS_TRUSTFIRST")) != NULL)
+ cc->trust_first = cups_boolean_value(value);
+
if ((value = getenv("CUPS_ANYROOT")) != NULL)
cc->any_root = cups_boolean_value(value);
* Then apply defaults for those values that haven't been set...
*/
+ if (cc->trust_first < 0)
+ cc->trust_first = 1;
+
if (cc->any_root < 0)
cc->any_root = 1;
cc->encryption = HTTP_ENCRYPTION_IF_REQUESTED;
if (cc->expired_certs < 0)
- cc->expired_certs = 1;
+ cc->expired_certs = 0;
#ifdef HAVE_GSSAPI
if (!cc->gss_service_name[0])
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;
+
+ /*
+ * Load settings from the org.cups.PrintingPrefs plist (which trump
+ * everything...)
+ */
+
+#ifdef __APPLE__
+ char sval[1024]; /* String value */
+ int bval; /* Boolean value */
+
+ if (cups_apple_get_boolean(kAllowAnyRootKey, &bval))
+ cc->any_root = bval;
+
+ if (cups_apple_get_boolean(kAllowExpiredCertsKey, &bval))
+ cc->expired_certs = bval;
+
+ if (cups_apple_get_string(kEncryptionKey, sval, sizeof(sval)))
+ cups_set_encryption(cc, sval);
+
+ if (cups_apple_get_string(kSSLOptionsKey, sval, sizeof(sval)))
+ cups_set_ssl_options(cc, sval);
+
+ if (cups_apple_get_boolean(kTrustOnFirstUseKey, &bval))
+ cc->trust_first = bval;
+
+ if (cups_apple_get_boolean(kValidateCertsKey, &bval))
+ cc->validate_certs = bval;
+#endif /* __APPLE__ */
}
#endif /* !__APPLE__ */
else if (!_cups_strcasecmp(line, "User") && value)
cups_set_user(cc, value);
+ else if (!_cups_strcasecmp(line, "TrustOnFirstUse") && value)
+ cc->trust_first = cups_boolean_value(value);
else if (!_cups_strcasecmp(line, "AllowAnyRoot") && value)
cc->any_root = cups_boolean_value(value);
else if (!_cups_strcasecmp(line, "AllowExpiredCerts") &&
<body>
<h1 class="title">client.conf(5)</h1>
<h2 class="title"><a name="NAME">Name</a></h2>
-client.conf - client configuration file for cups (deprecated)
+client.conf - client configuration file for cups
<h2 class="title"><a name="DESCRIPTION">Description</a></h2>
The <b>client.conf</b> file configures the CUPS client and is normally located in the <i>/etc/cups</i> and/or <i>~/.cups</i> directories.
Each line in the file can be a configuration directive, a blank line, or a comment. Comment lines start with the # character.
<p><b>Note:</b> Starting with OS X 10.7, this file is only used by command-line and X11 applications plus the IPP backend.
The <b>ServerName</b> directive is not supported on OS X at all.
+Starting with OS X 10.TODO, all applications can access these settings in the <i>/Library/Preferences/org.cups.PrintingPrefs.plist</i> file instead.
+See the NOTES section below for more information.
<h3><a name="DIRECTIVES">Directives</a></h3>
The following directives are understood by the client. Consult the online help for detailed descriptions:
<dl class="man">
<dt><b>AllowExpiredCerts Yes</b>
<dd style="margin-left: 5.0em"><dt><b>AllowExpiredCerts No</b>
<dd style="margin-left: 5.0em">Specifies whether to allow TLS with expired certificates.
-The default is "Yes".
+The default is "No".
<dt><b>Encryption IfRequested</b>
<dd style="margin-left: 5.0em"><dt><b>Encryption Never</b>
<dd style="margin-left: 5.0em"><dt><b>Encryption Required</b>
The <i>AllowRC4</i> option enables the 128-bit RC4 cipher suites, which are required for some older clients that do not implement newer ones.
The <i>AllowSSL3</i> option enables SSL v3.0, which is required for some older clients that do not support TLS v1.0.
The <i>DenyTLS1.0</i> option disables TLS v1.0 support - this sets the minimum protocol version to TLS v1.1.
+<dt><b>TrustOnFirstUse Yes</b>
+<dd style="margin-left: 5.0em"><dt><b>TrustOnFirstUse No</b>
+<dd style="margin-left: 5.0em">Specifies whether to trust new TLS certificates by default.
+The default is "Yes".
<dt><b>User </b><i>name</i>
<dd style="margin-left: 5.0em">Specifies the default user name to use for requests.
<dt><b>ValidateCerts Yes</b>
The default is "No".
</dl>
<h2 class="title"><a name="NOTES">Notes</a></h2>
-The <b>client.conf</b> file is deprecated and will no longer be supported in a future version of CUPS.
+The <b>client.conf</b> file is deprecated on OS X and will no longer be supported in a future version of CUPS.
+Configuration settings can instead be viewed or changed using the
+<b>defaults</b>(1)
+command:
+<pre class="man">
+defaults write /Library/Preferences/org.cups.PrintingPrefs.plist Encryption Required
+defaults write /Library/Preferences/org.cups.PrintingPrefs.plist TrustOnFirstUse -bool NO
+
+defaults read /Library/Preferences/org.cups.PrintingPrefs.plist Encryption
+</pre>
+On Linux and other systems using GNU TLS, the <i>/etc/cups/ssl/site.crl</i> file, if present, provides a list of revoked X.509 certificates and is used when validating certificates.
<h2 class="title"><a name="SEE_ALSO">See Also</a></h2>
<a href="man-cups.html?TOPIC=Man+Pages"><b>cups</b>(1),</a>
+<b>default</b>(1),
CUPS Online Help (<a href="http://localhost:631/help">http://localhost:631/help</a>)
<h2 class="title"><a name="COPYRIGHT">Copyright</a></h2>
-Copyright © 2007-2015 by Apple Inc.
+Copyright © 2007-2016 by Apple Inc.
</body>
</html>
.\"
.\" client.conf man page for CUPS.
.\"
-.\" Copyright 2007-2015 by Apple Inc.
+.\" Copyright 2007-2016 by Apple Inc.
.\" Copyright 2006 by Easy Software Products.
.\"
.\" These coded instructions, statements, and computer programs are the
.\" which should have been included with this file. If this file is
.\" file is missing or damaged, see the license at "http://www.cups.org/".
.\"
-.TH client.conf 5 "CUPS" "19 May 2015" "Apple Inc."
+.TH client.conf 5 "CUPS" "18 May 2016" "Apple Inc."
.SH NAME
-client.conf \- client configuration file for cups (deprecated)
+client.conf \- client configuration file for cups
.SH DESCRIPTION
The \fBclient.conf\fR file configures the CUPS client and is normally located in the \fI/etc/cups\fR and/or \fI~/.cups\fR directories.
Each line in the file can be a configuration directive, a blank line, or a comment. Comment lines start with the # character.
.LP
\fBNote:\fR Starting with OS X 10.7, this file is only used by command-line and X11 applications plus the IPP backend.
The \fBServerName\fR directive is not supported on OS X at all.
+Starting with OS X 10.TODO, all applications can access these settings in the \fI/Library/Preferences/org.cups.PrintingPrefs.plist\fR file instead.
+See the NOTES section below for more information.
.SS DIRECTIVES
The following directives are understood by the client. Consult the online help for detailed descriptions:
.TP 5
.TP 5
\fBAllowExpiredCerts No\fR
Specifies whether to allow TLS with expired certificates.
-The default is "Yes".
+The default is "No".
.TP 5
\fBEncryption IfRequested\fR
.TP 5
The \fIAllowSSL3\fR option enables SSL v3.0, which is required for some older clients that do not support TLS v1.0.
The \fIDenyTLS1.0\fR option disables TLS v1.0 support - this sets the minimum protocol version to TLS v1.1.
.TP 5
+\fBTrustOnFirstUse Yes\fR
+.TP 5
+\fBTrustOnFirstUse No\fR
+Specifies whether to trust new TLS certificates by default.
+The default is "Yes".
+.TP 5
\fBUser \fIname\fR
Specifies the default user name to use for requests.
.TP 5
Specifies whether to only allow TLS with certificates whose common name matches the hostname.
The default is "No".
.SH NOTES
-The \fBclient.conf\fR file is deprecated and will no longer be supported in a future version of CUPS.
+The \fBclient.conf\fR file is deprecated on OS X and will no longer be supported in a future version of CUPS.
+Configuration settings can instead be viewed or changed using the
+.BR defaults (1)
+command:
+.nf
+defaults write /Library/Preferences/org.cups.PrintingPrefs.plist Encryption Required
+defaults write /Library/Preferences/org.cups.PrintingPrefs.plist TrustOnFirstUse -bool NO
+
+defaults read /Library/Preferences/org.cups.PrintingPrefs.plist Encryption
+.fi
+On Linux and other systems using GNU TLS, the \fI/etc/cups/ssl/site.crl\fR file, if present, provides a list of revoked X.509 certificates and is used when validating certificates.
.SH SEE ALSO
.BR cups (1),
+.BR default (1),
CUPS Online Help (http://localhost:631/help)
.SH COPYRIGHT
-Copyright \[co] 2007-2015 by Apple Inc.
+Copyright \[co] 2007-2016 by Apple Inc.
72220F02133305BB00FCA411 /* string.c */,
72220F03133305BB00FCA411 /* tempfile.c */,
72220F05133305BB00FCA411 /* thread.c */,
+ 727AD5B619100A58009F6862 /* tls.c */,
270B267D17F5C06700C8A3A9 /* tls-darwin.c */,
270B267E17F5C06700C8A3A9 /* tls-gnutls.c */,
270B268117F5C5D600C8A3A9 /* tls-sspi.c */,
- 727AD5B619100A58009F6862 /* tls.c */,
72220F06133305BB00FCA411 /* transcode.c */,
72220F08133305BB00FCA411 /* usersys.c */,
72220F09133305BB00FCA411 /* util.c */,