SMTP


Simple Mail Transfer Protocol (SMTP)

SMTP is used to move email from a client to a mail server. Once the email is in the mail server, it is responsible to deliver the email. The mail server has specific algorithms to ensure that emails are correctly delivered even when problems in the network or in other servers are present. The server usually listens to port 25 for SMTP incoming calls.
El SMTP es usado para mover correo electrónico desde un cliente a un servidor de correo. Una vez que el correo electrónico está en el servidor de correo, este es responsable de distribuir el correo. El servidor de correo tiene algoritmos específicos para garantizar que los correos electrónicos sean correctamente distribuidos aun cuando problemas en la red o en otros servidores están presentes. El servidor usualmente escucha el puerto 25 por solicitudes SMTP.

Tip
The figure below shows how SMTP works. As soon as the server receives the request, it answers with a 220 code that indicates the type of SMTP server. The client must send a HELO command providing the name of the client computer. The server, then, will request the authorization by sending two 334 codes, one for the username and another one for the password. Observe that the 334 code uses the Base 64 coding in its response, and the client must use Base 64 in its reply to the server. If the username is authorized, the server will send a 235 code. The client must provide two email address as shown: from and to. The DATA response is sent to the server to indicate that the email data will be sent. The client sends the email body (and attachments using Base 64 coding). Two blank lines a period and two additional blank lines are sent to the mail server by the client to notify the all email data have been sent. The server must response with a 250, code if all data was successfully received. The client may send another email or quit.
La figura de abajo muestra como SMTP opera. Tan pronto como el servidor recibe la solicitud, este contesta con un código 220 que indica el tipo de servidor SMTP. El cliente debe enviar un comando HELO proporcionando el nombre de la computadora cliente. El servidor, entonces, solicitará la autorización enviando dos códigos 334. uno para el nombre del usuario y otro para su clave de acceso. Observe que los dos códigos 334 usan la codificación Base 64 en su respuesta, y el cliente debe usar Base 64 en su contestación al servidor. Si el nombre de usuario es autorizado, el servidor enviará un código 235. El cliente debe proporcionar dos direcciones de correo electrónico como se muestra: from y to. La respuesta DATA es enviada al servidor para indicar que los datos del correo electrónico se enviarán. El cliente envía el cuerpo del correo electrónico (y archivos adjuntos usando la codificación Base 64). Dos líneas vacías un punto y dos líneas vacías adicionales son enviadas al servidor de correo por el cliente para notificar que todos los datos del correo electrónico han sido enviados. El servidor debe responder con un código 250, si todos los datos fueron recibidos en forma exitosa. El cliente puede enviar otro correo electrónico o salirse.

smtp

Tip
Sockets place data in a buffer or pipe as shown in the figure below. You must read the socket to remove data from the buffer so that you can see new data. Thus if you do not read an SMTP code, this will be storage until the next read.
Los sockets colocan datos en un buffer o pipe como se muestra en la figura de abajo. Usted debe leer el sockect para remover los datos del buffer para que usted pueda ver los nuevos datos. Así si usted no lee un código de SMTP, este será almacenado hasta la próxima lectura.

pipe

DATA

The DATA field in SMTP may have subfields to send additional information about the email, these subfields are:
  • Date:
  • From:
  • Sender:
  • Reply-to:
  • Subject:
  • MIME-Version:
  • Content-Type:
The body of the mail message is begins with a DATA command after which it is transmitted line by line and is terminated with the sequence: Carriage Return, Line Feed, Dot, Carriage Return, Line Feed (\r\n.\r\n) Since a message body can contain a line with just a period as part of the text, the client sends two periods (dots) every time a line starts with a period.
El campo DATA en SMTP puede tener sub-campos para enviar información adicional acerca del correo electrónico, estos campos son:
  • Date:
  • From:
  • Sender:
  • Reply-to:
  • Subject:
  • MIME-Version:
  • Content-Type:
El cuerpo del mensaje de un correo electrónico comienza con el comando DATA el cual se transmite línea por línea y termina con la secuencia: Retorno de Carro, Línea Nueva, Punto, Retorno de Carro, Línea Nueva(\r\n.\r\n) Puesto que un cuerpo de mensaje puede contener una línea con un sólo punto como parte del texto, el cliente debe enviar dos puntos seguidos cada vez que una línea comienza con un punto.

Simple text email

The example below shows how to use the DATA subfields to send a simple text email.
El ejemplo de abajo muestra cómo usar los sub-campos de DATA para enviar un correo con texto sencillo.

Simple text email example

