Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

667 lines
27 KiB

/*++
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 <CRLF>.<CRLF>";
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 * 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 <smtpevent.h>
#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 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; }
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_fClearText;
BOOL m_fDidUserCmd;
BOOL m_fAuthAnon;
char *m_precvBuffer;
DWORD m_cbMaxRecvBuffer;
char m_OutputBuffer[SMTP_MAX_REPLY_LEN];
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_szUsedAuthMechanism[MAX_PATH + 1];
CHAR m_szUsedAuthKeyword[MAX_PATH + 1];
char m_szUserName[MAX_INTERNET_NAME + 1];
CHAR m_szAuthenticatedUserNameFromSink[MAX_INTERNET_NAME + 1];
//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 );
BOOL ShouldAcceptRcpt(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(void);
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 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();
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 ***********************/