public AuthMechanismProcessorStatus ProcessResponse(string data) { if (_challenge == null) { StringBuilder challenge = new StringBuilder(); challenge.Append(_random.Next(Int16.MaxValue)); challenge.Append("."); challenge.Append(DateTime.Now.Ticks.ToString()); challenge.Append("@"); challenge.Append(Connection.Server.Behaviour.DomainName); _challenge = challenge.ToString(); string base64Challenge = Convert.ToBase64String(Encoding.ASCII.GetBytes(challenge.ToString())); Connection.WriteResponse(new SmtpResponse(StandardSmtpResponseCode.AuthenticationContinue, base64Challenge)); return AuthMechanismProcessorStatus.Continue; } else { string response = DecodeBase64(data); string[] responseparts = response.Split(' '); if (responseparts.Length != 2) { throw new SmtpServerException(new SmtpResponse(StandardSmtpResponseCode.AuthenticationFailure, "Response in incorrect format - should be USERNAME RESPONSE")); } string username = responseparts[0]; string hash = responseparts[1]; Credentials = new CramMd5AuthenticationRequest(username, _challenge, hash); AuthenticationResult result = Connection.Server.Behaviour.ValidateAuthenticationCredentials(Connection, Credentials); switch (result) { case AuthenticationResult.Success: return AuthMechanismProcessorStatus.Success; default: return AuthMechanismProcessorStatus.Failed; } } }