// ------------------------ StartReceive -------------------------- private void StartReceive(SocketExchange InEx) { Socket socket = InEx.ConnectedSocket; // set the sync event to non signaled. m_manualEvent.Reset( ); // start receiving data ... if (socket != null) { socket.BeginReceive( mSockThreadState.buffer, 0, SockThreadState.BufferSize, 0, new AsyncCallback(ReceiveCallback), mSockThreadState); } else { InEx.ConnectedSecureSocket.BeginReceive( mSockThreadState.buffer, 0, SockThreadState.BufferSize, 0, new AsyncCallback(ReceiveCallback), mSockThreadState); } // Block on the event. The receive thread will signal when the receive is // complete. m_manualEvent.WaitOne( ); }
// --------------------------- constructor ----------------------- public Pop3Message( System.Int64 InMailDropPosition, SocketExchange InEx) { m_inboxPosition = InMailDropPosition; mSockEx = InEx; // object used to receive the mail message in a background thread. mSockThreadState = new SockThreadState( ); mSockThreadState.SockEx = InEx; mSockThreadState.sb = new StringBuilder( ); // load email ... LoadEmail(InEx, InMailDropPosition); // get body (if it exists) ... IEnumerator multipartEnumerator = MultipartEnumerator; while (multipartEnumerator.MoveNext()) { Pop3Component multipart = (Pop3Component) multipartEnumerator.Current; if (multipart.IsBody) { m_body = multipart.Data; break; } } }
void DumpHeader(SocketExchange InEx, Int64 InMailDropPosition) { // dump the header lines of the top part. InEx.Logger.AddMessage(NetworkRole.Server, "--- start header line dump ---"); MimeTopPart topPart = (MimeTopPart)mParts.GetTopPart(); for (int Ix = 0; Ix < topPart.PropertyLines.Length; ++Ix) { InEx.Logger.AddMessage(NetworkRole.Server, topPart.PropertyLines[Ix]); } for (int Ix = 0; Ix < topPart.MessageLines.Length; ++Ix) { InEx.Logger.AddMessage(NetworkRole.Server, topPart.MessageLines[Ix]); } InEx.Logger.AddMessage(NetworkRole.Server, "--- end of header line dump ---"); // dump the lines of each part. foreach (MimeMessagePart part in mParts) { InEx.Logger.AddMessage(NetworkRole.Server, "** message part **"); InEx.Logger.AddMessage(NetworkRole.Server, "** property lines **"); foreach (string line in part.PropertyLines) { InEx.Logger.AddMessage(NetworkRole.Server, line); } InEx.Logger.AddMessage(NetworkRole.Server, "** message lines **"); foreach (string line in part.MessageLines) { InEx.Logger.AddMessage(NetworkRole.Server, line); } } InEx.Logger.AddMessage(NetworkRole.Server, "---- end of parts ----------"); }
// --------------------------- OpenInBox ----------------------------- public SocketExchange OpenInbox( ) { // connect to the mail server. SocketExchange sockEx = new SocketExchange( m_credential.Server, Port, Logger); if (UseSecureConnection == true) { sockEx.SecureConnect( ); mSecureSocket = sockEx.ConnectedSecureSocket; } else { sockEx.Connect( ); m_socket = sockEx.ConnectedSocket; } SignalConnectedEvent(new MailEventArgs(MailEvent.Connected)); // receive initial connection response from mail server. sockEx.ExpectedResponseCodes = new ExpectedResponseCodes(PopConstants.Ok); sockEx.Receive( ); sockEx.ThrowIfUnexpectedResponse( ); // send login details ... MailServerLogin(sockEx); return(sockEx); }
// --------------------------- constructor ----------------------- public Pop3Message( long position, long size, Socket client, SocketExchange InEx) { m_inboxPosition = position; m_messageSize = size; mSocket = client; mSockEx = InEx; // object used to receive the mail message in a background thread. mSockThreadState = new Pop3StateObject( ); mSockThreadState.SockEx = InEx; mSockThreadState.sb = new StringBuilder( ); // load email ... LoadEmail(InEx); // get body (if it exists) ... IEnumerator multipartEnumerator = MultipartEnumerator; while (multipartEnumerator.MoveNext()) { Pop3Component multipart = (Pop3Component) multipartEnumerator.Current; if (multipart.IsBody) { m_body = multipart.Data; break; } } }
// --------------------------- ConnectAndLogin ----------------------------- public void ConnectAndLogin( ) { // connect to the mail server. mSockEx = new SocketExchange( m_credential.Server, Port, Logger); if (UseSecureConnection == true) { mSockEx.SecureConnect( ); } else { mSockEx.Connect( ); } SignalConnectedEvent(new MailEventArgs(MailEvent.Connected)); // receive initial connection response from mail server. mSockEx.ExpectedResponseCodes = new ExpectedResponseCodes(PopConstants.Ok); mSockEx.Receive( ); mSockEx.ThrowIfUnexpectedResponse( ); // send login details ... MailServerLogin( ); }
// ---------------------- LoadEmail --------------------------- private void LoadEmail(SocketExchange InEx, Int64 InMailDropPosition) { // tell the server we want to read the message. InEx.Send("retr " + InMailDropPosition + PopConstants.CrLf); InEx.ExpectedResponseCodes = new ExpectedResponseCodes(PopConstants.Ok, PopConstants.Error); InEx.SendReceive("retr " + InMailDropPosition + PopConstants.CrLf); InEx.ThrowIfUnexpectedResponse( ); // -ERR response. no such message number. if (InEx.ResponseCode == PopConstants.Error) { } else { // for now, receive SSL link messages in the same thread. if (InEx.ConnectedSecureSocket != null) { StringBuilder mail = null; mail = ReceiveMessage_SameThread(InEx); InEx.LoadResponseMessage(mail.ToString( )); } // receive in a background thread. else { StartReceive(InEx); InEx.LoadResponseMessage(mSockThreadState.sb.ToString( )); } } // parse email ... mParts = MimeCommon.MessagePartSplitter(InEx.ResponseMessage); string[] lines = MimeCommon.MessageLineSplitter(InEx.ResponseMessage); mAttachments = null; MimeAttachment attach = (MimeAttachment)Attachments.FirstAttachment( ).Current; if (attach != null) { attach.SaveAs("c:\\apress\\attachment.txt"); } // if (1 == 2) // DumpHeader(InEx, InMailDropPosition); for (int ix = 0; ix < lines.Length; ++ix) { InEx.Logger.AddMessage(NetworkRole.Server, lines[ix]); } ParseEmail(lines); // remove reading pop3State ... mSockThreadState = null; }
// -------------------------- AuthenticateToServer ------------------------- private void AuthenticateToServer(SocketExchange InExchange) { string message = null; // log the base64 encoded string that follows the 334 challenge. string ResponseData = InExchange.GetResponseData( ); byte[] msgBytes = Convert.FromBase64String(ResponseData); System.Text.Encoding encoding = System.Text.Encoding.UTF8; string msg = encoding.GetString(msgBytes); LogMessage(NetworkRole.Client, msg); // send the user name, expect back a challenge for the password. int LoopCx = 0; while (true) { message = Convert.ToBase64String( Encoding.ASCII.GetBytes(Username.ToCharArray( ))) + SmtpConstants.CrLf; InExchange.ExpectedResponseCodes = new ExpectedResponseCodes( SmtpConstants.Challenge, SmtpConstants.SyntaxError); InExchange.SendReceive(message); if (InExchange.ExpectedResponseCode == SmtpConstants.Challenge) { break; } else if (InExchange.ExpectedResponseCode == SmtpConstants.SyntaxError) { ++LoopCx; if (LoopCx >= 3) { InExchange.ThrowUnexpectedResponse(SmtpConstants.Challenge); } } else { InExchange.ThrowIfUnexpectedResponse( ); } } // send the password. expect back 235 = login successful. message = Convert.ToBase64String( Encoding.ASCII.GetBytes(Password.ToCharArray( ))) + SmtpConstants.CrLf; InExchange.ExpectedResponseCodes = new ExpectedResponseCodes(SmtpConstants.Authenticated); InExchange.SendReceive(message); InExchange.ThrowIfUnexpectedResponse( ); // is authenticated. SignalAuthenticatedEvent(new MailEventArgs(MailEvent.Authenticated)); }
/// <summary> /// send QUIT command and disconnect from server. /// </summary> /// <param name="InSockEx"></param> public void Disconnect(SocketExchange InSockEx) { // send quit message. InSockEx.ExpectedResponseCodes = new ExpectedResponseCodes(SmtpConstants.Quit); InSockEx.SendReceive("QUIT" + SmtpConstants.CrLf); InSockEx.ThrowIfUnexpectedResponse( ); SignalDisconnectedEvent(new MailEventArgs(MailEvent.Disconnected)); InSockEx.CloseConnection( ); }
// ------------------------------ SendMail -------------------------------- public void SendMail(MailMessage msg) { SocketExchange sockEx = null; try { sockEx = Connect( ); // send the MAIL FROM message to the server. This is the start of the sending // of the email message. sockEx.ExpectedResponseCodes = new ExpectedResponseCodes(SmtpConstants.Challenge, SmtpConstants.Ok); sockEx.SendReceive("MAIL FROM: <" + msg.From.Address + ">" + SmtpConstants.CrLf); sockEx.ThrowIfUnexpectedResponse( ); if (sockEx.ResponseCode == SmtpConstants.Challenge) { AuthenticateToServer(sockEx); } // send "rcpt to" message to the mail server to validate the recipients. ServerValidateRecipients(sockEx, msg.ToRecipients); ServerValidateRecipients(sockEx, msg.CCRecipients); ServerValidateRecipients(sockEx, msg.BCCRecipients); // send the DATA message to the server. sockEx.ExpectedResponseCodes = new ExpectedResponseCodes(SmtpConstants.DataReady); sockEx.SendReceive("DATA" + SmtpConstants.CrLf); sockEx.ThrowIfUnexpectedResponse( ); // send the message itself. SignalStartDataSendEvent(new MailEventArgs(MailEvent.StartDataSend)); sockEx.ExpectedResponseCodes = new ExpectedResponseCodes(SmtpConstants.Ok); string dataMessage = msg.ToString( ) + SmtpConstants.CrLf + "." + SmtpConstants.CrLf; sockEx.SendReceive(dataMessage); sockEx.ThrowIfUnexpectedResponse( ); SignalEndDataSendEvent(new MailEventArgs(MailEvent.EndDataSend)); Disconnect(sockEx); sockEx = null; } // close the connection. finally { if (sockEx != null) { SignalDisconnectedEvent(new MailEventArgs(MailEvent.Disconnected)); sockEx.CloseConnection( ); } } }
// ----------------------- NextEmail ---------------------------------- public bool NextEmail(SocketExchange InEx) { string returned; long pos; if (m_directPosition == -1) { if (m_inboxPosition == 0) { pos = 1; } else { pos = m_inboxPosition + 1; } } else { pos = m_directPosition + 1; m_directPosition = -1; } InEx.ExpectedResponseCodes = new ExpectedResponseCodes(PopConstants.Ok, PopConstants.Error); InEx.SendReceive("list " + pos.ToString( ) + PopConstants.CrLf); if (InEx.ExpectedResponseCode == PopConstants.Error) { return(false); } else { InEx.ThrowIfUnexpectedResponse( ); } returned = InEx.ResponseMessage; m_inboxPosition = pos; // strip out CRLF ... string[] noCr = returned.Split(new char[] { '\r' }); // get size ... string[] elements = noCr[0].Split(new char[] { ' ' }); long size = long.Parse(elements[2]); // ... else read email data m_pop3Message = new Pop3Message(m_inboxPosition, size, m_socket, InEx); return(true); }
// ------------------------- ServerValidateRecipients ------------------------ // Send "rcpt to" message to the mail server to validate each recipient. private void ServerValidateRecipients( SocketExchange InSock, ArrayList InRecipients) { IEnumerator it = InRecipients.GetEnumerator( ); while (it.MoveNext( ) == true) { EmailAddress recipient = (EmailAddress)it.Current; string message = "RCPT TO: <" + recipient.Address + ">" + SmtpConstants.CrLf; InSock.ExpectedResponseCodes = new ExpectedResponseCodes(SmtpConstants.Ok); InSock.SendReceive(message); InSock.ThrowIfUnexpectedResponse( ); } }
// -------------------- MailServerLogin -------------------------------- private void MailServerLogin(SocketExchange InEx) { // send username ... InEx.ExpectedResponseCodes = new ExpectedResponseCodes(PopConstants.Ok); InEx.SendReceive("user " + m_credential.User + PopConstants.CrLf); if (InEx.ExpectedResponseCode == null) { InEx.ThrowUnexpectedResponse( ); } // send password InEx.ExpectedResponseCodes = new ExpectedResponseCodes(PopConstants.Ok); InEx.SendReceive("pass " + m_credential.Pass + PopConstants.CrLf); InEx.ThrowIfUnexpectedResponse( ); }
public bool NextEmail(SocketExchange InEx, long directPosition) { bool ret; if (directPosition >= 0) { m_directPosition = directPosition; ret = NextEmail(InEx); } else { throw new Pop3MessageException("Position less than zero"); } return(ret); }
// ------------------------ StartReceive -------------------------- private void StartReceive(SocketExchange InEx) { // set the sync event to non signaled. m_manualEvent.Reset( ); // start receiving data ... mSocket.BeginReceive( mSockThreadState.buffer, 0, Pop3StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), mSockThreadState); // Block on the event. The receive thread will signal when the receive is // complete. m_manualEvent.WaitOne( ); }
// ---------------------- LoadEmail --------------------------- private void LoadEmail(SocketExchange InEx) { // tell the server we want to read the message. InEx.Send("retr " + m_inboxPosition + PopConstants.CrLf); // receive in a background thread. StartReceive(InEx); InEx.LoadResponseMessage(mSockThreadState.sb.ToString( )); // parse email ... string[] lines = InEx.ResponseMessage.Split(Chars.CharArrayChars('\r')); for (int ix = 0; ix < lines.Length; ++ix) { InEx.Logger.AddMessage(NetworkRole.Server, lines[ix]); } ParseEmail(lines); // remove reading pop3State ... mSockThreadState = null; }
private Program(ServerProgramOptions options) : base(options) { var dataPath = Path.Combine(GetThisFileDirectory(), "..", "..", "data", "csvdb"); var socketSerializer = new CustomSocketSerializer(); var socketParser = new CsvRecordParser <CustomSocket>(socketSerializer); var socketOptions = new CsvRepositoryOptions { IdPropertyName = "SocketName", CsvFileName = Path.Combine(dataPath, "socket.csv"), WalFileName = Path.Combine(dataPath, "wal_socket.txt") }; var socketsRepository = new CsvRepository <CustomSocket>(socketSerializer, socketParser, socketOptions).Sync(); var socketService = new SocketService(socketsRepository); var socketGroupSerializer = new SocketGroupSerializer(); var socketGroupParser = new CsvRecordParser <SocketGroup>(socketGroupSerializer); var socketGroupOptions = new CsvRepositoryOptions { IdPropertyName = "GroupName", CsvFileName = Path.Combine(dataPath, "socketGroup.csv"), WalFileName = Path.Combine(dataPath, "wal_socketGroup.txt") }; var socketGroupRepository = new CsvRepository <SocketGroup>(socketGroupSerializer, socketGroupParser, socketGroupOptions).Sync(); var socketGroupService = new GroupService(socketGroupRepository); var socketExchangeOptions = new SocketExchangeOptions { Version = Options.Version, Debug = options.Debug }; var socketExchange = new SocketExchangeImpl(socketService, socketGroupService, socketExchangeOptions); Server = new Grpc.Core.Server { Services = { SocketExchange.BindService(socketExchange) }, Ports = { new ServerPort("localhost", Options.Port, ServerCredentials.Insecure) } }; }
// ---------------------- LoadEmail --------------------------- private void LoadEmail(SocketExchange InEx, System.Int64 InMailDropPosition) { // tell the server we want to read the message. InEx.Send("retr " + InMailDropPosition + PopConstants.CrLf); InEx.ExpectedResponseCodes = new ExpectedResponseCodes(PopConstants.Ok, PopConstants.Error); InEx.SendReceive("retr " + InMailDropPosition + PopConstants.CrLf); InEx.ThrowIfUnexpectedResponse( ); // -ERR response. no such message number. if (InEx.ResponseCode == PopConstants.Error) { } else { // for now, receive SSL link messages in the same thread. if (InEx.ConnectedSecureSocket != null) { StringBuilder mail = null; mail = ReceiveMessage_SameThread(InEx); InEx.LoadResponseMessage(mail.ToString( )); } // receive in a background thread. else { StartReceive(InEx); InEx.LoadResponseMessage(mSockThreadState.sb.ToString( )); } } // parse email ... mParts = MimeCommon.MessagePartSplitter(InEx.ResponseMessage); string[] lines = MimeCommon.MessageLineSplitter(InEx.ResponseMessage); if (1 == 2) { mParts = MimeCommon.MessagePartSplitter(lines); } mAttachments = null; MimeAttachment attach = (MimeAttachment)Attachments.FirstAttachment( ).Current; if (attach != null) { attach.SaveAs("c:\\apress\\attachment.txt"); } if (1 == 2) { // dump the header lines of the top part. InEx.Logger.AddMessage(NetworkRole.Server, "--- start header line dump ---"); MimeTopPart topPart = ( MimeTopPart )mParts.GetTopPart( ); for (int Ix = 0; Ix < topPart.PropertyLines.Length; ++Ix) { InEx.Logger.AddMessage(NetworkRole.Server, topPart.PropertyLines[Ix]); } for (int Ix = 0; Ix < topPart.MessageLines.Length; ++Ix) { InEx.Logger.AddMessage(NetworkRole.Server, topPart.MessageLines[Ix]); } InEx.Logger.AddMessage(NetworkRole.Server, "--- end of header line dump ---"); // dump the lines of each part. foreach (MimeMessagePart part in mParts) { InEx.Logger.AddMessage(NetworkRole.Server, "** message part **"); InEx.Logger.AddMessage(NetworkRole.Server, "** property lines **"); foreach (string line in part.PropertyLines) { InEx.Logger.AddMessage(NetworkRole.Server, line); } InEx.Logger.AddMessage(NetworkRole.Server, "** message lines **"); foreach (string line in part.MessageLines) { InEx.Logger.AddMessage(NetworkRole.Server, line); } } InEx.Logger.AddMessage(NetworkRole.Server, "---- end of parts ----------"); } for (int ix = 0; ix < lines.Length; ++ix) { InEx.Logger.AddMessage(NetworkRole.Server, lines[ix]); } ParseEmail(lines); // remove reading pop3State ... mSockThreadState = null; }
public void CloseConnection() { SockEx.Send("quit"); mSockEx = null; m_pop3Message = null; }
// ------------------------- ReceiveCallback ------------------------- // receive MailMessage in background thread. private void ReceiveCallback(IAsyncResult InResult) { try { // Retrieve the state object and the client socket // from the asynchronous state object. SockThreadState sockThreadState = (SockThreadState)InResult.AsyncState; SocketExchange sockEx = sockThreadState.SockEx; Socket client = sockEx.ConnectedSocket; Socket secureSock = sockEx.ConnectedSecureSocket; int BufferSx = SockThreadState.BufferSize; int LoopCx = 0; while (true) { // a simple loop count. dont let it overflow. ++LoopCx; if (LoopCx > 1000) { LoopCx = 2; } // receive from the socket. int ReadCx; if (LoopCx == 1) { if (client != null) { ReadCx = client.EndReceive(InResult); } else { ReadCx = secureSock.EndReceive(InResult); } } else { if (client != null) { ReadCx = client.Receive( sockThreadState.buffer, 0, BufferSx, SocketFlags.None); } else { ReadCx = secureSock.Receive( sockThreadState.buffer, 0, BufferSx, SocketFlags.None); } } // did not receive anything. probably should leave. if (ReadCx == 0) { break; } // There might be more data, // so store the data received so far. string block = Encoding.ASCII.GetString(sockThreadState.buffer, 0, ReadCx); sockThreadState.sb.Append(block); // is this the end of the message if (sockThreadState.sb.Tail(5) == "\r\n.\r\n") { break; } } } catch (Exception e) { throw new Pop3ReceiveException( "ReceiveCallback error" + e.ToString( )); } finally { m_manualEvent.Set( ); } }
// ------------------------- ReceiveMessage_SameThread ------------------------- private StringBuilder ReceiveMessage_SameThread(SocketExchange InSockEx) { StringBuilder sb = new StringBuilder( ); int BufferSx = 512; byte[] buffer = new byte[512]; try { Socket client = InSockEx.ConnectedSocket; Socket secureSock = InSockEx.ConnectedSecureSocket; int LoopCx = 0; while (true) { // a simple loop count. dont let it overflow. ++LoopCx; if (LoopCx > 1000) { LoopCx = 2; } // receive from the socket. int ReadCx; if (client != null) { ReadCx = client.Receive( buffer, 0, BufferSx, SocketFlags.None); } else { ReadCx = secureSock.Receive( buffer, 0, BufferSx, SocketFlags.None); } // did not receive anything. probably should leave. if (ReadCx == 0) { InSockEx.Logger.AddMessage(NetworkRole.Server, "Got zero bytes"); break; } // There might be more data, // so store the data received so far. string block = Encoding.ASCII.GetString(buffer, 0, ReadCx); sb.Append(block); // is this the end of the message if (sb.Tail(5) == "\r\n.\r\n") { break; } } } catch (Exception e) { throw new Pop3ReceiveException( "ReceiveCallback error" + e.ToString( )); } finally { } return(sb); }
// ------------------------------ SendMail -------------------------------- public void SendMailOld(MailMessage msg) { SocketExchange sockEx = null; // connect to the mail server. sockEx = new SocketExchange(ServerName, Port, DetailLogger); try { if (UseSecureConnection == true) { sockEx.SecureConnect( ); } else { sockEx.Connect( ); } SignalConnectedEvent(new MailEventArgs(MailEvent.Connected)); // receive the initial server hello message. sockEx.ExpectedResponseCodes = new ExpectedResponseCodes(SmtpConstants.ServerReady); sockEx.Receive( ); sockEx.ThrowIfUnexpectedResponse( ); // hello message exchange. sockEx.ExpectedResponseCodes = new ExpectedResponseCodes(SmtpConstants.Ok); if (ServerRequiresAuthentication == true) { sockEx.SendReceive("EHLO " + Dns.GetHostName() + SmtpConstants.CrLf); } else { sockEx.SendReceive("HELO " + Dns.GetHostName() + SmtpConstants.CrLf); } sockEx.ThrowIfUnexpectedResponse( ); // got a 250, but did not get a 250-AUTH. receive more. if ((sockEx.ResponseCode == SmtpConstants.Ok) && (sockEx.ResponseMessageContains("AUTH") == false)) { LogMessage(NetworkRole.Client, "AUTH not received. Receive more."); sockEx.SleepThenReadMoreAvailableData(300); } // authentication loop sockEx.ReadMoreDelay = 0; if (ServerRequiresAuthentication == true) { int okCount = 0; while (true) { sockEx.ExpectedResponseCodes = new ExpectedResponseCodes(SmtpConstants.Ok, SmtpConstants.Challenge); sockEx.SendReceive("AUTH LOGIN" + SmtpConstants.CrLf); sockEx.ThrowIfUnexpectedResponse( ); if (sockEx.ResponseCode == SmtpConstants.Challenge) { AuthenticateToServer(sockEx); break; } else if (sockEx.ResponseCode == SmtpConstants.Ok) { ++okCount; continue; } } } // send the MAIL FROM message to the server. This is the start of the sending // of the email message. sockEx.ExpectedResponseCodes = new ExpectedResponseCodes(SmtpConstants.Challenge, SmtpConstants.Ok); sockEx.SendReceive("MAIL FROM: <" + msg.From.Address + ">" + SmtpConstants.CrLf); sockEx.ThrowIfUnexpectedResponse( ); if (sockEx.ResponseCode == SmtpConstants.Challenge) { AuthenticateToServer(sockEx); } // send "rcpt to" message to the mail server to validate the recipients. ServerValidateRecipients(sockEx, msg.ToRecipients); ServerValidateRecipients(sockEx, msg.CCRecipients); ServerValidateRecipients(sockEx, msg.BCCRecipients); // send the DATA message to the server. sockEx.ExpectedResponseCodes = new ExpectedResponseCodes(SmtpConstants.DataReady); sockEx.SendReceive("DATA" + SmtpConstants.CrLf); sockEx.ThrowIfUnexpectedResponse( ); // send the message itself. SignalStartDataSendEvent(new MailEventArgs(MailEvent.StartDataSend)); sockEx.ExpectedResponseCodes = new ExpectedResponseCodes(SmtpConstants.Ok); string dataMessage = msg.ToString( ) + SmtpConstants.CrLf + "." + SmtpConstants.CrLf; sockEx.SendReceive(dataMessage); sockEx.ThrowIfUnexpectedResponse( ); SignalEndDataSendEvent(new MailEventArgs(MailEvent.EndDataSend)); // send quit message. sockEx.ExpectedResponseCodes = new ExpectedResponseCodes(SmtpConstants.Quit); sockEx.SendReceive("QUIT" + SmtpConstants.CrLf); sockEx.ThrowIfUnexpectedResponse( ); } // close the connection. finally { SignalDisconnectedEvent(new MailEventArgs(MailEvent.Disconnected)); sockEx.CloseConnection( ); } }
// ------------------------- ReceiveCallback ------------------------- // receive MailMessage in background thread. private void ReceiveCallback(IAsyncResult InResult) { try { // Retrieve the state object and the client socket // from the asynchronous state object. Pop3StateObject sockThreadState = (Pop3StateObject)InResult.AsyncState; SocketExchange sockEx = sockThreadState.SockEx; Socket client = sockEx.ConnectedSocket; SecureSocket secureSock = sockEx.ConnectedSecureSocket; bool InlRcv = true; while (true) { // receive from the socket. int ReadCx; if (InlRcv == true) { if (client != null) { ReadCx = client.EndReceive(InResult); } else { ReadCx = secureSock.EndReceive(InResult); } } else { if (client != null) { ReadCx = client.Receive( sockThreadState.buffer, 0, Pop3StateObject.BufferSize, SocketFlags.None); } else { ReadCx = secureSock.Receive( sockThreadState.buffer, 0, Pop3StateObject.BufferSize, SocketFlags.None); } } InlRcv = false; // did not receive anything. probably should leave. if (ReadCx == 0) { break; } // There might be more data, // so store the data received so far. string block = Encoding.ASCII.GetString(sockThreadState.buffer, 0, ReadCx); sockThreadState.sb.Append(block); // is this the end of the message if (Stringer.Tail(sockThreadState.sb, 5) == "\r\n.\r\n") { break; } } } catch (Exception e) { throw new Pop3ReceiveException( "ReceiveCallback error" + e.ToString( )); } finally { m_manualEvent.Set( ); } }
/// <summary> /// Connect and login to the smtp server. /// </summary> /// <returns></returns> public SocketExchange Connect( ) { // connect to the mail server. SocketExchange sockEx = new SocketExchange(ServerName, Port, DetailLogger); if (UseSecureConnection == true) { sockEx.SecureConnect( ); } else { sockEx.Connect( ); } SignalConnectedEvent(new MailEventArgs(MailEvent.Connected)); // receive the initial server hello message. sockEx.ExpectedResponseCodes = new ExpectedResponseCodes(SmtpConstants.ServerReady); sockEx.Receive( ); sockEx.ThrowIfUnexpectedResponse( ); // hello message exchange. sockEx.ExpectedResponseCodes = new ExpectedResponseCodes(SmtpConstants.Ok); if (ServerRequiresAuthentication == true) { sockEx.SendReceive("EHLO " + Dns.GetHostName() + SmtpConstants.CrLf); } else { sockEx.SendReceive("HELO " + Dns.GetHostName() + SmtpConstants.CrLf); } sockEx.ThrowIfUnexpectedResponse( ); // got a 250, but did not get a 250-AUTH. receive more. if ((sockEx.ResponseCode == SmtpConstants.Ok) && (sockEx.ResponseMessageContains("AUTH") == false)) { LogMessage(NetworkRole.Client, "AUTH not received. Receive more."); sockEx.SleepThenReadMoreAvailableData(300); } // authentication loop sockEx.ReadMoreDelay = 0; if (ServerRequiresAuthentication == true) { int okCount = 0; while (true) { sockEx.ExpectedResponseCodes = new ExpectedResponseCodes(SmtpConstants.Ok, SmtpConstants.Challenge); sockEx.SendReceive("AUTH LOGIN" + SmtpConstants.CrLf); sockEx.ThrowIfUnexpectedResponse( ); if (sockEx.ResponseCode == SmtpConstants.Challenge) { AuthenticateToServer(sockEx); break; } else if (sockEx.ResponseCode == SmtpConstants.Ok) { ++okCount; continue; } } } return(sockEx); }