Project

General

Profile

Actions

Bug #1368

closed

lighttpd webdav authentication with Mac OS X

Added by Anonymous over 16 years ago. Updated about 16 years ago.

Status:
Fixed
Priority:
Normal
Category:
mod_webdav
Target version:
ASK QUESTIONS IN Forums:

Description

Mac OS X embeds a webdav client into the OS, in the Finder. The Finder accesses correctly webdav repos on lighttpd, when they are open. It fails when they require authentication.

This is a dump of the headers when the Finder accesses to a digest-protected webdav repos on lighttpd:


OPTIONS / HTTP/1.1
User-Agent: WebDAVFS/1.4.1 (01418000) Darwin/8.10.1 (i386)
Accept: */*
Content-Length: 0
Connection: keep-alive
Host: myhost.com

HTTP/1.1 200 OK
WWW-Authenticate: Digest realm="MyHost DAV access", nonce="7e256b33c41b22b95b334b6ef1e8fa57", qop="auth" 
Allow: OPTIONS, GET, HEAD, POST
Content-Length: 0
Date: Wed, 19 Sep 2007 00:25:24 GMT
Server: lighttpd

Then the Finder fails announcing "You cannot connect to this server because it cannot be found on the network. Try again later or try a different URL.".

This is how http://test.webdav.org reacts instead:


OPTIONS /auth-digest/ HTTP/1.1
User-Agent: WebDAVFS/1.4.1 (01418000) Darwin/8.10.1 (i386)
Accept: */*
Content-Length: 0
Connection: keep-alive
Host: test.webdav.org

HTTP/1.1 401 Authorization Required
Date: Wed, 19 Sep 2007 00:46:00 GMT
Server: Apache/2.0.54 (Debian GNU/Linux) DAV/2 SVN/1.3.2
WWW-Authenticate: Digest realm="test", nonce="AIyOXHI6BAA=37bbe8e103c6b4a8c8ed987e257f0d8e854e3bd4", algorithm=MD5, domain="/auth-digest/", qop="auth" 
Content-Length: 401
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=iso-8859-1

to this reply the Finder correctly prompts for a user and pass.

This makes webdav repos on lighttpd not accessible on the Mac.

-- mij

Actions #1

Updated by Anonymous over 16 years ago

I can confirm that a similar behaviour occurs on Windows XP. Open repos work, while authenticated repos do not. Differently to the Finder, windows requires UI/Pass to the user, but nothing is shown
after. Moreover, no real authentication attempt seems to exist from the client during the exchange. Instead, the client repeatedly requests OPTIONS every 4 seconds:


OPTIONS / HTTP/1.1
translate: f
User-Agent: Microsoft-WebDAV-MiniRedir/5.1.2600
Host: webdav.sportsmile.org
Content-Length: 0
Connection: Keep-Alive
Pragma: no-cache

HTTP/1.1 200 OK
WWW-Authenticate: Digest realm="Sportsmile.org DAV access", nonce="edf1f6b97e4bc9984ddd58c2c9a81e60", qop="auth" 
Allow: OPTIONS, GET, HEAD, POST
Content-Length: 0
Date: Wed, 19 Sep 2007 10:04:50 GMT
Server: lighttpd

OPTIONS / HTTP/1.1
translate: f
User-Agent: Microsoft-WebDAV-MiniRedir/5.1.2600
Host: webdav.sportsmile.org
Content-Length: 0
Connection: Keep-Alive
Pragma: no-cache

HTTP/1.1 200 OK
WWW-Authenticate: Digest realm="Sportsmile.org DAV access", once="ea6be7d0f07e3e268015471959276b00", qop="auth" 
Allow: OPTIONS, GET, HEAD, POST
Content-Length: 0
Date: Wed, 19 Sep 2007 10:04:50 GMT
Server: lighttpd

OPTIONS / HTTP/1.1
translate: f
User-Agent: Microsoft-WebDAV-MiniRedir/5.1.2600
Host: webdav.sportsmile.org
Content-Length: 0
Connection: Keep-Alive
Pragma: no-cache

HTTP/1.1 200 OK
WWW-Authenticate: Digest realm="Sportsmile.org DAV access", once="f1a7f3812eff37207f9c4f546a93e787", qop="auth" 
Allow: OPTIONS, GET, HEAD, POST
Content-Length: 0
Date: Wed, 19 Sep 2007 10:04:54 GMT
Server: lighttpd

-- mij

Actions #2

Updated by mij over 16 years ago

In the sake of completeness, cadaver works with the same lighttpd authenticated webdav setup. This is a dump of its exchange:


OPTIONS / HTTP/1.1
Host: webdav.myhost.com
User-Agent: cadaver/0.22.5 neon/0.26.3
Keep-Alive: 
Connection: TE, Keep-Alive
TE: trailers

