/// <summary> /// Default constructor. /// </summary> /// <param name="clientSocket">Referance to socket.</param> /// <param name="server">Referance to FTP server.</param> /// <param name="sessionID">Session ID which is assigned to this session.</param> /// <param name="logWriter">Log writer.</param> public FTP_Session(Socket clientSocket,FTP_Server server,string sessionID,SocketLogger logWriter) { m_pSocket = new BufferedSocket(clientSocket); m_pServer = server; m_SessionID = sessionID; // m_pLogWriter = logWriter; m_SessionStartTime = DateTime.Now; m_LastDataTime = DateTime.Now; m_pSocket.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.NoDelay,1); m_pSocket.Activity += new EventHandler(OnSocketActivity); // Start session proccessing StartSession(); }
/// <summary> /// Default constructor. /// </summary> /// <param name="clientSocket">Referance to socket.</param> /// <param name="server">Referance to IMAP server.</param> /// <param name="logWriter">Log writer.</param> internal IMAP_Session(Socket clientSocket,IMAP_Server server,SocketLogger logWriter) { m_pSocket = new BufferedSocket(clientSocket); m_pServer = server; m_SessionID = Guid.NewGuid().ToString(); m_SessionStartTime = DateTime.Now; m_LastDataTime = DateTime.Now; if(m_pServer.LogCommands){ m_pSocket.Logger = logWriter; m_pSocket.Logger.SessionID = m_SessionID; } m_pSocket.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.NoDelay,1); m_pSocket.Activity += new EventHandler(OnSocketActivity); // Start session proccessing StartSession(); }
/// <summary> /// Default constructor. /// </summary> /// <param name="clientSocket">Referance to socket.</param> /// <param name="server">Referance to SMTP server.</param> /// <param name="logWriter">Log writer.</param> internal SMTP_Session(Socket clientSocket,SMTP_Server server,SocketLogger logWriter) { m_pSocket = new BufferedSocket(clientSocket); m_pServer = server; m_pMsgStream = new MemoryStream(); m_SessionID = Guid.NewGuid().ToString(); m_BodyType = BodyType.x7_bit; m_Forward_path = new Hashtable(); m_CmdValidator = new SMTP_Cmd_Validator(); m_SessionStart = DateTime.Now; m_LastDataTime = DateTime.Now; if(m_pServer.LogCommands){ m_pSocket.Logger = logWriter; m_pSocket.Logger.SessionID = m_SessionID; } m_pSocket.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.NoDelay,1); m_pSocket.Activity += new EventHandler(OnSocketActivity); // Start session proccessing StartSession(); }
/// <summary> /// Connects to sepcified host. /// </summary> /// <param name="localEndpoint">Sets local endpoint. Pass null, to use default.</param> /// <param name="host">Host name or IP address.</param> /// <param name="port">Port where to connect.</param> public void Connect(IPEndPoint localEndpoint,string host,int port) { Socket s = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.IP); s.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.ReceiveTimeout,30000); s.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.NoDelay,1); m_pSocket = new BufferedSocket(s); if(localEndpoint != null){ m_pSocket.Bind(localEndpoint); } m_pSocket.Activity += new EventHandler(m_pSocket_Activity); if(SessionLog != null){ m_pLogger = new SocketLogger(s,SessionLog); m_pLogger.SessionID = Guid.NewGuid().ToString(); m_pSocket.Logger = m_pLogger; } if(host.IndexOf("@") == -1){ m_pSocket.Connect(new IPEndPoint(Dns_Client.Resolve(host)[0],port)); } else{ //---- Parse e-domain -------------------------------// string domain = host; // eg. Ivx <*****@*****.**> if(domain.IndexOf("<") > -1 && domain.IndexOf(">") > -1){ domain = domain.Substring(domain.IndexOf("<")+1,domain.IndexOf(">") - domain.IndexOf("<")-1); } if(domain.IndexOf("@") > -1){ domain = domain.Substring(domain.LastIndexOf("@") + 1); } if(domain.Trim().Length == 0){ if(m_pLogger != null){ m_pLogger.AddTextEntry("Destination address '" + host + "' is invalid, aborting !"); } throw new Exception("Destination address '" + host + "' is invalid, aborting !"); } //--- Get MX record -------------------------------------------// Dns_Client dns = new Dns_Client(); Dns_Client.DnsServers = m_pDnsServers; DnsServerResponse dnsResponse = dns.Query(domain,QTYPE.MX); switch(dnsResponse.ResponseCode) { case RCODE.NO_ERROR: MX_Record[] mxRecords = dnsResponse.GetMXRecords(); // Try all available hosts by MX preference order, if can't connect specified host. foreach(MX_Record mx in mxRecords){ try{ if(m_pLogger != null){ m_pLogger.AddTextEntry("Connecting with mx record to: " + mx.Host); } m_pSocket.Connect(new IPEndPoint(Dns_Client.Resolve(mx.Host)[0],port)); break; } catch{ // Just skip and let for to try next host. if(m_pLogger != null){ m_pLogger.AddTextEntry("Failed connect to: " + mx.Host); } } } // None of MX didn't connect if(mxRecords.Length > 0 && !m_pSocket.Connected){ throw new Exception("Destination email server is down"); } /* Rfc 2821 5 If no MX records are found, but an A RR is found, the A RR is treated as if it was associated with an implicit MX RR, with a preference of 0, pointing to that host. */ if(mxRecords.Length == 0){ // Try to connect with A record IPAddress[] ipEntry = null; try{ if(m_pLogger != null){ m_pLogger.AddTextEntry("No mx record, trying to get A record for: " + domain); } ipEntry = Dns_Client.Resolve(domain); } catch{ if(m_pLogger != null){ m_pLogger.AddTextEntry("Invalid domain,no MX or A record: " + domain); } throw new Exception("Invalid domain,no MX or A record: " + domain); } try{ if(m_pLogger != null){ m_pLogger.AddTextEntry("Connecting with A record to:" + domain); } m_pSocket.Connect(new IPEndPoint(ipEntry[0],port)); } catch{ if(m_pLogger != null){ m_pLogger.AddTextEntry("Failed connect to:" + domain); } throw new Exception("Destination email server is down"); } } break; case RCODE.NAME_ERROR: if(m_pLogger != null){ m_pLogger.AddTextEntry("Invalid domain,no MX or A record: " + domain); } throw new Exception("Invalid domain,no MX or A record: " + domain); case RCODE.SERVER_FAILURE: if(m_pLogger != null){ m_pLogger.AddTextEntry("Dns server unvailable."); } throw new Exception("Dns server unvailable."); } } /* * Notes: Greeting may be single or multiline response. * * Examples: * 220<SP>SMTP server ready<CRLF> * * 220-SMTP server ready<CRLF> * 220-Addtitional text<CRLF> * 220<SP>final row<CRLF> * */ // Read server response string responseLine = m_pSocket.ReadLine(1000); while(!responseLine.StartsWith("220 ")){ // If lisne won't start with 220, then its error response if(!responseLine.StartsWith("220")){ throw new Exception(responseLine); } responseLine = m_pSocket.ReadLine(1000); } m_Connected = true; }
/* /// <summary> /// Starts disconnecting SMTP client. /// </summary> public void BeginDisconnect() { if(!m_Connected){ throw new Exception("You must connect first"); } }*/ #region method Disconnect /// <summary> /// Disconnects smtp client from server. /// </summary> public void Disconnect() { try{ if(m_pSocket != null && m_pSocket.Connected){ m_pSocket.SendLine("QUIT"); m_pSocket.Shutdown(SocketShutdown.Both); } } catch{ } m_pSocket = null; m_Connected = false; m_Supports_Size = false; m_Supports_Bdat = false; m_Supports_Login = false; m_Supports_CramMd5 = false; if(m_pLogger != null){ m_pLogger.Flush(); m_pLogger = null; } }
/// <summary> /// Ends session, closes socket. /// </summary> private void EndSession() { try{ // Write logs to log file, if needed if(m_pServer.LogCommands){ m_pSocket.Logger.Flush(); } if(m_pSocket != null){ m_pSocket.Shutdown(SocketShutdown.Both); m_pSocket.Close(); m_pSocket = null; } } catch{ // We don't need to check errors here, because they only may be Socket closing errors. } finally{ m_pServer.RemoveSession(this); } }
/// <summary> /// Closes connection to Pop33 server. /// </summary> public void Disconnect() { if (socketStream != null) { // Send QUIT socketStream.Write(Encoding.ASCII.GetBytes("QUIT"), 0, 4); socketStream.Close(); } if (m_pLogger != null) { m_pLogger.Flush(); } m_pLogger = null; m_pSocket = null; m_Connected = false; m_Authenticated = false; }
/// <summary> /// Ends session, closes socket. /// </summary> private void EndSession() { m_pServer.RemoveSession(this); // Write logs to log file, if needed if(m_pServer.LogCommands){ // m_pLogWriter.AddEntry("//----- Sys: 'Session:'" + this.SessionID + " removed " + DateTime.Now); // m_pLogWriter.Flush(); m_pSocket.Logger.Flush(); } if(m_pSocket != null){ m_pSocket.Shutdown(SocketShutdown.Both); m_pSocket.Close(); m_pSocket = null; } }