Example #1
0
   bool
   POP3Connection::_ProtocolDELE(const String &Parameter)
   {
      String sInputParam;
      sInputParam = Parameter;
      sInputParam.TrimLeft();
      sInputParam.TrimRight();
      long lMessageID = _ttol(sInputParam);

      if (!_account)
      {
         _SendData("-ERR No such message (messages not loaded)");
         return true;
      }

      shared_ptr<Message> message = _GetMessage(lMessageID);
      if (message)
      {
         message->SetFlagDeleted(true);
         _SendData("+OK msg deleted"); 
      }
      else
         _SendData("-ERR No such message");

      return true;
   }
Example #2
0
   void
   POP3Connection::_ProtocolRSET()
   {
      if (Application::Instance()->GetFolderManager()->GetInboxMessages((int) _account->GetID(), _messages))
      {
         _ResetMailbox();
         _SendData("+OK 0");
      }
      else
         _SendData("-ERR Unable to access mailbox.");


   }
Example #3
0
 void
 POP3Connection::_ProtocolUSER(const String &Parameter)
 {
    // Apply domain aliases to the user name.
    shared_ptr<DomainAliases> pDA = ObjectCache::Instance()->GetDomainAliases();
    m_Username = pDA->ApplyAliasesOnAddress(Parameter);
    _SendData("+OK Send your password" );      
 }
Example #4
0
   void
   POP3Connection::_ProtocolQUIT()
   {
      _SaveMailboxChanges();
      _UnlockMailbox();

      _SendData("+OK POP3 server saying goodbye...");
   }
   void
   SMTPClientConnection::_SendQUIT()
   {
      // Disconnect from the remote SMTP server.
      m_bSessionEnded = true;

      _SendData("QUIT");
      _SetState(QUITSENT);
   }
 void
 SMTPClientConnection::_ProtocolSendUsername()
 {
    String sOut;
    StringParser::Base64Encode(m_sUsername, sOut);      
    _SendData(sOut);
    
    _SetState(SENDPASSWORD);
 }
   void
   SMTPClientConnection::_ProtocolSendPassword()
   {
      String sOut;
      StringParser::Base64Encode(m_sPassword, sOut);      
      
      _SetState(PASSWORDCHECK);

      _SendData(sOut);
   }
Example #8
0
   void
   POP3Connection::_ProtocolQUIT()
   {
      // NEED FOR BUG FIX: Unlock should not be allowed unless user was auth'd
      // because next pop check is allowed even if in-use!
      // Problem is people have grown accustomed to this & could cause more
      // issues if fixed.
      _SaveMailboxChanges();
      _UnlockMailbox();

      _SendData("+OK POP3 server saying goodbye...");
   }
