From: Michael R Sweet Date: Sun, 3 Sep 2023 01:19:10 +0000 (-0400) Subject: Initial update of TLS support - no more SSPI or Security.framework (CDSA) X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=123baa03a4e09047cfa25e003a0a9db8cc8fc363;p=thirdparty%2Fcups.git Initial update of TLS support - no more SSPI or Security.framework (CDSA) support. Require TLS support. --- diff --git a/Makedefs.in b/Makedefs.in index 07010f0656..a935ab1627 100644 --- a/Makedefs.in +++ b/Makedefs.in @@ -1,7 +1,7 @@ # # Common makefile definitions for CUPS. # -# Copyright © 2021 by OpenPrinting. +# Copyright © 2021-2023 by OpenPrinting. # Copyright © 2007-2019 by Apple Inc. # Copyright © 1997-2007 by Easy Software Products, all rights reserved. # @@ -111,13 +111,6 @@ LIBZ = @LIBZ@ INSTALLSTATIC = @INSTALLSTATIC@ -# -# IPP backend aliases... -# - -IPPALIASES = @IPPALIASES@ - - # # ippeveprinter commands... # diff --git a/backend/Makefile b/backend/Makefile index 9153c87ae1..8009e593d8 100644 --- a/backend/Makefile +++ b/backend/Makefile @@ -123,14 +123,8 @@ install-exec: $(INSTALLXPC) for file in $(UBACKENDS); do \ $(INSTALL_BIN) $$file $(SERVERBIN)/backend; \ done - for file in $(IPPALIASES); do \ - $(RM) $(SERVERBIN)/backend/$$file; \ - $(LN) ipp $(SERVERBIN)/backend/$$file; \ - done - if test "x$(DNSSD_BACKEND)" != x -a `uname` = Darwin; then \ - $(RM) $(SERVERBIN)/backend/mdns; \ - $(LN) $(DNSSD_BACKEND) $(SERVERBIN)/backend/mdns; \ - fi + $(RM) $(SERVERBIN)/backend/ipps; \ + $(LN) ipp $(SERVERBIN)/backend/ipps; \ if test "x$(SYMROOT)" != "x"; then \ $(INSTALL_DIR) $(SYMROOT); \ for file in $(RBACKENDS) $(UBACKENDS); do \ @@ -143,10 +137,8 @@ install-xpc: ipp echo Installing XPC backends in $(SERVERBIN)/apple $(INSTALL_DIR) -m 755 $(SERVERBIN)/apple $(INSTALL_BIN) ipp $(SERVERBIN)/apple - for file in $(IPPALIASES); do \ - $(RM) $(SERVERBIN)/apple/$$file; \ - $(LN) ipp $(SERVERBIN)/apple/$$file; \ - done + $(RM) $(SERVERBIN)/apple/ipps + $(LN) ipp $(SERVERBIN)/apple/ipps # @@ -169,16 +161,12 @@ install-libs: uninstall: $(RM) $(SERVERBIN)/apple/ipp - for file in $(IPPALIASES); do \ - $(RM) $(SERVERBIN)/apple/$$file; \ - done + $(RM) $(SERVERBIN)/apple/ipps -$(RMDIR) $(SERVERBIN)/apple for file in $(RBACKENDS) $(UBACKENDS); do \ $(RM) $(SERVERBIN)/backend/$$file; \ done - for file in $(IPPALIASES); do \ - $(RM) $(SERVERBIN)/backend/$$file; \ - done + $(RM) $(SERVERBIN)/backend/ipps -$(RMDIR) $(SERVERBIN)/backend -$(RMDIR) $(SERVERBIN) @@ -247,10 +235,8 @@ ipp: ipp.o ../cups/$(LIBCUPS) libbackend.a echo Linking $@... $(LD_CC) $(ALL_LDFLAGS) -o ipp ipp.o libbackend.a $(LINKCUPS) $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@ - $(RM) http https ipps - for file in $(IPPALIASES); do \ - $(LN) ipp $$file; \ - done + $(RM) ipps + $(LN) ipp ipps # diff --git a/berkeley/lpq.c b/berkeley/lpq.c index 6592d31089..017f3e83f0 100644 --- a/berkeley/lpq.c +++ b/berkeley/lpq.c @@ -78,14 +78,10 @@ main(int argc, /* I - Number of command-line arguments */ switch (*opt) { case 'E' : /* Encrypt */ -#ifdef HAVE_TLS cupsSetEncryption(HTTP_ENCRYPT_REQUIRED); if (http) httpEncryption(http, HTTP_ENCRYPT_REQUIRED); -#else - _cupsLangPrintf(stderr, _("%s: Sorry, no encryption support."), argv[0]); -#endif /* HAVE_TLS */ break; case 'U' : /* Username */ diff --git a/berkeley/lpr.c b/berkeley/lpr.c index 85fa079c52..a0d5f5fda3 100644 --- a/berkeley/lpr.c +++ b/berkeley/lpr.c @@ -69,11 +69,7 @@ main(int argc, /* I - Number of command-line arguments */ switch (ch = *opt) { case 'E' : /* Encrypt */ -#ifdef HAVE_TLS cupsSetEncryption(HTTP_ENCRYPT_REQUIRED); -#else - _cupsLangPrintf(stderr, _("%s: Sorry, no encryption support."), argv[0]); -#endif /* HAVE_TLS */ break; case 'U' : /* Username */ diff --git a/berkeley/lprm.c b/berkeley/lprm.c index 83618bf27f..ca4acc39fe 100644 --- a/berkeley/lprm.c +++ b/berkeley/lprm.c @@ -66,11 +66,7 @@ main(int argc, /* I - Number of command-line arguments */ switch (*opt) { case 'E' : /* Encrypt */ -#ifdef HAVE_TLS cupsSetEncryption(HTTP_ENCRYPT_REQUIRED); -#else - _cupsLangPrintf(stderr, _("%s: Sorry, no encryption support."), argv[0]); -#endif /* HAVE_TLS */ break; case 'P' : /* Cancel jobs on a printer */ diff --git a/config-scripts/cups-tls.m4 b/config-scripts/cups-tls.m4 index 783eed886d..001478b27d 100644 --- a/config-scripts/cups-tls.m4 +++ b/config-scripts/cups-tls.m4 @@ -9,10 +9,10 @@ dnl Licensed under Apache License v2.0. See the file "LICENSE" for more dnl information. dnl -AC_ARG_WITH([tls], AS_HELP_STRING([--with-tls=...], [use cdsa (macOS), gnutls, or openssl for TLS support])) +AC_ARG_WITH([tls], AS_HELP_STRING([--with-tls=...], [use gnutls or openssl for TLS support])) AS_IF([test "x$with_tls" = x], [ with_tls="yes" -], [test "$with_tls" != cdsa -a "$with_tls" != gnutls -a "$with_tls" != openssl -a "$with_tls" != no -a "$with_tls" != yes], [ +], [test "$with_tls" != gnutls -a "$with_tls" != openssl -a "$with_tls" != yes], [ AC_MSG_ERROR([Unsupported --with-tls value "$with_tls" specified.]) ]) @@ -33,7 +33,6 @@ AS_IF([test $with_tls = yes -o $with_tls = openssl], [ TLSLIBS="$($PKGCONFIG --libs openssl)" TLSFLAGS="$($PKGCONFIG --cflags openssl)" PKGCONFIG_REQUIRES="$PKGCONFIG_REQUIRES openssl" - AC_DEFINE([HAVE_TLS], [1], [Do we support TLS?]) AC_DEFINE([HAVE_OPENSSL], [1], [Do we have the OpenSSL library?]) ], [ AC_MSG_RESULT([no]) @@ -49,7 +48,6 @@ AS_IF([test $with_tls = yes -o $with_tls = openssl], [ with_tls="openssl" TLSLIBS="-lssl -lcrypto" PKGCONFIG_LIBS_STATIC="$PKGCONFIG_LIBS_STATIC $TLSLIBS" - AC_DEFINE([HAVE_TLS], [1], [Do we support TLS?]) AC_DEFINE([HAVE_OPENSSL], [1], [Do we have the OpenSSL library?]) ]) ]) @@ -76,7 +74,6 @@ AS_IF([test $with_tls = yes -o $with_tls = gnutls], [ TLSLIBS="$($PKGCONFIG --libs gnutls)" TLSFLAGS="$($PKGCONFIG --cflags gnutls)" PKGCONFIG_REQUIRES="$PKGCONFIG_REQUIRES gnutls" - AC_DEFINE([HAVE_TLS], [1], [Do we support TLS?]) AC_DEFINE([HAVE_GNUTLS], [1], [Do we have the GNU TLS library?]) ], [ AC_MSG_RESULT([no]) @@ -88,7 +85,6 @@ AS_IF([test $with_tls = yes -o $with_tls = gnutls], [ TLSLIBS="$($LIBGNUTLSCONFIG --libs)" TLSFLAGS="$($LIBGNUTLSCONFIG --cflags)" PKGCONFIG_LIBS_STATIC="$PKGCONFIG_LIBS_STATIC $TLSLIBS" - AC_DEFINE([HAVE_TLS], [1], [Do we support TLS?]) AC_DEFINE([HAVE_GNUTLS], [1], [Do we have the GNU TLS library?]) ]) @@ -109,44 +105,14 @@ AS_IF([test $with_tls = yes -o $with_tls = gnutls], [ ]) ]) -dnl Finally try using CSDA SSL (macOS)... -AS_IF([test $with_tls = yes -o $with_tls = cdsa], [ - dnl Look for CDSA... - AS_IF([test $host_os_name = darwin], [ - AC_CHECK_HEADER([Security/SecureTransport.h], [ - have_tls="1" - with_tls="cdsa" - AC_DEFINE([HAVE_TLS], [1], [Do we support TLS?]) - AC_DEFINE([HAVE_CDSASSL], [1], [Do we have the macOS SecureTransport API?]) - CUPS_SERVERKEYCHAIN="/Library/Keychains/System.keychain" - - dnl Check for the various security headers... - AC_CHECK_HEADER([Security/SecCertificate.h], [ - AC_DEFINE([HAVE_SECCERTIFICATE_H], [1], [Have the header?]) - ]) - AC_CHECK_HEADER([Security/SecItem.h], [ - AC_DEFINE([HAVE_SECITEM_H], [1], [Have the header?]) - ]) - AC_CHECK_HEADER([Security/SecPolicy.h], [ - AC_DEFINE([HAVE_SECPOLICY_H], [1], [Have the &6; } TLSFLAGS="$($PKGCONFIG --cflags openssl)" PKGCONFIG_REQUIRES="$PKGCONFIG_REQUIRES openssl" -printf "%s\n" "#define HAVE_TLS 1" >>confdefs.h - - printf "%s\n" "#define HAVE_OPENSSL 1" >>confdefs.h @@ -9796,9 +9792,6 @@ then : TLSLIBS="-lssl -lcrypto" PKGCONFIG_LIBS_STATIC="$PKGCONFIG_LIBS_STATIC $TLSLIBS" -printf "%s\n" "#define HAVE_TLS 1" >>confdefs.h - - printf "%s\n" "#define HAVE_OPENSSL 1" >>confdefs.h @@ -9953,9 +9946,6 @@ printf "%s\n" "yes" >&6; } TLSFLAGS="$($PKGCONFIG --cflags gnutls)" PKGCONFIG_REQUIRES="$PKGCONFIG_REQUIRES gnutls" -printf "%s\n" "#define HAVE_TLS 1" >>confdefs.h - - printf "%s\n" "#define HAVE_GNUTLS 1" >>confdefs.h @@ -9976,9 +9966,6 @@ then : TLSFLAGS="$($LIBGNUTLSCONFIG --cflags)" PKGCONFIG_LIBS_STATIC="$PKGCONFIG_LIBS_STATIC $TLSLIBS" -printf "%s\n" "#define HAVE_TLS 1" >>confdefs.h - - printf "%s\n" "#define HAVE_GNUTLS 1" >>confdefs.h @@ -10022,70 +10009,6 @@ fi fi -if test $with_tls = yes -o $with_tls = cdsa -then : - - if test $host_os_name = darwin -then : - - ac_fn_c_check_header_compile "$LINENO" "Security/SecureTransport.h" "ac_cv_header_Security_SecureTransport_h" "$ac_includes_default" -if test "x$ac_cv_header_Security_SecureTransport_h" = xyes -then : - - have_tls="1" - with_tls="cdsa" - -printf "%s\n" "#define HAVE_TLS 1" >>confdefs.h - - -printf "%s\n" "#define HAVE_CDSASSL 1" >>confdefs.h - - CUPS_SERVERKEYCHAIN="/Library/Keychains/System.keychain" - - ac_fn_c_check_header_compile "$LINENO" "Security/SecCertificate.h" "ac_cv_header_Security_SecCertificate_h" "$ac_includes_default" -if test "x$ac_cv_header_Security_SecCertificate_h" = xyes -then : - - -printf "%s\n" "#define HAVE_SECCERTIFICATE_H 1" >>confdefs.h - - -fi - - ac_fn_c_check_header_compile "$LINENO" "Security/SecItem.h" "ac_cv_header_Security_SecItem_h" "$ac_includes_default" -if test "x$ac_cv_header_Security_SecItem_h" = xyes -then : - - -printf "%s\n" "#define HAVE_SECITEM_H 1" >>confdefs.h - - -fi - - ac_fn_c_check_header_compile "$LINENO" "Security/SecPolicy.h" "ac_cv_header_Security_SecPolicy_h" "$ac_includes_default" -if test "x$ac_cv_header_Security_SecPolicy_h" = xyes -then : - - -printf "%s\n" "#define HAVE_SECPOLICY_H 1" >>confdefs.h - - -fi - - -fi - - -elif test $with_tls = cdsa -then : - - as_fn_error $? "--with-tls=cdsa is not compatible with your host operating system." "$LINENO" 5 - -fi - -fi - -IPPALIASES="http" if test $have_tls = 1 then : @@ -10093,12 +10016,10 @@ then : printf "%s\n" "$as_me: Using TLSLIBS=\"$TLSLIBS\"" >&6;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using TLSFLAGS=\"$TLSFLAGS\"" >&5 printf "%s\n" "$as_me: Using TLSFLAGS=\"$TLSFLAGS\"" >&6;} - IPPALIASES="http https ipps" -elif test $with_tls = yes -then : +else $as_nop - as_fn_error $? "--with-tls=yes was specified but no compatible TLS libraries could be found." "$LINENO" 5 + as_fn_error $? "No compatible TLS libraries could be found." "$LINENO" 5 fi @@ -10106,7 +10027,6 @@ fi - EXPORT_TLSLIBS="$TLSLIBS" diff --git a/cups/Dependencies b/cups/Dependencies index 1cb291bd9d..a27e9430a4 100644 --- a/cups/Dependencies +++ b/cups/Dependencies @@ -188,7 +188,7 @@ tls.o: tls.c cups-private.h string-private.h ../config.h \ ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ pwg.h http-private.h ../cups/language.h ../cups/http.h \ language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ - debug-internal.h debug-private.h tls-darwin.c tls-darwin.h + debug-internal.h debug-private.h transcode.o: transcode.c cups-private.h string-private.h ../config.h \ ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ diff --git a/cups/Makefile b/cups/Makefile index 10e4dc6315..d0104cee96 100644 --- a/cups/Makefile +++ b/cups/Makefile @@ -774,4 +774,4 @@ sloc: # include Dependencies -tls.o: tls-darwin.c tls-gnutls.c tls-openssl.c tls-sspi.c +tls.o: tls-gnutls.c tls-openssl.c diff --git a/cups/cups.h b/cups/cups.h index aa294b0286..a0d48b9feb 100644 --- a/cups/cups.h +++ b/cups/cups.h @@ -43,10 +43,10 @@ extern "C" { * Constants... */ -# define CUPS_VERSION 2.0403 +# define CUPS_VERSION 2.0500 # define CUPS_VERSION_MAJOR 2 -# define CUPS_VERSION_MINOR 4 -# define CUPS_VERSION_PATCH 3 +# define CUPS_VERSION_MINOR 5 +# define CUPS_VERSION_PATCH 0 # define CUPS_BC_FD 3 /* Back-channel file descriptor for diff --git a/cups/dest.c b/cups/dest.c index da775a3901..3dc41a4428 100644 --- a/cups/dest.c +++ b/cups/dest.c @@ -3417,9 +3417,7 @@ cups_enum_dests( int nfds, /* Number of files responded */ main_fd; /* File descriptor for lookups */ DNSServiceRef ipp_ref = NULL; /* IPP browser */ -# ifdef HAVE_TLS DNSServiceRef ipps_ref = NULL; /* IPPS browser */ -# endif /* HAVE_TLS */ # ifdef HAVE_POLL struct pollfd pfd; /* Polling data */ # else @@ -3429,9 +3427,7 @@ cups_enum_dests( # else /* HAVE_AVAHI */ int error; /* Error value */ AvahiServiceBrowser *ipp_ref = NULL; /* IPP browser */ -# ifdef HAVE_TLS AvahiServiceBrowser *ipps_ref = NULL; /* IPPS browser */ -# endif /* HAVE_TLS */ # endif /* HAVE_MDNSRESPONDER */ #else _cups_getdata_t data; /* Data for callback */ @@ -3659,7 +3655,6 @@ cups_enum_dests( return (0); } -# ifdef HAVE_TLS ipps_ref = data.main_ref; if (DNSServiceBrowse(&ipps_ref, kDNSServiceFlagsShareConnection, 0, "_ipps._tcp", NULL, (DNSServiceBrowseReply)cups_dnssd_browse_cb, &data) != kDNSServiceErr_NoError) { @@ -3671,7 +3666,6 @@ cups_enum_dests( return (0); } -# endif /* HAVE_TLS */ # else /* HAVE_AVAHI */ if ((data.simple_poll = avahi_simple_poll_new()) == NULL) @@ -3714,7 +3708,6 @@ cups_enum_dests( return (0); } -# ifdef HAVE_TLS data.browsers ++; if ((ipps_ref = avahi_service_browser_new(data.client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_ipps._tcp", NULL, 0, cups_dnssd_browse_cb, &data)) == NULL) { @@ -3729,7 +3722,6 @@ cups_enum_dests( return (0); } -# endif /* HAVE_TLS */ # endif /* HAVE_MDNSRESPONDER */ if (msec < 0) @@ -3923,10 +3915,8 @@ cups_enum_dests( if (ipp_ref) DNSServiceRefDeallocate(ipp_ref); -# ifdef HAVE_TLS if (ipps_ref) DNSServiceRefDeallocate(ipps_ref); -# endif /* HAVE_TLS */ if (data.main_ref) DNSServiceRefDeallocate(data.main_ref); @@ -3934,10 +3924,8 @@ cups_enum_dests( # else /* HAVE_AVAHI */ if (ipp_ref) avahi_service_browser_free(ipp_ref); -# ifdef HAVE_TLS if (ipps_ref) avahi_service_browser_free(ipps_ref); -# endif /* HAVE_TLS */ if (data.client) avahi_client_free(data.client); diff --git a/cups/getdevices.c b/cups/getdevices.c index 175e8656f5..b1fca8616b 100644 --- a/cups/getdevices.c +++ b/cups/getdevices.c @@ -130,8 +130,6 @@ cupsGetDevices( break; } } - -#ifdef HAVE_TLS else if (status == HTTP_STATUS_UPGRADE_REQUIRED) { /* @@ -143,7 +141,6 @@ cupsGetDevices( if (!httpReconnect2(http, 30000, NULL)) httpEncryption(http, HTTP_ENCRYPTION_REQUIRED); } -#endif /* HAVE_TLS */ } } while (status == HTTP_STATUS_UNAUTHORIZED || diff --git a/cups/getputfile.c b/cups/getputfile.c index 9a053c862d..ee6fef176b 100644 --- a/cups/getputfile.c +++ b/cups/getputfile.c @@ -157,7 +157,6 @@ cupsGetFd(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFA continue; } -#ifdef HAVE_TLS else if (status == HTTP_STATUS_UPGRADE_REQUIRED) { /* Flush any error message... */ @@ -176,7 +175,6 @@ cupsGetFd(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFA /* Try again, this time with encryption enabled... */ continue; } -#endif /* HAVE_TLS */ } while (status == HTTP_STATUS_UNAUTHORIZED || status == HTTP_STATUS_UPGRADE_REQUIRED); @@ -467,7 +465,6 @@ cupsPutFd(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFA continue; } -#ifdef HAVE_TLS else if (status == HTTP_STATUS_UPGRADE_REQUIRED) { /* Flush any error message... */ @@ -486,7 +483,6 @@ cupsPutFd(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFA /* Try again, this time with encryption enabled... */ continue; } -#endif /* HAVE_TLS */ } while (status == HTTP_STATUS_UNAUTHORIZED || status == HTTP_STATUS_UPGRADE_REQUIRED || status == HTTP_STATUS_NONE); diff --git a/cups/globals.c b/cups/globals.c index ddeab667c3..0e0b8f30d6 100644 --- a/cups/globals.c +++ b/cups/globals.c @@ -388,9 +388,7 @@ cups_globals_free(_cups_globals_t *cg) /* I - Pointer to global data */ httpClose(cg->http); -#ifdef HAVE_TLS _httpFreeCredentials(cg->tls_credentials); -#endif /* HAVE_TLS */ cupsFileClose(cg->stdio_files[0]); cupsFileClose(cg->stdio_files[1]); diff --git a/cups/http.c b/cups/http.c index c7e6e3bc37..f3a22d74c0 100644 --- a/cups/http.c +++ b/cups/http.c @@ -65,10 +65,7 @@ static ssize_t http_write_chunk(http_t *http, const char *buffer, static off_t http_set_length(http_t *http); static void http_set_timeout(int fd, double timeout); static void http_set_wait(http_t *http); - -#ifdef HAVE_TLS static int http_tls_upgrade(http_t *http); -#endif /* HAVE_TLS */ /* @@ -531,10 +528,8 @@ httpDelete(http_t *http, /* I - HTTP connection */ void _httpDisconnect(http_t *http) /* I - HTTP connection */ { -#ifdef HAVE_TLS if (http->tls) _httpTLSStop(http); -#endif /* HAVE_TLS */ httpAddrClose(NULL, http->fd); @@ -552,7 +547,6 @@ httpEncryption(http_t *http, /* I - HTTP connection */ { DEBUG_printf(("httpEncryption(http=%p, e=%d)", (void *)http, e)); -#ifdef HAVE_TLS if (!http) return (0); @@ -579,12 +573,6 @@ httpEncryption(http_t *http, /* I - HTTP connection */ else return (0); } -#else - if (e == HTTP_ENCRYPTION_ALWAYS || e == HTTP_ENCRYPTION_REQUIRED) - return (-1); - else - return (0); -#endif /* HAVE_TLS */ } @@ -679,10 +667,8 @@ httpFlush(http_t *http) /* I - HTTP connection */ http->state = HTTP_STATE_WAITING; -#ifdef HAVE_TLS if (http->tls) _httpTLSStop(http); -#endif /* HAVE_TLS */ httpAddrClose(NULL, http->fd); @@ -1111,10 +1097,8 @@ httpGetReady(http_t *http) /* I - HTTP connection */ return (0); else if (http->used > 0) return ((size_t)http->used); -#ifdef HAVE_TLS else if (http->tls) return (_httpTLSPending(http)); -#endif /* HAVE_TLS */ return (0); } @@ -1553,9 +1537,7 @@ httpInitialize(void) # endif /* !SO_NOSIGPIPE */ #endif /* _WIN32 */ -# ifdef HAVE_TLS _httpTLSInitialize(); -# endif /* HAVE_TLS */ initialized = 1; _cupsGlobalUnlock(); @@ -2362,13 +2344,11 @@ httpReconnect2(http_t *http, /* I - HTTP connection */ return (-1); } -#ifdef HAVE_TLS if (http->tls) { DEBUG_puts("2httpReconnect2: Shutting down SSL/TLS..."); _httpTLSStop(http); } -#endif /* HAVE_TLS */ /* * Close any previously open socket... @@ -2436,7 +2416,6 @@ httpReconnect2(http_t *http, /* I - HTTP connection */ http->hostaddr = &(addr->addr); http->error = 0; -#ifdef HAVE_TLS if (http->encryption == HTTP_ENCRYPTION_ALWAYS) { /* @@ -2453,7 +2432,6 @@ httpReconnect2(http_t *http, /* I - HTTP connection */ } else if (http->encryption == HTTP_ENCRYPTION_REQUIRED && !http->tls_upgrade) return (http_tls_upgrade(http)); -#endif /* HAVE_TLS */ DEBUG_printf(("1httpReconnect2: Connected to %s:%d...", httpAddrString(http->hostaddr, temp, sizeof(temp)), @@ -2539,11 +2517,9 @@ httpSetCredentials(http_t *http, /* I - HTTP connection */ if (!http || cupsArrayCount(credentials) < 1) return (-1); -#ifdef HAVE_TLS _httpFreeCredentials(http->tls_credentials); http->tls_credentials = _httpCreateCredentials(credentials); -#endif /* HAVE_TLS */ return (http->tls_credentials ? 0 : -1); } @@ -2728,10 +2704,8 @@ httpShutdown(http_t *http) /* I - HTTP connection */ if (!http || http->fd < 0) return; -#ifdef HAVE_TLS if (http->tls) _httpTLSStop(http); -#endif /* HAVE_TLS */ #ifdef _WIN32 shutdown(http->fd, SD_RECEIVE); /* Microsoft-ism... */ @@ -2806,7 +2780,6 @@ _httpUpdate(http_t *http, /* I - HTTP connection */ if (http->status < HTTP_STATUS_BAD_REQUEST) http->digest_tries = 0; -#ifdef HAVE_TLS if (http->status == HTTP_STATUS_SWITCHING_PROTOCOLS && !http->tls) { if (_httpTLSStart(http) != 0) @@ -2821,7 +2794,6 @@ _httpUpdate(http_t *http, /* I - HTTP connection */ *status = HTTP_STATUS_CONTINUE; return (0); } -#endif /* HAVE_TLS */ if (http_set_length(http) < 0) { @@ -3030,13 +3002,11 @@ _httpWait(http_t *http, /* I - HTTP connection */ * Check the SSL/TLS buffers for data first... */ -#ifdef HAVE_TLS if (http->tls && _httpTLSPending(http)) { DEBUG_puts("5_httpWait: Return 1 since there is pending TLS data."); return (1); } -#endif /* HAVE_TLS */ /* * Then try doing a select() or poll() to poll the socket... @@ -3403,7 +3373,6 @@ httpWriteResponse(http_t *http, /* I - HTTP connection */ httpSetField(http, HTTP_FIELD_KEEP_ALIVE, "timeout=10"); } -#ifdef HAVE_TLS if (status == HTTP_STATUS_UPGRADE_REQUIRED || status == HTTP_STATUS_SWITCHING_PROTOCOLS) { @@ -3416,7 +3385,6 @@ httpWriteResponse(http_t *http, /* I - HTTP connection */ if (!http->fields[HTTP_FIELD_CONTENT_LENGTH]) httpSetField(http, HTTP_FIELD_CONTENT_LENGTH, "0"); } -#endif /* HAVE_TLS */ if (!http->fields[HTTP_FIELD_SERVER]) httpSetField(http, HTTP_FIELD_SERVER, http->default_fields[HTTP_FIELD_SERVER] ? http->default_fields[HTTP_FIELD_SERVER] : CUPS_MINIMAL); @@ -4131,12 +4099,10 @@ http_read(http_t *http, /* I - HTTP connection */ do { -#ifdef HAVE_TLS if (http->tls) bytes = _httpTLSRead(http, buffer, (int)length); else -#endif /* HAVE_TLS */ - bytes = recv(http->fd, buffer, length, 0); + bytes = recv(http->fd, buffer, length, 0); if (bytes < 0) { @@ -4403,13 +4369,11 @@ http_send(http_t *http, /* I - HTTP connection */ http->status = HTTP_STATUS_CONTINUE; -#ifdef HAVE_TLS if (http->encryption == HTTP_ENCRYPTION_REQUIRED && !http->tls) { httpSetField(http, HTTP_FIELD_CONNECTION, "Upgrade"); httpSetField(http, HTTP_FIELD_UPGRADE, "TLS/1.2,TLS/1.1,TLS/1.0"); } -#endif /* HAVE_TLS */ if (httpPrintf(http, "%s %s HTTP/1.1\r\n", codes[request], buf) < 1) { @@ -4588,7 +4552,6 @@ http_set_wait(http_t *http) /* I - HTTP connection */ } -#ifdef HAVE_TLS /* * 'http_tls_upgrade()' - Force upgrade to TLS encryption. */ @@ -4679,7 +4642,6 @@ http_tls_upgrade(http_t *http) /* I - HTTP connection */ else return (ret); } -#endif /* HAVE_TLS */ /* @@ -4760,12 +4722,10 @@ http_write(http_t *http, /* I - HTTP connection */ while (nfds <= 0); } -#ifdef HAVE_TLS if (http->tls) bytes = _httpTLSWrite(http, buffer, (int)length); else -#endif /* HAVE_TLS */ - bytes = send(http->fd, buffer, length, 0); + bytes = send(http->fd, buffer, length, 0); DEBUG_printf(("8http_write: Write of " CUPS_LLFMT " bytes returned " CUPS_LLFMT ".", CUPS_LLCAST length, CUPS_LLCAST bytes)); diff --git a/cups/request.c b/cups/request.c index 66c803a04c..513c00f6b8 100644 --- a/cups/request.c +++ b/cups/request.c @@ -432,8 +432,6 @@ cupsGetResponse(http_t *http, /* I - Connection to server or @code CUPS_HTTP else http->status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED; } - -#ifdef HAVE_TLS else if (status == HTTP_STATUS_UPGRADE_REQUIRED) { /* @@ -445,7 +443,6 @@ cupsGetResponse(http_t *http, /* I - Connection to server or @code CUPS_HTTP if (!httpReconnect2(http, 30000, NULL)) httpEncryption(http, HTTP_ENCRYPTION_REQUIRED); } -#endif /* HAVE_TLS */ } if (response) @@ -636,7 +633,6 @@ cupsSendRequest(http_t *http, /* I - Connection to server or @code CUPS_HTTP return (HTTP_STATUS_ERROR); } -#ifdef HAVE_TLS /* * See if we have an auth-info attribute and are communicating over * a non-local link. If so, encrypt the link so that we can pass @@ -650,7 +646,6 @@ cupsSendRequest(http_t *http, /* I - Connection to server or @code CUPS_HTTP DEBUG_puts("1cupsSendRequest: Unable to encrypt connection."); return (HTTP_STATUS_SERVICE_UNAVAILABLE); } -#endif /* HAVE_TLS */ /* * Reconnect if the last response had a "Connection: close"... @@ -841,7 +836,6 @@ cupsSendRequest(http_t *http, /* I - Connection to server or @code CUPS_HTTP } break; -#ifdef HAVE_TLS case HTTP_STATUS_UPGRADE_REQUIRED : /* * Flush any error message, reconnect, and then upgrade with @@ -864,7 +858,6 @@ cupsSendRequest(http_t *http, /* I - Connection to server or @code CUPS_HTTP return (HTTP_STATUS_SERVICE_UNAVAILABLE); } break; -#endif /* HAVE_TLS */ case HTTP_STATUS_EXPECTATION_FAILED : /* diff --git a/cups/testhttp.c b/cups/testhttp.c index 66a112ed87..bd8864031f 100644 --- a/cups/testhttp.c +++ b/cups/testhttp.c @@ -781,7 +781,6 @@ main(int argc, /* I - Number of command-line arguments */ continue; } -#ifdef HAVE_TLS else if (status == HTTP_STATUS_UPGRADE_REQUIRED) { /* Flush any error message... */ @@ -800,7 +799,6 @@ main(int argc, /* I - Number of command-line arguments */ /* Try again, this time with encryption enabled... */ continue; } -#endif /* HAVE_TLS */ } while (status == HTTP_STATUS_UNAUTHORIZED || status == HTTP_STATUS_UPGRADE_REQUIRED); @@ -883,7 +881,6 @@ main(int argc, /* I - Number of command-line arguments */ continue; } -#ifdef HAVE_TLS else if (status == HTTP_STATUS_UPGRADE_REQUIRED) { /* Flush any error message... */ @@ -902,7 +899,6 @@ main(int argc, /* I - Number of command-line arguments */ /* Try again, this time with encryption enabled... */ continue; } -#endif /* HAVE_TLS */ } while (status == HTTP_STATUS_UNAUTHORIZED || status == HTTP_STATUS_UPGRADE_REQUIRED); diff --git a/cups/tls-darwin.c b/cups/tls-darwin.c deleted file mode 100644 index fb5caac071..0000000000 --- a/cups/tls-darwin.c +++ /dev/null @@ -1,2321 +0,0 @@ -/* - * TLS support code for CUPS on macOS. - * - * Copyright © 2021-2023 by OpenPrinting - * Copyright © 2007-2021 by Apple Inc. - * Copyright © 1997-2007 by Easy Software Products, all rights reserved. - * - * Licensed under Apache License v2.0. See the file "LICENSE" for more - * information. - */ - -/**** This file is included from tls.c ****/ - -/* - * Include necessary headers... - */ - -#include -#include "tls-darwin.h" - -/* - * Constants, very secure stuff... - */ - -#define _CUPS_CDSA_PASSWORD "42" /* CUPS keychain password */ -#define _CUPS_CDSA_PASSLEN 2 /* Length of keychain password */ - - -/* - * Local globals... - */ - -static int tls_auto_create = 0; - /* Auto-create self-signed certs? */ -static char *tls_common_name = NULL; - /* Default common name */ -#if TARGET_OS_OSX -static int tls_cups_keychain = 0; - /* Opened the CUPS keychain? */ -static SecKeychainRef tls_keychain = NULL; - /* Server cert keychain */ -#else -static SecIdentityRef tls_selfsigned = NULL; - /* Temporary self-signed cert */ -#endif /* TARGET_OS_OSX */ -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 */ - tls_min_version = _HTTP_TLS_1_0, - tls_max_version = _HTTP_TLS_MAX; - - -/* - * Local functions... - */ - -static CFArrayRef http_cdsa_copy_server(const char *common_name); -static SecCertificateRef http_cdsa_create_credential(http_credential_t *credential); -#if TARGET_OS_OSX -static const char *http_cdsa_default_path(char *buffer, size_t bufsize); -static SecKeychainRef http_cdsa_open_keychain(const char *path, char *filename, size_t filesize); -static SecKeychainRef http_cdsa_open_system_keychain(void); -#endif /* TARGET_OS_OSX */ -static OSStatus http_cdsa_read(SSLConnectionRef connection, void *data, size_t *dataLength); -static int http_cdsa_set_credentials(http_t *http); -static OSStatus http_cdsa_write(SSLConnectionRef connection, const void *data, size_t *dataLength); - - -/* - * 'cupsMakeServerCredentials()' - Make a self-signed certificate and private key pair. - * - * @since CUPS 2.0/OS 10.10@ - */ - -int /* O - 1 on success, 0 on failure */ -cupsMakeServerCredentials( - const char *path, /* I - Keychain path or @code NULL@ for default */ - const char *common_name, /* I - Common name */ - int num_alt_names, /* I - Number of subject alternate names */ - const char **alt_names, /* I - Subject Alternate Names */ - time_t expiration_date) /* I - Expiration date */ -{ -#if TARGET_OS_OSX - int pid, /* Process ID of command */ - status, /* Status of command */ - i; /* Looping var */ - char command[1024], /* Command */ - *argv[5], /* Command-line arguments */ - *envp[1000], /* Environment variables */ - days[32], /* CERTTOOL_EXPIRATION_DAYS env var */ - keychain[1024], /* Keychain argument */ - infofile[1024], /* Type-in information for cert */ - filename[1024]; /* Default keychain path */ - cups_file_t *fp; /* Seed/info file */ - - - DEBUG_printf(("cupsMakeServerCredentials(path=\"%s\", common_name=\"%s\", num_alt_names=%d, alt_names=%p, expiration_date=%d)", path, common_name, num_alt_names, (void *)alt_names, (int)expiration_date)); - - (void)num_alt_names; - (void)alt_names; - - if (!path) - path = http_cdsa_default_path(filename, sizeof(filename)); - - /* - * Run the "certtool" command to generate a self-signed certificate... - */ - - if (!cupsFileFind("certtool", getenv("PATH"), 1, command, sizeof(command))) - return (0); - - /* - * Create a file with the certificate information fields... - * - * Note: This assumes that the default questions are asked by the certtool - * command... - */ - - if ((fp = cupsTempFile2(infofile, sizeof(infofile))) == NULL) - return (0); - - cupsFilePrintf(fp, - "CUPS Self-Signed Certificate\n" - /* Enter key and certificate label */ - "r\n" /* Generate RSA key pair */ - "2048\n" /* 2048 bit encryption key */ - "y\n" /* OK (y = yes) */ - "b\n" /* Usage (b=signing/encryption) */ - "2\n" /* Sign with SHA256 */ - "y\n" /* OK (y = yes) */ - "%s\n" /* Common name */ - "\n" /* Country (default) */ - "\n" /* Organization (default) */ - "\n" /* Organizational unit (default) */ - "\n" /* State/Province (default) */ - "\n" /* Email address */ - "y\n", /* OK (y = yes) */ - common_name); - cupsFileClose(fp); - - snprintf(keychain, sizeof(keychain), "k=%s", path); - - argv[0] = "certtool"; - argv[1] = "c"; - argv[2] = keychain; - argv[3] = NULL; - - snprintf(days, sizeof(days), "CERTTOOL_EXPIRATION_DAYS=%d", (int)((expiration_date - time(NULL) + 86399) / 86400)); - envp[0] = days; - for (i = 0; i < (int)(sizeof(envp) / sizeof(envp[0]) - 2) && environ[i]; i ++) - envp[i + 1] = environ[i]; - envp[i] = NULL; - - posix_spawn_file_actions_t actions; /* File actions */ - - posix_spawn_file_actions_init(&actions); - posix_spawn_file_actions_addclose(&actions, 0); - posix_spawn_file_actions_addopen(&actions, 0, infofile, O_RDONLY, 0); - posix_spawn_file_actions_addclose(&actions, 1); - posix_spawn_file_actions_addopen(&actions, 1, "/dev/null", O_WRONLY, 0); - posix_spawn_file_actions_addclose(&actions, 2); - posix_spawn_file_actions_addopen(&actions, 2, "/dev/null", O_WRONLY, 0); - - if (posix_spawn(&pid, command, &actions, NULL, argv, envp)) - { - unlink(infofile); - return (0); - } - - posix_spawn_file_actions_destroy(&actions); - - unlink(infofile); - - while (waitpid(pid, &status, 0) < 0) - if (errno != EINTR) - { - return (0); - } - - return (!status); - -#else - int status = 0; /* Return status */ - OSStatus err; /* Error code (if any) */ - CFStringRef cfcommon_name = NULL; - /* CF string for server name */ - SecIdentityRef ident = NULL; /* Identity */ - SecKeyRef publicKey = NULL, - /* Public key */ - privateKey = NULL; - /* Private key */ - SecCertificateRef cert = NULL; /* Self-signed certificate */ - CFMutableDictionaryRef keyParams = NULL; - /* Key generation parameters */ - - - DEBUG_printf(("cupsMakeServerCredentials(path=\"%s\", common_name=\"%s\", num_alt_names=%d, alt_names=%p, expiration_date=%d)", path, common_name, num_alt_names, alt_names, (int)expiration_date)); - - (void)path; - (void)num_alt_names; - (void)alt_names; - (void)expiration_date; - - if (path) - { - DEBUG_puts("1cupsMakeServerCredentials: No keychain support compiled in, returning 0."); - return (0); - } - - if (tls_selfsigned) - { - DEBUG_puts("1cupsMakeServerCredentials: Using existing self-signed cert."); - return (1); - } - - cfcommon_name = CFStringCreateWithCString(kCFAllocatorDefault, common_name, kCFStringEncodingUTF8); - if (!cfcommon_name) - { - DEBUG_puts("1cupsMakeServerCredentials: Unable to create CF string of common name."); - goto cleanup; - } - - /* - * Create a public/private key pair... - */ - - keyParams = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - if (!keyParams) - { - DEBUG_puts("1cupsMakeServerCredentials: Unable to create key parameters dictionary."); - goto cleanup; - } - - CFDictionaryAddValue(keyParams, kSecAttrKeyType, kSecAttrKeyTypeRSA); - CFDictionaryAddValue(keyParams, kSecAttrKeySizeInBits, CFSTR("2048")); - CFDictionaryAddValue(keyParams, kSecAttrLabel, cfcommon_name); - - err = SecKeyGeneratePair(keyParams, &publicKey, &privateKey); - if (err != noErr) - { - DEBUG_printf(("1cupsMakeServerCredentials: Unable to generate key pair: %d.", (int)err)); - goto cleanup; - } - - /* - * Create a self-signed certificate using the public/private key pair... - */ - - CFIndex usageInt = kSecKeyUsageAll; - CFNumberRef usage = CFNumberCreate(kCFAllocatorDefault, kCFNumberCFIndexType, &usageInt); - CFIndex lenInt = 0; - CFNumberRef len = CFNumberCreate(kCFAllocatorDefault, kCFNumberCFIndexType, &lenInt); - CFTypeRef certKeys[] = { kSecCSRBasicConstraintsPathLen, kSecSubjectAltName, kSecCertificateKeyUsage }; - CFTypeRef certValues[] = { len, cfcommon_name, usage }; - CFDictionaryRef certParams = CFDictionaryCreate(kCFAllocatorDefault, certKeys, certValues, sizeof(certKeys) / sizeof(certKeys[0]), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - CFRelease(usage); - CFRelease(len); - - const void *ca_o[] = { kSecOidOrganization, CFSTR("") }; - const void *ca_cn[] = { kSecOidCommonName, cfcommon_name }; - CFArrayRef ca_o_dn = CFArrayCreate(kCFAllocatorDefault, ca_o, 2, NULL); - CFArrayRef ca_cn_dn = CFArrayCreate(kCFAllocatorDefault, ca_cn, 2, NULL); - const void *ca_dn_array[2]; - - ca_dn_array[0] = CFArrayCreate(kCFAllocatorDefault, (const void **)&ca_o_dn, 1, NULL); - ca_dn_array[1] = CFArrayCreate(kCFAllocatorDefault, (const void **)&ca_cn_dn, 1, NULL); - - CFArrayRef subject = CFArrayCreate(kCFAllocatorDefault, ca_dn_array, 2, NULL); - - cert = SecGenerateSelfSignedCertificate(subject, certParams, publicKey, privateKey); - - CFRelease(subject); - CFRelease(certParams); - - if (!cert) - { - DEBUG_puts("1cupsMakeServerCredentials: Unable to create self-signed certificate."); - goto cleanup; - } - - ident = SecIdentityCreate(kCFAllocatorDefault, cert, privateKey); - - if (ident) - { - _cupsMutexLock(&tls_mutex); - - if (tls_selfsigned) - CFRelease(ident); - else - tls_selfsigned = ident; - - _cupsMutexUnlock(&tls_mutex); - -# if 0 /* Someday perhaps SecItemCopyMatching will work for identities, at which point */ - CFTypeRef itemKeys[] = { kSecClass, kSecAttrLabel, kSecValueRef }; - CFTypeRef itemValues[] = { kSecClassIdentity, cfcommon_name, ident }; - CFDictionaryRef itemAttrs = CFDictionaryCreate(kCFAllocatorDefault, itemKeys, itemValues, sizeof(itemKeys) / sizeof(itemKeys[0]), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - - err = SecItemAdd(itemAttrs, NULL); - /* SecItemAdd consumes itemAttrs... */ - - CFRelease(ident); - - if (err != noErr) - { - DEBUG_printf(("1cupsMakeServerCredentials: Unable to add identity to keychain: %d.", (int)err)); - goto cleanup; - } -# endif /* 0 */ - - status = 1; - } - else - DEBUG_puts("1cupsMakeServerCredentials: Unable to create identity from cert and keys."); - - /* - * Cleanup and return... - */ - -cleanup: - - if (cfcommon_name) - CFRelease(cfcommon_name); - - if (keyParams) - CFRelease(keyParams); - - if (cert) - CFRelease(cert); - - if (publicKey) - CFRelease(publicKey); - - if (privateKey) - CFRelease(privateKey); - - DEBUG_printf(("1cupsMakeServerCredentials: Returning %d.", status)); - - return (status); -#endif /* TARGET_OS_OSX */ -} - - -/* - * 'cupsSetServerCredentials()' - Set the default server credentials. - * - * Note: The server credentials are used by all threads in the running process. - * This function is threadsafe. - * - * @since CUPS 2.0/macOS 10.10@ - */ - -int /* O - 1 on success, 0 on failure */ -cupsSetServerCredentials( - const char *path, /* I - Keychain path or @code NULL@ for default */ - const char *common_name, /* I - Default common name for server */ - int auto_create) /* I - 1 = automatically create self-signed certificates */ -{ - DEBUG_printf(("cupsSetServerCredentials(path=\"%s\", common_name=\"%s\", auto_create=%d)", path, common_name, auto_create)); - -#if TARGET_OS_OSX - char filename[1024]; /* Keychain filename */ - SecKeychainRef keychain = http_cdsa_open_keychain(path, filename, sizeof(filename)); - - if (!keychain) - { - DEBUG_puts("1cupsSetServerCredentials: Unable to open keychain."); - return (0); - } - - _cupsMutexLock(&tls_mutex); - - /* - * Close any keychain that is currently open... - */ - - if (tls_keychain) - CFRelease(tls_keychain); - - if (tls_keypath) - _cupsStrFree(tls_keypath); - - if (tls_common_name) - _cupsStrFree(tls_common_name); - - /* - * Save the new keychain... - */ - - tls_keychain = keychain; - tls_keypath = _cupsStrAlloc(filename); - tls_auto_create = auto_create; - tls_common_name = _cupsStrAlloc(common_name); - - _cupsMutexUnlock(&tls_mutex); - - DEBUG_puts("1cupsSetServerCredentials: Opened keychain, returning 1."); - return (1); - -#else - if (path) - { - DEBUG_puts("1cupsSetServerCredentials: No keychain support compiled in, returning 0."); - return (0); - } - - tls_auto_create = auto_create; - tls_common_name = _cupsStrAlloc(common_name); - - return (1); -#endif /* TARGET_OS_OSX */ -} - - -/* - * 'httpCopyCredentials()' - Copy the credentials associated with the peer in - * an encrypted connection. - * - * @since CUPS 1.5/macOS 10.7@ - */ - -int /* O - Status of call (0 = success) */ -httpCopyCredentials( - http_t *http, /* I - Connection to server */ - cups_array_t **credentials) /* O - Array of credentials */ -{ - OSStatus error; /* Error code */ - SecTrustRef peerTrust; /* Peer trust reference */ - CFDataRef data; /* Certificate data */ - - - DEBUG_printf(("httpCopyCredentials(http=%p, credentials=%p)", (void *)http, (void *)credentials)); - - if (credentials) - *credentials = NULL; - - if (!http || !http->tls || !credentials) - return (-1); - - if (!(error = SSLCopyPeerTrust(http->tls, &peerTrust)) && peerTrust) - { - if ((*credentials = cupsArrayNew(NULL, NULL)) != NULL) - { - CFArrayRef secArray = SecTrustCopyCertificateChain(peerTrust); - CFIndex i, count = CFArrayGetCount(secArray); - - DEBUG_printf(("2httpCopyCredentials: Peer provided %ld certificates.", (long)count)); - - for (i = 0; i < count; i ++) - { - SecCertificateRef secCert = (SecCertificateRef)CFArrayGetValueAtIndex(secArray, i); - -#ifdef DEBUG - CFStringRef cf_name = SecCertificateCopySubjectSummary(secCert); - char name[1024]; - if (cf_name) - CFStringGetCString(cf_name, name, sizeof(name), kCFStringEncodingUTF8); - else - strlcpy(name, "unknown", sizeof(name)); - - DEBUG_printf(("2httpCopyCredentials: Certificate %ld name is \"%s\".", (long)i, name)); -#endif /* DEBUG */ - - if ((data = SecCertificateCopyData(secCert)) != NULL) - { - DEBUG_printf(("2httpCopyCredentials: Adding %ld byte certificate blob.", (long)CFDataGetLength(data))); - - httpAddCredential(*credentials, CFDataGetBytePtr(data), (size_t)CFDataGetLength(data)); - CFRelease(data); - } - } - CFRelease(secArray); - } - - CFRelease(peerTrust); - } - - return (error); -} - - -/* - * '_httpCreateCredentials()' - Create credentials in the internal format. - */ - -http_tls_credentials_t /* O - Internal credentials */ -_httpCreateCredentials( - cups_array_t *credentials) /* I - Array of credentials */ -{ - CFMutableArrayRef peerCerts; /* Peer credentials reference */ - SecCertificateRef secCert; /* Certificate reference */ - http_credential_t *credential; /* Credential data */ - - - if (!credentials) - return (NULL); - - if ((peerCerts = CFArrayCreateMutable(kCFAllocatorDefault, - cupsArrayCount(credentials), - &kCFTypeArrayCallBacks)) == NULL) - return (NULL); - - for (credential = (http_credential_t *)cupsArrayFirst(credentials); - credential; - credential = (http_credential_t *)cupsArrayNext(credentials)) - { - if ((secCert = http_cdsa_create_credential(credential)) != NULL) - { - CFArrayAppendValue(peerCerts, secCert); - CFRelease(secCert); - } - } - - return (peerCerts); -} - - -/* - * 'httpCredentialsAreValidForName()' - Return whether the credentials are valid for the given name. - * - * @since CUPS 2.0/macOS 10.10@ - */ - -int /* O - 1 if valid, 0 otherwise */ -httpCredentialsAreValidForName( - cups_array_t *credentials, /* I - Credentials */ - const char *common_name) /* I - Name to check */ -{ - SecCertificateRef secCert; /* Certificate reference */ - CFStringRef cfcert_name = NULL; - /* Certificate's common name (CF string) */ - char cert_name[256]; /* Certificate's common name (C string) */ - int valid = 1; /* Valid name? */ - - - if ((secCert = http_cdsa_create_credential((http_credential_t *)cupsArrayFirst(credentials))) == NULL) - return (0); - - /* - * Compare the common names... - */ - - if ((cfcert_name = SecCertificateCopySubjectSummary(secCert)) == NULL) - { - /* - * Can't get common name, cannot be valid... - */ - - valid = 0; - } - else if (CFStringGetCString(cfcert_name, cert_name, sizeof(cert_name), kCFStringEncodingUTF8) && - _cups_strcasecmp(common_name, cert_name)) - { - /* - * Not an exact match for the common name, check for wildcard certs... - */ - - const char *domain = strchr(common_name, '.'); - /* Domain in common name */ - - if (strncmp(cert_name, "*.", 2) || !domain || _cups_strcasecmp(domain, cert_name + 1)) - { - /* - * Not a wildcard match. - */ - - /* TODO: Check subject alternate names */ - valid = 0; - } - } - - if (cfcert_name) - CFRelease(cfcert_name); - - CFRelease(secCert); - - return (valid); -} - - -/* - * 'httpCredentialsGetTrust()' - Return the trust of credentials. - * - * @since CUPS 2.0/macOS 10.10@ - */ - -http_trust_t /* O - Level of trust */ -httpCredentialsGetTrust( - cups_array_t *credentials, /* I - Credentials */ - const char *common_name) /* I - Common name for trust lookup */ -{ - SecCertificateRef secCert; /* Certificate reference */ - http_trust_t trust = HTTP_TRUST_OK; - /* Trusted? */ - cups_array_t *tcreds = NULL; /* Trusted credentials */ - _cups_globals_t *cg = _cupsGlobals(); - /* Per-thread globals */ - - - if (!common_name) - { - _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("No common name specified."), 1); - return (HTTP_TRUST_UNKNOWN); - } - - if ((secCert = http_cdsa_create_credential((http_credential_t *)cupsArrayFirst(credentials))) == NULL) - { - _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Unable to create credentials from array."), 1); - return (HTTP_TRUST_UNKNOWN); - } - - if (cg->any_root < 0) - _cupsSetDefaults(); - - /* - * Look this common name up in the default keychains... - */ - - httpLoadCredentials(NULL, &tcreds, common_name); - - if (tcreds) - { - char credentials_str[1024], /* String for incoming credentials */ - tcreds_str[1024]; /* String for saved credentials */ - - httpCredentialsString(credentials, credentials_str, sizeof(credentials_str)); - httpCredentialsString(tcreds, tcreds_str, sizeof(tcreds_str)); - - if (strcmp(credentials_str, tcreds_str)) - { - /* - * Credentials don't match, let's look at the expiration date of the new - * credentials and allow if the new ones have a later expiration... - */ - - if (!cg->trust_first) - { - /* - * Do not trust certificates on first use... - */ - - _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Trust on first use is disabled."), 1); - - trust = HTTP_TRUST_INVALID; - } - else if (httpCredentialsGetExpiration(credentials) <= httpCredentialsGetExpiration(tcreds)) - { - /* - * The new credentials are not newly issued... - */ - - _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("New credentials are older than stored credentials."), 1); - - trust = HTTP_TRUST_INVALID; - } - else if (!httpCredentialsAreValidForName(credentials, common_name)) - { - /* - * The common name does not match the issued certificate... - */ - - _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("New credentials are not valid for name."), 1); - - trust = HTTP_TRUST_INVALID; - } - else if (httpCredentialsGetExpiration(tcreds) < time(NULL)) - { - /* - * Save the renewed credentials... - */ - - trust = HTTP_TRUST_RENEWED; - - httpSaveCredentials(NULL, credentials, common_name); - } - } - - httpFreeCredentials(tcreds); - } - else if (cg->validate_certs && !httpCredentialsAreValidForName(credentials, common_name)) - { - _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("No stored credentials, not valid for name."), 1); - trust = HTTP_TRUST_INVALID; - } - else if (!cg->trust_first) - { - /* - * See if we have a site CA certificate we can compare... - */ - - if (!httpLoadCredentials(NULL, &tcreds, "site")) - { - if (cupsArrayCount(credentials) != (cupsArrayCount(tcreds) + 1)) - { - /* - * Certificate isn't directly generated from the CA cert... - */ - - trust = HTTP_TRUST_INVALID; - } - else - { - /* - * Do a tail comparison of the two certificates... - */ - - http_credential_t *a, *b; /* Certificates */ - - for (a = (http_credential_t *)cupsArrayFirst(tcreds), b = (http_credential_t *)cupsArrayIndex(credentials, 1); - a && b; - a = (http_credential_t *)cupsArrayNext(tcreds), b = (http_credential_t *)cupsArrayNext(credentials)) - if (a->datalen != b->datalen || memcmp(a->data, b->data, a->datalen)) - break; - - if (a || b) - trust = HTTP_TRUST_INVALID; - } - - if (trust != HTTP_TRUST_OK) - _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Credentials do not validate against site CA certificate."), 1); - } - else - { - _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Trust on first use is disabled."), 1); - trust = HTTP_TRUST_INVALID; - } - } - - if (trust == HTTP_TRUST_OK && !cg->expired_certs && !SecCertificateIsValid(secCert, CFAbsoluteTimeGetCurrent())) - { - _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Credentials have expired."), 1); - trust = HTTP_TRUST_EXPIRED; - } - - if (trust == HTTP_TRUST_OK && !cg->any_root && cupsArrayCount(credentials) == 1) - { - _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Self-signed credentials are blocked."), 1); - trust = HTTP_TRUST_INVALID; - } - - CFRelease(secCert); - - return (trust); -} - - -/* - * 'httpCredentialsGetExpiration()' - Return the expiration date of the credentials. - * - * @since CUPS 2.0/macOS 10.10@ - */ - -time_t /* O - Expiration date of credentials */ -httpCredentialsGetExpiration( - cups_array_t *credentials) /* I - Credentials */ -{ - SecCertificateRef secCert; /* Certificate reference */ - time_t expiration; /* Expiration date */ - - - if ((secCert = http_cdsa_create_credential((http_credential_t *)cupsArrayFirst(credentials))) == NULL) - return (0); - - expiration = (time_t)(SecCertificateNotValidAfter(secCert) + kCFAbsoluteTimeIntervalSince1970); - - CFRelease(secCert); - - return (expiration); -} - - -/* - * 'httpCredentialsString()' - Return a string representing the credentials. - * - * @since CUPS 2.0/macOS 10.10@ - */ - -size_t /* O - Total size of credentials string */ -httpCredentialsString( - cups_array_t *credentials, /* I - Credentials */ - char *buffer, /* I - Buffer or @code NULL@ */ - size_t bufsize) /* I - Size of buffer */ -{ - http_credential_t *first; /* First certificate */ - SecCertificateRef secCert; /* Certificate reference */ - - - DEBUG_printf(("httpCredentialsString(credentials=%p, buffer=%p, bufsize=" CUPS_LLFMT ")", (void *)credentials, (void *)buffer, CUPS_LLCAST bufsize)); - - if (!buffer) - return (0); - - if (bufsize > 0) - *buffer = '\0'; - - if ((first = (http_credential_t *)cupsArrayFirst(credentials)) != NULL && - (secCert = http_cdsa_create_credential(first)) != NULL) - { - /* - * Copy certificate (string) values from the SecCertificateRef and produce - * a one-line summary. The API for accessing certificate values like the - * issuer name is, um, "interesting"... - */ - -# if TARGET_OS_OSX - CFDictionaryRef cf_dict; /* Dictionary for certificate */ -# endif /* TARGET_OS_OSX */ - CFStringRef cf_string; /* CF string */ - char commonName[256],/* Common name associated with cert */ - issuer[256], /* Issuer name */ - sigalg[256]; /* Signature algorithm */ - time_t expiration; /* Expiration date of cert */ - unsigned char md5_digest[16]; /* MD5 result */ - - if (SecCertificateCopyCommonName(secCert, &cf_string) == noErr) - { - CFStringGetCString(cf_string, commonName, (CFIndex)sizeof(commonName), kCFStringEncodingUTF8); - CFRelease(cf_string); - } - else - { - strlcpy(commonName, "unknown", sizeof(commonName)); - } - - strlcpy(issuer, "unknown", sizeof(issuer)); - strlcpy(sigalg, "UnknownSignature", sizeof(sigalg)); - -# if TARGET_OS_OSX - if ((cf_dict = SecCertificateCopyValues(secCert, NULL, NULL)) != NULL) - { - CFDictionaryRef cf_issuer = CFDictionaryGetValue(cf_dict, kSecOIDX509V1IssuerName); - CFDictionaryRef cf_sigalg = CFDictionaryGetValue(cf_dict, kSecOIDX509V1SignatureAlgorithm); - - if (cf_issuer) - { - CFArrayRef cf_values = CFDictionaryGetValue(cf_issuer, kSecPropertyKeyValue); - CFIndex i, count = CFArrayGetCount(cf_values); - CFDictionaryRef cf_value; - - for (i = 0; i < count; i ++) - { - cf_value = CFArrayGetValueAtIndex(cf_values, i); - - if (!CFStringCompare(CFDictionaryGetValue(cf_value, kSecPropertyKeyLabel), kSecOIDOrganizationName, kCFCompareCaseInsensitive)) - CFStringGetCString(CFDictionaryGetValue(cf_value, kSecPropertyKeyValue), issuer, (CFIndex)sizeof(issuer), kCFStringEncodingUTF8); - } - } - - if (cf_sigalg) - { - CFArrayRef cf_values = CFDictionaryGetValue(cf_sigalg, kSecPropertyKeyValue); - CFIndex i, count = CFArrayGetCount(cf_values); - CFDictionaryRef cf_value; - - for (i = 0; i < count; i ++) - { - cf_value = CFArrayGetValueAtIndex(cf_values, i); - - if (!CFStringCompare(CFDictionaryGetValue(cf_value, kSecPropertyKeyLabel), CFSTR("Algorithm"), kCFCompareCaseInsensitive)) - { - CFStringRef cf_algorithm = CFDictionaryGetValue(cf_value, kSecPropertyKeyValue); - - if (!CFStringCompare(cf_algorithm, CFSTR("1.2.840.113549.1.1.5"), kCFCompareCaseInsensitive)) - strlcpy(sigalg, "SHA1WithRSAEncryption", sizeof(sigalg)); - else if (!CFStringCompare(cf_algorithm, CFSTR("1.2.840.113549.1.1.11"), kCFCompareCaseInsensitive)) - strlcpy(sigalg, "SHA256WithRSAEncryption", sizeof(sigalg)); - else if (!CFStringCompare(cf_algorithm, CFSTR("1.2.840.113549.1.1.4"), kCFCompareCaseInsensitive)) - strlcpy(sigalg, "MD5WithRSAEncryption", sizeof(sigalg)); - } - } - } - - CFRelease(cf_dict); - } -# endif /* TARGET_OS_OSX */ - - expiration = (time_t)(SecCertificateNotValidAfter(secCert) + kCFAbsoluteTimeIntervalSince1970); - - cupsHashData("md5", first->data, first->datalen, md5_digest, sizeof(md5_digest)); - - snprintf(buffer, bufsize, "%s (issued by %s) / %s / %s / %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", commonName, issuer, httpGetDateString(expiration), sigalg, 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]); - - CFRelease(secCert); - } - - DEBUG_printf(("1httpCredentialsString: Returning \"%s\".", buffer)); - - return (strlen(buffer)); -} - - -/* - * '_httpFreeCredentials()' - Free internal credentials. - */ - -void -_httpFreeCredentials( - http_tls_credentials_t credentials) /* I - Internal credentials */ -{ - if (credentials) - CFRelease(credentials); -} - - -/* - * 'httpLoadCredentials()' - Load X.509 credentials from a keychain file. - * - * @since CUPS 2.0/OS 10.10@ - */ - -int /* O - 0 on success, -1 on error */ -httpLoadCredentials( - const char *path, /* I - Keychain path or @code NULL@ for default */ - cups_array_t **credentials, /* IO - Credentials */ - const char *common_name) /* I - Common name for credentials */ -{ - OSStatus err; /* Error info */ -#if TARGET_OS_OSX - char filename[1024]; /* Filename for keychain */ - SecKeychainRef keychain = NULL,/* Keychain reference */ - syschain = NULL;/* System keychain */ - CFArrayRef list; /* Keychain list */ -#endif /* TARGET_OS_OSX */ - SecCertificateRef cert = NULL; /* Certificate */ - CFDataRef data; /* Certificate data */ - SecPolicyRef policy = NULL; /* Policy ref */ - CFStringRef cfcommon_name = NULL; - /* Server name */ - CFMutableDictionaryRef query = NULL; /* Query qualifiers */ - - - DEBUG_printf(("httpLoadCredentials(path=\"%s\", credentials=%p, common_name=\"%s\")", path, (void *)credentials, common_name)); - - if (!credentials) - return (-1); - - *credentials = NULL; - -#if TARGET_OS_OSX - keychain = http_cdsa_open_keychain(path, filename, sizeof(filename)); - - if (!keychain) - goto cleanup; - - syschain = http_cdsa_open_system_keychain(); - -#else - if (path) - return (-1); -#endif /* TARGET_OS_OSX */ - - cfcommon_name = CFStringCreateWithCString(kCFAllocatorDefault, common_name, kCFStringEncodingUTF8); - - policy = SecPolicyCreateSSL(1, cfcommon_name); - - if (cfcommon_name) - CFRelease(cfcommon_name); - - if (!policy) - goto cleanup; - - if (!(query = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks))) - goto cleanup; - - CFDictionaryAddValue(query, kSecClass, kSecClassCertificate); - CFDictionaryAddValue(query, kSecMatchPolicy, policy); - CFDictionaryAddValue(query, kSecReturnRef, kCFBooleanTrue); - CFDictionaryAddValue(query, kSecMatchLimit, kSecMatchLimitOne); - -#if TARGET_OS_OSX - if (syschain) - { - const void *values[2] = { syschain, keychain }; - - list = CFArrayCreate(kCFAllocatorDefault, (const void **)values, 2, &kCFTypeArrayCallBacks); - } - else - list = CFArrayCreate(kCFAllocatorDefault, (const void **)&keychain, 1, &kCFTypeArrayCallBacks); - CFDictionaryAddValue(query, kSecMatchSearchList, list); - CFRelease(list); -#endif /* TARGET_OS_OSX */ - - err = SecItemCopyMatching(query, (CFTypeRef *)&cert); - - if (err) - goto cleanup; - - if (CFGetTypeID(cert) != SecCertificateGetTypeID()) - goto cleanup; - - if ((data = SecCertificateCopyData(cert)) != NULL) - { - DEBUG_printf(("1httpLoadCredentials: Adding %d byte certificate blob.", (int)CFDataGetLength(data))); - - *credentials = cupsArrayNew(NULL, NULL); - httpAddCredential(*credentials, CFDataGetBytePtr(data), (size_t)CFDataGetLength(data)); - CFRelease(data); - } - - cleanup : - -#if TARGET_OS_OSX - if (keychain) - CFRelease(keychain); - - if (syschain) - CFRelease(syschain); -#endif /* TARGET_OS_OSX */ - if (cert) - CFRelease(cert); - if (policy) - CFRelease(policy); - if (query) - CFRelease(query); - - DEBUG_printf(("1httpLoadCredentials: Returning %d.", *credentials ? 0 : -1)); - - return (*credentials ? 0 : -1); -} - - -/* - * 'httpSaveCredentials()' - Save X.509 credentials to a keychain file. - * - * @since CUPS 2.0/OS 10.10@ - */ - -int /* O - -1 on error, 0 on success */ -httpSaveCredentials( - const char *path, /* I - Keychain path or @code NULL@ for default */ - cups_array_t *credentials, /* I - Credentials */ - const char *common_name) /* I - Common name for credentials */ -{ - int ret = 0; /* Return value */ - OSStatus err; /* Error info */ -#if TARGET_OS_OSX - char filename[1024]; /* Filename for keychain */ - SecKeychainRef keychain = NULL;/* Keychain reference */ - CFArrayRef list; /* Keychain list */ -#endif /* TARGET_OS_OSX */ - SecCertificateRef cert = NULL; /* Certificate */ - CFMutableDictionaryRef attrs = NULL; /* Attributes for add */ - - - DEBUG_printf(("httpSaveCredentials(path=\"%s\", credentials=%p, common_name=\"%s\")", path, (void *)credentials, common_name)); - if (!credentials) - { - DEBUG_puts("1httpSaveCredentials: No credentials, returning -1."); - return (-1); - } - - if (!httpCredentialsAreValidForName(credentials, common_name)) - { - DEBUG_puts("1httpSaveCredentials: Common name does not match."); - return (-1); - } - - if ((cert = http_cdsa_create_credential((http_credential_t *)cupsArrayFirst(credentials))) == NULL) - { - DEBUG_puts("1httpSaveCredentials: Unable to create certificate."); - goto cleanup; - } - -#if TARGET_OS_OSX - keychain = http_cdsa_open_keychain(path, filename, sizeof(filename)); - - if (!keychain) - { - DEBUG_puts("1httpSaveCredentials: No keychain, returning -1."); - return (-1); - } - -#else - if (path) - { - DEBUG_puts("1httpSaveCredentials: No path, returning -1."); - return (-1); - } -#endif /* TARGET_OS_OSX */ - - if ((attrs = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)) == NULL) - { - DEBUG_puts("1httpSaveCredentials: Unable to create dictionary."); - goto cleanup; - } - - CFDictionaryAddValue(attrs, kSecClass, kSecClassCertificate); - CFDictionaryAddValue(attrs, kSecValueRef, cert); - -#if TARGET_OS_OSX - if ((list = CFArrayCreate(kCFAllocatorDefault, (const void **)&keychain, 1, &kCFTypeArrayCallBacks)) == NULL) - { - DEBUG_puts("1httpSaveCredentials: Unable to create list of keychains."); - ret = -1; - goto cleanup; - } - CFDictionaryAddValue(attrs, kSecMatchSearchList, list); - CFRelease(list); -#endif /* TARGET_OS_OSX */ - - /* Note: SecItemAdd consumes "attrs"... */ - if((err = SecItemAdd(attrs, NULL)) != 0) - { - DEBUG_printf(("1httpSaveCredentials: SecItemAdd failed, returned %d.", (int)err)); - ret = -1; - } - - cleanup : - -#if TARGET_OS_OSX - CFRelease(keychain); -#endif /* TARGET_OS_OSX */ - CFRelease(cert); - - DEBUG_printf(("1httpSaveCredentials: Returning %d.", ret)); - - return (ret); -} - - -/* - * '_httpTLSInitialize()' - Initialize the TLS stack. - */ - -void -_httpTLSInitialize(void) -{ - /* - * Nothing to do... - */ -} - - -/* - * '_httpTLSPending()' - Return the number of pending TLS-encrypted bytes. - */ - -size_t -_httpTLSPending(http_t *http) /* I - HTTP connection */ -{ - size_t bytes; /* Bytes that are available */ - - - if (!SSLGetBufferedReadSize(http->tls, &bytes)) - return (bytes); - - return (0); -} - - -/* - * '_httpTLSRead()' - Read from a SSL/TLS connection. - */ - -int /* O - Bytes read */ -_httpTLSRead(http_t *http, /* I - HTTP connection */ - char *buf, /* I - Buffer to store data */ - int len) /* I - Length of buffer */ -{ - int result; /* Return value */ - OSStatus error; /* Error info */ - size_t processed; /* Number of bytes processed */ - - - error = SSLRead(http->tls, buf, (size_t)len, &processed); - DEBUG_printf(("5_httpTLSRead: error=%d, processed=%d", (int)error, (int)processed)); - switch (error) - { - case 0 : - result = (int)processed; - break; - - case errSSLWouldBlock : - if (processed) - result = (int)processed; - else - { - result = -1; - errno = EINTR; - } - break; - - case errSSLClosedGraceful : - default : - if (processed) - result = (int)processed; - else - { - result = -1; - errno = EPIPE; - } - break; - } - - return (result); -} - - -/* - * '_httpTLSSetOptions()' - Set TLS protocol and cipher suite options. - */ - -void -_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_min_version = min_version; - tls_max_version = max_version; - } -} - - -/* - * '_httpTLSStart()' - Set up SSL/TLS support on a connection. - */ - -int /* O - 0 on success, -1 on failure */ -_httpTLSStart(http_t *http) /* I - HTTP connection */ -{ - char hostname[256], /* Hostname */ - *hostptr; /* Pointer into hostname */ - _cups_globals_t *cg = _cupsGlobals(); - /* Pointer to library globals */ - OSStatus error; /* Error code */ - const char *message = NULL;/* Error message */ - char msgbuf[1024]; /* Error message buffer */ - cups_array_t *credentials; /* Credentials array */ - cups_array_t *names; /* CUPS distinguished names */ - CFArrayRef dn_array; /* CF distinguished names array */ - CFIndex count; /* Number of credentials */ - CFDataRef data; /* Certificate data */ - int i; /* Looping var */ - http_credential_t *credential; /* Credential data */ - - - DEBUG_printf(("3_httpTLSStart(http=%p)", (void *)http)); - - if (tls_options < 0) - { - DEBUG_puts("4_httpTLSStart: Setting defaults."); - _cupsSetDefaults(); - DEBUG_printf(("4_httpTLSStart: tls_options=%x, tls_min_version=%d, tls_max_version=%d", tls_options, tls_min_version, tls_max_version)); - } - -#if TARGET_OS_OSX - if (http->mode == _HTTP_MODE_SERVER && !tls_keychain) - { - DEBUG_puts("4_httpTLSStart: cupsSetServerCredentials not called."); - http->error = errno = EINVAL; - http->status = HTTP_STATUS_ERROR; - _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Server credentials not set."), 1); - - return (-1); - } -#endif /* TARGET_OS_OSX */ - - if ((http->tls = SSLCreateContext(kCFAllocatorDefault, http->mode == _HTTP_MODE_CLIENT ? kSSLClientSide : kSSLServerSide, kSSLStreamType)) == NULL) - { - DEBUG_puts("4_httpTLSStart: SSLCreateContext failed."); - http->error = errno = ENOMEM; - http->status = HTTP_STATUS_ERROR; - _cupsSetHTTPError(HTTP_STATUS_ERROR); - - return (-1); - } - - error = SSLSetConnection(http->tls, http); - DEBUG_printf(("4_httpTLSStart: SSLSetConnection, error=%d", (int)error)); - - if (!error) - { - error = SSLSetIOFuncs(http->tls, http_cdsa_read, http_cdsa_write); - DEBUG_printf(("4_httpTLSStart: SSLSetIOFuncs, error=%d", (int)error)); - } - - if (!error) - { - error = SSLSetSessionOption(http->tls, kSSLSessionOptionBreakOnServerAuth, - true); - DEBUG_printf(("4_httpTLSStart: SSLSetSessionOption, error=%d", (int)error)); - } - - if (!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_max_version < _HTTP_TLS_MAX) - { - error = SSLSetProtocolVersionMax(http->tls, protocols[tls_max_version]); - DEBUG_printf(("4_httpTLSStart: SSLSetProtocolVersionMax(%d), error=%d", protocols[tls_max_version], (int)error)); - } - } - - if (!error) - { - SSLCipherSuite supported[100]; /* Supported cipher suites */ - size_t num_supported; /* Number of supported cipher suites */ - SSLCipherSuite enabled[100]; /* Cipher suites to enable */ - size_t num_enabled; /* Number of cipher suites to enable */ - - num_supported = sizeof(supported) / sizeof(supported[0]); - error = SSLGetSupportedCiphers(http->tls, supported, &num_supported); - - if (!error) - { - DEBUG_printf(("4_httpTLSStart: %d cipher suites supported.", (int)num_supported)); - - for (i = 0, num_enabled = 0; i < (int)num_supported && num_enabled < (sizeof(enabled) / sizeof(enabled[0])); i ++) - { - switch (supported[i]) - { - /* Obviously insecure cipher suites that we never want to use */ - case SSL_NULL_WITH_NULL_NULL : - case SSL_RSA_WITH_NULL_MD5 : - case SSL_RSA_WITH_NULL_SHA : - case SSL_RSA_EXPORT_WITH_RC4_40_MD5 : - case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5 : - case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA : - case SSL_RSA_WITH_DES_CBC_SHA : - case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA : - case SSL_DH_DSS_WITH_DES_CBC_SHA : - case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA : - case SSL_DH_RSA_WITH_DES_CBC_SHA : - case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA : - case SSL_DHE_DSS_WITH_DES_CBC_SHA : - case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA : - case SSL_DHE_RSA_WITH_DES_CBC_SHA : - case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5 : - case SSL_DH_anon_WITH_RC4_128_MD5 : - case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA : - case SSL_DH_anon_WITH_DES_CBC_SHA : - case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA : - case SSL_FORTEZZA_DMS_WITH_NULL_SHA : - case TLS_DH_anon_WITH_AES_128_CBC_SHA : - case TLS_DH_anon_WITH_AES_256_CBC_SHA : - case TLS_ECDH_ECDSA_WITH_NULL_SHA : - case TLS_ECDHE_RSA_WITH_NULL_SHA : - case TLS_ECDH_anon_WITH_NULL_SHA : - case TLS_ECDH_anon_WITH_RC4_128_SHA : - case TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA : - case TLS_ECDH_anon_WITH_AES_128_CBC_SHA : - case TLS_ECDH_anon_WITH_AES_256_CBC_SHA : - case TLS_RSA_WITH_NULL_SHA256 : - case TLS_DH_anon_WITH_AES_128_CBC_SHA256 : - case TLS_DH_anon_WITH_AES_256_CBC_SHA256 : - case TLS_PSK_WITH_NULL_SHA : - case TLS_DHE_PSK_WITH_NULL_SHA : - case TLS_RSA_PSK_WITH_NULL_SHA : - case TLS_DH_anon_WITH_AES_128_GCM_SHA256 : - case TLS_DH_anon_WITH_AES_256_GCM_SHA384 : - case TLS_PSK_WITH_NULL_SHA256 : - case TLS_PSK_WITH_NULL_SHA384 : - case TLS_DHE_PSK_WITH_NULL_SHA256 : - case TLS_DHE_PSK_WITH_NULL_SHA384 : - case TLS_RSA_PSK_WITH_NULL_SHA256 : - case TLS_RSA_PSK_WITH_NULL_SHA384 : - case SSL_RSA_WITH_DES_CBC_MD5 : - DEBUG_printf(("4_httpTLSStart: Excluding insecure cipher suite %d", supported[i])); - break; - - /* RC4 cipher suites that should only be used as a last resort */ - case SSL_RSA_WITH_RC4_128_MD5 : - case SSL_RSA_WITH_RC4_128_SHA : - case TLS_ECDH_ECDSA_WITH_RC4_128_SHA : - case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA : - case TLS_ECDH_RSA_WITH_RC4_128_SHA : - case TLS_ECDHE_RSA_WITH_RC4_128_SHA : - case TLS_PSK_WITH_RC4_128_SHA : - case TLS_DHE_PSK_WITH_RC4_128_SHA : - case TLS_RSA_PSK_WITH_RC4_128_SHA : - if (tls_options & _HTTP_TLS_ALLOW_RC4) - enabled[num_enabled ++] = supported[i]; - else - DEBUG_printf(("4_httpTLSStart: Excluding RC4 cipher suite %d", supported[i])); - break; - - /* DH/DHE cipher suites that are problematic with parameters < 1024 bits */ - case TLS_DH_DSS_WITH_AES_128_CBC_SHA : - case TLS_DH_RSA_WITH_AES_128_CBC_SHA : - case TLS_DHE_DSS_WITH_AES_128_CBC_SHA : - case TLS_DHE_RSA_WITH_AES_128_CBC_SHA : - case TLS_DH_DSS_WITH_AES_256_CBC_SHA : - case TLS_DH_RSA_WITH_AES_256_CBC_SHA : - case TLS_DHE_DSS_WITH_AES_256_CBC_SHA : - case TLS_DHE_RSA_WITH_AES_256_CBC_SHA : - case TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA : - case TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA : - case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA : - case TLS_DH_DSS_WITH_AES_128_CBC_SHA256 : - case TLS_DH_RSA_WITH_AES_128_CBC_SHA256 : - case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 : - case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 : - case TLS_DH_DSS_WITH_AES_256_CBC_SHA256 : - case TLS_DH_RSA_WITH_AES_256_CBC_SHA256 : - case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 : - case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 : - case TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA : - case TLS_DHE_PSK_WITH_AES_128_CBC_SHA : - case TLS_DHE_PSK_WITH_AES_256_CBC_SHA : - case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 : - case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 : - if (tls_options & _HTTP_TLS_DENY_CBC) - { - DEBUG_printf(("4_httpTLSStart: Excluding CBC cipher suite %d", supported[i])); - break; - } - -// case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 : -// case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 : - case TLS_DH_RSA_WITH_AES_128_GCM_SHA256 : - case TLS_DH_RSA_WITH_AES_256_GCM_SHA384 : -// case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 : -// case TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 : - case TLS_DH_DSS_WITH_AES_128_GCM_SHA256 : - case TLS_DH_DSS_WITH_AES_256_GCM_SHA384 : - case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 : - case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 : - if (tls_options & _HTTP_TLS_ALLOW_DH) - enabled[num_enabled ++] = supported[i]; - else - DEBUG_printf(("4_httpTLSStart: Excluding DH/DHE cipher suite %d", supported[i])); - break; - - case TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA : - case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : - case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 : - case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 : - case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 : - case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 : - case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 : - case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 : - case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 : - case TLS_RSA_WITH_3DES_EDE_CBC_SHA : - case TLS_RSA_WITH_AES_128_CBC_SHA : - case TLS_RSA_WITH_AES_256_CBC_SHA : - if (tls_options & _HTTP_TLS_DENY_CBC) - { - DEBUG_printf(("4_httpTLSStart: Excluding CBC cipher suite %d", supported[i])); - break; - } - - /* Anything else we'll assume is "secure" */ - default : - enabled[num_enabled ++] = supported[i]; - break; - } - } - - DEBUG_printf(("4_httpTLSStart: %d cipher suites enabled.", (int)num_enabled)); - error = SSLSetEnabledCiphers(http->tls, enabled, num_enabled); - } - } - - if (!error && http->mode == _HTTP_MODE_CLIENT) - { - /* - * Client: set client-side credentials, if any... - */ - - if (cg->client_cert_cb) - { - error = SSLSetSessionOption(http->tls, - kSSLSessionOptionBreakOnCertRequested, true); - DEBUG_printf(("4_httpTLSStart: kSSLSessionOptionBreakOnCertRequested, error=%d", (int)error)); - } - else - { - error = http_cdsa_set_credentials(http); - DEBUG_printf(("4_httpTLSStart: http_cdsa_set_credentials, error=%d", (int)error)); - } - } - else if (!error) - { - /* - * Server: find/create a certificate for TLS... - */ - - if (http->fields[HTTP_FIELD_HOST]) - { - /* - * Use hostname for TLS upgrade... - */ - - strlcpy(hostname, http->fields[HTTP_FIELD_HOST], sizeof(hostname)); - } - else - { - /* - * Resolve hostname from connection address... - */ - - http_addr_t addr; /* Connection address */ - socklen_t addrlen; /* Length of address */ - - addrlen = sizeof(addr); - if (getsockname(http->fd, (struct sockaddr *)&addr, &addrlen)) - { - DEBUG_printf(("4_httpTLSStart: Unable to get socket address: %s", strerror(errno))); - hostname[0] = '\0'; - } - else if (httpAddrLocalhost(&addr)) - hostname[0] = '\0'; - else - { - httpAddrLookup(&addr, hostname, sizeof(hostname)); - DEBUG_printf(("4_httpTLSStart: Resolved socket address to \"%s\".", hostname)); - } - } - - if (isdigit(hostname[0] & 255) || hostname[0] == '[') - hostname[0] = '\0'; /* Don't allow numeric addresses */ - - _cupsMutexLock(&tls_mutex); - - if (hostname[0]) - http->tls_credentials = http_cdsa_copy_server(hostname); - else if (tls_common_name) - http->tls_credentials = http_cdsa_copy_server(tls_common_name); - - if (!http->tls_credentials && tls_auto_create && (hostname[0] || tls_common_name)) - { - DEBUG_printf(("4_httpTLSStart: Auto-create credentials for \"%s\".", hostname[0] ? hostname : tls_common_name)); - - if (!cupsMakeServerCredentials(tls_keypath, hostname[0] ? hostname : tls_common_name, 0, NULL, time(NULL) + 365 * 86400)) - { - DEBUG_puts("4_httpTLSStart: cupsMakeServerCredentials failed."); - http->error = errno = EINVAL; - http->status = HTTP_STATUS_ERROR; - _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Unable to create server credentials."), 1); - _cupsMutexUnlock(&tls_mutex); - - return (-1); - } - - http->tls_credentials = http_cdsa_copy_server(hostname[0] ? hostname : tls_common_name); - } - - _cupsMutexUnlock(&tls_mutex); - - if (!http->tls_credentials) - { - DEBUG_puts("4_httpTLSStart: Unable to find server credentials."); - http->error = errno = EINVAL; - http->status = HTTP_STATUS_ERROR; - _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Unable to find server credentials."), 1); - - return (-1); - } - - error = SSLSetCertificate(http->tls, http->tls_credentials); - - DEBUG_printf(("4_httpTLSStart: SSLSetCertificate, error=%d", (int)error)); - } - - DEBUG_printf(("4_httpTLSStart: tls_credentials=%p", (void *)http->tls_credentials)); - - /* - * Let the server know which hostname/domain we are trying to connect to - * in case it wants to serve up a certificate with a matching common name. - */ - - if (!error && http->mode == _HTTP_MODE_CLIENT) - { - /* - * Client: get the hostname to use for TLS... - */ - - if (httpAddrLocalhost(http->hostaddr)) - { - strlcpy(hostname, "localhost", sizeof(hostname)); - } - else - { - /* - * Otherwise make sure the hostname we have does not end in a trailing dot. - */ - - strlcpy(hostname, http->hostname, sizeof(hostname)); - if ((hostptr = hostname + strlen(hostname) - 1) >= hostname && - *hostptr == '.') - *hostptr = '\0'; - } - - error = SSLSetPeerDomainName(http->tls, hostname, strlen(hostname)); - - DEBUG_printf(("4_httpTLSStart: SSLSetPeerDomainName, error=%d", (int)error)); - } - - if (!error) - { - 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) - { - error = SSLHandshake(http->tls); - - DEBUG_printf(("4_httpTLSStart: SSLHandshake returned %d.", (int)error)); - - switch (error) - { - case noErr : - done = 1; - break; - - case errSSLWouldBlock : - error = noErr; /* Force a retry */ - usleep(1000); /* in 1 millisecond */ - break; - - case errSSLServerAuthCompleted : - error = 0; - if (cg->server_cert_cb) - { - error = httpCopyCredentials(http, &credentials); - if (!error) - { - error = (cg->server_cert_cb)(http, http->tls, credentials, - cg->server_cert_data); - httpFreeCredentials(credentials); - } - - DEBUG_printf(("4_httpTLSStart: Server certificate callback returned %d.", (int)error)); - } - break; - - case errSSLClientCertRequested : - error = 0; - - if (cg->client_cert_cb) - { - names = NULL; - error = SSLCopyDistinguishedNames(http->tls, &dn_array); - if (dn_array) - { - if (!error) { - if ((names = cupsArrayNew(NULL, NULL)) != NULL) - { - for (i = 0, count = CFArrayGetCount(dn_array); i < count; i++) - { - data = (CFDataRef)CFArrayGetValueAtIndex(dn_array, i); - - if ((credential = malloc(sizeof(*credential))) != NULL) - { - credential->datalen = (size_t)CFDataGetLength(data); - if ((credential->data = malloc(credential->datalen))) - { - memcpy((void *)credential->data, CFDataGetBytePtr(data), - credential->datalen); - cupsArrayAdd(names, credential); - } - else - free(credential); - } - } - } - } - CFRelease(dn_array); - } - - if (!error) - { - error = (cg->client_cert_cb)(http, http->tls, names, - cg->client_cert_data); - - DEBUG_printf(("4_httpTLSStart: Client certificate callback returned %d.", (int)error)); - } - - httpFreeCredentials(names); - } - break; - - case errSSLUnknownRootCert : - message = _("Unable to establish a secure connection to host (untrusted certificate)."); - break; - - case errSSLNoRootCert : - message = _("Unable to establish a secure connection to host (self-signed certificate)."); - break; - - case errSSLCertExpired : - message = _("Unable to establish a secure connection to host (expired certificate)."); - break; - - case errSSLCertNotYetValid : - message = _("Unable to establish a secure connection to host (certificate not yet valid)."); - break; - - case errSSLHostNameMismatch : - message = _("Unable to establish a secure connection to host (host name mismatch)."); - break; - - case errSSLXCertChainInvalid : - message = _("Unable to establish a secure connection to host (certificate chain invalid)."); - break; - - case errSSLConnectionRefused : - message = _("Unable to establish a secure connection to host (peer dropped connection before responding)."); - break; - - default : - break; - } - } - - /* - * Restore the previous timeout settings... - */ - - httpSetTimeout(http, old_timeout, old_cb, old_data); - } - - if (error) - { - http->error = error; - http->status = HTTP_STATUS_ERROR; - errno = ECONNREFUSED; - - CFRelease(http->tls); - http->tls = NULL; - - /* - * If an error string wasn't set by the callbacks use a generic one... - */ - - if (!message) - { - if (!cg->lang_default) - cg->lang_default = cupsLangDefault(); - - snprintf(msgbuf, sizeof(msgbuf), _cupsLangString(cg->lang_default, _("Unable to establish a secure connection to host (%d).")), error); - message = msgbuf; - } - - _cupsSetError(IPP_STATUS_ERROR_CUPS_PKI, message, 1); - - return (-1); - } - - return (0); -} - - -/* - * '_httpTLSStop()' - Shut down SSL/TLS on a connection. - */ - -void -_httpTLSStop(http_t *http) /* I - HTTP connection */ -{ - while (SSLClose(http->tls) == errSSLWouldBlock) - usleep(1000); - - CFRelease(http->tls); - http->tls = NULL; - - if (http->tls_credentials) - { - CFRelease(http->tls_credentials); - http->tls_credentials = NULL; - } -} - - -/* - * '_httpTLSWrite()' - Write to a SSL/TLS connection. - */ - -int /* O - Bytes written */ -_httpTLSWrite(http_t *http, /* I - HTTP connection */ - const char *buf, /* I - Buffer holding data */ - int len) /* I - Length of buffer */ -{ - ssize_t result; /* Return value */ - OSStatus error; /* Error info */ - size_t processed; /* Number of bytes processed */ - - - DEBUG_printf(("4_httpTLSWrite(http=%p, buf=%p, len=%d)", (void *)http, (void *)buf, len)); - - error = SSLWrite(http->tls, buf, (size_t)len, &processed); - - switch (error) - { - case 0 : - result = (int)processed; - break; - - case errSSLWouldBlock : - if (processed) - { - result = (int)processed; - } - else - { - result = -1; - errno = EINTR; - } - break; - - case errSSLClosedGraceful : - default : - if (processed) - { - result = (int)processed; - } - else - { - result = -1; - errno = EPIPE; - } - break; - } - - DEBUG_printf(("5_httpTLSWrite: Returning %d.", (int)result)); - - return ((int)result); -} - - -/* - * 'http_cdsa_copy_server()' - Find and copy server credentials from the keychain. - */ - -static CFArrayRef /* O - Array of certificates or NULL */ -http_cdsa_copy_server( - const char *common_name) /* I - Server's hostname */ -{ -#if TARGET_OS_OSX - OSStatus err; /* Error info */ - SecIdentityRef identity = NULL;/* Identity */ - CFArrayRef certificates = NULL; - /* Certificate array */ - SecPolicyRef policy = NULL; /* Policy ref */ - CFStringRef cfcommon_name = NULL; - /* Server name */ - CFMutableDictionaryRef query = NULL; /* Query qualifiers */ - CFArrayRef list = NULL; /* Keychain list */ - SecKeychainRef syschain = NULL;/* System keychain */ - SecKeychainStatus status = 0; /* Keychain status */ - - - DEBUG_printf(("3http_cdsa_copy_server(common_name=\"%s\")", common_name)); - - cfcommon_name = CFStringCreateWithCString(kCFAllocatorDefault, common_name, kCFStringEncodingUTF8); - - policy = SecPolicyCreateSSL(1, cfcommon_name); - - if (!policy) - { - DEBUG_puts("4http_cdsa_copy_server: Unable to create SSL policy."); - goto cleanup; - } - - if (!(query = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks))) - { - DEBUG_puts("4http_cdsa_copy_server: Unable to create query dictionary."); - goto cleanup; - } - - _cupsMutexLock(&tls_mutex); - - err = SecKeychainGetStatus(tls_keychain, &status); - - if (err == noErr && !(status & kSecUnlockStateStatus) && tls_cups_keychain) - SecKeychainUnlock(tls_keychain, _CUPS_CDSA_PASSLEN, _CUPS_CDSA_PASSWORD, TRUE); - - CFDictionaryAddValue(query, kSecClass, kSecClassIdentity); - CFDictionaryAddValue(query, kSecMatchPolicy, policy); - CFDictionaryAddValue(query, kSecReturnRef, kCFBooleanTrue); - CFDictionaryAddValue(query, kSecMatchLimit, kSecMatchLimitOne); - - syschain = http_cdsa_open_system_keychain(); - - if (syschain) - { - const void *values[2] = { syschain, tls_keychain }; - - list = CFArrayCreate(kCFAllocatorDefault, (const void **)values, 2, &kCFTypeArrayCallBacks); - } - else - list = CFArrayCreate(kCFAllocatorDefault, (const void **)&tls_keychain, 1, &kCFTypeArrayCallBacks); - - CFDictionaryAddValue(query, kSecMatchSearchList, list); - CFRelease(list); - - err = SecItemCopyMatching(query, (CFTypeRef *)&identity); - - _cupsMutexUnlock(&tls_mutex); - - if (err != noErr) - { - DEBUG_printf(("4http_cdsa_copy_server: SecItemCopyMatching failed with status %d.", (int)err)); - goto cleanup; - } - - if (CFGetTypeID(identity) != SecIdentityGetTypeID()) - { - DEBUG_puts("4http_cdsa_copy_server: Search returned something that is not an identity."); - goto cleanup; - } - - if ((certificates = CFArrayCreate(NULL, (const void **)&identity, 1, &kCFTypeArrayCallBacks)) == NULL) - { - DEBUG_puts("4http_cdsa_copy_server: Unable to create array of certificates."); - goto cleanup; - } - - cleanup : - - if (syschain) - CFRelease(syschain); - if (identity) - CFRelease(identity); - if (policy) - CFRelease(policy); - if (cfcommon_name) - CFRelease(cfcommon_name); - if (query) - CFRelease(query); - - DEBUG_printf(("4http_cdsa_copy_server: Returning %p.", (void *)certificates)); - - return (certificates); -#else - - (void)common_name; - - if (!tls_selfsigned) - return (NULL); - - return (CFArrayCreate(NULL, (const void **)&tls_selfsigned, 1, &kCFTypeArrayCallBacks)); -#endif /* TARGET_OS_OSX */ -} - - -/* - * 'http_cdsa_create_credential()' - Create a single credential in the internal format. - */ - -static SecCertificateRef /* O - Certificate */ -http_cdsa_create_credential( - http_credential_t *credential) /* I - Credential */ -{ - SecCertificateRef cert; /* Certificate */ - CFDataRef data; /* Data object */ - - - if (!credential) - return (NULL); - - data = CFDataCreate(kCFAllocatorDefault, credential->data, (CFIndex)credential->datalen); - cert = SecCertificateCreateWithData(kCFAllocatorDefault, data); - CFRelease(data); - - return (cert); -} - - -#if TARGET_OS_OSX -/* - * 'http_cdsa_default_path()' - Get the default keychain path. - */ - -static const char * /* O - Keychain path */ -http_cdsa_default_path(char *buffer, /* I - Path buffer */ - size_t bufsize) /* I - Size of buffer */ -{ - _cups_globals_t *cg = _cupsGlobals(); - /* Pointer to library globals */ - - - /* - * Determine the default keychain path. Note that the login and system - * keychains are no longer accessible to user applications starting in macOS - * 10.11.4 (!), so we need to create our own keychain just for CUPS. - */ - - if (cg->home) - snprintf(buffer, bufsize, "%s/.cups/ssl.keychain", cg->home); - else - strlcpy(buffer, "/etc/cups/ssl.keychain", bufsize); - - DEBUG_printf(("1http_cdsa_default_path: Using default path \"%s\".", buffer)); - - return (buffer); -} - - -/* - * 'http_cdsa_open_keychain()' - Open (or create) a keychain. - */ - -static SecKeychainRef /* O - Keychain or NULL */ -http_cdsa_open_keychain( - const char *path, /* I - Path to keychain */ - char *filename, /* I - Keychain filename */ - size_t filesize) /* I - Size of filename buffer */ -{ - SecKeychainRef keychain = NULL;/* Temporary keychain */ - OSStatus err; /* Error code */ - Boolean interaction; /* Interaction allowed? */ - SecKeychainStatus status = 0; /* Keychain status */ - - - /* - * Get the keychain filename... - */ - - if (!path) - { - path = http_cdsa_default_path(filename, filesize); - tls_cups_keychain = 1; - } - else - { - strlcpy(filename, path, filesize); - tls_cups_keychain = 0; - } - - /* - * Save the interaction setting and disable while we open the keychain... - */ - - SecKeychainGetUserInteractionAllowed(&interaction); - SecKeychainSetUserInteractionAllowed(FALSE); - - if (access(path, R_OK) && tls_cups_keychain) - { - /* - * Create a new keychain at the given path... - */ - - err = SecKeychainCreate(path, _CUPS_CDSA_PASSLEN, _CUPS_CDSA_PASSWORD, FALSE, NULL, &keychain); - } - else - { - /* - * Open the existing keychain and unlock as needed... - */ - - err = SecKeychainOpen(path, &keychain); - - if (err == noErr) - err = SecKeychainGetStatus(keychain, &status); - - if (err == noErr && !(status & kSecUnlockStateStatus) && tls_cups_keychain) - err = SecKeychainUnlock(keychain, _CUPS_CDSA_PASSLEN, _CUPS_CDSA_PASSWORD, TRUE); - } - - /* - * Restore interaction setting... - */ - - SecKeychainSetUserInteractionAllowed(interaction); - - /* - * Release the keychain if we had any errors... - */ - - if (err != noErr) - { - /* TODO: Set cups last error string */ - DEBUG_printf(("4http_cdsa_open_keychain: Unable to open keychain (%d), returning NULL.", (int)err)); - - if (keychain) - { - CFRelease(keychain); - keychain = NULL; - } - } - - /* - * Return the keychain or NULL... - */ - - return (keychain); -} - - -/* - * 'http_cdsa_open_system_keychain()' - Open the System keychain. - */ - -static SecKeychainRef -http_cdsa_open_system_keychain(void) -{ - SecKeychainRef keychain = NULL;/* Temporary keychain */ - OSStatus err; /* Error code */ - Boolean interaction; /* Interaction allowed? */ - SecKeychainStatus status = 0; /* Keychain status */ - - - /* - * Save the interaction setting and disable while we open the keychain... - */ - - SecKeychainGetUserInteractionAllowed(&interaction); - SecKeychainSetUserInteractionAllowed(TRUE); - - err = SecKeychainOpen("/Library/Keychains/System.keychain", &keychain); - - if (err == noErr) - err = SecKeychainGetStatus(keychain, &status); - - if (err == noErr && !(status & kSecUnlockStateStatus)) - err = errSecInteractionNotAllowed; - - /* - * Restore interaction setting... - */ - - SecKeychainSetUserInteractionAllowed(interaction); - - /* - * Release the keychain if we had any errors... - */ - - if (err != noErr) - { - /* TODO: Set cups last error string */ - DEBUG_printf(("4http_cdsa_open_system_keychain: Unable to open keychain (%d), returning NULL.", (int)err)); - - if (keychain) - { - CFRelease(keychain); - keychain = NULL; - } - } - - /* - * Return the keychain or NULL... - */ - - return (keychain); -} -#endif /* TARGET_OS_OSX */ - - -/* - * 'http_cdsa_read()' - Read function for the CDSA library. - */ - -static OSStatus /* O - -1 on error, 0 on success */ -http_cdsa_read( - SSLConnectionRef connection, /* I - SSL/TLS connection */ - void *data, /* I - Data buffer */ - size_t *dataLength) /* IO - Number of bytes */ -{ - OSStatus result; /* Return value */ - ssize_t bytes; /* Number of bytes read */ - http_t *http; /* HTTP connection */ - - - http = (http_t *)connection; - - if (!http->blocking || http->timeout_value > 0.0) - { - /* - * Make sure we have data before we read... - */ - - while (!_httpWait(http, http->wait_value, 0)) - { - if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data)) - continue; - - http->error = ETIMEDOUT; - return (-1); - } - } - - do - { - bytes = recv(http->fd, data, *dataLength, 0); - } - while (bytes == -1 && (errno == EINTR || errno == EAGAIN)); - - if ((size_t)bytes == *dataLength) - { - result = 0; - } - else if (bytes > 0) - { - *dataLength = (size_t)bytes; - result = errSSLWouldBlock; - } - else - { - *dataLength = 0; - - if (bytes == 0) - result = errSSLClosedGraceful; - else if (errno == EAGAIN) - result = errSSLWouldBlock; - else - result = errSSLClosedAbort; - } - - return (result); -} - - -/* - * 'http_cdsa_set_credentials()' - Set the TLS credentials. - */ - -static int /* O - Status of connection */ -http_cdsa_set_credentials(http_t *http) /* I - HTTP connection */ -{ - _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ - OSStatus error = 0; /* Error code */ - http_tls_credentials_t credentials = NULL; - /* TLS credentials */ - - - DEBUG_printf(("7http_tls_set_credentials(%p)", (void *)http)); - - /* - * Prefer connection specific credentials... - */ - - if ((credentials = http->tls_credentials) == NULL) - credentials = cg->tls_credentials; - - if (credentials) - { - error = SSLSetCertificate(http->tls, credentials); - DEBUG_printf(("4http_tls_set_credentials: SSLSetCertificate, error=%d", - (int)error)); - } - else - DEBUG_puts("4http_tls_set_credentials: No credentials to set."); - - return (error); -} - - -/* - * 'http_cdsa_write()' - Write function for the CDSA library. - */ - -static OSStatus /* O - -1 on error, 0 on success */ -http_cdsa_write( - SSLConnectionRef connection, /* I - SSL/TLS connection */ - const void *data, /* I - Data buffer */ - size_t *dataLength) /* IO - Number of bytes */ -{ - OSStatus result; /* Return value */ - ssize_t bytes; /* Number of bytes read */ - http_t *http; /* HTTP connection */ - - - http = (http_t *)connection; - - do - { - bytes = write(http->fd, data, *dataLength); - } - while (bytes == -1 && (errno == EINTR || errno == EAGAIN)); - - if ((size_t)bytes == *dataLength) - { - result = 0; - } - else if (bytes >= 0) - { - *dataLength = (size_t)bytes; - result = errSSLWouldBlock; - } - else - { - *dataLength = 0; - - if (errno == EAGAIN) - result = errSSLWouldBlock; - else - result = errSSLClosedAbort; - } - - return (result); -} diff --git a/cups/tls-darwin.h b/cups/tls-darwin.h deleted file mode 100644 index a8f691470e..0000000000 --- a/cups/tls-darwin.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * TLS support header for CUPS on macOS. - * - * Copyright © 2007-2019 by Apple Inc. - * Copyright © 1997-2007 by Easy Software Products, all rights reserved. - * - * Licensed under Apache License v2.0. See the file "LICENSE" for more - * information. - */ - -/**** This file is included from tls-darwin.c ****/ - -extern char **environ; - -#ifndef _SECURITY_VERSION_GREATER_THAN_57610_ -typedef CF_OPTIONS(uint32_t, SecKeyUsage) { - kSecKeyUsageAll = 0x7FFFFFFF -}; -#endif /* !_SECURITY_VERSION_GREATER_THAN_57610_ */ -extern const void * kSecCSRChallengePassword; -extern const void * kSecSubjectAltName; -extern const void * kSecCertificateKeyUsage; -extern const void * kSecCSRBasicConstraintsPathLen; -extern const void * kSecCertificateExtensions; -extern const void * kSecCertificateExtensionsEncoded; -extern const void * kSecOidCommonName; -extern const void * kSecOidCountryName; -extern const void * kSecOidStateProvinceName; -extern const void * kSecOidLocalityName; -extern const void * kSecOidOrganization; -extern const void * kSecOidOrganizationalUnit; -extern bool SecCertificateIsValid(SecCertificateRef certificate, CFAbsoluteTime verifyTime); -extern CFAbsoluteTime SecCertificateNotValidAfter(SecCertificateRef certificate); -extern SecCertificateRef SecGenerateSelfSignedCertificate(CFArrayRef subject, CFDictionaryRef parameters, SecKeyRef publicKey, SecKeyRef privateKey); -extern SecIdentityRef SecIdentityCreate(CFAllocatorRef allocator, SecCertificateRef certificate, SecKeyRef privateKey); diff --git a/cups/tls-sspi.c b/cups/tls-sspi.c deleted file mode 100644 index fee309298c..0000000000 --- a/cups/tls-sspi.c +++ /dev/null @@ -1,2403 +0,0 @@ -/* - * TLS support for CUPS on Windows using the Security Support Provider - * Interface (SSPI). - * - * Copyright © 2020-2023 by OpenPrinting. - * Copyright © 2010-2018 by Apple Inc. - * - * Licensed under Apache License v2.0. See the file "LICENSE" for more - * information. - */ - -/**** This file is included from tls.c ****/ - -/* - * Include necessary headers... - */ - -#include "debug-private.h" -#include - - -/* - * Include necessary libraries... - */ - -#pragma comment(lib, "Crypt32.lib") -#pragma comment(lib, "Secur32.lib") -#pragma comment(lib, "Ws2_32.lib") - - -/* - * Constants... - */ - -#ifndef SECURITY_FLAG_IGNORE_UNKNOWN_CA -# define SECURITY_FLAG_IGNORE_UNKNOWN_CA 0x00000100 /* Untrusted root */ -#endif /* SECURITY_FLAG_IGNORE_UNKNOWN_CA */ - -#ifndef SECURITY_FLAG_IGNORE_CERT_CN_INVALID -# define SECURITY_FLAG_IGNORE_CERT_CN_INVALID 0x00001000 /* Common name does not match */ -#endif /* !SECURITY_FLAG_IGNORE_CERT_CN_INVALID */ - -#ifndef SECURITY_FLAG_IGNORE_CERT_DATE_INVALID -# define SECURITY_FLAG_IGNORE_CERT_DATE_INVALID 0x00002000 /* Expired X509 Cert. */ -#endif /* !SECURITY_FLAG_IGNORE_CERT_DATE_INVALID */ - - -/* - * Local globals... - */ - -static int tls_options = -1,/* Options for TLS connections */ - tls_min_version = _HTTP_TLS_1_0, - tls_max_version = _HTTP_TLS_MAX; - - -/* - * Local functions... - */ - -static _http_sspi_t *http_sspi_alloc(void); -static int http_sspi_client(http_t *http, const char *hostname); -static PCCERT_CONTEXT http_sspi_create_credential(http_credential_t *cred); -static BOOL http_sspi_find_credentials(http_t *http, const LPWSTR containerName, const char *common_name); -static void http_sspi_free(_http_sspi_t *sspi); -static BOOL http_sspi_make_credentials(_http_sspi_t *sspi, const LPWSTR containerName, const char *common_name, _http_mode_t mode, int years); -static int http_sspi_server(http_t *http, const char *hostname); -static void http_sspi_set_error(const char *title); -static const char *http_sspi_strerror(char *buffer, size_t bufsize, DWORD code); -static DWORD http_sspi_verify(PCCERT_CONTEXT cert, const char *common_name, DWORD dwCertFlags); - - -/* - * 'cupsMakeServerCredentials()' - Make a self-signed certificate and private key pair. - */ - -int /* O - 1 on success, 0 on failure */ -cupsMakeServerCredentials( - const char *path, /* I - Keychain path or @code NULL@ for default */ - const char *common_name, /* I - Common name */ - int num_alt_names, /* I - Number of subject alternate names */ - const char **alt_names, /* I - Subject Alternate Names */ - time_t expiration_date) /* I - Expiration date */ -{ - _http_sspi_t *sspi; /* SSPI data */ - int ret; /* Return value */ - - - DEBUG_printf(("cupsMakeServerCredentials(path=\"%s\", common_name=\"%s\", num_alt_names=%d, alt_names=%p, expiration_date=%d)", path, common_name, num_alt_names, alt_names, (int)expiration_date)); - - (void)path; - (void)num_alt_names; - (void)alt_names; - - sspi = http_sspi_alloc(); - ret = http_sspi_make_credentials(sspi, L"ServerContainer", common_name, _HTTP_MODE_SERVER, (int)((expiration_date - time(NULL) + 86399) / 86400 / 365)); - - http_sspi_free(sspi); - - return (ret); -} - - -/* - * 'cupsSetServerCredentials()' - Set the default server credentials. - * - * Note: The server credentials are used by all threads in the running process. - * This function is threadsafe. - */ - -int /* O - 1 on success, 0 on failure */ -cupsSetServerCredentials( - const char *path, /* I - Keychain path or @code NULL@ for default */ - const char *common_name, /* I - Default common name for server */ - int auto_create) /* I - 1 = automatically create self-signed certificates */ -{ - DEBUG_printf(("cupsSetServerCredentials(path=\"%s\", common_name=\"%s\", auto_create=%d)", path, common_name, auto_create)); - - (void)path; - (void)common_name; - (void)auto_create; - - return (0); -} - - -/* - * 'httpCopyCredentials()' - Copy the credentials associated with the peer in - * an encrypted connection. - */ - -int /* O - Status of call (0 = success) */ -httpCopyCredentials( - http_t *http, /* I - Connection to server */ - cups_array_t **credentials) /* O - Array of credentials */ -{ - DEBUG_printf(("httpCopyCredentials(http=%p, credentials=%p)", http, credentials)); - - if (!http || !http->tls || !http->tls->remoteCert || !credentials) - { - if (credentials) - *credentials = NULL; - - return (-1); - } - - *credentials = cupsArrayNew(NULL, NULL); - httpAddCredential(*credentials, http->tls->remoteCert->pbCertEncoded, http->tls->remoteCert->cbCertEncoded); - - return (0); -} - - -/* - * '_httpCreateCredentials()' - Create credentials in the internal format. - */ - -http_tls_credentials_t /* O - Internal credentials */ -_httpCreateCredentials( - cups_array_t *credentials) /* I - Array of credentials */ -{ - return (http_sspi_create_credential((http_credential_t *)cupsArrayFirst(credentials))); -} - - -/* - * 'httpCredentialsAreValidForName()' - Return whether the credentials are valid for the given name. - */ - -int /* O - 1 if valid, 0 otherwise */ -httpCredentialsAreValidForName( - cups_array_t *credentials, /* I - Credentials */ - const char *common_name) /* I - Name to check */ -{ - int valid = 1; /* Valid name? */ - PCCERT_CONTEXT cert = http_sspi_create_credential((http_credential_t *)cupsArrayFirst(credentials)); - /* Certificate */ - char cert_name[1024]; /* Name from certificate */ - - - if (cert) - { - if (CertNameToStrA(X509_ASN_ENCODING, &(cert->pCertInfo->Subject), CERT_SIMPLE_NAME_STR, cert_name, sizeof(cert_name))) - { - /* - * Extract common name at end... - */ - - char *ptr = strrchr(cert_name, ','); - if (ptr && ptr[1]) - _cups_strcpy(cert_name, ptr + 2); - } - else - strlcpy(cert_name, "unknown", sizeof(cert_name)); - - CertFreeCertificateContext(cert); - } - else - strlcpy(cert_name, "unknown", sizeof(cert_name)); - - /* - * Compare the common names... - */ - - if (_cups_strcasecmp(common_name, cert_name)) - { - /* - * Not an exact match for the common name, check for wildcard certs... - */ - - const char *domain = strchr(common_name, '.'); - /* Domain in common name */ - - if (strncmp(cert_name, "*.", 2) || !domain || _cups_strcasecmp(domain, cert_name + 1)) - { - /* - * Not a wildcard match. - */ - - /* TODO: Check subject alternate names */ - valid = 0; - } - } - - return (valid); -} - - -/* - * 'httpCredentialsGetTrust()' - Return the trust of credentials. - */ - -http_trust_t /* O - Level of trust */ -httpCredentialsGetTrust( - cups_array_t *credentials, /* I - Credentials */ - const char *common_name) /* I - Common name for trust lookup */ -{ - http_trust_t trust = HTTP_TRUST_OK; /* Level of trust */ - PCCERT_CONTEXT cert = NULL; /* Certificate to validate */ - DWORD certFlags = 0; /* Cert verification flags */ - _cups_globals_t *cg = _cupsGlobals(); /* Per-thread global data */ - - - if (!common_name) - return (HTTP_TRUST_UNKNOWN); - - cert = http_sspi_create_credential((http_credential_t *)cupsArrayFirst(credentials)); - if (!cert) - return (HTTP_TRUST_UNKNOWN); - - if (cg->any_root < 0) - _cupsSetDefaults(); - - if (cg->any_root) - certFlags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA; - - if (cg->expired_certs) - certFlags |= SECURITY_FLAG_IGNORE_CERT_DATE_INVALID; - - if (!cg->validate_certs) - certFlags |= SECURITY_FLAG_IGNORE_CERT_CN_INVALID; - - if (http_sspi_verify(cert, common_name, certFlags) != SEC_E_OK) - trust = HTTP_TRUST_INVALID; - - CertFreeCertificateContext(cert); - - return (trust); -} - - -/* - * 'httpCredentialsGetExpiration()' - Return the expiration date of the credentials. - */ - -time_t /* O - Expiration date of credentials */ -httpCredentialsGetExpiration( - cups_array_t *credentials) /* I - Credentials */ -{ - time_t expiration_date = 0; /* Expiration data of credentials */ - PCCERT_CONTEXT cert = http_sspi_create_credential((http_credential_t *)cupsArrayFirst(credentials)); - /* Certificate */ - - if (cert) - { - SYSTEMTIME systime; /* System time */ - struct tm tm; /* UNIX date/time */ - - FileTimeToSystemTime(&(cert->pCertInfo->NotAfter), &systime); - - tm.tm_year = systime.wYear - 1900; - tm.tm_mon = systime.wMonth - 1; - tm.tm_mday = systime.wDay; - tm.tm_hour = systime.wHour; - tm.tm_min = systime.wMinute; - tm.tm_sec = systime.wSecond; - - expiration_date = mktime(&tm); - - CertFreeCertificateContext(cert); - } - - return (expiration_date); -} - - -/* - * 'httpCredentialsString()' - Return a string representing the credentials. - */ - -size_t /* O - Total size of credentials string */ -httpCredentialsString( - cups_array_t *credentials, /* I - Credentials */ - char *buffer, /* I - Buffer or @code NULL@ */ - size_t bufsize) /* I - Size of buffer */ -{ - http_credential_t *first = (http_credential_t *)cupsArrayFirst(credentials); - /* First certificate */ - PCCERT_CONTEXT cert; /* Certificate */ - - - DEBUG_printf(("httpCredentialsString(credentials=%p, buffer=%p, bufsize=" CUPS_LLFMT ")", credentials, buffer, CUPS_LLCAST bufsize)); - - if (!buffer) - return (0); - - if (bufsize > 0) - *buffer = '\0'; - - cert = http_sspi_create_credential(first); - - if (cert) - { - char cert_name[256]; /* Common name */ - SYSTEMTIME systime; /* System time */ - struct tm tm; /* UNIX date/time */ - time_t expiration; /* Expiration date of cert */ - unsigned char md5_digest[16]; /* MD5 result */ - - FileTimeToSystemTime(&(cert->pCertInfo->NotAfter), &systime); - - tm.tm_year = systime.wYear - 1900; - tm.tm_mon = systime.wMonth - 1; - tm.tm_mday = systime.wDay; - tm.tm_hour = systime.wHour; - tm.tm_min = systime.wMinute; - tm.tm_sec = systime.wSecond; - - expiration = mktime(&tm); - - if (CertNameToStrA(X509_ASN_ENCODING, &(cert->pCertInfo->Subject), CERT_SIMPLE_NAME_STR, cert_name, sizeof(cert_name))) - { - /* - * Extract common name at end... - */ - - char *ptr = strrchr(cert_name, ','); - if (ptr && ptr[1]) - _cups_strcpy(cert_name, ptr + 2); - } - else - strlcpy(cert_name, "unknown", sizeof(cert_name)); - - 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]); - - CertFreeCertificateContext(cert); - } - - DEBUG_printf(("1httpCredentialsString: Returning \"%s\".", buffer)); - - return (strlen(buffer)); -} - - -/* - * '_httpFreeCredentials()' - Free internal credentials. - */ - -void -_httpFreeCredentials( - http_tls_credentials_t credentials) /* I - Internal credentials */ -{ - if (!credentials) - return; - - CertFreeCertificateContext(credentials); -} - - -/* - * 'httpLoadCredentials()' - Load X.509 credentials from a keychain file. - */ - -int /* O - 0 on success, -1 on error */ -httpLoadCredentials( - const char *path, /* I - Keychain path or @code NULL@ for default */ - cups_array_t **credentials, /* IO - Credentials */ - const char *common_name) /* I - Common name for credentials */ -{ - HCERTSTORE store = NULL; /* Certificate store */ - PCCERT_CONTEXT storedContext = NULL; /* Context created from the store */ - DWORD dwSize = 0; /* 32 bit size */ - PBYTE p = NULL; /* Temporary storage */ - HCRYPTPROV hProv = (HCRYPTPROV)NULL; - /* Handle to a CSP */ - CERT_NAME_BLOB sib; /* Arbitrary array of bytes */ -#ifdef DEBUG - char error[1024]; /* Error message buffer */ -#endif /* DEBUG */ - - - DEBUG_printf(("httpLoadCredentials(path=\"%s\", credentials=%p, common_name=\"%s\")", path, credentials, common_name)); - - (void)path; - - if (credentials) - { - *credentials = NULL; - } - else - { - DEBUG_puts("1httpLoadCredentials: NULL credentials pointer, returning -1."); - return (-1); - } - - if (!common_name) - { - DEBUG_puts("1httpLoadCredentials: Bad common name, returning -1."); - return (-1); - } - - if (!CryptAcquireContextW(&hProv, L"RememberedContainer", MS_DEF_PROV_W, PROV_RSA_FULL, CRYPT_NEWKEYSET /*| CRYPT_MACHINE_KEYSET*/)) - { - if (GetLastError() == NTE_EXISTS) - { - if (!CryptAcquireContextW(&hProv, L"RememberedContainer", MS_DEF_PROV_W, PROV_RSA_FULL, 0 /*CRYPT_MACHINE_KEYSET*/)) - { - DEBUG_printf(("1httpLoadCredentials: CryptAcquireContext failed: %s", http_sspi_strerror(error, sizeof(error), GetLastError()))); - http_sspi_set_error("CryptAquireContext"); - goto cleanup; - } - } - } - - store = CertOpenStore(CERT_STORE_PROV_SYSTEM, X509_ASN_ENCODING|PKCS_7_ASN_ENCODING, hProv, CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_NO_CRYPT_RELEASE_FLAG | CERT_STORE_OPEN_EXISTING_FLAG, L"MY"); - - if (!store) - { - DEBUG_printf(("1httpLoadCredentials: CertOpenSystemStore failed: %s", http_sspi_strerror(error, sizeof(error), GetLastError()))); - http_sspi_set_error("CertOpenSystemStore"); - goto cleanup; - } - - dwSize = 0; - - if (!CertStrToNameA(X509_ASN_ENCODING, common_name, CERT_OID_NAME_STR, NULL, NULL, &dwSize, NULL)) - { - DEBUG_printf(("1httpLoadCredentials: CertStrToName failed: %s", http_sspi_strerror(error, sizeof(error), GetLastError()))); - http_sspi_set_error("CertStrToName"); - goto cleanup; - } - - p = (PBYTE)malloc(dwSize); - - if (!p) - { - DEBUG_printf(("1httpLoadCredentials: malloc failed for %d bytes.", dwSize)); - _cupsSetHTTPError(HTTP_STATUS_ERROR); - goto cleanup; - } - - if (!CertStrToNameA(X509_ASN_ENCODING, common_name, CERT_OID_NAME_STR, NULL, p, &dwSize, NULL)) - { - DEBUG_printf(("1httpLoadCredentials: CertStrToName failed: %s", http_sspi_strerror(error, sizeof(error), GetLastError()))); - http_sspi_set_error("CertStrToName"); - goto cleanup; - } - - sib.cbData = dwSize; - sib.pbData = p; - - storedContext = CertFindCertificateInStore(store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_NAME, &sib, NULL); - - if (!storedContext) - { - DEBUG_printf(("1httpLoadCredentials: Unable to find credentials for \"%s\".", common_name)); - goto cleanup; - } - - *credentials = cupsArrayNew(NULL, NULL); - httpAddCredential(*credentials, storedContext->pbCertEncoded, storedContext->cbCertEncoded); - -cleanup: - - /* - * Cleanup - */ - - if (storedContext) - CertFreeCertificateContext(storedContext); - - if (p) - free(p); - - if (store) - CertCloseStore(store, 0); - - if (hProv) - CryptReleaseContext(hProv, 0); - - DEBUG_printf(("1httpLoadCredentials: Returning %d.", *credentials ? 0 : -1)); - - return (*credentials ? 0 : -1); -} - - -/* - * 'httpSaveCredentials()' - Save X.509 credentials to a keychain file. - */ - -int /* O - -1 on error, 0 on success */ -httpSaveCredentials( - const char *path, /* I - Keychain path or @code NULL@ for default */ - cups_array_t *credentials, /* I - Credentials */ - const char *common_name) /* I - Common name for credentials */ -{ - HCERTSTORE store = NULL; /* Certificate store */ - PCCERT_CONTEXT storedContext = NULL; /* Context created from the store */ - PCCERT_CONTEXT createdContext = NULL; /* Context created by us */ - DWORD dwSize = 0; /* 32 bit size */ - PBYTE p = NULL; /* Temporary storage */ - HCRYPTPROV hProv = (HCRYPTPROV)NULL; - /* Handle to a CSP */ - CRYPT_KEY_PROV_INFO ckp; /* Handle to crypto key */ - int ret = -1; /* Return value */ -#ifdef DEBUG - char error[1024]; /* Error message buffer */ -#endif /* DEBUG */ - - - DEBUG_printf(("httpSaveCredentials(path=\"%s\", credentials=%p, common_name=\"%s\")", path, credentials, common_name)); - - (void)path; - - if (!common_name) - { - DEBUG_puts("1httpSaveCredentials: Bad common name, returning -1."); - return (-1); - } - - createdContext = http_sspi_create_credential((http_credential_t *)cupsArrayFirst(credentials)); - if (!createdContext) - { - DEBUG_puts("1httpSaveCredentials: Bad credentials, returning -1."); - return (-1); - } - - if (!CryptAcquireContextW(&hProv, L"RememberedContainer", MS_DEF_PROV_W, PROV_RSA_FULL, CRYPT_NEWKEYSET /*| CRYPT_MACHINE_KEYSET*/)) - { - if (GetLastError() == NTE_EXISTS) - { - if (!CryptAcquireContextW(&hProv, L"RememberedContainer", MS_DEF_PROV_W, PROV_RSA_FULL, 0 /*CRYPT_MACHINE_KEYSET*/)) - { - DEBUG_printf(("1httpSaveCredentials: CryptAcquireContext failed: %s", http_sspi_strerror(error, sizeof(error), GetLastError()))); - http_sspi_set_error("CryptAquireContext"); - goto cleanup; - } - } - } - - store = CertOpenStore(CERT_STORE_PROV_SYSTEM, X509_ASN_ENCODING|PKCS_7_ASN_ENCODING, hProv, CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_NO_CRYPT_RELEASE_FLAG | CERT_STORE_OPEN_EXISTING_FLAG, L"MY"); - - if (!store) - { - DEBUG_printf(("1httpSaveCredentials: CertOpenSystemStore failed: %s", http_sspi_strerror(error, sizeof(error), GetLastError()))); - http_sspi_set_error("CertOpenSystemStore"); - goto cleanup; - } - - dwSize = 0; - - if (!CertStrToNameA(X509_ASN_ENCODING, common_name, CERT_OID_NAME_STR, NULL, NULL, &dwSize, NULL)) - { - DEBUG_printf(("1httpSaveCredentials: CertStrToName failed: %s", http_sspi_strerror(error, sizeof(error), GetLastError()))); - http_sspi_set_error("CertStrToName"); - goto cleanup; - } - - p = (PBYTE)malloc(dwSize); - - if (!p) - { - DEBUG_printf(("1httpSaveCredentials: malloc failed for %d bytes.", dwSize)); - _cupsSetHTTPError(HTTP_STATUS_ERROR); - goto cleanup; - } - - if (!CertStrToNameA(X509_ASN_ENCODING, common_name, CERT_OID_NAME_STR, NULL, p, &dwSize, NULL)) - { - DEBUG_printf(("1httpSaveCredentials: CertStrToName failed: %s", http_sspi_strerror(error, sizeof(error), GetLastError()))); - http_sspi_set_error("CertToToName"); - goto cleanup; - } - - /* - * Add the created context to the named store, and associate it with the named - * container... - */ - - if (!CertAddCertificateContextToStore(store, createdContext, CERT_STORE_ADD_REPLACE_EXISTING, &storedContext)) - { - DEBUG_printf(("1httpSaveCredentials: CertAddCertificateContextToStore failed: %s", http_sspi_strerror(error, sizeof(error), GetLastError()))); - http_sspi_set_error("CertAddCertificateContextToStore"); - goto cleanup; - } - - ZeroMemory(&ckp, sizeof(ckp)); - ckp.pwszContainerName = L"RememberedContainer"; - ckp.pwszProvName = MS_DEF_PROV_W; - ckp.dwProvType = PROV_RSA_FULL; - ckp.dwFlags = 0 /*CRYPT_MACHINE_KEYSET*/; - ckp.dwKeySpec = AT_KEYEXCHANGE; - - if (!CertSetCertificateContextProperty(storedContext, CERT_KEY_PROV_INFO_PROP_ID, 0, &ckp)) - { - DEBUG_printf(("1httpSaveCredentials: CertSetCertificateContextProperty failed: %s", http_sspi_strerror(error, sizeof(error), GetLastError()))); - http_sspi_set_error("CertSetCertificateContextProperty"); - goto cleanup; - } - - ret = 0; - -cleanup: - - /* - * Cleanup - */ - - if (createdContext) - CertFreeCertificateContext(createdContext); - - if (storedContext) - CertFreeCertificateContext(storedContext); - - if (p) - free(p); - - if (store) - CertCloseStore(store, 0); - - if (hProv) - CryptReleaseContext(hProv, 0); - - DEBUG_printf(("1httpSaveCredentials: Returning %d.", ret)); - return (ret); -} - - -/* - * '_httpTLSInitialize()' - Initialize the TLS stack. - */ - -void -_httpTLSInitialize(void) -{ - /* - * Nothing to do... - */ -} - - -/* - * '_httpTLSPending()' - Return the number of pending TLS-encrypted bytes. - */ - -size_t /* O - Bytes available */ -_httpTLSPending(http_t *http) /* I - HTTP connection */ -{ - if (http->tls) - { - DEBUG_printf(("4_httpTLSPending: Returning %d.", http->tls->readBufferUsed + http->tls->decryptBufferUsed)); - return (http->tls->readBufferUsed + http->tls->decryptBufferUsed); - } - else - { - DEBUG_puts("4_httpTLSPending: Returning 0."); - return (0); - } -} - - -/* - * '_httpTLSRead()' - Read from a SSL/TLS connection. - */ - -int /* O - Bytes read */ -_httpTLSRead(http_t *http, /* I - HTTP connection */ - char *buf, /* I - Buffer to store data */ - int len) /* I - Length of buffer */ -{ - int i; /* Looping var */ - _http_sspi_t *sspi = http->tls; /* SSPI data */ - SecBufferDesc message; /* Array of SecBuffer struct */ - SecBuffer buffers[4] = { 0 }; /* Security package buffer */ - int num = 0; /* Return value */ - PSecBuffer pDataBuffer; /* Data buffer */ - PSecBuffer pExtraBuffer; /* Excess data buffer */ - SECURITY_STATUS scRet; /* SSPI status */ - - - DEBUG_printf(("4_httpTLSRead(http=%p, buf=%p, len=%d)", http, buf, len)); - - /* - * If there are bytes that have already been decrypted and have not yet been - * read, return those... - */ - - if (sspi->readBufferUsed > 0) - { - int bytesToCopy = min(sspi->readBufferUsed, len); - /* Number of bytes to copy */ - - memcpy(buf, sspi->readBuffer, bytesToCopy); - sspi->readBufferUsed -= bytesToCopy; - - if (sspi->readBufferUsed > 0) - memmove(sspi->readBuffer, sspi->readBuffer + bytesToCopy, sspi->readBufferUsed); - - DEBUG_printf(("5_httpTLSRead: Returning %d bytes previously decrypted.", bytesToCopy)); - - return (bytesToCopy); - } - - /* - * Initialize security buffer structs - */ - - message.ulVersion = SECBUFFER_VERSION; - message.cBuffers = 4; - message.pBuffers = buffers; - - do - { - /* - * If there is not enough space in the buffer, then increase its size... - */ - - if (sspi->decryptBufferLength <= sspi->decryptBufferUsed) - { - BYTE *temp; /* New buffer */ - - if (sspi->decryptBufferLength >= 262144) - { - WSASetLastError(E_OUTOFMEMORY); - DEBUG_puts("5_httpTLSRead: Decryption buffer too large (>256k)"); - return (-1); - } - - if ((temp = realloc(sspi->decryptBuffer, sspi->decryptBufferLength + 4096)) == NULL) - { - DEBUG_printf(("5_httpTLSRead: Unable to allocate %d byte decryption buffer.", sspi->decryptBufferLength + 4096)); - WSASetLastError(E_OUTOFMEMORY); - return (-1); - } - - sspi->decryptBufferLength += 4096; - sspi->decryptBuffer = temp; - - DEBUG_printf(("5_httpTLSRead: Resized decryption buffer to %d bytes.", sspi->decryptBufferLength)); - } - - buffers[0].pvBuffer = sspi->decryptBuffer; - buffers[0].cbBuffer = (unsigned long)sspi->decryptBufferUsed; - buffers[0].BufferType = SECBUFFER_DATA; - buffers[1].BufferType = SECBUFFER_EMPTY; - buffers[2].BufferType = SECBUFFER_EMPTY; - buffers[3].BufferType = SECBUFFER_EMPTY; - - DEBUG_printf(("5_httpTLSRead: decryptBufferUsed=%d", sspi->decryptBufferUsed)); - - scRet = DecryptMessage(&sspi->context, &message, 0, NULL); - - if (scRet == SEC_E_INCOMPLETE_MESSAGE) - { - num = recv(http->fd, sspi->decryptBuffer + sspi->decryptBufferUsed, (int)(sspi->decryptBufferLength - sspi->decryptBufferUsed), 0); - if (num < 0) - { - DEBUG_printf(("5_httpTLSRead: recv failed: %d", WSAGetLastError())); - return (-1); - } - else if (num == 0) - { - DEBUG_puts("5_httpTLSRead: Server disconnected."); - return (0); - } - - DEBUG_printf(("5_httpTLSRead: Read %d bytes into decryption buffer.", num)); - - sspi->decryptBufferUsed += num; - } - } - while (scRet == SEC_E_INCOMPLETE_MESSAGE); - - if (scRet == SEC_I_CONTEXT_EXPIRED) - { - http_sspi_set_error("DecryptMessage"); - DEBUG_puts("5_httpTLSRead: Context expired."); - WSASetLastError(WSAECONNRESET); - return (-1); - } - else if (scRet != SEC_E_OK) - { - http_sspi_set_error("DecryptMessage"); - DEBUG_printf(("5_httpTLSRead: DecryptMessage failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), scRet))); - WSASetLastError(WSASYSCALLFAILURE); - return (-1); - } - - /* - * The decryption worked. Now, locate data buffer. - */ - - pDataBuffer = NULL; - pExtraBuffer = NULL; - - for (i = 1; i < 4; i++) - { - if (buffers[i].BufferType == SECBUFFER_DATA) - pDataBuffer = &buffers[i]; - else if (!pExtraBuffer && (buffers[i].BufferType == SECBUFFER_EXTRA)) - pExtraBuffer = &buffers[i]; - } - - /* - * If a data buffer is found, then copy the decrypted bytes to the passed-in - * buffer... - */ - - if (pDataBuffer) - { - int bytesToCopy = min((int)pDataBuffer->cbBuffer, len); - /* Number of bytes to copy into buf */ - int bytesToSave = pDataBuffer->cbBuffer - bytesToCopy; - /* Number of bytes to save in our read buffer */ - - if (bytesToCopy) - memcpy(buf, pDataBuffer->pvBuffer, bytesToCopy); - - /* - * If there are more decrypted bytes than can be copied to the passed in - * buffer, then save them... - */ - - if (bytesToSave) - { - if ((sspi->readBufferLength - sspi->readBufferUsed) < bytesToSave) - { - BYTE *temp; /* New buffer pointer */ - - if ((temp = realloc(sspi->readBuffer, sspi->readBufferUsed + bytesToSave)) == NULL) - { - _cupsSetHTTPError(HTTP_STATUS_ERROR); - DEBUG_printf(("5_httpTLSRead: Unable to allocate %d bytes.", sspi->readBufferUsed + bytesToSave)); - WSASetLastError(E_OUTOFMEMORY); - return (-1); - } - - sspi->readBufferLength = sspi->readBufferUsed + bytesToSave; - sspi->readBuffer = temp; - } - - memcpy(((BYTE *)sspi->readBuffer) + sspi->readBufferUsed, ((BYTE *)pDataBuffer->pvBuffer) + bytesToCopy, bytesToSave); - - sspi->readBufferUsed += bytesToSave; - } - - num = bytesToCopy; - } - else - { - DEBUG_puts("5_httpTLSRead: Unable to find data buffer."); - _cupsSetError(IPP_STATUS_ERROR_CUPS_PKI, "Unable to find data buffer.", 0); - WSASetLastError(WSASYSCALLFAILURE); - return (-1); - } - - /* - * If the decryption process left extra bytes, then save those back in - * decryptBuffer. They will be processed the next time through the loop. - */ - - if (pExtraBuffer) - { - memmove(sspi->decryptBuffer, pExtraBuffer->pvBuffer, pExtraBuffer->cbBuffer); - sspi->decryptBufferUsed = pExtraBuffer->cbBuffer; - } - else - { - sspi->decryptBufferUsed = 0; - } - - return (num); -} - - -/* - * '_httpTLSSetOptions()' - Set TLS protocol and cipher suite options. - */ - -void -_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_min_version = min_version; - tls_max_version = max_version; - } -} - - -/* - * '_httpTLSStart()' - Set up SSL/TLS support on a connection. - */ - -int /* O - 0 on success, -1 on failure */ -_httpTLSStart(http_t *http) /* I - HTTP connection */ -{ - char hostname[256], /* Hostname */ - *hostptr; /* Pointer into hostname */ - - - DEBUG_printf(("3_httpTLSStart(http=%p)", http)); - - if (tls_options < 0) - { - DEBUG_puts("4_httpTLSStart: Setting defaults."); - _cupsSetDefaults(); - DEBUG_printf(("4_httpTLSStart: tls_options=%x", tls_options)); - } - - if ((http->tls = http_sspi_alloc()) == NULL) - return (-1); - - if (http->mode == _HTTP_MODE_CLIENT) - { - /* - * Client: determine hostname... - */ - - if (httpAddrLocalhost(http->hostaddr)) - { - strlcpy(hostname, "localhost", sizeof(hostname)); - } - else - { - /* - * Otherwise make sure the hostname we have does not end in a trailing dot. - */ - - strlcpy(hostname, http->hostname, sizeof(hostname)); - if ((hostptr = hostname + strlen(hostname) - 1) >= hostname && - *hostptr == '.') - *hostptr = '\0'; - } - - return (http_sspi_client(http, hostname)); - } - else - { - /* - * Server: determine hostname to use... - */ - - if (http->fields[HTTP_FIELD_HOST]) - { - /* - * Use hostname for TLS upgrade... - */ - - strlcpy(hostname, http->fields[HTTP_FIELD_HOST], sizeof(hostname)); - } - else - { - /* - * Resolve hostname from connection address... - */ - - http_addr_t addr; /* Connection address */ - socklen_t addrlen; /* Length of address */ - - addrlen = sizeof(addr); - if (getsockname(http->fd, (struct sockaddr *)&addr, &addrlen)) - { - DEBUG_printf(("4_httpTLSStart: Unable to get socket address: %s", strerror(errno))); - hostname[0] = '\0'; - } - else if (httpAddrLocalhost(&addr)) - hostname[0] = '\0'; - else - { - httpAddrLookup(&addr, hostname, sizeof(hostname)); - DEBUG_printf(("4_httpTLSStart: Resolved socket address to \"%s\".", hostname)); - } - } - -// fprintf(stderr, "_httpTLSStart: Using hostname '%s'.\n", hostname); - - return (http_sspi_server(http, hostname)); - } -} - - -/* - * '_httpTLSStop()' - Shut down SSL/TLS on a connection. - */ - -void -_httpTLSStop(http_t *http) /* I - HTTP connection */ -{ - _http_sspi_t *sspi = http->tls; /* SSPI data */ - - - if (sspi->contextInitialized && http->fd >= 0) - { - SecBufferDesc message; /* Array of SecBuffer struct */ - SecBuffer buffers[1] = { 0 }; - /* Security package buffer */ - DWORD dwType; /* Type */ - DWORD status; /* Status */ - - /* - * Notify schannel that we are about to close the connection. - */ - - dwType = SCHANNEL_SHUTDOWN; - - buffers[0].pvBuffer = &dwType; - buffers[0].BufferType = SECBUFFER_TOKEN; - buffers[0].cbBuffer = sizeof(dwType); - - message.cBuffers = 1; - message.pBuffers = buffers; - message.ulVersion = SECBUFFER_VERSION; - - status = ApplyControlToken(&sspi->context, &message); - - if (SUCCEEDED(status)) - { - PBYTE pbMessage; /* Message buffer */ - DWORD cbMessage; /* Message buffer count */ - DWORD cbData; /* Data count */ - DWORD dwSSPIFlags; /* SSL attributes we requested */ - DWORD dwSSPIOutFlags; /* SSL attributes we received */ - TimeStamp tsExpiry; /* Time stamp */ - - dwSSPIFlags = ASC_REQ_SEQUENCE_DETECT | - ASC_REQ_REPLAY_DETECT | - ASC_REQ_CONFIDENTIALITY | - ASC_REQ_EXTENDED_ERROR | - ASC_REQ_ALLOCATE_MEMORY | - ASC_REQ_STREAM; - - buffers[0].pvBuffer = NULL; - buffers[0].BufferType = SECBUFFER_TOKEN; - buffers[0].cbBuffer = 0; - - message.cBuffers = 1; - message.pBuffers = buffers; - message.ulVersion = SECBUFFER_VERSION; - - status = AcceptSecurityContext(&sspi->creds, &sspi->context, NULL, - dwSSPIFlags, SECURITY_NATIVE_DREP, NULL, - &message, &dwSSPIOutFlags, &tsExpiry); - - if (SUCCEEDED(status)) - { - pbMessage = buffers[0].pvBuffer; - cbMessage = buffers[0].cbBuffer; - - /* - * Send the close notify message to the client. - */ - - if (pbMessage && cbMessage) - { - cbData = send(http->fd, pbMessage, cbMessage, 0); - if ((cbData == SOCKET_ERROR) || (cbData == 0)) - { - status = WSAGetLastError(); - DEBUG_printf(("4_httpTLSStop: sending close notify failed: %d", status)); - } - else - { - FreeContextBuffer(pbMessage); - } - } - } - else - { - http_sspi_set_error("AcceptSecurityContext"); - DEBUG_printf(("4_httpTLSStop: AcceptSecurityContext failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), status))); - } - } - else - { - http_sspi_set_error("ApplyControlToken"); - DEBUG_printf(("4_httpTLSStop: ApplyControlToken failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), status))); - } - } - - http_sspi_free(sspi); - - http->tls = NULL; -} - - -/* - * '_httpTLSWrite()' - Write to a SSL/TLS connection. - */ - -int /* O - Bytes written */ -_httpTLSWrite(http_t *http, /* I - HTTP connection */ - const char *buf, /* I - Buffer holding data */ - int len) /* I - Length of buffer */ -{ - _http_sspi_t *sspi = http->tls; /* SSPI data */ - SecBufferDesc message; /* Array of SecBuffer struct */ - SecBuffer buffers[4] = { 0 }; /* Security package buffer */ - int bufferLen; /* Buffer length */ - int bytesLeft; /* Bytes left to write */ - const char *bufptr; /* Pointer into buffer */ - int num = 0; /* Return value */ - - - bufferLen = sspi->streamSizes.cbMaximumMessage + sspi->streamSizes.cbHeader + sspi->streamSizes.cbTrailer; - - if (bufferLen > sspi->writeBufferLength) - { - BYTE *temp; /* New buffer pointer */ - - if ((temp = (BYTE *)realloc(sspi->writeBuffer, bufferLen)) == NULL) - { - _cupsSetHTTPError(HTTP_STATUS_ERROR); - DEBUG_printf(("5_httpTLSWrite: Unable to allocate buffer of %d bytes.", bufferLen)); - WSASetLastError(E_OUTOFMEMORY); - return (-1); - } - - sspi->writeBuffer = temp; - sspi->writeBufferLength = bufferLen; - } - - bytesLeft = len; - bufptr = buf; - - while (bytesLeft) - { - int chunk = min((int)sspi->streamSizes.cbMaximumMessage, bytesLeft); - /* Size of data to write */ - SECURITY_STATUS scRet; /* SSPI status */ - - /* - * Copy user data into the buffer, starting just past the header... - */ - - memcpy(sspi->writeBuffer + sspi->streamSizes.cbHeader, bufptr, chunk); - - /* - * Setup the SSPI buffers - */ - - message.ulVersion = SECBUFFER_VERSION; - message.cBuffers = 4; - message.pBuffers = buffers; - - buffers[0].pvBuffer = sspi->writeBuffer; - buffers[0].cbBuffer = sspi->streamSizes.cbHeader; - buffers[0].BufferType = SECBUFFER_STREAM_HEADER; - buffers[1].pvBuffer = sspi->writeBuffer + sspi->streamSizes.cbHeader; - buffers[1].cbBuffer = (unsigned long) chunk; - buffers[1].BufferType = SECBUFFER_DATA; - buffers[2].pvBuffer = sspi->writeBuffer + sspi->streamSizes.cbHeader + chunk; - buffers[2].cbBuffer = sspi->streamSizes.cbTrailer; - buffers[2].BufferType = SECBUFFER_STREAM_TRAILER; - buffers[3].BufferType = SECBUFFER_EMPTY; - - /* - * Encrypt the data - */ - - scRet = EncryptMessage(&sspi->context, 0, &message, 0); - - if (FAILED(scRet)) - { - http_sspi_set_error("EncryptMessage"); - DEBUG_printf(("5_httpTLSWrite: EncryptMessage failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), scRet))); - WSASetLastError(WSASYSCALLFAILURE); - return (-1); - } - - /* - * Send the data. Remember the size of the total data to send is the size - * of the header, the size of the data the caller passed in and the size - * of the trailer... - */ - - num = send(http->fd, sspi->writeBuffer, buffers[0].cbBuffer + buffers[1].cbBuffer + buffers[2].cbBuffer, 0); - - if (num <= 0) - { - DEBUG_printf(("5_httpTLSWrite: send failed: %ld", WSAGetLastError())); - return (num); - } - - bytesLeft -= chunk; - bufptr += chunk; - } - - return (len); -} - - -/* - * 'http_sspi_alloc()' - Allocate SSPI object. - */ - -static _http_sspi_t * /* O - New SSPI/SSL object */ -http_sspi_alloc(void) -{ - return ((_http_sspi_t *)calloc(1, sizeof(_http_sspi_t))); -} - - -/* - * 'http_sspi_client()' - Negotiate a TLS connection as a client. - */ - -static int /* O - 0 on success, -1 on failure */ -http_sspi_client(http_t *http, /* I - Client connection */ - const char *hostname) /* I - Server hostname */ -{ - _http_sspi_t *sspi = http->tls; /* SSPI data */ - DWORD dwSSPIFlags; /* SSL connection attributes we want */ - DWORD dwSSPIOutFlags; /* SSL connection attributes we got */ - TimeStamp tsExpiry; /* Time stamp */ - SECURITY_STATUS scRet; /* Status */ - int cbData; /* Data count */ - SecBufferDesc inBuffer; /* Array of SecBuffer structs */ - SecBuffer inBuffers[2]; /* Security package buffer */ - SecBufferDesc outBuffer; /* Array of SecBuffer structs */ - SecBuffer outBuffers[1]; /* Security package buffer */ - int ret = 0; /* Return value */ - - - DEBUG_printf(("4http_sspi_client(http=%p, hostname=\"%s\")", http, hostname)); - - dwSSPIFlags = ISC_REQ_SEQUENCE_DETECT | - ISC_REQ_REPLAY_DETECT | - ISC_REQ_CONFIDENTIALITY | - ISC_RET_EXTENDED_ERROR | - ISC_REQ_ALLOCATE_MEMORY | - ISC_REQ_STREAM; - - /* - * Lookup the client certificate... - */ - - if (!http_sspi_find_credentials(http, L"ClientContainer", NULL)) - { - DEBUG_puts("5http_sspi_client: Unable to get client credentials."); - return (-1); - } - - /* - * Initiate a ClientHello message and generate a token. - */ - - outBuffers[0].pvBuffer = NULL; - outBuffers[0].BufferType = SECBUFFER_TOKEN; - outBuffers[0].cbBuffer = 0; - - outBuffer.cBuffers = 1; - outBuffer.pBuffers = outBuffers; - outBuffer.ulVersion = SECBUFFER_VERSION; - - scRet = InitializeSecurityContext(&sspi->creds, NULL, TEXT(""), dwSSPIFlags, 0, SECURITY_NATIVE_DREP, NULL, 0, &sspi->context, &outBuffer, &dwSSPIOutFlags, &tsExpiry); - - if (scRet != SEC_I_CONTINUE_NEEDED) - { - http_sspi_set_error("InitializeSecurityContext"); - DEBUG_printf(("5http_sspi_client: InitializeSecurityContext(1) failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), scRet))); - return (-1); - } - - /* - * Send response to server if there is one. - */ - - if (outBuffers[0].cbBuffer && outBuffers[0].pvBuffer) - { - if ((cbData = send(http->fd, outBuffers[0].pvBuffer, outBuffers[0].cbBuffer, 0)) <= 0) - { - DEBUG_printf(("5http_sspi_client: send failed: %d", WSAGetLastError())); - FreeContextBuffer(outBuffers[0].pvBuffer); - DeleteSecurityContext(&sspi->context); - return (-1); - } - - DEBUG_printf(("5http_sspi_client: %d bytes of handshake data sent.", cbData)); - - FreeContextBuffer(outBuffers[0].pvBuffer); - outBuffers[0].pvBuffer = NULL; - } - - dwSSPIFlags = ISC_REQ_MANUAL_CRED_VALIDATION | - ISC_REQ_SEQUENCE_DETECT | - ISC_REQ_REPLAY_DETECT | - ISC_REQ_CONFIDENTIALITY | - ISC_RET_EXTENDED_ERROR | - ISC_REQ_ALLOCATE_MEMORY | - ISC_REQ_STREAM; - - sspi->decryptBufferUsed = 0; - - /* - * Loop until the handshake is finished or an error occurs. - */ - - scRet = SEC_I_CONTINUE_NEEDED; - - while(scRet == SEC_I_CONTINUE_NEEDED || - scRet == SEC_E_INCOMPLETE_MESSAGE || - scRet == SEC_I_INCOMPLETE_CREDENTIALS) - { - if (sspi->decryptBufferUsed == 0 || scRet == SEC_E_INCOMPLETE_MESSAGE) - { - if (sspi->decryptBufferLength <= sspi->decryptBufferUsed) - { - BYTE *temp; /* New buffer */ - - if (sspi->decryptBufferLength >= 262144) - { - WSASetLastError(E_OUTOFMEMORY); - DEBUG_puts("5http_sspi_client: Decryption buffer too large (>256k)"); - return (-1); - } - - if ((temp = realloc(sspi->decryptBuffer, sspi->decryptBufferLength + 4096)) == NULL) - { - _cupsSetHTTPError(HTTP_STATUS_ERROR); - DEBUG_printf(("5http_sspi_client: Unable to allocate %d byte buffer.", sspi->decryptBufferLength + 4096)); - WSASetLastError(E_OUTOFMEMORY); - return (-1); - } - - sspi->decryptBufferLength += 4096; - sspi->decryptBuffer = temp; - } - - cbData = recv(http->fd, sspi->decryptBuffer + sspi->decryptBufferUsed, (int)(sspi->decryptBufferLength - sspi->decryptBufferUsed), 0); - - if (cbData < 0) - { - DEBUG_printf(("5http_sspi_client: recv failed: %d", WSAGetLastError())); - return (-1); - } - else if (cbData == 0) - { - DEBUG_printf(("5http_sspi_client: Server unexpectedly disconnected.")); - return (-1); - } - - DEBUG_printf(("5http_sspi_client: %d bytes of handshake data received", cbData)); - - sspi->decryptBufferUsed += cbData; - } - - /* - * Set up the input buffers. Buffer 0 is used to pass in data received from - * the server. Schannel will consume some or all of this. Leftover data - * (if any) will be placed in buffer 1 and given a buffer type of - * SECBUFFER_EXTRA. - */ - - inBuffers[0].pvBuffer = sspi->decryptBuffer; - inBuffers[0].cbBuffer = (unsigned long)sspi->decryptBufferUsed; - inBuffers[0].BufferType = SECBUFFER_TOKEN; - - inBuffers[1].pvBuffer = NULL; - inBuffers[1].cbBuffer = 0; - inBuffers[1].BufferType = SECBUFFER_EMPTY; - - inBuffer.cBuffers = 2; - inBuffer.pBuffers = inBuffers; - inBuffer.ulVersion = SECBUFFER_VERSION; - - /* - * Set up the output buffers. These are initialized to NULL so as to make it - * less likely we'll attempt to free random garbage later. - */ - - outBuffers[0].pvBuffer = NULL; - outBuffers[0].BufferType = SECBUFFER_TOKEN; - outBuffers[0].cbBuffer = 0; - - outBuffer.cBuffers = 1; - outBuffer.pBuffers = outBuffers; - outBuffer.ulVersion = SECBUFFER_VERSION; - - /* - * Call InitializeSecurityContext. - */ - - scRet = InitializeSecurityContext(&sspi->creds, &sspi->context, NULL, dwSSPIFlags, 0, SECURITY_NATIVE_DREP, &inBuffer, 0, NULL, &outBuffer, &dwSSPIOutFlags, &tsExpiry); - - /* - * If InitializeSecurityContext was successful (or if the error was one of - * the special extended ones), send the contents of the output buffer to the - * server. - */ - - if (scRet == SEC_E_OK || - scRet == SEC_I_CONTINUE_NEEDED || - FAILED(scRet) && (dwSSPIOutFlags & ISC_RET_EXTENDED_ERROR)) - { - if (outBuffers[0].cbBuffer && outBuffers[0].pvBuffer) - { - cbData = send(http->fd, outBuffers[0].pvBuffer, outBuffers[0].cbBuffer, 0); - - if (cbData <= 0) - { - DEBUG_printf(("5http_sspi_client: send failed: %d", WSAGetLastError())); - FreeContextBuffer(outBuffers[0].pvBuffer); - DeleteSecurityContext(&sspi->context); - return (-1); - } - - DEBUG_printf(("5http_sspi_client: %d bytes of handshake data sent.", cbData)); - - /* - * Free output buffer. - */ - - FreeContextBuffer(outBuffers[0].pvBuffer); - outBuffers[0].pvBuffer = NULL; - } - } - - /* - * If InitializeSecurityContext returned SEC_E_INCOMPLETE_MESSAGE, then we - * need to read more data from the server and try again. - */ - - if (scRet == SEC_E_INCOMPLETE_MESSAGE) - continue; - - /* - * If InitializeSecurityContext returned SEC_E_OK, then the handshake - * completed successfully. - */ - - if (scRet == SEC_E_OK) - { - /* - * If the "extra" buffer contains data, this is encrypted application - * protocol layer stuff. It needs to be saved. The application layer will - * later decrypt it with DecryptMessage. - */ - - DEBUG_puts("5http_sspi_client: Handshake was successful."); - - if (inBuffers[1].BufferType == SECBUFFER_EXTRA) - { - memmove(sspi->decryptBuffer, sspi->decryptBuffer + sspi->decryptBufferUsed - inBuffers[1].cbBuffer, inBuffers[1].cbBuffer); - - sspi->decryptBufferUsed = inBuffers[1].cbBuffer; - - DEBUG_printf(("5http_sspi_client: %d bytes of app data was bundled with handshake data", sspi->decryptBufferUsed)); - } - else - sspi->decryptBufferUsed = 0; - - /* - * Bail out to quit - */ - - break; - } - - /* - * Check for fatal error. - */ - - if (FAILED(scRet)) - { - http_sspi_set_error("InitializeSecurityContext"); - DEBUG_printf(("5http_sspi_client: InitializeSecurityContext(2) failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), scRet))); - ret = -1; - break; - } - - /* - * If InitializeSecurityContext returned SEC_I_INCOMPLETE_CREDENTIALS, - * then the server just requested client authentication. - */ - - if (scRet == SEC_I_INCOMPLETE_CREDENTIALS) - { - /* - * Unimplemented - */ - - _cupsSetError(IPP_STATUS_ERROR_CUPS_PKI, "Need client credentials.", 0); - DEBUG_printf(("5http_sspi_client: server requested client credentials.")); - ret = -1; - break; - } - - /* - * Copy any leftover data from the "extra" buffer, and go around again. - */ - - if (inBuffers[1].BufferType == SECBUFFER_EXTRA) - { - memmove(sspi->decryptBuffer, sspi->decryptBuffer + sspi->decryptBufferUsed - inBuffers[1].cbBuffer, inBuffers[1].cbBuffer); - - sspi->decryptBufferUsed = inBuffers[1].cbBuffer; - } - else - { - sspi->decryptBufferUsed = 0; - } - } - - if (!ret) - { - /* - * Success! Get the server cert - */ - - sspi->contextInitialized = TRUE; - - scRet = QueryContextAttributes(&sspi->context, SECPKG_ATTR_REMOTE_CERT_CONTEXT, (VOID *)&(sspi->remoteCert)); - - if (scRet != SEC_E_OK) - { - http_sspi_set_error("QueryContextAttributes"); - DEBUG_printf(("5http_sspi_client: QueryContextAttributes failed(SECPKG_ATTR_REMOTE_CERT_CONTEXT): %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), scRet))); - return (-1); - } - - /* - * Find out how big the header/trailer will be: - */ - - scRet = QueryContextAttributes(&sspi->context, SECPKG_ATTR_STREAM_SIZES, &sspi->streamSizes); - - if (scRet != SEC_E_OK) - { - http_sspi_set_error("QueryContextAttributes"); - DEBUG_printf(("5http_sspi_client: QueryContextAttributes failed(SECPKG_ATTR_STREAM_SIZES): %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), scRet))); - ret = -1; - } - } - - return (ret); -} - - -/* - * 'http_sspi_create_credential()' - Create an SSPI certificate context. - */ - -static PCCERT_CONTEXT /* O - Certificate context */ -http_sspi_create_credential( - http_credential_t *cred) /* I - Credential */ -{ - if (cred) - return (CertCreateCertificateContext(X509_ASN_ENCODING, cred->data, (DWORD)cred->datalen)); - else - return (NULL); -} - - -/* - * 'http_sspi_find_credentials()' - Retrieve a TLS certificate from the system store. - */ - -static BOOL /* O - 1 on success, 0 on failure */ -http_sspi_find_credentials( - http_t *http, /* I - HTTP connection */ - const LPWSTR container, /* I - Cert container name */ - const char *common_name) /* I - Common name of certificate */ -{ - _http_sspi_t *sspi = http->tls; /* SSPI data */ - HCERTSTORE store = NULL; /* Certificate store */ - PCCERT_CONTEXT storedContext = NULL; /* Context created from the store */ - DWORD dwSize = 0; /* 32 bit size */ - PBYTE p = NULL; /* Temporary storage */ - HCRYPTPROV hProv = (HCRYPTPROV)NULL; - /* Handle to a CSP */ - CERT_NAME_BLOB sib; /* Arbitrary array of bytes */ - SCHANNEL_CRED SchannelCred; /* Schannel credential data */ - TimeStamp tsExpiry; /* Time stamp */ - SECURITY_STATUS Status; /* Status */ - BOOL ok = TRUE; /* Return value */ - - - if (!CryptAcquireContextW(&hProv, (LPWSTR)container, MS_DEF_PROV_W, PROV_RSA_FULL, CRYPT_NEWKEYSET /*| CRYPT_MACHINE_KEYSET*/)) - { - if (GetLastError() == NTE_EXISTS) - { - if (!CryptAcquireContextW(&hProv, (LPWSTR)container, MS_DEF_PROV_W, PROV_RSA_FULL, 0 /*CRYPT_MACHINE_KEYSET*/)) - { - http_sspi_set_error("CryptAquireContext"); - DEBUG_printf(("5http_sspi_find_credentials: CryptAcquireContext failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), GetLastError()))); - ok = FALSE; - goto cleanup; - } - } - } - - store = CertOpenStore(CERT_STORE_PROV_SYSTEM, X509_ASN_ENCODING|PKCS_7_ASN_ENCODING, hProv, CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_NO_CRYPT_RELEASE_FLAG | CERT_STORE_OPEN_EXISTING_FLAG, L"MY"); - - if (!store) - { - http_sspi_set_error("CertOpenSystemStore"); - DEBUG_printf(("5http_sspi_find_credentials: CertOpenSystemStore failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), GetLastError()))); - ok = FALSE; - goto cleanup; - } - - if (common_name) - { - dwSize = 0; - - if (!CertStrToNameA(X509_ASN_ENCODING, common_name, CERT_OID_NAME_STR, NULL, NULL, &dwSize, NULL)) - { - http_sspi_set_error("CertStrToName"); - DEBUG_printf(("5http_sspi_find_credentials: CertStrToName failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), GetLastError()))); - ok = FALSE; - goto cleanup; - } - - p = (PBYTE)malloc(dwSize); - - if (!p) - { - _cupsSetHTTPError(HTTP_STATUS_ERROR); - DEBUG_printf(("5http_sspi_find_credentials: malloc failed for %d bytes.", dwSize)); - ok = FALSE; - goto cleanup; - } - - if (!CertStrToNameA(X509_ASN_ENCODING, common_name, CERT_OID_NAME_STR, NULL, p, &dwSize, NULL)) - { - http_sspi_set_error("CertStrToName"); - DEBUG_printf(("5http_sspi_find_credentials: CertStrToName failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), GetLastError()))); - ok = FALSE; - goto cleanup; - } - - sib.cbData = dwSize; - sib.pbData = p; - - storedContext = CertFindCertificateInStore(store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_NAME, &sib, NULL); - - if (!storedContext) - { - http_sspi_set_error("CertFindCertificateInStore"); - DEBUG_printf(("5http_sspi_find_credentials: Unable to find credentials for \"%s\".", common_name)); - ok = FALSE; - goto cleanup; - } - } - - ZeroMemory(&SchannelCred, sizeof(SchannelCred)); - - SchannelCred.dwVersion = SCHANNEL_CRED_VERSION; - - if (common_name) - { - SchannelCred.cCreds = 1; - SchannelCred.paCred = &storedContext; - } - - /* - * Set supported protocols (can also be overridden in the registry...) - */ - -#ifdef SP_PROT_TLS1_2_SERVER - if (http->mode == _HTTP_MODE_SERVER) - { - if (tls_min_version > _HTTP_TLS_1_1) - SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_2_SERVER; - else if (tls_min_version > _HTTP_TLS_1_0) - SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_2_SERVER | SP_PROT_TLS1_1_SERVER; - else 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 - 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_CLIENT; - else if (tls_min_version > _HTTP_TLS_1_0) - SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_2_CLIENT | SP_PROT_TLS1_1_CLIENT; - else 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 - SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_2_CLIENT | SP_PROT_TLS1_1_CLIENT | SP_PROT_TLS1_0_CLIENT; - } - -#else - if (http->mode == _HTTP_MODE_SERVER) - { - 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_min_version == _HTTP_TLS_SSL3) - SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_CLIENT | SP_PROT_SSL3_CLIENT; - else - SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_CLIENT; - } -#endif /* SP_PROT_TLS1_2_SERVER */ - - /* TODO: Support _HTTP_TLS_ALLOW_RC4, _HTTP_TLS_ALLOW_DH, and _HTTP_TLS_DENY_CBC options; right now we'll rely on Windows registry to enable/disable RC4/DH/CBC... */ - - /* - * Create an SSPI credential. - */ - - Status = AcquireCredentialsHandle(NULL, UNISP_NAME, http->mode == _HTTP_MODE_SERVER ? SECPKG_CRED_INBOUND : SECPKG_CRED_OUTBOUND, NULL, &SchannelCred, NULL, NULL, &sspi->creds, &tsExpiry); - if (Status != SEC_E_OK) - { - http_sspi_set_error("AcquireCredentialsHandle"); - DEBUG_printf(("5http_sspi_find_credentials: AcquireCredentialsHandle failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), Status))); - ok = FALSE; - goto cleanup; - } - -cleanup: - - /* - * Cleanup - */ - - if (storedContext) - CertFreeCertificateContext(storedContext); - - if (p) - free(p); - - if (store) - CertCloseStore(store, 0); - - if (hProv) - CryptReleaseContext(hProv, 0); - - return (ok); -} - - -/* - * 'http_sspi_free()' - Close a connection and free resources. - */ - -static void -http_sspi_free(_http_sspi_t *sspi) /* I - SSPI data */ -{ - if (!sspi) - return; - - if (sspi->contextInitialized) - DeleteSecurityContext(&sspi->context); - - if (sspi->decryptBuffer) - free(sspi->decryptBuffer); - - if (sspi->readBuffer) - free(sspi->readBuffer); - - if (sspi->writeBuffer) - free(sspi->writeBuffer); - - if (sspi->localCert) - CertFreeCertificateContext(sspi->localCert); - - if (sspi->remoteCert) - CertFreeCertificateContext(sspi->remoteCert); - - free(sspi); -} - - -/* - * 'http_sspi_make_credentials()' - Create a TLS certificate in the system store. - */ - -static BOOL /* O - 1 on success, 0 on failure */ -http_sspi_make_credentials( - _http_sspi_t *sspi, /* I - SSPI data */ - const LPWSTR container, /* I - Cert container name */ - const char *common_name, /* I - Common name of certificate */ - _http_mode_t mode, /* I - Client or server? */ - int years) /* I - Years until expiration */ -{ - HCERTSTORE store = NULL; /* Certificate store */ - PCCERT_CONTEXT storedContext = NULL; /* Context created from the store */ - PCCERT_CONTEXT createdContext = NULL; /* Context created by us */ - DWORD dwSize = 0; /* 32 bit size */ - PBYTE p = NULL; /* Temporary storage */ - HCRYPTPROV hProv = (HCRYPTPROV)NULL; - /* Handle to a CSP */ - CERT_NAME_BLOB sib; /* Arbitrary array of bytes */ - SCHANNEL_CRED SchannelCred; /* Schannel credential data */ - TimeStamp tsExpiry; /* Time stamp */ - SECURITY_STATUS Status; /* Status */ - HCRYPTKEY hKey = (HCRYPTKEY)NULL; /* Handle to crypto key */ - CRYPT_KEY_PROV_INFO kpi; /* Key container info */ - SYSTEMTIME et; /* System time */ - CERT_EXTENSIONS exts; /* Array of cert extensions */ - CRYPT_KEY_PROV_INFO ckp; /* Handle to crypto key */ - BOOL ok = TRUE; /* Return value */ - - - DEBUG_printf(("4http_sspi_make_credentials(sspi=%p, container=%p, common_name=\"%s\", mode=%d, years=%d)", sspi, container, common_name, mode, years)); - - if (!CryptAcquireContextW(&hProv, (LPWSTR)container, MS_DEF_PROV_W, PROV_RSA_FULL, CRYPT_NEWKEYSET /* | CRYPT_MACHINE_KEYSET*/)) - { - if (GetLastError() == NTE_EXISTS) - { - if (!CryptAcquireContextW(&hProv, (LPWSTR)container, MS_DEF_PROV_W, PROV_RSA_FULL, 0 /*CRYPT_MACHINE_KEYSET*/)) - { - http_sspi_set_error("CryptAquireContext"); - DEBUG_printf(("5http_sspi_make_credentials: CryptAcquireContext failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), GetLastError()))); -// fprintf(stderr, "5http_sspi_make_credentials: CryptAcquireContext failed: %s\n", http_sspi_strerror(sspi->error, sizeof(sspi->error), GetLastError())); - ok = FALSE; - goto cleanup; - } - } - } - - store = CertOpenStore(CERT_STORE_PROV_SYSTEM, X509_ASN_ENCODING|PKCS_7_ASN_ENCODING, hProv, CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_NO_CRYPT_RELEASE_FLAG | CERT_STORE_OPEN_EXISTING_FLAG, L"MY"); - - if (!store) - { - http_sspi_set_error("CertOpenSystemStore"); - DEBUG_printf(("5http_sspi_make_credentials: CertOpenSystemStore failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), GetLastError()))); -// fprintf(stderr, "5http_sspi_make_credentials: CertOpenSystemStore failed: %s\n", http_sspi_strerror(sspi->error, sizeof(sspi->error), GetLastError())); - ok = FALSE; - goto cleanup; - } - - dwSize = 0; - - if (!CertStrToNameA(X509_ASN_ENCODING, common_name, CERT_OID_NAME_STR, NULL, NULL, &dwSize, NULL)) - { - http_sspi_set_error("CertStrToName"); - DEBUG_printf(("5http_sspi_make_credentials: CertStrToName failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), GetLastError()))); -// fprintf(stderr, "5http_sspi_make_credentials: CertStrToName failed: %s\n", http_sspi_strerror(sspi->error, sizeof(sspi->error), GetLastError())); - ok = FALSE; - goto cleanup; - } - - p = (PBYTE)malloc(dwSize); - - if (!p) - { - _cupsSetHTTPError(HTTP_STATUS_ERROR); - DEBUG_printf(("5http_sspi_make_credentials: malloc failed for %d bytes", dwSize)); -// fprintf(stderr, "5http_sspi_make_credentials: malloc failed for %d bytes\n", dwSize); - ok = FALSE; - goto cleanup; - } - - if (!CertStrToNameA(X509_ASN_ENCODING, common_name, CERT_OID_NAME_STR, NULL, p, &dwSize, NULL)) - { - http_sspi_set_error("CertStrToName"); - DEBUG_printf(("5http_sspi_make_credentials: CertStrToName failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), GetLastError()))); -// fprintf(stderr, "5http_sspi_make_credentials: CertStrToName failed: %s\n", http_sspi_strerror(sspi->error, sizeof(sspi->error), GetLastError())); - ok = FALSE; - goto cleanup; - } - - sib.cbData = dwSize; - sib.pbData = p; - - /* - * Create a private key and self-signed certificate... - */ - - if (!CryptGenKey(hProv, AT_KEYEXCHANGE, CRYPT_EXPORTABLE | RSA1024BIT_KEY, &hKey)) - { - http_sspi_set_error("CryptGenKey"); - DEBUG_printf(("5http_sspi_make_credentials: CryptGenKey failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), GetLastError()))); -// fprintf(stderr, "5http_sspi_make_credentials: CryptGenKey failed: %s\n", http_sspi_strerror(sspi->error, sizeof(sspi->error), GetLastError())); - ok = FALSE; - goto cleanup; - } - - ZeroMemory(&kpi, sizeof(kpi)); - kpi.pwszContainerName = (LPWSTR)container; - kpi.pwszProvName = MS_DEF_PROV_W; - kpi.dwProvType = PROV_RSA_FULL; - kpi.dwFlags = CERT_SET_KEY_CONTEXT_PROP_ID; - kpi.dwKeySpec = AT_KEYEXCHANGE; - - GetSystemTime(&et); - et.wYear += years; - if (et.wMonth == 2 && et.wDay == 29) - et.wDay = 28; /* Avoid Feb 29th due to leap years */ - - ZeroMemory(&exts, sizeof(exts)); - - createdContext = CertCreateSelfSignCertificate(hProv, &sib, 0, &kpi, NULL, NULL, &et, &exts); - - if (!createdContext) - { - http_sspi_set_error("CertCreateSelfSignCertificate"); - DEBUG_printf(("5http_sspi_make_credentials: CertCreateSelfSignCertificate failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), GetLastError()))); -// fprintf(stderr, "5http_sspi_make_credentials: CertCreateSelfSignCertificate failed: %s\n", http_sspi_strerror(sspi->error, sizeof(sspi->error), GetLastError())); - ok = FALSE; - goto cleanup; - } - - /* - * Add the created context to the named store, and associate it with the named - * container... - */ - - if (!CertAddCertificateContextToStore(store, createdContext, CERT_STORE_ADD_REPLACE_EXISTING, &storedContext)) - { - http_sspi_set_error("CertAddCertificateContextToStore"); - DEBUG_printf(("5http_sspi_make_credentials: CertAddCertificateContextToStore failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), GetLastError()))); - ok = FALSE; - goto cleanup; - } - - ZeroMemory(&ckp, sizeof(ckp)); - ckp.pwszContainerName = (LPWSTR) container; - ckp.pwszProvName = MS_DEF_PROV_W; - ckp.dwProvType = PROV_RSA_FULL; - ckp.dwFlags = 0 /*CRYPT_MACHINE_KEYSET*/; - ckp.dwKeySpec = AT_KEYEXCHANGE; - - if (!CertSetCertificateContextProperty(storedContext, CERT_KEY_PROV_INFO_PROP_ID, 0, &ckp)) - { - http_sspi_set_error("CertSetCertificateContextProperty"); - DEBUG_printf(("5http_sspi_make_credentials: CertSetCertificateContextProperty failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), GetLastError()))); - ok = FALSE; - goto cleanup; - } - - /* - * Get a handle to use the certificate... - */ - - ZeroMemory(&SchannelCred, sizeof(SchannelCred)); - - SchannelCred.dwVersion = SCHANNEL_CRED_VERSION; - SchannelCred.cCreds = 1; - SchannelCred.paCred = &storedContext; - - /* - * Create an SSPI credential. - */ - - Status = AcquireCredentialsHandle(NULL, UNISP_NAME, mode == _HTTP_MODE_SERVER ? SECPKG_CRED_INBOUND : SECPKG_CRED_OUTBOUND, NULL, &SchannelCred, NULL, NULL, &sspi->creds, &tsExpiry); - if (Status != SEC_E_OK) - { - http_sspi_set_error("AcquireCredentialsHandle"); - DEBUG_printf(("5http_sspi_make_credentials: AcquireCredentialsHandle failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), Status))); -// fprintf(stderr, "5http_sspi_make_credentials: AcquireCredentialsHandle failed: %s\n", http_sspi_strerror(sspi->error, sizeof(sspi->error), Status)); - ok = FALSE; - goto cleanup; - } - -cleanup: - - /* - * Cleanup - */ - - if (hKey) - CryptDestroyKey(hKey); - - if (createdContext) - CertFreeCertificateContext(createdContext); - - if (storedContext) - CertFreeCertificateContext(storedContext); - - if (p) - free(p); - - if (store) - CertCloseStore(store, 0); - - if (hProv) - CryptReleaseContext(hProv, 0); - - return (ok); -} - - -/* - * 'http_sspi_server()' - Negotiate a TLS connection as a server. - */ - -static int /* O - 0 on success, -1 on failure */ -http_sspi_server(http_t *http, /* I - HTTP connection */ - const char *hostname) /* I - Hostname of server */ -{ - _http_sspi_t *sspi = http->tls; /* SSPI data */ - char common_name[512]; /* Common name for cert */ - DWORD dwSSPIFlags; /* SSL connection attributes we want */ - DWORD dwSSPIOutFlags; /* SSL connection attributes we got */ - TimeStamp tsExpiry; /* Time stamp */ - SECURITY_STATUS scRet; /* SSPI Status */ - SecBufferDesc inBuffer; /* Array of SecBuffer structs */ - SecBuffer inBuffers[2]; /* Security package buffer */ - SecBufferDesc outBuffer; /* Array of SecBuffer structs */ - SecBuffer outBuffers[1]; /* Security package buffer */ - int num = 0; /* 32 bit status value */ - BOOL fInitContext = TRUE; /* Has the context been init'd? */ - int ret = 0; /* Return value */ - - - DEBUG_printf(("4http_sspi_server(http=%p, hostname=\"%s\")", http, hostname)); - - dwSSPIFlags = ASC_REQ_SEQUENCE_DETECT | - ASC_REQ_REPLAY_DETECT | - ASC_REQ_CONFIDENTIALITY | - ASC_REQ_EXTENDED_ERROR | - ASC_REQ_ALLOCATE_MEMORY | - ASC_REQ_STREAM; - - sspi->decryptBufferUsed = 0; - - /* - * Lookup the server certificate... - */ - - snprintf(common_name, sizeof(common_name), "CN=%s", hostname); - - if (!http_sspi_find_credentials(http, L"ServerContainer", common_name)) - if (!http_sspi_make_credentials(http->tls, L"ServerContainer", common_name, _HTTP_MODE_SERVER, 10)) - { - DEBUG_puts("5http_sspi_server: Unable to get server credentials."); - return (-1); - } - - /* - * Set OutBuffer for AcceptSecurityContext call - */ - - outBuffer.cBuffers = 1; - outBuffer.pBuffers = outBuffers; - outBuffer.ulVersion = SECBUFFER_VERSION; - - scRet = SEC_I_CONTINUE_NEEDED; - - while (scRet == SEC_I_CONTINUE_NEEDED || - scRet == SEC_E_INCOMPLETE_MESSAGE || - scRet == SEC_I_INCOMPLETE_CREDENTIALS) - { - if (sspi->decryptBufferUsed == 0 || scRet == SEC_E_INCOMPLETE_MESSAGE) - { - if (sspi->decryptBufferLength <= sspi->decryptBufferUsed) - { - BYTE *temp; /* New buffer */ - - if (sspi->decryptBufferLength >= 262144) - { - WSASetLastError(E_OUTOFMEMORY); - DEBUG_puts("5http_sspi_server: Decryption buffer too large (>256k)"); - return (-1); - } - - if ((temp = realloc(sspi->decryptBuffer, sspi->decryptBufferLength + 4096)) == NULL) - { - _cupsSetHTTPError(HTTP_STATUS_ERROR); - DEBUG_printf(("5http_sspi_server: Unable to allocate %d byte buffer.", sspi->decryptBufferLength + 4096)); - WSASetLastError(E_OUTOFMEMORY); - return (-1); - } - - sspi->decryptBufferLength += 4096; - sspi->decryptBuffer = temp; - } - - for (;;) - { - num = recv(http->fd, sspi->decryptBuffer + sspi->decryptBufferUsed, (int)(sspi->decryptBufferLength - sspi->decryptBufferUsed), 0); - - if (num == -1 && WSAGetLastError() == WSAEWOULDBLOCK) - Sleep(1); - else - break; - } - - if (num < 0) - { - DEBUG_printf(("5http_sspi_server: recv failed: %d", WSAGetLastError())); - return (-1); - } - else if (num == 0) - { - DEBUG_puts("5http_sspi_server: client disconnected"); - return (-1); - } - - DEBUG_printf(("5http_sspi_server: received %d (handshake) bytes from client.", num)); - sspi->decryptBufferUsed += num; - } - - /* - * InBuffers[1] is for getting extra data that SSPI/SCHANNEL doesn't process - * on this run around the loop. - */ - - inBuffers[0].pvBuffer = sspi->decryptBuffer; - inBuffers[0].cbBuffer = (unsigned long)sspi->decryptBufferUsed; - inBuffers[0].BufferType = SECBUFFER_TOKEN; - - inBuffers[1].pvBuffer = NULL; - inBuffers[1].cbBuffer = 0; - inBuffers[1].BufferType = SECBUFFER_EMPTY; - - inBuffer.cBuffers = 2; - inBuffer.pBuffers = inBuffers; - inBuffer.ulVersion = SECBUFFER_VERSION; - - /* - * Initialize these so if we fail, pvBuffer contains NULL, so we don't try to - * free random garbage at the quit. - */ - - outBuffers[0].pvBuffer = NULL; - outBuffers[0].BufferType = SECBUFFER_TOKEN; - outBuffers[0].cbBuffer = 0; - - scRet = AcceptSecurityContext(&sspi->creds, (fInitContext?NULL:&sspi->context), &inBuffer, dwSSPIFlags, SECURITY_NATIVE_DREP, (fInitContext?&sspi->context:NULL), &outBuffer, &dwSSPIOutFlags, &tsExpiry); - - fInitContext = FALSE; - - if (scRet == SEC_E_OK || - scRet == SEC_I_CONTINUE_NEEDED || - (FAILED(scRet) && ((dwSSPIOutFlags & ISC_RET_EXTENDED_ERROR) != 0))) - { - if (outBuffers[0].cbBuffer && outBuffers[0].pvBuffer) - { - /* - * Send response to server if there is one. - */ - - num = send(http->fd, outBuffers[0].pvBuffer, outBuffers[0].cbBuffer, 0); - - if (num <= 0) - { - DEBUG_printf(("5http_sspi_server: handshake send failed: %d", WSAGetLastError())); - return (-1); - } - - DEBUG_printf(("5http_sspi_server: sent %d handshake bytes to client.", outBuffers[0].cbBuffer)); - - FreeContextBuffer(outBuffers[0].pvBuffer); - outBuffers[0].pvBuffer = NULL; - } - } - - if (scRet == SEC_E_OK) - { - /* - * If there's extra data then save it for next time we go to decrypt. - */ - - if (inBuffers[1].BufferType == SECBUFFER_EXTRA) - { - memcpy(sspi->decryptBuffer, (LPBYTE)(sspi->decryptBuffer + sspi->decryptBufferUsed - inBuffers[1].cbBuffer), inBuffers[1].cbBuffer); - sspi->decryptBufferUsed = inBuffers[1].cbBuffer; - } - else - { - sspi->decryptBufferUsed = 0; - } - break; - } - else if (FAILED(scRet) && scRet != SEC_E_INCOMPLETE_MESSAGE) - { - http_sspi_set_error("AcceptSecurityContext"); - DEBUG_printf(("5http_sspi_server: AcceptSecurityContext failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), scRet))); - ret = -1; - break; - } - - if (scRet != SEC_E_INCOMPLETE_MESSAGE && - scRet != SEC_I_INCOMPLETE_CREDENTIALS) - { - if (inBuffers[1].BufferType == SECBUFFER_EXTRA) - { - memcpy(sspi->decryptBuffer, (LPBYTE)(sspi->decryptBuffer + sspi->decryptBufferUsed - inBuffers[1].cbBuffer), inBuffers[1].cbBuffer); - sspi->decryptBufferUsed = inBuffers[1].cbBuffer; - } - else - { - sspi->decryptBufferUsed = 0; - } - } - } - - if (!ret) - { - sspi->contextInitialized = TRUE; - - /* - * Find out how big the header will be: - */ - - scRet = QueryContextAttributes(&sspi->context, SECPKG_ATTR_STREAM_SIZES, &sspi->streamSizes); - - if (scRet != SEC_E_OK) - { - http_sspi_set_error("QueryContextAttributes"); - DEBUG_printf(("5http_sspi_server: QueryContextAttributes failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), scRet))); - ret = -1; - } - } - - return (ret); -} - - -// -// 'http_sspi_set_error()' - Copy the Windows error string to the CUPS error string. -// - -static void -http_sspi_set_error(const char *title) // I - Prefix/title for error -{ - char temp[8192]; // Error string - size_t templen; // Length of prefix - - - snprintf(temp, sizeof(temp), "%s (%08x): ", title, GetLastError()); - templen = strlen(temp); - http_sspi_strerror(temp + templen, sizeof(temp) - templen, GetLastError()); - _cupsSetError(IPP_STATUS_ERROR_CUPS_PKI, temp, 0); -} - - -/* - * 'http_sspi_strerror()' - Return a string for the specified error code. - */ - -static const char * /* O - String for error */ -http_sspi_strerror(char *buffer, /* I - Error message buffer */ - size_t bufsize, /* I - Size of buffer */ - DWORD code) /* I - Error code */ -{ - if (FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, code, 0, buffer, (DWORD)bufsize, NULL)) - { - /* - * Strip trailing CR + LF... - */ - - char *ptr; /* Pointer into error message */ - - for (ptr = buffer + strlen(buffer) - 1; ptr >= buffer; ptr --) - if (*ptr == '\n' || *ptr == '\r') - *ptr = '\0'; - else - break; - } - else - snprintf(buffer, bufsize, "Unknown error %x", code); - - return (buffer); -} - - -/* - * 'http_sspi_verify()' - Verify a certificate. - */ - -static DWORD /* O - Error code (0 == No error) */ -http_sspi_verify( - PCCERT_CONTEXT cert, /* I - Server certificate */ - const char *common_name, /* I - Common name */ - DWORD dwCertFlags) /* I - Verification flags */ -{ - HTTPSPolicyCallbackData httpsPolicy; /* HTTPS Policy Struct */ - CERT_CHAIN_POLICY_PARA policyPara; /* Cert chain policy parameters */ - CERT_CHAIN_POLICY_STATUS policyStatus;/* Cert chain policy status */ - CERT_CHAIN_PARA chainPara; /* Used for searching and matching criteria */ - PCCERT_CHAIN_CONTEXT chainContext = NULL; - /* Certificate chain */ - PWSTR commonNameUnicode = NULL; - /* Unicode common name */ - LPSTR rgszUsages[] = { szOID_PKIX_KP_SERVER_AUTH, - szOID_SERVER_GATED_CRYPTO, - szOID_SGC_NETSCAPE }; - /* How are we using this certificate? */ - DWORD cUsages = sizeof(rgszUsages) / sizeof(LPSTR); - /* Number of ites in rgszUsages */ - DWORD count; /* 32 bit count variable */ - DWORD status; /* Return value */ -#ifdef DEBUG - char error[1024]; /* Error message string */ -#endif /* DEBUG */ - - - if (!cert) - return (SEC_E_WRONG_PRINCIPAL); - - /* - * Convert common name to Unicode. - */ - - if (!common_name || !*common_name) - return (SEC_E_WRONG_PRINCIPAL); - - count = MultiByteToWideChar(CP_ACP, 0, common_name, -1, NULL, 0); - commonNameUnicode = LocalAlloc(LMEM_FIXED, count * sizeof(WCHAR)); - if (!commonNameUnicode) - return (SEC_E_INSUFFICIENT_MEMORY); - - if (!MultiByteToWideChar(CP_ACP, 0, common_name, -1, commonNameUnicode, count)) - { - LocalFree(commonNameUnicode); - return (SEC_E_WRONG_PRINCIPAL); - } - - /* - * Build certificate chain. - */ - - ZeroMemory(&chainPara, sizeof(chainPara)); - - chainPara.cbSize = sizeof(chainPara); - chainPara.RequestedUsage.dwType = USAGE_MATCH_TYPE_OR; - chainPara.RequestedUsage.Usage.cUsageIdentifier = cUsages; - chainPara.RequestedUsage.Usage.rgpszUsageIdentifier = rgszUsages; - - if (!CertGetCertificateChain(NULL, cert, NULL, cert->hCertStore, &chainPara, 0, NULL, &chainContext)) - { - status = GetLastError(); - - http_sspi_set_error("CertGetCertificateChain"); - DEBUG_printf(("5http_sspi_verify: CertGetCertificateChain returned: %s", http_sspi_strerror(error, sizeof(error), status))); - - LocalFree(commonNameUnicode); - return (status); - } - - /* - * Validate certificate chain. - */ - - ZeroMemory(&httpsPolicy, sizeof(HTTPSPolicyCallbackData)); - httpsPolicy.cbStruct = sizeof(HTTPSPolicyCallbackData); - httpsPolicy.dwAuthType = AUTHTYPE_SERVER; - httpsPolicy.fdwChecks = dwCertFlags; - httpsPolicy.pwszServerName = commonNameUnicode; - - memset(&policyPara, 0, sizeof(policyPara)); - policyPara.cbSize = sizeof(policyPara); - policyPara.pvExtraPolicyPara = &httpsPolicy; - - memset(&policyStatus, 0, sizeof(policyStatus)); - policyStatus.cbSize = sizeof(policyStatus); - - if (!CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_SSL, chainContext, &policyPara, &policyStatus)) - { - status = GetLastError(); - - http_sspi_set_error("CertVerifyCertificateChainPolicy"); - DEBUG_printf(("5http_sspi_verify: CertVerifyCertificateChainPolicy returned %s", http_sspi_strerror(error, sizeof(error), status))); - } - else if (policyStatus.dwError) - status = policyStatus.dwError; - else - status = SEC_E_OK; - - if (chainContext) - CertFreeCertificateChain(chainContext); - - if (commonNameUnicode) - LocalFree(commonNameUnicode); - - return (status); -} diff --git a/cups/tls.c b/cups/tls.c index ff64d71325..6aaee40746 100644 --- a/cups/tls.c +++ b/cups/tls.c @@ -33,69 +33,8 @@ * Include platform-specific TLS code... */ -#ifdef HAVE_TLS -# ifdef HAVE_OPENSSL -# include "tls-openssl.c" -# elif defined(HAVE_GNUTLS) -# include "tls-gnutls.c" -# elif defined(HAVE_CDSASSL) -# include "tls-darwin.c" -# elif defined(HAVE_SSPISSL) -# include "tls-sspi.c" -# endif /* HAVE_GNUTLS */ -#else -/* Stubs for when TLS is not supported/available */ -int -httpCopyCredentials(http_t *http, cups_array_t **credentials) -{ - (void)http; - if (credentials) - *credentials = NULL; - return (-1); -} -int -httpCredentialsAreValidForName(cups_array_t *credentials, const char *common_name) -{ - (void)credentials; - (void)common_name; - return (1); -} -time_t -httpCredentialsGetExpiration(cups_array_t *credentials) -{ - (void)credentials; - return (INT_MAX); -} -http_trust_t -httpCredentialsGetTrust(cups_array_t *credentials, const char *common_name) -{ - (void)credentials; - (void)common_name; - return (HTTP_TRUST_OK); -} -size_t -httpCredentialsString(cups_array_t *credentials, char *buffer, size_t bufsize) -{ - (void)credentials; - (void)bufsize; - if (buffer) - *buffer = '\0'; - return (0); -} -int -httpLoadCredentials(const char *path, cups_array_t **credentials, const char *common_name) -{ - (void)path; - (void)credentials; - (void)common_name; - return (-1); -} -int -httpSaveCredentials(const char *path, cups_array_t *credentials, const char *common_name) -{ - (void)path; - (void)credentials; - (void)common_name; - return (-1); -} -#endif /* HAVE_TLS */ +#ifdef HAVE_OPENSSL +# include "tls-openssl.c" +#else /* HAVE_GNUTLS */ +# include "tls-gnutls.c" +#endif /* HAVE_OPENSSL */ diff --git a/cups/tlscheck.c b/cups/tlscheck.c index 11fa477d32..0a541f7233 100644 --- a/cups/tlscheck.c +++ b/cups/tlscheck.c @@ -16,10 +16,6 @@ #include "cups-private.h" -#ifndef HAVE_TLS -int main(void) { puts("Sorry, no TLS support compiled in."); return (1); } -#else - /* * Local functions... */ @@ -822,4 +818,3 @@ usage(void) exit(1); } -#endif /* !HAVE_TLS */ diff --git a/cups/usersys.c b/cups/usersys.c index 4e52ff7a74..df5cbaea8e 100644 --- a/cups/usersys.c +++ b/cups/usersys.c @@ -68,11 +68,9 @@ typedef struct _cups_client_conf_s /**** client.conf config data ****/ { _cups_digestoptions_t digestoptions; /* DigestOptions values */ _cups_uatokens_t uatokens; /* UserAgentTokens values */ -#ifdef HAVE_TLS int ssl_options, /* SSLOptions values */ ssl_min_version,/* Minimum SSL/TLS version */ ssl_max_version;/* Maximum SSL/TLS version */ -#endif /* HAVE_TLS */ int trust_first, /* Trust on first use? */ any_root, /* Allow any (e.g., self-signed) root */ expired_certs, /* Allow expired certs */ @@ -93,9 +91,7 @@ typedef struct _cups_client_conf_s /**** client.conf config data ****/ */ #ifdef __APPLE__ -# ifdef HAVE_TLS static int cups_apple_get_boolean(CFStringRef key, int *value); -# endif /* HAVE_TLS */ static int cups_apple_get_string(CFStringRef key, char *value, size_t valsize); #endif /* __APPLE__ */ static int cups_boolean_value(const char *value); @@ -109,9 +105,7 @@ static void cups_set_encryption(_cups_client_conf_t *cc, const char *value); static void cups_set_gss_service_name(_cups_client_conf_t *cc, const char *value); #endif /* HAVE_GSSAPI */ static void cups_set_server_name(_cups_client_conf_t *cc, const char *value); -#ifdef HAVE_TLS static void cups_set_ssl_options(_cups_client_conf_t *cc, const char *value); -#endif /* HAVE_TLS */ static void cups_set_uatokens(_cups_client_conf_t *cc, const char *value); static void cups_set_user(_cups_client_conf_t *cc, const char *value); @@ -274,10 +268,8 @@ cupsSetCredentials( if (cupsArrayCount(credentials) < 1) return (-1); -#ifdef HAVE_TLS _httpFreeCredentials(cg->tls_credentials); cg->tls_credentials = _httpCreateCredentials(credentials); -#endif /* HAVE_TLS */ return (cg->tls_credentials ? 0 : -1); } @@ -1106,14 +1098,11 @@ _cupsSetDefaults(void) if (cg->validate_certs < 0) cg->validate_certs = cc.validate_certs; -#ifdef HAVE_TLS _httpTLSSetOptions(cc.ssl_options | _HTTP_TLS_SET_DEFAULT, cc.ssl_min_version, cc.ssl_max_version); -#endif /* HAVE_TLS */ } #ifdef __APPLE__ -# ifdef HAVE_TLS /* * 'cups_apple_get_boolean()' - Get a boolean setting from the CUPS preferences. */ @@ -1134,7 +1123,6 @@ cups_apple_get_boolean( return ((int)bval_set); } -# endif /* HAVE_TLS */ /* @@ -1328,10 +1316,8 @@ cups_init_client_conf( cups_set_user(cc, "mobile"); #endif /* __APPLE__ && !TARGET_OS_OSX */ -#ifdef HAVE_TLS cc->ssl_min_version = _HTTP_TLS_1_0; cc->ssl_max_version = _HTTP_TLS_MAX; -#endif /* HAVE_TLS */ cc->encryption = (http_encryption_t)-1; cc->trust_first = -1; cc->any_root = -1; @@ -1345,7 +1331,6 @@ cups_init_client_conf( #if defined(__APPLE__) char sval[1024]; /* String value */ -# ifdef HAVE_TLS int bval; /* Boolean value */ if (cups_apple_get_boolean(kAllowAnyRootKey, &bval)) @@ -1381,7 +1366,6 @@ cups_init_client_conf( if (cups_apple_get_boolean(kValidateCertsKey, &bval)) cc->validate_certs = bval; -# endif /* HAVE_TLS */ if (cups_apple_get_string(kDigestOptionsKey, sval, sizeof(sval))) cups_set_digestoptions(cc, sval); @@ -1445,10 +1429,8 @@ cups_read_client_conf( else if (!_cups_strcasecmp(line, "GSSServiceName") && value) cups_set_gss_service_name(cc, value); #endif /* HAVE_GSSAPI */ -#ifdef HAVE_TLS else if (!_cups_strcasecmp(line, "SSLOptions") && value) cups_set_ssl_options(cc, value); -#endif /* HAVE_TLS */ } } @@ -1542,7 +1524,6 @@ cups_set_server_name( * 'cups_set_ssl_options()' - Set the SSLOptions value. */ -#ifdef HAVE_TLS static void cups_set_ssl_options( _cups_client_conf_t *cc, /* I - client.conf values */ @@ -1615,7 +1596,6 @@ cups_set_ssl_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_TLS */ /* diff --git a/scheduler/auth.c b/scheduler/auth.c index 7f6c3f6d2f..75e0926da5 100644 --- a/scheduler/auth.c +++ b/scheduler/auth.c @@ -1630,7 +1630,6 @@ cupsdIsAuthorized(cupsd_client_t *con, /* I - Connection */ if (auth == CUPSD_AUTH_DENY && best->satisfy == CUPSD_AUTH_SATISFY_ALL) return (HTTP_FORBIDDEN); -#ifdef HAVE_TLS /* * See if encryption is required... */ @@ -1647,7 +1646,6 @@ cupsdIsAuthorized(cupsd_client_t *con, /* I - Connection */ "cupsdIsAuthorized: Need upgrade to TLS..."); return (HTTP_UPGRADE_REQUIRED); } -#endif /* HAVE_TLS */ /* * Now see what access level is required... diff --git a/scheduler/auth.h b/scheduler/auth.h index 14885b0283..77801f86b3 100644 --- a/scheduler/auth.h +++ b/scheduler/auth.h @@ -107,10 +107,8 @@ typedef struct cupsd_client_s cupsd_client_t; VAR cups_array_t *Locations VALUE(NULL); /* Authorization locations */ -#ifdef HAVE_TLS VAR http_encryption_t DefaultEncryption VALUE(HTTP_ENCRYPT_REQUIRED); /* Default encryption for authentication */ -#endif /* HAVE_TLS */ /* diff --git a/scheduler/client.c b/scheduler/client.c index 327473a4d1..04b710a8d8 100644 --- a/scheduler/client.c +++ b/scheduler/client.c @@ -36,9 +36,7 @@ static int check_if_modified(cupsd_client_t *con, struct stat *filestats); static int compare_clients(cupsd_client_t *a, cupsd_client_t *b, void *data); -#ifdef HAVE_TLS static int cupsd_start_tls(cupsd_client_t *con, http_encryption_t e); -#endif /* HAVE_TLS */ static char *get_file(cupsd_client_t *con, struct stat *filestats, char *filename, size_t len); static http_status_t install_cupsd_conf(cupsd_client_t *con); @@ -352,7 +350,6 @@ cupsdAcceptClient(cupsd_listener_t *lis)/* I - Listener socket */ if (cupsArrayCount(Clients) == MaxClients) cupsdPauseListening(); -#ifdef HAVE_TLS /* * See if we are connecting on a secure port... */ @@ -368,7 +365,6 @@ cupsdAcceptClient(cupsd_listener_t *lis)/* I - Listener socket */ } else con->auto_ssl = 1; -#endif /* HAVE_TLS */ } @@ -439,14 +435,12 @@ cupsdCloseClient(cupsd_client_t *con) /* I - Client to close */ cupsArrayRemove(ActiveClients, con); cupsdSetBusyState(0); -#ifdef HAVE_TLS /* * Shutdown encryption as needed... */ if (httpIsEncrypted(con->http)) partial = 1; -#endif /* HAVE_TLS */ if (partial) { @@ -588,7 +582,6 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ return; } -#ifdef HAVE_TLS if (con->auto_ssl) { /* @@ -612,7 +605,6 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ return; } } -#endif /* HAVE_TLS */ switch (httpGetState(con->http)) { @@ -922,7 +914,6 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ if (!_cups_strcasecmp(httpGetField(con->http, HTTP_FIELD_CONNECTION), "Upgrade") && strstr(httpGetField(con->http, HTTP_FIELD_UPGRADE), "TLS/") != NULL && !httpIsEncrypted(con->http)) { -#ifdef HAVE_TLS /* * Do encryption stuff... */ @@ -940,13 +931,6 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ cupsdCloseClient(con); return; } -#else - if (!cupsdSendError(con, HTTP_STATUS_NOT_IMPLEMENTED, CUPSD_AUTH_NONE)) - { - cupsdCloseClient(con); - return; - } -#endif /* HAVE_TLS */ } httpClearFields(con->http); @@ -978,7 +962,6 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ if (!_cups_strcasecmp(httpGetField(con->http, HTTP_FIELD_CONNECTION), "Upgrade") && !httpIsEncrypted(con->http)) { -#ifdef HAVE_TLS /* * Do encryption stuff... */ @@ -997,13 +980,6 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ cupsdCloseClient(con); return; } -#else - if (!cupsdSendError(con, HTTP_STATUS_NOT_IMPLEMENTED, CUPSD_AUTH_NONE)) - { - cupsdCloseClient(con); - return; - } -#endif /* HAVE_TLS */ } if ((status = cupsdIsAuthorized(con, NULL)) != HTTP_STATUS_OK) @@ -1922,7 +1898,6 @@ cupsdSendError(cupsd_client_t *con, /* I - Connection */ cupsdLogClient(con, CUPSD_LOG_DEBUG2, "cupsdSendError code=%d, auth_type=%d", code, auth_type); -#ifdef HAVE_TLS /* * Force client to upgrade for authentication if that is how the * server is configured... @@ -1935,7 +1910,6 @@ cupsdSendError(cupsd_client_t *con, /* I - Connection */ { code = HTTP_STATUS_UPGRADE_REQUIRED; } -#endif /* HAVE_TLS */ /* * Put the request in the access_log file... @@ -2655,7 +2629,6 @@ compare_clients(cupsd_client_t *a, /* I - First client */ } -#ifdef HAVE_TLS /* * 'cupsd_start_tls()' - Start encryption on a connection. */ @@ -2674,7 +2647,6 @@ cupsd_start_tls(cupsd_client_t *con, /* I - Client connection */ cupsdLogClient(con, CUPSD_LOG_DEBUG, "Connection now encrypted."); return (0); } -#endif /* HAVE_TLS */ /* diff --git a/scheduler/client.h b/scheduler/client.h index e12a860dd6..302db2bf7d 100644 --- a/scheduler/client.h +++ b/scheduler/client.h @@ -49,9 +49,7 @@ struct cupsd_client_s header_used; /* Number of header bytes used */ char header[2048]; /* Header from CGI program */ cups_lang_t *language; /* Language to use */ -#ifdef HAVE_TLS int auto_ssl; /* Automatic test for SSL/TLS */ -#endif /* HAVE_TLS */ http_addr_t clientaddr; /* Client's server address */ char clientname[256];/* Client's server name for connection */ int clientport; /* Client's server port for connection */ @@ -136,7 +134,5 @@ extern void cupsdStopListening(void); extern void cupsdUpdateCGI(void); extern void cupsdWriteClient(cupsd_client_t *con); -#ifdef HAVE_TLS extern int cupsdEndTLS(cupsd_client_t *con); extern int cupsdStartTLS(cupsd_client_t *con); -#endif /* HAVE_TLS */ diff --git a/scheduler/conf.c b/scheduler/conf.c index b185351622..da22ff2d3c 100644 --- a/scheduler/conf.c +++ b/scheduler/conf.c @@ -136,9 +136,7 @@ static const cupsd_var_t cupsfiles_vars[] = { "AccessLog", &AccessLog, CUPSD_VARTYPE_STRING }, { "CacheDir", &CacheDir, CUPSD_VARTYPE_STRING }, { "ConfigFilePerm", &ConfigFilePerm, CUPSD_VARTYPE_PERM }, -#ifdef HAVE_TLS { "CreateSelfSignedCerts", &CreateSelfSignedCerts, CUPSD_VARTYPE_BOOLEAN }, -#endif /* HAVE_TLS */ { "DataDir", &DataDir, CUPSD_VARTYPE_STRING }, { "DocumentRoot", &DocumentRoot, CUPSD_VARTYPE_STRING }, { "ErrorLog", &ErrorLog, CUPSD_VARTYPE_STRING }, @@ -149,9 +147,7 @@ static const cupsd_var_t cupsfiles_vars[] = { "RemoteRoot", &RemoteRoot, CUPSD_VARTYPE_STRING }, { "RequestRoot", &RequestRoot, CUPSD_VARTYPE_STRING }, { "ServerBin", &ServerBin, CUPSD_VARTYPE_PATHNAME }, -#ifdef HAVE_TLS { "ServerKeychain", &ServerKeychain, CUPSD_VARTYPE_PATHNAME }, -#endif /* HAVE_TLS */ { "ServerRoot", &ServerRoot, CUPSD_VARTYPE_PATHNAME }, { "StateDir", &StateDir, CUPSD_VARTYPE_STRING }, { "SyncOnClose", &SyncOnClose, CUPSD_VARTYPE_BOOLEAN }, @@ -604,15 +600,9 @@ cupsdReadConfiguration(void) cupsdClearString(&Classification); ClassifyOverride = 0; -#ifdef HAVE_TLS -# if defined HAVE_GNUTLS || defined HAVE_OPENSSL cupsdSetString(&ServerKeychain, "ssl"); -# else - cupsdSetString(&ServerKeychain, "/Library/Keychains/System.keychain"); -# endif /* HAVE_GNUTLS || HAVE_OPENSSL */ _httpTLSSetOptions(_HTTP_TLS_NONE, _HTTP_TLS_1_0, _HTTP_TLS_MAX); -#endif /* HAVE_TLS */ language = cupsLangDefault(); @@ -699,10 +689,8 @@ cupsdReadConfiguration(void) ConfigFilePerm = CUPS_DEFAULT_CONFIG_FILE_PERM; FatalErrors = parse_fatal_errors(CUPS_DEFAULT_FATAL_ERRORS); default_auth_type = CUPSD_AUTH_BASIC; -#ifdef HAVE_TLS CreateSelfSignedCerts = TRUE; DefaultEncryption = HTTP_ENCRYPT_REQUIRED; -#endif /* HAVE_TLS */ DirtyCleanInterval = DEFAULT_KEEPALIVE; JobKillDelay = DEFAULT_TIMEOUT; JobRetryLimit = 5; @@ -1094,7 +1082,6 @@ cupsdReadConfiguration(void) if (CacheDir[0] != '/') cupsdSetStringf(&CacheDir, "%s/%s", ServerRoot, CacheDir); -#ifdef HAVE_TLS if (!_cups_strcasecmp(ServerKeychain, "internal")) cupsdClearString(&ServerKeychain); else if (ServerKeychain[0] != '/') @@ -1104,7 +1091,6 @@ cupsdReadConfiguration(void) if (!CreateSelfSignedCerts) cupsdLogMessage(CUPSD_LOG_DEBUG, "Self-signed TLS certificate generation is disabled."); cupsSetServerCredentials(ServerKeychain, ServerName, CreateSelfSignedCerts); -#endif /* HAVE_TLS */ /* * Make sure that directories and config files are owned and @@ -3005,7 +2991,6 @@ read_cupsd_conf(cups_file_t *fp) /* I - File to read from */ "FaxRetryLimit is deprecated; use " "JobRetryLimit on line %d of %s.", linenum, ConfigurationFile); } -#ifdef HAVE_TLS else if (!_cups_strcasecmp(line, "SSLOptions")) { /* @@ -3073,12 +3058,7 @@ read_cupsd_conf(cups_file_t *fp) /* I - File to read from */ _httpTLSSetOptions(options, min_version, max_version); } -#endif /* HAVE_TLS */ - else if ((!_cups_strcasecmp(line, "Port") || !_cups_strcasecmp(line, "Listen") -#ifdef HAVE_TLS - || !_cups_strcasecmp(line, "SSLPort") || !_cups_strcasecmp(line, "SSLListen") -#endif /* HAVE_TLS */ - ) && value) + else if ((!_cups_strcasecmp(line, "Port") || !_cups_strcasecmp(line, "Listen") || !_cups_strcasecmp(line, "SSLPort") || !_cups_strcasecmp(line, "SSLListen")) && value) { /* * Add listening address(es) to the list... @@ -3163,10 +3143,8 @@ read_cupsd_conf(cups_file_t *fp) /* I - File to read from */ memcpy(&(lis->address), &(addr->addr), sizeof(lis->address)); lis->fd = -1; -#ifdef HAVE_TLS if (!_cups_strcasecmp(line, "SSLPort") || !_cups_strcasecmp(line, "SSLListen")) lis->encryption = HTTP_ENCRYPT_ALWAYS; -#endif /* HAVE_TLS */ httpAddrString(&lis->address, temp, sizeof(temp)); @@ -3232,7 +3210,6 @@ read_cupsd_conf(cups_file_t *fp) /* I - File to read from */ return (0); } } -#ifdef HAVE_TLS else if (!_cups_strcasecmp(line, "DefaultEncryption")) { /* @@ -3254,7 +3231,6 @@ read_cupsd_conf(cups_file_t *fp) /* I - File to read from */ return (0); } } -#endif /* HAVE_TLS */ else if (!_cups_strcasecmp(line, "HostNameLookups") && value) { /* diff --git a/scheduler/conf.h b/scheduler/conf.h index 96c0fa5863..f254b6efd7 100644 --- a/scheduler/conf.h +++ b/scheduler/conf.h @@ -235,12 +235,10 @@ VAR int NumMimeTypes VALUE(0); VAR const char **MimeTypes VALUE(NULL); /* Array of MIME types */ -#ifdef HAVE_TLS VAR int CreateSelfSignedCerts VALUE(TRUE); /* Automatically create self-signed certs? */ VAR char *ServerKeychain VALUE(NULL); /* Keychain holding cert + key */ -#endif /* HAVE_TLS */ #ifdef HAVE_ONDEMAND VAR int IdleExitTimeout VALUE(60); diff --git a/scheduler/dirsvc.c b/scheduler/dirsvc.c index a438765a5e..5bf4a06891 100644 --- a/scheduler/dirsvc.c +++ b/scheduler/dirsvc.c @@ -372,7 +372,6 @@ dnssdBuildTxtRecord( * Get the URL scheme for the admin page... */ -# ifdef HAVE_TLS for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners); lis; lis = (cupsd_listener_t *)cupsArrayNext(Listeners)) { if (lis->encryption != HTTP_ENCRYPTION_NEVER) @@ -381,7 +380,6 @@ dnssdBuildTxtRecord( break; } } -# endif /* HAVE_TLS */ httpAssembleURIf(HTTP_URI_CODING_ALL, adminurl_str, sizeof(adminurl_str), admin_scheme, NULL, admin_hostname, DNSSDPort, "/%s/%s", (p->type & CUPS_PRINTER_CLASS) ? "classes" : "printers", p->name); keyvalue[count ][0] = "adminurl"; @@ -411,10 +409,8 @@ dnssdBuildTxtRecord( keyvalue[count ][0] = "UUID"; keyvalue[count++][1] = p->uuid + 9; -#ifdef HAVE_TLS keyvalue[count ][0] = "TLS"; - keyvalue[count++][1] = "1.2"; -#endif /* HAVE_TLS */ + keyvalue[count++][1] = "1.3"; if ((urf_supported = ippFindAttribute(p->ppd_attrs, "urf-supported", IPP_TAG_KEYWORD)) != NULL) { @@ -717,9 +713,7 @@ dnssdDeregisterPrinter( dnssdDeregisterInstance(&p->ipp_srv, from_callback); # ifdef HAVE_MDNSRESPONDER -# ifdef HAVE_TLS dnssdDeregisterInstance(&p->ipps_srv, from_callback); -# endif /* HAVE_TLS */ dnssdDeregisterInstance(&p->printer_srv, from_callback); # endif /* HAVE_MDNSRESPONDER */ } @@ -995,10 +989,8 @@ dnssdRegisterInstance( # ifdef HAVE_MDNSRESPONDER if (!strcmp(type, "_printer._tcp")) srv = &p->printer_srv; /* Target LPD service */ -# ifdef HAVE_TLS else if (!strcmp(type, "_ipps._tcp")) srv = &p->ipps_srv; /* Target IPPS service */ -# endif /* HAVE_TLS */ else srv = &p->ipp_srv; /* Target IPP service */ @@ -1219,10 +1211,8 @@ dnssdRegisterPrinter( status = dnssdRegisterInstance(NULL, p, name, "_printer._tcp", NULL, 0, NULL, 0, from_callback); -# ifdef HAVE_TLS if (status) dnssdRegisterInstance(NULL, p, name, "_ipps._tcp", DNSSDSubTypes, DNSSDPort, &ipp_txt, 0, from_callback); -# endif /* HAVE_TLS */ if (status) { @@ -1257,9 +1247,7 @@ dnssdRegisterPrinter( dnssdDeregisterInstance(&p->ipp_srv, from_callback); # ifdef HAVE_MDNSRESPONDER -# ifdef HAVE_TLS dnssdDeregisterInstance(&p->ipps_srv, from_callback); -# endif /* HAVE_TLS */ dnssdDeregisterInstance(&p->printer_srv, from_callback); # endif /* HAVE_MDNSRESPONDER */ } diff --git a/scheduler/ipp.c b/scheduler/ipp.c index 341c5e9cb1..de0084b36f 100644 --- a/scheduler/ipp.c +++ b/scheduler/ipp.c @@ -1280,7 +1280,6 @@ add_job(cupsd_client_t *con, /* I - Client connection */ send_http_error(con, HTTP_UNAUTHORIZED, printer); return (NULL); } -#ifdef HAVE_TLS else if (auth_info && !con->http->tls && !httpAddrLocalhost(con->http->hostaddr)) { @@ -1291,7 +1290,6 @@ add_job(cupsd_client_t *con, /* I - Client connection */ send_http_error(con, HTTP_UPGRADE_REQUIRED, printer); return (NULL); } -#endif /* HAVE_TLS */ /* * See if the printer is accepting jobs... @@ -11421,9 +11419,7 @@ validate_job(cupsd_client_t *con, /* I - Client connection */ { http_status_t status; /* Policy status */ ipp_attribute_t *attr; /* Current attribute */ -#ifdef HAVE_TLS ipp_attribute_t *auth_info; /* auth-info attribute */ -#endif /* HAVE_TLS */ ipp_attribute_t *format, /* Document-format attribute */ *name; /* Job-name attribute */ cups_ptype_t dtype; /* Destination type (printer/class) */ @@ -11550,9 +11546,7 @@ validate_job(cupsd_client_t *con, /* I - Client connection */ * Check policy... */ -#ifdef HAVE_TLS auth_info = ippFindAttribute(con->request, "auth-info", IPP_TAG_TEXT); -#endif /* HAVE_TLS */ if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, NULL)) != HTTP_OK) { @@ -11566,7 +11560,6 @@ validate_job(cupsd_client_t *con, /* I - Client connection */ send_http_error(con, HTTP_UNAUTHORIZED, printer); return; } -#ifdef HAVE_TLS else if (auth_info && !con->http->tls && !httpAddrLocalhost(con->http->hostaddr)) { @@ -11577,7 +11570,6 @@ validate_job(cupsd_client_t *con, /* I - Client connection */ send_http_error(con, HTTP_UPGRADE_REQUIRED, printer); return; } -#endif /* HAVE_TLS */ /* * Everything was ok, so return OK status... diff --git a/scheduler/main.c b/scheduler/main.c index d971d4ffe8..465de42981 100644 --- a/scheduler/main.c +++ b/scheduler/main.c @@ -1910,10 +1910,8 @@ service_add_listener(int fd, /* I - Socket file descriptor */ lis->fd = fd; lis->on_demand = 1; -# ifdef HAVE_TLS if (httpAddrPort(&(lis->address)) == 443) lis->encryption = HTTP_ENCRYPT_ALWAYS; -# endif /* HAVE_TLS */ } #endif /* HAVE_ONDEMAND */ diff --git a/scheduler/printers.h b/scheduler/printers.h index 0c7b1af70f..83624de666 100644 --- a/scheduler/printers.h +++ b/scheduler/printers.h @@ -119,9 +119,7 @@ struct cupsd_printer_s *pdl; /* pdl value for TXT record */ cupsd_srv_t ipp_srv; /* IPP service(s) */ # ifdef HAVE_MDNSRESPONDER -# ifdef HAVE_TLS cupsd_srv_t ipps_srv; /* IPPS service(s) */ -# endif /* HAVE_TLS */ cupsd_srv_t printer_srv; /* LPD service */ # endif /* HAVE_MDNSRESPONDER */ #endif /* HAVE_DNSSD */ diff --git a/systemv/cancel.c b/systemv/cancel.c index f5b8e12b5e..a30ed2ad43 100644 --- a/systemv/cancel.c +++ b/systemv/cancel.c @@ -77,14 +77,10 @@ main(int argc, /* I - Number of command-line arguments */ switch (*opt) { case 'E' : /* Encrypt */ -#ifdef HAVE_TLS cupsSetEncryption(HTTP_ENCRYPT_REQUIRED); if (http) httpEncryption(http, HTTP_ENCRYPT_REQUIRED); -#else - _cupsLangPrintf(stderr, _("%s: Sorry, no encryption support."), argv[0]); -#endif /* HAVE_TLS */ break; case 'U' : /* Username */ diff --git a/systemv/cupsaccept.c b/systemv/cupsaccept.c index a26abb4375..987cb5bcfa 100644 --- a/systemv/cupsaccept.c +++ b/systemv/cupsaccept.c @@ -90,11 +90,7 @@ main(int argc, /* I - Number of command-line arguments */ switch (*opt) { case 'E' : /* Encrypt */ -#ifdef HAVE_TLS cupsSetEncryption(HTTP_ENCRYPT_REQUIRED); -#else - _cupsLangPrintf(stderr, _("%s: Sorry, no encryption support."), command); -#endif /* HAVE_TLS */ break; case 'U' : /* Username */ diff --git a/systemv/lp.c b/systemv/lp.c index 6fa66d980f..7e85e04ee6 100644 --- a/systemv/lp.c +++ b/systemv/lp.c @@ -93,11 +93,7 @@ main(int argc, /* I - Number of command-line arguments */ switch (*opt) { case 'E' : /* Encrypt */ -#ifdef HAVE_TLS cupsSetEncryption(HTTP_ENCRYPT_REQUIRED); -#else - _cupsLangPrintf(stderr, _("%s: Sorry, no encryption support."), argv[0]); -#endif /* HAVE_TLS */ break; case 'U' : /* Username */ diff --git a/systemv/lpadmin.c b/systemv/lpadmin.c index f4325e25ad..83b28890f2 100644 --- a/systemv/lpadmin.c +++ b/systemv/lpadmin.c @@ -240,14 +240,10 @@ main(int argc, /* I - Number of command-line arguments */ case 'E' : /* Enable the printer/enable encryption */ if (printer == NULL) { -#ifdef HAVE_TLS cupsSetEncryption(HTTP_ENCRYPTION_REQUIRED); if (http) httpEncryption(http, HTTP_ENCRYPTION_REQUIRED); -#else - _cupsLangPrintf(stderr, _("%s: Sorry, no encryption support."), argv[0]); -#endif /* HAVE_TLS */ break; } diff --git a/systemv/lpinfo.c b/systemv/lpinfo.c index 65e9f3319f..0b33ff7e63 100644 --- a/systemv/lpinfo.c +++ b/systemv/lpinfo.c @@ -187,11 +187,7 @@ main(int argc, /* I - Number of command-line arguments */ switch (*opt) { case 'E' : /* Encrypt */ -#ifdef HAVE_TLS cupsSetEncryption(HTTP_ENCRYPT_REQUIRED); -#else - _cupsLangPrintf(stderr, _("%s: Sorry, no encryption support."), argv[0]); -#endif /* HAVE_TLS */ break; case 'h' : /* Connect to host */ diff --git a/systemv/lpmove.c b/systemv/lpmove.c index b330133d91..fad96f5f2c 100644 --- a/systemv/lpmove.c +++ b/systemv/lpmove.c @@ -63,12 +63,7 @@ main(int argc, /* I - Number of command-line arguments */ switch (*opt) { case 'E' : /* Encrypt */ -#ifdef HAVE_TLS cupsSetEncryption(HTTP_ENCRYPT_REQUIRED); - -#else - _cupsLangPrintf(stderr, _("%s: Sorry, no encryption support."), argv[0]); -#endif /* HAVE_TLS */ break; case 'h' : /* Connect to host */ diff --git a/systemv/lpstat.c b/systemv/lpstat.c index eb1258ac95..eb1531c1e9 100644 --- a/systemv/lpstat.c +++ b/systemv/lpstat.c @@ -85,13 +85,7 @@ main(int argc, /* I - Number of command-line arguments */ break; case 'E' : /* Encrypt */ -#ifdef HAVE_TLS cupsSetEncryption(HTTP_ENCRYPT_REQUIRED); -#else - _cupsLangPrintf(stderr, - _("%s: Sorry, no encryption support."), - argv[0]); -#endif /* HAVE_TLS */ break; case 'H' : /* Show server and port */ diff --git a/tools/ippeveprinter.c b/tools/ippeveprinter.c index 041a468ef7..47c477ef14 100644 --- a/tools/ippeveprinter.c +++ b/tools/ippeveprinter.c @@ -143,11 +143,7 @@ static const char * const ippeve_preason_strings[] = * URL scheme for web resources... */ -#ifdef HAVE_TLS -# define WEB_SCHEME "https" -#else -# define WEB_SCHEME "http" -#endif /* HAVE_TLS */ +#define WEB_SCHEME "https" /* @@ -387,9 +383,7 @@ main(int argc, /* I - Number of command-line args */ *device_uri = NULL, /* Device URI */ *output_format = NULL, /* Output format */ *icon = NULL, /* Icon file */ -#ifdef HAVE_TLS *keypath = NULL, /* Keychain path */ -#endif /* HAVE_TLS */ *location = "", /* Location of printer */ *make = "Example", /* Manufacturer */ *model = "Printer", /* Model */ @@ -476,7 +470,6 @@ main(int argc, /* I - Number of command-line args */ output_format = argv[i]; break; -#ifdef HAVE_TLS case 'K' : /* -K keypath */ i ++; if (i >= argc) @@ -484,7 +477,6 @@ main(int argc, /* I - Number of command-line args */ keypath = argv[i]; break; -#endif /* HAVE_TLS */ case 'M' : /* -M manufacturer */ i ++; @@ -726,9 +718,7 @@ main(int argc, /* I - Number of command-line args */ printer->ppdfile = strdup(ppdfile); #endif /* !CUPS_LITE */ -#ifdef HAVE_TLS cupsSetServerCredentials(keypath, printer->hostname, 1); -#endif /* HAVE_TLS */ /* * Run the print service... @@ -1579,12 +1569,9 @@ create_printer( { /* reference-uri-schemes-supported */ "file", "ftp", - "http" -#ifdef HAVE_TLS - , "https" -#endif /* HAVE_TLS */ + "http", + "https" }; -#ifdef HAVE_TLS static const char * const uri_authentication_supported[] = { /* uri-authentication-supported values */ "none", @@ -1600,7 +1587,6 @@ create_printer( "none", "tls" }; -#endif /* HAVE_TLS */ static const char * const which_jobs[] = { /* which-jobs-supported values */ "completed", @@ -1788,11 +1774,7 @@ create_printer( if (Verbosity) { -#ifdef HAVE_TLS fprintf(stderr, "printer-uri-supported=\"ipp://%s:%d/ipp/print\",\"ipps://%s:%d/ipp/print\"\n", printer->hostname, printer->port, printer->hostname, printer->port); -#else - fprintf(stderr, "printer-uri-supported=\"ipp://%s:%d/ipp/print\"\n", printer->hostname, printer->port); -#endif /* HAVE_TLS */ fprintf(stderr, "printer-uuid=\"%s\"\n", uuid); } @@ -1979,24 +1961,13 @@ create_printer( ippAddStrings(printer->attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_URISCHEME), "reference-uri-schemes-supported", (int)(sizeof(reference_uri_schemes_supported) / sizeof(reference_uri_schemes_supported[0])), NULL, reference_uri_schemes_supported); /* uri-authentication-supported */ -#ifdef HAVE_TLS if (PAMService) ippAddStrings(printer->attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "uri-authentication-supported", 2, NULL, uri_authentication_basic); else ippAddStrings(printer->attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "uri-authentication-supported", 2, NULL, uri_authentication_supported); -#else - if (PAMService) - ippAddString(printer->attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "uri-authentication-supported", NULL, "basic"); - else - ippAddString(printer->attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "uri-authentication-supported", NULL, "none"); -#endif /* HAVE_TLS */ /* uri-security-supported */ -#ifdef HAVE_TLS ippAddStrings(printer->attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "uri-security-supported", 2, NULL, uri_security_supported); -#else - ippAddString(printer->attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "uri-security-supported", NULL, "none"); -#endif /* HAVE_TLS */ /* which-jobs-supported */ ippAddStrings(printer->attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "which-jobs-supported", sizeof(which_jobs) / sizeof(which_jobs[0]), NULL, which_jobs); @@ -2585,11 +2556,7 @@ finish_document_uri( goto abort_job; } - if (strcmp(scheme, "file") && -#ifdef HAVE_TLS - strcmp(scheme, "https") && -#endif /* HAVE_TLS */ - strcmp(scheme, "http")) + if (strcmp(scheme, "file") && strcmp(scheme, "https") && strcmp(scheme, "http")) { respond_ipp(client, IPP_STATUS_ERROR_URI_SCHEME, "URI scheme \"%s\" not supported.", scheme); @@ -2666,12 +2633,10 @@ finish_document_uri( } else { -#ifdef HAVE_TLS if (port == 443 || !strcmp(scheme, "https")) encryption = HTTP_ENCRYPTION_ALWAYS; else -#endif /* HAVE_TLS */ - encryption = HTTP_ENCRYPTION_IF_REQUESTED; + encryption = HTTP_ENCRYPTION_IF_REQUESTED; if ((http = httpConnect2(hostname, port, NULL, AF_UNSPEC, encryption, 1, 30000, NULL)) == NULL) { @@ -3726,10 +3691,8 @@ ipp_get_printer_attributes( httpAssembleURI(HTTP_URI_CODING_ALL, uris[0], sizeof(uris[0]), "ipp", NULL, client->host_field, client->host_port, "/ipp/print"); values[num_values ++] = uris[0]; -#ifdef HAVE_TLS httpAssembleURI(HTTP_URI_CODING_ALL, uris[1], sizeof(uris[1]), "ipps", NULL, client->host_field, client->host_port, "/ipp/print"); values[num_values ++] = uris[1]; -#endif /* HAVE_TLS */ ippAddStrings(client->response, IPP_TAG_PRINTER, IPP_TAG_URI, "printer-uri-supported", num_values, NULL, values); } @@ -5816,13 +5779,11 @@ process_client(ippeve_client_t *client) /* I - Client */ * Loop until we are out of requests or timeout (30 seconds)... */ -#ifdef HAVE_TLS int first_time = 1; /* First time request? */ -#endif /* HAVE_TLS */ + while (httpWait(client->http, 30000)) { -#ifdef HAVE_TLS if (first_time) { /* @@ -5846,7 +5807,6 @@ process_client(ippeve_client_t *client) /* I - Client */ first_time = 0; } -#endif /* HAVE_TLS */ if (!process_http(client)) break; @@ -6038,7 +5998,6 @@ process_http(ippeve_client_t *client) /* I - Client connection */ if (!strcasecmp(httpGetField(client->http, HTTP_FIELD_CONNECTION), "Upgrade")) { -#ifdef HAVE_TLS if (strstr(httpGetField(client->http, HTTP_FIELD_UPGRADE), "TLS/") != NULL && !httpIsEncrypted(client->http)) { if (!respond_http(client, HTTP_STATUS_SWITCHING_PROTOCOLS, NULL, NULL, 0)) @@ -6054,10 +6013,7 @@ process_http(ippeve_client_t *client) /* I - Client connection */ fprintf(stderr, "%s Connection now encrypted.\n", client->hostname); } - else -#endif /* HAVE_TLS */ - - if (!respond_http(client, HTTP_STATUS_NOT_IMPLEMENTED, NULL, NULL, 0)) + else if (!respond_http(client, HTTP_STATUS_NOT_IMPLEMENTED, NULL, NULL, 0)) return (0); } @@ -7280,9 +7236,7 @@ register_printer( TXTRecordSetValue(&ipp_txt, "Duplex", 1, ippGetCount(sides_supported) > 1 ? "T" : "F"); if ((value = ippGetString(printer_uuid, 0, NULL)) != NULL) TXTRecordSetValue(&ipp_txt, "UUID", (uint8_t)strlen(value) - 9, value + 9); -# ifdef HAVE_TLS - TXTRecordSetValue(&ipp_txt, "TLS", 3, "1.2"); -# endif /* HAVE_TLS */ + TXTRecordSetValue(&ipp_txt, "TLS", 3, "1.3"); if (urf[0]) TXTRecordSetValue(&ipp_txt, "URF", (uint8_t)strlen(urf), urf); TXTRecordSetValue(&ipp_txt, "txtvers", 1, "1"); @@ -7327,7 +7281,6 @@ register_printer( return (0); } -# ifdef HAVE_TLS /* * Then register the _ipps._tcp (IPP) service type with the real port number to * advertise our IPPS printer... @@ -7348,7 +7301,6 @@ register_printer( _cupsLangPrintf(stderr, _("Unable to register \"%s.%s\": %d"), printer->dnssd_name, regtype, error); return (0); } -# endif /* HAVE_TLS */ /* * Similarly, register the _http._tcp,_printer (HTTP) service type with the @@ -7387,9 +7339,7 @@ register_printer( ipp_txt = avahi_string_list_add_printf(ipp_txt, "Duplex=%s", ippGetCount(sides_supported) > 1 ? "T" : "F"); if ((value = ippGetString(printer_uuid, 0, NULL)) != NULL) ipp_txt = avahi_string_list_add_printf(ipp_txt, "UUID=%s", value + 9); -# ifdef HAVE_TLS ipp_txt = avahi_string_list_add_printf(ipp_txt, "TLS=1.2"); -# endif /* HAVE_TLS */ if (urf[0]) ipp_txt = avahi_string_list_add_printf(ipp_txt, "URF=%s", urf); ipp_txt = avahi_string_list_add_printf(ipp_txt, "txtvers=1"); @@ -7431,7 +7381,6 @@ register_printer( free(temptypes); } -#ifdef HAVE_TLS /* * _ipps._tcp (IPPS) for secure printing... */ @@ -7454,7 +7403,6 @@ register_printer( free(temptypes); } -#endif /* HAVE_TLS */ /* * Finally _http.tcp (HTTP) for the web interface... @@ -7869,7 +7817,7 @@ show_media(ippeve_client_t *client) /* I - Client connection */ /* * Make sure the number of trays is consistent. */ - + if (num_sources != ippGetCount(input_tray)) { html_printf(client, "

