/*++ Copyright (c) 1994 Microsoft Corporation Module Name : smtpcli.hxx Abstract: This module defines the SMTP_CONNECTION class. This object maintains information about a new client connection Author: Rohan Phillips ( Rohanp ) 11-Dec-1995 Project: SMTP Server DLL Revision History: --*/ #ifndef _SMTP_CLIENT_HXX_ #define _SMTP_CLIENT_HXX_ /************************************************************ * Include Headers ************************************************************/ #include "conn.hxx" #include "simssl2.h" #include "addr821.hxx" /************************************************************ * Symbolic Constants ************************************************************/ static const char * SmtpCommands [] = { #undef SmtpDef #define SmtpDef(a) #a, #include "smtpdef.h" NULL }; enum SMTPSTATE { #undef SmtpDef #define SmtpDef(a) a, #include "smtpdef.h" LAST_SMTP_STATE }; enum LASTIOSTATE { READIO, WRITEIO, TRANSFILEIO, MAIL_QUEUEIO, REMOTE_MAIL_QUEUEIO, WRITEFILEIO }; const DWORD MIN_SMTP_COMMAND_SIZE = 4; //4 chars const DWORD SMTP_RESP_STATUS = 211; const DWORD SMTP_RESP_HELP = 214; const DWORD SMTP_RESP_READY = 220; const DWORD SMTP_RESP_CLOSE = 221; const DWORD SMTP_RESP_AUTHENTICATED = 235; const DWORD SMTP_RESP_OK = 250; const DWORD SMTP_RESP_WILL_FWRD = 251; const DWORD SMTP_RESP_ETRN_ZERO_MSGS = 251; const DWORD SMTP_RESP_VRFY_CODE = 252; const DWORD SMTP_RESP_ETRN_N_MSGS = 253; const DWORD SMTP_RESP_AUTH1_PASSED = 334; const DWORD SMTP_RESP_START = 354; const DWORD SMTP_RESP_SRV_UNAVAIL = 421; const DWORD SMTP_RESP_MBX_UNAVAIL = 450; const DWORD SMTP_RESP_REJECT_MAILFROM = 450; const DWORD SMTP_RESP_ERROR = 451; const DWORD SMTP_RESP_NORESOURCES = 452; const DWORD SMTP_RESP_NODE_INVALID = 459; const DWORD SMTP_RESP_BAD_CMD = 500; const DWORD SMTP_RESP_BAD_ARGS = 501; const DWORD SMTP_RESP_NOT_IMPL = 502; const DWORD SMTP_RESP_BAD_SEQ = 503; const DWORD SMTP_RESP_PARM_NOT_IMP = 504; const DWORD SMTP_RESP_MUST_SECURE = 530; const DWORD SMTP_RESP_AUTH_REJECT = 535; const DWORD SMTP_RESP_NOT_FOUND = 550; const DWORD SMTP_RESP_PLS_FWRD = 551; const DWORD SMTP_RESP_NOSTORAGE = 552; const DWORD SMTP_RESP_MBX_SYNTAX = 553; const DWORD SMTP_RESP_TRANS_FAILED = 554; //State of FSA in IsLineCompleteRFC822 const DWORD SEEN_NOTHING = 1; const DWORD SEEN_CR = 2; const DWORD SEEN_CRLF = 3; /* strings to be appended to numeric reply codes */ static const char * SMTP_READY_STR = "SMTP server ready"; static const char * SMTP_BAD_CMD_STR = "Unrecognized command"; static const char * SMTP_BAD_BODY_TYPE_STR = "Unsupported BODY type"; static const char * SMTP_MAIL_OK_STR = "Sender OK"; static const char * SMTP_QUIT_OK_STR = "Service closing transmission channel"; static const char * SMTP_BAD_SEQ_STR = "Bad sequence of commands"; static const char * SMTP_NOT_IMPL_STR = "Command not implemented"; static const char * SMTP_HELO_OK_STR = "Hi there, pleased to meet you"; static const char * SMTP_RECIP_OK_STR = "Recipient OK"; static const char * SMTP_BAD_RECIP_STR = "Addressee unknown"; static const char * SMTP_START_MAIL_STR = "Start mail input; end with ."; static const char * SMTP_RSET_OK_STR = "Resetting"; static const char * SMTP_LOCAL_DEL_STR = "Error in local delivery"; static const char * SMTP_SRV_UNAVAIL_STR = "Service not available or retries exceeded, closing channel"; static const char * SMTP_NO_STORAGE = "Insufficient system storage"; static const char * SMTP_NO_VALID_RECIPS = "No valid recipients"; static const char * SMTP_QUEUE_MAIL = "Queued mail for delivery"; static const char * SMTP_NO_MEMORY = "Out of memory"; static const char * SMTP_EMPTY_MAIL = "Empty mail message"; static const char * SMTP_TIMEOUT_MSG = "Timeout waiting for client input"; static const char * SMTP_TOO_MANY_ERR_MSG = "Too many errors on this connection---closing"; static const char * SMTP_NO_DOMAIN_NAME_MSG = "Domain Name required"; static const char * SMTP_NEED_MAIL_FROM_MSG = "Need Mail From: first"; static const char * SMTP_MAX_MSG_SIZE_EXCEEDED_MSG = "Message size exceeds fixed maximum message size"; static const char * SMTP_MAX_SESSION_SIZE_EXCEEDED_MSG = "Session size exceeds fixed maximum session size"; static const char * SMTP_INVALID_ADDR_MSG = "Invalid Address"; static const char * SMTP_SRV_UNAVAIL_MSG = "Service not available, closing transmission channel"; static const char * SMTP_NO_ETRN_IN_MSG = "ETRN may not be issued while mail transaction is occurring"; static const char * SMTP_ONLY_ONE_TLS_MSG = "Only one STARTTLS command can be issued per session"; static const char * SMTP_TLS_NOT_SUPPORTED = "Not supported at this server"; static const char * SMTP_NO_CERT_MSG = "Unable to initialize security subsystem"; static const char * SMTP_MSG_MUST_SECURE = "Must issue a STARTTLS command first"; static const char * SMTP_MSG_NOT_SECURE_ENOUGH = "Command refused due to lack of security"; static const char * SMTP_BDAT_EXPECTED = "BDAT command expected"; static const char * SMTP_BDAT_CHUNK_OK_STR = "CHUNK received OK"; static const char * SMTP_RDNS_REJECTION = "Rejected : Domain does not match IP address"; static const char * SMTP_RDNS_FAILURE = "Unable to verify the connecting host domain"; static const char * SMTP_REMOTE_HOST_REJECTED_FOR_SIZE = "Msg Size greater than allowed by Remote Host"; static const char * SMTP_REMOTE_HOST_REJECTED_FOR_TYPE = "Body type not supported by Remote Host"; static const char * SMTP_REMOTE_HOST_DROPPED_CONNECTION = "Connection dropped by Remote Host"; static const char * SMTP_REMOTE_HOST_REJECTED_AUTH = "Failed to authenticate with Remote Host"; static const char * SMTP_REMOTE_HOST_REJECTED_SSL = "Failed to negotiate secure channel with Remote Host"; //Enhanced status codes static const char * EPROT_SUCCESS = "2.0.0"; static const char * E_GOODBYE = "2.0.0"; static const char * ESENDER_ADDRESS_VALID = "2.1.0"; static const char * EVALID_DEST_ADDRESS = "2.1.5"; static const char * EMESSAGE_GOOD = "2.6.0"; static const char * ESEC_SUCCESS = "2.7.0"; static const char * EINTERNAL_ERROR = "4.0.0"; static const char * ENO_RESOURCES = "4.3.1"; static const char * ESVC_SHUTDOWN = "4.3.2"; static const char * ENO_SECURITY_TMP = "4.7.3"; static const char * EMAILBOX_FULL = "4.2.2"; static const char * EBAD_SENDER = "5.1.7"; static const char * ENOT_IMPLEMENTED = "5.3.3"; static const char * EMESSAGE_TOO_BIG = "5.3.4"; static const char * EINVALID_COMMAND = "5.5.1"; static const char * ESYNTAX_ERROR = "5.5.2"; static const char * ETOO_MANY_RCPTS = "5.5.3"; static const char * EINVALID_ARGS = "5.5.4"; static const char * ENO_FORWARDING = "5.7.1"; static const char * ENO_SECURITY = "5.7.3"; static const char * E_TLSNEEDED = "5.7.0"; static const char * ENO_SEC_PACKAGE = "5.7.4"; const DWORD MIN_BUFFLENGTH = 10; const DWORD SMTP_MAX_ERRORS = 10; const DWORD SMTP_MAX_USER_NAME_LEN = 64; const DWORD SMTP_MAX_DOMAIN_NAME_LEN = 256; const DWORD SMTP_MAX_PATH_LEN = 64; const DWORD SMTP_MAX_COMMANDLINE_LEN = 512; const DWORD SMTP_MAX_REPLY_LEN = 1024; const DWORD SMTP_MAX_MSG_SIZE = 42 * 1024; const char SMTP_COMMAND_NOERROR = (char) 0; const char SMTP_COMMAND_TOO_SHORT = (char) 1; const char SMTP_COMMAND_TOO_LONG = (char) 2; const char SMTP_COMMAND_NOT_FOUND = (char) 3; enum MailBodyDiagnosticCode { ERR_NONE = 0, ERR_OUT_OF_MEMORY, ERR_MAX_MSG_SIZE, ERR_AUTH_NEEDED, ERR_TLS_NEEDED, ERR_HELO_NEEDED, ERR_MAIL_NEEDED, ERR_RCPT_NEEDED, ERR_NO_VALID_RCPTS, ERR_RETRY }; // // Protocl Events // #include "cpropbag.h" #include "pe_out.hxx" #include #include "pe_supp.hxx" #include "pe_disp.h" // // Forwards for inbound extension related objects // interface IEventRouter; interface ISmtpOutboundCommandDispatcher; class CInboundContext; #define MAX_SSL_FRAGMENT_SIZE (32 * 1024) //We would like this to be LTE 32K but large enough to accomodate the //complete average mail file #define SMTP_WRITE_BLOCK_SIZE (4000) //See NT:415893 //Previously this value was 512 bytes, which would allow a buffer overrun to //happen against us after the DATA command. This value should be calculated //from the max accepted values used. #define REWRITTEN_GEN_MSGID_BUFFER 20 #define MAX_REWRITTEN_MSGID \ (REWRITTEN_GEN_MSGID_BUFFER+1) + \ sizeof("Message-ID: <123456789@>\r\n") + \ (MAX_INTERNET_NAME+1) //Worst case this will rewrite the following // - "FROM: " + mail from // - "RETURN-PATH: " + return path // - "BCC: " // - "MESSAGE-ID: " generated id + FQDN // - "X-OriginalArrivalTime: " + 64 byte buffer // - "Date: " + cMaxArpaData buffer // - CRLF CRLF #define MAX_REWRITTEN_HEADERS \ ((MAX_INTERNET_NAME+1) * 3 ) + \ sizeof("From: \r\n") + \ sizeof("Return-Path: \r\n") + \ sizeof("Bcc: \r\n") + \ sizeof("Message-ID: \r\n") + MAX_REWRITTEN_MSGID + \ sizeof("X-OriginalArrivalTime: \r\n") + 64 + \ sizeof("Date: \r\n") + cMaxArpaDate +\ sizeof("\r\n\r\n") #define MAX_NATIVE_RESPONSE_SIZE 1024 //This is the largest allowed size for an AUTH NTLM uuencoded //response string. Largest response size = 0x770 ~ 1600. uuencode //inflates size by 1.5 so about 2500 is the largest allowable size. #define MAX_REPLY_SIZE 4000 // // Redefine the type to indicate that this is a call-back function // typedef ATQ_COMPLETION PFN_ATQ_COMPLETION; enum ReverseDnsLookupCodes{ SUCCESS, LOOKUP_FAILED, NO_MATCH }; /************************************************************ * Type Definitions ************************************************************/ typedef struct _SMTPCLI_FILE_OVERLAPPED { SERVEREVENT_OVERLAPPED SeoOverlapped; LASTIOSTATE m_LastIoState; DWORD m_cbIoSize; LPBYTE m_pIoBuffer; } SMTPCLI_FILE_OVERLAPPED; typedef struct _TURN_DOMAIN_LIST { MULTISZ* pmsz; const char * szCurrentDomain; }TURN_DOMAIN_LIST, *PTURN_DOMAIN_LIST; /*++ class SMTP_CONNECTION This class is used for keeping track of individual client connections established with the server. It maintains the state of the connection being processed. --*/ class SMTP_CONNECTION : public CLIENT_CONNECTION { public: ~SMTP_CONNECTION (void); static CPool Pool; // override the mem functions to use CPool functions void *operator new (size_t cSize) { return Pool.Alloc(); } void operator delete (void *pInstance) { Pool.Free(pInstance); } int SmtpGetCommand(const char * Request, DWORD RequestLen, LPDWORD CmdSize); BOOL SmtpParseCompleteCommand(const CHAR *InputLine, CHAR *pszSearch, ULONG IntermediateSize, DWORD *pdwCmdSize); void HandleFullRecvBuffer(); BOOL SendSmtpResponse(BOOL SyncSend = TRUE); virtual BOOL ProcessClient( IN DWORD cbWritten, IN DWORD dwCompletionStatus, IN OUT OVERLAPPED * lpo); virtual BOOL StartSession( VOID); BOOL DoEHLOCommand(const char * InputLine, DWORD parameterSize); BOOL DoHELOCommand(const char * InputLine, DWORD parameterSize); BOOL DoRSETCommand(const char * InputLine, DWORD parameterSize); BOOL DoNOOPCommand(const char * InputLine, DWORD parameterSize); BOOL DoQUITCommand(const char * InputLine, DWORD parameterSize); BOOL DoHELPCommand(const char * InputLine, DWORD parameterSize); BOOL DoMAILCommand(const char * InputLine, DWORD parameterSize); BOOL DoRCPTCommand(const char * InputLine, DWORD parameterSize); BOOL DoDATACommand(const char * InputLine, DWORD parameterSize); BOOL DoVRFYCommand(const char * InputLine, DWORD parameterSize); BOOL DoAUTHCommand(const char * InputLine, DWORD parameterSize); BOOL DoLASTCommand(const char * InputLine, DWORD parameterSize); BOOL DoETRNCommand(const char * InputLine, DWORD parameterSize); BOOL DoTURNCommand(const char * InputLine, DWORD parameterSize); BOOL DoSTARTTLSCommand(const char * InputLine, DWORD parameterSize); BOOL DoTLSCommand(const char * InputLine, DWORD parameterSize); BOOL DoBDATCommand(const char * InputLine, DWORD parameterSize); BOOL ProcessReadIO( IN DWORD InputBufferLen, IN DWORD dwCompletionStatus, IN OUT OVERLAPPED * lpo); BOOL ProcessFileWrite(IN DWORD BytesWritten, IN DWORD dwCompletionStatus, IN OUT OVERLAPPED *lpo); BOOL ProcessDATAMailBody(const char *InputLine, DWORD UndecryptedTailSize, BOOL *pfAsyncOp); BOOL ProcessBDATMailBody(const char *InputLine, DWORD UndecryptedTailSize, BOOL *pfAsyncOp); BOOL DoDATACommandEx(const char * InputLine, DWORD parameterSize, DWORD UndecryptedTailSize,BOOL *lpfWritePended, BOOL *pfAsyncOp); BOOL DoBDATCommandEx(const char * InputLine, DWORD parameterSize, DWORD UndecryptedTailSize, BOOL *lpfWritePended, BOOL *pfAsyncOp); BOOL Do_EODCommand(const char * InputLine, DWORD parameterSize); BOOL FormatSmtpMessage(DWORD dwCode, const char * szEnhancedCodes, IN const char * Format, ...); BOOL FormatSmtpMessage(unsigned char *Buffer, DWORD dwBytes); void FormatEhloResponse(void); // inbound protocol extension related member functions HRESULT OnEvent( IUnknown * pIserver, IUnknown * pISession, IMailMsgProperties *pIMessage, LPPE_COMMAND_NODE pCommandNode, LPPE_BINDING_NODE pBindingNode, char * szArgs ); HRESULT OnNotifyAsyncCompletion( HRESULT hrResult ); BOOL ProcessAndSendResponse(); BOOL GlueDispatch(char * InputLine, DWORD IntermediateSize, DWORD CmdSize, BOOL * pfAsyncOp); BOOL ProcessPeBlob(const char * pbInputLine, DWORD cbSize); BOOL PE_CdFormatSmtpMessage(DWORD dwCode, const char * szEnhancedCodes,IN const char * Format, ...); BOOL PE_FormatSmtpMessage(IN const char * Format, ...); BOOL PE_FastFormatSmtpMessage(LPSTR pszBuffer, DWORD dwBytes); BOOL PE_DisconnectClient(); BOOL PE_SendSmtpResponse(); IUnknown *GetSessionPropertyBag() { return((IUnknown *)(IMailMsgPropertyBag *)(&m_SessionPropertyBag)); } char * CheckArgument(IN OUT char * Argument, BOOL WriteError = TRUE); static SMTP_CONNECTION * CreateSmtpConnection (IN PCLIENT_CONN_PARAMS ClientParam, PSMTP_SERVER_INSTANCE pInst); SOCKET QueryClientSocket(void) { return QuerySocket(); } LPCSTR QueryClientUserName() { if(m_szHeloAddr[0] != '\0') return m_szHeloAddr; else return ""; } void StartSessionTimer() { m_msSession = GetTickCount(); } DWORD QuerySessionTime() { return GetTickCount() - m_msSession; } ADDRESS_CHECK* QueryAccessCheck() { return &m_acAccessCheck; } BOOL BindInstanceAccessCheck(); VOID UnbindInstanceAccessCheck(); PSMTP_SERVER_INSTANCE QuerySmtpInstance( VOID ) const { _ASSERT(m_pInstance != NULL); return m_pInstance; } BOOL IsSmtpInstance( VOID ) const { return m_pInstance != NULL; } VOID SetSmtpInstance( IN PSMTP_SERVER_INSTANCE pInstance ) { _ASSERT(m_pInstance == NULL); m_pInstance = pInstance; } SMTP_SERVER_STATISTICS * QuerySmtpStatsObj( VOID ) const { return m_pSmtpStats; } VOID SetSmtpStatsObj( IN LPSMTP_SERVER_STATISTICS pSmtpStats ) { m_pSmtpStats = pSmtpStats; } // // These are overridden from the base CLIENT_CONNECTION class to support // switching of receive buffers. We need to be able to switch buffers to // support SSL, which needs upto 32K chunks. Note that even though SSL // V3.0 restricts fragment sizes to 16K, our schannel is capable of // generating 32K fragments (due to a bug). So, we read up to 32K. // virtual LPCSTR QueryRcvBuffer( VOID) const { return ((LPCSTR) m_precvBuffer); } virtual LPSTR QueryMRcvBuffer(VOID) // modifiable string { return (LPSTR) m_precvBuffer; } // // This method causes this object to allocate 32K buffers and use them as // the receive and output buffer. // BOOL SwitchToBigSSLBuffers(); DWORD QueryMaxReadSize() const { return m_cbMaxRecvBuffer; } void RequireAuth() { m_fAuthAnon = FALSE; HrSetISessionProperty(ISESSION_PID_ANONYMOUS_AUTH, FALSE); } private : //In case of chunking we write to the disk async DWORD m_AtqLocator; SMTPCLI_FILE_OVERLAPPED m_FileOverLapped; SMTPSTATE m_State; LASTIOSTATE m_LastClientIo; BOOL m_HelloSent; BOOL m_RecvdMailCmd; BOOL m_RecvdRcptCmd; BOOL m_RecvdAuthCmd; BOOL m_EmptyMail; BOOL m_Nooped; BOOL m_InHeader; BOOL m_LongBodyLine; BOOL m_fFoundEmbeddedCrlfDotCrlf; BOOL m_fScannedForCrlfDotCrlf; BOOL m_fSeenRFC822FromAddress; BOOL m_fSeenRFC822ToAddress; BOOL m_fSeenRFC822CcAddress; BOOL m_fSeenRFC822BccAddress; BOOL m_fSeenRFC822Subject; BOOL m_fSeenRFC822MsgId; BOOL m_fSeenRFC822SenderAddress; BOOL m_fSeenXPriority; BOOL m_fSeenXOriginalArrivalTime; BOOL m_fSeenContentType; BOOL m_fSetContentType; BOOL m_NeedToQuit; BOOL m_TimeToRewriteHeader; BOOL m_WritingData; BOOL m_SecurePort; BOOL m_fNegotiatingSSL; DWORD m_DNSLookupRetCode; BOOL m_fUseMbsCta; BOOL m_fAuthenticated; BOOL m_fMayRelay; BOOL m_fClearText; BOOL m_fDidUserCmd; BOOL m_fAuthAnon; char *m_precvBuffer; DWORD m_cbMaxRecvBuffer; char m_OutputBuffer[SMTP_MAX_REPLY_LEN]; BOOL m_fRecvBufferFull; char *m_pOutputBuffer; DWORD m_cbMaxOutputBuffer; CBuffer * m_pFileWriteBuffer; DWORD m_cbCurrentWriteBuffer; DWORD m_cbRecvBufferOffset; DWORD m_cbTempBDATLen; DWORD m_OutputBufferSize; DWORD m_cbParsable; DWORD m_ProtocolErrors; DWORD m_dwUnsuccessfulLogons; DWORD m_TotalMsgSize; DWORD m_SessionSize; DWORD m_cbDotStrippedTotalMsgSize; DWORD m_HeaderSize; DWORD m_HeaderFlags; DWORD m_MailBodyError; MailBodyDiagnosticCode m_MailBodyDiagnostic; DWORD m_dwCurrentCommand; DWORD m_HopCount; DWORD m_LocalHopCount; LONG m_cPendingIoCount; LONG m_cActiveThreads; char CommandErrorType; char *m_pszArgs; IMailMsgProperties *m_pIMsg; IMailMsgRecipients *m_pIMsgRecipsTemp; IMailMsgRecipientsAdd *m_pIMsgRecips; IMailMsgBind *m_pBindInterface; PFIO_CONTEXT m_IMsgHandle; char m_szHeloAddr[MAX_INTERNET_NAME + 1]; char m_szFromAddress[MAX_INTERNET_NAME + 1]; LIST_ENTRY m_HeaderList; DWORD m_msSession; DWORD m_CurrentOffset; CEncryptCtx m_encryptCtx; CSecurityCtx m_securityCtx; AC_RESULT m_acCheck; ADDRESS_CHECK m_acAccessCheck; METADATA_REF_HANDLER m_rfAccessCheck; // used authentication mechanism CHAR m_szUsedAuthKeyword[25]; CHAR m_szAuthenticatedUserNameFromSink[MAX_INTERNET_NAME + 1]; // configured authentication packages (pointer to refcounted object) CProviderPackagesInfo *m_pProviderPackagesInfo; //Chunking related flags BOOL m_fIsLastChunk; BOOL m_fIsBinaryMime; BOOL m_fIsChunkComplete; DWORD m_dwTrailerStatus; int m_nChunkSize; int m_nBytesRemainingInChunk; BOOL m_fBufferFullInBDAT; // inbound protocol extension related data members public: CInboundContext m_CInboundContext; BOOL m_fAsyncEventCompletion; BOOL m_fAsyncEOD; private: BOOL m_fIsPeUnderway; IEventRouter *m_pIEventRouter; ISmtpInboundCommandDispatcher *m_pCInboundDispatcher; CMailMsgPropertyBag m_SessionPropertyBag; PSMTP_SERVER_INSTANCE m_pInstance; LPSMTP_SERVER_STATISTICS m_pSmtpStats; PATQ_CONTEXT m_AtqSeoContext; BOOL m_fPeBlobReady; ISmtpInCallbackSink * m_pPeBlobCallback; DWORD m_LineCompletionState; //stores state of IsLineCompleteRFC822 automaton BOOL m_Truncate; //TRUE when in truncation mode; gpulla BOOL m_BufrWasFull; //TRUE when the last call to IsLineCompleteRFC822 yielded a full buffer. SMTP_CONNECTION( IN PSMTP_SERVER_INSTANCE pInstance, IN SOCKET sClient, IN const SOCKADDR_IN * psockAddrRemote, IN const SOCKADDR_IN * psockAddrLocal = NULL, IN PATQ_CONTEXT pAtqContext = NULL, IN PVOID pvInitialRequest = NULL, IN DWORD cbInitialData = 0); BOOL InitializeObject (BOOL IsSecureConnection); DWORD VerifiyClient (IN const char * ClientHostName, IN const char * KnownIpAddress); BOOL ExtractAndValidateRcpt(char * ToName, char ** ppArgument, char * szRcptAddress, char ** ppDomain ); HRESULT HrShouldAcceptRcpt(char * szDomainName ); BOOL IsClientSecureEnough(); BOOL HandleCompletedMessage(DWORD dwCommand, BOOL *pfAsyncOp); BOOL CreateMailBody (char * InputLine, DWORD ParameterSize, DWORD UndecryptedTailSize, BOOL *lpfWritePended); BOOL CreateMailBodyFromChunk (char * InputLine, DWORD ParameterSize, DWORD UndecryptedTailSize,BOOL *lpfWritePended); BOOL WriteRcvHeader(void); BOOL BindToStoreDrive(void); void HandleAddressError(char * InputLine); BOOL RewriteHeader(BOOL *lpfWritePended); void ReInitClassVariables(void); LONG IncPendingIoCount(void) { return InterlockedIncrement( &m_cPendingIoCount );} LONG DecPendingIoCount(void) { return InterlockedDecrement( &m_cPendingIoCount ); } LONG IncThreadCount(void) { return InterlockedIncrement( &m_cActiveThreads ); } LONG DecThreadCount(void) { return InterlockedDecrement( &m_cActiveThreads ); } //skips over WordSkip in Buffer char * SkipWord (char * Buffer, char * WordToSkip, DWORD WordLen); BOOL AddToField(void); BOOL WriteLine(char * Text, DWORD TexSize); VOID ProtocolLog( DWORD dwCommand = USE_CURRENT, LPCSTR pszParameters = "", DWORD dwWin32Error = NO_ERROR, DWORD dwSmtpError = NO_ERROR, DWORD BytesSent = 0, DWORD BytesRecv = 0, LPSTR pszTarget = ""); void TransactionLog( const char *pszOperation, const char *pszParameters, const char *pszTarget, DWORD dwWin32Error, DWORD dwServiceSpecificStatus ); BOOL DecryptInputBuffer(); BOOL ProcessInputBuffer(void); BOOL DoSmtpArgs (char *InputLine); BOOL DoRcptArgs (char *InputLine, char * szORCPTval, DWORD * pdwNotifyVal); BOOL DoSizeCommand(char * Value, char * InputLine); BOOL DoBodyCommand (char * Value, char * InputLine); BOOL DoRetCommand (char * Value, char * InputLine); BOOL DoEnvidCommand (char * Value, char * InputLine); BOOL DoNotifyCommand (char * Value, DWORD * pdwNotifyValue); BOOL DoOrcptCommand (char * Value); BOOL DoMailFromAuthArg (char * Value); BOOL IsXtext(char * Xtext); BOOL ProcessAuthInfo(AUTH_COMMAND, LPSTR Blob, unsigned char * OutptBuffer, DWORD * dwBytes); BOOL DoAuthNegotiation(const char *InputLine, DWORD dwLineSize); BOOL PendReadIO(DWORD UndecryptedTailSize); BOOL DoUSERCommand(const CHAR *InputLine, DWORD dwLineSize, unsigned char *OutputBuff, DWORD * dwBytes,DWORD * dwResponse, char * szECode); BOOL DoPASSCommand(const CHAR *InputLine, DWORD dwLineSize, unsigned char *OutputBuff, DWORD * dwBytes,DWORD * dwResponse, char * szECode); BOOL UseMbsCta() { return m_fUseMbsCta; } BOOL DoesClientHaveIpAccess(); //Partially async WriteFile BOOL WriteMailFile (char * Buffer, DWORD BuffSize, BOOL *lpfWritePended); //Fully async WriteFile BOOL WriteMailFileAtq(char * Buffer, DWORD dwBytesToWrite,DWORD dwIoMode); // void FreeAtqFileContext( void ); void ReleasImsg(BOOL DeleteIMsg); void ReleasRcptList(void); void GetAndPersistRFC822Headers( char* InputLine, char* pszValueBuf ); HRESULT SetAvailableMailMsgProperties(); char *IsLineCompleteRFC822( IN char *InputLine, IN DWORD nBytes, IN DWORD UndecryptedTailSize, OUT BOOL *p_FullBuffer ); //gpulla BOOL HandleInternalError(DWORD err); HRESULT HrGetISessionProperties(); // // Add corresponding HrSetISessionProperty overloads for DWORD, // LPSTR etc, as needed under this. // HRESULT HrSetISessionProperty(DWORD dwPropId, BOOL fValue); VOID CopyIPAddressesToSession(); BOOL AcceptAndDiscardBDAT(const char *InputLine, DWORD UndecryptedTailSize, BOOL *pfAsyncOp); BOOL AcceptAndDiscardDATA(const char *InputLine, DWORD UndecryptedTailSize, BOOL *pfAsyncOp); BOOL MailBodyErrorProcessing(); }; typedef BOOL (SMTP_CONNECTION::*PMFI)(const char * InputLine, DWORD InputLinseSize); static PMFI SmtpDispatchTable[] = { #undef SmtpDef #define SmtpDef(Smtp) &SMTP_CONNECTION::Do##Smtp##Command, #include "smtpdef.h" // modified by andreik // &SMTP_CONNECTION::DoLASTCommand, NULL }; //SMTPSTATE operator++(SMTPSTATE &state) //{return state = SMTPSTATE (state + 1);} # endif /************************ End of File ***********************/