address Logo

WebDAV と Windows クライアント

目次

2007/01/20

この記事では Windows クライアントの WebDAV の実装に関する問題が扱われている。Windows クライアントの WebDAV に関しては膨大な記事がネット上に存在するが、殆どは Apache の設定などのハウツーに関するもので、プロトコルレベルの議論は見つからない。ここではプロトコルレベルで発生している問題を扱い、そのためにサーバが何をしなくてはならないのかを解説する。

記事のスタイルはブログ風である。従ってどのような試行錯誤の中で問題を解決していったか、またその途中でどのような現象が発生したかがよく分かると思う。

なおサーバは Pegasus であるが、記事の内容は普遍的なものである。Pegasus に関しては「Pegasus 2.4, CGI/1.1 and WebDAV」を参考にしてほしい。

WinXP

実験対象のクライアントのバージョンは 5.1(SP2)

winxp-info

図1. WinXP のバージョン情報

この画面はウィンドウの HELP の「バージョン情報」で得られる。

システムエラー 67

2007/01/14


support.microsoft.com の情報(2003年7月)
によると WebClient サービスにはバグがあって、認証が働かないらしい。一旦サービスを停止させ、ウェブフォルダが作成されたら、また動作させよとのこと。この情報は現在も有効なのか否かは不明。(有効であれば3年間も放置されていることになる!)

現在の到達点。認証を外した上で

	net use * http://pc/dav 

を発行。結果は「システムエラー 67 」(ネットワーク名が見つからない)

ここに "pc" は筆者の実験中のサーバ名で、このように名前で指定できるためには

	Windows/system32/drivers/etc/hosts 

に "pc" と その IP アドレスを登録しなくてはならない。また "/dav" は、サーバ上に設定されている DAV ようのディレクトリである。なお net コマンドに関しては、例えば
http://www.atmarkit.co.jp/fwin2k/win2ktips/258netcommand/netcommand.html
に解説されている。

サーバのログは

OPTIONS / HTTP/1.1
translate: f
User-Agent: Microsoft-WebDAV-MiniRedir/5.1.2600
Host: pc
Content-Length: 0
Connection: Keep-Alive

となっている。

なお WinXP のユーザエイジェントは

になっているらしい。WebClient が動作しているか否かはサーバのログを見なくても、WinXP で

  1. コントロールパネル
  2. 管理ツール
  3. サービス

の順に辿れば WebClient の状態が分かる。

Win-XP クライアントはこの結論を出す前に

	PROPFIND /dav/ HTTP/1.1 

を試している。サーバの応答(認証は外してあるので、プロパティの応答はしている)に何らかの問題があったと考えられる。(後に見るように、この推測は正しくない。)
なお筆者のサーバの応答ヘッダには

	MS-Author-Via: DAV 

は含まれている。

WebClient サービスの停止

2007/01/14

WebClient サービスの簡便な停止の方法が
http://ulihansen.kicks-ass.net/aero/webdav/
に載っている。このサイトには WinXP 問題に関する詳しい説明と解決法が載っている。それによると Web フォルダーの作成の入力欄に次の2つのいずれかを使うと良いらしい。

	http://pc:80/dav 
	http://pc/dav# 

また Google によるネットの情報では

	http://pc/dav? 

も解決策とされている。

net use コマンドではいずれもダメであった。net use コマンドを使う第2の方法では
ユーザ名とパスワードの入力を促されたが(サーバは認証を要求していないのに...)
「システムエラー 5 が発生しました。アクセスが拒否されました」と言われた。
原因は net コマンドが、 dav# を "dav%23" としてサーバにリクエストを送ったためである。つまり "#" をパス名の一部と解釈したのである。これは net use コマンドのバグかも知れない。また第1と第3ではそもそもサーバにアクセスに行かない!

ネットワークプレースの追加

007/01/14

net コマンドではうまく行かない。しかし「マイネットワーク」の「ネットワークプレースを追加する」で

	http://pc/dav? 

とすると確かに「pc上のdav」が追加された。

xp-netplace

図1. WinXP のネットワークプレース

そしてサーバのログでは User-Agent が "Microsoft Data Access Internet Publishing Provider DAV" に変わった。確かに WebClient サービスが停止されたのである。

サーバを認証なしに設定していると net コマンドは依然として「67」エラーであるが、ダイジェスト認証に設定し

	net use * http://pc/dav 

を実行すると、ユーザ名とパスワードの入力を求められるようになり、ユーザ名

	arisawa@pc 

