Commit 7a59e94c authored by Sidnei da Silva's avatar Sidnei da Silva

- Merge r76767 from trunk. Fixes collector issue #1441, adding a...

 - Merge r76767 from trunk. Fixes collector issue #1441, adding a configuration option to enable Microsoft WebFolders to work with Zope again, disabled by default.
parent 22b3c51c
...@@ -8,6 +8,13 @@ Zope Changes ...@@ -8,6 +8,13 @@ Zope Changes
Bugs fixed Bugs fixed
- Collector #1441: WebDAV compatibility with Windows Web Folders
restored by adding a configuration variable that controls the
sending of the non-standard MS-Author-Via and Public
headers. Thanks for PatrickD for the the hard work coming up
with an initial patch.
(http://zope.org/Collectors/Zope/1441)
- Fixed bug in ZPublisher.BaseRequest with persistent site managers. An - Fixed bug in ZPublisher.BaseRequest with persistent site managers. An
EndRequestEvent was thrown after the ZODB connection was already EndRequestEvent was thrown after the ZODB connection was already
closed and thus the site manager not being available anymore. closed and thus the site manager not being available anymore.
...@@ -1319,9 +1326,9 @@ Zope Changes ...@@ -1319,9 +1326,9 @@ Zope Changes
x86_64 systems x86_64 systems
- ZReST: the charset used in the rendered HTML was not set to the - ZReST: the charset used in the rendered HTML was not set to the
corresponding output_encoding property of the ZReST instance. In addition corresponding output_encoding property of the ZReST
changing the encodings through the Properties tab did not re-render instance. In addition changing the encodings through the
the HTML. Properties tab did not re-render the HTML.
- Collector #1234: an exception triple passed to LOG() was not - Collector #1234: an exception triple passed to LOG() was not
propagated properly to the logging module of Python propagated properly to the logging module of Python
......
...@@ -150,6 +150,14 @@ def cgi_maxlen(value): ...@@ -150,6 +150,14 @@ def cgi_maxlen(value):
def http_header_max_length(value): def http_header_max_length(value):
return value return value
def enable_ms_author_via(value):
import webdav
webdav.enable_ms_author_via = value
def enable_ms_public_header(value):
import webdav
webdav.enable_ms_public_header = value
def catalog_getObject_raises(value): def catalog_getObject_raises(value):
if value is not None: if value is not None:
......
...@@ -95,6 +95,50 @@ class StartupTestCase(unittest.TestCase): ...@@ -95,6 +95,50 @@ class StartupTestCase(unittest.TestCase):
items.sort() items.sort()
self.assertEqual(items, [("FEARFACTORY", "rocks"), ("NSYNC","doesnt")]) self.assertEqual(items, [("FEARFACTORY", "rocks"), ("NSYNC","doesnt")])
def test_ms_author_via(self):
import webdav
from Zope2.Startup.handlers import handleConfig
default_setting = webdav.enable_ms_author_via
try:
conf, handler = self.load_config_text("""\
instancehome <<INSTANCE_HOME>>
enable-ms-author-via true
""")
handleConfig(None, handler)
self.assert_(webdav.enable_ms_author_via == True)
conf, handler = self.load_config_text("""\
instancehome <<INSTANCE_HOME>>
enable-ms-author-via false
""")
handleConfig(None, handler)
self.assert_(webdav.enable_ms_author_via == False)
finally:
webdav.enable_ms_author_via = default_setting
def test_ms_public_header(self):
import webdav
from Zope2.Startup.handlers import handleConfig
default_setting = webdav.enable_ms_public_header
try:
conf, handler = self.load_config_text("""\
instancehome <<INSTANCE_HOME>>
enable-ms-public-header true
""")
handleConfig(None, handler)
self.assert_(webdav.enable_ms_public_header == True)
conf, handler = self.load_config_text("""\
instancehome <<INSTANCE_HOME>>
enable-ms-public-header false
""")
handleConfig(None, handler)
self.assert_(webdav.enable_ms_public_header == False)
finally:
webdav.enable_ms_public_header = default_setting
def test_path(self): def test_path(self):
p1 = tempfile.mktemp() p1 = tempfile.mktemp()
p2 = tempfile.mktemp() p2 = tempfile.mktemp()
......
...@@ -553,6 +553,63 @@ ...@@ -553,6 +553,63 @@
</description> </description>
</key> </key>
<key name="enable-ms-author-via" datatype="boolean" handler="enable_ms_author_via" default="off">
<description>
Set this directive to 'true' to enable the "MS-Author-Via" header
in response to an OPTIONS WebDAV request. Early versions of
Microsoft Web Folders and Microsoft Office require this header to
be present to be able to connect to Zope via WebDAV.
This is disabled by default since it makes a lot of standards-compliant
things unhappy AND it tricks Microsoft Office into trying to edit Office
files stored in Zope via WebDAV even when the user isn't allowed to edit
them and is only trying to download them.
Check this collector entry for more information:
http://www.zope.org/Collectors/Zope/1441
Recent versions of Microsoft Web Folders, updated after January
2005, do not require this header anymore, and instead require a
"Public" header to be present in reply to the OPTIONS WebDAV
request.
(http://www.redmountainsw.com/wordpress/archives/webfolders-zope)
To get a recent Microsoft Web Folders implementation, refer to
Microsoft KB Article 907306.
(Software Update for Web Folders: May 18, 2007).
</description>
<metadefault>off</metadefault>
</key>
<key name="enable-ms-public-header" datatype="boolean" handler="enable_ms_public_header" default="off">
<description>
Set this directive to 'on' to enable sending the "Public" header
in response to an WebDAV OPTIONS request.
Though recent WebDAV drafts mention this header, the original
WebDAV RFC did not mention it as part of the standard. Very few
web servers out there include this header in their replies, most
notably IIS and Netscape Enterprise 3.6.
Since many best practices documents out in the web mention
turning off this header with the subject of "Mask Your Web Server
For Enhanced Security", this setting is off by
default. Presumably malicious people might take the presence of
this header as indication of an IIS Web Server and try to attack
your site, so be careful when turning it on.
Recent versions of Microsoft Web Folders, updated after January
2005, *do* require this header to be present in reply to the
OPTIONS WebDAV request.
(http://www.redmountainsw.com/wordpress/archives/webfolders-zope)
To get a recent Microsoft Web Folders implementation, refer to
Microsoft KB Article 907306.
(Software Update for Web Folders: May 18, 2007).
</description>
<metadefault>off</metadefault>
</key>
<key name="dns-server" datatype=".dns_resolver" attribute="dns_resolver"> <key name="dns-server" datatype=".dns_resolver" attribute="dns_resolver">
<description> <description>
Specify the IP address of your DNS server in order to cause resolved Specify the IP address of your DNS server in order to cause resolved
......
...@@ -18,8 +18,10 @@ $Id$ ...@@ -18,8 +18,10 @@ $Id$
import mimetypes import mimetypes
import sys import sys
import warnings import warnings
import re
from urllib import unquote from urllib import unquote
import webdav
import ExtensionClass import ExtensionClass
from Globals import InitializeClass from Globals import InitializeClass
from AccessControl import getSecurityManager from AccessControl import getSecurityManager
...@@ -54,6 +56,7 @@ from OFS.event import ObjectClonedEvent ...@@ -54,6 +56,7 @@ from OFS.event import ObjectClonedEvent
from OFS.event import ObjectWillBeMovedEvent from OFS.event import ObjectWillBeMovedEvent
import OFS.subscribers import OFS.subscribers
ms_dav_agent = re.compile("Microsoft.*Internet Publishing.*")
class Resource(ExtensionClass.Base, Lockable.LockableItem): class Resource(ExtensionClass.Base, Lockable.LockableItem):
...@@ -213,6 +216,15 @@ class Resource(ExtensionClass.Base, Lockable.LockableItem): ...@@ -213,6 +216,15 @@ class Resource(ExtensionClass.Base, Lockable.LockableItem):
RESPONSE.setHeader('Allow', ', '.join(self.__http_methods__)) RESPONSE.setHeader('Allow', ', '.join(self.__http_methods__))
RESPONSE.setHeader('Content-Length', 0) RESPONSE.setHeader('Content-Length', 0)
RESPONSE.setHeader('DAV', '1,2', 1) RESPONSE.setHeader('DAV', '1,2', 1)
# Microsoft Web Folders compatibility, only enabled if
# User-Agent matches.
if ms_dav_agent.match(REQUEST.get_header('User-Agent', '')):
if webdav.enable_ms_public_header:
RESPONSE.setHeader('Public', ', '.join(self.__http_methods__))
if webdav.enable_ms_author_via:
RESPONSE.setHeader('MS-Author-Via', 'DAV')
RESPONSE.setStatus(200) RESPONSE.setStatus(200)
return RESPONSE return RESPONSE
......
...@@ -36,3 +36,6 @@ ...@@ -36,3 +36,6 @@
Microsoft, U.C. Irvine, Netscape, Novell. February, 1999.""" Microsoft, U.C. Irvine, Netscape, Novell. February, 1999."""
__version__='$Revision: 1.7 $'[11:-2] __version__='$Revision: 1.7 $'[11:-2]
enable_ms_author_via = False
enable_ms_public_header = False
import unittest import unittest
MS_DAV_AGENT = "Microsoft Data Access Internet Publishing Provider DAV"
def make_request_response(environ=None):
from StringIO import StringIO
from ZPublisher.HTTPRequest import HTTPRequest
from ZPublisher.HTTPResponse import HTTPResponse
if environ is None:
environ = {}
stdout = StringIO()
stdin = StringIO()
resp = HTTPResponse(stdout=stdout)
environ.setdefault('SERVER_NAME', 'foo')
environ.setdefault('SERVER_PORT', '80')
environ.setdefault('REQUEST_METHOD', 'GET')
req = HTTPRequest(stdin, environ, resp)
return req, resp
class TestResource(unittest.TestCase): class TestResource(unittest.TestCase):
...@@ -12,6 +30,60 @@ class TestResource(unittest.TestCase): ...@@ -12,6 +30,60 @@ class TestResource(unittest.TestCase):
verifyClass(IDAVResource, Resource) verifyClass(IDAVResource, Resource)
verifyClass(IWriteLock, Resource) verifyClass(IWriteLock, Resource)
def test_ms_author_via(self):
import webdav
from webdav.Resource import Resource
default_settings = webdav.enable_ms_author_via
try:
req, resp = make_request_response()
resource = Resource()
resource.OPTIONS(req, resp)
self.assert_(not resp.headers.has_key('ms-author-via'))
webdav.enable_ms_author_via = True
req, resp = make_request_response()
resource = Resource()
resource.OPTIONS(req, resp)
self.assert_(not resp.headers.has_key('ms-author-via'))
req, resp = make_request_response(
environ={'USER_AGENT': MS_DAV_AGENT})
resource = Resource()
resource.OPTIONS(req, resp)
self.assert_(resp.headers.has_key('ms-author-via'))
self.assert_(resp.headers['ms-author-via'] == 'DAV')
finally:
webdav.enable_ms_author_via = default_settings
def test_ms_public_header(self):
import webdav
from webdav.Resource import Resource
default_settings = webdav.enable_ms_public_header
try:
req, resp = make_request_response()
resource = Resource()
resource.OPTIONS(req, resp)
self.assert_(not resp.headers.has_key('public'))
webdav.enable_ms_public_header = True
req, resp = make_request_response()
resource = Resource()
resource.OPTIONS(req, resp)
self.assert_(not resp.headers.has_key('public'))
self.assert_(resp.headers.has_key('allow'))
req, resp = make_request_response(
environ={'USER_AGENT': MS_DAV_AGENT})
resource = Resource()
resource.OPTIONS(req, resp)
self.assert_(resp.headers.has_key('public'))
self.assert_(resp.headers.has_key('allow'))
self.assert_(resp.headers['public'] == resp.headers['allow'])
finally:
webdav.enable_ms_public_header = default_settings
def test_suite(): def test_suite():
return unittest.TestSuite(( return unittest.TestSuite((
......
...@@ -443,6 +443,70 @@ instancehome $INSTANCE ...@@ -443,6 +443,70 @@ instancehome $INSTANCE
# #
# http-header-max-length 16384 # http-header-max-length 16384
# Directive: enable-ms-author-via
#
# Description:
# Set this directive to 'true' to enable the "MS-Author-Via" header
# in response to an OPTIONS WebDAV request. Early versions of
# Microsoft Web Folders and Microsoft Office require this header to
# be present to be able to connect to Zope via WebDAV.
#
# This is disabled by default since it makes a lot of standards-compliant
# things unhappy AND it tricks Microsoft Office into trying to edit Office
# files stored in Zope via WebDAV even when the user isn't allowed to edit
# them and is only trying to download them.
#
# Check this collector entry for more information:
# http://www.zope.org/Collectors/Zope/1441
#
# Recent versions of Microsoft Web Folders, updated after January
# 2005, do not require this header anymore, and instead require a
# "Public" header to be present in reply to the OPTIONS WebDAV
# request.
# (http://www.redmountainsw.com/wordpress/archives/webfolders-zope)
#
# To get a recent Microsoft Web Folders implementation, refer to
# Microsoft KB Article 907306.
# (Software Update for Web Folders: May 18, 2007).
#
# Default: off
#
# Example:
#
# enable-ms-author-via on
# Directive: enable-ms-public-header
#
# Description:
# Set this directive to 'on' to enable sending the "Public" header
# in response to an WebDAV OPTIONS request.
#
# Though recent WebDAV drafts mention this header, the original
# WebDAV RFC did not mention it as part of the standard. Very few
# web servers out there include this header in their replies, most
# notably IIS and Netscape Enterprise 3.6.
#
# Since many best practices documents out in the web mention
# turning off this header with the subject of "Mask Your Web Server
# For Enhanced Security", this setting is off by
# default. Presumably malicious people might take the presence of
# this header as indication of an IIS Web Server and try to attack
# your site, so be careful when turning it on.
#
# Recent versions of Microsoft Web Folders, updated after January
# 2005, *do* require this header to be present in reply to the
# OPTIONS WebDAV request.
# (http://www.redmountainsw.com/wordpress/archives/webfolders-zope)
#
# To get a recent Microsoft Web Folders implementation, refer to
# Microsoft KB Article 907306.
# (Software Update for Web Folders: May 18, 2007).
#
# Default: off
#
# Example:
#
# enable-ms-public-header on
# Directive: automatically-quote-dtml-request-data # Directive: automatically-quote-dtml-request-data
# #
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment