Smtp.cs :  » Network-Clients » OpenSmtp.net » OpenSmtp » Mail » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Network Clients » OpenSmtp.net 
OpenSmtp.net » OpenSmtp » Mail » Smtp.cs
namespace OpenSmtp.Mail{

/******************************************************************************
  Copyright 2001-2005 Ian Stallings
  OpenSmtp.Net is free software; you can redistribute it and/or modify
  it under the terms of the Lesser GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  OpenSmtp.Net is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  Lesser GNU General Public License for more details.

  You should have received a copy of the Lesser GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
/*******************************************************************************/


using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Collections;

  /// <summary>
  /// This Type sends a MailMessage using SMTP
  /// <seealso cref="EmailAddress"/>
  /// <seealso cref="MailMessage"/>
  /// <seealso cref="SmtpConfig"/>
  /// </summary>
  /// <example>
  /// <code>
  ///    from = new EmailAddress("support@OpenSmtp.com", "Support");
  ///    to = new EmailAddress("recipient@OpenSmtp.com", "Joe Smith");
  ///
  ///    msg = new MailMessage(from, to);
  ///    msg.Subject = "Testing OpenSmtp .Net SMTP component";
  ///    msg.Body = "Hello Joe Smith.";
  /// 
  ///    Smtp smtp = new Smtp("localhost", 25);
  ///    smtp.SendMail(msg);
  /// </code>
  /// </example>
  public class Smtp
  {
    internal TcpClient   tcpc;
    internal string   host;
    internal int     port = 25;
    internal string   username;
    internal string   password;

    internal int     sendTimeout = 50000;
    internal int     recieveTimeout = 50000;
    internal int     receiveBufferSize = 1024;
    internal int     sendBufferSize = 1024;
    
    /// <summary>Default constructor</summary>
    /// <example>
    /// <code>
    ///   Smtp smtp = new Smtp();
    ///   smtp.Host = "mail.OpenSmtp.com";
    ///   smtp.Port = 25;
    /// </code>
    /// </example>
    public Smtp()
    {}
    

    /// <summary>Constructor specifying a host and port</summary>
    /// <example>
    /// <code>
    ///   Smtp smtp = new Smtp("mail.OpenSmtp.com", 25);
    /// </code>
    /// </example>
    public Smtp(string host, int port) 
    {
      this.host = host;
      this.port = port;
    }

    /// <summary>Constructor specifying a host, username and password</summary>
    /// <example>
    /// <code>
    ///   Smtp smtp = new Smtp("mail.OpenSmtp.com", "login", "pwd");
    /// </code>
    /// </example>
    public Smtp(string host, string username, string password)
    {
      this.Host = host;
      this.Port = port;
      this.Username = username;
      this.Password = password;
    }

    /// <summary>Constructor specifying a host, username, password and port</summary>
    /// <example>
    /// <code>
    ///   Smtp smtp = new Smtp("mail.OpenSmtp.com", "login", "pwd", 25);
    /// </code>
    /// </example>
    public Smtp(string host, string username, string password, int port)
    {
      this.Host = host;
      this.Port = port;
      this.Username = username;
      this.Password = password;
    }

    //========================================================================
    // PROPERTIES
    //========================================================================

    /// <value>Stores the Host address SMTP server. The default value is "localhost"</value>
    /// <example>"mail.OpenSmtp.com"</example>
    public string Host
    {
      get { return(this.host); }
      set { this.host = value; }
    }    

    /// <value>Stores the Port of the host SMTP server. The default value is port 25</value>
    public int Port
    {
      get { return(this.port); }
      set { this.port = value; }
    }
    
    /// <value>Stores send timeout for the connection to the SMTP server in milliseconds.
    /// The default value is 10000 milliseconds.</value>
    public int SendTimeout
    {
      get { return this.sendTimeout; }
      set { sendTimeout = value; }
    }

