diff options
Diffstat (limited to 'mailnews/compose/src/nsSmtpProtocol.h')
-rw-r--r-- | mailnews/compose/src/nsSmtpProtocol.h | 247 |
1 files changed, 247 insertions, 0 deletions
diff --git a/mailnews/compose/src/nsSmtpProtocol.h b/mailnews/compose/src/nsSmtpProtocol.h new file mode 100644 index 000000000..b1370d4be --- /dev/null +++ b/mailnews/compose/src/nsSmtpProtocol.h @@ -0,0 +1,247 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nsSmtpProtocol_h___ +#define nsSmtpProtocol_h___ + +#include "mozilla/Attributes.h" +#ifdef MOZ_MAILNEWS_OAUTH2 +#include "msgIOAuth2Module.h" +#endif +#include "nsMsgProtocol.h" +#include "nsIStreamListener.h" +#include "nsISmtpUrl.h" +#include "nsIMsgStatusFeedback.h" +#include "nsMsgLineBuffer.h" +#include "nsIAuthModule.h" +#include "MailNewsTypes2.h" // for nsMsgSocketType + +#include "nsCOMPtr.h" +#include "nsTArray.h" + +#ifdef MOZ_MAILNEWS_OAUTH2 +class nsIVariant; +class nsIWritableVariant; +#endif + + /* states of the machine + */ +typedef enum _SmtpState { +SMTP_RESPONSE = 0, // 0 +SMTP_START_CONNECT, // 1 +SMTP_FINISH_CONNECT, // 2 +SMTP_SEND_HELO_RESPONSE, // 3 +SMTP_SEND_EHLO_RESPONSE, // 4 +SMTP_SEND_MAIL_RESPONSE, // 5 +SMTP_SEND_RCPT_RESPONSE, // 6 +SMTP_SEND_DATA_RESPONSE, // 7 +SMTP_SEND_POST_DATA, // 8 +SMTP_SEND_MESSAGE_RESPONSE, // 9 +SMTP_DONE, // 10 +SMTP_ERROR_DONE, // 11 +SMTP_FREE, // 12 +SMTP_AUTH_LOGIN_STEP0_RESPONSE, // 13 +SMTP_EXTN_LOGIN_RESPONSE, // 14 +SMTP_SEND_AUTH_LOGIN_STEP0, // 15 +SMTP_SEND_AUTH_LOGIN_STEP1, // 16 +SMTP_SEND_AUTH_LOGIN_STEP2, // 17 +SMTP_AUTH_LOGIN_RESPONSE, // 18 +SMTP_TLS_RESPONSE, // 19 +SMTP_AUTH_EXTERNAL_RESPONSE, // 20 +SMTP_AUTH_PROCESS_STATE, // 21 +SMTP_AUTH_CRAM_MD5_CHALLENGE_RESPONSE, // 22 +SMTP_SEND_AUTH_GSSAPI_FIRST, // 23 +SMTP_SEND_AUTH_GSSAPI_STEP, // 24 +#ifdef MOZ_MAILNEWS_OAUTH2 +SMTP_SUSPENDED, // 25 +SMTP_AUTH_OAUTH2_STEP, // 26 +SMTP_AUTH_OAUTH2_RESPONSE, // 27 +#endif +} SmtpState; + +// State Flags (Note, I use the word state in terms of storing +// state information about the connection (authentication, have we sent +// commands, etc. I do not intend it to refer to protocol state) +#define SMTP_PAUSE_FOR_READ 0x00000001 /* should we pause for the next read */ +#define SMTP_ESMTP_SERVER 0x00000002 +#define SMTP_EHLO_DSN_ENABLED 0x00000004 +#define SMTP_EHLO_STARTTLS_ENABLED 0x00000008 +#define SMTP_EHLO_SIZE_ENABLED 0x00000010 +#define SMTP_EHLO_8BIT_ENABLED 0x00000020 + +// insecure mechanisms follow +#define SMTP_AUTH_LOGIN_ENABLED 0x00000100 +#define SMTP_AUTH_PLAIN_ENABLED 0x00000200 +#define SMTP_AUTH_EXTERNAL_ENABLED 0x00000400 +// secure mechanisms follow +#define SMTP_AUTH_GSSAPI_ENABLED 0x00000800 +#define SMTP_AUTH_DIGEST_MD5_ENABLED 0x00001000 +#define SMTP_AUTH_CRAM_MD5_ENABLED 0x00002000 +#define SMTP_AUTH_NTLM_ENABLED 0x00004000 +#define SMTP_AUTH_MSN_ENABLED 0x00008000 +#ifdef MOZ_MAILNEWS_OAUTH2 +#define SMTP_AUTH_OAUTH2_ENABLED 0x00010000 +// sum of all above auth mechanisms +#define SMTP_AUTH_ANY 0x0001FF00 +// indicates that AUTH has been advertised +#define SMTP_AUTH 0x00020000 +// No login necessary (pref) +#define SMTP_AUTH_NONE_ENABLED 0x00040000 +#else +#define SMTP_AUTH_ANY 0x0000FF00 +#define SMTP_AUTH 0x00010000 +#define SMTP_AUTH_NONE_ENABLED 0x00020000 +#endif + +#ifdef MOZ_MAILNEWS_OAUTH2 +class nsSmtpProtocol : public nsMsgAsyncWriteProtocol, + public msgIOAuth2ModuleListener +#else +class nsSmtpProtocol : public nsMsgAsyncWriteProtocol +#endif +{ +public: + NS_DECL_ISUPPORTS_INHERITED +#ifdef MOZ_MAILNEWS_OAUTH2 + NS_DECL_MSGIOAUTH2MODULELISTENER +#endif + + // Creating a protocol instance requires the URL which needs to be run. + explicit nsSmtpProtocol(nsIURI * aURL); + + virtual nsresult LoadUrl(nsIURI * aURL, nsISupports * aConsumer = nullptr) override; + virtual nsresult SendData(const char * dataBuffer, bool aSuppressLogging = false) override; + + //////////////////////////////////////////////////////////////////////////////////////// + // we suppport the nsIStreamListener interface + //////////////////////////////////////////////////////////////////////////////////////// + + // stop binding is a "notification" informing us that the stream associated with aURL is going away. + NS_IMETHOD OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult status) override; + +private: + virtual ~nsSmtpProtocol(); + // if we are asked to load a url while we are blocked waiting for redirection information, + // then we'll store the url consumer in mPendingConsumer until we can actually load + // the url. + nsCOMPtr<nsISupports> mPendingConsumer; + + // the nsISmtpURL that is currently running + nsCOMPtr<nsISmtpUrl> m_runningURL; + + // the error state we want to set on the url + nsresult m_urlErrorState; + nsCOMPtr<nsIMsgStatusFeedback> m_statusFeedback; + + // Generic state information -- What state are we in? What state do we want to go to + // after the next response? What was the last response code? etc. + SmtpState m_nextState; + SmtpState m_nextStateAfterResponse; + int32_t m_responseCode; /* code returned from Smtp server */ + int32_t m_previousResponseCode; + int32_t m_continuationResponse; + nsCString m_responseText; /* text returned from Smtp server */ + RefPtr<nsMsgLineStreamBuffer> m_lineStreamBuffer; // used to efficiently extract lines from the incoming data stream + + nsTArray<nsCString> m_addresses; + uint32_t m_addressesLeft; + nsCString m_mailAddr; + nsCString m_helloArgument; + int32_t m_sizelimit; + + // *** the following should move to the smtp server when we support + // multiple smtp servers + bool m_usernamePrompted; + int32_t m_prefSocketType; + bool m_tlsEnabled; + + bool m_tlsInitiated; + + bool m_sendDone; + + int32_t m_totalAmountRead; + int64_t m_totalMessageSize; + + char *m_dataBuf; + uint32_t m_dataBufSize; + + int32_t m_originalContentLength; /* the content length at the time of calling graph progress */ + + // initialization function given a new url and transport layer + void Initialize(nsIURI * aURL); + virtual nsresult ProcessProtocolState(nsIURI * url, nsIInputStream * inputStream, + uint64_t sourceOffset, uint32_t length) override; + + //////////////////////////////////////////////////////////////////////////////////////// + // Communication methods --> Reading and writing protocol + //////////////////////////////////////////////////////////////////////////////////////// + + void UpdateStatus(const char16_t* aStatusName); + void UpdateStatusWithString(const char16_t * aStatusString); + + //////////////////////////////////////////////////////////////////////////////////////// + // Protocol Methods --> This protocol is state driven so each protocol method is + // designed to re-act to the current "state". I've attempted to + // group them together based on functionality. + //////////////////////////////////////////////////////////////////////////////////////// + + nsresult SmtpResponse(nsIInputStream * inputStream, uint32_t length); + nsresult ExtensionLoginResponse(nsIInputStream * inputStream, uint32_t length); + nsresult SendHeloResponse(nsIInputStream * inputStream, uint32_t length); + nsresult SendEhloResponse(nsIInputStream * inputStream, uint32_t length); + nsresult SendQuit(SmtpState aNextStateAfterResponse = SMTP_DONE); + + nsresult AuthGSSAPIFirst(); + nsresult AuthGSSAPIStep(); + nsresult AuthLoginStep0(); + void AuthLoginStep0Response(); + nsresult AuthLoginStep1(); + nsresult AuthLoginStep2(); + nsresult AuthLoginResponse(nsIInputStream * stream, uint32_t length); +#ifdef MOZ_MAILNEWS_OAUTH2 + nsresult AuthOAuth2Step1(); +#endif + + nsresult SendTLSResponse(); + nsresult SendMailResponse(); + nsresult SendRecipientResponse(); + nsresult SendDataResponse(); + void SendPostData(); + nsresult SendMessageResponse(); + nsresult ProcessAuth(); + + + //////////////////////////////////////////////////////////////////////////////////////// + // End of Protocol Methods + //////////////////////////////////////////////////////////////////////////////////////// + + void SendMessageInFile(); + + void AppendHelloArgument(nsACString& aResult); + nsresult GetPassword(nsCString &aPassword); + nsresult GetUsernamePassword(nsACString &aUsername, nsACString &aPassword); + nsresult PromptForPassword(nsISmtpServer *aSmtpServer, nsISmtpUrl *aSmtpUrl, + const char16_t **formatStrings, + nsACString &aPassword); + + void InitPrefAuthMethods(int32_t authMethodPrefValue); + nsresult ChooseAuthMethod(); + void MarkAuthMethodAsFailed(int32_t failedAuthMethod); + void ResetAuthMethods(); + + virtual const char* GetType() override {return "smtp";} + + int32_t m_prefAuthMethods; // set of capability flags for auth methods + int32_t m_failedAuthMethods; // ditto + int32_t m_currentAuthMethod; // exactly one capability flag, or 0 + +#ifdef MOZ_MAILNEWS_OAUTH2 + // The support module for OAuth2 logon, only present if OAuth2 is enabled + // and working. + nsCOMPtr<msgIOAuth2Module> mOAuth2Support; +#endif +}; + +#endif // nsSmtpProtocol_h___ |