SMTP AUTH LOGIN Cram-Md5認証
public static void ConnectCramMd5( string server, int port, string user, string pass ) {
var client = new TcpClient();
client.Connect( server, port );
var stream = new SslStream( client.GetStream() );
stream.AuthenticateAsClient(server);
ReceiveString( stream );
SendAndReceive( stream, string.Format( "EHLO {0}\r\n", Dns.GetHostName() ) );
var code = PickChallengeCode( SendAndReceive( stream, "AUTH CRAM-MD5\r\n" ) );
var source = string.Format( "{0} {1}", user, GetAsciiToHMACMD5( Base64ToAscii( code ), pass ) );
SendAndReceive( stream, AsciiToBase64( source ) + "\r\n" );
SendAndReceive( stream, "QUIT\r\n" );
}
static string PickChallengeCode( string source ) {
return source.Split(' ')[1];
}
static string GetAsciiToHMACMD5( string value, string key ) {
var hmacmd5 = new HMACMD5( Encoding.ASCII.GetBytes( key ) );
var hashBytes = hmacmd5.ComputeHash( Encoding.ASCII.GetBytes( value ) );
return BitConverter.ToString( hashBytes ).Replace( "-", "" ).ToLower();
}
static private string SendAndReceive( Stream stream, string request ) {
SendString( stream, request );
return ReceiveString( stream );
}
private static void SendString( Stream stream, string request ) {
var sendData = _encoding.GetBytes( request );
stream.Write( sendData, 0, sendData.Length );
stream.Flush();
Console.WriteLine( "< " + request );
}
private static string ReceiveString( Stream stream ) {
byte[] buff = new byte[1024 * 1024 - 1];
int receiveSize = stream.Read( buff, 0, buff.Length );
if ( receiveSize > 0 ) {
Array.Resize( ref buff, receiveSize - 2 );
var res = _encoding.GetString( buff );
Console.WriteLine( "> " + res );
return res;
}
throw new Exception( "Read Error." );
}
static string Base64ToAscii( string base64 ) {
var buff = Convert.FromBase64String( base64 );
return Encoding.ASCII.GetString( buff );
}
static string AsciiToBase64( string s ) {
var buff = Encoding.ASCII.GetBytes( s );
return Convert.ToBase64String( buff );
}