MAIL FROM: <ja.xolocotzibautista@ugto.mx>
RCPT TO: <punkyboy2099@hotmail.com>
DATA
Date: Tue, 15 NOV 11 11:45:30 -0600
From: "Jose Augusto " <ja@ugto.mx>
Sender: ja@ugto.mx
Reply-to: "Jose Augusto" <ja@ugto.mx>
Subject: Happy birthday
To: "Sergio Amaya" <punkyboy2099@hotmail.com>
Let's get together on the weekend to celebrate!
\r\n.\r\n

HTML email

The example below shows how to use the DATA subfields to send an HTML email. All HTML and CSS tags can be used in this type of emails expanding the flexibility in the email content.
El ejemplo de abajo muestra cómo usar los sub-campos de DATA para enviar un correo en HTML. Todas las etiquetas de HTML y CSS son válidas en este tipo de correos expandiendo la flexibilidad del contenido en los correos.

HTML email example

MAIL FROM: <ja@ugto.mx>
RCPT TO: <punkyboy2099@hotmail.com>
DATA
Date: Tue, 15 NOV 11 11:45:30 -0600
From: "Jose Augusto" <ja@ugto.mx>
Sender: ja@ugto.mx
Reply-to: "Jose Augusto" <ja@ugto.mx>
Subject: Happy birthday
To: "Sergio Amaya" <punkyboy2099@hotmail.com>
MIME-Version: 1.0
Content-type: text/html; charset=ISO-8859-1
<html>Let's get together on the <b>weekend</b> to celebrate!</html>
\r\n.\r\n

Multi-part email

A multipart email is used to send attachments, or emails in several formats. A boundary that is not included in the message must de designed to separate the parts of the email. The example below shows how to send a GIF image in an attached file. The boundary used in the example below is XYZ25678. Note that each part of the message is separate by --XYZ25678, while the last boundary is --XYZ25678--.
Un correo con partes múltiples es usado para enviar archivos adjuntos, o correos electrónicos en varios formatos. Una boundary o frontera que no se incluya en el mensaje debe ser designada para separar las partes del correo electrónico. El ejemplo de abajo muestra como se puede enviar una imagen del tipo GIF en un archivo adjunto. La frontera usada en el ejemplo de abajo es XYZ25678. Note que cada parte del mensaje está separada por --XYZ25678, mientras que la última frontera es --XYZ25678--.

Multi-part email example

MAIL FROM: <ja@ugto.mx>
RCPT TO: <punkyboy2099@hotmail.com>
DATA
Date: Tue, 15 NOV 11 11:45:30 -0600
From: "Jose Augusto" <ja@ugto.mx>
Sender: ja@ugto.mx
Reply-to: "Jose Augusto" <ja@ugto.mx>
Subject: Happy birthday
To: "Sergio Amaya" <punkyboy2099@hotmail.com>
MIME-Version: 1.0
Content-type: multipart/mixed; boundary="XYZ25678"
--XYZ25678
Content-type: text/html; charset=ISO-8859-1
/r/n
<html>Let's get together on the <b>weekend</b> to celebrate!</html>
/r/n
--XYZ25678
Content-type: image/gif;
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="john.gif";
/r/n
Image data in Base 64
/r/n
--XYZ25678--

SMTP Server

Inside the University of Guanajuato you may try to use mailhost.ugto.mx with port 25. From home, you may try to use smtp.gmail.com or smtp.live.com with port 587.
Dentro de la Universidad de Guanajuato usted puede tratar de usar mailhost.ugto.mx con el puerto 25. Desde casa, usted puede tratar de usar smtp.gmail.com o smtp.live.com en el puerto 587.

Problem 1
Create a program called EmailOut to send email using SMTP. You may use the Sys::Convert class to code and undecode Base 64.
Cree un programa llamado EmailOut para enviar correo electrónico usando SMTP. Usted puede usar la clase Sys::Convert para codificar y decodificar Base 64.

EmailOutRun

EmailOut.cpp
#include "stdafx.h" //________________________________________ EmailOut.cpp
#include "EmailOut.h"

int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE , LPTSTR cmdLine, int cmdShow){
     EmailOut app;
     return app.BeginDialog(IDI_EMAILOUT, hInstance);
}

void EmailOut::Window_Open(Win::Event& e)
{
}

