<!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>[10129] 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/10129">10129</a></dd>
<dt>Author</dt> <dd>sagen@apple.com</dd>
<dt>Date</dt> <dd>2012-12-05 16:49:47 -0800 (Wed, 05 Dec 2012)</dd>
</dl>

<h3>Log Message</h3>
<pre>Authentication factories not safe for unencrypted connections are automatically not advertised when an insecure (e.g. non-SSL) connection is made</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#CalendarServertrunkcalendarserverprovisiontesttest_rootpy">CalendarServer/trunk/calendarserver/provision/test/test_root.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="#CalendarServertrunkcontribmigrationcalendarcommonextrapy">CalendarServer/trunk/contrib/migration/calendarcommonextra.py</a></li>
<li><a href="#CalendarServertrunkcontribmigrationtesttest_commonextrapy">CalendarServer/trunk/contrib/migration/test/test_commonextra.py</a></li>
<li><a href="#CalendarServertrunktwextweb2channelhttppy">CalendarServer/trunk/twext/web2/channel/http.py</a></li>
<li><a href="#CalendarServertrunktwextweb2davauthpy">CalendarServer/trunk/twext/web2/dav/auth.py</a></li>
<li><a href="#CalendarServertrunktwextweb2davtesttest_aclpy">CalendarServer/trunk/twext/web2/dav/test/test_acl.py</a></li>
<li><a href="#CalendarServertrunktwextweb2davtesttest_resourcepy">CalendarServer/trunk/twext/web2/dav/test/test_resource.py</a></li>
<li><a href="#CalendarServertrunktwextweb2testtest_metafdpy">CalendarServer/trunk/twext/web2/test/test_metafd.py</a></li>
<li><a href="#CalendarServertrunktwistedcaldavresourcepy">CalendarServer/trunk/twistedcaldav/resource.py</a></li>
<li><a href="#CalendarServertrunktwistedcaldavstdconfigpy">CalendarServer/trunk/twistedcaldav/stdconfig.py</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#CalendarServertrunktwextweb2davtesttest_authpy">CalendarServer/trunk/twext/web2/dav/test/test_auth.py</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="CalendarServertrunkcalendarserverprovisiontesttest_rootpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/provision/test/test_root.py (10128 => 10129)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/provision/test/test_root.py        2012-12-05 04:54:04 UTC (rev 10128)
+++ CalendarServer/trunk/calendarserver/provision/test/test_root.py        2012-12-06 00:49:47 UTC (rev 10129)
</span><span class="lines">@@ -85,7 +85,8 @@
</span><span class="cx">         self.root = auth.AuthenticationWrapper(
</span><span class="cx">             root,
</span><span class="cx">             portal,
</span><del>-            credentialFactories=(basic.BasicCredentialFactory(&quot;Test realm&quot;),),
</del><ins>+            (basic.BasicCredentialFactory(&quot;Test realm&quot;),),
+            (basic.BasicCredentialFactory(&quot;Test realm&quot;),),
</ins><span class="cx">             loginInterfaces=(auth.IPrincipal,))
</span><span class="cx"> 
</span><span class="cx">         self.site = server.Site(self.root)
</span></span></pre></div>
<a id="CalendarServertrunkcalendarservertaputilpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/tap/util.py (10128 => 10129)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/tap/util.py        2012-12-05 04:54:04 UTC (rev 10128)
+++ CalendarServer/trunk/calendarserver/tap/util.py        2012-12-06 00:49:47 UTC (rev 10129)
</span><span class="lines">@@ -409,7 +409,8 @@
</span><span class="cx">     #
</span><span class="cx">     # Configure the Site and Wrappers
</span><span class="cx">     #
</span><del>-    credentialFactories = []
</del><ins>+    wireEncryptedCredentialFactories = []
+    wireUnencryptedCredentialFactories = []
</ins><span class="cx"> 
</span><span class="cx">     portal = Portal(auth.DavRealm())
</span><span class="cx"> 
</span><span class="lines">@@ -464,7 +465,9 @@
</span><span class="cx">                 log.error(&quot;Unknown scheme: %s&quot; % (scheme,))
</span><span class="cx"> 
</span><span class="cx">         if credFactory:
</span><del>-            credentialFactories.append(credFactory)
</del><ins>+            wireEncryptedCredentialFactories.append(credFactory)
+            if schemeConfig.get(&quot;AllowedOverWireUnencrypted&quot;, False):
+                wireUnencryptedCredentialFactories.append(credFactory)
</ins><span class="cx"> 
</span><span class="cx">     #
</span><span class="cx">     # Setup Resource hierarchy
</span><span class="lines">@@ -685,9 +688,10 @@
</span><span class="cx">     authWrapper = AuthenticationWrapper(
</span><span class="cx">         root,
</span><span class="cx">         portal,
</span><del>-        credentialFactories,
</del><ins>+        wireEncryptedCredentialFactories,
+        wireUnencryptedCredentialFactories,
</ins><span class="cx">         (auth.IPrincipal,),
</span><del>-        overrides=overrides,
</del><ins>+        overrides=overrides
</ins><span class="cx">     )
</span><span class="cx"> 
</span><span class="cx">     logWrapper = DirectoryLogWrapperResource(
</span></span></pre></div>
<a id="CalendarServertrunkconfcaldavdappleplist"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/conf/caldavd-apple.plist (10128 => 10129)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/conf/caldavd-apple.plist        2012-12-05 04:54:04 UTC (rev 10128)
+++ CalendarServer/trunk/conf/caldavd-apple.plist        2012-12-06 00:49:47 UTC (rev 10129)
</span><span class="lines">@@ -242,7 +242,7 @@
</span><span class="cx">       &lt;key&gt;Basic&lt;/key&gt;
</span><span class="cx">       &lt;dict&gt;
</span><span class="cx">         &lt;key&gt;Enabled&lt;/key&gt;
</span><del>-        &lt;false/&gt;
</del><ins>+        &lt;true/&gt;
</ins><span class="cx">       &lt;/dict&gt;
</span><span class="cx"> 
</span><span class="cx">       &lt;!-- Digest challenge/response --&gt;
</span></span></pre></div>
<a id="CalendarServertrunkconfcaldavdtestplist"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/conf/caldavd-test.plist (10128 => 10129)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/conf/caldavd-test.plist        2012-12-05 04:54:04 UTC (rev 10128)
+++ CalendarServer/trunk/conf/caldavd-test.plist        2012-12-06 00:49:47 UTC (rev 10129)
</span><span class="lines">@@ -507,6 +507,8 @@
</span><span class="cx">       &lt;dict&gt;
</span><span class="cx">         &lt;key&gt;Enabled&lt;/key&gt;
</span><span class="cx">         &lt;true/&gt;
</span><ins>+        &lt;key&gt;AllowedOverWireUnencrypted&lt;/key&gt; &lt;!-- advertised over non SSL? --&gt;
+        &lt;true/&gt;
</ins><span class="cx">       &lt;/dict&gt;
</span><span class="cx"> 
</span><span class="cx">       &lt;!-- Digest challenge/response --&gt;
</span><span class="lines">@@ -514,6 +516,8 @@
</span><span class="cx">       &lt;dict&gt;
</span><span class="cx">         &lt;key&gt;Enabled&lt;/key&gt;
</span><span class="cx">         &lt;true/&gt;
</span><ins>+        &lt;key&gt;AllowedOverWireUnencrypted&lt;/key&gt; &lt;!-- advertised over non SSL? --&gt;
+        &lt;true/&gt;
</ins><span class="cx">         &lt;key&gt;Algorithm&lt;/key&gt;
</span><span class="cx">         &lt;string&gt;md5&lt;/string&gt;
</span><span class="cx">         &lt;key&gt;Qop&lt;/key&gt;
</span><span class="lines">@@ -525,6 +529,8 @@
</span><span class="cx">       &lt;dict&gt;
</span><span class="cx">         &lt;key&gt;Enabled&lt;/key&gt;
</span><span class="cx">         &lt;true/&gt;
</span><ins>+        &lt;key&gt;AllowedOverWireUnencrypted&lt;/key&gt; &lt;!-- advertised over non SSL? --&gt;
+        &lt;true/&gt;
</ins><span class="cx">         &lt;key&gt;ServicePrincipal&lt;/key&gt;
</span><span class="cx">         &lt;string&gt;&lt;/string&gt;
</span><span class="cx">       &lt;/dict&gt;
</span></span></pre></div>
<a id="CalendarServertrunkcontribmigrationcalendarcommonextrapy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/contrib/migration/calendarcommonextra.py (10128 => 10129)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/contrib/migration/calendarcommonextra.py        2012-12-05 04:54:04 UTC (rev 10128)
+++ CalendarServer/trunk/contrib/migration/calendarcommonextra.py        2012-12-06 00:49:47 UTC (rev 10129)
</span><span class="lines">@@ -146,6 +146,7 @@
</span><span class="cx"> 
</span><span class="cx">     settings[&quot;EnableSSL&quot;] = True
</span><span class="cx">     settings[&quot;RedirectHTTPToHTTPS&quot;] = True
</span><ins>+    settings.setdefault(&quot;Authentication&quot;, {}).setdefault(&quot;Basic&quot;, {})[&quot;Enabled&quot;] = True
</ins><span class="cx"> 
</span><span class="cx"> def setCert(plistPath, otherCert):
</span><span class="cx">     &quot;&quot;&quot;
</span></span></pre></div>
<a id="CalendarServertrunkcontribmigrationtesttest_commonextrapy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/contrib/migration/test/test_commonextra.py (10128 => 10129)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/contrib/migration/test/test_commonextra.py        2012-12-05 04:54:04 UTC (rev 10128)
+++ CalendarServer/trunk/contrib/migration/test/test_commonextra.py        2012-12-06 00:49:47 UTC (rev 10129)
</span><span class="lines">@@ -34,6 +34,7 @@
</span><span class="cx">         orig = {
</span><span class="cx">         }
</span><span class="cx">         expected = {
</span><ins>+            'Authentication': {'Basic': {'Enabled': True}},
</ins><span class="cx">             'EnableSSL': True,
</span><span class="cx">             'RedirectHTTPToHTTPS': True,
</span><span class="cx">             'SSLAuthorityChain': '/test/pchain.pem',
</span></span></pre></div>
<a id="CalendarServertrunktwextweb2channelhttppy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/twext/web2/channel/http.py (10128 => 10129)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twext/web2/channel/http.py        2012-12-05 04:54:04 UTC (rev 10128)
+++ CalendarServer/trunk/twext/web2/channel/http.py        2012-12-06 00:49:47 UTC (rev 10129)
</span><span class="lines">@@ -637,11 +637,7 @@
</span><span class="cx">                 self._cleanup()
</span><span class="cx"> 
</span><span class="cx">     def getHostInfo(self):
</span><del>-        t=self.channel.transport
-        secure = interfaces.ISSLTransport(t, None) is not None
-        host = t.getHost()
-        host.host = _cachedGetHostByAddr(host.host)
-        return host, secure
</del><ins>+        return self.channel._host, self.channel._secure
</ins><span class="cx"> 
</span><span class="cx">     def getRemoteHost(self):
</span><span class="cx">         return self.channel.transport.getPeer()
</span><span class="lines">@@ -783,6 +779,9 @@
</span><span class="cx">         self.requests = []
</span><span class="cx">         
</span><span class="cx">     def connectionMade(self):
</span><ins>+        self._secure = interfaces.ISSLTransport(self.transport, None) is not None
+        address = self.transport.getHost()
+        self._host = _cachedGetHostByAddr(address.host)
</ins><span class="cx">         self.setTimeout(self.inputTimeOut)
</span><span class="cx">         self.factory.addConnectedChannel(self)
</span><span class="cx">     
</span></span></pre></div>
<a id="CalendarServertrunktwextweb2davauthpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/twext/web2/dav/auth.py (10128 => 10129)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twext/web2/dav/auth.py        2012-12-05 04:54:04 UTC (rev 10128)
+++ CalendarServer/trunk/twext/web2/dav/auth.py        2012-12-06 00:49:47 UTC (rev 10129)
</span><span class="lines">@@ -37,7 +37,9 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> class AuthenticationWrapper(WrapperResource):
</span><del>-    def __init__(self, resource, portal, credentialFactories, loginInterfaces):
</del><ins>+    def __init__(self, resource, portal,
+        wireEncryptedCredentialFactories, wireUnencryptedCredentialFactories,
+        loginInterfaces):
</ins><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Wrap the given resource and use the parameters to set up the request
</span><span class="cx">         to allow anyone to challenge and handle authentication.
</span><span class="lines">@@ -45,23 +47,42 @@
</span><span class="cx">         @param resource: L{DAVResource} FIXME: This should get promoted to
</span><span class="cx">             twext.web2.auth
</span><span class="cx">         @param portal: The cred portal
</span><del>-        @param credentialFactories: Sequence of credentialFactories that can
-            be used to authenticate by resources in this tree.
</del><ins>+        @param wireEncryptedCredentialFactories: Sequence of credentialFactories
+            that can be used to authenticate by resources in this tree over a
+            wire-encrypted channel (SSL).
+        @param wireUnencryptedCredentialFactories: Sequence of credentialFactories
+            that can be used to authenticate by resources in this tree over a
+            wire-unencrypted channel (non-SSL).
</ins><span class="cx">         @param loginInterfaces: More cred stuff
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         super(AuthenticationWrapper, self).__init__(resource)
</span><span class="cx"> 
</span><span class="cx">         self.portal = portal
</span><del>-        self.credentialFactories = dict([(factory.scheme, factory)
-                                         for factory in credentialFactories])
</del><ins>+        self.wireEncryptedCredentialFactories = dict([(factory.scheme, factory)
+                                         for factory in wireEncryptedCredentialFactories])
+        self.wireUnencryptedCredentialFactories = dict([(factory.scheme, factory)
+                                         for factory in wireUnencryptedCredentialFactories])
</ins><span class="cx">         self.loginInterfaces = loginInterfaces
</span><span class="cx"> 
</span><ins>+        # FIXME: some unit tests access self.credentialFactories, so assigning here
+        self.credentialFactories = self.wireEncryptedCredentialFactories
+
</ins><span class="cx">     def hook(self, req):
</span><span class="cx">         req.portal = self.portal
</span><del>-        req.credentialFactories = self.credentialFactories
</del><span class="cx">         req.loginInterfaces = self.loginInterfaces
</span><span class="cx"> 
</span><ins>+        # If not using SSL, use the factory list which excludes &quot;Basic&quot;
+        if req.chanRequest is None: # This is only None in unit tests
+            secureConnection = True
+        else:
+            ignored, secureConnection = req.chanRequest.getHostInfo()
+        req.credentialFactories = (
+            self.wireEncryptedCredentialFactories
+            if secureConnection
+            else self.wireUnencryptedCredentialFactories
+        )
</ins><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class IPrincipal(Interface):
</span><span class="cx">     pass
</span><span class="cx"> 
</span></span></pre></div>
<a id="CalendarServertrunktwextweb2davtesttest_aclpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/twext/web2/dav/test/test_acl.py (10128 => 10129)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twext/web2/dav/test/test_acl.py        2012-12-05 04:54:04 UTC (rev 10128)
+++ CalendarServer/trunk/twext/web2/dav/test/test_acl.py        2012-12-06 00:49:47 UTC (rev 10129)
</span><span class="lines">@@ -72,6 +72,7 @@
</span><span class="cx">             rootResource,
</span><span class="cx">             portal,
</span><span class="cx">             credentialFactories,
</span><ins>+            credentialFactories,
</ins><span class="cx">             loginInterfaces
</span><span class="cx">         ))
</span><span class="cx"> 
</span></span></pre></div>
<a id="CalendarServertrunktwextweb2davtesttest_authpyfromrev10125CalendarServertrunktwextweb2davtesttest_authpy"></a>
<div class="copfile"><h4>Copied: CalendarServer/trunk/twext/web2/dav/test/test_auth.py (from rev 10125, CalendarServer/trunk/twext/web2/dav/test/test_auth.py) (0 => 10129)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twext/web2/dav/test/test_auth.py                                (rev 0)
+++ CalendarServer/trunk/twext/web2/dav/test/test_auth.py        2012-12-06 00:49:47 UTC (rev 10129)
</span><span class="lines">@@ -0,0 +1,67 @@
</span><ins>+##
+# Copyright (c) 2012 Apple Computer, Inc. All rights reserved.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the &quot;Software&quot;), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+# 
+# THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+#
+# DRI: Wilfredo Sanchez, wsanchez@apple.com
+##
+
+import collections
+from twext.web2.dav.auth import AuthenticationWrapper
+import twext.web2.dav.test.util
+
+class AutoWrapperTestCase(twext.web2.dav.test.util.TestCase):
+
+    def test_basicAuthPrevention(self):
+        &quot;&quot;&quot;
+        Ensure authentication factories which are not safe to use over an
+        &quot;unencrypted wire&quot; are not advertised when an insecure (i.e. non-SSL
+        connection is made.
+        &quot;&quot;&quot;
+        FakeFactory = collections.namedtuple(&quot;FakeFactory&quot;, (&quot;scheme,&quot;))
+        wireEncryptedfactories = [FakeFactory(&quot;basic&quot;), FakeFactory(&quot;digest&quot;), FakeFactory(&quot;xyzzy&quot;)]
+        wireUnencryptedfactories = [FakeFactory(&quot;digest&quot;), FakeFactory(&quot;xyzzy&quot;)]
+
+        class FakeChannel(object):
+            def __init__(self, secure):
+                self.secure = secure
+            def getHostInfo(self):
+                return &quot;ignored&quot;, self.secure
+
+        class FakeRequest(object):
+            def __init__(self, secure):
+                self.portal = None
+                self.loginInterfaces = None
+                self.credentialFactories = None
+                self.chanRequest = FakeChannel(secure)
+
+        wrapper = AuthenticationWrapper(None, None,
+            wireEncryptedfactories, wireUnencryptedfactories, None)
+        req = FakeRequest(True) # Connection is over SSL
+        wrapper.hook(req)
+        self.assertEquals(
+            set(req.credentialFactories.keys()),
+            set([&quot;basic&quot;, &quot;digest&quot;, &quot;xyzzy&quot;])
+        )
+        req = FakeRequest(False) # Connection is not over SSL
+        wrapper.hook(req)
+        self.assertEquals(
+            set(req.credentialFactories.keys()),
+            set([&quot;digest&quot;, &quot;xyzzy&quot;])
+        )
</ins></span></pre></div>
<a id="CalendarServertrunktwextweb2davtesttest_resourcepy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/twext/web2/dav/test/test_resource.py (10128 => 10129)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twext/web2/dav/test/test_resource.py        2012-12-05 04:54:04 UTC (rev 10128)
+++ CalendarServer/trunk/twext/web2/dav/test/test_resource.py        2012-12-06 00:49:47 UTC (rev 10129)
</span><span class="lines">@@ -240,6 +240,7 @@
</span><span class="cx">             self.rootresource,
</span><span class="cx">             portal,
</span><span class="cx">             credentialFactories,
</span><ins>+            credentialFactories,
</ins><span class="cx">             loginInterfaces,
</span><span class="cx">         ))
</span><span class="cx"> 
</span></span></pre></div>
<a id="CalendarServertrunktwextweb2testtest_metafdpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/twext/web2/test/test_metafd.py (10128 => 10129)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twext/web2/test/test_metafd.py        2012-12-05 04:54:04 UTC (rev 10128)
+++ CalendarServer/trunk/twext/web2/test/test_metafd.py        2012-12-06 00:49:47 UTC (rev 10129)
</span><span class="lines">@@ -53,7 +53,10 @@
</span><span class="cx">             raise SocketError(ENOTCONN, &quot;Transport endpoint not connected&quot;)
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+    def getsockname(self):
+        return (&quot;4.3.2.1&quot;, 4321)
</ins><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class InheritedPortForTesting(sendfdport.InheritedPort):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     L{sendfdport.InheritedPort} subclass that prevents certain I/O operations
</span></span></pre></div>
<a id="CalendarServertrunktwistedcaldavresourcepy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/twistedcaldav/resource.py (10128 => 10129)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twistedcaldav/resource.py        2012-12-05 04:54:04 UTC (rev 10128)
+++ CalendarServer/trunk/twistedcaldav/resource.py        2012-12-06 00:49:47 UTC (rev 10129)
</span><span class="lines">@@ -3023,11 +3023,13 @@
</span><span class="cx">     &quot;&quot;&quot; AuthenticationWrapper implementation which allows overriding
</span><span class="cx">         credentialFactories on a per-resource-path basis &quot;&quot;&quot;
</span><span class="cx"> 
</span><del>-    def __init__(self, resource, portal, credentialFactories, loginInterfaces,
-        overrides=None):
</del><ins>+    def __init__(self, resource, portal,
+        wireEncryptedCredentialFactories, wireUnencryptedCredentialFactories,
+        loginInterfaces, overrides=None):
</ins><span class="cx"> 
</span><span class="cx">         super(AuthenticationWrapper, self).__init__(resource, portal,
</span><del>-            credentialFactories, loginInterfaces)
</del><ins>+            wireEncryptedCredentialFactories, wireUnencryptedCredentialFactories,
+            loginInterfaces)
</ins><span class="cx"> 
</span><span class="cx">         self.overrides = {}
</span><span class="cx">         if overrides:
</span><span class="lines">@@ -3043,7 +3045,7 @@
</span><span class="cx">         super(AuthenticationWrapper, self).hook(req)
</span><span class="cx"> 
</span><span class="cx">         factories = self.overrides.get(req.path.rstrip(&quot;/&quot;),
</span><del>-            self.credentialFactories)
</del><ins>+            req.credentialFactories)
</ins><span class="cx">         req.credentialFactories = factories
</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 (10128 => 10129)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twistedcaldav/stdconfig.py        2012-12-05 04:54:04 UTC (rev 10128)
+++ CalendarServer/trunk/twistedcaldav/stdconfig.py        2012-12-06 00:49:47 UTC (rev 10129)
</span><span class="lines">@@ -406,15 +406,20 @@
</span><span class="cx">     # Authentication
</span><span class="cx">     #
</span><span class="cx">     &quot;Authentication&quot;: {
</span><del>-        &quot;Basic&quot;: { &quot;Enabled&quot;: False }, # Clear text; best avoided
</del><ins>+        &quot;Basic&quot;: {                         # Clear text; best avoided
+            &quot;Enabled&quot;: True,
+            &quot;AllowedOverWireUnencrypted&quot;: False, # Advertised over non-SSL?
+        },
</ins><span class="cx">         &quot;Digest&quot;: {                        # Digest challenge/response
</span><span class="cx">             &quot;Enabled&quot;: True,
</span><span class="cx">             &quot;Algorithm&quot;: &quot;md5&quot;,
</span><span class="cx">             &quot;Qop&quot;: &quot;&quot;,
</span><ins>+            &quot;AllowedOverWireUnencrypted&quot;: True, # Advertised over non-SSL?
</ins><span class="cx">         },
</span><span class="cx">         &quot;Kerberos&quot;: {                       # Kerberos/SPNEGO
</span><span class="cx">             &quot;Enabled&quot;: False,
</span><del>-            &quot;ServicePrincipal&quot;: &quot;&quot;
</del><ins>+            &quot;ServicePrincipal&quot;: &quot;&quot;,
+            &quot;AllowedOverWireUnencrypted&quot;: True, # Advertised over non-SSL?
</ins><span class="cx">         },
</span><span class="cx">         &quot;Wiki&quot;: {
</span><span class="cx">             &quot;Enabled&quot;: False,
</span></span></pre>
</div>
</div>

</body>
</html>