Exchange 2007 アカウント (SMTP/POP3/IMAP) にログインするために、(現在ログインしている Windows ユーザーの既定の資格情報を使用して) 統合 Windows 認証を取得しようとしています。
私はすでにこれの実装を行っていますが、SSPI 関数を使用しているため、管理されていないコードのアクセス許可が必要です (ダメです)。これには NegotiateStream クラスを使用しようとしましたが、機能しません。
POP3/IMAP/SMTP で NegotiateStream を直接使用することはできません。会話全体のすべての要求と応答を base64 でラップし、メール プロトコルのサフィックスなどを含める必要があるためです。そのため、これを行う独自のストリーム クラスを実装しました。 NetworkStream と NegotiateStream の間に挿入しました。ただし、NegotiateStream によって作成された要求とそれが期待する応答は、私が正常に使用してきたもの (および NTLM/GSSAPI の種類の認証が可能な他のメール クライアントによって作成されたもの) とは異なることに気付きました。
特に、NegotiateStream は最初に、他の実装では送信されない 5 バイト長の要求を送信します。このパケットは、「プロトコル エラー」メッセージで Exchange によって拒否されます。
NegotiateStream によって作成された 2 番目の要求は正しいものです (NTLMSSP で始まります)。そこで、base64 エンコードの中間ストリームの最初のパケットを無視し、送信しないことにしました。Exchange が 2 番目のパケットを取得すると、このパケットを正常に消費し、適切な継続応答を返します。ただし、今回は NegotiateStream が 5 バイトの応答を受信する必要があるのに対し、サーバーははるかに大きな応答を返しました。簡単に言えば、NegotiateStream は +1 要求を送信し、必要以上に +1 応答を期待しています。
最初の「冗長な」5 バイト パケットの送信を回避できますが、NegotiateStream が期待する最初の 5 バイト応答パケットを発明することはできません。NegotiateStream が以前に送信しようとしたのと同じパケットをフィードしようとしましたが、もちろんこれは機能しませんでした。
何が起こっているのか、これを修正する方法を知りたいです。Windows XP SP3 および Windows Server 2008 でも同じ動作が発生します。
私は Kerberos/GSSAPI の専門家ではありませんが、ドキュメントで見つけたものから、Kerberos の会話は実際には 5 バイトのパケットで開始する必要があるようです。ただし、他の作業ツールを使用しているときに見たことはなく、Exchange も拒否します。おそらく、GSSAPI が SASL プロトコル (認証のために POP3/IMAP/SMTP で使用される) で使用されている場合、最初のパケットは省略されるべきでしょうか? しかし、これについて NegotiateStream にどのように伝えることができますか、または少なくともサーバーからの 5 バイトの応答を期待するときに何を送信する必要がありますか?
NegotiateStream のさまざまなモードを試しました。また、AUTH NTLM と AUTH GSSAPI の両方を Exchange に発行しましたが、これはすべて違いはありません。また、他の動作中の実装 (GSSAPI と NTLM の両方をサポート) はすべて同じように動作します (GSSAPI パケットと NTLM パケットに大きな違いはありません)。そこにあるすべての着信および発信パケットは、5 バイトをはるかに超えています。
Windows XP で IIS SMTP サービスも試してみましたが、結果は同じでした。SSPI ベースの非 NegotiateStream 実装は機能しますが、NegotiateStream は最初のパケットのために機能しません。送信しないと、NegotiateStream が最初の応答として何を期待しているのかわかりません。
SmtpClient クラスがこれを何らかの方法で管理し、デフォルトの資格情報と NTLM で認証できるため、機能させることができるはずだと思っていました。しかし、SmtpClient は内部で NegotiateStream を使用せず、古いバージョンのソフトウェアと同様に、管理されていない SSPI 呼び出しを行うだけであることがわかりました。
Visual Studio 2010 / .NET 4.0 でも試しました。うまくいきません (そして、NegotiateStream を微調整するための新しいメソッド/プロパティはありません)。
私は完全に迷っています:-(