Example #9
0
   bool
   POP3Connection::_ProtocolLIST(const String &sParameter)
   {
      if (!_account)
      {
         _SendData("-ERR Message list not loaded");
         return true;
      }

      String sResponse;

      if (sParameter.IsEmpty())
      {
         int iMessageCount = 0;
         __int64 iTotalBytes = 0;
         _GetMailboxContents(iMessageCount, iTotalBytes);

         // preallocate memory to speed up a bit.
         sResponse.reserve(iMessageCount * 10);

         sResponse.Format(_T("+OK %d messages (%I64d octets)"), iMessageCount, iTotalBytes);
         _SendData(sResponse);
      
      
         sResponse = "";
         String sRow;

         int index = 0;
         boost_foreach(shared_ptr<Message> pMessage, _messages)
         {
            index++;
            if (!pMessage->GetFlagDeleted())
            {
               sRow.Format(_T("%d %d\r\n"), index, pMessage->GetSize());
               sResponse.append(sRow);
            }
         }
   void 
   SMTPClientConnection::_ReadAndSend()
   {


      if (IniFileSettings::Instance()->GetLogLevel() > 99) LOG_DEBUG("SMTPClientConnection::~_Continue sendfile");
      // Continue sending the file..
      int bufferSize = GetBufferSize();
      shared_ptr<ByteBuffer> pBuffer = _currentFile.ReadChunk(bufferSize);

      while (pBuffer)
      {
         _transmissionBuffer.Append(pBuffer->GetBuffer(), pBuffer->GetSize());

         if (_transmissionBuffer.Flush())
         {
            // Data was sent. We'll wait with sending more data until
            // the current data has been sent.
            return; 
         }

         pBuffer = _currentFile.ReadChunk(bufferSize);
      }

      if (IniFileSettings::Instance()->GetLogLevel() > 99) LOG_DEBUG("SMTPClientConnection::~_SendFile done close file");
      // We're done sending!
      _currentFile.Close();

      // No more data to send. Make sure all buffered data is flushed.
      _transmissionBuffer.Flush(true);

      if (IniFileSettings::Instance()->GetLogLevel() > 99) LOG_DEBUG("SMTPClientConnection::~_SendFile flushed buffer");

      // We're ready to receive the Message accepted-response.
      if (IniFileSettings::Instance()->GetLogLevel() > 99) LOG_DEBUG("SMTPClientConnection::~_SendFile DATASENT set");

      // No \r\n on end because SendData adds
      _SendData("\r\n.");

      if (IniFileSettings::Instance()->GetLogLevel() > 99) LOG_DEBUG("SMTPClientConnection::~_SendFile . sent");

      // State change moved to AFTER crlf.crlf to help with race condition
      m_CurrentState = DATASENT;
      if (IniFileSettings::Instance()->GetLogLevel() > 99) LOG_DEBUG("SMTPClientConnection::~_SendFile DATASENT set");
      return;
   }
Example #11
0
   void
   POP3Connection::OnConnected()
   {
      String sData;

      String sWelcome = Configuration::Instance()->GetPOP3Configuration()->GetWelcomeMessage();

      sData += "+OK ";
      if (sWelcome.IsEmpty())
         sData += _T("POP3");
      else
         sData += sWelcome;

      _SendData(sData);

      PostReceive();
   }
Example #12
0
   POP3Connection::ParseResult
   POP3Connection::_ProtocolPASS(const String &Parameter)
   {

      m_Password = Parameter;

      AccountLogon accountLogon;
      bool disconnect = false;
      _account = accountLogon.Logon(GetIPAddress(), m_Username, m_Password, disconnect);

      if (disconnect)
      {
         _SendData("-ERR Invalid user name or password. Too many invalid logon attempts.");
         return ResultDisconnect;
      }

      if (!_account)
      {
         if (m_Username.Find(_T("@")) == -1)
            _SendData("-ERR Invalid user name or password. Please use full email address as user name.");
         else
            _SendData("-ERR Invalid user name or password.");

         return ResultNormalResponse;
      }

      // Try to lock mailbox.
      if (!POP3Sessions::Instance()->Lock(_account->GetID()))
      {
         _SendData("-ERR Your mailbox is already locked");
         return ResultNormalResponse; 
      }
  
      if (!Application::Instance()->GetFolderManager()->GetInboxMessages((int) _account->GetID(), _messages))
      {
         _SendData("+ERR Server error: Failed to fetch messages in Inbox.");
         return ResultNormalResponse;
      }

      _ResetMailbox();

      _SendData("+OK Mailbox locked and ready" );
      m_CurrentState = TRANSACTION;
      
      return ResultNormalResponse;
   }
Example #13
0
/************************************************************************
返回值: 
1   发送数据阻塞,等待下次事件通知,  需要设置socket的属性
0   函数正常返回
-1  网络连接出现问题,需要断开该连接
************************************************************************/
int CNetSocket::SendCacheData()
{
	if(miResendLength != 0)
	{
		int nRet = 0;
		nRet = _SendData(mszResendBuffer, miResendLength);
		if(nRet == 0)
		{
			mbCanSend = false;
			return 1;
		}
		if(nRet < 0)
		{
			//TRACE(1, "CNetSocket::SendCacheData 发送数据异常。nRet = "<<nRet<<" miResendLength = "<<miResendLength);
			return -1;
		}
		if((nRet < miResendLength) && (nRet > 0))
		{
			miResendLength -= nRet;
			assert(miResendLength > 0);
			memmove(mszResendBuffer, mszResendBuffer+nRet, miResendLength+1);
			mbCanSend = false;
			return 1;
		}

		if(nRet > miResendLength)
		{
			mbCanSend = false;
			//TRACE(1, "CNetSocket::SendCacheData 发送数据异常。nRet = "<<nRet<<" miResendLength = "<<miResendLength);
			return -1;
		}
	}

	miResendLength = 0;
	memset(mszResendBuffer, 0, SEND_CATCH_LEN);
	return 0;
}
   void
   SMTPClientConnection::InternalParseData(const AnsiString  &Request)
   {
      LOG_DEBUG("SMTPClientConnection::_ParseASCII()");

      String sData = "RECEIVED: " + Request;
      LOG_SMTP_CLIENT(GetSessionID(), GetIPAddress().ToString(), sData);

      // Below 3 lines is fix of the problem that occurs when the remote server answers
      // with 2 line in his welcome message.
      String sMinus = "-";
      if ((Request.GetLength() > 3) && (Request.GetAt(3) == sMinus.GetAt(0)))
      {
         LOG_DEBUG("SMTPClientConnection::~_ParseASCII() - 1");
         return;
      }

      int lFirstSpace = Request.Find(" ");
   
      AnsiString sFirstWordTemp;
      if (lFirstSpace < 0)
         sFirstWordTemp = Request;
      else
         sFirstWordTemp = Request.Mid(0, lFirstSpace);
      sFirstWordTemp.MakeUpper();
      int iCode = atoi(sFirstWordTemp);

      // We should not update all recipient's if we've just sent a
      // RCPT TO. We should only update the specific one we've just
      // sent to.
      // 
      // Also, we should not update state if we've just sent QUIT to
      // the server. At the time we send QUIT, the message has already
      // been either accepted for delivery and rejected. Any error after
      // this isn't relvat.
      if (m_CurrentState != RCPTTOSENT && m_CurrentState != QUITSENT)
      {
         if (IsPermanentNegative(iCode))
         {
            _UpdateAllRecipientsWithError(iCode, Request, false);
            _SendQUIT();
            return;
         }
         else if (IsTransientNegative(iCode))
         {
            _UpdateAllRecipientsWithError(iCode, Request, false);
            _SendQUIT();
            return;
         }
      }
   
      switch (m_CurrentState)
      {
      case SENDUSERNAME:
         _ProtocolSendUsername();
         break;
      case SENDPASSWORD:
         _ProtocolSendPassword();
         break;
      case PASSWORDCHECK:
         if (!_ProtocolPassswordCheck(iCode, Request))
         {
            // Authentication failed. We have just sent
            // a quit command.
            return;
         }

         break;
      }
      
      if (m_CurrentState == HELO)
      {
         if (iCode == 220)
         {
			   String sComputerName = Utilities::ComputerName(); 
      
            if (m_bUseSMTPAuth)
            {
               _SendData("EHLO " + sComputerName);
               _SetState(EHLOSENT);
            }
            else
            {
               _SendData("HELO " + sComputerName);
               _SetState(HELOSENT);
            }
        
            LOG_DEBUG("SMTPClientConnection::~_ParseASCII() - 2");

            return ;
         }
         else
         {
            LOG_DEBUG("SMTPClientConnection::~_ParseASCII() - 3");
            _UpdateAllRecipientsWithError(iCode, Request, false);
            _SendQUIT();
            return;
         }
      }

      if (m_CurrentState == EHLOSENT)
      {
         // Ask the server to initiate login process.
         _SendData("AUTH LOGIN");
         _SetState(SENDUSERNAME);
         return ;
      }

      if (m_CurrentState == HELOSENT)
      {
         if (IsPositiveCompletion(iCode))
         {
            // --- Server accepted HELO. Go to HEADER/MAILFROM state.
            _SetState(MAILFROM);
         }
	      else
         {
            _UpdateAllRecipientsWithError(iCode, Request, false);
         }
      }
   

      if (m_CurrentState == MAILFROM)
      {
         String sFrom = m_pDeliveryMessage->GetFromAddress();
         String sData = "MAIL FROM:<" + sFrom + ">";
         _SendData(sData);
         m_CurrentState = MAILFROMSENT;
         LOG_DEBUG("SMTPClientConnection::~_ParseASCII() - 4");
         return;
      }

      if (m_CurrentState == MAILFROMSENT)
      {
         if (IsPositiveCompletion(iCode))
         {
            // --- Server accepted mail from. Go to header/rcpt to state.
            m_CurrentState = RCPTTO;
         }
         else
         {
            LOG_DEBUG("SMTPClientConnection::~_ParseASCII() - 5");
            _UpdateAllRecipientsWithError(iCode, Request, false);
         }

      }

      if (m_CurrentState == RCPTTO)
      {
         LOG_DEBUG("SMTPClientConnection::~_ParseASCII() - 6");

         shared_ptr<MessageRecipient> pRecipient = _GetNextRecipient();
         if (!pRecipient) 
         {
            _SendQUIT();
            return;
         }
         
         String sRecipient = pRecipient->GetAddress();
         String sData = "RCPT TO:<" + sRecipient + ">";
         _SendData(sData);
         m_CurrentState = RCPTTOSENT;

         return;

      }

      if (m_CurrentState == RCPTTOSENT)
      {
         if (m_iCurRecipient < m_vecRecipients.size())
         {
            if (IsPositiveCompletion(iCode))
            {
               _actualRecipients.insert(m_vecRecipients[m_iCurRecipient]);
            }
            else
            {
               _UpdateRecipientWithError(iCode, Request, m_vecRecipients[m_iCurRecipient], false);
            }
         }

         shared_ptr<MessageRecipient> pRecipient = _GetNextRecipient();
         if (pRecipient)
         {
            // Send next recipient.
            _SendData("RCPT TO:<" + pRecipient->GetAddress() + ">");
            m_CurrentState = RCPTTOSENT;
         }
         else
         {
            if (_actualRecipients.size() == 0)
            {
               _SendQUIT();
               return;
            }
            
            m_CurrentState = DATAQUESTION;
         }
      }

      if (m_CurrentState == DATAQUESTION)
      {
         _SendData("DATA");
         m_CurrentState = DATA;
         LOG_DEBUG("SMTPClientConnection::~_ParseASCII() - 7");
         return;
      }

      if (m_CurrentState == DATA)
      {
         if (IsPositiveIntermediate(iCode))
         {
            // Send the data!
            const String fileName = PersistentMessage::GetFileName(m_pDeliveryMessage);
            LOG_DEBUG("SMTPClientConnection::~_BEFORE SendFile");
            _StartSendFile(fileName);
            LOG_DEBUG("SMTPClientConnection::~_AFTER SendFile");
            return;
         }
      }

      if (m_CurrentState == DATASENT)
      {
            LOG_DEBUG("SMTPClientConnection::~_BEFORE SendQUIT");
         _SendQUIT();
            LOG_DEBUG("SMTPClientConnection::~_AFTER SendQUIT");

         if (IsPositiveCompletion(iCode))
         {
            _UpdateSuccessfulRecipients();
            LOG_DEBUG("SMTPClientConnection::~_ParseASCII() - 9");
            return;
         }
         else
         {
            _UpdateAllRecipientsWithError(iCode, Request, false);
            LOG_DEBUG("SMTPClientConnection::~_ParseASCII() - 10");
         }

         return;
      }

      if (m_CurrentState == QUITSENT)
      {     
         // We just received a reply on our QUIT. Time to disconnect.
         m_bPendingDisconnect = true;
         PostDisconnect();
      }
   }
Example #15
0
   POP3Connection::ParseResult
   POP3Connection::InternalParseData(const AnsiString &Request)
   //---------------------------------------------------------------------------()
   // DESCRIPTION:
   // Parses a client POP3 command.
   //---------------------------------------------------------------------------()
   {
      _LogClientCommand(Request);

      if (Request.GetLength() > 500)
      {
         // This line is to long... is this an evil user?
         _SendData("-ERR Line to long.");
         return ResultNormalResponse;
      }
      
      String sCommand;
      String sParameter;

      if (Request.Find(" ")>-1)
      {
         sCommand = Request.Left(Request.Find(" "));
         sParameter = Request.Mid(Request.Find(" ") + 1);
      }
      else
         sCommand = Request;

      POP3Command command = GetCommand(m_CurrentState, sCommand);

      switch (command)
      {
         case NOOP:
            _SendData("+OK");
            return ResultNormalResponse;
         case HELP:
            _SendData("+OK Normal POP3 commands allowed");
            return ResultNormalResponse;
         case USER:
            _ProtocolUSER(sParameter);
            return ResultNormalResponse;
         case PASS:
            return _ProtocolPASS(sParameter);
         case STAT:
            _ProtocolSTAT(sParameter);
            return ResultNormalResponse;
         case LIST:
            _ProtocolLIST(sParameter);
            return ResultNormalResponse;
         case RETR:
            return _ProtocolRETR(sParameter);
         case DELE:
            _ProtocolDELE (sParameter);
            return ResultNormalResponse;
         case TOP:
            _ProtocolTOP(sParameter);
            return ResultNormalResponse;
         case RSET:
            _ProtocolRSET();
            return ResultNormalResponse;   
         case UIDL:
            _ProtocolUIDL(sParameter);
            return ResultNormalResponse;   
         case QUIT:
            _ProtocolQUIT();
            return ResultDisconnect;
         case CAPA:
            _SendData("+OK CAPA list follows\r\nUSER\r\nUIDL\r\nTOP\r\n.");
            return ResultNormalResponse;
         case INVALID:
            _SendData("-ERR Invalid command in current state." );
            return ResultNormalResponse;  
         default:
            assert(0); // What command is this?
            _SendData("-ERR Invalid command in current state." );
            return ResultNormalResponse;  
      }
   }