Wireshark-dev: [Wireshark-dev] [PATCH] Outlook anywhere: ncacn_http support
From: Julien Kerihuel <j.kerihuel@xxxxxxxxxxxxxx>
Date: Sun, 05 Dec 2010 23:22:10 +0100
Hi Lists,

I've just finished to write a ncacn_http dissector for Wireshark which
provides the ability to dissect Outlook anywhere packets properly (as
specified by [MS-RPCH].pdf documentation.

I have attached to this email all the material needed to test the patch:
        - stunnel.pem: the SSL RSA key to use to decrypt SSL'd capture
        - sample_outlook_anywhere_ssl.pcap: the capture with SSL enabled
        and including RTS + nspi, rfr, mapi packets
        - sample_outlook_anywhere_not_ssl.pcap: the capture performed on
        lo without SSL enabled and filtered to show only RTS packets.

Relevant RTS packets can be displayed using (dcerpc.pkt_type == 20)
filter.

The patch also adds some fuzzy naming on RTS packets given MS-RPCH
specifications. They define these PDU body through the flags, number of
commands fields and command sequences.

FYI, this capture was done between Outlook 2010 and Exchange 2010 using
a local SSL proxy to avoid Diffie-Hellman algorithm usage (default with
Exchange 2010).

In this scenario:
        - 192.168.0.120 is the Outlook 2010 client
        - 192.168.0.103 is the SSL proxy

I have also added to the email the dcerpc.idl patch for Samba4 which
adds the associated IDL for RTS support:
00001-Add-ncacn_http-RTS-IDL-implementation-in-dcerpc.idl.patch

It probably doesn't respect the Samba4 usual naming convention, but I
thought it would be more useful under this form so you can turn fields
to any names you prefer.

Kind Regards,
Julien.

-- 
Julien Kerihuel
j.kerihuel@xxxxxxxxxxxxxx
OpenChange Project Manager/Developer/Maintainer

GPG Fingerprint: 0B55 783D A781 6329 108A  B609 7EF6 FE11 A35F 1F79


Index: epan/dissectors/packet-dcerpc.c
===================================================================
--- epan/dissectors/packet-dcerpc.c	(revision 35124)
+++ epan/dissectors/packet-dcerpc.c	(working copy)
@@ -2,6 +2,7 @@
  * Routines for DCERPC packet disassembly
  * Copyright 2001, Todd Sabin <tas[AT]webspan.net>
  * Copyright 2003, Tim Potter <tpot[AT]samba.org>
+ * Copyright 2010, Julien Kerihuel <j.kerihuel[AT]openchange.org>
  *
  * $Id$
  *
@@ -47,6 +48,7 @@
 #include <epan/dissectors/packet-dcerpc-nt.h>
 #include <epan/expert.h>
 #include <epan/strutil.h>
+#include <epan/addr_resolv.h>
 
 static int dcerpc_tap = -1;
 
@@ -78,6 +80,7 @@
     { PDU_SHUTDOWN,   "Shutdown"},
     { PDU_CO_CANCEL,  "Co_cancel"},
     { PDU_ORPHANED,   "Orphaned"},
+    { PDU_RTS,	      "RTS"},
     { 0,              NULL }
 };
 
@@ -335,6 +338,64 @@
 };
 
 
+/*
+ * RTS Flags
+ */
+#define	RTS_FLAG_NONE			0x0000
+#define	RTS_FLAG_PING			0x0001
+#define	RTS_FLAG_OTHER_CMD		0x0002
+#define	RTS_FLAG_RECYCLE_CHANNEL	0x0004
+#define	RTS_FLAG_IN_CHANNEL		0x0008
+#define	RTS_FLAG_OUT_CHANNEL		0x0010
+#define	RTS_FLAG_EOF			0x0020
+#define	RTS_FLAG_ECHO			0x0040
+
+/*
+ * RTS Commands
+ */
+static const value_string rts_command_vals[] = {
+     { 0x0,	"ReceiveWindowSize" },
+     { 0x1,	"FlowControlAck" },
+     { 0x2,	"ConnectionTimeOut" },
+     { 0x3,	"Cookie" },
+     { 0x4,	"ChannelLifetime" },
+     { 0x5,	"ClientKeepalive" },
+     { 0x6,	"Version" },
+     { 0x7,	"Empty" },
+     { 0x8,	"Padding" },
+     { 0x9,	"NegativeANCE" },
+     { 0xA,	"ANCE" },
+     { 0xB,	"ClientAddress" },
+     { 0xC,	"AssociationGroupId" },
+     { 0xD,	"Destination" },
+     { 0xE,	"PingTrafficSentNotify" },
+     { 0x0,	NULL }
+};
+
+/*
+ * RTS client address type
+ */
+#define	RTS_IPV4	0
+#define	RTS_IPV6	1
+
+static const value_string rts_addresstype_vals[] = {
+     { RTS_IPV4,	"IPV4" },
+     { RTS_IPV6,	"IPV6" },
+     { 0x0,		NULL }
+};
+
+/*
+ * RTS Forward destination
+ */
+
+static const value_string rts_forward_destination_vals[] = {
+     { 0x0,	"FDClient" },
+     { 0x1,	"FDInProxy" },
+     { 0x2,	"FDServer" },
+     { 0x3,	"FDOutProxy" },
+     { 0x0,	NULL }
+};
+
 /* we need to keep track of what transport were used, ie what handle we came
  * in through so we know what kind of pinfo->dce_smb_fid was passed to us.
  */