HTTP/1.1 200 OK
WWW-Authenticate: Digest realm="myhost.com DAV access", nonce="b3a1f040bb50f4fc47145addf2300ecc", qop="auth" 
Allow: OPTIONS, GET, HEAD, POST
Content-Length: 0
Date: Wed, 19 Sep 2007 21:10:53 GMT
Server: lighttpd

PROPFIND / HTTP/1.1
Host: webdav.myhost.com
User-Agent: cadaver/0.22.5 neon/0.26.3
Connection: TE
TE: trailers
Depth: 0
Content-Length: 288
Content-Type: application/xml

<?xml version="1.0" encoding="utf-8"?>
<propfind xmlns="DAV:"><prop>
<getcontentlength xmlns="DAV:"/>
<getlastmodified xmlns="DAV:"/>
<executable xmlns="http://apache.org/dav/props/"/>
<resourcetype xmlns="DAV:"/>
<checked-in xmlns="DAV:"/>
<checked-out xmlns="DAV:"/>
</prop></propfind>

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Digest realm="myhost.com DAV access", nonce="5ddd361061e0d2eef6160d8d0271292b", qop="auth" 
Content-Type: text/html
Content-Length: 351
Date: Wed, 19 Sep 2007 21:10:53 GMT
Server: lighttpd

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
  <title>401 - Unauthorized</title>
 </head>
 <body>
  <h1>401 - Unauthorized</h1>
 </body>
</html>

PROPFIND / HTTP/1.1
Host: webdav.myhost.com
User-Agent: cadaver/0.22.5 neon/0.26.3
Connection: TE
TE: trailers
Depth: 0
Content-Length: 288
Content-Type: application/xml
Authorization: Digest username="user", realm="myhost.com DAV access", nonce="5ddd361061e0d2eef6160d8d0271292b", uri="/", response="4ab5c9344c3edad1ebf2e960293e7e69", algorithm="MD5", cnonce="cd0ba87f5c7c8699302bef4c3ba738c2", nc=00000001, qop="auth" 

<?xml version="1.0" encoding="utf-8"?>
<propfind xmlns="DAV:"><prop>
<getcontentlength xmlns="DAV:"/>
<getlastmodified xmlns="DAV:"/>
<executable xmlns="http://apache.org/dav/props/"/>
<resourcetype xmlns="DAV:"/>
<checked-in xmlns="DAV:"/>
<checked-out xmlns="DAV:"/>
</prop></propfind>

HTTP/1.1 207 Multi-status
Content-Type: text/xml; charset="utf-8" 
Content-Length: 682
Date: Wed, 19 Sep 2007 21:10:57 GMT
Server: lighttpd

<?xml version="1.0" encoding="utf-8"?>
<D:multistatus xmlns:D="DAV:" xmlns:ns0="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/">
<D:response>
<D:href>http://webdav.myhost.com/</D:href>
<D:propstat>
<D:prop>
<D:getcontentlength>512</D:getcontentlength><D:getlastmodified ns0:dt="dateTime.rfc1123">Wed, 19 Sep 2007 09:59:25 GMT</D:getlastmodified><D:resourcetype><D:collection/></D:resourcetype></D:prop>
<D:status>HTTP/1.1 200 OK</D:status>
</D:propstat>
<D:propstat>
<D:prop>
<executable xmlns="http://apache.org/dav/props/"/><checked-in xmlns="DAV:"/><checked-out xmlns="DAV:"/></D:prop>
<D:status>HTTP/1.1 404 Not Found</D:status>
</D:propstat>
</D:response>
</D:multistatus>

PROPFIND / HTTP/1.1
Host: webdav.myhost.com
User-Agent: cadaver/0.22.5 neon/0.26.3
Connection: TE
TE: trailers
Depth: 1
Content-Length: 288
Content-Type: application/xml
Authorization: Digest username="user", realm="myhost.com DAV access", nonce="5ddd361061e0d2eef6160d8d0271292b", uri="/", response="644285b7183c37c0a450e59e9e1fa9dc", algorithm="MD5", cnonce="cd0ba87f5c7c8699302bef4c3ba738c2", nc=00000002, qop="auth" 

<?xml version="1.0" encoding="utf-8"?>
<propfind xmlns="DAV:"><prop>
<getcontentlength xmlns="DAV:"/>
<getlastmodified xmlns="DAV:"/>
<executable xmlns="http://apache.org/dav/props/"/>
<resourcetype xmlns="DAV:"/>
<checked-in xmlns="DAV:"/>
<checked-out xmlns="DAV:"/>
</prop></propfind>

HTTP/1.1 207 Multi-status
Content-Type: text/xml; charset="utf-8" 
Content-Length: 9027
Date: Wed, 19 Sep 2007 21:10:58 GMT
Server: lighttpd

<?xml version="1.0" encoding="utf-8"?>
<... XML directory listing follows ...>
Actions #3

Updated by mij over 16 years ago

Replying to mij:

