Branch data Line data Source code
1 : : // $Id: SMTP.h 6219 2008-10-01 05:39:07Z vern $
2 : : //
3 : : // See the file "COPYING" in the main distribution directory for copyright.
4 : :
5 : : #ifndef smtp_h
6 : : #define smtp_h
7 : :
8 : : #include <list>
9 : : using namespace std;
10 : :
11 : : #include "TCP.h"
12 : : #include "MIME.h"
13 : :
14 : :
15 : : #undef SMTP_CMD_DEF
16 : : #define SMTP_CMD_DEF(cmd) SMTP_CMD_##cmd,
17 : :
18 : : typedef enum {
19 : : #include "SMTP_cmd.def"
20 : : } SMTP_Cmd;
21 : :
22 : : // State is updated on every SMTP reply.
23 : : typedef enum {
24 : : SMTP_CONNECTED, // 0: before the opening message
25 : : SMTP_INITIATED, // 1: after opening message 220, EHLO/HELO expected
26 : : SMTP_NOT_AVAILABLE, // 2: after opening message 554, etc.
27 : : SMTP_READY, // 3: after EHLO/HELO and reply 250
28 : : SMTP_MAIL_OK, // 4: after MAIL/SEND/SOML/SAML and 250, RCPT expected
29 : : SMTP_RCPT_OK, // 5: after one successful RCPT, DATA or more RCPT expected
30 : : SMTP_IN_DATA, // 6: after DATA
31 : : SMTP_AFTER_DATA, // 7: after . and before reply
32 : : SMTP_IN_AUTH, // 8: after AUTH and 334
33 : : SMTP_IN_TLS, // 9: after STARTTLS and 220
34 : : SMTP_QUIT, // 10: after QUIT
35 : : SMTP_AFTER_GAP, // 11: after a gap is detected
36 : : SMTP_GAP_RECOVERY, // 12: after the first reply after a gap
37 : : } SMTP_State;
38 : :
39 : :
40 : : class SMTP_Analyzer : public TCP_ApplicationAnalyzer {
41 : : public:
42 : : SMTP_Analyzer(Connection* conn);
43 : : ~SMTP_Analyzer();
44 : :
45 : : virtual void Done();
46 : : virtual void DeliverStream(int len, const u_char* data, bool orig);
47 : : virtual void ConnectionFinished(int half_finished);
48 : : virtual void Undelivered(int seq, int len, bool orig);
49 : 4 : virtual int RewritingTrace()
50 [ + - ][ - + ]: 4 : { return rewriting_smtp_trace || TCP_ApplicationAnalyzer::RewritingTrace(); }
51 : :
52 : 0 : void SkipData() { skip_data = 1; } // skip delivery of data lines
53 : :
54 : 4 : static Analyzer* InstantiateAnalyzer(Connection* conn)
55 : : {
56 : 4 : return new SMTP_Analyzer(conn);
57 : : }
58 : :
59 : 1 : static bool Available()
60 : : {
61 : : return smtp_request || smtp_reply ||
62 [ - + ][ # # ]: 1 : smtp_data || smtp_unexpected;
[ # # ][ # # ]
63 : : }
64 : :
65 : : protected:
66 : :
67 : : void ProcessLine(int length, const char* line, bool orig);
68 : : void NewCmd(const int cmd_code);
69 : : void NewReply(const int reply_code);
70 : : void ProcessExtension(int ext_len, const char* ext);
71 : : void ProcessData(int length, const char* line);
72 : :
73 : : void UpdateState(const int cmd_code, const int reply_code);
74 : :
75 : : void BeginData();
76 : : void EndData();
77 : :
78 : : int ParseCmd(int cmd_len, const char* cmd);
79 : :
80 : : void RequestEvent(int cmd_len, const char* cmd,
81 : : int arg_len, const char* arg);
82 : : void Unexpected(const int is_orig, const char* msg,
83 : : int detail_len, const char* detail);
84 : : void UnexpectedCommand(const int cmd_code, const int reply_code);
85 : : void UnexpectedReply(const int cmd_code, const int reply_code);
86 : :
87 : : bool orig_is_sender;
88 : : int expect_sender, expect_recver;
89 : : int state;
90 : : int last_replied_cmd;
91 : : int first_cmd; // first un-replied SMTP cmd, or -1
92 : : int pending_reply; // code assoc. w/ multi-line reply, or 0
93 : : int pipelining; // whether pipelining is supported
94 : : list<int> pending_cmd_q; // to support pipelining
95 : : int skip_data; // whether to skip message body
96 : : int orig_record_contents; // keep the original record_contents
97 : : BroString* line_after_gap; // last line before the first reply
98 : : // after a gap
99 : :
100 : : MIME_Mail* mail;
101 : : };
102 : :
103 : : #endif
|