2002-05-23 10:00:19 +00:00
|
|
|
/* packet-dcerpc-mapi.c
|
|
|
|
* Routines for MS Exchange MAPI
|
|
|
|
* Copyright 2002, Ronnie Sahlberg
|
|
|
|
*
|
2004-07-18 00:24:25 +00:00
|
|
|
* $Id$
|
2002-05-23 10:00:19 +00:00
|
|
|
*
|
|
|
|
* Ethereal - Network traffic analyzer
|
|
|
|
* By Gerald Combs <gerald@ethereal.com>
|
|
|
|
* Copyright 1998 Gerald Combs
|
2002-08-28 21:04:11 +00:00
|
|
|
*
|
2002-05-23 10:00:19 +00:00
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
2002-08-28 21:04:11 +00:00
|
|
|
*
|
2002-05-23 10:00:19 +00:00
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
2002-08-28 21:04:11 +00:00
|
|
|
*
|
2002-05-23 10:00:19 +00:00
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "config.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <glib.h>
|
|
|
|
#include <epan/packet.h>
|
|
|
|
#include "packet-dcerpc.h"
|
2002-05-23 12:23:29 +00:00
|
|
|
#include "packet-dcerpc-nt.h"
|
2002-05-23 10:00:19 +00:00
|
|
|
#include "packet-dcerpc-mapi.h"
|
2002-05-23 12:23:29 +00:00
|
|
|
#include "smb.h" /* for "NT_errors[]" */
|
2002-05-25 08:41:12 +00:00
|
|
|
#include "prefs.h"
|
2002-05-23 10:00:19 +00:00
|
|
|
|
|
|
|
static int proto_dcerpc_mapi = -1;
|
2003-06-26 04:30:31 +00:00
|
|
|
static int hf_mapi_opnum = -1;
|
2002-05-23 12:23:29 +00:00
|
|
|
static int hf_mapi_unknown_string = -1;
|
|
|
|
static int hf_mapi_unknown_short = -1;
|
2003-05-10 02:15:04 +00:00
|
|
|
static int hf_mapi_unknown_long = -1;
|
2002-05-23 12:23:29 +00:00
|
|
|
static int hf_mapi_hnd = -1;
|
|
|
|
static int hf_mapi_rc = -1;
|
|
|
|
static int hf_mapi_encap_datalen = -1;
|
2003-02-07 08:56:12 +00:00
|
|
|
static int hf_mapi_encrypted_data = -1;
|
2002-05-25 08:41:12 +00:00
|
|
|
static int hf_mapi_decrypted_data_maxlen = -1;
|
|
|
|
static int hf_mapi_decrypted_data_offset = -1;
|
|
|
|
static int hf_mapi_decrypted_data_len = -1;
|
|
|
|
static int hf_mapi_decrypted_data = -1;
|
2002-05-25 09:19:45 +00:00
|
|
|
static int hf_mapi_pdu_len = -1;
|
|
|
|
static int hf_mapi_pdu_trailer = -1;
|
|
|
|
static int hf_mapi_pdu_extra_trailer = -1;
|
2002-05-23 12:23:29 +00:00
|
|
|
|
2002-05-23 10:00:19 +00:00
|
|
|
static gint ett_dcerpc_mapi = -1;
|
2002-05-25 09:19:45 +00:00
|
|
|
static gint ett_mapi_decrypted_pdu = -1;
|
2002-05-23 10:00:19 +00:00
|
|
|
|
|
|
|
static e_uuid_t uuid_dcerpc_mapi = {
|
|
|
|
0xa4f1db00, 0xca47, 0x1067,
|
|
|
|
{ 0xb3, 0x1f, 0x00, 0xdd, 0x01, 0x06, 0x62, 0xda }
|
|
|
|
};
|
|
|
|
|
|
|
|
static guint16 ver_dcerpc_mapi = 0;
|
|
|
|
|
2002-05-23 12:23:29 +00:00
|
|
|
#define DISSECT_UNKNOWN(len) \
|
|
|
|
{\
|
|
|
|
proto_tree_add_text(tree, tvb, offset, len,\
|
|
|
|
"unknown data (%d byte%s)", len,\
|
|
|
|
plurality(len, "", "s"));\
|
|
|
|
offset += len;\
|
|
|
|
}
|
|
|
|
|
2002-05-25 08:41:12 +00:00
|
|
|
/* decryption */
|
|
|
|
static gboolean mapi_decrypt = FALSE;
|
|
|
|
static GMemChunk *mapi_decrypted_data_chunk = NULL;
|
|
|
|
static int mapi_decrypted_data_init_count = 200;
|
|
|
|
static GHashTable *mapi_decrypted_table = NULL;
|
|
|
|
typedef struct {
|
|
|
|
guint32 frame;
|
|
|
|
guint32 callid;
|
|
|
|
tvbuff_t *tvb;
|
|
|
|
unsigned char *data;
|
|
|
|
} mapi_decrypted_data_t;
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
free_all_decrypted(gpointer key_arg, gpointer value _U_, gpointer user_data _U_)
|
|
|
|
{
|
|
|
|
mapi_decrypted_data_t *mdd=(mapi_decrypted_data_t *)key_arg;
|
|
|
|
|
|
|
|
if(mdd->tvb){
|
|
|
|
tvb_free(mdd->tvb);
|
|
|
|
mdd->tvb=NULL;
|
|
|
|
}
|
|
|
|
if(mdd->data){
|
|
|
|
g_free(mdd->data);
|
|
|
|
mdd->data=NULL;
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
static guint
|
|
|
|
mapi_decrypt_hash(gconstpointer k)
|
|
|
|
{
|
2002-11-28 03:57:50 +00:00
|
|
|
const mapi_decrypted_data_t *mdd=(const mapi_decrypted_data_t *)k;
|
2002-05-25 08:41:12 +00:00
|
|
|
return mdd->frame;
|
|
|
|
}
|
|
|
|
static gint
|
|
|
|
mapi_decrypt_equal(gconstpointer k1, gconstpointer k2)
|
|
|
|
{
|
2002-11-28 03:57:50 +00:00
|
|
|
const mapi_decrypted_data_t *mdd1=(const mapi_decrypted_data_t *)k1;
|
|
|
|
const mapi_decrypted_data_t *mdd2=(const mapi_decrypted_data_t *)k2;
|
2002-05-25 08:41:12 +00:00
|
|
|
|
|
|
|
return ( (mdd1->frame==mdd2->frame)
|
|
|
|
&&(mdd1->callid==mdd2->callid) );
|
|
|
|
}
|
|
|
|
static void
|
|
|
|
mapi_decrypt_init(void)
|
|
|
|
{
|
|
|
|
if(mapi_decrypted_table){
|
|
|
|
g_hash_table_foreach_remove(mapi_decrypted_table,
|
|
|
|
free_all_decrypted, NULL);
|
|
|
|
} else {
|
|
|
|
mapi_decrypted_table=g_hash_table_new(mapi_decrypt_hash,
|
|
|
|
mapi_decrypt_equal);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(mapi_decrypted_data_chunk){
|
|
|
|
g_mem_chunk_destroy(mapi_decrypted_data_chunk);
|
|
|
|
mapi_decrypted_data_chunk=NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(mapi_decrypt){
|
|
|
|
mapi_decrypted_data_chunk=g_mem_chunk_new("mapi_decrypt_chunk",
|
|
|
|
sizeof(mapi_decrypted_data_t),
|
|
|
|
mapi_decrypted_data_init_count*sizeof(mapi_decrypted_data_t),
|
|
|
|
G_ALLOC_ONLY);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
mapi_decrypt_pdu(tvbuff_t *tvb, int offset,
|
2004-01-19 20:10:37 +00:00
|
|
|
packet_info *pinfo, proto_tree *tree, guint8 *drep)
|
2002-05-25 08:41:12 +00:00
|
|
|
{
|
|
|
|
dcerpc_info *di;
|
|
|
|
mapi_decrypted_data_t *mmd=NULL;
|
|
|
|
guint32 len;
|
2002-11-28 03:57:50 +00:00
|
|
|
const unsigned char *ptr;
|
2002-05-25 08:41:12 +00:00
|
|
|
guint32 i;
|
2002-05-25 09:19:45 +00:00
|
|
|
guint16 pdu_len;
|
|
|
|
proto_item *it = NULL;
|
|
|
|
proto_tree *tr = NULL;
|
2002-05-25 08:41:12 +00:00
|
|
|
|
|
|
|
di=pinfo->private_data;
|
|
|
|
if(di->conformant_run){
|
|
|
|
return offset;
|
|
|
|
}
|
|
|
|
|
|
|
|
offset=dissect_ndr_uint32(tvb, offset, pinfo, tree, drep, hf_mapi_decrypted_data_maxlen, NULL);
|
|
|
|
offset=dissect_ndr_uint32(tvb, offset, pinfo, tree, drep, hf_mapi_decrypted_data_offset, NULL);
|
|
|
|
offset=dissect_ndr_uint32(tvb, offset, pinfo, tree, drep, hf_mapi_decrypted_data_len, &len);
|
|
|
|
|
2002-06-15 22:24:31 +00:00
|
|
|
if(len>(guint32)tvb_length_remaining(tvb, offset)){
|
|
|
|
len=tvb_length_remaining(tvb, offset);
|
|
|
|
}
|
|
|
|
|
2002-05-25 08:41:12 +00:00
|
|
|
if(!pinfo->fd->flags.visited){
|
2004-02-25 09:31:07 +00:00
|
|
|
ptr=(const unsigned char *)tvb_get_ptr(tvb, offset, len);
|
2002-05-25 08:41:12 +00:00
|
|
|
mmd=g_mem_chunk_alloc(mapi_decrypted_data_chunk);
|
|
|
|
mmd->callid=di->call_id;
|
|
|
|
mmd->frame=pinfo->fd->num;
|
|
|
|
mmd->data=g_malloc(len);
|
|
|
|
for(i=0;i<len;i++){
|
|
|
|
mmd->data[i]=ptr[i]^0xa5;
|
|
|
|
}
|
|
|
|
mmd->tvb=tvb_new_real_data(mmd->data, len, len);
|
|
|
|
g_hash_table_insert(mapi_decrypted_table, mmd, mmd);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!mmd){
|
|
|
|
mapi_decrypted_data_t mmd_key;
|
|
|
|
mmd_key.callid=di->call_id;
|
|
|
|
mmd_key.frame=pinfo->fd->num;
|
|
|
|
mmd=g_hash_table_lookup(mapi_decrypted_table, &mmd_key);
|
|
|
|
}
|
|
|
|
|
2002-06-04 07:03:57 +00:00
|
|
|
add_new_data_source(pinfo, mmd->tvb, "Decrypted MAPI");
|
2002-05-25 09:19:45 +00:00
|
|
|
|
|
|
|
/* decrypted PDU */
|
|
|
|
/* All from 10 minutes eyeballing. This may be wrong.
|
|
|
|
The PDU is NOT NDR encoded. So this completely new marshalling
|
|
|
|
used by MAPI needs to be figured out.
|
|
|
|
|
|
|
|
It seems that ASCII text strings always are NULL terminated,
|
|
|
|
also no obvious string-length-byte can be seen so it seems the
|
2002-08-28 21:04:11 +00:00
|
|
|
length of strings are determined by searching the terminating null
|
2002-05-25 09:19:45 +00:00
|
|
|
byte.
|
|
|
|
|
|
|
|
The first two bytes of the PDU is the length of the PDU including
|
|
|
|
the two length bytes.
|
|
|
|
The third byte may be a subcommand byte ?
|
|
|
|
|
2002-08-28 21:04:11 +00:00
|
|
|
After the PDU comes, in requests a 4 byte thing. Which is either
|
|
|
|
(not very often) 0xffffffff or something else. If it is
|
2002-05-25 09:19:45 +00:00
|
|
|
'something else' these four bytes are repeated for the matching
|
|
|
|
response packet.
|
|
|
|
In some repsonse packets, this 4 byte trailer are sometimes followed
|
|
|
|
by some other data. Unclear if this is just random padding or actual
|
|
|
|
data. Seems a bit non-random for padding though.
|
|
|
|
|
|
|
|
Some response packets have a PDU of 2 bytes only, ie only the
|
|
|
|
2 byte length field followed by the 4 byte trailer.
|
|
|
|
strange.
|
|
|
|
perhaps the 4 byte trailers, and the extra trailers have some
|
|
|
|
special meaning?
|
|
|
|
More work needs to be done in this area.
|
|
|
|
*/
|
|
|
|
it=proto_tree_add_text(tree, mmd->tvb, 0, len, "Decrypted MAPI PDU");
|
|
|
|
tr=proto_item_add_subtree(it, ett_mapi_decrypted_pdu);
|
|
|
|
|
|
|
|
pdu_len=tvb_get_letohs(mmd->tvb, 0);
|
|
|
|
proto_tree_add_uint(tr, hf_mapi_pdu_len, mmd->tvb, 0, 2, pdu_len);
|
|
|
|
|
2002-05-25 08:41:12 +00:00
|
|
|
/*XXX call dissector here */
|
2002-05-25 11:26:30 +00:00
|
|
|
proto_tree_add_item(tr, hf_mapi_decrypted_data, mmd->tvb, 2, pdu_len-2, FALSE);
|
2002-05-25 09:19:45 +00:00
|
|
|
|
|
|
|
proto_tree_add_item(tr, hf_mapi_pdu_trailer, mmd->tvb, pdu_len, 4, FALSE);
|
2002-05-25 10:25:27 +00:00
|
|
|
if(len>((guint32)pdu_len+4)){
|
2002-05-25 09:19:45 +00:00
|
|
|
proto_tree_add_item(tr, hf_mapi_pdu_extra_trailer, mmd->tvb, pdu_len+4, len-(pdu_len+4), FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-05-25 08:41:12 +00:00
|
|
|
offset+=len;
|
|
|
|
|
|
|
|
return offset;
|
|
|
|
}
|
2002-05-23 12:23:29 +00:00
|
|
|
|
|
|
|
static int
|
|
|
|
mapi_logon_rqst(tvbuff_t *tvb, int offset,
|
2004-01-19 20:10:37 +00:00
|
|
|
packet_info *pinfo, proto_tree *tree, guint8 *drep)
|
2002-05-23 12:23:29 +00:00
|
|
|
{
|
2003-02-07 22:44:54 +00:00
|
|
|
offset = dissect_ndr_cvstring(tvb, offset, pinfo, tree, drep,
|
2003-02-10 02:07:15 +00:00
|
|
|
sizeof(guint8), hf_mapi_unknown_string, TRUE, NULL);
|
2002-05-23 12:23:29 +00:00
|
|
|
|
|
|
|
DISSECT_UNKNOWN(tvb_length_remaining(tvb, offset));
|
2002-08-28 21:04:11 +00:00
|
|
|
|
2002-05-23 12:23:29 +00:00
|
|
|
return offset;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* The strings in this function are decoded properly on seen captures.
|
|
|
|
There might be offsets/padding mismatched due to potential pointer expansions
|
|
|
|
or padding bytes. Captures where this code breaks will tell us about that */
|
|
|
|
static int
|
|
|
|
mapi_logon_reply(tvbuff_t *tvb, int offset,
|
2004-01-19 20:10:37 +00:00
|
|
|
packet_info *pinfo, proto_tree *tree, guint8 *drep)
|
2002-05-23 12:23:29 +00:00
|
|
|
{
|
|
|
|
offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
|
In the policy handle hashing, handle more than one policy handle having
the same value, as an open might return handle XXX, handle XXX might
then be closed, and a subsequent handle might return handle XXX, and we
want to keep the two handles distinct to avoid, for example, displaying
handles closed before they're opened.
In policy handle open replies, store the handle name only if the
operation succeeded. We can now do that without parsing the packet
twice.
Have "dissect_nt_policy_hnd()" optionally return, through a pointer, the
protocol tree item for the handle, so that its caller can decorate the
item with the name of the handle - that's done on opens, where we do
that only if the operation succeeds.
svn path=/trunk/; revision=7787
2003-06-05 04:22:04 +00:00
|
|
|
hf_mapi_hnd, NULL, NULL, FALSE, FALSE);
|
2002-05-23 12:23:29 +00:00
|
|
|
|
|
|
|
DISSECT_UNKNOWN(20); /* this is 20 bytes, unless there are pointers */
|
|
|
|
|
2003-02-07 22:44:54 +00:00
|
|
|
offset = dissect_ndr_cvstring(tvb, offset, pinfo, tree, drep,
|
2003-02-10 02:07:15 +00:00
|
|
|
sizeof(guint8), hf_mapi_unknown_string, TRUE, NULL);
|
2002-05-23 12:23:29 +00:00
|
|
|
|
2003-05-10 02:15:04 +00:00
|
|
|
/* Was DISSECT_UNKNOWN(6), but the 1 or 2 bytes the comment that
|
|
|
|
was here referred to probably were padding, if they were seen;
|
|
|
|
in another capture, there are 5 bytes there - it's probably a
|
|
|
|
4-byte quantity, always aligned on a 4-byte boundary. */
|
|
|
|
offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
|
|
|
|
hf_mapi_unknown_long, NULL);
|
2002-05-23 12:23:29 +00:00
|
|
|
|
2003-02-07 22:44:54 +00:00
|
|
|
offset = dissect_ndr_cvstring(tvb, offset, pinfo, tree, drep,
|
2003-02-10 02:07:15 +00:00
|
|
|
sizeof(guint8), hf_mapi_unknown_string, TRUE, NULL);
|
2002-05-23 12:23:29 +00:00
|
|
|
|
|
|
|
DISSECT_UNKNOWN( tvb_length_remaining(tvb, offset)-4 );
|
|
|
|
|
|
|
|
offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
|
|
|
|
hf_mapi_rc, NULL);
|
|
|
|
|
|
|
|
return offset;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2003-10-24 00:42:16 +00:00
|
|
|
mapi_ec_do_rpc_request(tvbuff_t *tvb, int offset,
|
2004-01-19 20:10:37 +00:00
|
|
|
packet_info *pinfo, proto_tree *tree, guint8 *drep)
|
2002-05-23 12:23:29 +00:00
|
|
|
{
|
|
|
|
offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
|
In the policy handle hashing, handle more than one policy handle having
the same value, as an open might return handle XXX, handle XXX might
then be closed, and a subsequent handle might return handle XXX, and we
want to keep the two handles distinct to avoid, for example, displaying
handles closed before they're opened.
In policy handle open replies, store the handle name only if the
operation succeeded. We can now do that without parsing the packet
twice.
Have "dissect_nt_policy_hnd()" optionally return, through a pointer, the
protocol tree item for the handle, so that its caller can decorate the
item with the name of the handle - that's done on opens, where we do
that only if the operation succeeds.
svn path=/trunk/; revision=7787
2003-06-05 04:22:04 +00:00
|
|
|
hf_mapi_hnd, NULL, NULL, FALSE, FALSE);
|
2002-05-23 12:23:29 +00:00
|
|
|
|
2002-05-25 08:41:12 +00:00
|
|
|
if(!mapi_decrypt){
|
|
|
|
/* this is a unidimensional varying and conformant array of
|
2002-08-28 21:04:11 +00:00
|
|
|
encrypted data */
|
2002-05-25 08:41:12 +00:00
|
|
|
offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
|
2003-02-07 08:56:12 +00:00
|
|
|
dissect_ndr_byte_array, NDR_POINTER_REF,
|
|
|
|
"Encrypted data", hf_mapi_encrypted_data);
|
2002-05-25 08:41:12 +00:00
|
|
|
} else {
|
|
|
|
offset = mapi_decrypt_pdu(tvb, offset, pinfo, tree, drep);
|
|
|
|
}
|
2002-05-23 12:23:29 +00:00
|
|
|
|
|
|
|
/* length of encrypted data. */
|
|
|
|
offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
|
|
|
|
hf_mapi_encap_datalen, NULL);
|
|
|
|
|
|
|
|
offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
|
|
|
|
hf_mapi_unknown_short, NULL);
|
|
|
|
|
|
|
|
return offset;
|
|
|
|
}
|
|
|
|
static int
|
2003-10-24 00:42:16 +00:00
|
|
|
mapi_ec_do_rpc_reply(tvbuff_t *tvb, int offset,
|
2004-01-19 20:10:37 +00:00
|
|
|
packet_info *pinfo, proto_tree *tree, guint8 *drep)
|
2002-05-23 12:23:29 +00:00
|
|
|
{
|
|
|
|
offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
|
In the policy handle hashing, handle more than one policy handle having
the same value, as an open might return handle XXX, handle XXX might
then be closed, and a subsequent handle might return handle XXX, and we
want to keep the two handles distinct to avoid, for example, displaying
handles closed before they're opened.
In policy handle open replies, store the handle name only if the
operation succeeded. We can now do that without parsing the packet
twice.
Have "dissect_nt_policy_hnd()" optionally return, through a pointer, the
protocol tree item for the handle, so that its caller can decorate the
item with the name of the handle - that's done on opens, where we do
that only if the operation succeeds.
svn path=/trunk/; revision=7787
2003-06-05 04:22:04 +00:00
|
|
|
hf_mapi_hnd, NULL, NULL, FALSE, FALSE);
|
2002-05-23 12:23:29 +00:00
|
|
|
|
2002-05-25 08:41:12 +00:00
|
|
|
if(!mapi_decrypt){
|
|
|
|
/* this is a unidimensional varying and conformant array of
|
2002-08-28 21:04:11 +00:00
|
|
|
encrypted data */
|
2002-05-25 08:41:12 +00:00
|
|
|
offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
|
2003-02-07 08:56:12 +00:00
|
|
|
dissect_ndr_byte_array, NDR_POINTER_REF,
|
|
|
|
"Encrypted data", hf_mapi_encrypted_data);
|
2002-05-25 08:41:12 +00:00
|
|
|
} else {
|
|
|
|
offset = mapi_decrypt_pdu(tvb, offset, pinfo, tree, drep);
|
|
|
|
}
|
2002-08-28 21:04:11 +00:00
|
|
|
|
2002-05-23 12:23:29 +00:00
|
|
|
/* length of encrypted data */
|
|
|
|
offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
|
|
|
|
hf_mapi_encap_datalen, NULL);
|
|
|
|
|
|
|
|
offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
|
|
|
|
hf_mapi_rc, NULL);
|
|
|
|
|
|
|
|
return offset;
|
|
|
|
}
|
|
|
|
|
2002-05-23 12:48:28 +00:00
|
|
|
static int
|
|
|
|
mapi_logoff_rqst(tvbuff_t *tvb, int offset,
|
2004-01-19 20:10:37 +00:00
|
|
|
packet_info *pinfo, proto_tree *tree, guint8 *drep)
|
2002-05-23 12:48:28 +00:00
|
|
|
{
|
|
|
|
offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
|
In the policy handle hashing, handle more than one policy handle having
the same value, as an open might return handle XXX, handle XXX might
then be closed, and a subsequent handle might return handle XXX, and we
want to keep the two handles distinct to avoid, for example, displaying
handles closed before they're opened.
In policy handle open replies, store the handle name only if the
operation succeeded. We can now do that without parsing the packet
twice.
Have "dissect_nt_policy_hnd()" optionally return, through a pointer, the
protocol tree item for the handle, so that its caller can decorate the
item with the name of the handle - that's done on opens, where we do
that only if the operation succeeds.
svn path=/trunk/; revision=7787
2003-06-05 04:22:04 +00:00
|
|
|
hf_mapi_hnd, NULL, NULL, FALSE, FALSE);
|
2002-05-23 12:48:28 +00:00
|
|
|
|
|
|
|
return offset;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
mapi_logoff_reply(tvbuff_t *tvb, int offset,
|
2004-01-19 20:10:37 +00:00
|
|
|
packet_info *pinfo, proto_tree *tree, guint8 *drep)
|
2002-05-23 12:48:28 +00:00
|
|
|
{
|
|
|
|
offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
|
In the policy handle hashing, handle more than one policy handle having
the same value, as an open might return handle XXX, handle XXX might
then be closed, and a subsequent handle might return handle XXX, and we
want to keep the two handles distinct to avoid, for example, displaying
handles closed before they're opened.
In policy handle open replies, store the handle name only if the
operation succeeded. We can now do that without parsing the packet
twice.
Have "dissect_nt_policy_hnd()" optionally return, through a pointer, the
protocol tree item for the handle, so that its caller can decorate the
item with the name of the handle - that's done on opens, where we do
that only if the operation succeeds.
svn path=/trunk/; revision=7787
2003-06-05 04:22:04 +00:00
|
|
|
hf_mapi_hnd, NULL, NULL, FALSE, FALSE);
|
2002-05-23 12:48:28 +00:00
|
|
|
|
|
|
|
offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
|
|
|
|
hf_mapi_rc, NULL);
|
|
|
|
|
|
|
|
return offset;
|
|
|
|
}
|
|
|
|
|
2002-05-23 12:23:29 +00:00
|
|
|
|
2002-05-23 10:00:19 +00:00
|
|
|
static dcerpc_sub_dissector dcerpc_mapi_dissectors[] = {
|
2003-10-24 00:42:16 +00:00
|
|
|
{ MAPI_EC_DO_CONNECT, "EcDoConnect",
|
2002-05-23 12:23:29 +00:00
|
|
|
mapi_logon_rqst,
|
|
|
|
mapi_logon_reply },
|
2003-10-24 00:42:16 +00:00
|
|
|
{ MAPI_EC_DO_DISCONNECT,"EcDoDisconnect",
|
2002-05-23 12:48:28 +00:00
|
|
|
mapi_logoff_rqst,
|
|
|
|
mapi_logoff_reply },
|
2003-10-24 00:42:16 +00:00
|
|
|
{ MAPI_EC_DO_RPC, "EcDoRpc",
|
|
|
|
mapi_ec_do_rpc_request,
|
|
|
|
mapi_ec_do_rpc_reply },
|
|
|
|
{ MAPI_EC_GET_MORE_RPC, "EcGetMoreRpc", NULL, NULL },
|
|
|
|
{ MAPI_EC_REGISTER_PUSH_NOTIFICATION, "EcRRegisterPushNotification",
|
|
|
|
NULL, NULL },
|
|
|
|
{ MAPI_EC_UNREGISTER_PUSH_NOTIFICATION, "EcRUnregisterPushNotification",
|
|
|
|
NULL, NULL },
|
|
|
|
{ MAPI_EC_DUMMY_RPC, "EcDummyRpc", NULL, NULL },
|
|
|
|
{ MAPI_EC_GET_DC_NAME, "EcRGetDCName", NULL, NULL },
|
|
|
|
{ MAPI_EC_NET_GET_DC_NAME, "EcRNetGetDCName", NULL, NULL },
|
|
|
|
{ MAPI_EC_DO_RPC_EXT, "EcDoRpcExt", NULL, NULL },
|
2002-05-31 00:31:13 +00:00
|
|
|
{0, NULL, NULL, NULL }
|
2002-05-23 10:00:19 +00:00
|
|
|
};
|
|
|
|
|
2002-08-28 21:04:11 +00:00
|
|
|
void
|
2002-05-23 10:00:19 +00:00
|
|
|
proto_register_dcerpc_mapi(void)
|
|
|
|
{
|
2002-05-23 12:23:29 +00:00
|
|
|
|
|
|
|
static hf_register_info hf[] = {
|
2003-06-26 04:30:31 +00:00
|
|
|
{ &hf_mapi_opnum,
|
|
|
|
{ "Operation", "mapi.opnum", FT_UINT16, BASE_DEC,
|
|
|
|
NULL, 0x0, "", HFILL }},
|
|
|
|
|
2002-05-23 12:23:29 +00:00
|
|
|
{ &hf_mapi_hnd,
|
2002-08-28 21:04:11 +00:00
|
|
|
{ "Context Handle", "mapi.hnd", FT_BYTES, BASE_NONE,
|
2002-05-23 12:23:29 +00:00
|
|
|
NULL, 0x0, "", HFILL }},
|
|
|
|
|
|
|
|
{ &hf_mapi_rc,
|
2002-08-28 21:04:11 +00:00
|
|
|
{ "Return code", "mapi.rc", FT_UINT32, BASE_HEX,
|
2002-05-23 12:23:29 +00:00
|
|
|
VALS (NT_errors), 0x0, "", HFILL }},
|
|
|
|
|
|
|
|
{ &hf_mapi_unknown_string,
|
|
|
|
{ "Unknown string", "mapi.unknown_string", FT_STRING, BASE_NONE,
|
|
|
|
NULL, 0, "Unknown string. If you know what this is, contact ethereal developers.", HFILL }},
|
|
|
|
|
|
|
|
{ &hf_mapi_unknown_short,
|
|
|
|
{ "Unknown short", "mapi.unknown_short", FT_UINT16, BASE_HEX,
|
|
|
|
NULL, 0, "Unknown short. If you know what this is, contact ethereal developers.", HFILL }},
|
|
|
|
|
2003-05-10 02:15:04 +00:00
|
|
|
{ &hf_mapi_unknown_long,
|
|
|
|
{ "Unknown long", "mapi.unknown_long", FT_UINT32, BASE_HEX,
|
|
|
|
NULL, 0, "Unknown long. If you know what this is, contact ethereal developers.", HFILL }},
|
|
|
|
|
2002-05-23 12:23:29 +00:00
|
|
|
{ &hf_mapi_encap_datalen,
|
2002-08-28 21:04:11 +00:00
|
|
|
{ "Length", "mapi.encap_len", FT_UINT16, BASE_DEC,
|
2002-05-23 12:23:29 +00:00
|
|
|
NULL, 0x0, "Length of encapsulated/encrypted data", HFILL }},
|
|
|
|
|
2003-02-07 08:56:12 +00:00
|
|
|
{ &hf_mapi_encrypted_data,
|
|
|
|
{ "Encrypted data", "mapi.encrypted_data", FT_BYTES, BASE_HEX,
|
|
|
|
NULL, 0, "Encrypted data", HFILL }},
|
|
|
|
|
2002-05-25 08:41:12 +00:00
|
|
|
{ &hf_mapi_decrypted_data_maxlen,
|
2002-08-28 21:04:11 +00:00
|
|
|
{ "Max Length", "mapi.decrypted.data.maxlen", FT_UINT32, BASE_DEC,
|
2002-05-25 08:41:12 +00:00
|
|
|
NULL, 0x0, "Maximum size of buffer for decrypted data", HFILL }},
|
|
|
|
|
|
|
|
{ &hf_mapi_decrypted_data_offset,
|
2002-08-28 21:04:11 +00:00
|
|
|
{ "Offset", "mapi.decrypted.data.offset", FT_UINT32, BASE_DEC,
|
2002-05-25 08:41:12 +00:00
|
|
|
NULL, 0x0, "Offset into buffer for decrypted data", HFILL }},
|
|
|
|
|
|
|
|
{ &hf_mapi_decrypted_data_len,
|
2002-08-28 21:04:11 +00:00
|
|
|
{ "Length", "mapi.decrypted.data.len", FT_UINT32, BASE_DEC,
|
2002-05-25 08:41:12 +00:00
|
|
|
NULL, 0x0, "Used size of buffer for decrypted data", HFILL }},
|
|
|
|
|
|
|
|
{ &hf_mapi_decrypted_data,
|
2002-08-28 21:04:11 +00:00
|
|
|
{ "Decrypted data", "mapi.decrypted.data", FT_BYTES, BASE_HEX,
|
2002-05-25 08:41:12 +00:00
|
|
|
NULL, 0x0, "Decrypted data", HFILL }},
|
2002-05-23 12:23:29 +00:00
|
|
|
|
2002-05-25 09:19:45 +00:00
|
|
|
{ &hf_mapi_pdu_len,
|
2002-08-28 21:04:11 +00:00
|
|
|
{ "Length", "mapi.pdu.len", FT_UINT16, BASE_DEC,
|
2002-05-25 09:19:45 +00:00
|
|
|
NULL, 0x0, "Size of the command PDU", HFILL }},
|
|
|
|
|
|
|
|
{ &hf_mapi_pdu_trailer,
|
2002-08-28 21:04:11 +00:00
|
|
|
{ "Trailer", "mapi.pdu.trailer", FT_UINT32, BASE_HEX,
|
2002-05-25 09:19:45 +00:00
|
|
|
NULL, 0x0, "If you know what this is, contact ethereal developers", HFILL }},
|
|
|
|
|
|
|
|
{ &hf_mapi_pdu_extra_trailer,
|
2002-08-28 21:04:11 +00:00
|
|
|
{ "unknown", "mapi.pdu.extra_trailer", FT_BYTES, BASE_HEX,
|
2002-05-31 00:31:13 +00:00
|
|
|
NULL, 0x0, "If you know what this is, contact ethereal developers", HFILL }}
|
2002-05-23 12:23:29 +00:00
|
|
|
};
|
|
|
|
|
2002-05-25 08:41:12 +00:00
|
|
|
|
2002-05-23 10:00:19 +00:00
|
|
|
static gint *ett[] = {
|
|
|
|
&ett_dcerpc_mapi,
|
2002-05-31 00:31:13 +00:00
|
|
|
&ett_mapi_decrypted_pdu
|
2002-05-23 10:00:19 +00:00
|
|
|
};
|
2002-05-25 08:41:12 +00:00
|
|
|
module_t *mapi_module;
|
2002-05-23 10:00:19 +00:00
|
|
|
|
|
|
|
proto_dcerpc_mapi = proto_register_protocol(
|
|
|
|
"Microsoft Exchange MAPI", "MAPI", "mapi");
|
|
|
|
|
2002-08-28 21:04:11 +00:00
|
|
|
proto_register_field_array(proto_dcerpc_mapi, hf,
|
2002-05-23 12:23:29 +00:00
|
|
|
array_length(hf));
|
2002-05-23 10:00:19 +00:00
|
|
|
proto_register_subtree_array(ett, array_length(ett));
|
2002-05-25 08:41:12 +00:00
|
|
|
mapi_module = prefs_register_protocol(proto_dcerpc_mapi, NULL);
|
2003-01-28 23:56:40 +00:00
|
|
|
prefs_register_bool_preference(mapi_module, "decrypt",
|
2002-05-25 08:41:12 +00:00
|
|
|
"Decrypt MAPI PDUs",
|
|
|
|
"Whether the dissector should decrypt MAPI PDUs",
|
|
|
|
&mapi_decrypt);
|
|
|
|
register_init_routine(mapi_decrypt_init);
|
2002-05-23 10:00:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
proto_reg_handoff_dcerpc_mapi(void)
|
|
|
|
{
|
|
|
|
/* Register protocol as dcerpc */
|
|
|
|
|
2002-08-28 21:04:11 +00:00
|
|
|
dcerpc_init_uuid(proto_dcerpc_mapi, ett_dcerpc_mapi,
|
|
|
|
&uuid_dcerpc_mapi, ver_dcerpc_mapi,
|
2003-06-26 04:30:31 +00:00
|
|
|
dcerpc_mapi_dissectors, hf_mapi_opnum);
|
2002-05-23 10:00:19 +00:00
|
|
|
}
|