void POP3ClientConnection::ParseData(const AnsiString &sRequest) { command_buffer_.append(sRequest); command_buffer_.append("\r\n"); bool is_awaiting_multiline_response = current_state_ == StateCAPASent || current_state_ == StateUIDLRequestSent; if (is_awaiting_multiline_response) { bool multiline_response_completed = sRequest == "." || !CommandIsSuccessfull_(command_buffer_); if (!multiline_response_completed) { EnqueueRead(); return; } } bool postReceive = InternalParseData(command_buffer_); // The ASCII buffer has been parsed, so we // may clear it now. command_buffer_.Empty(); if (postReceive) EnqueueRead(); }
void SMTPClientConnection::ParseData(const AnsiString &Request) //---------------------------------------------------------------------------() // DESCRIPTION: // Parses a server SMTP cmmand. //---------------------------------------------------------------------------() { multi_line_response_buffer_ += Request; if (multi_line_response_buffer_.GetLength() > 10000) { UpdateAllRecipientsWithError_(500, "Unexpected response from server (too long).", false); return; } if (Request.GetLength() > 3 && (Request.GetAt(3) == '-')) { // Multi-line response. Wait for full buffer. multi_line_response_buffer_ += "\r\n"; EnqueueRead(); return; } bool postReceive = InternalParseData(multi_line_response_buffer_); multi_line_response_buffer_.Empty(); if (postReceive) EnqueueRead(); }
void POP3ClientConnection::OnHandshakeCompleted() { if (GetConnectionSecurity() == CSSSL) EnqueueRead(); else if (GetConnectionSecurity() == CSSTARTTLSOptional || GetConnectionSecurity() == CSSTARTTLSRequired) { SendUserName_(); EnqueueRead(); } }
void SMTPClientConnection::OnHandshakeCompleted() { if (GetConnectionSecurity() == CSSSL) EnqueueRead(); else if (GetConnectionSecurity() == CSSTARTTLSRequired || GetConnectionSecurity() == CSSTARTTLSOptional) { ProtocolStateHELOEHLO_(""); EnqueueRead(); } }
void SpamAssassinClient::ParseData(std::shared_ptr<ByteBuffer> pBuf) { if (!result_) { String logMessage; logMessage.Format(_T("Parsing response from SpamAssassin. Session %d"), GetSessionID()); LOG_DEBUG(logMessage); result_ = std::shared_ptr<File>(new File); result_->Open(FileUtilities::GetTempFileName(), File::OTAppend); spam_dsize_ = ParseFirstBuffer_(pBuf); } // Append output to the file result_->Write(pBuf); total_result_bytes_written_ += pBuf->GetSize(); if (total_result_bytes_written_ < spam_dsize_) EnqueueRead(); else FinishTesting_(); }
void POP3ClientConnection::OnConnected() { if (GetConnectionSecurity() == CSNone || GetConnectionSecurity() == CSSTARTTLSOptional || GetConnectionSecurity() == CSSTARTTLSRequired) EnqueueRead(); }
void POP3ClientConnection::ParseData(std::shared_ptr<ByteBuffer> pBuf) { // Append message buffer with the binary data we've received. if (!transmission_buffer_) { if (!ParseFirstBinary_(pBuf)) { EnqueueRead(""); return; } String fileName = PersistentMessage::GetFileName(current_message_); // Create a binary buffer for this message. transmission_buffer_ = std::shared_ptr<TransparentTransmissionBuffer>(new TransparentTransmissionBuffer(false)); if (!transmission_buffer_->Initialize(fileName)) { // We have probably failed to create the file... LOG_DEBUG("POP3 External Account: Error creating binary buffer or file."); QuitNow_(); return; } PrependHeaders_(); } transmission_buffer_->Append(pBuf->GetBuffer(), pBuf->GetSize()); transmission_buffer_->Flush(); // Clear the binary buffer. pBuf->Empty(); if (!transmission_buffer_->GetTransmissionEnded()) { EnqueueRead(""); return; } // Since this may be a time-consuming task, do it asynchronously std::shared_ptr<AsynchronousTask<TCPConnection> > finalizationTask = std::shared_ptr<AsynchronousTask<TCPConnection> >(new AsynchronousTask<TCPConnection> (std::bind(&POP3ClientConnection::HandlePOP3FinalizationTaskCompleted_, this), shared_from_this())); Application::Instance()->GetAsyncWorkQueue()->AddTask(finalizationTask); }
void SMTPClientConnection::OnConnected() { if (GetConnectionSecurity() == CSNone || GetConnectionSecurity() == CSSTARTTLSRequired || GetConnectionSecurity() == CSSTARTTLSOptional) { EnqueueRead(); } }
void POP3ClientConnection::HandlePOP3FinalizationTaskCompleted_() { // The entire message has now been downloaded from the // remote POP3 server. Save it in the database and deliver // it to the account. String fileName = PersistentMessage::GetFileName(current_message_); current_message_->SetSize(FileUtilities::FileSize(fileName)); if (current_message_->GetSize() == 0) { // Error handling. LOG_DEBUG("POP3 External Account: Message is 0 bytes."); QuitNow_(); return; } ParseMessageHeaders_(); if (DoSpamProtection_()) { // should we scan this message for virus later on? current_message_->SetFlagVirusScan(account_->GetUseAntiVirus()); FireOnExternalAccountDownload_(current_message_, (*cur_message_).second); // the message was not classified as spam which we should delete. SaveMessage_(); // Notify the SMTP deliverer that there is a new message. Application::Instance()->SubmitPendingEmail(); } MarkCurrentMessageAsRead_(); // Switch to ASCII since we're going to request a new message. SetReceiveBinary(false); // Move on to the next message to download cur_message_++; RequestNextMessage_(); EnqueueRead(""); }
bool SpamAssassinClient::SendFileContents_(const String &sFilename) { String logMessage; logMessage.Format(_T("Sending message to SpamAssassin. Session %d, File: %s"), GetSessionID(), sFilename.c_str()); LOG_DEBUG(logMessage); File oFile; try { oFile.Open(sFilename, File::OTReadOnly); } catch (...) { String sErrorMsg; sErrorMsg.Format(_T("Could not send file %s via socket since the file could not be opened."), sFilename.c_str()); ErrorManager::Instance()->ReportError(ErrorManager::High, 5019, "SMTPClientConnection::SendFileContents_", sErrorMsg); return false; } const int maxIterations = 100000; for (int i = 0; i < maxIterations; i++) { std::shared_ptr<ByteBuffer> pBuf = oFile.ReadChunk(20000); if (pBuf->GetSize() == 0) break; BYTE *pSendBuffer = (BYTE*) pBuf->GetBuffer(); size_t iSendBufferSize = pBuf->GetSize(); EnqueueWrite(pBuf); } EnqueueShutdownSend(); // Request the response... EnqueueRead(""); return true; }
void SMTPClientConnection::ReadAndSend_() { // Continue sending the file.. int bufferSize = GetBufferSize(); std::shared_ptr<ByteBuffer> pBuffer = current_file_.ReadChunk(bufferSize); while (pBuffer->GetSize() > 0) { transmission_buffer_.Append(pBuffer->GetBuffer(), pBuffer->GetSize()); if (transmission_buffer_.Flush()) { // Data was sent. We'll wait with sending more data until // the current data has been sent. return; } pBuffer = current_file_.ReadChunk(bufferSize); } // We're done sending! current_file_.Close(); // No more data to send. Make sure all buffered data is flushed. transmission_buffer_.Flush(true); // We're ready to receive the Message accepted-response. // No \r\n on end because EnqueueWrite adds EnqueueWrite_("\r\n."); EnqueueRead(); // State change moved to AFTER crlf.crlf to help with race condition current_state_ = DATASENT; }
void TCPConnection::EnqueueRead() { EnqueueRead(GetCommandSeparator()); }