c# - Cómo usar SSL en la clase TcpClient
.net email (3)
En el marco .NET hay una clase TcpClient
para recuperar correos electrónicos de un servidor de correo electrónico. La clase TcpClient
tiene 4 constructores para conectarse con el servidor que toman como máximo dos parámetros. Funciona bien con aquellos servidores que no utilizan SSL. Pero gmail o muchos otros proveedores de correo electrónico usan SSL para IMAP.
Puedo conectarme con el servidor de Gmail pero no puedo autenticarme con email_id y contraseña.
Mi código para autenticar usuario es
public void AuthenticateUser(string username, string password)
{
_imapSw.WriteLine("$ LOGIN " + username + " " + password);
//_imapSw is a object of StreamWriter class
_imapSw.Flush();
Response();
}
Pero este código no puede iniciar sesión.
Entonces, ¿cómo puedo usar la clase TcpClient
para recuperar correos electrónicos cuando tengo que usar SSL?
Para adaptar la mejor respuesta anterior específicamente a la cuestión de la autenticación IMAP e IMAP, deberá modificar el código ligeramente para usar los comandos IMAP de la siguiente manera. Para la depuración, puede establecer puntos de interrupción justo después de asignar strOut para ver las respuestas del servidor.
pmOffice pmO = new pmOffice();
pmO.GetpmOffice(3, false);
TcpClient mail = new TcpClient();
SslStream sslStream;
int bytes = -1;
mail.Connect("outlook.office365.com", 993);
sslStream = new SslStream(mail.GetStream());
sslStream.AuthenticateAsClient("outlook.office365.com");
byte[] buffer = new byte[2048];
// Read the stream to make sure we are connected
bytes = sslStream.Read(buffer, 0, buffer.Length);
Console.WriteLine(Encoding.ASCII.GetString(buffer, 0, bytes));
//Send the users login details (insert your username & password in the following line
sslStream.Write(Encoding.ASCII.GetBytes("$ LOGIN " + pmO.mailUsername + " " + pmO.mailPassword + "/r/n"));
bytes = sslStream.Read(buffer, 0, buffer.Length);
string strOut = Encoding.ASCII.GetString(buffer, 0, bytes);
// Get the status of the inbox (# of messages)
sslStream.Write(Encoding.ASCII.GetBytes("$ STATUS INBOX (messages)/r/n"));
bytes = sslStream.Read(buffer, 0, buffer.Length);
strOut = Encoding.ASCII.GetString(buffer, 0, bytes);
Puede envolver el NetworkStream
proporcionado por TcpClient
con un SslStream
. Esto proporcionará el manejo necesario de SSL y certificados.
Es posible que deba insertar algún código de controlador para realizar una devolución de llamada de validación de certificado, por ejemplo, a través de ServicePointManager.ServerCertificateValidationCallback
.
SslStream utilizar SslStream junto con TcpClient luego usar SslStream para leer los datos en lugar de TcpClient.
Algo a lo largo de las líneas de:
TcpClient mail = new TcpClient();
SslStream sslStream;
mail.Connect("pop.gmail.com", 995);
sslStream = new SslStream(mail.GetStream());
sslStream.AuthenticateAsClient("pop.gmail.com");
byte[] buffer = new byte[2048];
StringBuilder messageData = new StringBuilder();
int bytes = -1;
do
{
bytes = sslStream.Read(buffer, 0, buffer.Length);
Decoder decoder = Encoding.UTF8.GetDecoder();
char[] chars = new char[decoder.GetCharCount(buffer, 0, bytes)];
decoder.GetChars(buffer, 0, bytes, chars, 0);
messageData.Append(chars);
if (messageData.ToString().IndexOf("<EOF>") != -1)
{
break;
}
} while (bytes != 0);
Console.Write(messageData.ToString());
Console.ReadKey();
EDITAR
El código anterior simplemente se conectará a través de SSL a Gmail y generará el contenido de un mensaje de prueba. Para iniciar sesión en una cuenta de gmail y emitir comandos, deberá hacer algo como:
TcpClient mail = new TcpClient();
SslStream sslStream;
int bytes = -1;
mail.Connect("pop.gmail.com", 995);
sslStream = new SslStream(mail.GetStream());
sslStream.AuthenticateAsClient("pop.gmail.com");
byte[] buffer = new byte[2048];
// Read the stream to make sure we are connected
bytes = sslStream.Read(buffer, 0, buffer.Length);
Console.WriteLine(Encoding.ASCII.GetString(buffer, 0, bytes));
//Send the users login details
sslStream.Write(Encoding.ASCII.GetBytes("USER USER_EMAIL/r/n"));
bytes = sslStream.Read(buffer, 0, buffer.Length);
Console.WriteLine(Encoding.ASCII.GetString(buffer, 0, bytes));
//Send the password
sslStream.Write(Encoding.ASCII.GetBytes("PASS USER_PASSWORD/r/n"));
bytes = sslStream.Read(buffer, 0, buffer.Length);
Console.WriteLine(Encoding.ASCII.GetString(buffer, 0, bytes));
// Get the first email
sslStream.Write(Encoding.ASCII.GetBytes("RETR 1/r/n"));
bytes = sslStream.Read(buffer, 0, buffer.Length);
Console.WriteLine(Encoding.ASCII.GetString(buffer, 0, bytes));
Obviamente, sin toda la duplicación de código :)