Branch data Line data Source code
1 : : // $Id: DCE_RPC.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 dce_rpc_h
6 : : #define dce_rpc_h
7 : :
8 : : // NOTE: This is a somewhat crude analyzer for DCE/RPC (used on Microsoft
9 : : // Windows systems) and shouldn't be considered as stable.
10 : :
11 : : #include "NetVar.h"
12 : : #include "TCP.h"
13 : :
14 : : #include "dce_rpc_simple_pac.h"
15 : :
16 : 0 : class UUID {
17 : : public:
18 : : UUID();
19 : : UUID(const u_char data[16]);
20 : : UUID(const binpac::bytestring &uuid);
21 : : UUID(const char* s);
22 : :
23 : 0 : const char* to_string() const { return s.c_str(); }
24 : 0 : const string& str() const { return s; }
25 : : bool operator==(const UUID& u) const
26 : : { return s == u.str(); }
27 : 0 : bool operator<(const UUID& u) const
28 : 0 : { return s < u.str(); }
29 : :
30 : : protected:
31 : : u_char data[16];
32 : : string s;
33 : : };
34 : :
35 : : const char* uuid_to_string(const u_char* uuid_data);
36 : :
37 : : struct dce_rpc_endpoint_addr {
38 : : // All fields are in host byteorder.
39 : : uint32 addr;
40 : : u_short port;
41 : : TransportProto proto;
42 : :
43 : 0 : dce_rpc_endpoint_addr()
44 : : {
45 : 0 : addr = 0;
46 : 0 : port = 0;
47 : 0 : proto = TRANSPORT_UNKNOWN;
48 : 0 : }
49 : :
50 : 0 : bool is_valid_addr() const
51 [ # # ][ # # ]: 0 : { return addr != 0 && port != 0 && proto != TRANSPORT_UNKNOWN; }
[ # # ]
52 : :
53 : 0 : bool operator<(dce_rpc_endpoint_addr const &e) const
54 : : {
55 [ # # ]: 0 : if ( addr != e.addr )
56 : 0 : return addr < e.addr;
57 [ # # ]: 0 : if ( proto != e.proto )
58 : 0 : return proto < e.proto;
59 [ # # ]: 0 : if ( port != e.port )
60 : 0 : return port < e.port;
61 : :
62 : 0 : return false;
63 : : }
64 : :
65 : 0 : string to_string() const
66 : : {
67 : : static char buf[128];
68 : : snprintf(buf, sizeof(buf), "%s/%d/%s",
69 : : dotted_addr(htonl(addr)), port,
70 : : proto == TRANSPORT_TCP ? "tcp" :
71 [ # # ][ # # ]: 0 : (proto == TRANSPORT_UDP ? "udp" : "?"));
72 : :
73 : 0 : return string(buf);
74 : : }
75 : : };
76 : :
77 : : /*
78 : : enum DCE_RPC_PTYPE {
79 : : DCE_RPC_REQUEST, DCE_RPC_PING, DCE_RPC_RESPONSE, DCE_RPC_FAULT,
80 : : DCE_RPC_WORKING, DCE_RPC_NOCALL, DCE_RPC_REJECT, DCE_RPC_ACK,
81 : : DCE_RPC_CL_CANCEL, DCE_RPC_FACK, DCE_RPC_CANCEL_ACK, DCE_RPC_BIND,
82 : : DCE_RPC_BIND_ACK, DCE_RPC_BIND_NAK, DCE_RPC_ALTER_CONTEXT,
83 : : DCE_RPC_ALTER_CONTEXT_RESP, DCE_RPC_SHUTDOWN, DCE_RPC_CO_CANCEL,
84 : : DCE_RPC_ORPHANED,
85 : : };
86 : : */
87 : :
88 : : #define DCE_RPC_HEADER_LENGTH 16
89 : :
90 : : class DCE_RPC_Header {
91 : : public:
92 : : DCE_RPC_Header(Analyzer* a, const u_char* bytes);
93 : :
94 : : BroEnum::dce_rpc_ptype PTYPE() const { return ptype; }
95 : 0 : int FragLen() const { return frag_len; }
96 : 0 : int LittleEndian() const { return bytes[4] >> 4; }
97 : : bool Fragmented() const { return fragmented; }
98 : :
99 : 0 : void Weird(const char* msg) { analyzer->Weird(msg); }
100 : 0 : void SetBytes(const u_char* b) { bytes = b; }
101 : :
102 : : protected:
103 : : Analyzer* analyzer;
104 : : const u_char* bytes;
105 : : BroEnum::dce_rpc_ptype ptype;
106 : : int frag_len;
107 : : bool fragmented;
108 : : };
109 : :
110 : : // Create a general DCE_RPC_Session class so that it can be used in
111 : : // case the RPC conversation is tunneled through other connections,
112 : : // e.g. through an SMB session.
113 : :
114 : : class DCE_RPC_Session {
115 : : public:
116 : : DCE_RPC_Session(Analyzer* a);
117 [ # # ][ # # ]: 0 : virtual ~DCE_RPC_Session() {}
118 : : virtual void DeliverPDU(int is_orig, int len, const u_char* data);
119 : :
120 : : static bool LooksLikeRPC(int len, const u_char* msg);
121 : 3 : static bool any_dce_rpc_event()
122 [ + - ][ + - ]: 3 : { return dce_rpc_message || dce_rpc_bind || dce_rpc_request; }
[ - + ]
123 : :
124 : : protected:
125 : : void DeliverBind(const binpac::DCE_RPC_Simple::DCE_RPC_PDU* pdu);
126 : : void DeliverRequest(const binpac::DCE_RPC_Simple::DCE_RPC_PDU* pdu);
127 : : void DeliverResponse(const binpac::DCE_RPC_Simple::DCE_RPC_PDU* pdu);
128 : :
129 : : void DeliverEpmapperRequest(
130 : : const binpac::DCE_RPC_Simple::DCE_RPC_PDU* pdu,
131 : : const binpac::DCE_RPC_Simple::DCE_RPC_Request* req);
132 : : void DeliverEpmapperResponse(
133 : : const binpac::DCE_RPC_Simple::DCE_RPC_PDU* pdu,
134 : : const binpac::DCE_RPC_Simple::DCE_RPC_Response* resp);
135 : : void DeliverEpmapperMapResponse(
136 : : const binpac::DCE_RPC_Simple::DCE_RPC_PDU* pdu,
137 : : const binpac::DCE_RPC_Simple::DCE_RPC_Response* resp);
138 : :
139 : : Analyzer* analyzer;
140 : : UUID if_uuid;
141 : : BroEnum::dce_rpc_if_id if_id;
142 : : int opnum;
143 : 0 : struct {
144 : : dce_rpc_endpoint_addr addr;
145 : : UUID uuid;
146 : : } mapped;
147 : : };
148 : :
149 : : class Contents_DCE_RPC_Analyzer : public TCP_SupportAnalyzer {
150 : : public:
151 : : Contents_DCE_RPC_Analyzer(Connection* conn, bool orig, DCE_RPC_Session* session,
152 : : bool speculative);
153 : : ~Contents_DCE_RPC_Analyzer();
154 : :
155 : : protected:
156 : : virtual void DeliverStream(int len, const u_char* data, bool orig);
157 : : virtual void DeliverPDU(int len, const u_char* data);
158 : :
159 : : void InitState();
160 : :
161 : : int speculation;
162 : : u_char* msg_buf;
163 : : int msg_len;
164 : : int buf_n; // number of bytes in msg_buf
165 : : int buf_len; // size off msg_buf
166 : : DCE_RPC_Header* hdr;
167 : :
168 : : bool ParseHeader();
169 : :
170 : : DCE_RPC_Session* session;
171 : : };
172 : :
173 : : class DCE_RPC_Analyzer : public TCP_ApplicationAnalyzer {
174 : : public:
175 : : DCE_RPC_Analyzer(Connection* conn, bool speculative = false);
176 : : ~DCE_RPC_Analyzer();
177 : :
178 : 0 : static Analyzer* InstantiateAnalyzer(Connection* conn)
179 : 0 : { return new DCE_RPC_Analyzer(conn); }
180 : :
181 : 1 : static bool Available()
182 : 1 : { return DCE_RPC_Session::any_dce_rpc_event(); }
183 : :
184 : : protected:
185 : : DCE_RPC_Session* session;
186 : : bool speculative;
187 : : };
188 : :
189 : : #endif /* dce_rpc_h */
|