tags:

views:

409

answers:

1

I am writing an application which tests email addresses, for one part of this I need to send a small amount of data to an email address to validate it completely, I am currently using sockets to acomplish this.

Whilst I was testing I used a friends SMTP server to test on, and my socket worked fine, but when I tried the same thing on a big email provider (gmail, hotmail etc) it had none of it.

Now I have come to the conclusion that this is authentication and security related, so I tested sending a message to gmail using .Nets built in SmtpClient and various Mail objects using SslEnabled and giving it the credentials it asked for, this proceeded to work.

What I need to accomplish is:

sending this data without having to provide login details purely acting as an exchange. also a means to encorperate the Ssl security into my socket.

Any help with any of this would be great and much appriciated! Code below...

    /// <summary>
    /// Opens up the socket and begins trying to connect to the provided domain
    /// </summary>
    /// <param name="domain">The domain listening on SMTP ports</param>
    /// <param name="recipient">The email recipient</param>
    /// <returns>Bool verifying success</returns>
    public static bool ActivateSocket(string domain, string recipient)
    {
        //X509Certificate cert = new X509Certificate();

        //Prepare our first command
        string SMTPcommand = "HELO www.codegremlin.co.uk\r\n";
        Encoding ASCII = Encoding.ASCII;
        //convert to byte array and get the buffers ready
        Byte[] ByteCommand = ASCII.GetBytes(SMTPcommand);
        Byte[] RecvResponseCode = new Byte[3];
        Byte[] RecvFullMessage = new Byte[256];
        //method response value
        bool TransactionSuccess = false;



        try
        {
            // do all of this outside so its fresh after every iteration
            Socket s = null;
            IPEndPoint hostEndPoint;
            IPAddress hostAddress = null;
            int conPort = 587;

            // get all the ip's assosciated with the domain
            IPHostEntry hostInfo = Dns.GetHostEntry(domain);
            IPAddress[] IPaddresses = hostInfo.AddressList;

            // go through each ip and attempt a connection
            for (int index = 0; index < IPaddresses.Length; index++)
            {
                hostAddress = IPaddresses[index];
                // get our end point
                hostEndPoint = new IPEndPoint(hostAddress, conPort);

                // prepare the socket
                s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                s.ReceiveTimeout = 2000;
                s.SendTimeout = 4000;
                try { s.Connect(hostEndPoint); }
                catch { Console.WriteLine("Connection timed out..."); }

                if (!s.Connected)
                {
                    // Connection failed, try next IPaddress.
                    TransactionSuccess = false;
                    s = null;
                    continue;
                }
                else
                {
                    // im going through the send mail, SMTP proccess here, slightly incorrectly but it
                    //is enough to promote a response from the server

                    s.Receive(RecvFullMessage);
                    Console.WriteLine(ASCII.GetString(RecvFullMessage));

                    s.Send(ByteCommand, ByteCommand.Length, 0);
                    s.Receive(RecvFullMessage);
                    Console.WriteLine(ASCII.GetString(RecvFullMessage));

                    ByteCommand = ASCII.GetBytes("MAIL FROM:[email protected]\r\n");
                    s.Send(ByteCommand, ByteCommand.Length, 0);
                    s.Receive(RecvFullMessage);
                    Console.WriteLine(ASCII.GetString(RecvFullMessage));

                    ByteCommand = ASCII.GetBytes("RCPT TO:[email protected]\r\n");
                    s.Send(ByteCommand, ByteCommand.Length, 0);
                    s.Receive(RecvFullMessage);
                    Console.WriteLine(ASCII.GetString(RecvFullMessage));

                    ByteCommand = ASCII.GetBytes("DATA\r\n");
                    s.Send(ByteCommand, ByteCommand.Length, 0);
                    s.Receive(RecvFullMessage);
                    Console.WriteLine(ASCII.GetString(RecvFullMessage));

                    ByteCommand = ASCII.GetBytes("this email was sent as a test!\r\n.\r\n");
                    s.Send(ByteCommand, ByteCommand.Length, 0);
                    s.Receive(RecvFullMessage);
                    Console.WriteLine(ASCII.GetString(RecvFullMessage));

                    ByteCommand = ASCII.GetBytes("SEND\r\n");
                    s.Send(ByteCommand, ByteCommand.Length, 0);
                    s.Receive(RecvFullMessage);
                    Console.WriteLine(ASCII.GetString(RecvFullMessage));

                    ByteCommand = ASCII.GetBytes("QUIT\r\n");
                    s.Send(ByteCommand, ByteCommand.Length, 0);
                    s.Receive(RecvFullMessage);
                    Console.WriteLine(ASCII.GetString(RecvFullMessage));

                    int i = 0;
                    TransactionSuccess = true;
                }

            }


        }

        catch (SocketException e)
        {
            Console.WriteLine("SocketException caught!!!");
            Console.WriteLine("Source : " + e.Source);
            Console.WriteLine("Message : " + e.Message);
        }
        catch (ArgumentNullException e)
        {
            Console.WriteLine("ArgumentNullException caught!!!");
            Console.WriteLine("Source : " + e.Source);
            Console.WriteLine("Message : " + e.Message);
        }
        catch (NullReferenceException e)
        {
            Console.WriteLine("NullReferenceException caught!!!");
            Console.WriteLine("Source : " + e.Source);
            Console.WriteLine("Message : " + e.Message);
        }
        catch (Exception e)
        {
            Console.WriteLine("Exception caught!!!");
            Console.WriteLine("Source : " + e.Source);
            Console.WriteLine("Message : " + e.Message);
        }

        return TransactionSuccess;

    }
+2  A: 

Why exactly are you trying to implement this functionality on your own?

You should reuse an existing implementation of SMTP, otherwise you'll never get all the details of the numerous RFCs correctly implemented.

I suggest you take a second look at the SmtpClient class, since it seems to do exactly what you want to do.

There is one more thing: You are aware of the fact, that the SMTP server you need to talk to for gmail adresses is not gmail.com, right? You need to retrieve the MX records from the DNS for gmail.com and connect to one of those.

In addition to that, you shouldn't connect to any SMTP directly to deliver mail. You will not succeed if the server implements graylisting and other spam-fighting techniques. Rely on the MTA on your system to send e-mails. If you're implementing this to check for the correctness of e-mail adresses, you need to provide a working FROM address and check that mailbox for bounces from your MTA.

Storm
thanks for the quick response I'll address these points and get let you know!
DevlopingTheNextGen