notably from the dump, cadaver does not attempt to authenticate at the first response from lighttpd. It recognizes the 200 code and goes ahead with a speculative PROPFIND. Only then lighttpd responds with a 401 code, after which cadaver attempts authentication.

In analogy, the Mac and Windows client give up with a failure after the first (200) response from lighttpd: they switch to "accessed" status but don't get the payload with description. Cadaver instead insists, in second stage it gets the 401 auth request and then authenticates and gets access.

Actions #4

Updated by Anonymous over 16 years ago

WebDav works for me on the mac with authentication on 1.4.16. I think it depends on what order you list the modules in. "mod_webdav" must go before "mod_auth".

-- krolaw

Actions #5

Updated by mij over 16 years ago

Replying to krolaw:
I've updated the wiki on mod_webdav to report this indeed :). Notice that the initialization order hack does work with OS X and linux, but does not with Windows. The way lighttpd responds with auth is still weird if you sniff a session btw lighttpd and Win.

In IRC darix was stating the bug is scheduled for fix for 1.50.

Actions #6

Updated by HenrikHolst over 16 years ago

This is fixed in the patches that I have sent into trac at #1324 (for 1.4.x) and #1396 (for 1.5.x). The problem is that OPTIONS will not be passed on to mod_webdav since mod_auth blocks the URI, but then the lighttpd core will change the "401 authorization is required" from mod_auth into a 200 OK for all OPTIONS request wich falsly tell the webdav client that this path does not support webdav.

If you apply the patches that I have linked to this behaviour is changed and the core will pass the "401 authorizations is required" to the client which then forces it to include the correct authorization so that mod_auth will pass on the URI to mod_webdav who then can add it's OPTIONS.

Actions #7

Updated by Anonymous over 16 years ago

interestingly enough to fix it on 1.4.13 you just put mod_webdav before mod_auth and you are done. It works. :)

Actions #8

Updated by HenrikHolst over 16 years ago

What you do when you put the mod_webdav before mod_auth is that you let the webdav module handle the URL before any form of authorization is performed, this might be OK for you but there is naurally some situations where you don't even want non-authorized clients to know the OPTIONS possible on that URL.

Clearly it would always be an advantage (from a security perspective) to let the URL be authorized before we trow it at any module (some modules might catch the URL in such a way that the URL would then never be seen by mod_auth and therefore would be accepted regardless of your authorization rules), wouldn't you agree?

Actions #9

Updated by mij over 16 years ago

What is the status of this ticket? Given HenrikHolst considerations, we might consider to document this issue on the wiki, recommending lighttpd's webdav for open resources, and recommend instead to proxy a more reliable implementation for password-protected resources.

Actions #10

Updated by Anonymous over 16 years ago

can you prove that there is a real issue when mod_webdav is before mod_auth?

Actions #11

Updated by Anonymous over 16 years ago

This of course depends upon how mod_webdav changes in the future, there is no guarantee that it wont't be the endpoint for some trigger one day and then we are wide open.

And all this arguing over a simple two line patch that only enhances the security of lighttpd?

In case you haven't looked up the patch it is a simple:

+

+ /* If authorization is required we cannot send a 200 response! */

+ if (con->http_status == 401)

+ break;

+

Not very intrusive? But then getting something merged mainline in lighttpd seams like a very long process :)

Actions #12

Updated by HenrikHolst over 16 years ago

Recommending mod_webdav for only open resources would be a little harsh. What this is all about is that lighty has a small flaw where OPTIONS requests are handled wrongly if they are behind a closed resource.

This has implications for mod_webdav since that is the one standard module that adds OPTIONS and since lighty works like it does (without the patch mentioned above) then one has to put mod_webdav before mod_auth.

For now I can see only one issue with placing mod_webdav before mod_auth and that is that any non-authorized users can find out that the resource is a webdav resource, this might be a non-issue for some people and a real-issue for others.

There is however a possible issue in the long run, we don't know wheter mod_webdav (or any other module for that matter) might put more code in the "handle_uri_clean" path and since any such code would hit the module before mod_auth (if it is before mod_auth in the config) we might one day hit something we don't want to.

So there is no real issue at the moment, however the patch is as you all can see only two lines of code, has no other property than enhance the security of lighty so it should be merged in my opinon since it is the true fix to this OPTIONS problem with mod_webdav, but putting mod_auth before works for now.

Actions #13

Updated by HenrikHolst over 16 years ago

Going through RFCs today I saw that lightys current behaviour actually goes against the specification:

<RFC4918>

8. General Request and Response Handling

8.1 Precedence in Error Handling

Servers MUST return authorization errors in preference to other errors. This avoids leaking information about protected resources (e.g., a client that finds that a hidden resource exists by seeing a 423 Locked response to an anonymous request to the resource).

Actions #14

Updated by stbuehler about 16 years ago

Duplicate of #1324.

Actions #15

Updated by stbuehler about 16 years ago

  • Status changed from New to Fixed
  • Resolution set to duplicate
Actions

Also available in: Atom