Mono.Security.Protocol.Ntlm名前空間(Mono.Security.dll)には、NTLM認証(NT LAN Manager Authentication)で用いられるNTLMメッセージを抽象化したクラスが用意されている。
これらのクラスはSystem.Net.WebRequest等でHTTPにおけるNTLM認証を行うために用いられているが、IMAPにおけるAUTHENTICATEコマンドでの認証にも使用できる(IMAPの他、POP、SMTP等その他のプロトコルでも使用できると思われる)。
IMAP AUTHENTICATEコマンドによるNTLM認証の手続きは次のようになる。
C: 0001 AUTHENTICATE NTLM // 1.NTLM認証の開始 S: + // 2.サーバからのコマンド継続要求応答を受信 C: Base64(Type1Message) // 3.クライアントからBASE64エンコードしたネゴシエーションメッセージを送信 S: + Base64(Type2Message) // 4.サーバからのBASE64エンコードされたチャレンジメッセージを受信 C: Base64(Type3Message) // 5.クライアントからBASE64エンコードした認証メッセージを送信 S: 0001 OK // 6.サーバからのタグ付き応答(OKもしくはNO)を受信
クライアント側でのNTLM認証の実装イメージは次のようになる。
// 1.NTLM認証の開始 var authenticateCommand = "0001 AUTHENTICATE NTLM"; networkStream.Write(authenticateCommand); // 2.サーバからのコマンド継続要求応答を受信 var continuation = networkStream.Read(...); // 3.クライアントからBASE64エンコードしたネゴシエーションメッセージを送信 var type1 = new Type1Message(); type1.Host = host; type1.Domain = domain; networkStream.Write(Convert.ToBase64String(type1.GetBytes())); // 4.サーバからのBASE64エンコードされたチャレンジメッセージを受信 var type2 = new Type2Message(Convert.FromBase64String(networkStream.Read(...))); // 5.クライアントからBASE64エンコードした認証メッセージを送信 var type3 = new Type3Message(); type3.Challenge = type2.Nonce; type3.Host = host; type3.Domain = domain; type3.Password = password; type3.Username = username; networkStream.Write(Convert.ToBase64String(type3.GetBytes())); // 6.サーバからのタグ付き応答(OKもしくはNO)を受信 var authenticateResponse = networkStream.Read(...); if (authenticateResponse.Contains("OK")) Console.WriteLine("authentication succeeded"); else Console.WriteLine("authentication failed");
以下は上記実装イメージに基づく実装でNTLM認証を行った場合のログ。 テストに使ったサーバはDovecot 1.2 rc3、認証に用いた値はhost = "localhost", domain = "localdomain", username = "user", password = "pass"。
C: 0001 CAPABILITY S: * CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE SORT THREAD=REFERENCES THREAD=REFS MULTIAPPEND UNSELECT IDLE CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH AUTH=PLAIN AUTH=LOGIN AUTH=DIGEST-MD5 AUTH=CRAM-MD5 AUTH=ANONYMOUS AUTH=NTLM S: 0001 OK Capability completed. C: 0002 AUTHENTICATE NTLM S: + C: TlRMTVNTUAABAAAAA7IAAAsACwApAAAACQAJACAAAABMT0NBTEhPU1RMT0NBTERPTUFJTg== S: + TlRMTVNTUAACAAAAAAAAAAAAAAABAoAAj2iTN/u5xGkAAAAAAAAAABQAFAAwAAAAAwAMAGgAYQB5AGEAdABlAAAAAAA= C: TlRMTVNTUAADAAAAGAAYAHAAAAAYABgAiAAAABYAFgBAAAAACAAIAFYAAAASABIAXgAAAAAAAACgAAAAAYIAAEwATwBDAEEATABEAE8ATQBBAEkATgB1AHMAZQByAEwATwBDAEEATABIAE8AUwBUAAFbwdXcoGba6LxkTycgeeGwIJ1qG4DV0McBNvTO8hBeGTjEfV6fYxVQayTslZLG7Q== S: 0002 OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE SORT THREAD=REFERENCES THREAD=REFS MULTIAPPEND UNSELECT IDLE CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH] Logged in