にして
「システムエラー1219」
「同じユーザによる、サーバまたは共有リソースへの複数のユーザ名での複数の接続は許可されません。サーバまたは共有リソースへの以前の接続をすべて切断してから、再試行してください。」と言われる。(しかし同じ事をやっても別のメッセージがでる事もある。)

ユーザ名の問題

WinXP はネットワーク資源のアクセスに関しては "arisawa" のような、ネットワーク情報の付加されないユーザ名を拒否する。従ってサーバ側でユーザ名を、次のいずれかに設定しなくてはならない。

	arisawa@pc 
	pc\arisawa 

ここに "pc" は筆者が実験中のサーバ名である。「\」を使うのは Win 臭くて嫌なので、筆者は "arisawa@pc" に設定している。(後に見るように、これでもよろしい。)

追加 (2007/02/03)

ホスト名が要求されるのは「ネットワークプレイスの追加」の時だけらしい。
従って

	arisawa@pc 
	arisawa 

の 2 つのユーザ名を許すように設定すれば、ウェブフォルダーの作成に成功した後は "arisawa" でやっていける。

なお、「ネットワークプレイスの追加」の時のホスト名が

	http://ar.aichi-u.ac.hp/dav? 

のようなフルアドレスの場合でも、追加の際に要求されるユーザ名は

	arisawa@ar 

のようにホスト名だけを追加したもので構わない。

実験

2007/01/16

実験環境

なお、WinXP は SP2 以降、通信路が暗号化されていない場合の基本認証を禁止している(文献)。

net use による実験

次に示すのは

	net use * http://pc/dav 

によるログである。(これはユーザ認証を求められた後に「67」エラー)

OPTIONS / HTTP/1.1
translate: f
User-Agent: Microsoft-WebDAV-MiniRedir/5.1.2600
Host: pc
Content-Length: 0
Connection: Keep-Alive


PROPFIND /dav HTTP/1.1
Depth: 0
translate: f
User-Agent: Microsoft-WebDAV-MiniRedir/5.1.2600
Host: pc
Content-Length: 0
Connection: Keep-Alive

# redirect to /dav/

PROPFIND /dav/ HTTP/1.1
Depth: 0
translate: f
User-Agent: Microsoft-WebDAV-MiniRedir/5.1.2600
Host: pc
Content-Length: 0
Connection: Keep-Alive

ここでダイジェスト認証を求めらる。しかし WinXP は、ここでアクセスを止める。サーバには認証情報を送っていない。
"#" で始まる行は、サーバからクライアントへの指示。(ログから得られた筆者のコメント)

ウェブフォルダをクリックした場合

次に示すのはウェブフォルダをクリックした場合のログ。

PROPFIND /dav HTTP/1.1
Content-Language: en-us
Accept-Language: ja, en-us;q=0.2
Content-Type: text/xml
Translate: f
Depth: 0
Content-Length: 0
User-Agent: Microsoft Data Access Internet Publishing Provider DAV
Host: pc
Connection: Keep-Alive

# redirect to /dav/

PROPFIND /dav HTTP/1.1
Content-Language: en-us
Accept-Language: ja, en-us;q=0.2
Content-Type: text/xml
Translate: f
Depth: 1
Content-Length: 489
User-Agent: Microsoft Data Access Internet Publishing Provider DAV
Host: pc
Connection: Keep-Alive

Redirection の指示が無視されている!
(PROPFIND に関しては "/" を付ける必要はないかも知れないが...)

構わず

	Depth: 1 

が実行される。つまり、サーバの応答を無視している!

そして期待される結果が得られないので、さらに続いて OPTION をトライする。

OPTIONS / HTTP/1.1
Translate: f
User-Agent: Microsoft Data Access Internet Publishing Provider Protocol Discovery
Host: pc
Content-Length: 0
Connection: Keep-Alive


OPTIONS /dav HTTP/1.1
Translate: f
User-Agent: Microsoft Data Access Internet Publishing Provider Protocol Discovery
Host: pc
Content-Length: 0
Connection: Keep-Alive


#  redirect to /dav/

OPTIONS /dav/ HTTP/1.1
Translate: f
User-Agent: Microsoft Data Access Internet Publishing Provider Protocol Discovery
Host: pc
Content-Length: 0
Connection: Keep-Alive


# Reply: 401 Unauthorized

WinXP はサーバの認証要求に応えない(パスワード入力画面が現れない)。もちろんクライアントはマウントに失敗する。

やんちゃな WinXP クライアントにつきあうか? その場合には

の(いずれか、あるいは両方の)改造を加えなくてはならなくなる。サーバコードがくちゃくちゃする!

対策