@@ -397,6 +458,32 @@
 static int hf_dcerpc_cn_cancel_count = -1;
 static int hf_dcerpc_cn_status = -1;
 static int hf_dcerpc_cn_deseg_req = -1;
+static int hf_dcerpc_cn_rts_flags = -1;
+static int hf_dcerpc_cn_rts_flags_none = -1;
+static int hf_dcerpc_cn_rts_flags_ping = -1;
+static int hf_dcerpc_cn_rts_flags_other_cmd = -1;
+static int hf_dcerpc_cn_rts_flags_recycle_channel = -1;
+static int hf_dcerpc_cn_rts_flags_in_channel = -1;
+static int hf_dcerpc_cn_rts_flags_out_channel = -1;
+static int hf_dcerpc_cn_rts_flags_eof = -1;
+static int hf_dcerpc_cn_rts_flags_echo = -1;
+static int hf_dcerpc_cn_rts_commands_nb = -1;
+static int hf_dcerpc_cn_rts_command = -1;
+static int hf_dcerpc_cn_rts_command_receivewindowsize = -1;
+static int hf_dcerpc_cn_rts_command_fack_bytesreceived = -1;
+static int hf_dcerpc_cn_rts_command_fack_availablewindow = -1;
+static int hf_dcerpc_cn_rts_command_fack_channelcookie = -1;
+static int hf_dcerpc_cn_rts_command_connectiontimeout = -1;
+static int hf_dcerpc_cn_rts_command_cookie = -1;
+static int hf_dcerpc_cn_rts_command_channellifetime = -1;
+static int hf_dcerpc_cn_rts_command_clientkeepalive = -1;
+static int hf_dcerpc_cn_rts_command_version = -1;
+static int hf_dcerpc_cn_rts_command_conformancecount = -1;
+static int hf_dcerpc_cn_rts_command_padding = -1;
+static int hf_dcerpc_cn_rts_command_addrtype = -1;
+static int hf_dcerpc_cn_rts_command_associationgroupid = -1;
+static int hf_dcerpc_cn_rts_command_forwarddestination = -1;
+static int hf_dcerpc_cn_rts_command_pingtrafficsentnotify = -1;
 static int hf_dcerpc_auth_type = -1;
 static int hf_dcerpc_auth_level = -1;
 static int hf_dcerpc_auth_pad_len = -1;
@@ -470,6 +557,9 @@
 static gint ett_dcerpc_cn_ctx = -1;
 static gint ett_dcerpc_cn_iface = -1;
 static gint ett_dcerpc_cn_trans_syntax = -1;
+static gint ett_dcerpc_cn_rts_flags = -1;
+static gint ett_dcerpc_cn_rts_command = -1;
+static gint ett_dcerpc_cn_rts_pdu = -1;
 static gint ett_dcerpc_drep = -1;
 static gint ett_dcerpc_dg_flags1 = -1;
 static gint ett_dcerpc_dg_flags2 = -1;
@@ -3915,6 +4005,306 @@
     }
 }
 
