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; }
void POP3Connection::_ProtocolRSET() { if (Application::Instance()->GetFolderManager()->GetInboxMessages((int) _account->GetID(), _messages)) { _ResetMailbox(); _SendData("+OK 0"); } else _SendData("-ERR Unable to access mailbox."); }
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" ); }
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); }
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..."); }
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; }
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(); }
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; }
/************************************************************************ 返回值: 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(); } }
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; } }