void EmailOut::btSend_Click(Win::Event& e)
{
     Sys::Socket skt;
     char buffer[256];
     int code = -1;
     int bytes = 0;
     //________________________________ CONNECT
     if (skt.Connect(L"mailhost.ugto.mx", 25) == SOCKET_ERROR)
     {
          this->MessageBox(skt.GetLastErrorDesc(), L"EmailOut", MB_OK | MB_ICONERROR);
          return;
     }
     //
     code = skt.ReceiveCode();
     if (code != 220)
     {
          this->MessageBox(L"220 Unable to connect", L"EmailOut", MB_OK | MB_ICONERROR);
          return;
     }
     //______________________________ HELO
     _snprintf_s(buffer, 256, _TRUNCATE, "HELO mycomputer\r\n");
     bytes = skt.Send(buffer);
     if (bytes <= 0)
     {
          this->MessageBox(L"Unable to send HELO", L"EmailOut", MB_OK | MB_ICONERROR);
          return;
     }

     //...
     //______________________________ QUIT
     bytes = skt.Send("QUIT\r\n");
     if (bytes <= 0)
     {
          ...
     }
     code = skt.ReceiveCode();
     if (code != 221)
     {
          ...
     }
     skt.Disconnect();
}

Problem 2
Create a program called EmailHtml to send HTML email using SMTP.
Cree un programa llamado EmailHtml para enviar correo electrónico en HTML usando SMTP.

EmailHtmlRun

EmailHtmlReceive

Problem 3
Modify the project of problem 3 in Wintempla > Sockets > Secure Socket to send email using SSL (SP_PROT_SSL3) on port 465 in the SMTP server: smtp.mail.yahoo.ca. Add a multiline textbox to display the SMTP conversation. For a gmail account, you need to modify your account setup (send and email POP/IMAP) by enabling IMAP (SMTP).
Modifique el proyecto el problema 3 en Wintempla > Sockets > Secure Socket para enviar un correo usando SSL (SP_PROT_SSL3) en el puerto 465 en el servidor de SMTP: smtp.mail.yahoo.ca. Agregue una caja de texto con la propiedad de multi-línea para mostrar la conversación de SMTP. Para una cuenta de gmail, usted necesita modificar la configuración de la cuenta (enviar y correo POP/IMAP) habilitando IMAP (SMTP).

SecureEmailGui

SecureEmail.cpp
...