    /// <value>Stores send timeout for the connection to the SMTP server in milliseconds.
    /// The default value is 10000 milliseconds.</value>
    public int RecieveTimeout
    {
      get { return this.recieveTimeout; }
      set { recieveTimeout = value; }
    }

    /// <value>Stores the username used to authenticate on the SMTP server.
    /// If no authentication is needed leave this value blank.</value>
    public string Username
    {
      get { return this.username; }
      set { username = value; }
    }

    /// <value>Stores the password used to authenticate on the SMTP server.
    /// If no authentication is needed leave this value blank.</value>
    public string Password
    {
      get { return this.password; }
      set { password = value; }
    }

    //========================================================================
    // EVENTS
    //========================================================================
    
    /// <value>Event that fires when connected with target SMTP server.</value>
    public event EventHandler Connected;
    
    /// <value>Event that fires when dicconnected with target SMTP server.</value>
    public event EventHandler Disconnected;
    
    /// <value>Event that fires when authentication is successful.</value>
    public event EventHandler Authenticated;
    
    /// <value>Event that fires when message transfer has begun.</value>
    public event EventHandler StartedMessageTransfer;
    
    /// <value>Event that fires when message transfer has ended.</value>
    public event EventHandler EndedMessageTransfer;
    
    internal void OnConnect(EventArgs e)
    {
      if (Connected != null)
        Connected(this, e);
    }

    internal void OnDisconnect(EventArgs e)
    {
      if (Disconnected != null)
        Disconnected(this, e);
    }
        
    internal void OnAuthenticated(EventArgs e)
    {
      if (Authenticated != null)
        Authenticated(this, e);
    }

    internal void OnStartedMessageTransfer(EventArgs e)
    {
      if (StartedMessageTransfer != null)
        StartedMessageTransfer(this, e);
    }
    
    internal void OnEndedMessageTransfer(EventArgs e)
    {
      if (EndedMessageTransfer != null)
        EndedMessageTransfer(this, e);
    }

    //========================================================================
    // METHODS
    //========================================================================
    
    /// <summary>Sends a mail message using supplied MailMessage properties as string params</summary>
    /// <param name="from">RFC 822 formatted email sender address</param>
    /// <param name="to">RFC 822 formatted email recipient address</param>
    /// <param name="subject">Subject of the email message</param>
    /// <param name="body">Text body of the email message</param>
    /// <example>
    /// <code>
    ///   Smtp smtp = new Smtp("mail.OpenSmtp.com", 25);
    ///    smtp.SendMail("support@OpenSmtp.com", "recipient@OpenSmtp.com", "Hi", "Hello Joe Smith");
    /// </code>
    /// </example>
    public void SendMail(string from, string to, string subject, string body)
    {
      MailMessage msg = new MailMessage(from, to); 
      msg.subject = subject;
      msg.body = body;
      
      SendMail(msg);
    }
    
    /// <summary>Sends a mail message using supplied MailMessage and Smtp properties</summary>
    /// <param name="msg">MailMessage instance</param>
    /// <param name="host">SMTP host address</param>
    /// <param name="port">Port used to connect to host</param>
    /// <example>
    /// <code>
    ///    MailMessage msg = new MailMessage("support@OpenSmtp.com", "recipient@OpenSmtp.com");
    ///    msg.Subject = "Hi";
    ///    msg.Body = "Hello Joe Smith."
    ///   Smtp smtp = new Smtp();
    ///    smtp.SendMail(msg, "mail.OpenSmtp.com", 25);
    /// </code>
    /// </example>
    public void SendMail(MailMessage msg, string host, int port)
    {
      this.host = host;
      this.port = port;
      SendMail(msg);
    }
    

