LCOV - code coverage report
Current view: top level - src - MIME.h (source / functions) Hit Total Coverage
Test: app.info Lines: 19 24 79.2 %
Date: 2010-12-13 Functions: 9 15 60.0 %
Branches: 2 12 16.7 %

           Branch data     Line data    Source code
       1                 :            : // $Id: MIME.h 3526 2006-09-12 07:32:21Z vern $
       2                 :            : 
       3                 :            : #ifndef mime_h
       4                 :            : #define mime_h
       5                 :            : 
       6                 :            : #include <assert.h>
       7                 :            : 
       8                 :            : #include <stdio.h>
       9                 :            : #include <vector>
      10                 :            : #include <queue>
      11                 :            : using namespace std;
      12                 :            : 
      13                 :            : #include "md5.h"
      14                 :            : #include "Base64.h"
      15                 :            : #include "BroString.h"
      16                 :            : #include "Analyzer.h"
      17                 :            : 
      18                 :            : // MIME: Multipurpose Internet Mail Extensions
      19                 :            : // Follows RFC 822 & 2822 (Internet Mail), 2045-2049 (MIME)
      20                 :            : // See related files: SMTP.h and SMTP.cc
      21                 :            : 
      22                 :            : // MIME Constants
      23                 :            : 
      24                 :            : #define HT      '\011'
      25                 :            : #define SP      '\040'
      26                 :            : #define CR      '\015'
      27                 :            : #define LF      '\012'
      28                 :            : 
      29                 :            : enum MIME_CONTENT_TYPE {
      30                 :            :         CONTENT_TYPE_MULTIPART,
      31                 :            :         CONTENT_TYPE_MESSAGE,
      32                 :            :         CONTENT_TYPE_TEXT,
      33                 :            :         CONTENT_TYPE_OTHER,     // image | audio | video | application | <other>
      34                 :            : };
      35                 :            : 
      36                 :            : enum MIME_EVENT_TYPE {
      37                 :            :         MIME_EVENT_ILLEGAL_FORMAT,
      38                 :            :         MIME_EVENT_ILLEGAL_ENCODING,
      39                 :            :         MIME_EVENT_CONTENT_GAP,
      40                 :            :         MIME_EVENT_OTHER,
      41                 :            : };
      42                 :            : 
      43                 :            : 
      44                 :            : 
      45                 :            : // MIME data structures.
      46                 :            : 
      47                 :            : class MIME_Multiline;
      48                 :            : class MIME_Header;
      49                 :            : class MIME_Body;
      50                 :            : class MIME_Entity;      // an "entity" contains headers and a body
      51                 :            : class MIME_Mail;
      52                 :            : class MIME_Message;
      53                 :            : 
      54                 :            : class MIME_Multiline {
      55                 :            : public:
      56                 :            :         MIME_Multiline();
      57                 :            :         ~MIME_Multiline();
      58                 :            : 
      59                 :            :         void append(int len, const char* data);
      60                 :            :         BroString* get_concatenated_line();
      61                 :            : 
      62                 :            : protected:
      63                 :            :         vector<const BroString*> buffer;
      64                 :            :         BroString* line;
      65                 :            : };
      66                 :            : 
      67                 :            : class MIME_Header {
      68                 :            : public:
      69                 :            :         MIME_Header(MIME_Multiline* hl);
      70                 :            :         ~MIME_Header();
      71                 :            : 
      72                 :      63111 :         data_chunk_t get_name() const   { return name; }
      73                 :      16419 :         data_chunk_t get_value() const  { return value; }
      74                 :            : 
      75                 :            :         data_chunk_t get_value_token();
      76                 :            :         data_chunk_t get_value_after_token();
      77                 :            : 
      78                 :            : protected:
      79                 :            :         int get_first_token();
      80                 :            : 
      81                 :            :         MIME_Multiline* lines;
      82                 :            :         data_chunk_t name;
      83                 :            :         data_chunk_t value;
      84                 :            :         data_chunk_t value_token, rest_value;
      85                 :            : };
      86                 :            : 
      87                 :            : 
      88                 :            : // declare(PList, MIME_Header);
      89                 :            : typedef vector<MIME_Header*> MIME_HeaderList;
      90                 :            : 
      91                 :            : class MIME_Entity {
      92                 :            : public:
      93                 :            :         MIME_Entity(MIME_Message* output_message, MIME_Entity* parent_entity);
      94                 :            :         virtual ~MIME_Entity();
      95                 :            : 
      96                 :            :         virtual void Deliver(int len, const char* data, int trailing_CRLF);
      97                 :            :         virtual void EndOfData();
      98                 :            : 
      99                 :        881 :         MIME_Entity* Parent() const { return parent; }
     100                 :          0 :         StringVal* ContentType() const { return content_type_str; }
     101                 :          0 :         StringVal* ContentSubType() const { return content_subtype_str; }
     102                 :          0 :         int ContentTransferEncoding() const { return content_encoding; }
     103                 :            : 
     104                 :            : protected:
     105                 :            :         void init();
     106                 :            : 
     107                 :            :         // {begin, continuation, end} of a header.
     108                 :            :         void NewHeader(int len, const char* data);
     109                 :            :         void ContHeader(int len, const char* data);
     110                 :            :         void FinishHeader();
     111                 :            : 
     112                 :            :         void ParseMIMEHeader(MIME_Header* h);
     113                 :            :         int LookupMIMEHeaderName(data_chunk_t name);
     114                 :            :         int ParseContentTypeField(MIME_Header* h);
     115                 :            :         int ParseContentEncodingField(MIME_Header* h);
     116                 :            :         int ParseFieldParameters(int len, const char* data);
     117                 :            : 
     118                 :            :         void ParseContentType(data_chunk_t type, data_chunk_t sub_type);
     119                 :            :         void ParseContentEncoding(data_chunk_t encoding_mechanism);
     120                 :            :         void ParseParameter(data_chunk_t attr, data_chunk_t val);
     121                 :            : 
     122                 :            :         void BeginBody();
     123                 :            :         void NewDataLine(int len, const char* data, int trailing_CRLF);
     124                 :            : 
     125                 :            :         int CheckBoundaryDelimiter(int len, const char* data);
     126                 :            :         void DecodeDataLine(int len, const char* data, int trailing_CRLF);
     127                 :            :         void DecodeBinary(int len, const char* data, int trailing_CRLF);
     128                 :            :         void DecodeQuotedPrintable(int len, const char* data);
     129                 :            :         void DecodeBase64(int len, const char* data);
     130                 :            :         void StartDecodeBase64();
     131                 :            :         void FinishDecodeBase64();
     132                 :            : 
     133                 :            :         int GetDataBuffer();
     134                 :            :         void DataOctet(char ch);
     135                 :            :         void DataOctets(int len, const char* data);
     136                 :            :         void SubmitData(int len, const char* buf);
     137                 :            : 
     138                 :            :         virtual void SubmitHeader(MIME_Header* h);
     139                 :            :         // Submit all headers in member "headers".
     140                 :            :         virtual void SubmitAllHeaders();
     141                 :            : 
     142                 :          0 :         virtual MIME_Entity* NewChildEntity() { return new MIME_Entity(message, this); }
     143                 :            :         void BeginChildEntity();
     144                 :            :         void EndChildEntity();
     145                 :            : 
     146                 :            :         void IllegalFormat(const char* explanation);
     147                 :            :         void IllegalEncoding(const char* explanation);
     148                 :            : 
     149                 :            :         void DebugPrintHeaders();
     150                 :            : 
     151                 :            :         int in_header;
     152                 :            :         int end_of_data;
     153                 :            :         MIME_Multiline* current_header_line;
     154                 :            :         int current_field_type;
     155                 :            :         int need_to_parse_parameters;
     156                 :            : 
     157                 :            :         StringVal* content_type_str;
     158                 :            :         StringVal* content_subtype_str;
     159                 :            :         BroString* content_encoding_str;
     160                 :            :         BroString* multipart_boundary;
     161                 :            : 
     162                 :            :         int content_type, content_subtype, content_encoding;
     163                 :            : 
     164                 :            :         MIME_HeaderList headers;
     165                 :            :         MIME_Entity* parent;
     166                 :            :         MIME_Entity* current_child_entity;
     167                 :            : 
     168                 :            :         Base64Decoder* base64_decoder;
     169                 :            : 
     170                 :            :         int data_buf_length;
     171                 :            :         char* data_buf_data;
     172                 :            :         int data_buf_offset;
     173                 :            : 
     174                 :            :         MIME_Message* message;
     175                 :            : };
     176                 :            : 
     177                 :            : // The reason I separate MIME_Message as an abstract class is to
     178                 :            : // present the *interface* separated from its implementation to
     179                 :            : // generate Bro events.
     180                 :            : 
     181                 :            : class MIME_Message {
     182                 :            : public:
     183                 :        881 :         MIME_Message(Analyzer* arg_analyzer)
     184                 :        881 :                 {
     185                 :            :                 // Cannot initialize top_level entity because we do
     186                 :            :                 // not know its type yet (MIME_Entity / MIME_Mail /
     187                 :            :                 // etc.).
     188                 :        881 :                 top_level = 0;
     189                 :        881 :                 finished = 0;
     190                 :        881 :                 analyzer = arg_analyzer;
     191                 :        881 :                 }
     192                 :            : 
     193                 :        881 :         virtual ~MIME_Message()
     194                 :        881 :                 {
     195 [ -  + ][ #  # ]:        881 :                 if ( ! finished )
                 [ #  # ]
     196                 :          0 :                         internal_error("Done() must be called before destruction");
     197 [ -  + ][ #  # ]:        881 :                 }
                 [ #  # ]
     198                 :            : 
     199                 :        881 :         virtual void Done()     { finished = 1; }
     200                 :            : 
     201                 :        331 :         int Finished() const    { return finished; }
     202                 :            : 
     203                 :      11277 :         virtual void Deliver(int len, const char* data, int trailing_CRLF)
     204                 :            :                 {
     205                 :      11277 :                 top_level->Deliver(len, data, trailing_CRLF);
     206                 :      11277 :                 }
     207                 :            : 
     208                 :        881 :         Analyzer* GetAnalyzer() const   { return analyzer; }
     209                 :            : 
     210                 :            :         // Events generated by MIME_Entity
     211                 :            :         virtual void BeginEntity(MIME_Entity*) = 0;
     212                 :            :         virtual void EndEntity(MIME_Entity*) = 0;
     213                 :            :         virtual void SubmitHeader(MIME_Header* h) = 0;
     214                 :            :         virtual void SubmitAllHeaders(MIME_HeaderList& hlist) = 0;
     215                 :            :         virtual void SubmitData(int len, const char* buf) = 0;
     216                 :            :         virtual int RequestBuffer(int* plen, char** pbuf) = 0;
     217                 :            :         virtual void SubmitEvent(int event_type, const char* detail) = 0;
     218                 :            : 
     219                 :            : protected:
     220                 :            :         Analyzer* analyzer;
     221                 :            : 
     222                 :            :         MIME_Entity* top_level;
     223                 :            :         int finished;
     224                 :            : 
     225                 :            :         RecordVal* BuildHeaderVal(MIME_Header* h);
     226                 :            :         TableVal* BuildHeaderTable(MIME_HeaderList& hlist);
     227                 :            : };
     228                 :            : 
     229                 :            : class MIME_Mail : public MIME_Message {
     230                 :            : public:
     231                 :            :         MIME_Mail(Analyzer* mail_conn, int buf_size = 0);
     232                 :            :         ~MIME_Mail();
     233                 :            :         void Done();
     234                 :            : 
     235                 :            :         void BeginEntity(MIME_Entity* entity);
     236                 :            :         void EndEntity(MIME_Entity* entity);
     237                 :            :         void SubmitHeader(MIME_Header* h);
     238                 :            :         void SubmitAllHeaders(MIME_HeaderList& hlist);
     239                 :            :         void SubmitData(int len, const char* buf);
     240                 :            :         int RequestBuffer(int* plen, char** pbuf);
     241                 :            :         void SubmitAllData();
     242                 :            :         void SubmitEvent(int event_type, const char* detail);
     243                 :            : 
     244                 :            : protected:
     245                 :            :         int min_overlap_length;
     246                 :            :         int max_chunk_length;
     247                 :            :         int buffer_start;
     248                 :            :         int data_start;
     249                 :            :         int buffer_offset;
     250                 :            :         int compute_content_hash;
     251                 :            :         int content_hash_length;
     252                 :            :         md5_state_t md5_hash;
     253                 :            :         vector<const BroString*> entity_content;
     254                 :            :         vector<const BroString*> all_content;
     255                 :            : 
     256                 :            :         BroString* data_buffer;
     257                 :            : };
     258                 :            : 
     259                 :            : 
     260                 :            : extern int is_null_data_chunk(data_chunk_t b);
     261                 :            : extern StringVal* new_string_val(int length, const char* data);
     262                 :            : extern StringVal* new_string_val(const char* data, const char* end_of_data);
     263                 :            : extern StringVal* new_string_val(const data_chunk_t buf);
     264                 :            : extern int fputs(data_chunk_t b, FILE* fp);
     265                 :            : extern int strcasecmp_n(data_chunk_t s, const char* t);
     266                 :            : extern int is_lws(char ch);
     267                 :            : extern int MIME_is_field_name_char(char ch);
     268                 :            : extern int MIME_count_leading_lws(int len, const char* data);
     269                 :            : extern int MIME_count_trailing_lws(int len, const char* data);
     270                 :            : extern int MIME_skip_comments(int len, const char* data);
     271                 :            : extern int MIME_skip_lws_comments(int len, const char* data);
     272                 :            : extern int MIME_get_token(int len, const char* data, data_chunk_t* token);
     273                 :            : extern int MIME_get_slash_token_pair(int len, const char* data, data_chunk_t* first, data_chunk_t* second);
     274                 :            : extern int MIME_get_value(int len, const char* data, BroString*& buf);
     275                 :            : extern int MIME_get_field_name(int len, const char* data, data_chunk_t* name);
     276                 :            : extern BroString* MIME_decode_quoted_pairs(data_chunk_t buf);
     277                 :            : 
     278                 :            : #endif

Generated by: LCOV version 1.8