2007/01/16

ウェブフォルダをクリックした場合のログからは対策の方向が見えてくる。PROPFIND でのリダイレクションを WinXP は捕えない(Mac/OSX は捕えている)。たぶん WinXP の DAV クライアントは、まさかリダイレクションの指示が返ってくるとは思っていないのであろう。相手は DAV サーバであり、単なる http サーバではないのだから... と。

http サーバの場合にはクライアントから

	http://host/foo 

のようなリクエストがあり、"foo" がディレクトリであれば、クライアントにそのことを知らせるために

	http://host/foo/ 

でアクセスするように求める。これによってクライアントは "foo" がディレクトリである事を認識する。

多分どのサーバでも Pegasus と同様な手順を踏むと思うのだが、Pegasus はリクエストされているファイルを完全に確定してから、アクセス制限のチェックや認証を求め、さらにそれに合格したリクエストに関してのみ、(その対象が CGI であれば) CGI プログラムを実行する。つまりリダイレクションは CGI である webdav にリクエストが渡る前に行われる。Pegasus 自身は GET, HEAD, POST, OPTION 以外のメソッドを知らないのだ。

しかし WebDAV は PROPFIND を持っている。これを使えばリダイレクションをしなくてもクライアントは "foo" がディレクトリてある事が分かる。従って WinXP 対策としては、WebDAV に特徴的なメソッドに対してはリダイレクションをしない事が考えられる。しかしこの方向はサーバのプログラムコードを複雑にするから嫌だ。

筆者にとっては WebDAV はあくまで Pegasus の CGI の一つである。WebDAV に固有なコードは一行だって入れたくはないのである。そこで次のように考えてみた。"foo" と言うディレクトリが存在するからリダイレクションを指示することになるのだと...

そこで "/doc/dav" を作らない事にした。その代わりハンドラの内容を(とりあえず)次のようにしてみた*

	/dav	-  +  /bin/webdav /dav /doc/dav1 
	/dav/*  -  +  /bin/webdav /dav /doc/dav1 

この意味は

	http://pc/dav/foo 

のようなリクエストに対して

	/bin/webdav /dav /doc/dav1 

を実行する事を指示する。webdav はリクエストの内容 "/dav/foo" を環境変数 $request から知る事ができる。そこで、webdav に与えられた2つの引数 "/dav" と "/doc/dav1" を参照して "/doc/dav1/foo" を構成し、実際の処理対象のディレクトリを "/doc/dav1" にすり替えるようと言う訳である。

注意 *: 現在はこの仕様は変わっている。第3フィールドは WebDAV の場合には "+" ではなく、"*" を指定する。(2007/01/19)

この考えで webdav に(引数が与えられるように)手を加えたところ、今度はうまく WinXP クライアントを騙せた。

xp-dav

WinXP クライアントによる "http://pc/dav" のマウント

めでたしめでたし。

注意: "/doc/dav1" にしたのは単なる実験環境だからである。これをどのようにすべきかに関しては次の節を見よ。

WebDAV の使い方

筆者は Microsoft は嫌いである。だから悪口を書く事が多いが、ここでは WebDAV のサポートに当たって Microsoft が考えたであろう事を肯定的に述べてみたい。

WebDAV はどのような目的で使われるのか? 次の2つが考えられる。

  1. 単なるネットワーク上のファイルサーバ
  2. ホームページのメンテナンス用のインターフェース

第1の場合には、ファイルの実態をドキュメントルートの下に置くのは好ましくない。従ってクライアントとのインターフェースが

	http://pc/dav 

であっても、実際にファイルが置かれる場所は "/doc/dav" ではなく、ドキュメントルート "/doc" の外にあるディレクトリになるであろう。

第2の場合には、ユーザはマウントされたディレクトリの中にドキュメントルート以下のファイルを全て見たいのである。従って "/doc" が編集の対象となるディレクトリに指定されなくてはならない。この場合のハンドラの設定は

	/dav      -    +    /bin/webdav /dav /doc 
	/dav/*    -    +    /bin/webdav /dav /doc 

となる*。この場合、ユーザの誤操作を防ぐ意味でも、マウントされたディレクトリの中に "/dav" が含まれない方が好ましい。

つまり、よく考えてみると Microsoft の考え方に合理性があるのである。

注意 *: 現在はこの仕様は変わっている。第3フィールドは WebDAV の場合には "+" ではなく、"*" を指定する。(2007/01/19)

ちょっと変なクライアントの実装

マウントされた HTML ファイルをダブルクリックすると IE が起動し、そして認証が求められた。なぜ認証が求められるか不思議に思いサーバのログを調べるとリクエストは次のようになっている。

GET /dav/memo.html HTTP/1.1
Accept: */*
Accept-Language: ja
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)
Host: pc
Connection: Keep-Alive

