Branch data Line data Source code
1 : : // $Id: DCE_RPC.cc 6916 2009-09-24 20:48:36Z vern $
2 : : //
3 : : // See the file "COPYING" in the main distribution directory for copyright.
4 : :
5 : : #include "config.h"
6 : :
7 : : #include <stdlib.h>
8 : : #include <string>
9 : : #include <map>
10 : :
11 : : using namespace std;
12 : :
13 : : #include "DCE_RPC.h"
14 : : #include "Sessions.h"
15 : : #include "DPM.h"
16 : :
17 : : #define xbyte(b, n) (((const u_char*) (b))[n])
18 : :
19 : : #define extract_uint16(little_endian, bytes) \
20 : : ((little_endian) ? \
21 : : uint16(xbyte(bytes, 0)) | ((uint16(xbyte(bytes, 1))) << 8) : \
22 : : uint16(xbyte(bytes, 1)) | ((uint16(xbyte(bytes, 0))) << 8))
23 : :
24 : : static int uuid_index[] = {
25 : : 3, 2, 1, 0,
26 : : 5, 4, 7, 6,
27 : : 8, 9, 10, 11,
28 : : 12, 13, 14, 15
29 : : };
30 : :
31 : 0 : const char* uuid_to_string(const u_char* uuid_data)
32 : : {
33 : : static char s[1024];
34 : 0 : char* sp = s;
35 : :
36 [ # # ]: 0 : for ( int i = 0; i < 16; ++i )
37 : : {
38 [ # # ][ # # ]: 0 : if ( i == 4 || i == 6 || i == 8 || i == 10 )
[ # # ][ # # ]
39 : 0 : sp += snprintf(sp, s + sizeof(s) - sp, "-");
40 : :
41 : 0 : int j = uuid_index[i];
42 : 0 : sp += snprintf(sp, s + sizeof(s) - sp, "%02x", uuid_data[j]);
43 : : }
44 : :
45 : 0 : return s;
46 : : }
47 : :
48 : 0 : UUID::UUID()
49 : : {
50 : 0 : memset(data, 0, 16);
51 : 0 : s = uuid_to_string(data);
52 : 0 : }
53 : :
54 : 0 : UUID::UUID(const u_char d[16])
55 : : {
56 : 0 : memcpy(data, d, 16);
57 : 0 : s = uuid_to_string(data);
58 : 0 : }
59 : :
60 : 0 : UUID::UUID(const binpac::bytestring& uuid)
61 : : {
62 [ # # # # ]: 0 : if ( uuid.length() != 16 )
63 : 0 : internal_error("UUID length error");
64 : 0 : memcpy(data, uuid.begin(), 16);
65 : 0 : s = uuid_to_string(data);
66 : 0 : }
67 : :
68 : 0 : UUID::UUID(const char* str)
69 : : {
70 : 0 : s = string(str);
71 : 0 : const char* sp = str;
72 : : int i;
73 [ # # ][ # # ]: 0 : for ( i = 0; i < 16; ++i )
74 : : {
75 [ # # ][ # # ]: 0 : if ( *sp == '-' )
76 : 0 : ++sp;
77 [ # # ][ # # ]: 0 : if ( ! *sp || ! *(sp+1) )
[ # # ][ # # ]
78 : 0 : break;
79 : :
80 : : data[uuid_index[i]] =
81 : 0 : (u_char) (decode_hex(*sp) * 16 + decode_hex(*(sp+1)));
82 : : }
83 : :
84 [ # # ][ # # ]: 0 : if ( i != 16 )
85 : 0 : internal_error(fmt("invalid UUID string: %s", str));
86 : 0 : }
87 : :
88 : : typedef map<UUID, BroEnum::dce_rpc_if_id> uuid_map_t;
89 : :
90 : 0 : static uuid_map_t& well_known_uuid_map()
91 : : {
92 [ # # ][ # # ]: 0 : static uuid_map_t the_map;
[ # # ]
93 : : static bool initialized = false;
94 : :
95 [ # # ]: 0 : if ( initialized )
96 : 0 : return the_map;
97 : :
98 : : using namespace BroEnum;
99 : :
100 : 0 : the_map[UUID("e1af8308-5d1f-11c9-91a4-08002b14a0fa")] = DCE_RPC_epmapper;
101 : :
102 : 0 : the_map[UUID("afa8bd80-7d8a-11c9-bef4-08002b102989")] = DCE_RPC_mgmt;
103 : :
104 : : // It's said that the following interfaces are merely aliases.
105 : 0 : the_map[UUID("12345778-1234-abcd-ef00-0123456789ab")] = DCE_RPC_lsarpc;
106 : 0 : the_map[UUID("12345678-1234-abcd-ef00-01234567cffb")] = DCE_RPC_netlogon;
107 : 0 : the_map[UUID("12345778-1234-abcd-ef00-0123456789ac")] = DCE_RPC_samr;
108 : :
109 : : // The next group of aliases.
110 : 0 : the_map[UUID("4b324fc8-1670-01d3-1278-5a47bf6ee188")] = DCE_RPC_srvsvc;
111 : 0 : the_map[UUID("12345678-1234-abcd-ef00-0123456789ab")] = DCE_RPC_spoolss;
112 : 0 : the_map[UUID("45f52c28-7f9f-101a-b52b-08002b2efabe")] = DCE_RPC_winspipe;
113 : 0 : the_map[UUID("6bffd098-a112-3610-9833-46c3f87e345a")] = DCE_RPC_wkssvc;
114 : :
115 : : // DRS - NT directory replication service.
116 : 0 : the_map[UUID("e3514235-4b06-11d1-ab04-00c04fc2dcd2")] = DCE_RPC_drs;
117 : :
118 : : // "The IOXIDResolver RPC interface (formerly known as
119 : : // IObjectExporter) is remotely used to reach the local object
120 : : // resolver (OR)."
121 : 0 : the_map[UUID("99fcfec4-5260-101b-bbcb-00aa0021347a")] = DCE_RPC_oxid;
122 : :
123 : 0 : the_map[UUID("3919286a-b10c-11d0-9ba8-00c04fd92ef5")] = DCE_RPC_lsa_ds;
124 : :
125 : 0 : the_map[UUID("000001a0-0000-0000-c000-000000000046")] = DCE_RPC_ISCMActivator;
126 : :
127 : 0 : initialized = true;
128 : 0 : return the_map;
129 : : }
130 : :
131 : : // Used to remember mapped DCE/RPC endpoints and parse the follow-up
132 : : // connections as DCE/RPC sessions.
133 : 6 : map<dce_rpc_endpoint_addr, UUID> dce_rpc_endpoints;
134 : :
135 : 0 : static bool is_mapped_dce_rpc_endpoint(const dce_rpc_endpoint_addr& addr)
136 : : {
137 : 0 : return dce_rpc_endpoints.find(addr) != dce_rpc_endpoints.end();
138 : : }
139 : :
140 : 0 : bool is_mapped_dce_rpc_endpoint(const ConnID* id, TransportProto proto)
141 : : {
142 : : #ifdef BROv6
143 : : if ( ! is_v4_addr(id->dst_addr) )
144 : : return false;
145 : : #endif
146 : 0 : dce_rpc_endpoint_addr addr;
147 : 0 : addr.addr = ntohl(to_v4_addr(id->dst_addr));
148 : 0 : addr.port = ntohs(id->dst_port);
149 : 0 : addr.proto = proto;
150 : :
151 : 0 : return is_mapped_dce_rpc_endpoint(addr);
152 : : }
153 : :
154 : : static void add_dce_rpc_endpoint(const dce_rpc_endpoint_addr& addr,
155 : 0 : const UUID& uuid)
156 : : {
157 : 0 : DEBUG_MSG("Adding endpoint %s @ %s\n",
158 : : uuid.to_string(), addr.to_string().c_str());
159 : 0 : dce_rpc_endpoints[addr] = uuid;
160 : :
161 : : // FIXME: Once we can pass the cookie to the analyzer, we can get rid
162 : : // of the dce_rpc_endpoints table.
163 : : // FIXME: Don't hard-code the timeout.
164 : :
165 : : // Convert the address to a v4/v6 address (depending on how
166 : : // Bro was configured). This is all based on the address currently
167 : : // being a 32-bit host-order v4 address.
168 : 0 : AddrVal a(htonl(addr.addr));
169 : 0 : const addr_type at = a.AsAddr();
170 : : dpm->ExpectConnection(0, at, addr.port, addr.proto,
171 : 0 : AnalyzerTag::DCE_RPC, 5 * 60, 0);
172 : 0 : }
173 : :
174 : 0 : DCE_RPC_Header::DCE_RPC_Header(Analyzer* a, const u_char* b)
175 : : {
176 : 0 : analyzer = a;
177 : 0 : bytes = b;
178 : :
179 : : // This checks whether it's both the first fragment *and*
180 : : // the last fragment.
181 [ # # ][ # # ]: 0 : if ( (bytes[3] & 0x3) != 0x3 )
182 : : {
183 : 0 : fragmented = 1;
184 : 0 : Weird("Fragmented DCE/RPC message");
185 : : }
186 : : else
187 : 0 : fragmented = 0;
188 : :
189 : 0 : ptype = (BroEnum::dce_rpc_ptype) bytes[2];
190 [ # # ][ # # ]: 0 : frag_len = extract_uint16(LittleEndian(), bytes + 8);
191 : 0 : }
192 : :
193 : 0 : DCE_RPC_Session::DCE_RPC_Session(Analyzer* a)
194 : : : analyzer(a),
195 : : if_uuid("00000000-0000-0000-0000-000000000000"),
196 : 0 : if_id(BroEnum::DCE_RPC_unknown_if)
197 : : {
198 : 0 : opnum = -1;
199 : 0 : }
200 : :
201 : 0 : bool DCE_RPC_Session::LooksLikeRPC(int len, const u_char* msg)
202 : : {
203 : : // if ( ! is_IPC )
204 : : // return false;
205 : :
206 : : try
207 : : {
208 : 0 : binpac::DCE_RPC_Simple::DCE_RPC_Header h;
209 : 0 : h.Parse(msg, msg + len);
210 [ # # # # ]: 0 : if ( h.rpc_vers() == 5 && h.rpc_vers_minor() == 0 )
[ # # ]
211 : : {
212 [ # # ]: 0 : if ( h.frag_length() == len )
213 : 0 : return true;
214 : : else
215 : : {
216 : 0 : DEBUG_MSG("length mismatch: %d != %d\n",
217 : : h.frag_length(), len);
218 : 0 : return false;
219 : : }
220 [ # # ]: 0 : }
221 : : }
222 : 0 : catch ( const binpac::Exception& )
223 : : {
224 : : // do nothing
225 : : }
226 : :
227 : 0 : return false;
228 : : }
229 : :
230 : 0 : void DCE_RPC_Session::DeliverPDU(int is_orig, int len, const u_char* data)
231 : : {
232 [ # # ]: 0 : if ( dce_rpc_message )
233 : : {
234 : 0 : val_list* vl = new val_list;
235 : 0 : vl->append(analyzer->BuildConnVal());
236 : 0 : vl->append(new Val(is_orig, TYPE_BOOL));
237 : 0 : vl->append(new EnumVal(data[2], enum_dce_rpc_ptype));
238 : 0 : vl->append(new StringVal(len, (const char*) data));
239 : :
240 : 0 : analyzer->ConnectionEvent(dce_rpc_message, vl);
241 : : }
242 : :
243 : : try
244 : : {
245 : : // TODO: handle incremental input
246 : 0 : binpac::DCE_RPC_Simple::DCE_RPC_PDU pdu;
247 : 0 : pdu.Parse(data, data + len);
248 : :
249 [ # # # # ]: 0 : switch ( pdu.header()->PTYPE() ) {
250 : : case binpac::DCE_RPC_Simple::DCE_RPC_BIND:
251 : : case binpac::DCE_RPC_Simple::DCE_RPC_ALTER_CONTEXT:
252 : 0 : DeliverBind(&pdu);
253 : 0 : break;
254 : :
255 : : case binpac::DCE_RPC_Simple::DCE_RPC_REQUEST:
256 : 0 : DeliverRequest(&pdu);
257 : 0 : break;
258 : :
259 : : case binpac::DCE_RPC_Simple::DCE_RPC_RESPONSE:
260 : 0 : DeliverResponse(&pdu);
261 : : break;
262 : 0 : }
263 : : }
264 : 0 : catch ( const binpac::Exception& e )
265 : : {
266 : 0 : analyzer->Weird(e.msg().c_str());
267 : : }
268 : 0 : }
269 : :
270 : 0 : void DCE_RPC_Session::DeliverBind(const binpac::DCE_RPC_Simple::DCE_RPC_PDU* pdu)
271 : : {
272 : 0 : binpac::DCE_RPC_Simple::DCE_RPC_Bind* bind = pdu->body()->bind();
273 : :
274 [ # # ]: 0 : for ( int i = 0; i < bind->p_context_elem()->n_context_elem(); ++i )
275 : : {
276 : : binpac::DCE_RPC_Simple::p_cont_elem_t* elem =
277 : 0 : (*bind->p_context_elem()->p_cont_elem())[i];
278 : :
279 : 0 : if_uuid = UUID(elem->abstract_syntax()->if_uuid().begin());
280 : : uuid_map_t::const_iterator uuid_it =
281 : 0 : well_known_uuid_map().find(if_uuid);
282 : :
283 [ # # ]: 0 : if ( uuid_it == well_known_uuid_map().end() )
284 : : {
285 : : #ifdef DEBUG
286 : : // conn->Weird(fmt("Unknown DCE_RPC interface %s",
287 : : // if_uuid.to_string()));
288 : : #endif
289 : 0 : if_id = BroEnum::DCE_RPC_unknown_if;
290 : : }
291 : : else
292 : 0 : if_id = uuid_it->second;
293 : :
294 [ # # ]: 0 : if ( dce_rpc_bind )
295 : : {
296 : 0 : val_list* vl = new val_list;
297 : 0 : vl->append(analyzer->BuildConnVal());
298 : 0 : vl->append(new StringVal(if_uuid.to_string()));
299 : : // vl->append(new EnumVal(if_id, enum_dce_rpc_if_id));
300 : :
301 : 0 : analyzer->ConnectionEvent(dce_rpc_bind, vl);
302 : : }
303 : : }
304 : 0 : }
305 : :
306 : 0 : void DCE_RPC_Session::DeliverRequest(const binpac::DCE_RPC_Simple::DCE_RPC_PDU* pdu)
307 : : {
308 : 0 : binpac::DCE_RPC_Simple::DCE_RPC_Request* req = pdu->body()->request();
309 : :
310 : 0 : opnum = req->opnum();
311 : :
312 [ # # ]: 0 : if ( dce_rpc_request )
313 : : {
314 : 0 : val_list* vl = new val_list;
315 : 0 : vl->append(analyzer->BuildConnVal());
316 : 0 : vl->append(new Val(opnum, TYPE_COUNT));
317 : : vl->append(new StringVal(req->stub().length(),
318 : 0 : (const char*) req->stub().begin()));
319 : :
320 : 0 : analyzer->ConnectionEvent(dce_rpc_request, vl);
321 : : }
322 : :
323 [ # # ]: 0 : switch ( if_id ) {
324 : : case BroEnum::DCE_RPC_epmapper:
325 : 0 : DeliverEpmapperRequest(pdu, req);
326 : : break;
327 : :
328 : : default:
329 : : break;
330 : : }
331 : 0 : }
332 : :
333 : 0 : void DCE_RPC_Session::DeliverResponse(const binpac::DCE_RPC_Simple::DCE_RPC_PDU* pdu)
334 : : {
335 : 0 : binpac::DCE_RPC_Simple::DCE_RPC_Response* resp = pdu->body()->response();
336 : :
337 [ # # ]: 0 : if ( dce_rpc_response )
338 : : {
339 : 0 : val_list* vl = new val_list;
340 : 0 : vl->append(analyzer->BuildConnVal());
341 : 0 : vl->append(new Val(opnum, TYPE_COUNT));
342 : : vl->append(new StringVal(resp->stub().length(),
343 : 0 : (const char*) resp->stub().begin()));
344 : 0 : analyzer->ConnectionEvent(dce_rpc_response, vl);
345 : : }
346 : :
347 [ # # ]: 0 : switch ( if_id ) {
348 : : case BroEnum::DCE_RPC_epmapper:
349 : 0 : DeliverEpmapperResponse(pdu, resp);
350 : : break;
351 : :
352 : : default:
353 : : break;
354 : : }
355 : 0 : }
356 : :
357 : : void DCE_RPC_Session::DeliverEpmapperRequest(
358 : : const binpac::DCE_RPC_Simple::DCE_RPC_PDU* /* pdu */,
359 : 0 : const binpac::DCE_RPC_Simple::DCE_RPC_Request* /* req */)
360 : : {
361 : : // DEBUG_MSG("Epmapper request opnum = %d\n", req->opnum());
362 : : // ### TODO(rpang): generate an event on epmapper request
363 : 0 : }
364 : :
365 : : void DCE_RPC_Session::DeliverEpmapperResponse(
366 : : const binpac::DCE_RPC_Simple::DCE_RPC_PDU* pdu,
367 : 0 : const binpac::DCE_RPC_Simple::DCE_RPC_Response* resp)
368 : : {
369 : : // DEBUG_MSG("Epmapper request opnum = %d\n", req->opnum());
370 [ # # ]: 0 : switch ( opnum ) {
371 : : case 3: // Map
372 : 0 : DeliverEpmapperMapResponse(pdu, resp);
373 : : break;
374 : : }
375 : 0 : }
376 : :
377 : :
378 : : void DCE_RPC_Session::DeliverEpmapperMapResponse(
379 : : const binpac::DCE_RPC_Simple::DCE_RPC_PDU* pdu,
380 : 0 : const binpac::DCE_RPC_Simple::DCE_RPC_Response* resp)
381 : : {
382 : : try
383 : : {
384 : 0 : binpac::DCE_RPC_Simple::epmapper_map_resp epm_resp;
385 : :
386 : : epm_resp.Parse(resp->stub().begin(), resp->stub().end(),
387 : 0 : pdu->byteorder());
388 : :
389 [ # # ]: 0 : for ( unsigned int twr_i = 0;
390 : : twr_i < epm_resp.towers()->actual_count(); ++twr_i )
391 : : {
392 : : binpac::DCE_RPC_Simple::epm_tower* twr =
393 : 0 : (*epm_resp.towers()->towers())[twr_i]->tower();
394 : :
395 : 0 : mapped.addr = dce_rpc_endpoint_addr();
396 : 0 : mapped.uuid = UUID();
397 : :
398 [ # # ]: 0 : for ( int floor_i = 0; floor_i < twr->num_floors();
399 : : ++floor_i )
400 : : {
401 : : binpac::DCE_RPC_Simple::epm_floor* floor =
402 : 0 : (*twr->floors())[floor_i];
403 : :
404 [ # # # # : 0 : switch ( floor->protocol() ) {
# ]
405 : : case binpac::DCE_RPC_Simple::EPM_PROTOCOL_UUID:
406 [ # # ]: 0 : if ( floor_i == 0 )
407 : 0 : mapped.uuid = UUID(floor->lhs()->data()->uuid()->if_uuid());
408 : 0 : break;
409 : :
410 : : case binpac::DCE_RPC_Simple::EPM_PROTOCOL_TCP:
411 : : mapped.addr.port =
412 : 0 : floor->rhs()->data()->tcp();
413 : 0 : mapped.addr.proto = TRANSPORT_TCP;
414 : 0 : break;
415 : :
416 : : case binpac::DCE_RPC_Simple::EPM_PROTOCOL_UDP:
417 : : mapped.addr.port =
418 : 0 : floor->rhs()->data()->udp();
419 : 0 : mapped.addr.proto = TRANSPORT_UDP;
420 : 0 : break;
421 : :
422 : : case binpac::DCE_RPC_Simple::EPM_PROTOCOL_IP:
423 : : mapped.addr.addr =
424 : 0 : floor->rhs()->data()->ip();
425 : : break;
426 : : }
427 : : }
428 : :
429 [ # # ]: 0 : if ( mapped.addr.is_valid_addr() )
430 : 0 : add_dce_rpc_endpoint(mapped.addr, mapped.uuid);
431 : :
432 [ # # ]: 0 : if ( epm_map_response )
433 : : {
434 : 0 : val_list* vl = new val_list;
435 : 0 : vl->append(analyzer->BuildConnVal());
436 : 0 : vl->append(new StringVal(mapped.uuid.to_string()));
437 : 0 : vl->append(new PortVal(mapped.addr.port, mapped.addr.proto));
438 : 0 : vl->append(new AddrVal(htonl(mapped.addr.addr)));
439 : :
440 : 0 : analyzer->ConnectionEvent(epm_map_response, vl);
441 : : }
442 : 0 : }
443 : : }
444 : 0 : catch ( const binpac::Exception& e )
445 : : {
446 : 0 : analyzer->Weird(e.msg().c_str());
447 : : }
448 : 0 : }
449 : :
450 : : Contents_DCE_RPC_Analyzer::Contents_DCE_RPC_Analyzer(Connection* conn,
451 : 0 : bool orig, DCE_RPC_Session* arg_session, bool speculative)
452 : 0 : : TCP_SupportAnalyzer(AnalyzerTag::Contents_DCE_RPC, conn, orig)
453 : : {
454 : 0 : session = arg_session;
455 : 0 : msg_buf = 0;
456 : 0 : buf_len = 0;
457 [ # # ][ # # ]: 0 : speculation = speculative ? 0 : 1;
458 : :
459 : 0 : InitState();
460 : 0 : }
461 : :
462 : 0 : void Contents_DCE_RPC_Analyzer::InitState()
463 : : {
464 : : // Allocate space for header.
465 [ # # ]: 0 : if ( ! msg_buf )
466 : : {
467 : 0 : buf_len = DCE_RPC_HEADER_LENGTH;
468 : 0 : msg_buf = new u_char[buf_len];
469 : : }
470 : :
471 : 0 : buf_n = 0;
472 : 0 : msg_len = 0;
473 : 0 : hdr = 0;
474 : 0 : }
475 : :
476 : 0 : Contents_DCE_RPC_Analyzer::~Contents_DCE_RPC_Analyzer()
477 : : {
478 [ # # ][ # # ]: 0 : delete [] msg_buf;
[ # # ]
479 : 0 : delete hdr;
480 [ # # ][ # # ]: 0 : }
[ # # ]
481 : :
482 : 0 : void Contents_DCE_RPC_Analyzer::DeliverStream(int len, const u_char* data, bool orig)
483 : : {
484 : 0 : TCP_SupportAnalyzer::DeliverStream(len, data, orig);
485 : :
486 : : TCP_Analyzer* tcp =
487 : 0 : static_cast<TCP_ApplicationAnalyzer*>(Parent())->TCP();
488 : :
489 [ # # # # ]: 0 : if ( tcp->HadGap(orig) || tcp->IsPartial() )
[ # # ]
490 : 0 : return;
491 : :
492 [ # # ]: 0 : if ( speculation == 0 ) // undecided
493 : : {
494 [ # # ]: 0 : if ( ! DCE_RPC_Session::LooksLikeRPC(len, data) )
495 : 0 : speculation = -1;
496 : : else
497 : 0 : speculation = 1;
498 : : }
499 : :
500 [ # # ]: 0 : if ( speculation < 0 )
501 : 0 : return;
502 : :
503 [ # # ]: 0 : ASSERT(buf_len >= DCE_RPC_HEADER_LENGTH);
504 [ # # ]: 0 : while ( len > 0 )
505 : : {
506 [ # # ]: 0 : if ( buf_n < DCE_RPC_HEADER_LENGTH )
507 : : {
508 [ # # ][ # # ]: 0 : while ( buf_n < DCE_RPC_HEADER_LENGTH && len > 0 )
509 : : {
510 : 0 : msg_buf[buf_n] = *data;
511 : 0 : ++buf_n; ++data; --len;
512 : : }
513 : :
514 [ # # ]: 0 : if ( buf_n < DCE_RPC_HEADER_LENGTH )
515 : 0 : break;
516 : : else
517 : : {
518 [ # # ]: 0 : if ( ! ParseHeader() )
519 : 0 : return;
520 : : }
521 : : }
522 : :
523 [ # # ][ # # ]: 0 : while ( buf_n < msg_len && len > 0 )
524 : : {
525 : 0 : msg_buf[buf_n] = *data;
526 : 0 : ++buf_n; ++data; --len;
527 : : }
528 : :
529 [ # # ]: 0 : if ( buf_n < msg_len )
530 : 0 : break;
531 : : else
532 : : {
533 [ # # ]: 0 : if ( msg_len > 0 )
534 : 0 : DeliverPDU(msg_len, msg_buf);
535 : : // Reset for next message
536 : 0 : InitState();
537 : : }
538 : : }
539 : : }
540 : :
541 : 0 : void Contents_DCE_RPC_Analyzer::DeliverPDU(int len, const u_char* data)
542 : : {
543 : 0 : session->DeliverPDU(IsOrig(), len, data);
544 : 0 : }
545 : :
546 : 0 : bool Contents_DCE_RPC_Analyzer::ParseHeader()
547 : : {
548 : 0 : delete hdr;
549 : 0 : hdr = 0;
550 : :
551 [ # # ]: 0 : if ( msg_buf[0] != 5 ) // DCE/RPC version
552 : : {
553 : 0 : Conn()->Weird("DCE/RPC_version_error (non-DCE/RPC?)");
554 : 0 : Conn()->SetSkip(1);
555 : 0 : msg_len = 0;
556 : 0 : return false;
557 : : }
558 : :
559 : 0 : hdr = new DCE_RPC_Header(this, msg_buf);
560 : :
561 : 0 : msg_len = hdr->FragLen();
562 [ # # ]: 0 : if ( msg_len > buf_len )
563 : : {
564 : 0 : u_char* new_msg_buf = new u_char[msg_len];
565 : 0 : memcpy(new_msg_buf, msg_buf, buf_n);
566 [ # # ]: 0 : delete [] msg_buf;
567 : 0 : buf_len = msg_len;
568 : 0 : msg_buf = new_msg_buf;
569 : 0 : hdr->SetBytes(new_msg_buf);
570 : : }
571 : :
572 : 0 : return true;
573 : : }
574 : :
575 : 0 : DCE_RPC_Analyzer::DCE_RPC_Analyzer(Connection* conn, bool arg_speculative)
576 : 0 : : TCP_ApplicationAnalyzer(AnalyzerTag::DCE_RPC, conn)
577 : : {
578 : 0 : session = new DCE_RPC_Session(this);
579 : 0 : speculative = arg_speculative;
580 : :
581 : : AddSupportAnalyzer(new Contents_DCE_RPC_Analyzer(conn, true, session,
582 : 0 : speculative));
583 : : AddSupportAnalyzer(new Contents_DCE_RPC_Analyzer(conn, false, session,
584 : 0 : speculative));
585 : 0 : }
586 : :
587 : 0 : DCE_RPC_Analyzer::~DCE_RPC_Analyzer()
588 : : {
589 [ # # ][ # # ]: 0 : delete session;
[ # # ]
590 [ + - ][ + - ]: 6 : }
[ # # ][ # # ]
[ # # ]
|