    /// <summary>Sends a mail message using supplied MailMessage</summary>
    /// <param name="msg">MailMessage instance</param>
    /// <example>
    /// <code>
    ///    MailMessage msg = new MailMessage("support@OpenSmtp.com", "recipient@OpenSmtp.com");
    ///    msg.Subject = "Hi";
    ///    msg.Body = "Hello Joe Smith."
    ///   Smtp smtp = new Smtp("mail.OpenSmtp.com", 25);
    ///    smtp.SendMail(msg);
    /// </code>
    /// </example>
    public void SendMail(MailMessage msg)
    {

      NetworkStream nwstream = GetConnection();

      CheckForError(ReadFromStream(ref nwstream), ReplyConstants.HELO_REPLY);

      if (this.username != null && this.username.Length > 0 && this.password != null && this.password.Length > 0)
      {
        WriteToStream(ref nwstream, "EHLO " + Dns.GetHostName() + "\r\n");
      }
      else
        WriteToStream(ref nwstream, "HELO " + Dns.GetHostName() + "\r\n");

      CheckForError(ReadFromStream(ref nwstream), ReplyConstants.OK);

      // Authentication is used if the u/p are supplied
      AuthLogin(ref nwstream);

      WriteToStream(ref nwstream, "MAIL FROM: <" + msg.from.address + ">\r\n");
      CheckForError(ReadFromStream(ref nwstream), ReplyConstants.OK);

      SendRecipientList(ref nwstream, msg.recipientList);
      SendRecipientList(ref nwstream, msg.ccList);
      SendRecipientList(ref nwstream, msg.bccList);

      WriteToStream(ref nwstream, "DATA\r\n");
      CheckForError(ReadFromStream(ref nwstream), ReplyConstants.START_INPUT);


      OnStartedMessageTransfer(EventArgs.Empty);
      WriteToStream(ref nwstream, msg.ToString() + "\r\n.\r\n");
      CheckForError(ReadFromStream(ref nwstream), ReplyConstants.OK);
      OnEndedMessageTransfer(EventArgs.Empty);

      WriteToStream(ref nwstream, "QUIT\r\n");
      CheckForError(ReadFromStream(ref nwstream), ReplyConstants.QUIT);

      CloseConnection();

    }
    
    
    /// <summary>Resets the Smtp instance to it's defaut values; set in the SmtpConfig class</summary>
    /// <example>
    /// <code>
    ///   Smtp smtp = new Smtp("mail.OpenSmtp.com", 25);
    ///    smtp.Reset();
    /// </code>
    /// </example>
    public void Reset()
    {
      host    = null;
      port   = 25;
      username = null;
      password = null;
      
      CloseConnection();
    }
    
    
    // --------------- Helper methods ------------------------------------

    private NetworkStream GetConnection()
    {
      try
      {
        if (host == null)
        { host = SmtpConfig.SmtpHost; }

        if (port == 0)
        { port = SmtpConfig.SmtpPort; }

        if (host != null && port != 0)
        {
          tcpc = new TcpClient(host, port);
          
          LogMessage("connecting to:" + host + ":" + port, ""); 
          tcpc.ReceiveTimeout= recieveTimeout;
          tcpc.SendTimeout = sendTimeout;
          tcpc.ReceiveBufferSize = receiveBufferSize;
          tcpc.SendBufferSize = sendBufferSize;

          LingerOption lingerOption = new LingerOption(true, 10);
          tcpc.LingerState = lingerOption;
          
        }
        else
        {
          throw new SmtpException("Cannot use SendMail() method without specifying target host and port");
        }
      }
      catch(SocketException e)
      {
        throw new SmtpException("Cannot connect to specified smtp host(" + host + ":" + port + ").", e);
      }

      OnConnect(EventArgs.Empty);
      return tcpc.GetStream(); 
    }
    
    private void CloseConnection()
    {
      // add delimeter to log file
      LogMessage("------------------------------------------------------\r\n", "");
      
      // fire disconnect event
      OnDisconnect(EventArgs.Empty);
      
      // destroy tcp connection if it hasn't already closed
      if (tcpc!=null)      
      { tcpc.Close(); }
    }


