POP3_Session.cs
上传用户:horngjaan
上传日期:2009-12-12
资源大小:2882k
文件大小:29k
- using System;
- using System.IO;
- using System.ComponentModel;
- using System.Collections;
- using System.Diagnostics;
- using System.Net;
- using System.Net.Sockets;
- using System.Threading;
- using System.Windows.Forms;
- using LumiSoft.MailServer;
- namespace LumiSoft.MailServer.POP3
- {
- /// <summary>
- /// POP3 Session.
- /// </summary>
- internal class POP3_Session
- {
- private Socket m_pClientSocket = null; // Referance to client Socket.
- private POP3_Server m_pPOP3_Server = null; // Referance to POP3 server.
- private string m_SessionID = ""; // Holds session ID.
- private string m_ConnectedIp = ""; // Holds conneted computers IP.
- private string m_UserName = ""; // Holds loggedIn UserName.
- private string m_Password = ""; // Holds loggedIn Password.
- private bool m_Authenticated = false; // Holds authentication flag.
- private string m_MD5_prefix = ""; // Session MD5 prefix for APOP command
- private int m_BadCmdCount = 0; // Holds number of bad commands.
- private POP3_Messages m_POP3_Messages = null;
- private _LogWriter m_pLogWriter = null;
-
- // Events
- internal ValidateIPHandler ValidateIPAddress = null;
- internal AuthUserEventHandler AuthUser = null;
- internal GetMessagesInfoHandler GetMessgesList = null;
- internal GetMessageHandler GetMailEvent = null;
- internal DeleteMessageHandler DeleteMessageEvent = null;
- internal GetTopLinesHandler GetTopLines = null;
-
- /// <summary>
- /// Default constructor.
- /// </summary>
- /// <param name="clientSocket">Referance to socket.</param>
- /// <param name="server">Referance to POP3 server.</param>
- /// <param name="sessionID">Session ID which is assigned to this session.</param>
- /// <param name="logWriter">Log writer.</param>
- public POP3_Session(Socket clientSocket,POP3_Server server,string sessionID,_LogWriter logWriter)
- {
- m_pClientSocket = clientSocket;
- m_pPOP3_Server = server;
- m_SessionID = sessionID;
- m_POP3_Messages = new POP3_Messages();
- m_pLogWriter = logWriter;
- }
- #region function StartProcessing
- /// <summary>
- /// Starts POP3 Session processing.
- /// </summary>
- public void StartProcessing()
- {
- try
- {
- // Store client ip
- m_ConnectedIp = Core.ParseIP_from_EndPoint(m_pClientSocket.RemoteEndPoint.ToString());
- // Check if ip is allowed to connect this computer
- if(OnValidate_IpAddress(m_ConnectedIp)){
- // Notify that server is ready
- m_MD5_prefix = "<" + Guid.NewGuid().ToString().ToLower() + ">";
- SendData("+OK POP3 server ready " + m_MD5_prefix + "rn");
-
- // Create message loop
- int lastCmdTime = Environment.TickCount;
- string lastCmd = "";
- while(true)
- {
- if(m_pClientSocket.Available > 0){
- ReadReplyCode replyCode = Core.ReadLineFromSocket(m_pClientSocket,out lastCmd,m_pPOP3_Server.CommandIdleTimeOut);
- if(replyCode == ReadReplyCode.Ok){
- if(SwitchCommand(lastCmd)){
- break;
- }
- }
- //----- There was bad command (usually cmd isn't terminated with '<CRLF>') -------------//
- else{
- //---- Check that maximum bad commands count isn't exceeded ---------------//
- if(m_BadCmdCount > m_pPOP3_Server.MaxBadCommands-1){
- SendData("-ERR Too many bad commandsrn");
- break;
- }
- m_BadCmdCount++;
- //-------------------------------------------------------------------------//
- switch(replyCode)
- {
- case ReadReplyCode.LenghtExceeded:
- SendData("-ERR Line too long.rn");
- break;
- case ReadReplyCode.TimeOut:
- SendData("-ERR Command timeout.rn");
- break;
- case ReadReplyCode.UnKnownError:
- SendData("-ERR UnKnown Error.rn");
-
- m_pPOP3_Server.OnSysError(new Exception("ReadReplyCode.UnKnownError"),new System.Diagnostics.StackTrace());
- break;
- }
- }
- //------- End of bad command ------------------------------------------------------------//
- // reset last command time
- lastCmdTime = Environment.TickCount;
- }
- //----- Session timeout stuff ------------------------------------------------//
- if(m_pClientSocket.Available == 0){
- if(Environment.TickCount > lastCmdTime + m_pPOP3_Server.SessionIdleTimeOut){
- // Notify for closing
- SendData("-ERR Session timeout, OK POP3 server signing offrn");
- break;
- }
-
- // Wait 100ms to save CPU, otherwise while loop may take 100% CPU.
- Thread.Sleep(100);
- }
- //-----------------------------------------------------------------------------//
- }
- }
- }
- catch(ThreadInterruptedException x){
- }
- catch(Exception x){
- if(!m_pClientSocket.Connected){
- m_pLogWriter.AddEntry("Connection is aborted by client machine",this.SessionID,m_ConnectedIp,"x");
- return;
- }
- m_pPOP3_Server.OnSysError(x,new System.Diagnostics.StackTrace());
- }
- finally{
- m_pPOP3_Server.RemoveSession(this.SessionID,m_pLogWriter);
- m_pClientSocket.Close();
- // Write logs to log file, if needed
- if(m_pPOP3_Server.LogCommands){
- m_pLogWriter.Flush();
- }
- }
- }
- #endregion
- #region function SwitchCommand
- /// <summary>
- /// Parses and executes POP3 commmand.
- /// </summary>
- /// <param name="POP3_commandTxt">POP3 command text.</param>
- /// <returns>Returns true,if session must be terminated.</returns>
- private bool SwitchCommand(string POP3_commandTxt)
- {
- try
- {
- //---- Parse command --------------------------------------------------//
- string[] cmdParts = POP3_commandTxt.TrimStart().Split(new char[]{' '});
- string POP3_command = cmdParts[0];
- POP3_command = POP3_command.ToUpper();
- //---------------------------------------------------------------------//
- //----- loging stuff --------------------------------------------------------------------------//
- if(m_pPOP3_Server.LogCommands){
- string lCmdTxt = POP3_commandTxt.Replace("rn","<CRLF>");
- m_pLogWriter.AddEntry(lCmdTxt,this.SessionID,m_ConnectedIp,"C");
- }
- //---- End of loging ---------------------------------------------------------------------------//
- switch(POP3_command)
- {
- case "USER":
- USER(Core.GetArgsText(POP3_commandTxt,"USER"));
- break;
- case "PASS":
- PASS(Core.GetArgsText(POP3_commandTxt,"PASS"));
- break;
-
- case "STAT":
- STAT();
- break;
- case "LIST":
- LIST(Core.GetArgsText(POP3_commandTxt,"LIST"));
- break;
- case "RETR":
- RETR(Core.GetArgsText(POP3_commandTxt,"RETR"));
- break;
- case "DELE":
- DELE(Core.GetArgsText(POP3_commandTxt,"DELE"));
- break;
- case "NOOP":
- NOOP();
- break;
- case "RSET":
- RSET();
- break;
- case "QUIT":
- QUIT();
- return true;
- //----- Optional commands ----- //
- case "UIDL":
- UIDL(Core.GetArgsText(POP3_commandTxt,"UIDL"));
- break;
- case "APOP":
- APOP(Core.GetArgsText(POP3_commandTxt,"APOP"));
- break;
- case "TOP":
- TOP(Core.GetArgsText(POP3_commandTxt,"TOP"));
- break;
-
- default:
- SendData("-ERR Invalid commandrn");
- //---- Check that maximum bad commands count isn't exceeded ---------------//
- if(m_BadCmdCount > m_pPOP3_Server.MaxBadCommands-1){
- SendData("421 Too many bad commands, closing transmission channelrn");
- return true;
- }
- m_BadCmdCount++;
- //-------------------------------------------------------------------------//
- break;
-
- }
- }
- catch(Exception x)
- {
- // Connection lost
- if(!m_pClientSocket.Connected){
- return true;
- }
-
- SendData("-ERR Unkown temp errorrn");
- m_pPOP3_Server.OnSysError(x,new System.Diagnostics.StackTrace());
- }
-
- return false;
- }
- #endregion
- #region function USER
- private void USER(string argsText)
- {
- /* RFC 1939 7. USER
- Arguments:
- a string identifying a mailbox (required), which is of
- significance ONLY to the server
-
- NOTE:
- If the POP3 server responds with a positive
- status indicator ("+OK"), then the client may issue
- either the PASS command to complete the authentication,
- or the QUIT command to terminate the POP3 session.
-
- */
- if(m_Authenticated){
- SendData("-ERR You are already authenticatedrn");
- return;
- }
- if(m_UserName.Length > 0){
- SendData("-ERR username is already specified, please specify passwordrn");
- return;
- }
- string[] param = argsText.Split(new char[]{' '});
- // There must be only one parameter - userName
- if(argsText.Length > 0 && param.Length == 1){
- string userName = param[0];
-
- // Check if user isn't logged in already
- if(!m_pPOP3_Server.IsUserLoggedIn(userName)){
- SendData("+OK User:'" + userName + "' ok rn");
- m_UserName = userName;
- }
- else{
- SendData("-ERR User:'" + userName + "' already logged inrn");
- }
- }
- else{
- SendData("-ERR Syntax error. Syntax:{USER username}rn");
- }
- }
- #endregion
- #region function PASS
- private void PASS(string argsText)
- {
- /* RFC 7. PASS
- Arguments:
- a server/mailbox-specific password (required)
-
- Restrictions:
- may only be given in the AUTHORIZATION state immediately
- after a successful USER command
-
- NOTE:
- When the client issues the PASS command, the POP3 server
- uses the argument pair from the USER and PASS commands to
- determine if the client should be given access to the
- appropriate maildrop.
-
- Possible Responses:
- +OK maildrop locked and ready
- -ERR invalid password
- -ERR unable to lock maildrop
-
- */
- if(m_Authenticated){
- SendData("-ERR You are already authenticatedrn");
- return;
- }
- if(m_UserName.Length == 0){
- SendData("-ERR please specify username firstrn");
- return;
- }
- string[] param = argsText.Split(new char[]{' '});
- // There may be only one parameter - password
- if(param.Length == 1){
- string password = param[0];
-
- // Authenticate user
- if(OnAuthUser(m_UserName,password,"",AuthType.Plain)){
- SendData("+OK Password okrn");
- m_Password = password;
- m_Authenticated = true;
- // Get user messages info.
- OnGetMessagesInfo();
- }
- else{
- SendData("-ERR UserName or Password is incorrectrn");
- m_UserName = ""; // Reset userName !!!
- }
- }
- else{
- SendData("-ERR Syntax error. Syntax:{PASS userName}rn");
- }
- }
- #endregion
- #region function STAT
- private void STAT()
- {
- /* RFC 1939 5. STAT
- NOTE:
- The positive response consists of "+OK" followed by a single
- space, the number of messages in the maildrop, a single
- space, and the size of the maildrop in octets.
-
- Note that messages marked as deleted are not counted in
- either total.
-
- Example:
- C: STAT
- S: +OK 2 320
- */
- if(!m_Authenticated){
- SendData("-ERR You must authenticate first.");
- return;
- }
-
- SendData("+OK " + m_POP3_Messages.Count.ToString() + " " + m_POP3_Messages.GetTotalMessagesSize() + "rn");
- }
- #endregion
- #region function LIST
- private void LIST(string argsText)
- {
- /* RFC 1939 5. LIST
- Arguments:
- a message-number (optional), which, if present, may NOT
- refer to a message marked as deleted
-
- NOTE:
- If an argument was given and the POP3 server issues a
- positive response with a line containing information for
- that message.
- If no argument was given and the POP3 server issues a
- positive response, then the response given is multi-line.
-
- Note that messages marked as deleted are not listed.
-
- Examples:
- C: LIST
- S: +OK 2 messages (320 octets)
- S: 1 120
- S: 2 200
- S: .
- ...
- C: LIST 2
- S: +OK 2 200
- ...
- C: LIST 3
- S: -ERR no such message, only 2 messages in maildrop
-
- */
- if(!m_Authenticated){
- SendData("-ERR You must authenticate first.");
- return;
- }
- string[] param = argsText.Split(new char[]{' '});
- // Argument isn't specified, multiline response.
- if(argsText.Length == 0){
- SendData("+OK " + m_POP3_Messages.Count.ToString() + " messagesrn");
-
- // Send message number and size for each message
- foreach(POP3_Message msg in m_POP3_Messages.ActiveMessages){
- SendData(msg.MessageNr.ToString() + " " + msg.MessageSize + "rn");
- }
- // ".<CRLF>" - means end of list
- SendData(".rn");
- }
- else{
- // If parameters specified,there may be only one parameter - messageNr
- if(param.Length == 1){
- // Check if messageNr is valid
- if(Core.IsNumber(param[0])){
- int messageNr = Convert.ToInt32(param[0]);
- if(m_POP3_Messages.MessageExists(messageNr)){
- POP3_Message msg = m_POP3_Messages[messageNr];
- SendData("+OK " + messageNr.ToString() + " " + msg.MessageSize + "rn");
- }
- else{
- SendData("-ERR no such message, or marked for deletionrn");
- }
- }
- else{
- SendData("-ERR message-number is invalidrn");
- }
- }
- else{
- SendData("-ERR Syntax error. Syntax:{LIST [messageNr]}rn");
- }
- }
- }
- #endregion
- #region function RETR
- private void RETR(string argsText)
- {
- /* RFC 1939 5. RETR
- Arguments:
- a message-number (required) which may NOT refer to a
- message marked as deleted
-
- NOTE:
- If the POP3 server issues a positive response, then the
- response given is multi-line. After the initial +OK, the
- POP3 server sends the message corresponding to the given
- message-number, being careful to byte-stuff the termination
- character (as with all multi-line responses).
-
- Example:
- C: RETR 1
- S: +OK 120 octets
- S: <the POP3 server sends the entire message here>
- S: .
-
- */
- if(!m_Authenticated){
- SendData("-ERR You must authenticate first.");
- return;
- }
-
- string[] param = argsText.Split(new char[]{' '});
- // There must be only one parameter - messageNr
- if(argsText.Length > 0 && param.Length == 1){
- // Check if messageNr is valid
- if(Core.IsNumber(param[0])){
- int messageNr = Convert.ToInt32(param[0]);
- if(m_POP3_Messages.MessageExists(messageNr)){
- POP3_Message msg = m_POP3_Messages[messageNr];
- SendData("+OK " + msg.MessageSize + " octetsrn");
-
- // Raise Event, request message
- byte[] message = OnGetMail(msg.MessageID);
- if(message != null){
- //------- Do period handling and send message -----------------------//
- // If line starts with '.', add additional '.'.(Read rfc for more info)
- using(MemoryStream msgStrm = Core.DoPeriodHandling(message,true)){
- // Send message to client
- if(msgStrm != null){
- SendData(msgStrm);
- }
- }
- //-------------------------------------------------------------------//
- }
-
- // "."<CRLF> - means end of message
- SendData(".rn");
- }
- else{
- SendData("-ERR no such messagern");
- }
- }
- else{
- SendData("-ERR message-number is invalidrn");
- }
- }
- else{
- SendData("-ERR Syntax error. Syntax:{RETR messageNr}rn");
- }
- }
- #endregion
- #region function DELE
- private void DELE(string argsText)
- {
- /* RFC 1939 5. DELE
- Arguments:
- a message-number (required) which may NOT refer to a
- message marked as deleted
-
- NOTE:
- The POP3 server marks the message as deleted. Any future
- reference to the message-number associated with the message
- in a POP3 command generates an error. The POP3 server does
- not actually delete the message until the POP3 session
- enters the UPDATE state.
- */
- if(!m_Authenticated){
- SendData("-ERR You must authenticate first.");
- return;
- }
- string[] param = argsText.Split(new char[]{' '});
- // There must be only one parameter - messageNr
- if(argsText.Length > 0 && param.Length == 1){
- // Check if messageNr is valid
- if(Core.IsNumber(param[0])){
- int nr = Convert.ToInt32(param[0]);
- if(m_POP3_Messages.MessageExists(nr)){
- POP3_Message msg = m_POP3_Messages[nr];
- msg.MarkedForDelete = true;
- SendData("+OK marked for deletern");
- }
- else{
- SendData("-ERR no such messagern");
- }
- }
- else{
- SendData("-ERR message-number is invalidrn");
- }
- }
- else{
- SendData("-ERR Syntax error. Syntax:{DELE messageNr}rn");
- }
- }
- #endregion
- #region function NOOP
- private void NOOP()
- {
- /* RFC 1939 5. NOOP
- NOTE:
- The POP3 server does nothing, it merely replies with a
- positive response.
- */
- if(!m_Authenticated){
- SendData("-ERR You must authenticate first.");
- return;
- }
- SendData("+OKrn");
- }
- #endregion
- #region function RSET
- private void RSET()
- {
- /* RFC 1939 5. RSET
- Discussion:
- If any messages have been marked as deleted by the POP3
- server, they are unmarked. The POP3 server then replies
- with a positive response.
- */
- if(!m_Authenticated){
- SendData("-ERR You must authenticate first.");
- return;
- }
- Reset();
- SendData("+OKrn");
- }
- #endregion
- #region function QUIT
- private void QUIT()
- {
- /* RFC 1939 6. QUIT
- NOTE:
- The POP3 server removes all messages marked as deleted
- from the maildrop and replies as to the status of this
- operation. If there is an error, such as a resource
- shortage, encountered while removing messages, the
- maildrop may result in having some or none of the messages
- marked as deleted be removed. In no case may the server
- remove any messages not marked as deleted.
- Whether the removal was successful or not, the server
- then releases any exclusive-access lock on the maildrop
- and closes the TCP connection.
- */
-
- Update();
- SendData("+OK POP3 server signing offrn");
- }
- #endregion
- //--- Optional commands
- #region function TOP
- private void TOP(string argsText)
- {
- /* RFC 1939 7. TOP
- Arguments:
- a message-number (required) which may NOT refer to to a
- message marked as deleted, and a non-negative number
- of lines (required)
-
- NOTE:
- If the POP3 server issues a positive response, then the
- response given is multi-line. After the initial +OK, the
- POP3 server sends the headers of the message, the blank
- line separating the headers from the body, and then the
- number of lines of the indicated message's body, being
- careful to byte-stuff the termination character (as with
- all multi-line responses).
-
- Examples:
- C: TOP 1 10
- S: +OK
- S: <the POP3 server sends the headers of the
- message, a blank line, and the first 10 lines
- of the body of the message>
- S: .
- ...
- C: TOP 100 3
- S: -ERR no such message
-
- */
- string[] param = argsText.Split(new char[]{' '});
-
- // There must be at two parameters - messageNr and nrLines
- if(param.Length == 2){
- // Check if messageNr and nrLines is valid
- if(Core.IsNumber(param[0]) && Core.IsNumber(param[1])){
- int messageNr = Convert.ToInt32(param[0]);
- if(m_POP3_Messages.MessageExists(messageNr)){
- POP3_Message msg = m_POP3_Messages[messageNr];
- byte[] lines = OnGetTopLines(msg.MessageID,Convert.ToInt32(param[1]));
- if(lines != null){
- SendData("+OKrn");
- SendData(lines);
- SendData(".rn");
- }
- else{
- SendData("-ERR no such messagern");
- }
- }
- else{
- SendData("-ERR no such messagern");
- }
- }
- else{
- SendData("-ERR message-number or number of lines is invalidrn");
- }
- }
- else{
- SendData("-ERR Syntax error. Syntax:{TOP messageNr nrLines}rn");
- }
- }
- #endregion
- #region function UIDL
- private void UIDL(string argsText)
- {
- /* RFC 1939 UIDL [msg]
- Arguments:
- a message-number (optional), which, if present, may NOT
- refer to a message marked as deleted
-
- NOTE:
- If an argument was given and the POP3 server issues a positive
- response with a line containing information for that message.
- If no argument was given and the POP3 server issues a positive
- response, then the response given is multi-line. After the
- initial +OK, for each message in the maildrop, the POP3 server
- responds with a line containing information for that message.
-
- Examples:
- C: UIDL
- S: +OK
- S: 1 whqtswO00WBw418f9t5JxYwZ
- S: 2 QhdPYR:00WBw1Ph7x7
- S: .
- ...
- C: UIDL 2
- S: +OK 2 QhdPYR:00WBw1Ph7x7
- ...
- C: UIDL 3
- S: -ERR no such message
- */
- string[] param = argsText.Split(new char[]{' '});
- // Argument isn't specified, multiline response.
- if(argsText.Length == 0){
- SendData("+OKrn");
- // List all messages UID's
- foreach(POP3_Message msg in m_POP3_Messages.ActiveMessages){
- SendData("+OK " + msg.MessageNr.ToString() + " " + msg.MessageID + "rn");
- }
- SendData(".rn");
- }
- else{
- // If parameters specified,there may be only one parameter - messageID
- if(param.Length == 1){
- // Check if messageNr is valid
- if(Core.IsNumber(param[0])){
- int messageNr = Convert.ToInt32(param[0]);
- if(m_POP3_Messages.MessageExists(messageNr)){
- POP3_Message msg = m_POP3_Messages[messageNr];
- SendData("+OK " + messageNr.ToString() + " " + msg.MessageID + "rn");
- }
- else{
- SendData("-ERR no such messagern");
- }
- }
- else{
- SendData("-ERR message-number is invalidrn");
- }
- }
- else{
- SendData("-ERR Syntax error. Syntax:{UIDL [messageNr]}rn");
- }
- }
- }
- #endregion
- #region function APOP
- private void APOP(string argsText)
- {
- /* RFC 1939 7. APOP
- Arguments:
- a string identifying a mailbox and a MD5 digest string
- (both required)
-
- NOTE:
- A POP3 server which implements the APOP command will
- include a timestamp in its banner greeting. The syntax of
- the timestamp corresponds to the `msg-id' in [RFC822], and
- MUST be different each time the POP3 server issues a banner
- greeting.
-
- Examples:
- S: +OK POP3 server ready <1896.697170952@dbc.mtview.ca.us>
- C: APOP mrose c4c9334bac560ecc979e58001b3e22fb
- S: +OK maildrop has 1 message (369 octets)
- In this example, the shared secret is the string `tan-
- staaf'. Hence, the MD5 algorithm is applied to the string
- <1896.697170952@dbc.mtview.ca.us>tanstaaf
-
- which produces a digest value of
- c4c9334bac560ecc979e58001b3e22fb
-
- */
- string[] param = argsText.Split(new char[]{' '});
- // There must be two params
- if(param.Length == 2){
- string userName = param[0];
- string md5HexHash = param[1];
- // Authenticate user
- if(OnAuthUser(userName,md5HexHash,m_MD5_prefix,AuthType.APOP)){
- m_UserName = userName;
- SendData("+OK authentication was successfulrn");
- }
- else{
- SendData("-ERR authentication failedrn");
- }
- }
- else{
- SendData("-ERR syntax error. Syntax:{APOP userName md5HexHash}rn");
- }
- }
- #endregion
- #region function AUTH ???
- private void AUTH()
- {
- }
- #endregion
-
- #region function Reset
- private void Reset()
- {
- /* RFC 1939 5. RSET
- Discussion:
- If any messages have been marked as deleted by the POP3
- server, they are unmarked.
- */
- m_POP3_Messages.ResetDeleteFlags();
- }
- #endregion
- #region function Update
- private void Update()
- {
- /* RFC 1939 6.
- NOTE:
- When the client issues the QUIT command from the TRANSACTION state,
- the POP3 session enters the UPDATE state. (Note that if the client
- issues the QUIT command from the AUTHORIZATION state, the POP3
- session terminates but does NOT enter the UPDATE state.)
- If a session terminates for some reason other than a client-issued
- QUIT command, the POP3 session does NOT enter the UPDATE state and
- MUST not remove any messages from the maildrop.
- */
- if(m_Authenticated){
- // Delete all message which are marked for deletion ---//
- foreach(POP3_Message msg in m_POP3_Messages.Messages){
- if(msg.MarkedForDelete){
- OnDeleteMessage(msg.MessageID);
- }
- }
- //-----------------------------------------------------//
- }
- }
- #endregion
- #region function SendData (3)
-
- private void SendData(string data)
- {
- Byte[] byte_data = System.Text.Encoding.ASCII.GetBytes(data.ToCharArray());
- int size = m_pClientSocket.Send(byte_data,byte_data.Length,0);
- if(m_pPOP3_Server.LogCommands){
- string reply = System.Text.Encoding.ASCII.GetString(byte_data);
- reply = reply.Replace("rn","<CRLF>");
- m_pLogWriter.AddEntry(reply,this.SessionID,m_ConnectedIp,"S");
- }
- }
- private void SendData(byte[] data)
- {
- using(MemoryStream strm = new MemoryStream(data)){
- SendData(strm);
- }
- }
- private void SendData(MemoryStream strm)
- {
- //---- split message to blocks -------------------------------//
- long totalSent = 0;
- while(strm.Position < strm.Length){
- int blockSize = 4024;
- byte[] dataBuf = new byte[blockSize];
- int nCount = strm.Read(dataBuf,0,blockSize);
- m_pClientSocket.Send(dataBuf,nCount,SocketFlags.None);
- totalSent += nCount;
- }
- //-------------------------------------------------------------//
- if(m_pPOP3_Server.LogCommands){
- m_pLogWriter.AddEntry("big binary " + strm.Length.ToString() + " bytes'",this.SessionID,m_ConnectedIp,"S");
- }
- }
- #endregion
- #region Properties Implementation
- /// <summary>
- /// Gets session ID.
- /// </summary>
- public string SessionID
- {
- get{ return m_SessionID; }
- }
- /// <summary>
- /// Gets userName.
- /// </summary>
- public string UserName
- {
- get{ return m_UserName; }
- }
- #endregion
- #region Events Implementation
- #region function OnValidate_IpAddress
- // ---- Events implementation -------------------------------//
- protected virtual bool OnValidate_IpAddress(string ConnectedIP)
- {
- ValidateIP_EventArgs oArg = new ValidateIP_EventArgs(ConnectedIP);
- if(this.ValidateIPAddress != null){
- this.ValidateIPAddress(this, oArg);
- }
- return oArg.Validated;
-
- }
- #endregion
- #region function OnAuthUser
- /// <summary>
- ///
- /// </summary>
- /// <param name="userName"></param>
- /// <param name="passwData"></param>
- /// <param name="data"></param>
- /// <param name="authType"></param>
- /// <returns></returns>
- protected virtual bool OnAuthUser(string userName,string passwData,string data,AuthType authType)
- {
- AuthUser_EventArgs oArg = new AuthUser_EventArgs(m_ConnectedIp,userName,passwData,data,authType);
- if(this.AuthUser != null){
- this.AuthUser(this,oArg);
- }
-
- return oArg.Validated;
- }
- #endregion
- #region function OnGetMessagesInfo
- protected virtual void OnGetMessagesInfo()
- {
- GetMessagesInfo_EventArgs oArg = new GetMessagesInfo_EventArgs(m_POP3_Messages,m_UserName);
- if(this.GetMessgesList != null){
- this.GetMessgesList(this, oArg);
- }
- }
- #endregion
- #region function OnGetMail
- protected virtual byte[] OnGetMail(string messageID)
- {
- GetMessage_EventArgs oArg = new GetMessage_EventArgs(messageID,m_UserName);
- if(this.GetMailEvent != null){
- this.GetMailEvent(this, oArg);
- }
-
- return oArg.Message;
- }
- #endregion
- #region function OnDeleteMessage
- protected virtual bool OnDeleteMessage(string messageID)
- {
- DeleteMessage_EventArgs oArg = new DeleteMessage_EventArgs(messageID,m_UserName);
- if(this.DeleteMessageEvent != null){
- this.DeleteMessageEvent(this, oArg);
- }
-
- return true;
- }
- #endregion
- #region function OnGetTopLines
- protected byte[] OnGetTopLines(string messageID,int nLines)
- {
- GetTopLines_Eventargs oArgs = new GetTopLines_Eventargs(m_UserName,messageID,nLines);
- if(this.GetTopLines != null){
- this.GetTopLines(this,oArgs);
- }
- return oArgs.LinesData;
- }
- #endregion
- #endregion
-
- }
- }