Back to index

lightning-sunbird  0.9+nobinonly
nsSmtpProtocol.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #ifndef nsSmtpProtocol_h___
00039 #define nsSmtpProtocol_h___
00040 
00041 #include "nsMsgProtocol.h"
00042 #include "nsIStreamListener.h"
00043 #include "nsXPIDLString.h"
00044 #include "nsISmtpUrl.h"
00045 #include "nsIMsgStatusFeedback.h"
00046 #include "nsIMsgLogonRedirector.h"
00047 #include "nsIMsgStringService.h"
00048 #include "nsMsgLineBuffer.h"
00049 #include "nsIAuthModule.h"
00050 
00051 #include "nsCOMPtr.h"
00052 
00053  /* states of the machine
00054  */
00055 typedef enum _SmtpState {
00056 SMTP_RESPONSE = 0,                                  // 0
00057 SMTP_START_CONNECT,                                 // 1
00058 SMTP_FINISH_CONNECT,                                // 2
00059 SMTP_SEND_HELO_RESPONSE,                            // 3
00060 SMTP_SEND_EHLO_RESPONSE,                            // 4
00061 SMTP_SEND_VRFY_RESPONSE,                            // 5
00062 SMTP_SEND_MAIL_RESPONSE,                            // 6
00063 SMTP_SEND_RCPT_RESPONSE,                            // 7
00064 SMTP_SEND_DATA_RESPONSE,                            // 8
00065 SMTP_SEND_POST_DATA,                                // 9
00066 SMTP_SEND_MESSAGE_RESPONSE,                         // 10
00067 SMTP_DONE,                                          // 11
00068 SMTP_ERROR_DONE,                                    // 12
00069 SMTP_FREE,                                          // 13
00070 SMTP_AUTH_LOGIN_STEP0_RESPONSE,                     // 14
00071 SMTP_EXTN_LOGIN_RESPONSE,                           // 15
00072 SMTP_SEND_AUTH_LOGIN_STEP0,                         // 16
00073 SMTP_SEND_AUTH_LOGIN_STEP1,                         // 17
00074 SMTP_SEND_AUTH_LOGIN_STEP2,                         // 18
00075 SMTP_AUTH_LOGIN_RESPONSE,                           // 19
00076 SMTP_TLS_RESPONSE,                                  // 20
00077 SMTP_AUTH_EXTERNAL_RESPONSE,                        // 21
00078 SMTP_AUTH_PROCESS_STATE,                            // 22
00079 SMTP_AUTH_CRAM_MD5_CHALLENGE_RESPONSE,              // 23
00080 SMTP_SEND_AUTH_GSSAPI_FIRST,                        // 24
00081 SMTP_SEND_AUTH_GSSAPI_STEP                          // 25
00082 } SmtpState;
00083 
00084 // State Flags (Note, I use the word state in terms of storing 
00085 // state information about the connection (authentication, have we sent
00086 // commands, etc. I do not intend it to refer to protocol state)
00087 #define SMTP_PAUSE_FOR_READ             0x00000001  /* should we pause for the next read */
00088 #define SMTP_EHLO_DSN_ENABLED           0x00000002
00089 #define SMTP_AUTH_LOGIN_ENABLED         0x00000004
00090 #define SMTP_AUTH_PLAIN_ENABLED         0x00000008
00091 #define SMTP_AUTH_EXTERNAL_ENABLED      0x00000010
00092 #define SMTP_EHLO_STARTTLS_ENABLED      0x00000020
00093 
00094 // if we are using a login redirection
00095 // and we are waiting for it to give us the
00096 // host and port to connect to, then this flag
00097 // will be set...
00098 #define SMTP_WAIT_FOR_REDIRECTION       0x00000040
00099 // if we are using login redirection and we received a load Url
00100 // request while we were stil waiting for the redirection information
00101 // then we'll look in this field 
00102 #define SMTP_LOAD_URL_PENDING           0x00000080
00103 // if we are using login redirection, then this flag will be set.
00104 // Note, this is different than the flag for whether we are waiting
00105 // for login redirection information.
00106 #define SMTP_USE_LOGIN_REDIRECTION      0x00000100
00107 #define SMTP_ESMTP_SERVER               0x00000200
00108 #define SMTP_AUTH_CRAM_MD5_ENABLED      0x00000400
00109 #define SMTP_AUTH_DIGEST_MD5_ENABLED    0x00000800
00110 #define SMTP_AUTH_NTLM_ENABLED          0x00001000
00111 #define SMTP_AUTH_MSN_ENABLED           0x00002000
00112 #define SMTP_AUTH_ANY_ENABLED           0x0000BC1C
00113 #define SMTP_EHLO_SIZE_ENABLED          0x00004000
00114 #define SMTP_AUTH_GSSAPI_ENABLED        0x00008000
00115 
00116 typedef enum _PrefAuthMethod {
00117     PREF_AUTH_NONE = 0,
00118     PREF_AUTH_ANY = 1
00119 } PrefAuthMethod;
00120 
00121 typedef enum _PrefTrySSL {
00122     PREF_SECURE_NEVER = 0,
00123     PREF_SECURE_TRY_STARTTLS = 1,
00124     PREF_SECURE_ALWAYS_STARTTLS = 2,
00125     PREF_SECURE_ALWAYS_SMTPS = 3
00126 } PrefTrySSL;
00127 
00128 class nsSmtpProtocol : public nsMsgAsyncWriteProtocol,
00129                        public nsIMsgLogonRedirectionRequester
00130 {
00131 public:
00132     NS_DECL_ISUPPORTS_INHERITED
00133     NS_DECL_NSIMSGLOGONREDIRECTIONREQUESTER
00134 
00135     // Creating a protocol instance requires the URL which needs to be run.
00136     nsSmtpProtocol(nsIURI * aURL);
00137     virtual ~nsSmtpProtocol();
00138 
00139     virtual nsresult LoadUrl(nsIURI * aURL, nsISupports * aConsumer = nsnull);
00140     virtual PRInt32 SendData(nsIURI * aURL, const char * dataBuffer, PRBool aSuppressLogging = PR_FALSE);
00141 
00143     // we suppport the nsIStreamListener interface 
00145 
00146     // stop binding is a "notification" informing us that the stream associated with aURL is going away. 
00147     NS_IMETHOD OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult status);
00148 
00149 private:
00150     // logon redirection related variables and methods
00151     nsresult RequestOverrideInfo(nsISmtpServer * aSmtpServer); // kicks off the request to get redirection info for the server
00152     nsCString mLogonCookie; // an opaque cookie we pass to certain servers to logon
00153     // if we are asked to load a url while we are blocked waiting for redirection information,
00154     // then we'll store the url consumer in mPendingConsumer until we can actually load
00155     // the url.
00156     nsCOMPtr<nsISupports> mPendingConsumer;
00157     // we cache the logon redirector in the short term so after we receive
00158     // the redirect information we can logoff the redirector...
00159     nsCOMPtr <nsIMsgLogonRedirector> m_logonRedirector;
00160 
00161     // the nsISmtpURL that is currently running
00162     nsCOMPtr<nsISmtpUrl> m_runningURL;
00163 
00164     // the error state we want to set on the url
00165     nsresult m_urlErrorState;
00166     PRUint32 m_LastTime;
00167     nsCOMPtr<nsIMsgStatusFeedback> m_statusFeedback;
00168 
00169     // Generic state information -- What state are we in? What state do we want to go to
00170     // after the next response? What was the last response code? etc. 
00171     SmtpState m_nextState;
00172     SmtpState m_nextStateAfterResponse;
00173     PRInt32 m_responseCode;    /* code returned from Smtp server */
00174     PRInt32 m_previousResponseCode; 
00175     PRInt32 m_continuationResponse;
00176     nsCString m_responseText;   /* text returned from Smtp server */
00177     nsMsgLineStreamBuffer *m_lineStreamBuffer; // used to efficiently extract lines from the incoming data stream
00178 
00179     char           *m_addressCopy;
00180     char           *m_addresses;
00181     PRUint32       m_addressesLeft;
00182     char           *m_verifyAddress;
00183     nsXPIDLCString m_mailAddr;
00184     nsXPIDLCString m_helloArgument;
00185     PRInt32        m_sizelimit;
00186 
00187     // *** the following should move to the smtp server when we support
00188     // multiple smtp servers
00189     PRInt32 m_prefAuthMethod;
00190     PRBool m_prefTrySecAuth;
00191     PRBool m_usernamePrompted;
00192     PRInt32 m_prefTrySSL;
00193     PRBool m_tlsEnabled;
00194   
00195     PRBool m_tlsInitiated;
00196 
00197     PRBool m_sendDone;
00198 
00199     PRInt32 m_totalAmountRead;
00200 #ifdef UNREADY_CODE 
00201     // message specific information
00202     PRInt32 m_totalAmountWritten;
00203 #endif /* UNREADY_CODE */
00204     PRUint32 m_totalMessageSize;
00205     
00206     char *m_dataBuf;
00207     PRUint32 m_dataBufSize;
00208 
00209     PRInt32   m_originalContentLength; /* the content length at the time of calling graph progress */
00210 
00211     // initialization function given a new url and transport layer
00212     void Initialize(nsIURI * aURL);
00213     virtual nsresult ProcessProtocolState(nsIURI * url, nsIInputStream * inputStream, 
00214                                           PRUint32 sourceOffset, PRUint32 length);
00215 
00217     // Communication methods --> Reading and writing protocol
00219 
00220     nsCOMPtr<nsIMsgStringService> mSmtpBundle;
00221     void UpdateStatus(PRInt32 aStatusID);
00222     void UpdateStatusWithString(const PRUnichar * aStatusString);
00223 
00225     // Protocol Methods --> This protocol is state driven so each protocol method is 
00226     //                                    designed to re-act to the current "state". I've attempted to 
00227     //                                    group them together based on functionality. 
00229 
00230     PRInt32 SmtpResponse(nsIInputStream * inputStream, PRUint32 length); 
00231     PRInt32 ExtensionLoginResponse(nsIInputStream * inputStream, PRUint32 length);
00232     PRInt32 SendHeloResponse(nsIInputStream * inputStream, PRUint32 length);
00233     PRInt32 SendEhloResponse(nsIInputStream * inputStream, PRUint32 length); 
00234 
00235     PRInt32 AuthGSSAPIFirst();
00236     PRInt32 AuthGSSAPIStep();
00237     PRInt32 AuthLoginStep0();
00238     PRInt32 AuthLoginStep0Response();
00239     PRInt32 AuthLoginStep1();
00240     PRInt32 AuthLoginStep2();
00241     PRInt32 AuthLoginResponse(nsIInputStream * stream, PRUint32 length);
00242 
00243     PRInt32 SendTLSResponse();
00244     PRInt32 SendVerifyResponse(); // mscott: this one is apparently unimplemented...
00245     PRInt32 SendMailResponse();
00246     PRInt32 SendRecipientResponse();
00247     PRInt32 SendDataResponse();
00248     PRInt32 SendPostData();
00249     PRInt32 SendMessageResponse();
00250     PRInt32 CramMD5LoginResponse();
00251     PRInt32 ProcessAuth();
00252 
00253 
00255     // End of Protocol Methods
00257 
00258     PRInt32 SendMessageInFile();
00259 
00260     void AppendHelloArgument(nsACString& aResult);
00261     nsresult GetPassword(char **aPassword);
00262     nsresult GetUsernamePassword(char **aUsername, char **aPassword);
00263     nsresult PromptForPassword(nsISmtpServer *aSmtpServer, nsISmtpUrl *aSmtpUrl, const PRUnichar **formatStrings, char **aPassword);
00264 
00265     void BackupAuthFlags();
00266     void RestoreAuthFlags();
00267     PRInt32 m_origAuthFlags;
00268 };
00269 
00270 #endif  // nsSmtpProtocol_h___