何と IE が直接アクセスしているのである! だからもう一度認証のやり直しである。ちゃんとファイルシステムとして実装されていない、とりあえず見かけ上なんとかファイルシステムに見えればよいだなんてあんまりだ。

まとめ

2007/02/04

WinXP クライアントからは

Pegasus 側では

Win2000

Win2000 は既にリリースされて 7 年を経ており、その間に多くの修正が加えられている。従って実験中の OS バージョンをはっきりさせておく必要があろう。筆者のは

	OS 名      Microsoft Windows 2000 Professional 
	バージョン  5.0.2195 Service Pack 4 ビルド 2195 

である。

win2000-info

システテム情報

この画面は、「コントロールパネル」→「管理ツール」を辿って得られる。

同じ情報は WinXP と同様に、ウィンドウの「HELP」からも得られる。

様々な User-Agent

2007/01/14

Win-2000 をクライアントにした場合に観測される様々な User-Agent

SP3 以降では、他に次のようなものが観測される

不思議な事にメソッドによって使い分けているようである。
サーバのログを見ると

	GET /_vti_inf.html HTTP/1.1 
	POST /_vti_bin/shtml.exe/_vti_rpc HTTP/1.1 

が見える。これは何故か? POST がクライアントから自動的に行われる事に危うさを感じるが...

この問題に対する microsoft による情報は
http://support.microsoft.com/kb/828909/ja

ネットの記事によるとサーバが次のヘッダを持っていれば

	MS-Author-Via: DAV 

Win クライアントは _vti_inf.html を要求しないらしい*

注 *: 筆者の実験を見る限り、このヘッダを持っていても要求することがある。

実験

2007/01/19

さて WinXP はクリアしたので、今日は Win2000 に再度アタックする。

「ネットワークプレイスの追加ウイザード」から

	http://pc/dav 

で追加を試みるも、「入力したフォルダは有効ではない」と言われる。サーバは次のように反応している。(このサーバは WinXP をマウントできる。)

OPTIONS / HTTP/1.1
Translate: f
User-Agent: Microsoft Data Access Internet Publishing Provider Protocol Discovery
Host: pc
Content-Length: 0
Connection: Keep-Alive


OPTIONS /dav HTTP/1.1
Translate: f
User-Agent: Microsoft Data Access Internet Publishing Provider Protocol Discovery
Host: pc
Content-Length: 0
Connection: Keep-Alive


# Reply: 401 Unauthorized


OPTIONS / HTTP/1.1
User-Agent: Microsoft Data Access Internet Publishing Provider Cache Manager
Host: pc
Content-Length: 0
Connection: Keep-Alive


OPTIONS /dav HTTP/1.1
Accept-Language: ja, en-us;q=0.2
User-Agent: Microsoft Data Access Internet Publishing Provider DAV 1.1
Host: pc
Content-Length: 0
Connection: Keep-Alive


# Reply: 401 Unauthorized