+static void
+dissect_dcerpc_cn_rts (tvbuff_t *tvb, gint offset, packet_info *pinfo,
+		       proto_tree *dcerpc_tree, e_dce_cn_common_hdr_t *hdr)
+{
+     proto_item *pdu_tf = NULL;
+     proto_item *tf = NULL;
+     proto_tree *cn_rts_flags_tree = NULL;
+     proto_tree *cn_rts_pdu_tree = NULL;
+     proto_tree *cn_rts_command_tree = NULL;
+     guint16 rts_flags;
+     guint16 commands_nb;
+     guint32 command;
+     guint32 *cmd;
+     guint32 i;
+     guint32 conformance_count;
+     guint8 *padding = NULL;
+     guint32 addrtype;
+     guint32 addr;
+     struct e_in6_addr addr6;
+
+     /* Dissect specific RTS header */
+     rts_flags = dcerpc_tvb_get_ntohs (tvb, offset, hdr->drep);
+     tf = proto_tree_add_uint (dcerpc_tree, hf_dcerpc_cn_rts_flags, tvb, offset, 2, rts_flags);
+     cn_rts_flags_tree = proto_item_add_subtree(tf, ett_dcerpc_cn_rts_flags);
+     proto_tree_add_boolean (cn_rts_flags_tree, hf_dcerpc_cn_rts_flags_none, tvb, offset, 1, rts_flags);
+     proto_tree_add_boolean (cn_rts_flags_tree, hf_dcerpc_cn_rts_flags_ping, tvb, offset, 1, rts_flags);
+     proto_tree_add_boolean (cn_rts_flags_tree, hf_dcerpc_cn_rts_flags_other_cmd, tvb, offset, 1, rts_flags);
+     proto_tree_add_boolean (cn_rts_flags_tree, hf_dcerpc_cn_rts_flags_recycle_channel, tvb, offset, 1, rts_flags);
+     proto_tree_add_boolean (cn_rts_flags_tree, hf_dcerpc_cn_rts_flags_in_channel, tvb, offset, 1, rts_flags);
+     proto_tree_add_boolean (cn_rts_flags_tree, hf_dcerpc_cn_rts_flags_out_channel, tvb, offset, 1, rts_flags);
+     proto_tree_add_boolean (cn_rts_flags_tree, hf_dcerpc_cn_rts_flags_eof, tvb, offset, 1, rts_flags);
+     offset += 2;
+
+     offset = dissect_dcerpc_uint16 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
+				     hf_dcerpc_cn_rts_commands_nb, &commands_nb);
+
+     /* Create the RTS PDU tree - we do not yet know its name */
+     pdu_tf = proto_tree_add_text(dcerpc_tree, tvb, offset, tvb_length_remaining(tvb, offset), "RTS PDU");
+     cn_rts_pdu_tree = proto_item_add_subtree(pdu_tf, ett_dcerpc_cn_rts_pdu);
+
+     cmd = g_malloc(sizeof (guint32) * (commands_nb + 1));
+
+     /* Dissect commands */
+     for (i = 0; i < (int) commands_nb; i++) {
+	  command = dcerpc_tvb_get_ntohl (tvb, offset, hdr->drep);
+	  cmd[i] = command;
+	  tf = proto_tree_add_uint (cn_rts_pdu_tree, hf_dcerpc_cn_rts_command, tvb, offset, 4, command);
+	  cn_rts_command_tree = proto_item_add_subtree(tf, ett_dcerpc_cn_rts_command);
+	  offset += 4;
+	  switch (command) {
+	  case 0x0:
+	       offset = dissect_dcerpc_uint32 (tvb, offset, pinfo, cn_rts_command_tree, hdr->drep, hf_dcerpc_cn_rts_command_receivewindowsize, NULL);
+	       break;
+	  case 0x1:
+	       offset = dissect_dcerpc_uint32 (tvb, offset, pinfo, cn_rts_command_tree, hdr->drep, hf_dcerpc_cn_rts_command_fack_bytesreceived, NULL);
+	       offset = dissect_dcerpc_uint32 (tvb, offset, pinfo, cn_rts_command_tree, hdr->drep, hf_dcerpc_cn_rts_command_fack_availablewindow, NULL);
+	       offset = dissect_dcerpc_uuid_t (tvb, offset, pinfo, cn_rts_command_tree, hdr->drep, hf_dcerpc_cn_rts_command_fack_channelcookie, NULL);
+	       break;
+	  case 0x2:
+	       offset = dissect_dcerpc_uint32 (tvb, offset, pinfo, cn_rts_command_tree, hdr->drep, hf_dcerpc_cn_rts_command_connectiontimeout, NULL);
+	       break;
+	  case 0x3:
+	       offset = dissect_dcerpc_uuid_t (tvb, offset, pinfo, cn_rts_command_tree, hdr->drep, hf_dcerpc_cn_rts_command_cookie, NULL);
+	       break;
+	  case 0x4:
+	       offset = dissect_dcerpc_uint32 (tvb, offset, pinfo, cn_rts_command_tree, hdr->drep, hf_dcerpc_cn_rts_command_channellifetime, NULL);
+	       break;
+	  case 0x5:
+	       offset = dissect_dcerpc_uint32 (tvb, offset, pinfo, cn_rts_command_tree, hdr->drep, hf_dcerpc_cn_rts_command_clientkeepalive, NULL);
+	       break;
+	  case 0x6:
+	       offset = dissect_dcerpc_uint32 (tvb, offset, pinfo, cn_rts_command_tree, hdr->drep, hf_dcerpc_cn_rts_command_version, NULL);
+	       break;
+	  case 0x7:	       
+	       break;
+	  case 0x8:
+	       conformance_count = dcerpc_tvb_get_ntohl (tvb, offset, hdr->drep);
+	       proto_tree_add_uint (cn_rts_command_tree, hf_dcerpc_cn_rts_command_conformancecount, tvb, offset, 4, conformance_count);
+	       offset += 4;
+	       padding = tvb_memdup(tvb, offset, conformance_count);
+	       proto_tree_add_bytes (cn_rts_command_tree, hf_dcerpc_cn_rts_command_padding, tvb, offset, conformance_count, padding);
+	       offset += conformance_count;
+	       break;
+	  case 0x9:
+	       break;
+	  case 0xA:
+	       break;
+	  case 0xB:
+	       addrtype = dcerpc_tvb_get_ntohl (tvb, offset, hdr->drep);
+	       proto_tree_add_uint (cn_rts_command_tree, hf_dcerpc_cn_rts_command_addrtype, tvb, offset, 4, addrtype);
+	       offset += 4;
+	       switch (addrtype) {
+	       case RTS_IPV4:
+		    addr = tvb_get_ipv4(tvb, offset);
+		    proto_tree_add_text(cn_rts_command_tree, tvb, offset, 4, "%s", (const char *)get_hostname(addr));
+		    offset += 4;
+		    break;
+	       case RTS_IPV6:
+		    tvb_get_ipv6(tvb, offset, &addr6);
+		    proto_tree_add_text(cn_rts_command_tree, tvb, offset, 16, "%s", (const char *)get_hostname6(&addr6));
+		    offset += 16;
+		    break;
+	       }
+	       padding = tvb_memdup(tvb, offset, 12);
+	       proto_tree_add_bytes (cn_rts_command_tree, hf_dcerpc_cn_rts_command_padding, tvb, offset, 12, padding);
+	       offset += 12;
+	       break;
+	  case 0xC:
+	       offset = dissect_dcerpc_uuid_t (tvb, offset, pinfo, cn_rts_command_tree, hdr->drep, hf_dcerpc_cn_rts_command_associationgroupid, NULL);	       
+	       break;
+	  case 0xD:
+	       offset = dissect_dcerpc_uint32 (tvb, offset, pinfo, cn_rts_command_tree, hdr->drep, hf_dcerpc_cn_rts_command_forwarddestination, NULL);
+	       break;
+	  case 0xE:
+	       offset = dissect_dcerpc_uint32 (tvb, offset, pinfo, cn_rts_command_tree, hdr->drep, hf_dcerpc_cn_rts_command_pingtrafficsentnotify, NULL);
+	       break;
+	  default:
+	       ;
+	  }
+     }
+
+     /* Define which PDU Body we are dealing with */
+     switch (rts_flags) {
+     case RTS_FLAG_NONE:
+	  switch (commands_nb) {
+	  case 1:
+	       if (cmd[0] == 0x2) {
+		    col_add_fstr(pinfo->cinfo, COL_INFO, "CONN/A3 RTS PDU");
+	       } else if (cmd[0] == 0x3) {
+		    col_add_fstr(pinfo->cinfo, COL_INFO, "IN_R1/A5 or IN_R1/A6 or IN_R2/A2 or IN_R2/A5 or OUT_R2/A4 RTS PDU");
+	       } else if (cmd[0] == 0x7) {
+		    col_add_fstr(pinfo->cinfo, COL_INFO, "IN_R1/B1 RTS PDU");
+	       } else if (cmd[0] == 0x0) {
+		    col_add_fstr(pinfo->cinfo, COL_INFO, "IN_R1/B2 RTS PDU");
+	       } else if (cmd[0] == 0xD) {
+		    col_add_fstr(pinfo->cinfo, COL_INFO, "IN_R2/A3 or IN_R2/A4 RTS PDU");
+	       } else if (cmd[0] == 0xA) {
+		    col_add_fstr(pinfo->cinfo, COL_INFO, "OUT_R1/A9 or OUT_R1/A10 or OUT_R1/A11 or OUT_R2/B1 or OUT_R2/B2 RTS PDU");
+	       }
+	       break;
+	  case 2:
+	       if ((cmd[0] == 0x0) && (cmd[1] == 0x6)) {
+		    col_add_fstr(pinfo->cinfo, COL_INFO, "CONN/B3 RTS PDU");
+	       } else if ((cmd[0] == 0xD) && (cmd[1] == 0xA)) {
+		    col_add_fstr(pinfo->cinfo, COL_INFO, "OUT_R2/A5 or OUT_R2/A6 RTS PDU");
+	       }
+	       break;
+	  case 3:
+	       if ((cmd[0] == 0x6) && (cmd[1] == 0x0) && (cmd[2] == 0x2)) {
+		    col_add_fstr(pinfo->cinfo, COL_INFO, "CONN/C1 or CONN/C2 RTS PDU");
+	       }
+	       break;
+	  case 4:
+	       if ((cmd[0] == 0x6) && (cmd[1] == 0x3) && (cmd[2] == 0x3) && (cmd[3] == 0x0)) {
+		    col_add_fstr(pinfo->cinfo, COL_INFO, "CONN/A1 RTS PDU");
+	       } else if ((cmd[0] == 0xD) && (cmd[1] == 0x6) && (cmd[2] == 0x0) && (cmd[3] == 0x2)) {
+		    col_add_fstr(pinfo->cinfo, COL_INFO, "IN_R1/A3 RTS PDU or IN_R1/A4 RTS PDU");
+	       } 
+	       break;
+	  case 6:
+	       if ((cmd[0] == 0x6) && (cmd[1] == 0x3) && (cmd[2] == 0x3) && (cmd[3] == 0x4) && (cmd[4] == 0x5) && (cmd[5] == 0xC)) {
+		    col_add_fstr(pinfo->cinfo, COL_INFO, "CONN/B1 RTS PDU");
+	       }
+	       break;
+	  default:
+	       col_add_fstr(pinfo->cinfo, COL_INFO, "RTS PDU");
+	  }
+	  break;
+     case RTS_FLAG_PING:
+	  switch (commands_nb) {
+	  case 0:
+	       col_add_fstr(pinfo->cinfo, COL_INFO, "Ping RTS PDU");
+	       break;
+	  case 1:
+	       if ((cmd[0] == 0x7) || (cmd[0] == 0x8)) {
+		    col_add_fstr(pinfo->cinfo, COL_INFO, "OUT_R2/C1 RTS PDU");
+	       }
+	       break;
+	  default:
+	       col_add_fstr(pinfo->cinfo, COL_INFO, "RTS PDU");
+	  }
+	  break;
+     case RTS_FLAG_OTHER_CMD:
+	  switch (commands_nb) {
+	  case 1:
+	       if (cmd[0] == 0x5) {
+		    col_add_fstr(pinfo->cinfo, COL_INFO, "Keep-Alive RTS PDU");
+	       } else if (cmd[0] == 0xE) {
+		    col_add_fstr(pinfo->cinfo, COL_INFO, "PingTrafficSentNotify");
+	       } else if (cmd[0] == 0x1) {
+		    col_add_fstr(pinfo->cinfo, COL_INFO, "FlowControlAck RTS PDU");
+	       }
+	       break;
+	  case 2:
+	       if ((cmd[0] == 0xD) && (cmd[1] == 0x1)) {
+		    col_add_fstr(pinfo->cinfo, COL_INFO, "FlowControlAckWithDestination RTS PDU");
+	       }
+	       break;
+	  default:
+	       col_add_fstr(pinfo->cinfo, COL_INFO, "RTS PDU");
+	  }
+	  break;
+     case RTS_FLAG_RECYCLE_CHANNEL:
+	  switch(commands_nb) {
+	  case 1:
+	       if (cmd[0] == 0xD) {
+		    col_add_fstr(pinfo->cinfo, COL_INFO, "OUT_R1/A1 or OUT_R1/A2 or OUT_R2/A1 or OUT_R2/A2 RTS PDU");
+	       }
+	       break;
+	  case 4:
+	       if ((cmd[0] == 0x6) && (cmd[1] == 0x3) && (cmd[2] == 0x3) && (cmd[3] == 0x3)) {
+		    col_add_fstr(pinfo->cinfo, COL_INFO, "IN_R1/A1 RTS PDU or IN_R2/A1 RTS PDU");
+	       } 
+	       break;
+	  case 5:
+	       if ((cmd[0] == 0x6) && (cmd[1] == 0x3) && (cmd[2] == 0x3) && (cmd[3] == 0x3) && (cmd[4] == 0x0)) {
+		    col_add_fstr(pinfo->cinfo, COL_INFO, "OUT_R1/A3 or OUT_R2/A3 RTS PDU");
+	       }
+	       break;
+	  default:
+	       col_add_fstr(pinfo->cinfo, COL_INFO, "RTS PDU");
+	  }
+	  break;
+     case RTS_FLAG_IN_CHANNEL|RTS_FLAG_RECYCLE_CHANNEL:
+	  switch (commands_nb) {
+	  case 6:
+	       if ((cmd[0] == 0x6) && (cmd[1] == 0x3) && (cmd[2] == 0x3) && (cmd[3] == 0x3) && (cmd[4] == 0x0) && (cmd[5] == 0x2)) {
+		    col_add_fstr(pinfo->cinfo, COL_INFO, "IN_R1/A2 RTS PDU");
+	       }
+	       break;
+	  default:
+	       col_add_fstr(pinfo->cinfo, COL_INFO, "RTS PDU");
+	  }
+     case RTS_FLAG_IN_CHANNEL:
+	  switch (commands_nb) {
+	  case 7:
+	       if ((cmd[0] == 0x6) && (cmd[1] == 0x3) && (cmd[2] == 0x3) && (cmd[3] == 0x0) && (cmd[4] == 0x2) && (cmd[5] == 0xC) && (cmd[6] == 0xB)) {
+		    col_add_fstr(pinfo->cinfo, COL_INFO, "CONN/B2 RTS PDU");
+	       }
+	       break;
+	  default:
+	       col_add_fstr(pinfo->cinfo, COL_INFO, "RTS PDU");
+	  }
+     case RTS_FLAG_RECYCLE_CHANNEL|RTS_FLAG_OUT_CHANNEL:
+	  switch (commands_nb) {
+	  case 7:
+	       if ((cmd[0] == 0x6) && (cmd[1] == 0x3) && (cmd[2] == 0x3) && (cmd[3] == 0x3) && (cmd[4] == 0x4) && (cmd[5] == 0) && (cmd[6] == 0x2)) {
+		    col_add_fstr(pinfo->cinfo, COL_INFO, "OUT_R1/A4 RTS PDU");
+	       }
+	       break;
+	  }
+	  break;
+     case RTS_FLAG_OUT_CHANNEL:
+	  switch (commands_nb) {
+	  case 2:
+	       if ((cmd[0] == 0xD) && (cmd[1] == 0x3)) {
+		    col_add_fstr(pinfo->cinfo, COL_INFO, "OUT_R1/A7 or OUT_R1/A8 or OUT_R2/A8 RTS PDU");
+	       }
+	       break;
+	  case 3:
+	       if ((cmd[0] == 0xD) && (cmd[1] == 0x6) && (cmd[2] == 0x2)) {
+		    col_add_fstr(pinfo->cinfo, COL_INFO, "OUT_R1/A5 or OUT_R1/A6 RTS PDU");
+	       } else if ((cmd[0] == 0xD) && (cmd[1] == 0x3) && (cmd[2] == 0x6)) {
+		    col_add_fstr(pinfo->cinfo, COL_INFO, "OUT_R2/A7 RTS PDU");
+	       }
+	       break;
+	  case 5:
+	       if ((cmd[0] == 0x6) && (cmd[1] == 0x3) && (cmd[2] == 0x3) && (cmd[3] == 0x4) && (cmd[4] == 0x0)) {
+		    col_add_fstr(pinfo->cinfo, COL_INFO, "CONN/A2 RTS PDU");
+	       }
+	       break;
+	  default:
+	       col_add_fstr(pinfo->cinfo, COL_INFO, "RTS PDU");
+	  }
+     case RTS_FLAG_EOF:
+	  switch (commands_nb) {
+	  case 1:
+	       if (cmd[0] == 0xA) {
+		    col_add_fstr(pinfo->cinfo, COL_INFO, "OUT_R2/B3 RTS PDU");
+	       }
+	       break;
+	  }
+	  break;
+     case RTS_FLAG_ECHO:
+	  switch (commands_nb) {
+	  case 0:
+	       col_add_fstr(pinfo->cinfo, COL_INFO, "Echo RTS PDU");
+	       break;
+	  }
+	  break;
+     default:
+	  col_add_fstr(pinfo->cinfo, COL_INFO, "RTS PDU");
+     }
+
+     g_free(cmd);
+
+
+
+}
+
 /*
  * DCERPC dissector for connection oriented calls.
  * We use transport type to later multiplex between what kind of
@@ -3967,7 +4357,7 @@
     if (hdr.rpc_ver_minor != 0 && hdr.rpc_ver_minor != 1)
         return FALSE;
     hdr.ptype = tvb_get_guint8 (tvb, offset++);
-    if (hdr.ptype > 19)
+    if (hdr.ptype > 20)
         return FALSE;
 
     hdr.flags = tvb_get_guint8 (tvb, offset++);
@@ -4174,6 +4564,9 @@
          * verifier.
          */
         break;