void SecureEmail::btSend_Click(Win::Event& e)
{
     const wchar_t* servername = L"smtp.gmail.com";
     //const wchar_t* servername = L"smtp.mail.yahoo.ca";
     const int port = 465;
     const DWORD protocol =SP_PROT_TLS1;
     //const DWORD protocol = SP_PROT_SSL3;
     //_____________________________________________________________________ Create Credentials
     Sys::SecuritySupportProvider ssp;
     SECURITY_STATUS status;
     status = ssp.CreateCredentials(protocol);
     if (status != SEC_E_OK)
     {
          this->MessageBox(ssp.GetErrorDescr(status), L"SecureEmail", MB_OK | MB_ICONERROR);
          return;
     }
     //____________________________________________________________________ Create socket and connect
     Sys::Socket socket;
     if (socket.Connect(servername, port) == SOCKET_ERROR)
     {
          this->MessageBox(socket.GetLastErrorDesc(), L"SecureEmail", MB_OK | MB_ICONERROR);
          return;
     }
     //____________________________________________________________ Handshake
     status = ssp.ClientHandshake(socket, servername);
     if (status != SEC_E_OK)
     {
          this->MessageBox(ssp.GetErrorDescr(status), L"SecureEmail", MB_OK | MB_ICONERROR);
          return;
     }
     //____________________________________________________________ Get Certificate
     Sys::SecurityCertificate certificate;
     status = ssp.GetCertificate(certificate);
     if (status != SEC_E_OK)
     {
          this->MessageBox(ssp.GetErrorDescr(status), L"SecureEmail", MB_OK | MB_ICONERROR);
          return;
     }
     ////____________________________________________________________ Display Certificate
     //wstring info;
     //certificate.GetDisplayInfo(true, info);
     //this->MessageBox(info, L"Certificate Info", MB_OK);
     //_____________________________________________________________Verify Certificate
     const int verify = certificate.Verify(servername, 0);
     if (verify != S_OK)
     {
          if (verify == S_FALSE)
          {
               Sys::DisplayLastError(hWnd, L"SecureEmail");
          }
          else
          {
               this->MessageBox(certificate.GetErrorDesc(verify), L"SecureEmail", MB_OK | MB_ICONERROR);
          }
          ssp.DisconnectFromServer(socket);
          socket.Disconnect();
          return;
     }
     //_____________________________________________________________ 1. Receive 220
     string text;
     wstring wtext;
     int code = ssp.ReceiveCode(socket, text);
     Sys::Convert::StringToWstring(text, wtext);
     if (code != 220)
     {     

          this->MessageBox(wtext, L"SecureEmail", MB_OK | MB_ICONERROR);
          ssp.DisconnectFromServer(socket);
          socket.Disconnect();
          return;
     }
     tbxOutput.Text += wtext;
     tbxOutput.Text += L"\r\n";
     //_____________________________________________________________ 2. Send HELO\r\n
     string myComputer;
     wstring wmyComputer;
     Sys::Information::getEnvironmentVariable(L"COMPUTERNAME", wmyComputer);
     Sys::Convert::WstringToString(wmyComputer, myComputer);
     char buffer[256];
     _snprintf_s(buffer, 256, _TRUNCATE, "HELO %s\r\n", myComputer.c_str());
     if (ssp.Send(socket, buffer) <= 0)
     {
          this->MessageBox(L"Error sending HELO", L"SecureEmail", MB_OK | MB_ICONERROR);
          ssp.DisconnectFromServer(socket);
          socket.Disconnect();
          return;
     }
     Sys::Convert::StringToWstring(buffer, wtext);
     tbxOutput.Text += wtext;
     tbxOutput.Text += L"\r\n";
     //________________________________________ 3. Recv 250 HELO
     ...     
     //________________________________________ 4. Send AUTH LOGIN\r\n
     ...
     //________________________________________ 5. Recv "Username:" in Base64
     ...
     //________________________________________ 6. Send my username (my email address)
     string text_base64;
     Sys::Convert::WstringToString(tbxUsername.Text, text);
     Sys::Convert::Base64BitEncode(text.c_str(), (int)text.length(), text_base64);
     text_base64 += "\r\n";
     if (ssp.Send(socket, text_base64.c_str()) <= 0)
     {
          this->MessageBox(L"Error sending username", L"SecureEmail", MB_OK | MB_ICONERROR);
          ssp.DisconnectFromServer(socket);
          socket.Disconnect();
          return;
     }
     Sys::Convert::StringToWstring(text_base64, wtext);
     tbxOutput.Text += wtext;
     tbxOutput.Text += L"\r\n";
     //________________________________________ 7. Recv "Password:" in Base64
     ...
     //_________________________________________8. Send my password
     ...
     //_________________________________________ 9. Recv 235 OK
     ...
     //_________________________________________10. Send MAIL FROM\r\b
     ...
     //_________________________________________ 11. Recv 250 OK
     ...
     //_________________________________________ 12 Send RCPT TO
     ...
     //_________________________________________ 13. Recv 250 OK
     ...
     //__________________________________________14. Send DATA
     ...
     //_________________________________________ 15.Send Date:
     ...
     //_________________________________________ 16. Send From:
     ...
     //_________________________________________ 17. Send Sender:
     ...
     //_________________________________________ 18: Send Reply-to:
     ...
     //_________________________________________19. Send Subject:
     ...
     //_________________________________________20: Send To:
     ...
     //_________________________________________20.1 Send MIME-Version:1.0
     ...
     //_________________________________________20.2 Send Content type: text/html
     ...
     //_________________________________________20.3 Send "message"
     ...
     //_________________________________________ 21. Send DATA End
     ...
     //_________________________________________ 22. Send Quit
     ...
     //_________________________________________ 23. Disconnect
     ssp.DisconnectFromServer(socket);
     socket.Disconnect();
}


Yahoo Canada

Incoming Mail (POP) Server - Requires SSL
  • Server - pop.mail.yahoo.com
  • Port - 995
  • Requires SSL - Yes
Outgoing Mail (SMTP) Server - Requires TLS
  • Server - smtp.mail.yahoo.com
  • Port - 465 or 587
  • Requires SSL - Yes
  • Requires authentication - Yes
If your POP client doesn't offer TLS, you'll still be able to use SSL.
Login info - Requires authentication
  • Email address - Your full email address (name@yahoo.ca.)
  • Password - Your account's password.

Server

A server program is one of the most complexes because:
  • Tries keeping a conversation despite the unexpected behavior of some clients
  • Tries serving all the clients using the minimum number of resources
  • Tries waiting for the clients
  • Decides not to wait when the client does no answer because a network problem
  • Must be very efficient. In most cases the languages C or C++ are used to write server programs

El programa servidor es uno de los más sofisticados porque:
  • Trata de mantener una conversación a pesar que los clientes se comporten de forma inesperada
  • Trata de atender a todos sus clientes con el menor número de recursos
  • Trata de esperar a los clientes en forma razonable
  • Decide no esperar cuando el cliente no contesta debido a un problema de red
  • Deben ser muy eficiente. Casi siempre se usan los lenguajes C o C++ para hacer programas en el servidor

© Copyright 2000-2019 Wintempla selo. All Rights Reserved. Sep 05 2019. Home