Error: Different number of trays in media-source-supported and printer-input-tray defined for printer.

\n"); @@ -8444,9 +8392,7 @@ usage(int status) /* O - Exit status */ _cupsLangPuts(stdout, _("-A Enable authentication")); _cupsLangPuts(stdout, _("-D device-uri Set the device URI for the printer")); _cupsLangPuts(stdout, _("-F output-type/subtype Set the output format for the printer")); -#ifdef HAVE_TLS _cupsLangPuts(stdout, _("-K keypath Set location of server X.509 certificates and keys.")); -#endif /* HAVE_TLS */ _cupsLangPuts(stdout, _("-M manufacturer Set manufacturer name (default=Test)")); #if !CUPS_LITE _cupsLangPuts(stdout, _("-P filename.ppd Load printer attributes from PPD file")); diff --git a/tools/ipptool.c b/tools/ipptool.c index 98f6657fab..0c5754ce68 100644 --- a/tools/ipptool.c +++ b/tools/ipptool.c @@ -342,12 +342,7 @@ main(int argc, /* I - Number of command-line args */ break; case 'E' : /* Encrypt with TLS */ -#ifdef HAVE_TLS data.encryption = HTTP_ENCRYPT_REQUIRED; -#else - _cupsLangPrintf(stderr, _("%s: Sorry, no encryption support."), - argv[0]); -#endif /* HAVE_TLS */ break; case 'I' : /* Ignore errors */ @@ -390,11 +385,7 @@ main(int argc, /* I - Number of command-line args */ break; case 'S' : /* Encrypt with SSL */ -#ifdef HAVE_TLS data.encryption = HTTP_ENCRYPT_ALWAYS; -#else - _cupsLangPrintf(stderr, _("%s: Sorry, no encryption support."), "ipptool"); -#endif /* HAVE_TLS */ break; case 'T' : /* Set timeout */ @@ -641,11 +632,7 @@ main(int argc, /* I - Number of command-line args */ } } } - else if (!strncmp(argv[i], "ipp://", 6) || !strncmp(argv[i], "http://", 7) -#ifdef HAVE_TLS - || !strncmp(argv[i], "ipps://", 7) || !strncmp(argv[i], "https://", 8) -#endif /* HAVE_TLS */ - ) + else if (!strncmp(argv[i], "ipp://", 6) || !strncmp(argv[i], "http://", 7) || !strncmp(argv[i], "ipps://", 7) || !strncmp(argv[i], "https://", 8)) { /* * Set URI... @@ -657,10 +644,8 @@ main(int argc, /* I - Number of command-line args */ usage(); } -#ifdef HAVE_TLS if (!strncmp(argv[i], "ipps://", 7) || !strncmp(argv[i], "https://", 8)) data.encryption = HTTP_ENCRYPT_ALWAYS; -#endif /* HAVE_TLS */ if (!_ippVarsSet(data.vars, "uri", argv[i])) { @@ -3870,7 +3855,7 @@ print_json_attr( } -/* +/* * 'print_json_string()' - Print a string in JSON format. */ diff --git a/vcnet/config.h b/vcnet/config.h index d4bd0ed7db..2b347ab851 100644 --- a/vcnet/config.h +++ b/vcnet/config.h @@ -385,7 +385,6 @@ typedef unsigned long useconds_t; * Which encryption libraries do we have? */ -#define HAVE_TLS 1 #define HAVE_OPENSSL 1 /* #undef HAVE_GNUTLS */ diff --git a/xcode/CUPS.xcodeproj/project.pbxproj b/xcode/CUPS.xcodeproj/project.pbxproj index 597946440b..ae3d16bf5b 100644 --- a/xcode/CUPS.xcodeproj/project.pbxproj +++ b/xcode/CUPS.xcodeproj/project.pbxproj @@ -3168,7 +3168,6 @@ /* Begin PBXFileReference section */ 2706965A1CADF3E200FFE5FB /* libcups_ios.a */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libcups_ios.a; sourceTree = BUILT_PRODUCTS_DIR; }; - 270B267D17F5C06700C8A3A9 /* tls-darwin.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = "tls-darwin.c"; path = "../cups/tls-darwin.c"; sourceTree = ""; }; 270B267E17F5C06700C8A3A9 /* tls-gnutls.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = "tls-gnutls.c"; path = "../cups/tls-gnutls.c"; sourceTree = ""; }; 270B268117F5C5D600C8A3A9 /* tls-sspi.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = "tls-sspi.c"; path = "../cups/tls-sspi.c"; sourceTree = ""; }; 270CCDA7135E3C9E00007BE2 /* testmime */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testmime; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -3311,7 +3310,6 @@ 27D3037D134148CB00F022B1 /* libcups2.def */ = {isa = PBXFileReference; lastKnownFileType = text; name = libcups2.def; path = ../cups/libcups2.def; sourceTree = ""; }; 27F89DA21B3AC43B00E5A4B7 /* testraster.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = testraster.c; path = ../cups/testraster.c; sourceTree = ""; }; 27F9A76D28CBFC03002CCEE0 /* tls-openssl.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = "tls-openssl.c"; path = "../cups/tls-openssl.c"; sourceTree = ""; }; - 27F9A76E28CBFC03002CCEE0 /* tls-darwin.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "tls-darwin.h"; path = "../cups/tls-darwin.h"; sourceTree = ""; }; 720DD6C21358FD5F0064AA82 /* snmp */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = snmp; sourceTree = BUILT_PRODUCTS_DIR; }; 720DD6D21358FDDE0064AA82 /* snmp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = snmp.c; path = ../backend/snmp.c; sourceTree = ""; }; 720E854120164E7A00C6C411 /* ipp-file.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "ipp-file.c"; path = "../cups/ipp-file.c"; sourceTree = ""; }; @@ -4993,8 +4991,6 @@ 72220F02133305BB00FCA411 /* string.c */, 72220F03133305BB00FCA411 /* tempfile.c */, 72220F05133305BB00FCA411 /* thread.c */, - 27F9A76E28CBFC03002CCEE0 /* tls-darwin.h */, - 270B267D17F5C06700C8A3A9 /* tls-darwin.c */, 270B267E17F5C06700C8A3A9 /* tls-gnutls.c */, 27F9A76D28CBFC03002CCEE0 /* tls-openssl.c */, 270B268117F5C5D600C8A3A9 /* tls-sspi.c */, @@ -11766,6 +11762,7 @@ DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = c99; GCC_NO_COMMON_BLOCKS = YES; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES; @@ -11831,6 +11828,7 @@ DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = c99; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES; diff --git a/xcode/config.h b/xcode/config.h index 294d25c4da..62e0baebf5 100644 --- a/xcode/config.h +++ b/xcode/config.h @@ -306,7 +306,6 @@ * Which encryption libraries do we have? */ -#define HAVE_TLS 1 #define HAVE_OPENSSL 1 /* #undef HAVE_GNUTLS */