<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[15217] CalendarServer/trunk</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.calendarserver.org//changeset/15217">15217</a></dd>
<dt>Author</dt> <dd>cdaboo@apple.com</dd>
<dt>Date</dt> <dd>2015-10-23 12:37:48 -0700 (Fri, 23 Oct 2015)</dd>
</dl>
<h3>Log Message</h3>
<pre>Support for pySecureTransport in addition to pyOpenSSL.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#CalendarServertrunkbin_buildsh">CalendarServer/trunk/bin/_build.sh</a></li>
<li><a href="#CalendarServertrunkcalendarserverpushapplepushpy">CalendarServer/trunk/calendarserver/push/applepush.py</a></li>
<li><a href="#CalendarServertrunkcalendarserverpushutilpy">CalendarServer/trunk/calendarserver/push/util.py</a></li>
<li><a href="#CalendarServertrunkcalendarservertapcaldavpy">CalendarServer/trunk/calendarserver/tap/caldav.py</a></li>
<li><a href="#CalendarServertrunkcalendarservertaputilpy">CalendarServer/trunk/calendarserver/tap/util.py</a></li>
<li><a href="#CalendarServertrunkconfcaldavdappleplist">CalendarServer/trunk/conf/caldavd-apple.plist</a></li>
<li><a href="#CalendarServertrunkconfcaldavdtestplist">CalendarServer/trunk/conf/caldavd-test.plist</a></li>
<li><a href="#CalendarServertrunkconflocalserverstestxml">CalendarServer/trunk/conf/localservers-test.xml</a></li>
<li><a href="#CalendarServertrunkrequirementsdevtxt">CalendarServer/trunk/requirements-dev.txt</a></li>
<li><a href="#CalendarServertrunksetuppy">CalendarServer/trunk/setup.py</a></li>
<li><a href="#CalendarServertrunksupport_cache_deps">CalendarServer/trunk/support/_cache_deps</a></li>
<li><a href="#CalendarServertrunktwistedcaldavclientpoolpy">CalendarServer/trunk/twistedcaldav/client/pool.py</a></li>
<li><a href="#CalendarServertrunktwistedcaldavstdconfigpy">CalendarServer/trunk/twistedcaldav/stdconfig.py</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li>CalendarServer/trunk/lib-patches/Twisted/</li>
<li><a href="#CalendarServertrunklibpatchesTwistedsecuretransportpatch">CalendarServer/trunk/lib-patches/Twisted/securetransport.patch</a></li>
<li><a href="#CalendarServertrunkrequirementscstxt">CalendarServer/trunk/requirements-cs.txt</a></li>
<li><a href="#CalendarServertrunkrequirementsdefaulttxt">CalendarServer/trunk/requirements-default.txt</a></li>
<li><a href="#CalendarServertrunkrequirementsosxtxt">CalendarServer/trunk/requirements-osx.txt</a></li>
<li><a href="#CalendarServertrunkrequirementstwisteddefaulttxt">CalendarServer/trunk/requirements-twisted-default.txt</a></li>
<li><a href="#CalendarServertrunkrequirementstwistedosxtxt">CalendarServer/trunk/requirements-twisted-osx.txt</a></li>
</ul>
<h3>Removed Paths</h3>
<ul>
<li><a href="#CalendarServertrunkrequirementsstabletxt">CalendarServer/trunk/requirements-stable.txt</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="CalendarServertrunkbin_buildsh"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/bin/_build.sh (15216 => 15217)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/bin/_build.sh        2015-10-23 19:26:11 UTC (rev 15216)
+++ CalendarServer/trunk/bin/_build.sh        2015-10-23 19:37:48 UTC (rev 15217)
</span><span class="lines">@@ -92,7 +92,6 @@
</span><span class="cx"> conditional_set do_get "true";
</span><span class="cx"> conditional_set do_setup "true";
</span><span class="cx"> conditional_set force_setup "false";
</span><del>- conditional_set requirements "${wd}/requirements-dev.txt"
</del><span class="cx"> conditional_set virtualenv_opts "";
</span><span class="cx">
</span><span class="cx"> dev_home="${wd}/.develop";
</span><span class="lines">@@ -159,6 +158,19 @@
</span><span class="cx"> else
</span><span class="cx"> hash () { echo "INTERNAL ERROR: No hash function."; exit 1; }
</span><span class="cx"> fi;
</span><ins>+
+ default_requirements="${wd}/requirements-default.txt";
+ use_openssl="true"
+ if [ -z "${USE_OPENSSL-}" ]; then
+ case "$(uname -s)" in
+ Darwin)
+ default_requirements="${wd}/requirements-osx.txt";
+         use_openssl="false"
+ ;;
+ esac;
+ fi;
+ conditional_set requirements "${default_requirements}"
+
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx">
</span><span class="lines">@@ -475,27 +487,29 @@
</span><span class="cx">
</span><span class="cx"> # The OpenSSL version number is special. Our strategy is to get the integer
</span><span class="cx"> # value of OPENSSL_VERSION_NUBMER for use in inequality comparison.
</span><del>- ruler;
</del><ins>+ if [ ${use_openssl} == "true" ]; then
+ ruler;
</ins><span class="cx">
</span><del>- local min_ssl_version="9470463"; # OpenSSL 0.9.8zf
</del><ins>+ local min_ssl_version="9470463"; # OpenSSL 0.9.8zf
</ins><span class="cx">
</span><del>- local ssl_version="$(c_macro openssl/ssl.h OPENSSL_VERSION_NUMBER)";
- if [ -z "${ssl_version}" ]; then ssl_version="0x0"; fi;
- ssl_version="$("${bootstrap_python}" -c "print ${ssl_version}")";
</del><ins>+ local ssl_version="$(c_macro openssl/ssl.h OPENSSL_VERSION_NUMBER)";
+ if [ -z "${ssl_version}" ]; then ssl_version="0x0"; fi;
+ ssl_version="$("${bootstrap_python}" -c "print ${ssl_version}")";
</ins><span class="cx">
</span><del>- if [ "${ssl_version}" -ge "${min_ssl_version}" ]; then
- using_system "OpenSSL";
- else
- local v="0.9.8zf";
- local n="openssl";
- local p="${n}-${v}";
</del><ins>+ if [ "${ssl_version}" -ge "${min_ssl_version}" ]; then
+ using_system "OpenSSL";
+ else
+ local v="0.9.8zf";
+ local n="openssl";
+ local p="${n}-${v}";
</ins><span class="cx">
</span><del>- # use 'config' instead of 'configure'; 'make' instead of 'jmake'.
- # also pass 'shared' to config to build shared libs.
- c_dependency -c "config" -m "c69a4a679233f7df189e1ad6659511ec" \
- -p "make depend" -b "make" \
- "openssl" "${p}" \
- "http://www.openssl.org/source/${p}.tar.gz" "shared";
</del><ins>+ # use 'config' instead of 'configure'; 'make' instead of 'jmake'.
+ # also pass 'shared' to config to build shared libs.
+ c_dependency -c "config" -m "c69a4a679233f7df189e1ad6659511ec" \
+ -p "make depend" -b "make" \
+ "openssl" "${p}" \
+ "http://www.openssl.org/source/${p}.tar.gz" "shared";
+ fi;
</ins><span class="cx"> fi;
</span><span class="cx">
</span><span class="cx">
</span><span class="lines">@@ -689,7 +703,14 @@
</span><span class="cx"> fi;
</span><span class="cx"> done;
</span><span class="cx">
</span><ins>+ ruler "Patching Python requirements";
</ins><span class="cx"> echo "";
</span><ins>+ if [ ! -e "${dev_patches}/Twisted" ]; then
+         apply_patches "Twisted" "${py_virtualenv}/lib/python2.7/site-packages"
+         touch "${dev_patches}/Twisted";
+ fi;
+
+ echo "";
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx">
</span></span></pre></div>
<a id="CalendarServertrunkcalendarserverpushapplepushpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/push/applepush.py (15216 => 15217)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/push/applepush.py        2015-10-23 19:26:11 UTC (rev 15216)
+++ CalendarServer/trunk/calendarserver/push/applepush.py        2015-10-23 19:37:48 UTC (rev 15217)
</span><span class="lines">@@ -124,6 +124,7 @@
</span><span class="cx"> settings[protocol]["PrivateKeyPath"],
</span><span class="cx"> chainPath=settings[protocol]["AuthorityChainPath"],
</span><span class="cx"> passphrase=settings[protocol]["Passphrase"],
</span><ins>+ keychainIdentity=settings[protocol]["KeychainIdentity"],
</ins><span class="cx"> staggerNotifications=settings["EnableStaggering"],
</span><span class="cx"> staggerSeconds=settings["StaggerSeconds"],
</span><span class="cx"> testConnector=providerTestConnector,
</span><span class="lines">@@ -144,6 +145,7 @@
</span><span class="cx"> settings[protocol]["PrivateKeyPath"],
</span><span class="cx"> chainPath=settings[protocol]["AuthorityChainPath"],
</span><span class="cx"> passphrase=settings[protocol]["Passphrase"],
</span><ins>+ keychainIdentity=settings[protocol]["KeychainIdentity"],
</ins><span class="cx"> testConnector=feedbackTestConnector,
</span><span class="cx"> reactor=reactor,
</span><span class="cx"> )
</span><span class="lines">@@ -511,7 +513,7 @@
</span><span class="cx">
</span><span class="cx"> def __init__(
</span><span class="cx"> self, host, port, certPath, keyPath, chainPath="",
</span><del>- passphrase="", sslMethod="TLSv1_METHOD", testConnector=None,
</del><ins>+ passphrase="", keychainIdentity="", sslMethod="TLSv1_METHOD", testConnector=None,
</ins><span class="cx"> reactor=None
</span><span class="cx"> ):
</span><span class="cx">
</span><span class="lines">@@ -521,6 +523,7 @@
</span><span class="cx"> self.keyPath = keyPath
</span><span class="cx"> self.chainPath = chainPath
</span><span class="cx"> self.passphrase = passphrase
</span><ins>+ self.keychainIdentity = keychainIdentity
</ins><span class="cx"> self.sslMethod = sslMethod
</span><span class="cx"> self.testConnector = testConnector
</span><span class="cx">
</span><span class="lines">@@ -543,6 +546,7 @@
</span><span class="cx"> self.certPath,
</span><span class="cx"> certificateChainFile=self.chainPath,
</span><span class="cx"> passwdCallback=passwdCallback,
</span><ins>+ keychainIdentity=self.keychainIdentity,
</ins><span class="cx"> sslmethod=getattr(OpenSSL.SSL, self.sslMethod)
</span><span class="cx"> )
</span><span class="cx"> connect(GAIEndpoint(self.reactor, self.host, self.port, context),
</span><span class="lines">@@ -554,14 +558,15 @@
</span><span class="cx">
</span><span class="cx"> def __init__(
</span><span class="cx"> self, store, host, port, certPath, keyPath, chainPath="",
</span><del>- passphrase="", sslMethod="TLSv1_METHOD",
</del><ins>+ passphrase="", keychainIdentity="", sslMethod="TLSv1_METHOD",
</ins><span class="cx"> staggerNotifications=False, staggerSeconds=3,
</span><span class="cx"> testConnector=None, reactor=None
</span><span class="cx"> ):
</span><span class="cx">
</span><span class="cx"> APNConnectionService.__init__(
</span><span class="cx"> self, host, port, certPath, keyPath,
</span><del>- chainPath=chainPath, passphrase=passphrase, sslMethod=sslMethod,
</del><ins>+ chainPath=chainPath, passphrase=passphrase,
+ keychainIdentity=keychainIdentity, sslMethod=sslMethod,
</ins><span class="cx"> testConnector=testConnector, reactor=reactor)
</span><span class="cx">
</span><span class="cx"> self.store = store
</span><span class="lines">@@ -775,13 +780,15 @@
</span><span class="cx">
</span><span class="cx"> def __init__(
</span><span class="cx"> self, store, updateSeconds, host, port,
</span><del>- certPath, keyPath, chainPath="", passphrase="", sslMethod="TLSv1_METHOD",
</del><ins>+ certPath, keyPath, chainPath="",
+ passphrase="", keychainIdentity="", sslMethod="TLSv1_METHOD",
</ins><span class="cx"> testConnector=None, reactor=None
</span><span class="cx"> ):
</span><span class="cx">
</span><span class="cx"> APNConnectionService.__init__(
</span><span class="cx"> self, host, port, certPath, keyPath,
</span><del>- chainPath=chainPath, passphrase=passphrase, sslMethod=sslMethod,
</del><ins>+ chainPath=chainPath, passphrase=passphrase,
+ keychainIdentity=keychainIdentity, sslMethod=sslMethod,
</ins><span class="cx"> testConnector=testConnector, reactor=reactor)
</span><span class="cx">
</span><span class="cx"> self.store = store
</span></span></pre></div>
<a id="CalendarServertrunkcalendarserverpushutilpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/push/util.py (15216 => 15217)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/push/util.py        2015-10-23 19:26:11 UTC (rev 15216)
+++ CalendarServer/trunk/calendarserver/push/util.py        2015-10-23 19:37:48 UTC (rev 15217)
</span><span class="lines">@@ -41,7 +41,34 @@
</span><span class="cx"> @return: C{str} topic, or empty string if value is not found
</span><span class="cx"> """
</span><span class="cx"> certData = open(certPath).read()
</span><del>- x509 = crypto.load_certificate(crypto.FILETYPE_PEM, certData)
</del><ins>+ return getAPNTopicFromX509(crypto.load_certificate(crypto.FILETYPE_PEM, certData))
+
+
+
+def getAPNTopicFromIdentity(identity):
+ """
+ Given a keychain identity certificate, extract the UID value portion of the
+ subject, which in this context is used for the associated APN topic.
+
+ @param identity: keychain identity to lookup
+ @type identity: C{str}
+
+ @return: C{str} topic, or empty string if value is not found
+ """
+ return getAPNTopicFromX509(crypto.load_certificate(None, identity))
+
+
+
+def getAPNTopicFromX509(x509):
+ """
+ Given an L{X509} certificate, extract the UID value portion of the
+ subject, which in this context is used for the associated APN topic.
+
+ @param x509: the certificate
+ @type x509: L{X509}
+
+ @return: C{str} topic, or empty string if value is not found
+ """
</ins><span class="cx"> subject = x509.get_subject()
</span><span class="cx"> components = subject.get_components()
</span><span class="cx"> for name, value in components:
</span></span></pre></div>
<a id="CalendarServertrunkcalendarservertapcaldavpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/tap/caldav.py (15216 => 15217)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/tap/caldav.py        2015-10-23 19:26:11 UTC (rev 15216)
+++ CalendarServer/trunk/calendarserver/tap/caldav.py        2015-10-23 19:37:48 UTC (rev 15217)
</span><span class="lines">@@ -835,6 +835,7 @@
</span><span class="cx"> config.SSLCertificate,
</span><span class="cx"> certificateChainFile=config.SSLAuthorityChain,
</span><span class="cx"> passwdCallback=getSSLPassphrase,
</span><ins>+ keychainIdentity=config.SSLKeychainIdentity,
</ins><span class="cx"> sslmethod=getattr(OpenSSL.SSL, config.SSLMethod),
</span><span class="cx"> ciphers=config.SSLCiphers.strip(),
</span><span class="cx"> verifyClient=config.Authentication.ClientCertificate.Enabled,
</span></span></pre></div>
<a id="CalendarServertrunkcalendarservertaputilpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/tap/util.py (15216 => 15217)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/tap/util.py        2015-10-23 19:26:11 UTC (rev 15216)
+++ CalendarServer/trunk/calendarserver/tap/util.py        2015-10-23 19:37:48 UTC (rev 15217)
</span><span class="lines">@@ -33,7 +33,7 @@
</span><span class="cx"> from calendarserver.provision.root import RootResource
</span><span class="cx"> from calendarserver.push.applepush import APNSubscriptionResource
</span><span class="cx"> from calendarserver.push.notifier import NotifierFactory
</span><del>-from calendarserver.push.util import getAPNTopicFromCertificate
</del><ins>+from calendarserver.push.util import getAPNTopicFromCertificate, getAPNTopicFromIdentity
</ins><span class="cx"> from calendarserver.tools import diagnose
</span><span class="cx"> from calendarserver.tools.util import checkDirectory
</span><span class="cx"> from calendarserver.webadmin.landing import WebAdminLandingResource
</span><span class="lines">@@ -1301,7 +1301,18 @@
</span><span class="cx"> and that it's valid.
</span><span class="cx"> """
</span><span class="cx">
</span><del>- if config.SSLCertificate:
</del><ins>+ if hasattr(OpenSSL, "__SecureTransport__"):
+ if config.SSLKeychainIdentity:
+ # Fall through to see if we can load the identity from the keychain
+ certificate_title = "Keychain: {}".format(config.SSLKeychainIdentity)
+ else:
+ message = (
+ "No Keychain Identity was set for TLS"
+ )
+ postAlert("MissingKeychainIdentityAlert", [])
+ return False, message
+
+ elif config.SSLCertificate:
</ins><span class="cx"> if not os.path.exists(config.SSLCertificate):
</span><span class="cx"> message = (
</span><span class="cx"> "The configured TLS certificate ({cert}) is missing".format(
</span><span class="lines">@@ -1310,34 +1321,44 @@
</span><span class="cx"> )
</span><span class="cx"> postAlert("MissingCertificateAlert", ["path", config.SSLCertificate])
</span><span class="cx"> return False, message
</span><ins>+
+ length = os.stat(config.SSLCertificate).st_size
+ if length == 0:
+ message = (
+ "The configured TLS certificate ({cert}) is empty".format(
+ cert=config.SSLCertificate
+ )
+ )
+ return False, message
+ certificate_title = config.SSLCertificate
</ins><span class="cx"> else:
</span><span class="cx"> return True, "TLS disabled"
</span><span class="cx">
</span><del>- length = os.stat(config.SSLCertificate).st_size
- if length == 0:
- message = (
- "The configured TLS certificate ({cert}) is empty".format(
- cert=config.SSLCertificate
- )
- )
- return False, message
-
</del><span class="cx"> try:
</span><span class="cx"> ChainingOpenSSLContextFactory(
</span><span class="cx"> config.SSLPrivateKey,
</span><span class="cx"> config.SSLCertificate,
</span><span class="cx"> certificateChainFile=config.SSLAuthorityChain,
</span><span class="cx"> passwdCallback=getSSLPassphrase,
</span><ins>+ keychainIdentity=config.SSLKeychainIdentity,
</ins><span class="cx"> sslmethod=getattr(OpenSSL.SSL, config.SSLMethod),
</span><span class="cx"> ciphers=config.SSLCiphers.strip()
</span><span class="cx"> )
</span><span class="cx"> except Exception as e:
</span><del>- message = (
- "The configured TLS certificate ({cert}) cannot be used: {reason}".format(
- cert=config.SSLCertificate,
- reason=str(e)
</del><ins>+ if hasattr(OpenSSL, "__SecureTransport__"):
+ message = (
+ "The configured TLS Keychain Identity ({cert}) cannot be used: {reason}".format(
+ cert=certificate_title,
+ reason=str(e)
+ )
</ins><span class="cx"> )
</span><del>- )
</del><ins>+ else:
+ message = (
+ "The configured TLS certificate ({cert}) cannot be used: {reason}".format(
+ cert=certificate_title,
+ reason=str(e)
+ )
+ )
</ins><span class="cx"> return False, message
</span><span class="cx">
</span><span class="cx"> return True, "TLS enabled"
</span><span class="lines">@@ -1358,39 +1379,62 @@
</span><span class="cx"> protoConfig = config.Notifications.Services.APNS[protocol]
</span><span class="cx">
</span><span class="cx"> # Verify the cert exists
</span><del>- if not os.path.exists(protoConfig.CertificatePath):
- message = (
- "The {proto} APNS certificate ({cert}) is missing".format(
- proto=protocol,
- cert=protoConfig.CertificatePath
</del><ins>+ if hasattr(OpenSSL, "__SecureTransport__"):
+ if protoConfig.KeychainIdentity:
+ # Verify we can extract the topic
+ if not protoConfig.Topic:
+ topic = getAPNTopicFromIdentity(protoConfig.KeychainIdentity)
+ protoConfig.Topic = topic
+ if not protoConfig.Topic:
+ postAlert("PushNotificationKeychainIdentityAlert", [])
+ message = "Cannot extract APN topic"
+ return False, message
+
+ # Fall through to see if we can load the identity from the keychain
+ certificate_title = "Keychain: {}".format(protoConfig.KeychainIdentity)
+ else:
+ message = (
+ "No {proto} APNS Keychain Identity was set".format(
+ proto=protocol,
+ )
</ins><span class="cx"> )
</span><del>- )
- postAlert("PushNotificationCertificateAlert", [])
- return False, message
</del><ins>+ postAlert("MissingKeychainIdentityAlert", [])
+ return False, message
</ins><span class="cx">
</span><del>- # Verify we can extract the topic
- if not protoConfig.Topic:
- topic = getAPNTopicFromCertificate(protoConfig.CertificatePath)
- protoConfig.Topic = topic
- if not protoConfig.Topic:
- postAlert("PushNotificationCertificateAlert", [])
- message = "Cannot extract APN topic"
- return False, message
</del><ins>+ else:
+ if not os.path.exists(protoConfig.CertificatePath):
+ message = (
+ "The {proto} APNS certificate ({cert}) is missing".format(
+ proto=protocol,
+ cert=protoConfig.CertificatePath
+ )
+ )
+ postAlert("PushNotificationCertificateAlert", [])
+ return False, message
</ins><span class="cx">
</span><del>- # Verify we can acquire the passphrase
- if not protoConfig.Passphrase:
- try:
- passphrase = getPasswordFromKeychain(accountName)
- protoConfig.Passphrase = passphrase
- except KeychainAccessError:
- # The system doesn't support keychain
- pass
- except KeychainPasswordNotFound:
- # The password doesn't exist in the keychain.
</del><ins>+ # Verify we can extract the topic
+ if not protoConfig.Topic:
+ topic = getAPNTopicFromCertificate(protoConfig.CertificatePath)
+ protoConfig.Topic = topic
+ if not protoConfig.Topic:
</ins><span class="cx"> postAlert("PushNotificationCertificateAlert", [])
</span><del>- message = "Cannot retrieve APN passphrase from keychain"
</del><ins>+ message = "Cannot extract APN topic"
</ins><span class="cx"> return False, message
</span><span class="cx">
</span><ins>+ # Verify we can acquire the passphrase
+ if not protoConfig.Passphrase:
+ try:
+ passphrase = getPasswordFromKeychain(accountName)
+ protoConfig.Passphrase = passphrase
+ except KeychainAccessError:
+ # The system doesn't support keychain
+ pass
+ except KeychainPasswordNotFound:
+ # The password doesn't exist in the keychain.
+ postAlert("PushNotificationCertificateAlert", [])
+ message = "Cannot retrieve APN passphrase from keychain"
+ return False, message
+
</ins><span class="cx"> # Let OpenSSL try to use the cert
</span><span class="cx"> try:
</span><span class="cx"> if protoConfig.Passphrase:
</span><span class="lines">@@ -1403,16 +1447,26 @@
</span><span class="cx"> protoConfig.CertificatePath,
</span><span class="cx"> certificateChainFile=protoConfig.AuthorityChainPath,
</span><span class="cx"> passwdCallback=passwdCallback,
</span><ins>+ keychainIdentity=protoConfig.KeychainIdentity,
</ins><span class="cx"> sslmethod=getattr(OpenSSL.SSL, "TLSv1_METHOD"),
</span><span class="cx"> )
</span><span class="cx"> except Exception as e:
</span><del>- message = (
- "The {proto} APNS certificate ({cert}) cannot be used: {reason}".format(
- proto=protocol,
- cert=protoConfig.CertificatePath,
- reason=str(e)
</del><ins>+ if hasattr(OpenSSL, "__SecureTransport__"):
+ message = (
+ "The {proto} APNS Keychain Identity ({cert}) cannot be used: {reason}".format(
+ proto=protocol,
+ cert=certificate_title,
+ reason=str(e)
+ )
</ins><span class="cx"> )
</span><del>- )
</del><ins>+ else:
+ message = (
+ "The {proto} APNS certificate ({cert}) cannot be used: {reason}".format(
+ proto=protocol,
+ cert=certificate_title,
+ reason=str(e)
+ )
+ )
</ins><span class="cx"> postAlert("PushNotificationCertificateAlert", [])
</span><span class="cx"> return False, message
</span><span class="cx">
</span></span></pre></div>
<a id="CalendarServertrunkconfcaldavdappleplist"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/conf/caldavd-apple.plist (15216 => 15217)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/conf/caldavd-apple.plist        2015-10-23 19:26:11 UTC (rev 15216)
+++ CalendarServer/trunk/conf/caldavd-apple.plist        2015-10-23 19:37:48 UTC (rev 15217)
</span><span class="lines">@@ -353,19 +353,11 @@
</span><span class="cx"> SSL/TLS
</span><span class="cx"> -->
</span><span class="cx">
</span><del>- <!-- Public key -->
- <key>SSLCertificate</key>
</del><ins>+ <!-- Keychain identity to use instead of cert files -->
+ <key>SSLKeychainIdentity</key>
</ins><span class="cx"> <string></string>
</span><span class="cx">
</span><del>- <!-- SSL authority chain (for intermediate certs) -->
- <key>SSLAuthorityChain</key>
- <string></string>
</del><span class="cx">
</span><del>- <!-- Private key -->
- <key>SSLPrivateKey</key>
- <string></string>
-
-
</del><span class="cx"> <!--
</span><span class="cx"> Process management
</span><span class="cx"> -->
</span></span></pre></div>
<a id="CalendarServertrunkconfcaldavdtestplist"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/conf/caldavd-test.plist (15216 => 15217)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/conf/caldavd-test.plist        2015-10-23 19:26:11 UTC (rev 15216)
+++ CalendarServer/trunk/conf/caldavd-test.plist        2015-10-23 19:37:48 UTC (rev 15217)
</span><span class="lines">@@ -573,7 +573,11 @@
</span><span class="cx"> <key>SSLPrivateKey</key>
</span><span class="cx"> <string>twistedcaldav/test/data/server.pem</string>
</span><span class="cx">
</span><ins>+ <!-- Keychain identity to use instead of cert files -->
+ <key>SSLKeychainIdentity</key>
+ <string>org.calendarserver.test</string>
</ins><span class="cx">
</span><ins>+
</ins><span class="cx"> <!--
</span><span class="cx"> Process management
</span><span class="cx"> -->
</span></span></pre></div>
<a id="CalendarServertrunkconflocalserverstestxml"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/conf/localservers-test.xml (15216 => 15217)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/conf/localservers-test.xml        2015-10-23 19:26:11 UTC (rev 15216)
+++ CalendarServer/trunk/conf/localservers-test.xml        2015-10-23 19:37:48 UTC (rev 15217)
</span><span class="lines">@@ -21,7 +21,7 @@
</span><span class="cx"> <servers>
</span><span class="cx"> <server>
</span><span class="cx"> <id>A</id>
</span><del>- <uri>http://localhost:8008</uri>
</del><ins>+ <uri>https://localhost:8443</uri>
</ins><span class="cx"> <allowed-from>127.0.0.1</allowed-from>
</span><span class="cx"> <allowed-from>::1</allowed-from>
</span><span class="cx"> <allowed-from>::ffff:127.0.0.1</allowed-from>
</span><span class="lines">@@ -29,7 +29,7 @@
</span><span class="cx"> </server>
</span><span class="cx"> <server>
</span><span class="cx"> <id>B</id>
</span><del>- <uri>http://localhost:8108</uri>
</del><ins>+ <uri>https://localhost:8543</uri>
</ins><span class="cx"> <allowed-from>127.0.0.1</allowed-from>
</span><span class="cx"> <allowed-from>::1</allowed-from>
</span><span class="cx"> <allowed-from>::ffff:127.0.0.1</allowed-from>
</span></span></pre></div>
<a id="CalendarServertrunklibpatchesTwistedsecuretransportpatch"></a>
<div class="addfile"><h4>Added: CalendarServer/trunk/lib-patches/Twisted/securetransport.patch (0 => 15217)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/lib-patches/Twisted/securetransport.patch         (rev 0)
+++ CalendarServer/trunk/lib-patches/Twisted/securetransport.patch        2015-10-23 19:37:48 UTC (rev 15217)
</span><span class="lines">@@ -0,0 +1,31 @@
</span><ins>+Index: twisted/internet/_sslverify.py
+===================================================================
+--- twisted/internet/_sslverify.py        (revision 45115)
++++ twisted/internet/_sslverify.py        (working copy)
+@@ -162,7 +162,9 @@
+
+ major, minor = list(int(part) for part in lib.__version__.split("."))[:2]
+
+- if (major, minor) >= (0, 12):
++ if hasattr(lib, "__SecureTransport__"):
++ pass
++ elif (major, minor) >= (0, 12):
+ try:
+ from service_identity import VerificationError
+ from service_identity.pyopenssl import verify_hostname
+
+Index: twisted/protocols/tls.py
+===================================================================
+--- twisted/protocols/tls.py        (revision 45115)
++++ twisted/protocols/tls.py        (working copy)
+@@ -660,7 +660,9 @@
+ @rtype: L{OpenSSL.SSL.Connection}
+ """
+ context = self._oldStyleContextFactory.getContext()
+- return Connection(context, None)
++ connection = Connection(context, None)
++ connection.set_app_data(protocol)
++ return connection
+
+
+ def serverConnectionForTLS(self, protocol):
</ins></span></pre></div>
<a id="CalendarServertrunkrequirementscstxt"></a>
<div class="addfile"><h4>Added: CalendarServer/trunk/requirements-cs.txt (0 => 15217)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/requirements-cs.txt         (rev 0)
+++ CalendarServer/trunk/requirements-cs.txt        2015-10-23 19:37:48 UTC (rev 15217)
</span><span class="lines">@@ -0,0 +1,39 @@
</span><ins>+##
+# Main CalendarServer dependency (does not include Twisted)
+##
+
+--editable . # calendarserver
+
+ zope.interface==4.1.2
+
+ --editable svn+http://svn.calendarserver.org/repository/calendarserver/twext/trunk@15216#egg=twextpy
+ #cffi==1.3.0
+ # pycparser==2.13
+ #twisted
+
+ # [LDAP] extra
+ python-ldap==2.4.19
+ #setuptools
+
+ # [DAL] extra
+ sqlparse==0.1.14 # Compat issue in 0.1.15; fix before updating
+
+ # [OpenDirectory] extra
+ #pyobjc-framework-OpenDirectory # Use system module
+
+ # [Postgres] extra
+ pg8000==1.10.2
+
+ # [Oracle] extra
+ #cx_Oracle==5.2 # Needs manual patch
+
+ --editable svn+http://svn.calendarserver.org/repository/calendarserver/PyKerberos/trunk@15140#egg=kerberos
+
+ --editable svn+http://svn.calendarserver.org/repository/calendarserver/PyCalendar/trunk@15020#egg=pycalendar
+ python-dateutil==1.5 # Note: v2.0+ is for Python 3
+ pytz==2015.4
+
+ psutil==2.2.1
+ setproctitle==1.1.8
+ # xattr==0.7.5 # Only needed for upgrades from ancient versions. Added in _cache_deps.
+ #cffi
</ins></span></pre></div>
<a id="CalendarServertrunkrequirementsdefaulttxt"></a>
<div class="addfile"><h4>Added: CalendarServer/trunk/requirements-default.txt (0 => 15217)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/requirements-default.txt         (rev 0)
+++ CalendarServer/trunk/requirements-default.txt        2015-10-23 19:37:48 UTC (rev 15217)
</span><span class="lines">@@ -0,0 +1,7 @@
</span><ins>+##
+# Set of dependencies for non-OS X systems.
+##
+
+--requirement requirements-cs.txt
+--requirement requirements-twisted-default.txt
+--requirement requirements-dev.txt
</ins></span></pre></div>
<a id="CalendarServertrunkrequirementsdevtxt"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/requirements-dev.txt (15216 => 15217)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/requirements-dev.txt        2015-10-23 19:26:11 UTC (rev 15216)
+++ CalendarServer/trunk/requirements-dev.txt        2015-10-23 19:37:48 UTC (rev 15217)
</span><span class="lines">@@ -1,6 +1,3 @@
</span><del>-# Get master requirements
---requirement requirements-stable.txt
-
</del><span class="cx"> # Additional dependencies for development and testing
</span><span class="cx"> pyflakes
</span><span class="cx"> docutils
</span></span></pre></div>
<a id="CalendarServertrunkrequirementsosxtxt"></a>
<div class="addfile"><h4>Added: CalendarServer/trunk/requirements-osx.txt (0 => 15217)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/requirements-osx.txt         (rev 0)
+++ CalendarServer/trunk/requirements-osx.txt        2015-10-23 19:37:48 UTC (rev 15217)
</span><span class="lines">@@ -0,0 +1,7 @@
</span><ins>+##
+# Set of dependencies for OS X systems.
+##
+
+--requirement requirements-cs.txt
+--requirement requirements-twisted-osx.txt
+--requirement requirements-dev.txt
</ins></span></pre></div>
<a id="CalendarServertrunkrequirementsstabletxt"></a>
<div class="delfile"><h4>Deleted: CalendarServer/trunk/requirements-stable.txt (15216 => 15217)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/requirements-stable.txt        2015-10-23 19:26:11 UTC (rev 15216)
+++ CalendarServer/trunk/requirements-stable.txt        2015-10-23 19:37:48 UTC (rev 15217)
</span><span class="lines">@@ -1,80 +0,0 @@
</span><del>-##
-#
-# Specify specific versions of our dependencies here.
-#
-##
-#
-# This defines the versions of dependencies that we are developing and
-# testing with.
-#
-# Other versions of dependencies are likely to work in most cases, but
-# here you can see what our automated builds are using, so this
-# combination is known to work.
-#
-##
-#
-# This file should contain every module in the output of:
-# ./bin/dependencies -a
-#
-##
-
---editable . # calendarserver
-
- zope.interface==4.1.2
-
- Twisted==15.2.1
- #zope.interface
-
- # NOTE: Twisted also uses pyOpenSSL, pycrypto and service_identity,
- # but doesn't specify them as dependencies, so that are explicitly
- # added to calendarserver.
- #pyOpenSSL
- service_identity==14.0.0
- characteristic==14.3.0
- pyasn1==0.1.7
- pyasn1-modules==0.0.5
- #pyOpenSSL
- pycrypto==2.6.1
-
- --editable svn+http://svn.calendarserver.org/repository/calendarserver/twext/trunk@15169#egg=twextpy
- cffi==1.1.0
- pycparser==2.13
- #twisted
-
- # [LDAP] extra
- python-ldap==2.4.19
- #setuptools
-
- # [DAL] extra
- sqlparse==0.1.14 # Compat issue in 0.1.15; fix before updating
-
- # [OpenDirectory] extra
- #pyobjc-framework-OpenDirectory # Use system module
-
- # [Postgres] extra
- pg8000==1.10.2
-
- # [Oracle] extra
- #cx_Oracle==5.2 # Needs manual patch
-
- pyOpenSSL==0.14
- cryptography==0.9
-         idna
- #pyasn1
- #cffi
- enum34==1.0.4
- ipaddress
- setuptools==17.0
- #six
- six==1.9.0
-
- --editable svn+http://svn.calendarserver.org/repository/calendarserver/PyKerberos/trunk@15140#egg=kerberos
-
- --editable svn+http://svn.calendarserver.org/repository/calendarserver/PyCalendar/trunk@15020#egg=pycalendar
- python-dateutil==1.5 # Note: v2.0+ is for Python 3
- pytz==2015.4
-
- psutil==2.2.1
- setproctitle==1.1.8
- # xattr==0.7.5 # Only needed for upgrades from ancient versions. Added in _cache_deps.
- #cffi
</del></span></pre></div>
<a id="CalendarServertrunkrequirementstwisteddefaulttxt"></a>
<div class="addfile"><h4>Added: CalendarServer/trunk/requirements-twisted-default.txt (0 => 15217)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/requirements-twisted-default.txt         (rev 0)
+++ CalendarServer/trunk/requirements-twisted-default.txt        2015-10-23 19:37:48 UTC (rev 15217)
</span><span class="lines">@@ -0,0 +1,29 @@
</span><ins>+##
+# Twisted dependency for non-OS X systems (uses pyOpenSSL).
+##
+
+
+Twisted==15.2.1
+ #zope.interface
+
+ # NOTE: Twisted also uses pyOpenSSL, pycrypto and service_identity,
+ # but doesn't specify them as dependencies, so that are explicitly
+ # added to calendarserver.
+ #pyOpenSSL
+ service_identity==14.0.0
+ characteristic==14.3.0
+ pyasn1==0.1.7
+ pyasn1-modules==0.0.5
+ #pyOpenSSL
+ pycrypto==2.6.1
+
+ pyOpenSSL==0.14
+ cryptography==0.9
+         idna
+ #pyasn1
+ #cffi
+ enum34==1.0.4
+ ipaddress
+ setuptools==17.0
+ #six
+ six==1.9.0
</ins></span></pre></div>
<a id="CalendarServertrunkrequirementstwistedosxtxt"></a>
<div class="addfile"><h4>Added: CalendarServer/trunk/requirements-twisted-osx.txt (0 => 15217)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/requirements-twisted-osx.txt         (rev 0)
+++ CalendarServer/trunk/requirements-twisted-osx.txt        2015-10-23 19:37:48 UTC (rev 15217)
</span><span class="lines">@@ -0,0 +1,14 @@
</span><ins>+##
+# Twisted dependency for OS X systems (uses pySecureTransport).
+##
+
+Twisted==15.2.1
+ #zope.interface
+ pycrypto==2.6.1
+
+ --editable svn+http://svn.calendarserver.org/repository/calendarserver/OSXFrameworks/trunk@15215#egg=osxframeworks
+ cffi==1.3.0
+ pycparser==2.13
+
+ --editable svn+http://svn.calendarserver.org/repository/calendarserver/PySecureTransport/trunk@15213#egg=pysecuretransport
+
</ins></span></pre></div>
<a id="CalendarServertrunksetuppy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/setup.py (15216 => 15217)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/setup.py        2015-10-23 19:26:11 UTC (rev 15216)
+++ CalendarServer/trunk/setup.py        2015-10-23 19:37:48 UTC (rev 15217)
</span><span class="lines">@@ -18,13 +18,13 @@
</span><span class="cx">
</span><span class="cx"> from __future__ import print_function
</span><span class="cx">
</span><del>-import os
</del><span class="cx"> from os.path import dirname, basename, abspath, join as joinpath, normpath
</span><del>-import subprocess
-
-import errno
</del><span class="cx"> from setuptools import setup, find_packages as setuptools_find_packages
</span><span class="cx"> from xml.etree import ElementTree
</span><ins>+import errno
+import os
+import subprocess
+import sys
</ins><span class="cx">
</span><span class="cx"> base_version = "8.0"
</span><span class="cx">
</span><span class="lines">@@ -326,8 +326,6 @@
</span><span class="cx"> "twextpy",
</span><span class="cx">
</span><span class="cx"> # Security frameworks
</span><del>- "pyOpenSSL>=0.14", # also for Twisted
- "service_identity", # for Twisted
</del><span class="cx"> "pycrypto", # for Twisted
</span><span class="cx"> "kerberos",
</span><span class="cx">
</span><span class="lines">@@ -346,6 +344,17 @@
</span><span class="cx"> "setproctitle",
</span><span class="cx"> ]
</span><span class="cx">
</span><ins>+if sys.platform == "darwin":
+ install_requirements.extend([
+ "OSXFrameworks",
+ "pySecureTransport",
+ ])
+else:
+ install_requirements.extend([
+ "pyOpenSSL>=0.14", # also for Twisted
+ "service_identity", # for Twisted
+ ])
+
</ins><span class="cx"> extras_requirements = {
</span><span class="cx"> "LDAP": ["twextpy[LDAP]"],
</span><span class="cx"> "OpenDirectory": ["twextpy[OpenDirectory]"],
</span></span></pre></div>
<a id="CalendarServertrunksupport_cache_deps"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/support/_cache_deps (15216 => 15217)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/support/_cache_deps        2015-10-23 19:26:11 UTC (rev 15216)
+++ CalendarServer/trunk/support/_cache_deps        2015-10-23 19:37:48 UTC (rev 15217)
</span><span class="lines">@@ -28,7 +28,7 @@
</span><span class="cx">
</span><span class="cx"> export PATH="/Applications/Server.app/Contents/ServerRoot/usr/bin:${PATH}";
</span><span class="cx">
</span><del>-requirements="${wd}/requirements-stable.txt";
</del><ins>+requirements="${wd}/requirements-osx.txt";
</ins><span class="cx"> extra_features="OpenDirectory,Postgres";
</span><span class="cx">
</span><span class="cx">
</span></span></pre></div>
<a id="CalendarServertrunktwistedcaldavclientpoolpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/twistedcaldav/client/pool.py (15216 => 15217)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twistedcaldav/client/pool.py        2015-10-23 19:26:11 UTC (rev 15216)
+++ CalendarServer/trunk/twistedcaldav/client/pool.py        2015-10-23 19:37:48 UTC (rev 15217)
</span><span class="lines">@@ -424,8 +424,9 @@
</span><span class="cx"> """
</span><span class="cx"> from twistedcaldav.config import config
</span><span class="cx"> return ChainingOpenSSLContextFactory(
</span><del>- config.SSLPrivateKey, config.SSLCertificate,
- certificateChainFile=config.SSLAuthorityChain,
</del><ins>+ "", "",
+ certificateChainFile="",
+ keychainIdentity="",
</ins><span class="cx"> sslmethod=getattr(OpenSSL.SSL, config.SSLMethod)
</span><span class="cx"> )
</span><span class="cx">
</span></span></pre></div>
<a id="CalendarServertrunktwistedcaldavstdconfigpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/twistedcaldav/stdconfig.py (15216 => 15217)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twistedcaldav/stdconfig.py        2015-10-23 19:26:11 UTC (rev 15216)
+++ CalendarServer/trunk/twistedcaldav/stdconfig.py        2015-10-23 19:37:48 UTC (rev 15217)
</span><span class="lines">@@ -464,11 +464,12 @@
</span><span class="cx"> #
</span><span class="cx"> # SSL/TLS
</span><span class="cx"> #
</span><del>- "SSLCertificate" : "", # Public key
- "SSLPrivateKey" : "", # Private key
- "SSLAuthorityChain" : "", # Certificate Authority Chain
- "SSLPassPhraseDialog": "/etc/apache2/getsslpassphrase",
- "SSLCertAdmin" : "/Applications/Server.app/Contents/ServerRoot/usr/sbin/certadmin",
</del><ins>+ "SSLCertificate" : "", # Public key
+ "SSLPrivateKey" : "", # Private key
+ "SSLAuthorityChain" : "", # Certificate Authority Chain
+ "SSLPassPhraseDialog" : "/etc/apache2/getsslpassphrase",
+ "SSLCertAdmin" : "/Applications/Server.app/Contents/ServerRoot/usr/sbin/certadmin",
+ "SSLKeychainIdentity" : "", # Keychain identity to use in place of cert files
</ins><span class="cx">
</span><span class="cx"> #
</span><span class="cx"> # Process management
</span><span class="lines">@@ -843,6 +844,7 @@
</span><span class="cx"> "PrivateKeyPath" : "Certificates/apns:com.apple.calendar.key.pem",
</span><span class="cx"> "AuthorityChainPath" : "Certificates/apns:com.apple.calendar.chain.pem",
</span><span class="cx"> "Passphrase" : "",
</span><ins>+ "KeychainIdentity" : "apns:com.apple.calendar",
</ins><span class="cx"> "Topic" : "",
</span><span class="cx"> },
</span><span class="cx"> "CardDAV" : {
</span><span class="lines">@@ -850,6 +852,7 @@
</span><span class="cx"> "PrivateKeyPath" : "Certificates/apns:com.apple.contact.key.pem",
</span><span class="cx"> "AuthorityChainPath" : "Certificates/apns:com.apple.contact.chain.pem",
</span><span class="cx"> "Passphrase" : "",
</span><ins>+ "KeychainIdentity" : "apns:com.apple.contact",
</ins><span class="cx"> "Topic" : "",
</span><span class="cx"> },
</span><span class="cx"> },
</span><span class="lines">@@ -1731,9 +1734,10 @@
</span><span class="cx"> service[direction].Username,
</span><span class="cx"> service[direction].Server
</span><span class="cx"> )
</span><del>- password = getPasswordFromKeychain(account)
- service[direction]["Password"] = password
- log.info("iMIP %s password successfully retreived from keychain" % (direction,))
</del><ins>+ if not service[direction]["Password"]:
+ password = getPasswordFromKeychain(account)
+ service[direction]["Password"] = password
+ log.info("iMIP %s password successfully retrieved from keychain" % (direction,))
</ins><span class="cx"> except KeychainAccessError:
</span><span class="cx"> # The system doesn't support keychain
</span><span class="cx"> pass
</span></span></pre>
</div>
</div>
</body>
</html>