Leaked source code of windows server 2003
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.

691 lines
29 KiB

  1. /*++
  2. Copyright (c) 1994 Microsoft Corporation
  3. Module Name :
  4. smtpcli.hxx
  5. Abstract:
  6. This module defines the SMTP_CONNECTION class.
  7. This object maintains information about a new client connection
  8. Author:
  9. Rohan Phillips ( Rohanp ) 11-Dec-1995
  10. Project:
  11. SMTP Server DLL
  12. Revision History:
  13. --*/
  14. #ifndef _SMTP_CLIENT_HXX_
  15. #define _SMTP_CLIENT_HXX_
  16. /************************************************************
  17. * Include Headers
  18. ************************************************************/
  19. #include "conn.hxx"
  20. #include "simssl2.h"
  21. #include "addr821.hxx"
  22. /************************************************************
  23. * Symbolic Constants
  24. ************************************************************/
  25. static const char * SmtpCommands [] = {
  26. #undef SmtpDef
  27. #define SmtpDef(a) #a,
  28. #include "smtpdef.h"
  29. NULL
  30. };
  31. enum SMTPSTATE
  32. {
  33. #undef SmtpDef
  34. #define SmtpDef(a) a,
  35. #include "smtpdef.h"
  36. LAST_SMTP_STATE
  37. };
  38. enum LASTIOSTATE
  39. {
  40. READIO, WRITEIO, TRANSFILEIO, MAIL_QUEUEIO, REMOTE_MAIL_QUEUEIO, WRITEFILEIO
  41. };
  42. const DWORD MIN_SMTP_COMMAND_SIZE = 4; //4 chars
  43. const DWORD SMTP_RESP_STATUS = 211;
  44. const DWORD SMTP_RESP_HELP = 214;
  45. const DWORD SMTP_RESP_READY = 220;
  46. const DWORD SMTP_RESP_CLOSE = 221;
  47. const DWORD SMTP_RESP_AUTHENTICATED = 235;
  48. const DWORD SMTP_RESP_OK = 250;
  49. const DWORD SMTP_RESP_WILL_FWRD = 251;
  50. const DWORD SMTP_RESP_ETRN_ZERO_MSGS = 251;
  51. const DWORD SMTP_RESP_VRFY_CODE = 252;
  52. const DWORD SMTP_RESP_ETRN_N_MSGS = 253;
  53. const DWORD SMTP_RESP_AUTH1_PASSED = 334;
  54. const DWORD SMTP_RESP_START = 354;
  55. const DWORD SMTP_RESP_SRV_UNAVAIL = 421;
  56. const DWORD SMTP_RESP_MBX_UNAVAIL = 450;
  57. const DWORD SMTP_RESP_REJECT_MAILFROM = 450;
  58. const DWORD SMTP_RESP_ERROR = 451;
  59. const DWORD SMTP_RESP_NORESOURCES = 452;
  60. const DWORD SMTP_RESP_NODE_INVALID = 459;
  61. const DWORD SMTP_RESP_BAD_CMD = 500;
  62. const DWORD SMTP_RESP_BAD_ARGS = 501;
  63. const DWORD SMTP_RESP_NOT_IMPL = 502;
  64. const DWORD SMTP_RESP_BAD_SEQ = 503;
  65. const DWORD SMTP_RESP_PARM_NOT_IMP = 504;
  66. const DWORD SMTP_RESP_MUST_SECURE = 530;
  67. const DWORD SMTP_RESP_AUTH_REJECT = 535;
  68. const DWORD SMTP_RESP_NOT_FOUND = 550;
  69. const DWORD SMTP_RESP_PLS_FWRD = 551;
  70. const DWORD SMTP_RESP_NOSTORAGE = 552;
  71. const DWORD SMTP_RESP_MBX_SYNTAX = 553;
  72. const DWORD SMTP_RESP_TRANS_FAILED = 554;
  73. //State of FSA in IsLineCompleteRFC822
  74. const DWORD SEEN_NOTHING = 1;
  75. const DWORD SEEN_CR = 2;
  76. const DWORD SEEN_CRLF = 3;
  77. /* strings to be appended to numeric reply codes */
  78. static const char * SMTP_READY_STR = "SMTP server ready";
  79. static const char * SMTP_BAD_CMD_STR = "Unrecognized command";
  80. static const char * SMTP_BAD_BODY_TYPE_STR = "Unsupported BODY type";
  81. static const char * SMTP_MAIL_OK_STR = "Sender OK";
  82. static const char * SMTP_QUIT_OK_STR = "Service closing transmission channel";
  83. static const char * SMTP_BAD_SEQ_STR = "Bad sequence of commands";
  84. static const char * SMTP_NOT_IMPL_STR = "Command not implemented";
  85. static const char * SMTP_HELO_OK_STR = "Hi there, pleased to meet you";
  86. static const char * SMTP_RECIP_OK_STR = "Recipient OK";
  87. static const char * SMTP_BAD_RECIP_STR = "Addressee unknown";
  88. static const char * SMTP_START_MAIL_STR = "Start mail input; end with <CRLF>.<CRLF>";
  89. static const char * SMTP_RSET_OK_STR = "Resetting";
  90. static const char * SMTP_LOCAL_DEL_STR = "Error in local delivery";
  91. static const char * SMTP_SRV_UNAVAIL_STR = "Service not available or retries exceeded, closing channel";
  92. static const char * SMTP_NO_STORAGE = "Insufficient system storage";
  93. static const char * SMTP_NO_VALID_RECIPS = "No valid recipients";
  94. static const char * SMTP_QUEUE_MAIL = "Queued mail for delivery";
  95. static const char * SMTP_NO_MEMORY = "Out of memory";
  96. static const char * SMTP_EMPTY_MAIL = "Empty mail message";
  97. static const char * SMTP_TIMEOUT_MSG = "Timeout waiting for client input";
  98. static const char * SMTP_TOO_MANY_ERR_MSG = "Too many errors on this connection---closing";
  99. static const char * SMTP_NO_DOMAIN_NAME_MSG = "Domain Name required";
  100. static const char * SMTP_NEED_MAIL_FROM_MSG = "Need Mail From: first";
  101. static const char * SMTP_MAX_MSG_SIZE_EXCEEDED_MSG = "Message size exceeds fixed maximum message size";
  102. static const char * SMTP_MAX_SESSION_SIZE_EXCEEDED_MSG = "Session size exceeds fixed maximum session size";
  103. static const char * SMTP_INVALID_ADDR_MSG = "Invalid Address";
  104. static const char * SMTP_SRV_UNAVAIL_MSG = "Service not available, closing transmission channel";
  105. static const char * SMTP_NO_ETRN_IN_MSG = "ETRN may not be issued while mail transaction is occurring";
  106. static const char * SMTP_ONLY_ONE_TLS_MSG = "Only one STARTTLS command can be issued per session";
  107. static const char * SMTP_TLS_NOT_SUPPORTED = "Not supported at this server";
  108. static const char * SMTP_NO_CERT_MSG = "Unable to initialize security subsystem";
  109. static const char * SMTP_MSG_MUST_SECURE = "Must issue a STARTTLS command first";
  110. static const char * SMTP_MSG_NOT_SECURE_ENOUGH = "Command refused due to lack of security";
  111. static const char * SMTP_BDAT_EXPECTED = "BDAT command expected";
  112. static const char * SMTP_BDAT_CHUNK_OK_STR = "CHUNK received OK";
  113. static const char * SMTP_RDNS_REJECTION = "Rejected : Domain does not match IP address";
  114. static const char * SMTP_RDNS_FAILURE = "Unable to verify the connecting host domain";
  115. static const char * SMTP_REMOTE_HOST_REJECTED_FOR_SIZE = "Msg Size greater than allowed by Remote Host";
  116. static const char * SMTP_REMOTE_HOST_REJECTED_FOR_TYPE = "Body type not supported by Remote Host";
  117. static const char * SMTP_REMOTE_HOST_DROPPED_CONNECTION = "Connection dropped by Remote Host";
  118. static const char * SMTP_REMOTE_HOST_REJECTED_AUTH = "Failed to authenticate with Remote Host";
  119. static const char * SMTP_REMOTE_HOST_REJECTED_SSL = "Failed to negotiate secure channel with Remote Host";
  120. //Enhanced status codes
  121. static const char * EPROT_SUCCESS = "2.0.0";
  122. static const char * E_GOODBYE = "2.0.0";
  123. static const char * ESENDER_ADDRESS_VALID = "2.1.0";
  124. static const char * EVALID_DEST_ADDRESS = "2.1.5";
  125. static const char * EMESSAGE_GOOD = "2.6.0";
  126. static const char * ESEC_SUCCESS = "2.7.0";
  127. static const char * EINTERNAL_ERROR = "4.0.0";
  128. static const char * ENO_RESOURCES = "4.3.1";
  129. static const char * ESVC_SHUTDOWN = "4.3.2";
  130. static const char * ENO_SECURITY_TMP = "4.7.3";
  131. static const char * EMAILBOX_FULL = "4.2.2";
  132. static const char * EBAD_SENDER = "5.1.7";
  133. static const char * ENOT_IMPLEMENTED = "5.3.3";
  134. static const char * EMESSAGE_TOO_BIG = "5.3.4";
  135. static const char * EINVALID_COMMAND = "5.5.1";
  136. static const char * ESYNTAX_ERROR = "5.5.2";
  137. static const char * ETOO_MANY_RCPTS = "5.5.3";
  138. static const char * EINVALID_ARGS = "5.5.4";
  139. static const char * ENO_FORWARDING = "5.7.1";
  140. static const char * ENO_SECURITY = "5.7.3";
  141. static const char * E_TLSNEEDED = "5.7.0";
  142. static const char * ENO_SEC_PACKAGE = "5.7.4";
  143. const DWORD MIN_BUFFLENGTH = 10;
  144. const DWORD SMTP_MAX_ERRORS = 10;
  145. const DWORD SMTP_MAX_USER_NAME_LEN = 64;
  146. const DWORD SMTP_MAX_DOMAIN_NAME_LEN = 256;
  147. const DWORD SMTP_MAX_PATH_LEN = 64;
  148. const DWORD SMTP_MAX_COMMANDLINE_LEN = 512;
  149. const DWORD SMTP_MAX_REPLY_LEN = 1024;
  150. const DWORD SMTP_MAX_MSG_SIZE = 42 * 1024;
  151. const char SMTP_COMMAND_NOERROR = (char) 0;
  152. const char SMTP_COMMAND_TOO_SHORT = (char) 1;
  153. const char SMTP_COMMAND_TOO_LONG = (char) 2;
  154. const char SMTP_COMMAND_NOT_FOUND = (char) 3;
  155. enum MailBodyDiagnosticCode {
  156. ERR_NONE = 0,
  157. ERR_OUT_OF_MEMORY,
  158. ERR_MAX_MSG_SIZE,
  159. ERR_AUTH_NEEDED,
  160. ERR_TLS_NEEDED,
  161. ERR_HELO_NEEDED,
  162. ERR_MAIL_NEEDED,
  163. ERR_RCPT_NEEDED,
  164. ERR_NO_VALID_RCPTS,
  165. ERR_RETRY
  166. };
  167. //
  168. // Protocl Events
  169. //
  170. #include "cpropbag.h"
  171. #include "pe_out.hxx"
  172. #include <smtpevent.h>
  173. #include "pe_supp.hxx"
  174. #include "pe_disp.h"
  175. //
  176. // Forwards for inbound extension related objects
  177. //
  178. interface IEventRouter;
  179. interface ISmtpOutboundCommandDispatcher;
  180. class CInboundContext;
  181. #define MAX_SSL_FRAGMENT_SIZE (32 * 1024)
  182. //We would like this to be LTE 32K but large enough to accomodate the
  183. //complete average mail file
  184. #define SMTP_WRITE_BLOCK_SIZE (4000)
  185. //See NT:415893
  186. //Previously this value was 512 bytes, which would allow a buffer overrun to
  187. //happen against us after the DATA command. This value should be calculated
  188. //from the max accepted values used.
  189. #define REWRITTEN_GEN_MSGID_BUFFER 20
  190. #define MAX_REWRITTEN_MSGID \
  191. (REWRITTEN_GEN_MSGID_BUFFER+1) + \
  192. sizeof("Message-ID: <123456789@>\r\n") + \
  193. (MAX_INTERNET_NAME+1)
  194. //Worst case this will rewrite the following
  195. // - "FROM: " + mail from
  196. // - "RETURN-PATH: " + return path
  197. // - "BCC: "
  198. // - "MESSAGE-ID: " generated id + FQDN
  199. // - "X-OriginalArrivalTime: " + 64 byte buffer
  200. // - "Date: " + cMaxArpaData buffer
  201. // - CRLF CRLF
  202. #define MAX_REWRITTEN_HEADERS \
  203. ((MAX_INTERNET_NAME+1) * 3 ) + \
  204. sizeof("From: \r\n") + \
  205. sizeof("Return-Path: \r\n") + \
  206. sizeof("Bcc: \r\n") + \
  207. sizeof("Message-ID: \r\n") + MAX_REWRITTEN_MSGID + \
  208. sizeof("X-OriginalArrivalTime: \r\n") + 64 + \
  209. sizeof("Date: \r\n") + cMaxArpaDate +\
  210. sizeof("\r\n\r\n")
  211. #define MAX_NATIVE_RESPONSE_SIZE 1024
  212. //This is the largest allowed size for an AUTH NTLM uuencoded
  213. //response string. Largest response size = 0x770 ~ 1600. uuencode
  214. //inflates size by 1.5 so about 2500 is the largest allowable size.
  215. #define MAX_REPLY_SIZE 4000
  216. //
  217. // Redefine the type to indicate that this is a call-back function
  218. //
  219. typedef ATQ_COMPLETION PFN_ATQ_COMPLETION;
  220. enum ReverseDnsLookupCodes{
  221. SUCCESS,
  222. LOOKUP_FAILED,
  223. NO_MATCH
  224. };
  225. /************************************************************
  226. * Type Definitions
  227. ************************************************************/
  228. typedef struct _SMTPCLI_FILE_OVERLAPPED
  229. {
  230. SERVEREVENT_OVERLAPPED SeoOverlapped;
  231. LASTIOSTATE m_LastIoState;
  232. DWORD m_cbIoSize;
  233. LPBYTE m_pIoBuffer;
  234. } SMTPCLI_FILE_OVERLAPPED;
  235. typedef struct _TURN_DOMAIN_LIST
  236. {
  237. MULTISZ* pmsz;
  238. const char * szCurrentDomain;
  239. }TURN_DOMAIN_LIST, *PTURN_DOMAIN_LIST;
  240. /*++
  241. class SMTP_CONNECTION
  242. This class is used for keeping track of individual client
  243. connections established with the server.
  244. It maintains the state of the connection being processed.
  245. --*/
  246. class SMTP_CONNECTION : public CLIENT_CONNECTION
  247. {
  248. public:
  249. ~SMTP_CONNECTION (void);
  250. static CPool Pool;
  251. // override the mem functions to use CPool functions
  252. void *operator new (size_t cSize)
  253. { return Pool.Alloc(); }
  254. void operator delete (void *pInstance)
  255. { Pool.Free(pInstance); }
  256. int SmtpGetCommand(const char * Request, DWORD RequestLen, LPDWORD CmdSize);
  257. BOOL SmtpParseCompleteCommand(const CHAR *InputLine, CHAR *pszSearch,
  258. ULONG IntermediateSize, DWORD *pdwCmdSize);
  259. void HandleFullRecvBuffer();
  260. BOOL SendSmtpResponse(BOOL SyncSend = TRUE);
  261. virtual BOOL ProcessClient( IN DWORD cbWritten,
  262. IN DWORD dwCompletionStatus,
  263. IN OUT OVERLAPPED * lpo);
  264. virtual BOOL StartSession( VOID);
  265. BOOL DoEHLOCommand(const char * InputLine, DWORD parameterSize);
  266. BOOL DoHELOCommand(const char * InputLine, DWORD parameterSize);
  267. BOOL DoRSETCommand(const char * InputLine, DWORD parameterSize);
  268. BOOL DoNOOPCommand(const char * InputLine, DWORD parameterSize);
  269. BOOL DoQUITCommand(const char * InputLine, DWORD parameterSize);
  270. BOOL DoHELPCommand(const char * InputLine, DWORD parameterSize);
  271. BOOL DoMAILCommand(const char * InputLine, DWORD parameterSize);
  272. BOOL DoRCPTCommand(const char * InputLine, DWORD parameterSize);
  273. BOOL DoDATACommand(const char * InputLine, DWORD parameterSize);
  274. BOOL DoVRFYCommand(const char * InputLine, DWORD parameterSize);
  275. BOOL DoAUTHCommand(const char * InputLine, DWORD parameterSize);
  276. BOOL DoLASTCommand(const char * InputLine, DWORD parameterSize);
  277. BOOL DoETRNCommand(const char * InputLine, DWORD parameterSize);
  278. BOOL DoTURNCommand(const char * InputLine, DWORD parameterSize);
  279. BOOL DoSTARTTLSCommand(const char * InputLine, DWORD parameterSize);
  280. BOOL DoTLSCommand(const char * InputLine, DWORD parameterSize);
  281. BOOL DoBDATCommand(const char * InputLine, DWORD parameterSize);
  282. BOOL ProcessReadIO( IN DWORD InputBufferLen,
  283. IN DWORD dwCompletionStatus,
  284. IN OUT OVERLAPPED * lpo);
  285. BOOL ProcessFileWrite(IN DWORD BytesWritten,
  286. IN DWORD dwCompletionStatus,
  287. IN OUT OVERLAPPED *lpo);
  288. BOOL ProcessDATAMailBody(const char *InputLine, DWORD UndecryptedTailSize, BOOL *pfAsyncOp);
  289. BOOL ProcessBDATMailBody(const char *InputLine, DWORD UndecryptedTailSize, BOOL *pfAsyncOp);
  290. BOOL DoDATACommandEx(const char * InputLine, DWORD parameterSize, DWORD UndecryptedTailSize,BOOL *lpfWritePended, BOOL *pfAsyncOp);
  291. BOOL DoBDATCommandEx(const char * InputLine, DWORD parameterSize, DWORD UndecryptedTailSize, BOOL *lpfWritePended, BOOL *pfAsyncOp);
  292. BOOL Do_EODCommand(const char * InputLine, DWORD parameterSize);
  293. BOOL FormatSmtpMessage(DWORD dwCode, const char * szEnhancedCodes, IN const char * Format, ...);
  294. BOOL FormatSmtpMessage(unsigned char *Buffer, DWORD dwBytes);
  295. void FormatEhloResponse(void);
  296. // inbound protocol extension related member functions
  297. HRESULT OnEvent(
  298. IUnknown * pIserver,
  299. IUnknown * pISession,
  300. IMailMsgProperties *pIMessage,
  301. LPPE_COMMAND_NODE pCommandNode,
  302. LPPE_BINDING_NODE pBindingNode,
  303. char * szArgs
  304. );
  305. HRESULT OnNotifyAsyncCompletion(
  306. HRESULT hrResult
  307. );
  308. BOOL ProcessAndSendResponse();
  309. BOOL GlueDispatch(char * InputLine, DWORD IntermediateSize, DWORD CmdSize, BOOL * pfAsyncOp);
  310. BOOL ProcessPeBlob(const char * pbInputLine, DWORD cbSize);
  311. BOOL PE_CdFormatSmtpMessage(DWORD dwCode, const char * szEnhancedCodes,IN const char * Format, ...);
  312. BOOL PE_FormatSmtpMessage(IN const char * Format, ...);
  313. BOOL PE_FastFormatSmtpMessage(LPSTR pszBuffer, DWORD dwBytes);
  314. BOOL PE_DisconnectClient();
  315. BOOL PE_SendSmtpResponse();
  316. IUnknown *GetSessionPropertyBag() { return((IUnknown *)(IMailMsgPropertyBag *)(&m_SessionPropertyBag)); }
  317. char * CheckArgument(IN OUT char * Argument, BOOL WriteError = TRUE);
  318. static SMTP_CONNECTION * CreateSmtpConnection (IN PCLIENT_CONN_PARAMS ClientParam,
  319. PSMTP_SERVER_INSTANCE pInst);
  320. SOCKET QueryClientSocket(void)
  321. {
  322. return QuerySocket();
  323. }
  324. LPCSTR QueryClientUserName()
  325. {
  326. if(m_szHeloAddr[0] != '\0')
  327. return m_szHeloAddr;
  328. else
  329. return "";
  330. }
  331. void StartSessionTimer()
  332. {
  333. m_msSession = GetTickCount();
  334. }
  335. DWORD QuerySessionTime()
  336. {
  337. return GetTickCount() - m_msSession;
  338. }
  339. ADDRESS_CHECK* QueryAccessCheck() { return &m_acAccessCheck; }
  340. BOOL BindInstanceAccessCheck();
  341. VOID UnbindInstanceAccessCheck();
  342. PSMTP_SERVER_INSTANCE QuerySmtpInstance( VOID ) const
  343. { _ASSERT(m_pInstance != NULL); return m_pInstance; }
  344. BOOL IsSmtpInstance( VOID ) const
  345. { return m_pInstance != NULL; }
  346. VOID SetSmtpInstance( IN PSMTP_SERVER_INSTANCE pInstance )
  347. { _ASSERT(m_pInstance == NULL); m_pInstance = pInstance; }
  348. SMTP_SERVER_STATISTICS * QuerySmtpStatsObj( VOID ) const
  349. { return m_pSmtpStats; }
  350. VOID SetSmtpStatsObj( IN LPSMTP_SERVER_STATISTICS pSmtpStats )
  351. { m_pSmtpStats = pSmtpStats; }
  352. //
  353. // These are overridden from the base CLIENT_CONNECTION class to support
  354. // switching of receive buffers. We need to be able to switch buffers to
  355. // support SSL, which needs upto 32K chunks. Note that even though SSL
  356. // V3.0 restricts fragment sizes to 16K, our schannel is capable of
  357. // generating 32K fragments (due to a bug). So, we read up to 32K.
  358. //
  359. virtual LPCSTR QueryRcvBuffer( VOID) const
  360. { return ((LPCSTR) m_precvBuffer); }
  361. virtual LPSTR QueryMRcvBuffer(VOID) // modifiable string
  362. { return (LPSTR) m_precvBuffer; }
  363. //
  364. // This method causes this object to allocate 32K buffers and use them as
  365. // the receive and output buffer.
  366. //
  367. BOOL SwitchToBigSSLBuffers();
  368. DWORD QueryMaxReadSize() const
  369. { return m_cbMaxRecvBuffer; }
  370. void RequireAuth()
  371. {
  372. m_fAuthAnon = FALSE;
  373. HrSetISessionProperty(ISESSION_PID_ANONYMOUS_AUTH, FALSE);
  374. }
  375. private :
  376. //In case of chunking we write to the disk async
  377. DWORD m_AtqLocator;
  378. SMTPCLI_FILE_OVERLAPPED m_FileOverLapped;
  379. SMTPSTATE m_State;
  380. LASTIOSTATE m_LastClientIo;
  381. BOOL m_HelloSent;
  382. BOOL m_RecvdMailCmd;
  383. BOOL m_RecvdRcptCmd;
  384. BOOL m_RecvdAuthCmd;
  385. BOOL m_EmptyMail;
  386. BOOL m_Nooped;
  387. BOOL m_InHeader;
  388. BOOL m_LongBodyLine;
  389. BOOL m_fFoundEmbeddedCrlfDotCrlf;
  390. BOOL m_fScannedForCrlfDotCrlf;
  391. BOOL m_fSeenRFC822FromAddress;
  392. BOOL m_fSeenRFC822ToAddress;
  393. BOOL m_fSeenRFC822CcAddress;
  394. BOOL m_fSeenRFC822BccAddress;
  395. BOOL m_fSeenRFC822Subject;
  396. BOOL m_fSeenRFC822MsgId;
  397. BOOL m_fSeenRFC822SenderAddress;
  398. BOOL m_fSeenXPriority;
  399. BOOL m_fSeenXOriginalArrivalTime;
  400. BOOL m_fSeenContentType;
  401. BOOL m_fSetContentType;
  402. BOOL m_NeedToQuit;
  403. BOOL m_TimeToRewriteHeader;
  404. BOOL m_WritingData;
  405. BOOL m_SecurePort;
  406. BOOL m_fNegotiatingSSL;
  407. DWORD m_DNSLookupRetCode;
  408. BOOL m_fUseMbsCta;
  409. BOOL m_fAuthenticated;
  410. BOOL m_fMayRelay;
  411. BOOL m_fClearText;
  412. BOOL m_fDidUserCmd;
  413. BOOL m_fAuthAnon;
  414. char *m_precvBuffer;
  415. DWORD m_cbMaxRecvBuffer;
  416. char m_OutputBuffer[SMTP_MAX_REPLY_LEN];
  417. BOOL m_fRecvBufferFull;
  418. char *m_pOutputBuffer;
  419. DWORD m_cbMaxOutputBuffer;
  420. CBuffer * m_pFileWriteBuffer;
  421. DWORD m_cbCurrentWriteBuffer;
  422. DWORD m_cbRecvBufferOffset;
  423. DWORD m_cbTempBDATLen;
  424. DWORD m_OutputBufferSize;
  425. DWORD m_cbParsable;
  426. DWORD m_ProtocolErrors;
  427. DWORD m_dwUnsuccessfulLogons;
  428. DWORD m_TotalMsgSize;
  429. DWORD m_SessionSize;
  430. DWORD m_cbDotStrippedTotalMsgSize;
  431. DWORD m_HeaderSize;
  432. DWORD m_HeaderFlags;
  433. DWORD m_MailBodyError;
  434. MailBodyDiagnosticCode m_MailBodyDiagnostic;
  435. DWORD m_dwCurrentCommand;
  436. DWORD m_HopCount;
  437. DWORD m_LocalHopCount;
  438. LONG m_cPendingIoCount;
  439. LONG m_cActiveThreads;
  440. char CommandErrorType;
  441. char *m_pszArgs;
  442. IMailMsgProperties *m_pIMsg;
  443. IMailMsgRecipients *m_pIMsgRecipsTemp;
  444. IMailMsgRecipientsAdd *m_pIMsgRecips;
  445. IMailMsgBind *m_pBindInterface;
  446. PFIO_CONTEXT m_IMsgHandle;
  447. char m_szHeloAddr[MAX_INTERNET_NAME + 1];
  448. char m_szFromAddress[MAX_INTERNET_NAME + 1];
  449. LIST_ENTRY m_HeaderList;
  450. DWORD m_msSession;
  451. DWORD m_CurrentOffset;
  452. CEncryptCtx m_encryptCtx;
  453. CSecurityCtx m_securityCtx;
  454. AC_RESULT m_acCheck;
  455. ADDRESS_CHECK m_acAccessCheck;
  456. METADATA_REF_HANDLER m_rfAccessCheck;
  457. // used authentication mechanism
  458. CHAR m_szUsedAuthKeyword[25];
  459. CHAR m_szAuthenticatedUserNameFromSink[MAX_INTERNET_NAME + 1];
  460. // configured authentication packages (pointer to refcounted object)
  461. CProviderPackagesInfo *m_pProviderPackagesInfo;
  462. //Chunking related flags
  463. BOOL m_fIsLastChunk;
  464. BOOL m_fIsBinaryMime;
  465. BOOL m_fIsChunkComplete;
  466. DWORD m_dwTrailerStatus;
  467. int m_nChunkSize;
  468. int m_nBytesRemainingInChunk;
  469. BOOL m_fBufferFullInBDAT;
  470. // inbound protocol extension related data members
  471. public:
  472. CInboundContext m_CInboundContext;
  473. BOOL m_fAsyncEventCompletion;
  474. BOOL m_fAsyncEOD;
  475. private:
  476. BOOL m_fIsPeUnderway;
  477. IEventRouter *m_pIEventRouter;
  478. ISmtpInboundCommandDispatcher *m_pCInboundDispatcher;
  479. CMailMsgPropertyBag m_SessionPropertyBag;
  480. PSMTP_SERVER_INSTANCE m_pInstance;
  481. LPSMTP_SERVER_STATISTICS m_pSmtpStats;
  482. PATQ_CONTEXT m_AtqSeoContext;
  483. BOOL m_fPeBlobReady;
  484. ISmtpInCallbackSink * m_pPeBlobCallback;
  485. DWORD m_LineCompletionState; //stores state of IsLineCompleteRFC822 automaton
  486. BOOL m_Truncate; //TRUE when in truncation mode; gpulla
  487. BOOL m_BufrWasFull; //TRUE when the last call to IsLineCompleteRFC822 yielded a full buffer.
  488. SMTP_CONNECTION(
  489. IN PSMTP_SERVER_INSTANCE pInstance,
  490. IN SOCKET sClient,
  491. IN const SOCKADDR_IN * psockAddrRemote,
  492. IN const SOCKADDR_IN * psockAddrLocal = NULL,
  493. IN PATQ_CONTEXT pAtqContext = NULL,
  494. IN PVOID pvInitialRequest = NULL,
  495. IN DWORD cbInitialData = 0);
  496. BOOL InitializeObject (BOOL IsSecureConnection);
  497. DWORD VerifiyClient (IN const char * ClientHostName, IN const char * KnownIpAddress);
  498. BOOL ExtractAndValidateRcpt(char * ToName, char ** ppArgument, char * szRcptAddress, char ** ppDomain );
  499. HRESULT HrShouldAcceptRcpt(char * szDomainName );
  500. BOOL IsClientSecureEnough();
  501. BOOL HandleCompletedMessage(DWORD dwCommand, BOOL *pfAsyncOp);
  502. BOOL CreateMailBody (char * InputLine, DWORD ParameterSize, DWORD UndecryptedTailSize, BOOL *lpfWritePended);
  503. BOOL CreateMailBodyFromChunk (char * InputLine, DWORD ParameterSize, DWORD UndecryptedTailSize,BOOL *lpfWritePended);
  504. BOOL WriteRcvHeader(void);
  505. BOOL BindToStoreDrive(void);
  506. void HandleAddressError(char * InputLine);
  507. BOOL RewriteHeader(BOOL *lpfWritePended);
  508. void ReInitClassVariables(void);
  509. LONG IncPendingIoCount(void) { return InterlockedIncrement( &m_cPendingIoCount );}
  510. LONG DecPendingIoCount(void) { return InterlockedDecrement( &m_cPendingIoCount ); }
  511. LONG IncThreadCount(void) { return InterlockedIncrement( &m_cActiveThreads ); }
  512. LONG DecThreadCount(void) { return InterlockedDecrement( &m_cActiveThreads ); }
  513. //skips over WordSkip in Buffer
  514. char * SkipWord (char * Buffer, char * WordToSkip, DWORD WordLen);
  515. BOOL AddToField(void);
  516. BOOL WriteLine(char * Text, DWORD TexSize);
  517. VOID ProtocolLog(
  518. DWORD dwCommand = USE_CURRENT,
  519. LPCSTR pszParameters = "",
  520. DWORD dwWin32Error = NO_ERROR,
  521. DWORD dwSmtpError = NO_ERROR,
  522. DWORD BytesSent = 0,
  523. DWORD BytesRecv = 0,
  524. LPSTR pszTarget = "");
  525. void TransactionLog(
  526. const char *pszOperation,
  527. const char *pszParameters,
  528. const char *pszTarget,
  529. DWORD dwWin32Error,
  530. DWORD dwServiceSpecificStatus
  531. );
  532. BOOL DecryptInputBuffer();
  533. BOOL ProcessInputBuffer(void);
  534. BOOL DoSmtpArgs (char *InputLine);
  535. BOOL DoRcptArgs (char *InputLine, char * szORCPTval, DWORD * pdwNotifyVal);
  536. BOOL DoSizeCommand(char * Value, char * InputLine);
  537. BOOL DoBodyCommand (char * Value, char * InputLine);
  538. BOOL DoRetCommand (char * Value, char * InputLine);
  539. BOOL DoEnvidCommand (char * Value, char * InputLine);
  540. BOOL DoNotifyCommand (char * Value, DWORD * pdwNotifyValue);
  541. BOOL DoOrcptCommand (char * Value);
  542. BOOL DoMailFromAuthArg (char * Value);
  543. BOOL IsXtext(char * Xtext);
  544. BOOL ProcessAuthInfo(AUTH_COMMAND, LPSTR Blob, unsigned char * OutptBuffer, DWORD * dwBytes);
  545. BOOL DoAuthNegotiation(const char *InputLine, DWORD dwLineSize);
  546. BOOL PendReadIO(DWORD UndecryptedTailSize);
  547. BOOL DoUSERCommand(const CHAR *InputLine, DWORD dwLineSize, unsigned char *OutputBuff, DWORD * dwBytes,DWORD * dwResponse, char * szECode);
  548. BOOL DoPASSCommand(const CHAR *InputLine, DWORD dwLineSize, unsigned char *OutputBuff, DWORD * dwBytes,DWORD * dwResponse, char * szECode);
  549. BOOL UseMbsCta() { return m_fUseMbsCta; }
  550. BOOL DoesClientHaveIpAccess();
  551. //Partially async WriteFile
  552. BOOL WriteMailFile (char * Buffer, DWORD BuffSize, BOOL *lpfWritePended);
  553. //Fully async WriteFile
  554. BOOL WriteMailFileAtq(char * Buffer, DWORD dwBytesToWrite,DWORD dwIoMode);
  555. // void FreeAtqFileContext( void );
  556. void ReleasImsg(BOOL DeleteIMsg);
  557. void ReleasRcptList(void);
  558. void GetAndPersistRFC822Headers( char* InputLine, char* pszValueBuf );
  559. HRESULT SetAvailableMailMsgProperties();
  560. char *IsLineCompleteRFC822(
  561. IN char *InputLine,
  562. IN DWORD nBytes,
  563. IN DWORD UndecryptedTailSize,
  564. OUT BOOL *p_FullBuffer
  565. ); //gpulla
  566. BOOL HandleInternalError(DWORD err);
  567. HRESULT HrGetISessionProperties();
  568. //
  569. // Add corresponding HrSetISessionProperty overloads for DWORD,
  570. // LPSTR etc, as needed under this.
  571. //
  572. HRESULT HrSetISessionProperty(DWORD dwPropId, BOOL fValue);
  573. VOID CopyIPAddressesToSession();
  574. BOOL AcceptAndDiscardBDAT(const char *InputLine, DWORD UndecryptedTailSize, BOOL *pfAsyncOp);
  575. BOOL AcceptAndDiscardDATA(const char *InputLine, DWORD UndecryptedTailSize, BOOL *pfAsyncOp);
  576. BOOL MailBodyErrorProcessing();
  577. };
  578. typedef BOOL (SMTP_CONNECTION::*PMFI)(const char * InputLine, DWORD InputLinseSize);
  579. static PMFI SmtpDispatchTable[] = {
  580. #undef SmtpDef
  581. #define SmtpDef(Smtp) &SMTP_CONNECTION::Do##Smtp##Command,
  582. #include "smtpdef.h"
  583. // modified by andreik
  584. // &SMTP_CONNECTION::DoLASTCommand,
  585. NULL
  586. };
  587. //SMTPSTATE operator++(SMTPSTATE &state)
  588. //{return state = SMTPSTATE (state + 1);}
  589. # endif
  590. /************************ End of File ***********************/