1 //--------------------------------------------------------------------------
2 // Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved.
3 // Copyright (C) 2011-2013 Sourcefire, Inc.
4 //
5 // This program is free software; you can redistribute it and/or modify it
6 // under the terms of the GNU General Public License Version 2 as published
7 // by the Free Software Foundation.  You may not use, modify or distribute
8 // this program under any other version of the GNU General Public License.
9 //
10 // This program is distributed in the hope that it will be useful, but
11 // WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License along
16 // with this program; if not, write to the Free Software Foundation, Inc.,
17 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18 //--------------------------------------------------------------------------
19 
20 // imap_paf.h author Hui Cao <huica@cisco.com>
21 
22 #ifndef IMAP_PAF_H
23 #define IMAP_PAF_H
24 
25 // Protocol aware flushing for IMAP
26 
27 #include "mime/file_mime_paf.h"
28 #include "stream/stream_splitter.h"
29 
30 struct ImapDataInfo
31 {
32     int paren_cnt;            // The open parentheses count in fetch
33     const char* next_letter;  // The current command in fetch
34     bool found_len;
35     uint32_t length;
36     bool esc_nxt_char;        // true if the next character has been escaped
37 };
38 
39 // States for IMAP PAF
40 typedef enum _ImapPafState
41 {
42     IMAP_PAF_REG_STATE,           // default state. eat until LF
43     IMAP_PAF_DATA_HEAD_STATE,     // parses the fetch header
44     IMAP_PAF_DATA_LEN_STATE,      // parse the literal length
45     IMAP_PAF_DATA_STATE,          // search for and flush on MIME boundaries
46     IMAP_PAF_FLUSH_STATE,         // flush if a termination sequence is found
47     IMAP_PAF_CMD_IDENTIFIER,      // determine the line identifier ('+', '*', tag)
48     IMAP_PAF_CMD_TAG,             // currently analyzing tag . identifier
49     IMAP_PAF_CMD_STATUS,          // currently parsing second argument
50     IMAP_PAF_CMD_SEARCH           // currently searching data for a command
51 } ImapPafState;
52 
53 typedef enum _ImapDataEnd
54 {
55     IMAP_PAF_DATA_END_UNKNOWN,
56     IMAP_PAF_DATA_END_PAREN
57 } ImapDataEnd;
58 
59 // State tracker for IMAP PAF
60 struct ImapPafData
61 {
62     MimeDataPafInfo mime_info;    // Mime response information
63     ImapPafState imap_state;      // The current IMAP paf stat
64     ImapDataInfo imap_data_info;  // Used for parsing data
65     ImapDataEnd data_end_state;
66     bool end_of_data;
67 };
68 
69 class ImapSplitter : public snort::StreamSplitter
70 {
71 public:
72     ImapSplitter(bool c2s);
73 
74     Status scan(snort::Packet*, const uint8_t* data, uint32_t len,
75         uint32_t flags, uint32_t* fp) override;
76 
is_paf()77     bool is_paf() override { return true; }
78 
79 public:
80     ImapPafData state;
81 };
82 
83 // Function: Check if IMAP data end is reached
84 bool imap_is_data_end(snort::Flow* ssn);
85 
86 #endif
87 
88