+    case PDU_RTS:
+      dissect_dcerpc_cn_rts (fragment_tvb, offset, pinfo, dcerpc_tree, &hdr);
+      break;
 
     default:
         /* might as well dissect the auth info */
@@ -5284,6 +5677,58 @@
           { "Status", "dcerpc.cn_status", FT_UINT32, BASE_HEX, VALS(reject_status_vals), 0x0, NULL, HFILL }},
         { &hf_dcerpc_cn_deseg_req,
           { "Desegmentation Required", "dcerpc.cn_deseg_req", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+	{ &hf_dcerpc_cn_rts_flags, 
+	  { "RTS Flags", "dcerpc.cn_rts_flags", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+	{ &hf_dcerpc_cn_rts_flags_none,
+	  {"None", "dcerpc.cn_rts_flags.none", FT_BOOLEAN, 8, TFS (&tfs_set_notset), RTS_FLAG_NONE, NULL, HFILL }},
+	{ &hf_dcerpc_cn_rts_flags_ping,
+	  { "Ping", "dcerpc.cn_rts.flags.ping", FT_BOOLEAN, 8, TFS (&tfs_set_notset), RTS_FLAG_PING, NULL, HFILL }},
+	{ &hf_dcerpc_cn_rts_flags_other_cmd,
+	  { "Other Cmd", "dcerpc.cn_rts_flags.other_cmd", FT_BOOLEAN, 8, TFS (&tfs_set_notset), RTS_FLAG_OTHER_CMD, NULL, HFILL }},
+	{ &hf_dcerpc_cn_rts_flags_recycle_channel,
+	  { "Recycle Channel", "dcerpc.cn_rts_flags.recycle_channel", FT_BOOLEAN, 8, TFS (&tfs_set_notset), RTS_FLAG_RECYCLE_CHANNEL, NULL, HFILL }},
+	{ &hf_dcerpc_cn_rts_flags_in_channel,
+	  { "In Channel", "dcerpc.cn_rts_flags.in_channel", FT_BOOLEAN, 8, TFS (&tfs_set_notset), RTS_FLAG_IN_CHANNEL, NULL, HFILL }},
+	{ &hf_dcerpc_cn_rts_flags_out_channel,
+	  { "Out Channel", "dcerpc.cn_rts_flags.out_channel", FT_BOOLEAN, 8, TFS (&tfs_set_notset), RTS_FLAG_OUT_CHANNEL, NULL, HFILL }},
+	{ &hf_dcerpc_cn_rts_flags_eof,
+	  { "EOF", "dcerpc.cn_rts_flags.eof", FT_BOOLEAN, 8, TFS (&tfs_set_notset), RTS_FLAG_EOF, NULL, HFILL }},
+	{ &hf_dcerpc_cn_rts_flags_echo,
+	  { "Echo", "dcerpc.cn_rts_flags.echo", FT_BOOLEAN, 8, TFS (&tfs_set_notset), RTS_FLAG_ECHO, NULL, HFILL }},
+	{ &hf_dcerpc_cn_rts_commands_nb,
+	  { "RTS Number of Commands", "dcerpc.cn_rts_commands_nb", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+	{ &hf_dcerpc_cn_rts_command,
+	  { "RTS Command", "dcerpc_cn_rts_command", FT_UINT32, BASE_HEX, VALS(rts_command_vals), 0x0, NULL, HFILL }},
+	{ &hf_dcerpc_cn_rts_command_receivewindowsize,
+	  {"Receive Window Size", "dcerpc_cn_rts_command.receivewindowsize", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+	{ &hf_dcerpc_cn_rts_command_fack_bytesreceived,
+	  {"Bytes Received", "dcerpc_cn_rts_command.fack.bytesreceived", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+	{ &hf_dcerpc_cn_rts_command_fack_availablewindow,
+	  {"Available Window", "dcerpc_cn_rts_command.fack.availablewindow", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+	{ &hf_dcerpc_cn_rts_command_fack_channelcookie,
+	  {"Channel Cookie", "dcerpc_cn_rts_command.fack.channelcookie", FT_GUID, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+	{ &hf_dcerpc_cn_rts_command_connectiontimeout,
+	  {"Connection Timeout", "dcerpc_cn_rts_command.connectiontimeout", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+	{ &hf_dcerpc_cn_rts_command_cookie,
+	  {"Cookie", "dcerpc_cn_rts_command.cookie", FT_GUID, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+	{ &hf_dcerpc_cn_rts_command_channellifetime,
+	  {"Channel Lifetime", "dcerpc_cn_rts_command.channellifetime", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+	{ &hf_dcerpc_cn_rts_command_clientkeepalive,
+	  {"Client Keepalive", "dcerpc_cn_rts_command.clientkeepalive", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+	{ &hf_dcerpc_cn_rts_command_version,
+	  {"Version", "dcerpc_cn_rts_command.version", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+	{ &hf_dcerpc_cn_rts_command_conformancecount,
+	  {"Conformance Count", "dcerpc_cn_rts_command.padding.conformancecount", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+	{ &hf_dcerpc_cn_rts_command_padding, 
+	  { "Padding", "dcerpc_cn_rts_command.padding.padding", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}}, 
+	{ &hf_dcerpc_cn_rts_command_addrtype,
+	  { "Address Type", "dcerpc_cn_rts_command.addrtype", FT_UINT32, BASE_DEC, VALS (rts_addresstype_vals), 0x0, NULL, HFILL }},
+	{ &hf_dcerpc_cn_rts_command_associationgroupid,
+	  {"Association Group ID", "dcerpc_cn_rts_command.associationgroupid", FT_GUID, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+	{ &hf_dcerpc_cn_rts_command_forwarddestination,
+	  {"Forward Destination", "dcerpc_cn_rts_command.forwarddestination", FT_UINT32, BASE_DEC, VALS (rts_forward_destination_vals), 0x0, NULL, HFILL }},
+	{ &hf_dcerpc_cn_rts_command_pingtrafficsentnotify,
+	  {"Ping Traffic Sent Notify", "dcerpc_cn_rts_command.pingtrafficsentnotify", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
         { &hf_dcerpc_auth_type,
           { "Auth type", "dcerpc.auth_type", FT_UINT8, BASE_DEC, VALS (authn_protocol_vals), 0x0, NULL, HFILL }},
         { &hf_dcerpc_auth_level,
@@ -5462,6 +5907,9 @@
         &ett_dcerpc_cn_ctx,
         &ett_dcerpc_cn_iface,
         &ett_dcerpc_cn_trans_syntax,
+	&ett_dcerpc_cn_rts_flags,
+	&ett_dcerpc_cn_rts_command,
+	&ett_dcerpc_cn_rts_pdu,
         &ett_dcerpc_drep,
         &ett_dcerpc_dg_flags1,
         &ett_dcerpc_dg_flags2,
Index: epan/dissectors/packet-dcerpc.h
===================================================================
--- epan/dissectors/packet-dcerpc.h	(revision 35124)
+++ epan/dissectors/packet-dcerpc.h	(working copy)
@@ -113,8 +113,8 @@
 #define PDU_SHUTDOWN   17
 #define PDU_CO_CANCEL  18
 #define PDU_ORPHANED   19
+#define PDU_RTS        20
 
-
 /*
  * helpers for packet-dcerpc.c and packet-dcerpc-ndr.c
  * If you're writing a subdissector, you almost certainly want the

Attachment: stunnel.pem
Description: application/x509-ca-cert

Attachment: sample_outlook_anywhere_not_ssl.pcap
Description: Binary data

Attachment: sample_outlook_anywhere_ssl.pcap
Description: Binary data

From 4ea48f3f3f8197818623c7794f5e8540b63fe0c2 Mon Sep 17 00:00:00 2001
From: Julien Kerihuel <j.kerihuel@xxxxxxxxxxxxxx>
Date: Sun, 5 Dec 2010 23:10:30 +0100
Subject: [PATCH] Add ncacn_http (RTS) IDL implementation in dcerpc.idl


Signed-off-by: Julien Kerihuel <j.kerihuel@xxxxxxxxxxxxxx>
---
 librpc/idl/dcerpc.idl |  154 ++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 153 insertions(+), 1 deletions(-)

diff --git a/librpc/idl/dcerpc.idl b/librpc/idl/dcerpc.idl
index d98d7bd..68838ad 100644
--- a/librpc/idl/dcerpc.idl
+++ b/librpc/idl/dcerpc.idl
@@ -252,6 +252,156 @@ interface dcerpc
 	typedef [public] struct {
 	} dcerpc_working;
 
+	/* RTS data structures */
+	typedef [public] struct {
+		GUID		Cookie;
+	} RTSCookie;
+
+	typedef [v1_enum,public] enum {
+		RTS_IPV4	= 0,
+		RTS_IPV6	= 1
+	} AddressType;
+
+	typedef [nodiscriminant] union {
+		[case(RTS_IPV4)] ipv4address	ClientAddressIPV4;
+		[case(RTS_IPV6)] ipv6address	ClientAddressIPV6;
+	} ClientAddressType;
+
+	typedef [public] struct {
+		AddressType					AddressType;
+		[switch_is(AddressType)] ClientAddressType	ClientAddress;
+		uint8						Padding[12];
+	} ClientAddress;
+
+	typedef [v1_enum, public] enum {
+		FDClient	= 0,
+		FDInProxy	= 1,
+		FDServer	= 2,
+		FDOutProxy	= 3
+	} ForwardDestination;
+
+	typedef [public] struct {
+		uint32		BytesReceived;
+		uint32		AvailableWindow;
+		RTSCookie	ChannelCookie;
+	} FlowControlAcknowledgment;
+
+	/* RTS commands */
+
+	/* RTS command: 0x0 */
+	typedef [public] struct {
+		[range(0x2000,0x40000)] uint32	ReceiveWindowSize;
+	} dcerpc_rts_cmd_ReceiveWindowSize;
+
+	/* RTS command: 0x1 */
+	typedef [public] struct {
+		FlowControlAcknowledgment	Ack;
+	} dcerpc_rts_cmd_FlowControlAck;
+
+	/* RTS command: 0x2 */
+	typedef [public] struct {
+		[range(0x1D4C0,0xDBBA00)] uint32	ConnectionTimeout;
+	} dcerpc_rts_cmd_ConnectionTimeout;
+
+	/* RTS command: 0x3 */
+	typedef [public] struct {
+		RTSCookie	Cookie;
+	} dcerpc_rts_cmd_Cookie;
+
+	/* RTS command: 0x4 */
+	typedef [public] struct {
+		[range(0x20000,0x800000000)] uint32	ChannelLifetime;
+	} dcerpc_rts_cmd_ChannelLifetime;
+
+	/* RTS command: 0x5 */
+	typedef [public] struct {
+		uint32		ClientKeepalive;
+	} dcerpc_rts_cmd_ClientKeepalive;
+
+	/* RTS command: 0x6 */
+	typedef [public] struct {
+		uint32		Version;
+	} dcerpc_rts_cmd_Version;
+
+	/* RTS command: 0x7 */
+	typedef [public] struct {
+	} dcerpc_rts_cmd_Empty;
+
+	/* RTS command: 0x8 */
+	typedef [public] struct {
+		[range(0x0,0xFFFF)] uint32	ConformanceCount;
+		uint8				Padding[ConformanceCount];
+	} dcerpc_rts_cmd_Padding;
+
+	/* RTS command: 0x9 */
+	typedef [public] struct {
+	} dcerpc_rts_cmd_NegativeANCE;
+
+	/* RTS Command: 0xA */
+	typedef [public] struct {
+	} dcerpc_rts_cmd_ANCE;
+
+	/* RTS command: 0xB */
+	typedef [public] struct {
+		ClientAddress	ClientAddress;
+	} dcerpc_rts_cmd_ClientAddress;
+
+	/* RTS command: 0xC */
+	typedef [public] struct {
+		RTSCookie	AssociationGroupId;
+	} dcerpc_rts_cmd_AssociationGroupId;
+
+	/* RTS command: 0xD */
+	typedef [public] struct {
+		ForwardDestination	ForwardDestination;
+	} dcerpc_rts_cmd_Destination;
+
+	/* RTS command: 0xE */
+	typedef [public] struct {
+		uint32	PingTrafficSent;
+	} dcerpc_rts_cmd_PingTrafficSentNotify;
+
+	typedef [nodiscriminant] union {
+		[case(0x0)] dcerpc_rts_cmd_ReceiveWindowSize		ReceiveWindowSize;
+		[case(0x1)] dcerpc_rts_cmd_FlowControlAck		FlowControlAck;
+		[case(0x2)] dcerpc_rts_cmd_ConnectionTimeout		ConnectionTimeout;
+		[case(0x3)] dcerpc_rts_cmd_Cookie			Cookie;
+		[case(0x4)] dcerpc_rts_cmd_ChannelLifetime		ChannelLifetime;
+		[case(0x5)] dcerpc_rts_cmd_ClientKeepalive		ClientKeepalive;
+		[case(0x6)] dcerpc_rts_cmd_Version			Version;
+		[case(0x7)] dcerpc_rts_cmd_Empty			Empty;
+		[case(0x8)] dcerpc_rts_cmd_Padding			Padding;
+		[case(0x9)] dcerpc_rts_cmd_NegativeANCE			NegativeANCE;
+		[case(0xA)] dcerpc_rts_cmd_ANCE				ANCE;
+		[case(0xB)] dcerpc_rts_cmd_ClientAddress		ClientAddress;
+		[case(0xC)] dcerpc_rts_cmd_AssociationGroupId		AssociationGroupId;
+		[case(0xD)] dcerpc_rts_cmd_Destination			Destination;
+		[case(0xE)] dcerpc_rts_cmd_PingTrafficSentNotify	PingTrafficSentNotify;
+	} dcerpc_rts_cmds;
+
+	typedef [public] struct {
+		uint32						CommandType;
+		[switch_is(CommandType)] dcerpc_rts_cmds	Command;
+	} dcerpc_rts_cmd;
+
+	/* The RTS flags */
+	typedef [public, bitmap16bit] bitmap {
+		RTS_FLAG_NONE			=	0x0000,
+		RTS_FLAG_PING			=	0x0001,
+		RTS_FLAG_OTHER_CMD		=	0x0002,
+		RTS_FLAG_RECYCLE_CHANNEL	=	0x0004,
+		RTS_FLAG_IN_CHANNEL		=	0x0008,
+		RTS_FLAG_OUT_CHANNEL		=	0x0010,
+		RTS_FLAG_EOF			=	0x0020,
+		RTS_FLAG_ECHO			=	0x0040
+	} dcerpc_rts_flags;
+
+	typedef [public] struct {
+		dcerpc_rts_flags	Flags;
+		uint16			NumberOfCommands;
+		dcerpc_rts_cmd		Commands[NumberOfCommands];
+	} dcerpc_rts;
+
 	typedef [enum8bit] enum {
 		DCERPC_PKT_REQUEST     =  0,	/* Ordinary request. */
 		DCERPC_PKT_PING        =  1,	/* Connectionless is server alive ? */
@@ -272,7 +422,8 @@ interface dcerpc
 		DCERPC_PKT_AUTH3       = 16, 	/* not the real name!  this is undocumented! */
 		DCERPC_PKT_SHUTDOWN    = 17,	/* Server to client request to shutdown. */
 		DCERPC_PKT_CO_CANCEL   = 18,	/* Connection-oriented cancel request. */
-		DCERPC_PKT_ORPHANED    = 19	/* Client telling server it's aborting a partially sent request or telling server to stop sending replies. */
+		DCERPC_PKT_ORPHANED    = 19,	/* Client telling server it's aborting a partially sent request or telling server to stop sending replies. */
+		DCERPC_PKT_RTS	       = 20	/* RTS packets used in ncacn_http */
 	} dcerpc_pkt_type;
 
 	typedef [nodiscriminant] union {
@@ -296,6 +447,7 @@ interface dcerpc
 		[case(DCERPC_PKT_CO_CANCEL)]  dcerpc_co_cancel co_cancel;
 		[case(DCERPC_PKT_ORPHANED)]   dcerpc_orphaned orphaned;
 		[case(DCERPC_PKT_AUTH3)]      dcerpc_auth3    auth3;
+		[case(DCERPC_PKT_RTS)]	      dcerpc_rts      rts;
 	} dcerpc_payload;
 
 	/* pfc_flags values */
-- 
1.7.1

Attachment: signature.asc
Description: This is a digitally signed message part