    private bool AuthLogin(ref NetworkStream nwstream)
    {
      if (this.username != null && this.username.Length > 0 && this.password != null && this.password.Length > 0)
      {
        WriteToStream(ref nwstream, "AUTH LOGIN\r\n");
        if (AuthImplemented(ReadFromStream(ref nwstream)))
        {
          WriteToStream(ref nwstream, Convert.ToBase64String(Encoding.ASCII.GetBytes(this.username.ToCharArray())) + "\r\n");

          CheckForError(ReadFromStream(ref nwstream), ReplyConstants.SERVER_CHALLENGE);

          WriteToStream(ref nwstream, Convert.ToBase64String(Encoding.ASCII.GetBytes(this.password.ToCharArray())) + "\r\n");
          CheckForError(ReadFromStream(ref nwstream), ReplyConstants.AUTH_SUCCESSFUL);
          
          OnAuthenticated(EventArgs.Empty);
          return true;
        }
      }

      return false;
    }
        
    private void SendRecipientList(ref NetworkStream nwstream, ArrayList recipients)
    {
      //  Iterate through all addresses and send them:
      for (IEnumerator i = recipients.GetEnumerator();i.MoveNext();)
      {
        EmailAddress recipient = (EmailAddress)i.Current;
        WriteToStream(ref nwstream, "RCPT TO: <" + recipient.address + ">\r\n");

        // potential 501 error (not valid sender, bad email address) below:
        CheckForError(ReadFromStream(ref nwstream), ReplyConstants.OK);
      }  
    }

    private bool CheckMailMessage(MailMessage message)
    {
      string returnMessage = "Mail Message is missing ";
    
      if (message.To == null || message.To.Count <= 0)
      {  
        throw new SmtpException(returnMessage + "'To:' field");
      }
      else
      { return true; }
    }

    /**
     * NetworkStream Helper methods
     */
    private void WriteToStream(ref NetworkStream nw, string line)
    {
      try
      {
        byte[] arrToSend = Encoding.ASCII.GetBytes(line);
        nw.Write(arrToSend, 0, arrToSend.Length);
        //Console.WriteLine("[client]:" + line);
        LogMessage(line, "[client]: ");
      }
      catch(System.Exception)
      {
        throw new SmtpException("Write to Stream threw an System.Exception");
      }
    }

    private string ReadFromStream(ref NetworkStream nw)
    {
      try
      {
      
        byte[] readBuffer = new byte[4096];
      
        int length = nw.Read(readBuffer, 0, readBuffer.Length);
        string returnMsg = Encoding.ASCII.GetString(readBuffer, 0, length);

        LogMessage(returnMsg, "[server]: ");
        return returnMsg;
      }
      catch(System.Exception e)
      {
        throw new SmtpException("Read from Stream threw an System.Exception: " + e.ToString());
      }
    }

    private void LogMessage(string msg, string src)
    {
      Log log = new Log();
      if (SmtpConfig.LogToText)  { log.logToTextFile(SmtpConfig.LogPath, msg, src); }
    }
    
    /**
     *
     * Checks stream returned from SMTP server for success code
     * If the success code is not present it will throw an error.    
     *
     */
    private void CheckForError(string s, string successCode)
    {
      if (s.IndexOf(successCode) == -1)
        throw new SmtpException("ERROR - Expecting: " + successCode + ". Recieved: " + s);
    }

    /// Check to see if the command sent returns a Unknown Command Error
    private bool IsUnknownCommand(string s)
    {
      if (s.IndexOf(ReplyConstants.UNKNOWN) != -1) { return true; }
      else { return false; }
    }

    /// Check to see if AUTH command returns valid challenge. 
    /// A valid AUTH string must be passed into this method.
    private bool AuthImplemented(string s)
    {
      if (s.IndexOf(ReplyConstants.SERVER_CHALLENGE) != -1)
      { return true; }
      
      return false;
    }
  }
  
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.