First, we briefly introduce how the authenticated SMTP server uses Auth primitives to authenticate, and the detailed definition can be referred to RFC2554.
details as follows:
1) First, you need to use EHLO instead of the original HELO.
2) After the success of EHLO, the client needs to send an act of Auth, negotiate with the server for the username and password of the authentication.
3) If the negotiation is successful, the server returns the result code starting with 3, which can pass the username and password to the server.
4) Finally, if the verification is successful, you can start sending information.
Here is an actual example, the client connects to the 263 SMTP server in the Telnet SMMAND window in WinXP:
220 Welcome To Coremail System (with Anti-spam) 2.1
Ehlo 263.net
250-192.168.30.29
250-Pipelining
250-Size 10240000
250-ETRN
250-auth login
250 8bitmime
Auth login
334 vxnlcm5hbwu6
BXLHY2NVDW50
334 UGFZC3DVCMQ6
BXLWYXNZD29YZA ==
235 Authentication Successful
Mail from: myaccount@263.net
250 ok
RCPT to: myaccount@263.net
250 ok
Data
354 END DATA with
THIS IS A TESTING Email.
Haha.
.
250 ok: queued as ac5291d6406c4
Quit
221 BYE
The above content is the whole process of sending information. Among them, it is primarily related to authentication: Auth login "client input 334 vxnlcm5hbwu6" server prompt "UserName: =" bxlhy2nvdw50 "client Enter" MyAccount = "Base64 Code 334 UGFZC3DVCMQ6" Server Tips " Password: = "bxlwyxnzd29yza ==" Client Enter "Mypassword =" Base64 Code 235 Authentication Success Eti server side can see the analysis from above, during this authentication process, both the server and client pass directly through Socket The standard base64 encoded plain text. This process can be very convenient to use C # implementation or directly to the original source code. In addition, some ESMTP servers do not support authentication of Auth login, only supporting Auth CRAM-MD5 mode verification. However, the difference between the two is only different from the coding method of the text. Source code to implement this function can be downloaded on the sourceforge.net/projects/opensmtp-net/. Here is a simple pseudo code: public void sendmail (MailMessage MSG) {networkStream nWSTream = getConnection ();
WriteToStream (ref nwstream, "EHLO" smtpHost "/ r / n"); string welcomeMsg = ReadFromStream (ref nwstream);. // implement HELO command if EHLO is unrecognized if (IsUnknownCommand (welcomeMsg)) {WriteToStream (ref nwstream , "Helo" SMTPHOST "/ R / N");} Checkfor erroRR (WelcomeMSG, ReplyConstants.ok);
// Authentication is buy ly the u / p area support Authlogin (Ref nwstream);
WrittoTream (Ref NWSTREAM, "Mail from: <" msg.from.address "> / r / n"); CheckForr (Ref nwstream), ReplyConstants.ok;
SendrecipientList (Ref NWSTREAM, MSG.TO); SendRecipientList (Ref NWSTREAM, MSG.CC); SendRecipientList (Ref NWSTREAM, MSG.BCC);
WrittoTream (Ref NWSTREAM, "DATA / R / N"); CheckForr (ReadFromstream (Ref nwstream), replyconstants.start_input);
IF (msg.replyto.name! = null && msg.replyto.name.length! = 0) {WrittoTream (Ref nwstream, "reply-to: /" msg.replyto.name "/" <" msg .Replyto.address "> / r / n");} else {WRITETREAM (Ref nwstream, "reply-to: <" msg.replyto.address "> / r / n");} IF (MSG. From.name! = Null && msg.from.name.length! = 0) {WrittoTream (Ref nwstream, "from: /" " msg.from.name " / "<" msg.from.address " > / r / n ");} else {WrittoTream (Ref NWSTREAM," from: <" msg.from.address "> / r / n ");} WrittoTream (Ref NWSTREAM," To: " CreateAddressList ( Msg.to) "/ r / n"); if (msg.cc.count! = 0) {WRITETREAM (Ref nwstream, "CC:" CreateAddressList (msg.cc) "/ r / n"); } WRITETOSTREAM (Ref NWSTREAM, "Subject:" Msg.Subject "/ R / N");
IF (Msg.Priority! = null) {WrittoTream (Ref nwstream, "x-priority: msg.priority " / r / n ");}
IF (Msg.Headers.count> 0) {SendHeaders (REF NWSTREAM, MSG);} if (msg.attachments.count> 0 || msg.htmlbody! = null) {SendMessageBody (Ref NWSTREAM, MSG);} else { WrittoTream (REF NWSTREAM, MSG.BODY "/ R / N);} WritentStream (Ref nwstream," /R/n./r/N "); CheckForr (REPLYCONSTREAM, ReplyConstants.ok); WritetostReam (Ref nwstream, "quit / r / n"); CheckForer (ReplyConstants.quit); CloseConnection ();}