GET /_vti_inf.html HTTP/1.1
Date: Fri, 19 Jan 2007 13:26:25 GMT
MIME-Version: 1.0
Accept: */*
User-Agent: Mozilla/2.0 (compatible; MS FrontPage 4.0)
Host: pc
Accept: auth/sicily
Content-Length: 0
Connection: Keep-Alive
Cache-Control: no-cache


# Reply: 404 Not Found


POST /_vti_bin/shtml.exe/_vti_rpc HTTP/1.1
Date: Fri, 19 Jan 2007 13:26:25 GMT
MIME-Version: 1.0
User-Agent: MSFrontPage/4.0
Host: pc
Accept: auth/sicily
Content-Length: 41
Content-Type: application/x-www-form-urlencoded
X-Vermeer-Content-Type: application/x-www-form-urlencoded
Connection: Keep-Alive
Cache-Control: no-cache


# unallowed: POST /_vti_rpc

WinXP でやったように

	http://pc/dav? 

とやっても、やはりフェブフォルダは作成されない。(同じメッセージ)

サーバが認証情報を要求しているのに、無視している。

そこで、サーバのパスワードを外して

	http://pc/dav 

でウェブフォルダの作成を試みると成功。作成されたウェブフォルダをダブルクリックするとマウントされているのが確認できる。

この時のサーバのログは次の通り:

OPTIONS / HTTP/1.1
User-Agent: Microsoft Data Access Internet Publishing Provider Cache Manager
Host: pc
Content-Length: 0
Connection: Keep-Alive


OPTIONS /dav HTTP/1.1
Accept-Language: ja, en-us;q=0.2
User-Agent: Microsoft Data Access Internet Publishing Provider DAV 1.1
Host: pc
Content-Length: 0
Connection: Keep-Alive


PROPFIND /dav HTTP/1.1
Accept-Language: ja, en-us;q=0.2
Content-Type: text/xml
Translate: f
Content-Length: 0
Depth: 0
User-Agent: Microsoft Data Access Internet Publishing Provider DAV 1.1
Host: pc
Connection: Keep-Alive


OPTIONS /dav HTTP/1.1
User-Agent: Microsoft Data Access Internet Publishing Provider Cache Manager
Host: pc
Content-Length: 0
Connection: Keep-Alive


PROPFIND /dav HTTP/1.1
Accept-Language: ja, en-us;q=0.2
Content-Type: text/xml
Translate: f
Content-Length: 380
Depth: 1
User-Agent: Microsoft Data Access Internet Publishing Provider DAV 1.1
Host: pc
Connection: Keep-Alive

どうやら Win2000 をサポートするには、OPTIONS に対して認証を要求してはならないらしい。
(ウェブフォルダが作成されたら、後は認証を要求しても大丈夫かと試したが、「予期しないエラー」でダメである。)

対策

2007/01/20

認証なしの OPTIONS を許してみる。
しかし

win2000-msg

Win2000 のエラーメッセージ

表示されているファイルの中のメッセージは

	You can't POST on <a href="/_vti_bin/shtml.exe/_vti_rpc"> here 

である。

この問題は OPTIONS への応答ヘッダに

	MS-Author-Via: DAV 

を含める事によって解決した。

Win2000 にパスワード入力画面が現れて、必要な情報を入れてやった。今度はエラーにはならない。しかしダメ。マウントはされたように見えるが、そこにファイルの一覧が見えない。
サーバのログを調べると

	PROPFIND /dav HTTP/1.1 

にまで進んだ事を示している。サーバはここで認証を要求する。
クライアントは確かにダイジェスト認証で応えてはいるが、サーバのログは認証エラーを示している。Win2000 はダイジェストの計算を間違えている! そしてまたもや、サーバからの応答メッセージを捕えていない。

でも不思議だねー。Win2000 クライアントは、その後、パスワード入力画面を示さない。再起動しても、ウェブフォルダーを作り直してもである! どうやら一回入力したパスワードが記憶されていて、それが使われているらしい。こういうのは実に嫌だ。

パスワード入力画面の問題は「ゴミ箱」を空にしたら解決した。さらに認証されなかった問題も同時に解決。

win2000-dav

Win2000 の WebDAV のマウント画面

日本語のファイル名

2007/02/04

日本の文字を含むファイルやディレクトリにアクセスできない事に気づいた。
サーバのログを見て、あっと驚く。
Win2000 クライアントは RFC の規則を守っていない!

これでは Win2000 の場合には日本文字を含むファイルのサポートをあきらめるしかないであろう。
(文字コードを解析して Win2000 のための特殊パッチを充てる程の価値はないと思う)

NB: この記事は正確ではない。これは IE5.0 を使用していたからである。IE6.0 をインストールしたら、日本の文字を含むファイル名のファイルにアクセスできた。
こういう問題が IE と絡んでいるところが Win らしい。
(2007/02/08)

まとめ

2007/02/04

クライアント側から見た WinXP との違いをまとめる。

win2000-auth

Win2000 の認証画面

Win2000 のサポートについて

2007/01/20

Pegasus は Win2000 クライアントをマウントするするようになったものの、これを正式の仕様にするのは嫌だ。そのためには OPTIONS を認証なしにどのディレクトリに対しても許さなくてはならない。この場合、OPTIONS の応答に CGI が使われれば、セキュリティ上の弱点になる。他方 Pegasus の本体で処理すれば、OPTIONS の本来の趣旨に反し、ディレクトリが何であれ一律に全てのメソッドをサポートしているかのような応答をせざるを得なくなる。(今回の筆者が採用した方法は後者であり、また Windows IIS も後者ではないかと思われる。)

さらに

	MS-Author-Via: DAV 

を Pegasus の(CGI にではなく)本体に組み込むのも嫌である。

結局 WIn2000 のサポートのためのコードは Pegasus の全体の論理構造を崩し、単なる Win2000 のためのダーティトリックである。従って Win2000 はコンパイラオプションによって許すことにしようと思う。