MojErr AuthYahooCommand::HandleResponse(const std::string& line) { SmtpSession::SmtpError error; MojLogInfo(m_log, "AUTH XYMCOOKIE command response"); if (m_state == State_SendingYCookie) { if (m_statusCode == 334) { m_state = State_SendingTCookie; WriteCommand(); } else { error = GetStandardError(); error.internalError = "AUTH XYMCOOKIE, no tcookie prompt"; m_session.AuthYahooFailure(error); } } else if (m_state == State_SendingTCookie) { if (m_status == Status_Ok) { MojLogInfo(m_log, "AUTH XYMCOOKIE OK"); m_session.AuthYahooSuccess(); } else { error = GetStandardError(); error.internalError = "AUTH XYMCOOKIE failed at ycookie prompt"; m_session.AuthYahooFailure(error); } Complete(); } return MojErrNone; }
MojErr OldHelloCommand::HandleResponse(const std::string& line) { if (m_statusCode == 250) { m_session.HasSizeExtension(false); m_session.HasTLSExtension(false); m_session.HasChunkingExtension(false); m_session.HasPipeliningExtension(false); m_session.HasAuthExtension(false); m_session.HasPlainAuth(false); m_session.HasLoginAuth(false); m_session.HasYahooAuth(false); m_status = Status_Ok; m_session.HelloSuccess(); } else { m_status = Status_Err; SmtpSession::SmtpError error = GetStandardError(); error.internalError = "HLO failed"; m_session.HelloFailure(error); } Complete(); return MojErrNone; }
MojErr AuthPlainCommand::HandleResponse(const std::string& line) { MojLogInfo(m_log, "AUTH PLAIN command response"); if (m_status == Status_Ok) { MojLogInfo(m_log, "AUTH PLAIN OK"); m_session.AuthPlainSuccess(); } else { SmtpSession::SmtpError error = GetStandardError(); error.internalError = "AUTH PLAIN failed"; m_session.AuthPlainFailure(error); } Complete(); return MojErrNone; }
MojErr SmtpSendMailCommand::HandleResponse(const std::string& line) { try { switch (m_write_state) { case State_SendMailFrom: { MojLogInfo(m_log, "MAIL FROM command response"); if (m_status == Status_Ok) { MojLogInfo(m_log, "MAIL FROM command +OK"); m_toIdx = 0; if(m_toIdx < m_toAddress.size()) { m_write_state = State_SendRcptTo; } else { m_error.errorCode = MailError::BAD_RECIPIENTS; // Error out if for some reason there is no recipient. m_error.errorOnEmail = true; m_error.errorOnAccount = false; m_error.internalError = "Error setting forward address"; m_write_state = State_SendErrorRset; } WriteEmail(); } else { MojLogInfo(m_log, "MAIL FROM command -ERR"); m_error = GetStandardError(); m_error.internalError = "Error setting reverse address"; m_write_state = State_SendErrorRset; WriteEmail(); } break; } case State_SendRcptTo: { MojLogInfo(m_log, "RCPT TO command response"); if (m_status == Status_Ok) { m_toIdx++; if (m_toIdx < m_toAddress.size()) { MojLogInfo(m_log, "RCPT TO command +OK, more to come"); m_write_state = State_SendRcptTo; } else { MojLogInfo(m_log, "RCPT TO command +OK, done"); m_write_state = State_SendData; } WriteEmail(); } else { MojLogInfo(m_log, "RCPT TO command -ERR"); m_error = GetStandardError(); if (m_status == 550) { // general failure means bad recipient m_error.errorCode = MailError::BAD_RECIPIENTS; m_error.errorOnEmail = true; m_error.errorOnAccount = false; } // 452 is technically a non-fatal error that says no more recipients can be // added, on the expectation we'll go and send our mail, and then send a // copy to the next batch of recipients. Instead, we'll treat this as a // permanent error, and not send it to anyone (by sending RSET, and not DATA). // 552 is (as the spec says) an old and occasionally seen typo of 452. if (m_status == 452 || m_status == 552) { m_error.errorCode = MailError::BAD_RECIPIENTS; // too many, actually m_error.errorOnEmail = true; m_error.errorOnAccount = false; } m_error.internalError = "Error setting forward address"; m_write_state = State_SendErrorRset; WriteEmail(); } break; } case State_SendData: { MojLogInfo(m_log, "DATA command response"); if (m_status == Status_Ok) { MojLogInfo(m_log, "DATA command +OK"); m_write_state = State_SendBody; WriteEmail(); } else { MojLogInfo(m_log, "DATA command -ERR"); m_error = GetStandardError(); m_error.internalError = "Error starting mail body"; m_write_state = State_SendErrorRset; WriteEmail(); } break; } case State_SendBody: { MojLogInfo(m_log, "BODY command response"); if (m_status == Status_Ok) { MojLogInfo(m_log, "BODY command +OK"); m_write_state = State_SendRset; WriteEmail(); } else { MojLogInfo(m_log, "BODY command -ERR"); m_error = GetStandardError(); m_error.internalError = "Error completing send"; m_write_state = State_SendErrorRset; WriteEmail(); } break; } case State_SendRset: { MojLogInfo(m_log, "RSET command response"); if (m_status == Status_Ok) { MojLogInfo(m_log, "RSET command +OK"); SendDone(); } else { MojLogInfo(m_log, "RSET command -ERR"); m_error = GetStandardError(); m_error.internalError = "Error resetting"; HandleSmtpError(m_error); } break; } case State_SendErrorRset: { // Handle an error response after clearing an error: if we had one bad e-mail, we want to // be sure we are in a good state before going to the next e-mail. HandleSmtpError(m_error); break; } default: { MojLogInfo(m_log, "Unknown write mail state %d in SmtpSendMailCommand::HandleResponse", m_write_state); HandleFailure("bad HandleResponse state"); break; } } } catch(const std::exception& e) { HandleException(e, __func__, __FILE__, __LINE__); } catch(...) { HandleUnknownException(); } return MojErrNone; }