Abstract This article introduces how to enhance the NMSMTP Control Function of sending emails in BCB to implement the mail sending program with the identity authentication function.
Key words: ESMTP, MIME, identity authentication
Introduction
To effectively suppress the spread of spam, the identity authentication function of ESMTP is currently used in the mail sending and receiving systems of most websites. That is, when a user sends an email, the user's identity must be verified. If the account or password is incorrect, the email server rejects sending the email. Borland C ++ Builder 6 has a variety of controls for developers, including the mail sending control NMSMTP, which is convenient to use, however, the only drawback is that it does not support identity authentication when sending emails. Based on the analysis of the mail sending protocol, the author designs the mail sending program with the identity authentication function on the basis of the use of controls.
ESMTP protocol analysis
To implement the identity authentication function, some content is added to the ESMTP protocol, which is identity authentication. Next, let's take a look at this authentication process, taking the author's mailbox on Netease as an example (C indicates the client, S indicates the mail server ):
(1) C: AUTH LOGIN
(2) S: 334 dXNlcm5hbWU6
(3) C: d3lxX2puX3NkX2Nu
(4) S: 334 UGFzc3dvcmQ6
(5) C: Skip the password
(6) S: 235 Authentication successful
Detailed description:
(1) the client sends authentication commands to the server.
(2) The server returns a Base64 encoded string. 334 indicates success. The encoded string is decoded as "username:", indicating that the user name must be sent from the client.
(3) The username string sent by the client in Base64 encoding. "wyq_jn_sd_cn" is used here ".
(4) The server returns a Base64 encoded string. 334 indicates success. The decoded string is "password:", indicating that the client needs to send the user password.
(5) the client sends a Base64 encoded password string, which is omitted here.
(6) The server returns a normal string. The value 235 indicates that authentication is successful and an email can be sent.
MIME Base64 encoding explanation
Generally, an 8-bit byte is encoded by a computer, and 0--FF is a 256 different 8-bit combination. The Base64 encoding we want to introduce now is 6 bits per byte, with a total of 26 = 64 combinations. Each combination corresponds to one character, which is "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567 89 + /. this means that each three common encodings can be converted to four Base64 encodings. What if the common encoding to be converted is not an integer multiple of three? Base64 requires that the number of bytes with less than a few digits is supplemented by 0, and then the number of = is supplemented by a few characters.
Design Concept
We can use the NMSMTP control to connect to the mail server. Call the Connect method and then listen to the OnConnect event. In the OnConnect event, we can add the identity authentication function. Here, we mainly use some basic network communication functions inherited by NMSMTP from Powersock, including Read, DataAvailable, and SendBuffer to implement identity authentication. If the identity authentication is successful, you can continue sending the email; otherwise, an error message is prompted to disconnect the network.
Program Implementation
Use BCB to design the form shown in 1.
Figure 1 Main Program Interface
1. Call the connection function in The OnClick event of the logon button.
Void _ fastcall TForm1: Logon1Click (TObject * Sender)
{
AddLog ("logging on" + Edit1-> Text + "......");
NMSMTP1-> Host = Edit1-> Text; // Host address
NMSMTP1-> Port = 25; // host Port. The default value is 25.
NMSMTP1-> UserID = Edit4-> Text; // User Name
NMSMTP1-> Connect (); // Connect to the host
}
2. Handling OnConnect events
Void _ fastcall TForm1: NMSMTP1Connect (TObject * Sender)
{
AddLog ("the server is connected successfully. ");
AnsiString Data = "", rData = "";
Bool B _ OK;
If (CheckBox1-> Checked ){
Data = "auth login"; // Logon Request command
NMSMTP1-> SendBuffer (Data. c_str (), Data. Length (); // Command issued
RData = WaitForReply (5); // wait for receiving the returned data, which must be returned within 5 seconds
B _ OK = false;
If (rData. Length ()> = 3 ){
// 334 means that the server requires the user name
If (rData. TrimLeft (). SubString (334) = "){
AddLog ("verifying identity ......");
B _ OK = true;
}
}
If (! B _ OK ){
AddLog ("Logon Failed, exiting ......");
NMSMTP1-> Disconnect ();
Return;
}
RData = "";
Data = encode (Edit4-> Text) + "; // convert the username to Base64 encoding.
NMSMTP1-> SendBuffer (Data. c_str (), Data. Length (); // user name for sending
RData = WaitForReply (5 );
B _ OK = false;
If (rData. Length ()> = 3 ){
// 334 indicates that the server requires a password
If (rData. TrimLeft (). SubString (334) = "){
AddLog ("verifying password ......");
B _ OK = true;
}
}
If (! B _ OK ){
AddLog ("Logon Failed, exiting ......");
NMSMTP1-> Disconnect ();
Return;
}
RData = "";
Data = encode (Edit5-> Text) + "; // convert the password to Base64 encoding.
NMSMTP1-> SendBuffer (Data. c_str (), Data. Length (); // send a password
RData = WaitForReply (5 );
B _ OK = false;
If (rData. Length ()> = 3 ){
If (rData. TrimLeft (). SubString (235) = "){
AddLog ("Login successful ......");
B _ OK = true;
}
}
If (! B _ OK ){
AddLog ("Logon Failed, exiting ......");
NMSMTP1-> Disconnect ();
Return;
}
}
SendMail-> Enabled = true; // you can send emails.
Disconnect-> Enabled = true; // disconnect allowed
Logon1-> Enabled = false; // you cannot log on again.
}
3. MIME Base64 encoding and conversion
AnsiString TForm1: encode (AnsiString s)
{
Int m_len; // String Length
Int I; // cyclic variable
Int m_tmp; // Temporary Variable
AnsiString m_64code; // stores Base64 encoded strings
Char * m_s; // temporary storage parameter string
// Base64 sequence table
Char m_64 [] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 + /";
M_len = s. Length (); // obtain the string Length.
M_s = s. c_str ();
M_64code = ""; // The return string is null.
// Process characters less than 3
For (I = 0; I <m_len-m_len % 3; I + = 3 ){
M_tmp = m_s [I]/4;
M_64code + = m_64 [m_tmp];
M_tmp = m_s [I] % 4*16 + m_s [I + 1]/16;
M_64code + = m_64 [m_tmp];
M_tmp = m_s [I + 1] % 16*4 + m_s [I + 2]/64;
M_64code + = m_64 [m_tmp];
M_tmp = m_s [I + 2] % 64;
M_64code + = m_64 [m_tmp];
}
// If the length of the string is divided by 3 to 2, the number of digits that are insufficient is supplemented by 0, and the end is supplemented by "="
If (m_len % 3 = 2 ){
M_tmp = m_s [m_len-2]/4;
M_64code + = m_64 [m_tmp];
M_tmp = m_s [m_len-2] % 4*16 + m_s [m_len-1]/16;
M_64code + = m_64 [m_tmp];
M_tmp = m_s [m_len-1] % 16*4;
M_64code + = m_64 [m_tmp];
M_64code + =;
}
// If the length of the string is divided by 3 and the remainder is 1, the number of digits below is supplemented by 0, and the end is supplemented by two "="
If (m_len % 3 = 1 ){
M_tmp = m_s [m_len-1]/4;
M_64code + = m_64 [m_tmp];
M_tmp = m_s [m_len-1] % 4*16;
M_64code + = m_64 [m_tmp];
M_64code + = "= ";
}
Return m_64code;
}
Conclusion
In Windows 2000, this program is compiled and debugged Using Borland C ++ Builder 6.0. By doing experiments using Netease And Sina Mail respectively, identity authentication and email sending functions can be successfully completed.