#include <epan/crypt/crypt-des.h>
#include "packet-dcerpc.h"
#include "packet-gssapi.h"
-#include <epan/crc32.h>
+#include <wsutil/crc32.h>
#include "packet-ntlmssp.h"
static const value_string ntlmssp_message_types[] = {
{ NTLMSSP_NEGOTIATE, "NTLMSSP_NEGOTIATE" },
{ NTLMSSP_CHALLENGE, "NTLMSSP_CHALLENGE" },
- { NTLMSSP_AUTH, "NTLMSSP_AUTH" },
- { NTLMSSP_UNKNOWN, "NTLMSSP_UNKNOWN" },
+ { NTLMSSP_AUTH, "NTLMSSP_AUTH" },
+ { NTLMSSP_UNKNOWN, "NTLMSSP_UNKNOWN" },
{ 0, NULL }
};
*
* See also
*
- * http://davenport.sourceforge.net/ntlm.html
+ * http://davenport.sourceforge.net/ntlm.html
*
* although that document says that:
*
- * 0x00010000 is "Target Type Domain";
- * 0x00020000 is "Target Type Server"
- * 0x00040000 is "Target Type Share";
+ * 0x00010000 is "Target Type Domain";
+ * 0x00020000 is "Target Type Server"
+ * 0x00040000 is "Target Type Share";
*
* and that 0x00100000, 0x00200000, and 0x00400000 are
* "Request Init Response", "Request Accept Response", and
* http://msdn2.microsoft.com/en-us/library/cc236621.aspx
*
*/
-#define NTLMSSP_NEGOTIATE_UNICODE 0x00000001
-#define NTLMSSP_NEGOTIATE_OEM 0x00000002
-#define NTLMSSP_REQUEST_TARGET 0x00000004
-#define NTLMSSP_NEGOTIATE_00000008 0x00000008
-#define NTLMSSP_NEGOTIATE_SIGN 0x00000010
-#define NTLMSSP_NEGOTIATE_SEAL 0x00000020
-#define NTLMSSP_NEGOTIATE_DATAGRAM 0x00000040
-#define NTLMSSP_NEGOTIATE_LM_KEY 0x00000080
-#define NTLMSSP_NEGOTIATE_00000100 0x00000100
-#define NTLMSSP_NEGOTIATE_NTLM 0x00000200
-#define NTLMSSP_NEGOTIATE_NT_ONLY 0x00000400
-#define NTLMSSP_NEGOTIATE_00000800 0x00000800
-#define NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED 0x00001000
+#define NTLMSSP_NEGOTIATE_UNICODE 0x00000001
+#define NTLMSSP_NEGOTIATE_OEM 0x00000002
+#define NTLMSSP_REQUEST_TARGET 0x00000004
+#define NTLMSSP_NEGOTIATE_00000008 0x00000008
+#define NTLMSSP_NEGOTIATE_SIGN 0x00000010
+#define NTLMSSP_NEGOTIATE_SEAL 0x00000020
+#define NTLMSSP_NEGOTIATE_DATAGRAM 0x00000040
+#define NTLMSSP_NEGOTIATE_LM_KEY 0x00000080
+#define NTLMSSP_NEGOTIATE_00000100 0x00000100
+#define NTLMSSP_NEGOTIATE_NTLM 0x00000200
+#define NTLMSSP_NEGOTIATE_NT_ONLY 0x00000400
+#define NTLMSSP_NEGOTIATE_00000800 0x00000800
+#define NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED 0x00001000
#define NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED 0x00002000
-#define NTLMSSP_NEGOTIATE_00004000 0x00004000
-#define NTLMSSP_NEGOTIATE_ALWAYS_SIGN 0x00008000
-#define NTLMSSP_TARGET_TYPE_DOMAIN 0x00010000
-#define NTLMSSP_TARGET_TYPE_SERVER 0x00020000
-#define NTLMSSP_TARGET_TYPE_SHARE 0x00040000
-#define NTLMSSP_NEGOTIATE_EXTENDED_SECURITY 0x00080000
-#define NTLMSSP_NEGOTIATE_IDENTIFY 0x00100000
-#define NTLMSSP_NEGOTIATE_00200000 0x00200000
-#define NTLMSSP_REQUEST_NON_NT_SESSION 0x00400000
-#define NTLMSSP_NEGOTIATE_TARGET_INFO 0x00800000
-#define NTLMSSP_NEGOTIATE_01000000 0x01000000
-#define NTLMSSP_NEGOTIATE_VERSION 0x02000000
-#define NTLMSSP_NEGOTIATE_04000000 0x04000000
-#define NTLMSSP_NEGOTIATE_08000000 0x08000000
-#define NTLMSSP_NEGOTIATE_10000000 0x10000000
-#define NTLMSSP_NEGOTIATE_128 0x20000000
-#define NTLMSSP_NEGOTIATE_KEY_EXCH 0x40000000
-#define NTLMSSP_NEGOTIATE_56 0x80000000
+#define NTLMSSP_NEGOTIATE_00004000 0x00004000
+#define NTLMSSP_NEGOTIATE_ALWAYS_SIGN 0x00008000
+#define NTLMSSP_TARGET_TYPE_DOMAIN 0x00010000
+#define NTLMSSP_TARGET_TYPE_SERVER 0x00020000
+#define NTLMSSP_TARGET_TYPE_SHARE 0x00040000
+#define NTLMSSP_NEGOTIATE_EXTENDED_SECURITY 0x00080000
+#define NTLMSSP_NEGOTIATE_IDENTIFY 0x00100000
+#define NTLMSSP_NEGOTIATE_00200000 0x00200000
+#define NTLMSSP_REQUEST_NON_NT_SESSION 0x00400000
+#define NTLMSSP_NEGOTIATE_TARGET_INFO 0x00800000
+#define NTLMSSP_NEGOTIATE_01000000 0x01000000
+#define NTLMSSP_NEGOTIATE_VERSION 0x02000000
+#define NTLMSSP_NEGOTIATE_04000000 0x04000000
+#define NTLMSSP_NEGOTIATE_08000000 0x08000000
+#define NTLMSSP_NEGOTIATE_10000000 0x10000000
+#define NTLMSSP_NEGOTIATE_128 0x20000000
+#define NTLMSSP_NEGOTIATE_KEY_EXCH 0x40000000
+#define NTLMSSP_NEGOTIATE_56 0x80000000
static int proto_ntlmssp = -1;
static int hf_ntlmssp_auth = -1;
static int hf_ntlmssp_blob_len = -1;
static int hf_ntlmssp_blob_maxlen = -1;
static int hf_ntlmssp_blob_offset = -1;
+static int hf_ntlmssp_version = -1;
static int hf_ntlmssp_version_major = -1;
static int hf_ntlmssp_version_minor = -1;
static int hf_ntlmssp_version_build_number = -1;
static int hf_ntlmssp_version_ntlm_current_revision = -1;
-static int hf_ntlmssp_address_list = -1;
-static int hf_ntlmssp_address_list_len = -1;
-static int hf_ntlmssp_address_list_maxlen = -1;
-static int hf_ntlmssp_address_list_offset = -1;
-static int hf_ntlmssp_address_list_server_nb = -1;
-static int hf_ntlmssp_address_list_domain_nb = -1;
-static int hf_ntlmssp_address_list_server_dns = -1;
-static int hf_ntlmssp_address_list_domain_dns = -1;
-static int hf_ntlmssp_address_list_forest_dns = -1;
-static int hf_ntlmssp_address_list_terminator = -1;
-static int hf_ntlmssp_address_list_item_type = -1;
-static int hf_ntlmssp_address_list_item_len = -1;
-static int hf_ntlmssp_address_list_item_content = -1;
+
+static int hf_ntlmssp_challenge_target_info = -1;
+static int hf_ntlmssp_challenge_target_info_len = -1;
+static int hf_ntlmssp_challenge_target_info_maxlen = -1;
+static int hf_ntlmssp_challenge_target_info_offset = -1;
+
+static int hf_ntlmssp_challenge_target_info_item_type = -1;
+static int hf_ntlmssp_challenge_target_info_item_len = -1;
+
+static int hf_ntlmssp_challenge_target_info_end = -1;
+static int hf_ntlmssp_challenge_target_info_nb_computer_name = -1;
+static int hf_ntlmssp_challenge_target_info_nb_domain_name = -1;
+static int hf_ntlmssp_challenge_target_info_dns_computer_name = -1;
+static int hf_ntlmssp_challenge_target_info_dns_domain_name = -1;
+static int hf_ntlmssp_challenge_target_info_dns_tree_name = -1;
+static int hf_ntlmssp_challenge_target_info_flags = -1;
+static int hf_ntlmssp_challenge_target_info_timestamp = -1;
+static int hf_ntlmssp_challenge_target_info_restrictions = -1;
+static int hf_ntlmssp_challenge_target_info_target_name =-1;
+static int hf_ntlmssp_challenge_target_info_channel_bindings =-1;
+
+static int hf_ntlmssp_ntlmv2_response_item_type = -1;
+static int hf_ntlmssp_ntlmv2_response_item_len = -1;
+
+static int hf_ntlmssp_ntlmv2_response_end = -1;
+static int hf_ntlmssp_ntlmv2_response_nb_computer_name = -1;
+static int hf_ntlmssp_ntlmv2_response_nb_domain_name = -1;
+static int hf_ntlmssp_ntlmv2_response_dns_computer_name = -1;
+static int hf_ntlmssp_ntlmv2_response_dns_domain_name = -1;
+static int hf_ntlmssp_ntlmv2_response_dns_tree_name = -1;
+static int hf_ntlmssp_ntlmv2_response_flags = -1;
+static int hf_ntlmssp_ntlmv2_response_timestamp = -1;
+static int hf_ntlmssp_ntlmv2_response_restrictions = -1;
+static int hf_ntlmssp_ntlmv2_response_target_name =-1;
+static int hf_ntlmssp_ntlmv2_response_channel_bindings =-1;
+
static int hf_ntlmssp_message_integrity_code = -1;
static int hf_ntlmssp_verf = -1;
static int hf_ntlmssp_verf_vers = -1;
static int hf_ntlmssp_verf_crc32 = -1;
static int hf_ntlmssp_verf_sequence = -1;
static int hf_ntlmssp_decrypted_payload = -1;
+
static int hf_ntlmssp_ntlmv2_response = -1;
static int hf_ntlmssp_ntlmv2_response_hmac = -1;
static int hf_ntlmssp_ntlmv2_response_header = -1;
static int hf_ntlmssp_ntlmv2_response_time = -1;
static int hf_ntlmssp_ntlmv2_response_chal = -1;
static int hf_ntlmssp_ntlmv2_response_unknown = -1;
-static int hf_ntlmssp_ntlmv2_response_name = -1;
-static int hf_ntlmssp_ntlmv2_response_name_type = -1;
-static int hf_ntlmssp_ntlmv2_response_name_len = -1;
-static int hf_ntlmssp_ntlmv2_response_restriction = -1;
-static int hf_ntlmssp_ntlmv2_response_client_time = -1;
static gint ett_ntlmssp = -1;
static gint ett_ntlmssp_negotiate_flags = -1;
static gint ett_ntlmssp_string = -1;
static gint ett_ntlmssp_blob = -1;
static gint ett_ntlmssp_version = -1;
-static gint ett_ntlmssp_address_list = -1;
-static gint ett_ntlmssp_address_list_item = -1;
+static gint ett_ntlmssp_challenge_target_info = -1;
+static gint ett_ntlmssp_challenge_target_info_item = -1;
static gint ett_ntlmssp_ntlmv2_response = -1;
-static gint ett_ntlmssp_ntlmv2_response_name = -1;
+static gint ett_ntlmssp_ntlmv2_response_item = -1;
/* Configuration variables */
const char *gbl_nt_password = NULL;
}
fprintf(stderr,"%s",txt2);
}
-/*
- static void printnchar(const guint8* tab,int nb,char* txt,char* txt2)
+#if 0
+static void printnchar(const guint8* tab,int nb,char* txt,char* txt2)
{
int i=0;
fprintf(stderr,"%s ",txt);
}
fprintf(stderr,"%s",txt2);
}
-*/
+#endif
#else
static void printnbyte(const guint8* tab _U_,int nb _U_, const char* txt _U_,const char* txt2 _U_)
{
}
#endif
+
/*
* GSlist of decrypted payloads.
*/
static GSList *decrypted_payloads;
-int LEBE_Convert(int value)
+#if 0
+static int
+LEBE_Convert(int value)
{
char a,b,c,d;
/* Get each byte */
d=(value&0xFF000000) >> 24;
return (a << 24) | (b << 16) | (c << 8) | d;
}
+#endif
+
/*
Perform a DES encryption with a 16 bit key and 8bit data item.
It's in fact 3 susbsequent call to crypt_des_ecb with a 7 bit key.
Missing bits for the key are replaced by 0;
Returns output in response, which is expected to be 24 bytes.
*/
-static int crypt_des_ecb_long(guint8 *response,
- const guint8 *key,
- const guint8 *data)
+static int
+crypt_des_ecb_long(guint8 *response,
+ const guint8 *key,
+ const guint8 *data)
{
guint8 pw21[21]; /* 21 bytes place for the needed key */
return 1;
}
+
/*
Generate a challenge response, given an eight byte challenge and
either the NT or the Lan Manager password hash (16 bytes).
Returns output in response, which is expected to be 24 bytes.
*/
-static int ntlmssp_generate_challenge_response(guint8 *response,
- const guint8 *passhash,
- const guint8 *challenge)
+static int
+ntlmssp_generate_challenge_response(guint8 *response,
+ const guint8 *passhash,
+ const guint8 *challenge)
{
guint8 pw21[21]; /* Password hash padded to 21 bytes */
/* Ultra simple ainsi to unicode converter, will only work for ascii password ...*/
-static void str_to_unicode(const char *nt_password, char *nt_password_unicode)
+static void
+str_to_unicode(const char *nt_password, char *nt_password_unicode)
{
size_t password_len = 0;
size_t i;
}
}
}
+
#if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
static guint32
get_md4pass_list(md4_pass** p_pass_list,const char* nt_password)
{
- guint32 nb_pass = 0;
- enc_key_t *ek;
- unsigned char nt_password_hash[NTLMSSP_KEY_LEN];
- int password_len = 0;
- char nt_password_unicode[256];
- md4_pass* pass_list;
- int i = 0;
- if(!krb_decrypt){
- pass_list=NULL;
- return 0;
- }
- read_keytab_file_from_preferences();
-
- for(ek=enc_key_list;ek;ek=ek->next){
- if( ek->keylength == NTLMSSP_KEY_LEN ) {
- nb_pass++;
- }
- }
- memset(nt_password_hash,0,NTLMSSP_KEY_LEN);
- if (nt_password[0] != '\0' && ( strlen(nt_password) < 129 )) {
- nb_pass++;
- password_len = strlen(nt_password);
- str_to_unicode(nt_password,nt_password_unicode);
- crypt_md4(nt_password_hash,nt_password_unicode,password_len*2);
- }
- if( nb_pass == 0 ) {
- /* Unable to calculate the session key without a password or if password is more than 128 char ......*/
- return 0;
- }
- i = 0;
- *p_pass_list = ep_alloc(nb_pass*sizeof(md4_pass));
- pass_list=*p_pass_list;
-
- if( memcmp(nt_password_hash,gbl_zeros,NTLMSSP_KEY_LEN) != 0 ) {
- memcpy(pass_list[i].md4,nt_password_hash,NTLMSSP_KEY_LEN);
- i = 1;
- }
- for(ek=enc_key_list;ek;ek=ek->next){
- if( ek->keylength == NTLMSSP_KEY_LEN ) {
- memcpy(pass_list[i].md4,ek->keyvalue,NTLMSSP_KEY_LEN);
- i++;
- }
- }
- return nb_pass;
+ guint32 nb_pass = 0;
+ enc_key_t *ek;
+ unsigned char nt_password_hash[NTLMSSP_KEY_LEN];
+ int password_len = 0;
+ char nt_password_unicode[256];
+ md4_pass* pass_list;
+ int i = 0;
+ if(!krb_decrypt){
+ pass_list=NULL;
+ return 0;
+ }
+ read_keytab_file_from_preferences();
+
+ for(ek=enc_key_list;ek;ek=ek->next){
+ if( ek->keylength == NTLMSSP_KEY_LEN ) {
+ nb_pass++;
+ }
+ }
+ memset(nt_password_hash,0,NTLMSSP_KEY_LEN);
+ if (nt_password[0] != '\0' && ( strlen(nt_password) < 129 )) {
+ nb_pass++;
+ password_len = strlen(nt_password);
+ str_to_unicode(nt_password,nt_password_unicode);
+ crypt_md4(nt_password_hash,nt_password_unicode,password_len*2);
+ }
+ if( nb_pass == 0 ) {
+ /* Unable to calculate the session key without a password or if password is more than 128 char ......*/
+ return 0;
+ }
+ i = 0;
+ *p_pass_list = ep_alloc(nb_pass*sizeof(md4_pass));
+ pass_list=*p_pass_list;
+
+ if( memcmp(nt_password_hash,gbl_zeros,NTLMSSP_KEY_LEN) != 0 ) {
+ memcpy(pass_list[i].md4,nt_password_hash,NTLMSSP_KEY_LEN);
+ i = 1;
+ }
+ for(ek=enc_key_list;ek;ek=ek->next){
+ if( ek->keylength == NTLMSSP_KEY_LEN ) {
+ memcpy(pass_list[i].md4,ek->keyvalue,NTLMSSP_KEY_LEN);
+ i++;
+ }
+ }
+ return nb_pass;
}
#endif
-/* Create an NTLMSSP version 2
+
+/* Create an NTLMSSP version 2 key
*/
static void
create_ntlmssp_v2_key(const char *nt_password _U_, const guint8 *serverchallenge , const guint8 *clientchallenge ,
- guint8 *sessionkey ,const guint8 *encryptedsessionkey , int flags , ntlmssp_blob ntlm_response, ntlmssp_blob lm_response _U_, ntlmssp_header_t *ntlmssph ) {
+ guint8 *sessionkey ,const guint8 *encryptedsessionkey , int flags ,
+ const ntlmssp_blob *ntlm_response, const ntlmssp_blob *lm_response _U_, ntlmssp_header_t *ntlmssph )
+{
char domain_name_unicode[256];
char user_uppercase[256];
char buf[512];
memset(user_uppercase,0,256);
user_len = strlen(ntlmssph->acct_name);
if( user_len < 129 ) {
- memset(buf,0,512);
- str_to_unicode(ntlmssph->acct_name,buf);
- for (j = 0; j < (2*user_len); j++) {
- if( buf[j] != '\0' ) {
- user_uppercase[j] = toupper(buf[j]);
- }
- }
+ memset(buf,0,512);
+ str_to_unicode(ntlmssph->acct_name,buf);
+ for (j = 0; j < (2*user_len); j++) {
+ if( buf[j] != '\0' ) {
+ user_uppercase[j] = toupper(buf[j]);
+ }
+ }
}
else {
- /* Unable to calculate the session not enought space in buffer, note this is unlikely to happen but ......*/
- return;
+ /* Unable to calculate the session not enought space in buffer, note this is unlikely to happen but ......*/
+ return;
}
domain_len = strlen(ntlmssph->domain_name);
if( domain_len < 129 ) {
/* NT proof = First NTLMSSP_KEY_LEN bytes of NT response */
memset(buf,0,512);
memcpy(buf,serverchallenge,8);
- memcpy(buf+8,ntlm_response.contents+NTLMSSP_KEY_LEN,ntlm_response.length-NTLMSSP_KEY_LEN);
- md5_hmac(buf,ntlm_response.length-8,ntowf,NTLMSSP_KEY_LEN,nt_proof);
+ memcpy(buf+8,ntlm_response->contents+NTLMSSP_KEY_LEN,ntlm_response->length-NTLMSSP_KEY_LEN);
+ md5_hmac(buf,ntlm_response->length-8,ntowf,NTLMSSP_KEY_LEN,nt_proof);
printnbyte(nt_proof,NTLMSSP_KEY_LEN,"NT proof: ","\n");
- if( !memcmp(nt_proof,ntlm_response.contents,NTLMSSP_KEY_LEN) ) {
+ if( !memcmp(nt_proof,ntlm_response->contents,NTLMSSP_KEY_LEN) ) {
found = 1;
break;
}
*/
static void
create_ntlmssp_v1_key(const char *nt_password, const guint8 *serverchallenge, const guint8 *clientchallenge,
- guint8 *sessionkey,const guint8 *encryptedsessionkey, int flags, const guint8 *ref_nt_challenge_response,const guint8 *ref_lm_challenge_response)
+ guint8 *sessionkey,const guint8 *encryptedsessionkey, int flags,
+ const guint8 *ref_nt_challenge_response,const guint8 *ref_lm_challenge_response)
{
unsigned char lm_password_upper[NTLMSSP_KEY_LEN];
unsigned char lm_password_hash[NTLMSSP_KEY_LEN];
crypt_des_ecb(lm_password_hash, lmhash_key, lm_password_upper, 1);
crypt_des_ecb(lm_password_hash+8, lmhash_key, lm_password_upper+7, 1);
ntlmssp_generate_challenge_response(lm_challenge_response,
- lm_password_hash, serverchallenge);
+ lm_password_hash, serverchallenge);
memcpy(sessionbasekey,lm_password_hash,NTLMSSP_KEY_LEN);
}
else {
memcpy(sessionkey,keyexchangekey,NTLMSSP_KEY_LEN);
}
}
+
static void
get_siging_key(guint8 *sign_key_server,guint8* sign_key_client,const guint8 key[NTLMSSP_KEY_LEN], int keylen)
{
/* We return either a 128 or 64 bit key
*/
static void
-get_sealing_rc4key(const guint8 exportedsessionkey[NTLMSSP_KEY_LEN] ,const int flags ,int *keylen ,guint8 *clientsealkey ,guint8 *serversealkey)
+get_sealing_rc4key(const guint8 exportedsessionkey[NTLMSSP_KEY_LEN] ,const int flags ,int *keylen ,
+ guint8 *clientsealkey ,guint8 *serversealkey)
{
md5_state_t md5state;
md5_state_t md5state2;
clientsealkey[7]=0xb0;
}
}
- serversealkey = memcpy(serversealkey,clientsealkey,*keylen);
+ memcpy(serversealkey,clientsealkey,*keylen);
}
}
/* Create an NTLMSSP version 1 key.
*/
static int
dissect_ntlmssp_string (tvbuff_t *tvb, int offset,
- proto_tree *ntlmssp_tree,
- gboolean unicode_strings,
- int string_hf, int *start, int *end,
- const char **stringp)
+ proto_tree *ntlmssp_tree,
+ gboolean unicode_strings,
+ int string_hf, int *start, int *end,
+ const char **stringp)
{
proto_tree *tree = NULL;
proto_item *tf = NULL;
int result_length;
guint16 bc;
- *start = (string_offset > offset+8 ? string_offset : tvb_reported_length(tvb));
+ *start = (string_offset > offset+8 ? string_offset : (signed)tvb_reported_length(tvb));
if (0 == string_length) {
*end = *start;
if (ntlmssp_tree)
- proto_tree_add_string(ntlmssp_tree, string_hf, tvb,
- offset, 8, "NULL");
+ proto_tree_add_string(ntlmssp_tree, string_hf, tvb,
+ offset, 8, "NULL");
if (stringp != NULL)
*stringp = "";
return offset+8;
bc = result_length = string_length;
string_text = get_unicode_or_ascii_string(tvb, &string_offset,
- unicode_strings, &result_length,
- FALSE, TRUE, &bc);
+ unicode_strings, &result_length,
+ FALSE, TRUE, &bc);
if (stringp != NULL) {
if (!string_text) string_text = ""; /* Make sure we don't blow up later */
if (ntlmssp_tree) {
tf = proto_tree_add_string(ntlmssp_tree, string_hf, tvb,
- string_offset, result_length, string_text);
+ string_offset, result_length, string_text);
tree = proto_item_add_subtree(tf, ett_ntlmssp_string);
}
proto_tree_add_uint(tree, hf_ntlmssp_string_len,
- tvb, offset, 2, string_length);
+ tvb, offset, 2, string_length);
offset += 2;
proto_tree_add_uint(tree, hf_ntlmssp_string_maxlen,
- tvb, offset, 2, string_maxlen);
+ tvb, offset, 2, string_maxlen);
offset += 2;
proto_tree_add_uint(tree, hf_ntlmssp_string_offset,
- tvb, offset, 4, string_offset);
+ tvb, offset, 4, string_offset);
offset += 4;
*end = string_offset + string_length;
*/
static int
dissect_ntlmssp_blob (tvbuff_t *tvb, int offset,
- proto_tree *ntlmssp_tree,
- int blob_hf, int *end, ntlmssp_blob *result)
+ proto_tree *ntlmssp_tree,
+ int blob_hf, int *end, ntlmssp_blob *result)
{
proto_item *tf = NULL;
proto_tree *tree = NULL;
if (0 == blob_length) {
*end = (blob_offset > ((guint)offset)+8 ? blob_offset : ((guint)offset)+8);
if (ntlmssp_tree)
- proto_tree_add_text(ntlmssp_tree, tvb, offset, 8, "%s: Empty",
- proto_registrar_get_name(blob_hf));
+ proto_tree_add_text(ntlmssp_tree, tvb, offset, 8, "%s: Empty",
+ proto_registrar_get_name(blob_hf));
return offset+8;
}
if (ntlmssp_tree) {
tf = proto_tree_add_item (ntlmssp_tree, blob_hf, tvb,
- blob_offset, blob_length, FALSE);
+ blob_offset, blob_length, FALSE);
tree = proto_item_add_subtree(tf, ett_ntlmssp_blob);
}
proto_tree_add_uint(tree, hf_ntlmssp_blob_len,
- tvb, offset, 2, blob_length);
+ tvb, offset, 2, blob_length);
offset += 2;
proto_tree_add_uint(tree, hf_ntlmssp_blob_maxlen,
- tvb, offset, 2, blob_maxlen);
+ tvb, offset, 2, blob_maxlen);
offset += 2;
proto_tree_add_uint(tree, hf_ntlmssp_blob_offset,
- tvb, offset, 4, blob_offset);
+ tvb, offset, 4, blob_offset);
offset += 4;
*end = blob_offset + blob_length;
if (blob_length < MAX_BLOB_SIZE)
{
tvb_memcpy(tvb, result->contents, blob_offset, blob_length);
- if (blob_hf == hf_ntlmssp_auth_lmresponse && !(memcmp(tvb->real_data+blob_offset+8,"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",NTLMSSP_KEY_LEN)))
+ if (blob_hf == hf_ntlmssp_auth_lmresponse && !(tvb_memeql(tvb, blob_offset+8, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", NTLMSSP_KEY_LEN)))
{
proto_tree_add_item (ntlmssp_tree,
- hf_ntlmssp_ntlm_client_challenge,
- tvb, blob_offset, 8, FALSE);
+ hf_ntlmssp_ntlm_client_challenge,
+ tvb, blob_offset, 8, ENC_NA);
}
}
}
if (blob_hf == hf_ntlmssp_auth_ntresponse && blob_length > 24)
{
proto_tree_add_item (ntlmssp_tree,
- hf_ntlmssp_ntlm_client_challenge,
- tvb, blob_offset+32, 8, FALSE);
- dissect_ntlmv2_response(tvb, tree, blob_offset, blob_length);
+ hf_ntlmssp_ntlm_client_challenge,
+ tvb, blob_offset+32, 8, ENC_NA);
+ dissect_ntlmv2_response(tvb, tree, blob_offset, blob_length);
}
return offset;
static int
dissect_ntlmssp_negotiate_flags (tvbuff_t *tvb, int offset,
- proto_tree *ntlmssp_tree,
- guint32 negotiate_flags)
+ proto_tree *ntlmssp_tree,
+ guint32 negotiate_flags)
{
proto_tree *negotiate_flags_tree = NULL;
proto_item *tf = NULL;
if (ntlmssp_tree) {
tf = proto_tree_add_uint (ntlmssp_tree,
- hf_ntlmssp_negotiate_flags,
- tvb, offset, 4, negotiate_flags);
+ hf_ntlmssp_negotiate_flags,
+ tvb, offset, 4, negotiate_flags);
negotiate_flags_tree = proto_item_add_subtree (tf, ett_ntlmssp_negotiate_flags);
}
proto_tree_add_boolean (negotiate_flags_tree,
- hf_ntlmssp_negotiate_flags_80000000,
- tvb, offset, 4, negotiate_flags);
+ hf_ntlmssp_negotiate_flags_80000000,
+ tvb, offset, 4, negotiate_flags);
proto_tree_add_boolean (negotiate_flags_tree,
- hf_ntlmssp_negotiate_flags_40000000,
- tvb, offset, 4, negotiate_flags);
+ hf_ntlmssp_negotiate_flags_40000000,
+ tvb, offset, 4, negotiate_flags);
proto_tree_add_boolean (negotiate_flags_tree,
- hf_ntlmssp_negotiate_flags_20000000,
- tvb, offset, 4, negotiate_flags);
+ hf_ntlmssp_negotiate_flags_20000000,
+ tvb, offset, 4, negotiate_flags);
proto_tree_add_boolean (negotiate_flags_tree,
- hf_ntlmssp_negotiate_flags_10000000,
- tvb, offset, 4, negotiate_flags);
+ hf_ntlmssp_negotiate_flags_10000000,
+ tvb, offset, 4, negotiate_flags);
proto_tree_add_boolean (negotiate_flags_tree,
- hf_ntlmssp_negotiate_flags_8000000,
- tvb, offset, 4, negotiate_flags);
+ hf_ntlmssp_negotiate_flags_8000000,
+ tvb, offset, 4, negotiate_flags);
proto_tree_add_boolean (negotiate_flags_tree,
- hf_ntlmssp_negotiate_flags_4000000,
- tvb, offset, 4, negotiate_flags);
+ hf_ntlmssp_negotiate_flags_4000000,
+ tvb, offset, 4, negotiate_flags);
proto_tree_add_boolean (negotiate_flags_tree,
- hf_ntlmssp_negotiate_flags_2000000,
- tvb, offset, 4, negotiate_flags);
+ hf_ntlmssp_negotiate_flags_2000000,
+ tvb, offset, 4, negotiate_flags);
proto_tree_add_boolean (negotiate_flags_tree,
- hf_ntlmssp_negotiate_flags_1000000,
- tvb, offset, 4, negotiate_flags);
+ hf_ntlmssp_negotiate_flags_1000000,
+ tvb, offset, 4, negotiate_flags);
proto_tree_add_boolean (negotiate_flags_tree,
- hf_ntlmssp_negotiate_flags_800000,
- tvb, offset, 4, negotiate_flags);
+ hf_ntlmssp_negotiate_flags_800000,
+ tvb, offset, 4, negotiate_flags);
proto_tree_add_boolean (negotiate_flags_tree,
- hf_ntlmssp_negotiate_flags_400000,
- tvb, offset, 4, negotiate_flags);
+ hf_ntlmssp_negotiate_flags_400000,
+ tvb, offset, 4, negotiate_flags);
proto_tree_add_boolean (negotiate_flags_tree,
- hf_ntlmssp_negotiate_flags_200000,
- tvb, offset, 4, negotiate_flags);
+ hf_ntlmssp_negotiate_flags_200000,
+ tvb, offset, 4, negotiate_flags);
proto_tree_add_boolean (negotiate_flags_tree,
- hf_ntlmssp_negotiate_flags_100000,
- tvb, offset, 4, negotiate_flags);
+ hf_ntlmssp_negotiate_flags_100000,
+ tvb, offset, 4, negotiate_flags);
proto_tree_add_boolean (negotiate_flags_tree,
- hf_ntlmssp_negotiate_flags_80000,
- tvb, offset, 4, negotiate_flags);
+ hf_ntlmssp_negotiate_flags_80000,
+ tvb, offset, 4, negotiate_flags);
proto_tree_add_boolean (negotiate_flags_tree,
- hf_ntlmssp_negotiate_flags_40000,
- tvb, offset, 4, negotiate_flags);
+ hf_ntlmssp_negotiate_flags_40000,
+ tvb, offset, 4, negotiate_flags);
proto_tree_add_boolean (negotiate_flags_tree,
- hf_ntlmssp_negotiate_flags_20000,
- tvb, offset, 4, negotiate_flags);
+ hf_ntlmssp_negotiate_flags_20000,
+ tvb, offset, 4, negotiate_flags);
proto_tree_add_boolean (negotiate_flags_tree,
- hf_ntlmssp_negotiate_flags_10000,
- tvb, offset, 4, negotiate_flags);
+ hf_ntlmssp_negotiate_flags_10000,
+ tvb, offset, 4, negotiate_flags);
proto_tree_add_boolean (negotiate_flags_tree,
- hf_ntlmssp_negotiate_flags_8000,
- tvb, offset, 4, negotiate_flags);
+ hf_ntlmssp_negotiate_flags_8000,
+ tvb, offset, 4, negotiate_flags);
proto_tree_add_boolean (negotiate_flags_tree,
- hf_ntlmssp_negotiate_flags_4000,
- tvb, offset, 4, negotiate_flags);
+ hf_ntlmssp_negotiate_flags_4000,
+ tvb, offset, 4, negotiate_flags);
proto_tree_add_boolean (negotiate_flags_tree,
- hf_ntlmssp_negotiate_flags_2000,
- tvb, offset, 4, negotiate_flags);
+ hf_ntlmssp_negotiate_flags_2000,
+ tvb, offset, 4, negotiate_flags);
proto_tree_add_boolean (negotiate_flags_tree,
- hf_ntlmssp_negotiate_flags_1000,
- tvb, offset, 4, negotiate_flags);
+ hf_ntlmssp_negotiate_flags_1000,
+ tvb, offset, 4, negotiate_flags);
proto_tree_add_boolean (negotiate_flags_tree,
- hf_ntlmssp_negotiate_flags_800,
- tvb, offset, 4, negotiate_flags);
+ hf_ntlmssp_negotiate_flags_800,
+ tvb, offset, 4, negotiate_flags);
proto_tree_add_boolean (negotiate_flags_tree,
- hf_ntlmssp_negotiate_flags_400,
- tvb, offset, 4, negotiate_flags);
+ hf_ntlmssp_negotiate_flags_400,
+ tvb, offset, 4, negotiate_flags);
proto_tree_add_boolean (negotiate_flags_tree,
- hf_ntlmssp_negotiate_flags_200,
- tvb, offset, 4, negotiate_flags);
+ hf_ntlmssp_negotiate_flags_200,
+ tvb, offset, 4, negotiate_flags);
proto_tree_add_boolean (negotiate_flags_tree,
- hf_ntlmssp_negotiate_flags_100,
- tvb, offset, 4, negotiate_flags);
+ hf_ntlmssp_negotiate_flags_100,
+ tvb, offset, 4, negotiate_flags);
proto_tree_add_boolean (negotiate_flags_tree,
- hf_ntlmssp_negotiate_flags_80,
- tvb, offset, 4, negotiate_flags);
+ hf_ntlmssp_negotiate_flags_80,
+ tvb, offset, 4, negotiate_flags);
proto_tree_add_boolean (negotiate_flags_tree,
- hf_ntlmssp_negotiate_flags_40,
- tvb, offset, 4, negotiate_flags);
+ hf_ntlmssp_negotiate_flags_40,
+ tvb, offset, 4, negotiate_flags);
proto_tree_add_boolean (negotiate_flags_tree,
- hf_ntlmssp_negotiate_flags_20,
- tvb, offset, 4, negotiate_flags);
+ hf_ntlmssp_negotiate_flags_20,
+ tvb, offset, 4, negotiate_flags);
proto_tree_add_boolean (negotiate_flags_tree,
- hf_ntlmssp_negotiate_flags_10,
- tvb, offset, 4, negotiate_flags);
+ hf_ntlmssp_negotiate_flags_10,
+ tvb, offset, 4, negotiate_flags);
proto_tree_add_boolean (negotiate_flags_tree,
- hf_ntlmssp_negotiate_flags_08,
- tvb, offset, 4, negotiate_flags);
+ hf_ntlmssp_negotiate_flags_08,
+ tvb, offset, 4, negotiate_flags);
proto_tree_add_boolean (negotiate_flags_tree,
- hf_ntlmssp_negotiate_flags_04,
- tvb, offset, 4, negotiate_flags);
+ hf_ntlmssp_negotiate_flags_04,
+ tvb, offset, 4, negotiate_flags);
proto_tree_add_boolean (negotiate_flags_tree,
- hf_ntlmssp_negotiate_flags_02,
- tvb, offset, 4, negotiate_flags);
+ hf_ntlmssp_negotiate_flags_02,
+ tvb, offset, 4, negotiate_flags);
proto_tree_add_boolean (negotiate_flags_tree,
- hf_ntlmssp_negotiate_flags_01,
- tvb, offset, 4, negotiate_flags);
+ hf_ntlmssp_negotiate_flags_01,
+ tvb, offset, 4, negotiate_flags);
return (offset + 4);
}
/* Dissect "version" */
/* From MS-NLMP:
- 0 Major Version Number 1 byte
- 1 Minor Version Number 1 byte
- 2 Build Number short(LE)
+ 0 Major Version Number 1 byte
+ 1 Minor Version Number 1 byte
+ 2 Build Number short(LE)
3 (Reserved) 3 bytes
- 4 NTLM Current Revision 1 byte
+ 4 NTLM Current Revision 1 byte
*/
static int
if (ntlmssp_tree) {
proto_item *tf;
proto_tree *version_tree;
- tf = proto_tree_add_text(ntlmssp_tree, tvb, offset, 8,
- "Version %u.%u (Build %u); NTLM Current Revision %u",
- tvb_get_guint8(tvb, offset),
- tvb_get_guint8(tvb, offset+1),
- tvb_get_letohs(tvb, offset+2),
- tvb_get_guint8(tvb, offset+7));
+ tf = proto_tree_add_none_format(ntlmssp_tree, hf_ntlmssp_version, tvb, offset, 8,
+ "Version %u.%u (Build %u); NTLM Current Revision %u",
+ tvb_get_guint8(tvb, offset),
+ tvb_get_guint8(tvb, offset+1),
+ tvb_get_letohs(tvb, offset+2),
+ tvb_get_guint8(tvb, offset+7));
version_tree = proto_item_add_subtree (tf, ett_ntlmssp_version);
proto_tree_add_item(version_tree, hf_ntlmssp_version_major , tvb, offset , 1, ENC_NA);
proto_tree_add_item(version_tree, hf_ntlmssp_version_minor , tvb, offset+1, 1, ENC_NA);
/* Dissect a NTLM response. This is documented at
http://ubiqx.org/cifs/SMB.html#SMB.8, para 2.8.5.3 */
-/* Name types */
-
+/* Attribute types */
/*
* XXX - the davenport document says that a type of 5 has been seen,
* "apparently containing the 'parent' DNS domain for servers in
* subdomains".
+ * XXX: MS-NLMP info is newer than Davenport info;
+ * The attribute type list and the attribute names below are
+ * based upon MS-NLMP.
*/
-#define NTLM_NAME_END 0x0000
-#define NTLM_NAME_NB_HOST 0x0001
-#define NTLM_NAME_NB_DOMAIN 0x0002
-#define NTLM_NAME_DNS_HOST 0x0003
-#define NTLM_NAME_DNS_DOMAIN 0x0004
-#define NTLM_NAME_DNS_FOREST 0x0005
-#define NTLM_NAME_CLIENT_TIME 0x0007
-#define NTLM_NAME_RESTRICTION 0x0008
+#define NTLM_TARGET_INFO_END 0x0000
+#define NTLM_TARGET_INFO_NB_COMPUTER_NAME 0x0001
+#define NTLM_TARGET_INFO_NB_DOMAIN_NAME 0x0002
+#define NTLM_TARGET_INFO_DNS_COMPUTER_NAME 0x0003
+#define NTLM_TARGET_INFO_DNS_DOMAIN_NAME 0x0004
+#define NTLM_TARGET_INFO_DNS_TREE_NAME 0x0005
+#define NTLM_TARGET_INFO_FLAGS 0x0006
+#define NTLM_TARGET_INFO_TIMESTAMP 0x0007
+#define NTLM_TARGET_INFO_RESTRICTIONS 0x0008
+#define NTLM_TARGET_INFO_TARGET_NAME 0x0009
+#define NTLM_TARGET_INFO_CHANNEL_BINDINGS 0x000A
+
+static const value_string ntlm_name_types[] = {
+ { NTLM_TARGET_INFO_END, "End of list" },
+ { NTLM_TARGET_INFO_NB_COMPUTER_NAME, "NetBIOS computer name" },
+ { NTLM_TARGET_INFO_NB_DOMAIN_NAME, "NetBIOS domain name" },
+ { NTLM_TARGET_INFO_DNS_COMPUTER_NAME, "DNS computer name" },
+ { NTLM_TARGET_INFO_DNS_DOMAIN_NAME, "DNS domain name" },
+ { NTLM_TARGET_INFO_DNS_TREE_NAME, "DNS tree name" },
+ { NTLM_TARGET_INFO_FLAGS, "Flags" },
+ { NTLM_TARGET_INFO_TIMESTAMP, "Timestamp" },
+ { NTLM_TARGET_INFO_RESTRICTIONS, "Restrictions" },
+ { NTLM_TARGET_INFO_TARGET_NAME, "Target Name"},
+ { NTLM_TARGET_INFO_CHANNEL_BINDINGS, "Channel Bindings"},
+ { 0, NULL }
+};
+
+/* The following *must* match the order of the list of attribute types */
+/* Assumption: values in the list are a sequence starting with 0 and */
+/* with no gaps allowing a direct access of the array by attribute type */
+static int *ntlmssp_hf_challenge_target_info_hf_ptr_array[] = {
+ &hf_ntlmssp_challenge_target_info_end,
+ &hf_ntlmssp_challenge_target_info_nb_computer_name,
+ &hf_ntlmssp_challenge_target_info_nb_domain_name,
+ &hf_ntlmssp_challenge_target_info_dns_computer_name,
+ &hf_ntlmssp_challenge_target_info_dns_domain_name,
+ &hf_ntlmssp_challenge_target_info_dns_tree_name,
+ &hf_ntlmssp_challenge_target_info_flags,
+ &hf_ntlmssp_challenge_target_info_timestamp,
+ &hf_ntlmssp_challenge_target_info_restrictions,
+ &hf_ntlmssp_challenge_target_info_target_name,
+ &hf_ntlmssp_challenge_target_info_channel_bindings
+};
+static int *ntlmssp_hf_ntlmv2_response_hf_ptr_array[] = {
+ &hf_ntlmssp_ntlmv2_response_end,
+ &hf_ntlmssp_ntlmv2_response_nb_computer_name,
+ &hf_ntlmssp_ntlmv2_response_nb_domain_name,
+ &hf_ntlmssp_ntlmv2_response_dns_computer_name,
+ &hf_ntlmssp_ntlmv2_response_dns_domain_name,
+ &hf_ntlmssp_ntlmv2_response_dns_tree_name,
+ &hf_ntlmssp_ntlmv2_response_flags,
+ &hf_ntlmssp_ntlmv2_response_timestamp,
+ &hf_ntlmssp_ntlmv2_response_restrictions,
+ &hf_ntlmssp_ntlmv2_response_target_name,
+ &hf_ntlmssp_ntlmv2_response_channel_bindings
+};
+typedef struct _tif {
+ gint *ett;
+ int *hf_item_type;
+ int *hf_item_length;
+ int **hf_attr_array_p;
+} tif_t;
+
+static tif_t ntlmssp_challenge_target_info_tif = {
+ &ett_ntlmssp_challenge_target_info_item,
+ &hf_ntlmssp_challenge_target_info_item_type,
+ &hf_ntlmssp_challenge_target_info_item_len,
+ ntlmssp_hf_challenge_target_info_hf_ptr_array
+};
-static const value_string ntlm_name_types[] = {
- { NTLM_NAME_END, "End of list" },
- { NTLM_NAME_NB_HOST, "NetBIOS host name" },
- { NTLM_NAME_NB_DOMAIN, "NetBIOS domain name" },
- { NTLM_NAME_DNS_HOST, "DNS host name" },
- { NTLM_NAME_DNS_DOMAIN, "DNS domain name" },
- { NTLM_NAME_DNS_FOREST, "DNS forest name" },
-
- { NTLM_NAME_CLIENT_TIME, "Client Time" },
- { NTLM_NAME_RESTRICTION, "Encoding restriction" },
- { 0, NULL }
+static tif_t ntlmssp_ntlmv2_response_tif = {
+ &ett_ntlmssp_ntlmv2_response_item,
+ &hf_ntlmssp_ntlmv2_response_item_type,
+ &hf_ntlmssp_ntlmv2_response_item_len,
+ ntlmssp_hf_ntlmv2_response_hf_ptr_array
};
+static void
+dissect_ntlmssp_target_info_list(tvbuff_t *tvb, proto_tree *tree,
+ guint32 target_info_offset, guint16 target_info_length,
+ tif_t *tif_p)
+{
+ guint32 item_offset;
+ guint16 item_type;
+ guint16 item_length;
+
+
+ /* Now enumerate through the individual items in the list */
+ item_offset = target_info_offset;
+
+ while (item_offset < (target_info_offset + target_info_length)) {
+ proto_item *target_info_tf;
+ proto_tree *target_info_tree;
+ guint32 content_offset;
+ guint16 content_length;
+ guint32 type_offset;
+ guint32 len_offset;
+
+ int **hf_array_p = tif_p->hf_attr_array_p;
+
+ /* Content type */
+ type_offset = item_offset;
+ item_type = tvb_get_letohs(tvb, type_offset);
+
+ /* Content length */
+ len_offset = type_offset + 2;
+ content_length = tvb_get_letohs(tvb, len_offset);
+
+ /* Content value */
+ content_offset = len_offset + 2;
+ item_length = content_length + 4;
+
+ target_info_tf = proto_tree_add_text(tree, tvb, item_offset, item_length, "Attribute: %s",
+ val_to_str(item_type, ntlm_name_types, "Unknown (%d)"));
+
+ target_info_tree = proto_item_add_subtree (target_info_tf, *tif_p->ett);
+ proto_tree_add_item (target_info_tree, *tif_p->hf_item_type, tvb, type_offset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item (target_info_tree, *tif_p->hf_item_length, tvb, len_offset, 2, ENC_LITTLE_ENDIAN);
+
+ switch (item_type) {
+ case NTLM_TARGET_INFO_NB_COMPUTER_NAME:
+ case NTLM_TARGET_INFO_NB_DOMAIN_NAME:
+ case NTLM_TARGET_INFO_DNS_COMPUTER_NAME:
+ case NTLM_TARGET_INFO_DNS_DOMAIN_NAME:
+ case NTLM_TARGET_INFO_DNS_TREE_NAME:
+ case NTLM_TARGET_INFO_TARGET_NAME:
+ if (content_length > 0) {
+ const gchar *text;
+
+ text = tvb_get_ephemeral_faked_unicode(tvb, content_offset, content_length / 2, TRUE);
+ proto_tree_add_string(target_info_tree, *hf_array_p[item_type],
+ tvb, content_offset, content_length, text);
+ proto_item_append_text(target_info_tf, ": %s", text);
+ }
+ break;
+
+ case NTLM_TARGET_INFO_FLAGS:
+ proto_tree_add_item(target_info_tree, *hf_array_p[item_type],
+ tvb, content_offset, content_length, ENC_LITTLE_ENDIAN);
+ break;
+
+ case NTLM_TARGET_INFO_TIMESTAMP:
+ dissect_nt_64bit_time(tvb, target_info_tree, content_offset, *hf_array_p[item_type]);
+ break;
+
+ case NTLM_TARGET_INFO_RESTRICTIONS:
+ case NTLM_TARGET_INFO_CHANNEL_BINDINGS:
+ proto_tree_add_item(target_info_tree, *hf_array_p[item_type],
+ tvb, content_offset, content_length, ENC_NA);
+ break;
+
+ default:
+ break;
+ }
+
+ item_offset += item_length;
+ }
+}
+
int
dissect_ntlmv2_response(tvbuff_t *tvb, proto_tree *tree, int offset, int len)
{
- proto_item *ntlmv2_item = NULL;
- proto_tree *ntlmv2_tree = NULL;
- const guint8 *restriction_bytes;
- /* Dissect NTLMv2 bits&pieces */
-
- if (tree) {
- ntlmv2_item = proto_tree_add_item(
- tree, hf_ntlmssp_ntlmv2_response, tvb,
- offset, len, TRUE);
- ntlmv2_tree = proto_item_add_subtree(
- ntlmv2_item, ett_ntlmssp_ntlmv2_response);
- }
-
- proto_tree_add_item(
- ntlmv2_tree, hf_ntlmssp_ntlmv2_response_hmac, tvb,
- offset, 16, TRUE);
-
- offset += 16;
-
- proto_tree_add_item(
- ntlmv2_tree, hf_ntlmssp_ntlmv2_response_header, tvb,
- offset, 4, TRUE);
-
- offset += 4;
-
- proto_tree_add_item(
- ntlmv2_tree, hf_ntlmssp_ntlmv2_response_reserved, tvb,
- offset, 4, TRUE);
-
- offset += 4;
-
- offset = dissect_nt_64bit_time(
- tvb, ntlmv2_tree, offset, hf_ntlmssp_ntlmv2_response_time);
-
- proto_tree_add_item(
- ntlmv2_tree, hf_ntlmssp_ntlmv2_response_chal, tvb,
- offset, 8, TRUE);
-
- offset += 8;
-
- proto_tree_add_item(
- ntlmv2_tree, hf_ntlmssp_ntlmv2_response_unknown, tvb,
- offset, 4, TRUE);
-
- offset += 4;
-
- /* Variable length list of names */
-
- while(1) {
- guint16 name_type = tvb_get_letohs(tvb, offset);
- guint16 name_len = tvb_get_letohs(tvb, offset + 2);
- proto_tree *name_tree = NULL;
- proto_item *name_item = NULL;
- const char *name = NULL;
-
- if (ntlmv2_tree) {
- name_item = proto_tree_add_item(
- ntlmv2_tree, hf_ntlmssp_ntlmv2_response_name,
- tvb, offset, 0, TRUE);
- name_tree = proto_item_add_subtree(
- name_item, ett_ntlmssp_ntlmv2_response_name);
- }
-
- /* Dissect name header */
-
- proto_tree_add_item(
- name_tree, hf_ntlmssp_ntlmv2_response_name_type, tvb,
- offset, 2, TRUE);
-
- offset += 2;
-
- proto_tree_add_item(
- name_tree, hf_ntlmssp_ntlmv2_response_name_len, tvb,
- offset, 2, TRUE);
-
- offset += 2;
-
- /* Dissect name */
-
- switch(name_type){
- case NTLM_NAME_END:
- name = "NULL";
- proto_item_append_text(
- name_item, "%s",
- val_to_str(name_type, ntlm_name_types,
- "Unknown"));
- break;
- case NTLM_NAME_CLIENT_TIME:
- dissect_nt_64bit_time(
- tvb, name_tree, offset,
- hf_ntlmssp_ntlmv2_response_client_time);
- proto_item_append_text(
- name_item, "Client Time");
- break;
- case NTLM_NAME_RESTRICTION:
- proto_item_append_text(
- name_item, "%s",
- val_to_str(name_type, ntlm_name_types,
- "Unknown"));
- restriction_bytes = tvb_get_ptr(tvb, offset,name_len);
- proto_tree_add_bytes (name_tree,hf_ntlmssp_ntlmv2_response_restriction,tvb,offset,name_len,restriction_bytes);
- break;
- case NTLM_NAME_NB_HOST:
- case NTLM_NAME_NB_DOMAIN:
- case NTLM_NAME_DNS_HOST:
- case NTLM_NAME_DNS_DOMAIN:
- case NTLM_NAME_DNS_FOREST:
- default:
- name = tvb_get_ephemeral_faked_unicode(
- tvb, offset, name_len / 2, TRUE);
- proto_tree_add_text(
- name_tree, tvb, offset, name_len,
- "Value: %s", name);
- proto_item_append_text(
- name_item, "%s, %s",
- val_to_str(name_type, ntlm_name_types,
- "Unknown"), name);
- break;
- }
-
-
- offset += name_len;
-
- proto_item_set_len(name_item, name_len + 4);
-
- if (name_type == 0) /* End of list */
- break;
- }
-
- /*
- * XXX - Windows puts 4 bytes of additional stuff here.
- * Samba's smbclient doesn't.
- * Both of them appear to be able to connect to W2K SMB
- * servers.
- * Should we display the rest of the response as an
- * "extra data" item?
- *
- * XXX - we should also check whether we go past the length
- * of the response.
- */
- return offset;
+ proto_item *ntlmv2_item = NULL;
+ proto_tree *ntlmv2_tree = NULL;
+ int orig_offset;
+
+ /* Dissect NTLMv2 bits&pieces */
+ orig_offset = offset;
+
+ if (tree) {
+ ntlmv2_item = proto_tree_add_item(
+ tree, hf_ntlmssp_ntlmv2_response, tvb,
+ offset, len, ENC_NA);
+ ntlmv2_tree = proto_item_add_subtree(
+ ntlmv2_item, ett_ntlmssp_ntlmv2_response);
+ }
+
+ proto_tree_add_item(
+ ntlmv2_tree, hf_ntlmssp_ntlmv2_response_hmac, tvb,
+ offset, 16, ENC_NA);
+
+ offset += 16;
+
+ proto_tree_add_item(
+ ntlmv2_tree, hf_ntlmssp_ntlmv2_response_header, tvb,
+ offset, 4, ENC_LITTLE_ENDIAN);
+
+ offset += 4;
+
+ proto_tree_add_item(
+ ntlmv2_tree, hf_ntlmssp_ntlmv2_response_reserved, tvb,
+ offset, 4, ENC_LITTLE_ENDIAN);
+
+ offset += 4;
+
+ offset = dissect_nt_64bit_time(
+ tvb, ntlmv2_tree, offset, hf_ntlmssp_ntlmv2_response_time);
+
+ proto_tree_add_item(
+ ntlmv2_tree, hf_ntlmssp_ntlmv2_response_chal, tvb,
+ offset, 8, ENC_NA);
+
+ offset += 8;
+
+ proto_tree_add_item(
+ ntlmv2_tree, hf_ntlmssp_ntlmv2_response_unknown, tvb,
+ offset, 4, ENC_LITTLE_ENDIAN);
+
+ offset += 4;
+
+ /* Variable length list of attributes */
+ /*
+ * XXX - Windows puts one or more sets of 4 bytes of additional stuff (all zeros ?)
+ * at the end of the attributes.
+ * Samba's smbclient doesn't.
+ * Both of them appear to be able to connect to W2K SMB
+ * servers.
+ * The additional stuff will be dissected as extra "end" attributes.
+ *
+ */
+ dissect_ntlmssp_target_info_list(tvb, ntlmv2_tree,
+ offset, len - (offset - orig_offset),
+ &ntlmssp_ntlmv2_response_tif);
+
+ return offset+len;
}
/* tapping into ntlmssph not yet implemented */
/* NTLMSSP Negotiate Flags */
negotiate_flags = tvb_get_letohl (tvb, offset);
offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
- negotiate_flags);
+ negotiate_flags);
/*
* XXX - the davenport document says that these might not be
* isn't enough to contain them.
*/
offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, FALSE,
- hf_ntlmssp_negotiate_domain,
- &data_start, &data_end, NULL);
+ hf_ntlmssp_negotiate_domain,
+ &data_start, &data_end, NULL);
offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, FALSE,
- hf_ntlmssp_negotiate_workstation,
- &item_start, &item_end, NULL);
+ hf_ntlmssp_negotiate_workstation,
+ &item_start, &item_end, NULL);
data_start = MIN(data_start, item_start);
data_end = MAX(data_end, item_end);
- /* If there are more bytes before the data block dissect a version field */
+ /* If there are more bytes before the data block dissect a version field
+ if NTLMSSP_NEGOTIATE_VERSION is set in the flags (see MS-NLMP) */
if (offset < data_start) {
- offset = dissect_ntlmssp_version(tvb, offset, ntlmssp_tree);
+ if (negotiate_flags & NTLMSSP_NEGOTIATE_VERSION)
+ offset = dissect_ntlmssp_version(tvb, offset, ntlmssp_tree);
}
return data_end;
}
static int
-dissect_ntlmssp_address_list (tvbuff_t *tvb, int offset,
- proto_tree *ntlmssp_tree,
- int *end)
+dissect_ntlmssp_challenge_target_info_blob (tvbuff_t *tvb, int offset,
+ proto_tree *ntlmssp_tree,
+ int *end)
{
- guint16 list_length = tvb_get_letohs(tvb, offset);
- guint16 list_maxlen = tvb_get_letohs(tvb, offset+2);
- guint32 list_offset = tvb_get_letohl(tvb, offset+4);
- guint16 item_type, item_length;
- guint32 item_offset;
+ guint16 challenge_target_info_length = tvb_get_letohs(tvb, offset);
+ guint16 challenge_target_info_maxlen = tvb_get_letohs(tvb, offset+2);
+ guint32 challenge_target_info_offset = tvb_get_letohl(tvb, offset+4);
proto_item *tf = NULL;
- proto_tree *tree = NULL;
- proto_item *addr_tf = NULL;
- proto_tree *addr_tree = NULL;
+ proto_tree *challenge_target_info_tree = NULL;
- /* the address list is just a blob */
- if (0 == list_length) {
- *end = (list_offset > ((guint)offset)+8 ? list_offset : ((guint)offset)+8);
+ /* the target info list is just a blob */
+ if (0 == challenge_target_info_length) {
+ *end = (challenge_target_info_offset > ((guint)offset)+8 ? challenge_target_info_offset : ((guint)offset)+8);
if (ntlmssp_tree)
- proto_tree_add_text(ntlmssp_tree, tvb, offset, 8,
- "Address List: Empty");
+ proto_tree_add_text(ntlmssp_tree, tvb, offset, 8,
+ "Target Info List: Empty");
return offset+8;
}
if (ntlmssp_tree) {
- tf = proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_address_list, tvb,
- list_offset, list_length, FALSE);
- tree = proto_item_add_subtree(tf, ett_ntlmssp_address_list);
+ tf = proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_challenge_target_info, tvb,
+ challenge_target_info_offset, challenge_target_info_length, ENC_NA);
+ challenge_target_info_tree = proto_item_add_subtree(tf, ett_ntlmssp_challenge_target_info);
}
- proto_tree_add_uint(tree, hf_ntlmssp_address_list_len,
- tvb, offset, 2, list_length);
+ proto_tree_add_uint(challenge_target_info_tree, hf_ntlmssp_challenge_target_info_len,
+ tvb, offset, 2, challenge_target_info_length);
offset += 2;
- proto_tree_add_uint(tree, hf_ntlmssp_address_list_maxlen,
- tvb, offset, 2, list_maxlen);
+ proto_tree_add_uint(challenge_target_info_tree, hf_ntlmssp_challenge_target_info_maxlen,
+ tvb, offset, 2, challenge_target_info_maxlen);
offset += 2;
- proto_tree_add_uint(tree, hf_ntlmssp_address_list_offset,
- tvb, offset, 4, list_offset);
+ proto_tree_add_uint(challenge_target_info_tree, hf_ntlmssp_challenge_target_info_offset,
+ tvb, offset, 4, challenge_target_info_offset);
offset += 4;
- /* Now enumerate through the individual items in the list */
- item_offset = list_offset;
-
- while (item_offset < (list_offset + list_length)) {
- const char *text=NULL;
- guint32 content_offset;
- guint16 content_length;
- guint32 type_offset;
- guint32 len_offset;
+ dissect_ntlmssp_target_info_list(tvb, challenge_target_info_tree,
+ challenge_target_info_offset, challenge_target_info_length,
+ &ntlmssp_challenge_target_info_tif);
- /* Content type */
- type_offset = item_offset;
- item_type = tvb_get_letohs(tvb, type_offset);
-
- /* Content length */
- len_offset = type_offset + 2;
- content_length = tvb_get_letohs(tvb, len_offset);
-
- /* Content value */
- content_offset = len_offset + 2;
- item_length = content_length + 4;
-
- /* Strings are always in Unicode regardless of the negotiated
- string type. */
- if (content_length > 0) {
- guint16 bc;
- int result_length;
- int item_offset_int;
-
- item_offset_int = content_offset;
- bc = content_length;
- text = get_unicode_or_ascii_string(tvb, &item_offset_int,
- TRUE, &result_length,
- FALSE, FALSE, &bc);
- }
-
- if (!text) text = ""; /* Make sure we don't blow up below */
-
- switch(item_type) {
- case NTLM_NAME_NB_HOST:
- addr_tf = proto_tree_add_string(tree, hf_ntlmssp_address_list_server_nb,
- tvb, item_offset, item_length, text);
- break;
- case NTLM_NAME_NB_DOMAIN:
- addr_tf = proto_tree_add_string(tree, hf_ntlmssp_address_list_domain_nb,
- tvb, item_offset, item_length, text);
- break;
- case NTLM_NAME_DNS_HOST:
- addr_tf = proto_tree_add_string(tree, hf_ntlmssp_address_list_server_dns,
- tvb, item_offset, item_length, text);
- break;
- case NTLM_NAME_DNS_DOMAIN:
- addr_tf = proto_tree_add_string(tree, hf_ntlmssp_address_list_domain_dns,
- tvb, item_offset, item_length, text);
- break;
- case NTLM_NAME_DNS_FOREST:
- addr_tf = proto_tree_add_string(tree, hf_ntlmssp_address_list_forest_dns,
- tvb, item_offset, item_length, text);
- break;
- case NTLM_NAME_END:
- addr_tf = proto_tree_add_item(tree, hf_ntlmssp_address_list_terminator,
- tvb, item_offset, item_length, TRUE);
- break;
- default:
- addr_tf = proto_tree_add_text(tree, tvb, item_offset, item_length, "Unknown type:0x%04x", item_type);
- }
-
- /* Now show the actual bytes that made up the summary line */
- addr_tree = proto_item_add_subtree (addr_tf,
- ett_ntlmssp_address_list_item);
- proto_tree_add_item (addr_tree, hf_ntlmssp_address_list_item_type,
- tvb, type_offset, 2, TRUE);
- proto_tree_add_item (addr_tree, hf_ntlmssp_address_list_item_len,
- tvb, len_offset, 2, TRUE);
- if (content_length > 0) {
- proto_tree_add_string(addr_tree, hf_ntlmssp_address_list_item_content,
- tvb, content_offset, content_length, text);
- }
-
- item_offset += item_length;
- }
-
- *end = list_offset + list_length;
+ *end = challenge_target_info_offset + challenge_target_info_length;
return offset;
}
/* tapping into ntlmssph not yet implemented */
static int
dissect_ntlmssp_challenge (tvbuff_t *tvb, packet_info *pinfo, int offset,
- proto_tree *ntlmssp_tree, ntlmssp_header_t *ntlmssph _U_)
+ proto_tree *ntlmssp_tree, ntlmssp_header_t *ntlmssph _U_)
{
guint32 negotiate_flags;
int item_start, item_end;
* XXX - Original name "domain" changed to "target_name" to match MS-NLMP
*/
offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, unicode_strings,
- hf_ntlmssp_challenge_target_name,
- &item_start, &item_end, NULL);
+ hf_ntlmssp_challenge_target_name,
+ &item_start, &item_end, NULL);
data_start = item_start;
data_end = item_end;
/* NTLMSSP Negotiate Flags */
offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
- negotiate_flags);
+ negotiate_flags);
/* NTLMSSP NT Lan Manager Challenge */
proto_tree_add_item (ntlmssp_tree,
- hf_ntlmssp_ntlm_server_challenge,
- tvb, offset, 8, FALSE);
+ hf_ntlmssp_ntlm_server_challenge,
+ tvb, offset, 8, ENC_NA);
/*
* Store the flags and the RC4 state information with the conversation,
/*
* XXX - SSP key? The davenport document says
*
- * The context field is typically populated when Negotiate Local
- * Call is set. It contains an SSPI context handle, which allows
- * the client to "short-circuit" authentication and effectively
- * circumvent responding to the challenge. Physically, the context
- * is two long values. This is covered in greater detail later,
- * in the "Local Authentication" section.
+ * The context field is typically populated when Negotiate Local
+ * Call is set. It contains an SSPI context handle, which allows
+ * the client to "short-circuit" authentication and effectively
+ * circumvent responding to the challenge. Physically, the context
+ * is two long values. This is covered in greater detail later,
+ * in the "Local Authentication" section.
*
* It also says that that information may be omitted.
*/
proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_reserved,
- tvb, offset, 8, FALSE);
+ tvb, offset, 8, ENC_NA);
offset += 8;
/*
* address list).
*/
if (offset < data_start) {
- offset = dissect_ntlmssp_address_list(tvb, offset, ntlmssp_tree, &item_end);
+ offset = dissect_ntlmssp_challenge_target_info_blob(tvb, offset, ntlmssp_tree, &item_end);
/* XXX: This code assumes that the address list in the data block */
/* is always after the target name. Is this OK ? */
data_end = MAX(data_end, item_end);
}
- /* If there are more bytes before the data block dissect a version field */
+ /* If there are more bytes before the data block dissect a version field
+ if NTLMSSP_NEGOTIATE_VERSION is set in the flags (see MS-NLMP) */
if (offset < data_start) {
- offset = dissect_ntlmssp_version(tvb, offset, ntlmssp_tree);
+ if (negotiate_flags & NTLMSSP_NEGOTIATE_VERSION)
+ offset = dissect_ntlmssp_version(tvb, offset, ntlmssp_tree);
}
return MAX(offset, data_end);
static int
dissect_ntlmssp_auth (tvbuff_t *tvb, packet_info *pinfo, int offset,
- proto_tree *ntlmssp_tree, ntlmssp_header_t *ntlmssph)
+ proto_tree *ntlmssp_tree, ntlmssp_header_t *ntlmssph)
{
int item_start, item_end;
int data_start, data_end = 0;
* it means this is the first time we've dissected this frame, so
* we should give it flag info.
*/
-#if 0
- conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
- pinfo->ptype, pinfo->srcport,
- pinfo->destport, 0);
- if (conversation != NULL) {
- conv_ntlmssp_info = conversation_get_proto_data(conversation, proto_ntlmssp);
- if (conv_ntlmssp_info != NULL) {
- /*
- * We have flag info; attach it to the frame.
- */
- /* XXX: The *conv_ntlmssp_info struct attached to the frame is the
- same as the one attached to the conversation.
- Is this what is indended ? */
- p_add_proto_data(pinfo->fd, proto_ntlmssp, conv_ntlmssp_info);
- }
- }
-#else /* XXX: Create conv_ntlmssp_info & etc if no previous CHALLENGE seen */
- /* so we'll have a place to store flags. */
- /* This is a bit brute-force but looks like it will be OK. */
+ /* XXX: Create conv_ntlmssp_info & etc if no previous CHALLENGE seen */
+ /* so we'll have a place to store flags. */
+ /* This is a bit brute-force but looks like it will be OK. */
conversation = find_or_create_conversation(pinfo);
conv_ntlmssp_info = conversation_get_proto_data(conversation, proto_ntlmssp);
if (conv_ntlmssp_info == NULL) {
same as the one attached to the conversation. That is: *both* point to
the exact same struct in memory. Is this what is indended ? */
p_add_proto_data(pinfo->fd, proto_ntlmssp, conv_ntlmssp_info);
-#endif
}
if (conv_ntlmssp_info != NULL) {
/* Lan Manager response */
data_start = tvb_get_letohl(tvb, offset+4);
offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
- hf_ntlmssp_auth_lmresponse,
- &item_end,
- conv_ntlmssp_info == NULL ? NULL :
- &conv_ntlmssp_info->lm_response);
+ hf_ntlmssp_auth_lmresponse,
+ &item_end,
+ conv_ntlmssp_info == NULL ? NULL :
+ &conv_ntlmssp_info->lm_response);
data_end = MAX(data_end, item_end);
/* NTLM response */
item_start = tvb_get_letohl(tvb, offset+4);
offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
- hf_ntlmssp_auth_ntresponse,
- &item_end,
- conv_ntlmssp_info == NULL ? NULL :
- &conv_ntlmssp_info->ntlm_response);
+ hf_ntlmssp_auth_ntresponse,
+ &item_end,
+ conv_ntlmssp_info == NULL ? NULL :
+ &conv_ntlmssp_info->ntlm_response);
if( conv_ntlmssp_info != NULL && conv_ntlmssp_info->ntlm_response.length > 24 ) {
memcpy(conv_ntlmssp_info->client_challenge,conv_ntlmssp_info->ntlm_response.contents+32,8);
}
/* domain name */
item_start = tvb_get_letohl(tvb, offset+4);
offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree,
- unicode_strings,
- hf_ntlmssp_auth_domain,
- &item_start, &item_end, &(ntlmssph->domain_name));
+ unicode_strings,
+ hf_ntlmssp_auth_domain,
+ &item_start, &item_end, &(ntlmssph->domain_name));
/*ntlmssph->domain_name_len=item_end-item_start;*/
data_start = MIN(data_start, item_start);
data_end = MAX(data_end, item_end);
/* user name */
item_start = tvb_get_letohl(tvb, offset+4);
offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree,
- unicode_strings,
- hf_ntlmssp_auth_username,
- &item_start, &item_end, &(ntlmssph->acct_name));
+ unicode_strings,
+ hf_ntlmssp_auth_username,
+ &item_start, &item_end, &(ntlmssph->acct_name));
/*ntlmssph->acct_name_len=item_end-item_start;*/
data_start = MIN(data_start, item_start);
data_end = MAX(data_end, item_end);
- if (check_col(pinfo->cinfo, COL_INFO))
- col_append_fstr(pinfo->cinfo, COL_INFO, ", User: %s\\%s",
- ntlmssph->domain_name, ntlmssph->acct_name);
+ col_append_sep_fstr(pinfo->cinfo, COL_INFO, ", ", "User: %s\\%s",
+ ntlmssph->domain_name, ntlmssph->acct_name);
/* hostname */
item_start = tvb_get_letohl(tvb, offset+4);
offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree,
- unicode_strings,
- hf_ntlmssp_auth_hostname,
- &item_start, &item_end, &(ntlmssph->host_name));
+ unicode_strings,
+ hf_ntlmssp_auth_hostname,
+ &item_start, &item_end, &(ntlmssph->host_name));
data_start = MIN(data_start, item_start);
data_end = MAX(data_end, item_end);
if (offset < data_start) {
/* Session Key */
offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
- hf_ntlmssp_auth_sesskey,
- &item_end, &sessionblob);
+ hf_ntlmssp_auth_sesskey,
+ &item_end, &sessionblob);
data_end = MAX(data_end, item_end);
}
if ((conv_ntlmssp_info != NULL) && (conv_ntlmssp_info->flags == 0)) {
conv_ntlmssp_info->flags = negotiate_flags;
}
- }
+ } else
+ negotiate_flags = 0;
- /* If there are more bytes before the data block dissect a version field */
+ /* If there are more bytes before the data block dissect a version field
+ if NTLMSSP_NEGOTIATE_VERSION is set in the flags (see MS-NLMP) */
if (offset < data_start) {
- offset = dissect_ntlmssp_version(tvb, offset, ntlmssp_tree);
+ if (negotiate_flags & NTLMSSP_NEGOTIATE_VERSION)
+ offset = dissect_ntlmssp_version(tvb, offset, ntlmssp_tree);
}
/* If there are still more bytes before the data block dissect an MIC (message integrity_code) field */
{
conv_ntlmssp_info->rc4_state_initialized = 0;
if( conv_ntlmssp_info->is_auth_ntlm_v2 ) {
- create_ntlmssp_v2_key(gbl_nt_password, conv_ntlmssp_info->server_challenge,conv_ntlmssp_info->client_challenge, sspkey,encryptedsessionkey,conv_ntlmssp_info->flags,conv_ntlmssp_info->ntlm_response,conv_ntlmssp_info->lm_response,ntlmssph);
+ create_ntlmssp_v2_key(gbl_nt_password, conv_ntlmssp_info->server_challenge,conv_ntlmssp_info->client_challenge, sspkey,encryptedsessionkey,conv_ntlmssp_info->flags,&conv_ntlmssp_info->ntlm_response,&conv_ntlmssp_info->lm_response,ntlmssph);
}
else
{
}
return MAX(offset, data_end);
}
+
static guint8*
get_sign_key(packet_info *pinfo, int cryptpeer)
{
ntlmssp_info *conv_ntlmssp_info;
conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
- pinfo->ptype, pinfo->srcport,
- pinfo->destport, 0);
+ pinfo->ptype, pinfo->srcport,
+ pinfo->destport, 0);
if (conversation == NULL) {
/* We don't have a conversation. In this case, stop processing
because we do not have enough info to decrypt the payload */
else {
/* We have a conversation, check for encryption state */
conv_ntlmssp_info = conversation_get_proto_data(conversation,
- proto_ntlmssp);
+ proto_ntlmssp);
if (conv_ntlmssp_info == NULL) {
/* No encryption state tied to the conversation. Therefore, we
- cannot decrypt the payload */
+ cannot decrypt the payload */
return NULL;
}
else {
/* We have the encryption state in the conversation. So return the
- crypt state tied to the requested peer
+ crypt state tied to the requested peer
*/
if (cryptpeer == 1) {
- return (guint8*)&conv_ntlmssp_info->sign_key_client;
+ return (guint8*)&conv_ntlmssp_info->sign_key_client;
} else {
- return (guint8*)&conv_ntlmssp_info->sign_key_server;
+ return (guint8*)&conv_ntlmssp_info->sign_key_server;
}
}
}
}
+
/*
* Get the encryption state tied to this conversation. cryptpeer indicates
* whether to retrieve the client key (1) or the server key (0)
ntlmssp_info *conv_ntlmssp_info;
conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
- pinfo->ptype, pinfo->srcport,
- pinfo->destport, 0);
+ pinfo->ptype, pinfo->srcport,
+ pinfo->destport, 0);
if (conversation == NULL) {
/* We don't have a conversation. In this case, stop processing
because we do not have enough info to decrypt the payload */
else {
/* We have a conversation, check for encryption state */
conv_ntlmssp_info = conversation_get_proto_data(conversation,
- proto_ntlmssp);
+ proto_ntlmssp);
if (conv_ntlmssp_info == NULL) {
/* No encryption state tied to the conversation. Therefore, we
- cannot decrypt the payload */
+ cannot decrypt the payload */
return NULL;
}
else {
/* We have the encryption state in the conversation. So return the
- crypt state tied to the requested peer
+ crypt state tied to the requested peer
*/
if (cryptpeer == 1) {
- return &conv_ntlmssp_info->rc4_state_client;
+ return &conv_ntlmssp_info->rc4_state_client;
} else {
- return &conv_ntlmssp_info->rc4_state_server;
+ return &conv_ntlmssp_info->rc4_state_server;
}
}
}
}
-void
+
+static void
decrypt_data_payload(tvbuff_t *tvb, int offset, guint32 encrypted_block_length,
- packet_info *pinfo, proto_tree *tree _U_,gpointer key);
+ packet_info *pinfo, proto_tree *tree _U_,gpointer key);
static void
decrypt_verifier(tvbuff_t *tvb, int offset, guint32 encrypted_block_length,
- packet_info *pinfo, proto_tree *tree,gpointer key);
-/*
-tvbuff_t *
+ packet_info *pinfo, proto_tree *tree,gpointer key);
+
+#if 0
+static tvbuff_t *
dissect_ntlmssp_encrypted_payload(tvbuff_t *data_tvb,
- tvbuff_t *auth_tvb _U_,
- int offset,
- packet_info *pinfo,
- dcerpc_auth_info *auth_info _U_)*/
+ tvbuff_t *auth_tvb _U_,
+ int offset,
+ packet_info *pinfo,
+ dcerpc_auth_info *auth_info _U_)
+#endif
-int
+static int
dissect_ntlmssp_payload(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
{
volatile int offset = 0;
guint32 ntlm_magic_size = 4;
guint32 ntlm_signature_size = 8;
guint32 ntlm_seq_size = 4;
+ void *pd_save;
+
length = tvb_length (tvb);
/* signature + seq + real payload */
encrypted_block_length = length - ntlm_magic_size;
/* Setup a new tree for the NTLMSSP payload */
if (tree) {
tf = proto_tree_add_item (tree,
- hf_ntlmssp_verf,
- tvb, offset, -1, FALSE);
+ hf_ntlmssp_verf,
+ tvb, offset, -1, ENC_NA);
ntlmssp_tree = proto_item_add_subtree (tf,
- ett_ntlmssp);
+ ett_ntlmssp);
}
/*
* in the packet after our blob to see, so we just re-throw the
* exception.
*/
+ pd_save = pinfo->private_data;
TRY {
/* Version number */
proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_vers,
- tvb, offset, 4, TRUE);
+ tvb, offset, 4, ENC_LITTLE_ENDIAN);
offset += 4;
/* Encrypted body */
proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_body,
- tvb, offset, ntlm_signature_size + ntlm_seq_size, TRUE);
+ tvb, offset, ntlm_signature_size + ntlm_seq_size, ENC_NA);
tvb_memcpy(tvb, key, offset, ntlm_signature_size + ntlm_seq_size);
/* Try to decrypt */
decrypt_data_payload (tvb, offset+(ntlm_signature_size + ntlm_seq_size), encrypted_block_length-(ntlm_signature_size + ntlm_seq_size), pinfo, ntlmssp_tree,key);
} CATCH(BoundsError) {
RETHROW;
} CATCH(ReportedBoundsError) {
+ /* Restore the private_data structure in case one of the
+ * called dissectors modified it (and, due to the exception,
+ * was unable to restore it).
+ */
+ pinfo->private_data = pd_save;
show_reported_bounds_error(tvb, pinfo, tree);
} ENDTRY;
return offset;
}
-void
+
+static void
decrypt_data_payload(tvbuff_t *tvb, int offset, guint32 encrypted_block_length,
- packet_info *pinfo, proto_tree *tree _U_,gpointer key)
+ packet_info *pinfo, proto_tree *tree _U_,gpointer key)
{
tvbuff_t *decr_tvb; /* Used to display decrypted buffer */
guint8 *peer_block;
if (!packet_ntlmssp_info->payload_decrypted) {
/* Pull the challenge info from the conversation */
conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
- pinfo->ptype, pinfo->srcport,
- pinfo->destport, 0);
+ pinfo->ptype, pinfo->srcport,
+ pinfo->destport, 0);
if (conversation == NULL) {
/* There is no conversation, thus no encryption state */
return ;
}
conv_ntlmssp_info = conversation_get_proto_data(conversation,
- proto_ntlmssp);
+ proto_ntlmssp);
if (conv_ntlmssp_info == NULL) {
/* There is no NTLMSSP state tied to the conversation */
- return ;
+ return ;
}
if (conv_ntlmssp_info->rc4_state_initialized != 1 ) {
- /* The crypto sybsystem is not initialized. This means that either
- the conversation did not include a challenge, or that we do not have the right password */
- return;
+ /* The crypto sybsystem is not initialized. This means that either
+ the conversation did not include a challenge, or that we do not have the right password */
+ return;
}
if( key != NULL ){
stored_packet_ntlmssp_info = g_hash_table_lookup(hash_packet,key);
/* Do the decryption of the payload */
crypt_rc4(rc4_state, packet_ntlmssp_info->decrypted_payload,
- encrypted_block_length);
+ encrypted_block_length);
/* decrypt the verifier */
/*printnchar(packet_ntlmssp_info->decrypted_payload,encrypted_block_length,"data: ","\n");*/
/* We setup a temporary buffer so we can re-encrypt the payload after
/* Show the decrypted buffer in a new window */
decr_tvb = tvb_new_real_data(packet_ntlmssp_info->decrypted_payload,
- encrypted_block_length,
- encrypted_block_length);
+ encrypted_block_length,
+ encrypted_block_length);
tvb_set_child_real_data_tvbuff(tvb, decr_tvb);
pinfo->gssapi_decrypted_tvb = decr_tvb;
}
+
static void
dissect_ntlmssp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
proto_tree *volatile ntlmssp_tree = NULL;
proto_item *tf = NULL;
ntlmssp_header_t *ntlmssph;
+ void *pd_save;
ntlmssph=ep_alloc(sizeof(ntlmssp_header_t));
ntlmssph->type=0;
/* Setup a new tree for the NTLMSSP payload */
if (tree) {
tf = proto_tree_add_item (tree,
- proto_ntlmssp,
- tvb, offset, -1, FALSE);
+ proto_ntlmssp,
+ tvb, offset, -1, ENC_NA);
ntlmssp_tree = proto_item_add_subtree (tf,
- ett_ntlmssp);
+ ett_ntlmssp);
}
/*
* in the packet after our blob to see, so we just re-throw the
* exception.
*/
+ pd_save = pinfo->private_data;
TRY {
/* NTLMSSP constant */
proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_auth,
- tvb, offset, 8, FALSE);
+ tvb, offset, 8, ENC_ASCII|ENC_NA);
offset += 8;
/* NTLMSSP Message Type */
proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_message_type,
- tvb, offset, 4, TRUE);
+ tvb, offset, 4, ENC_LITTLE_ENDIAN);
ntlmssph->type = tvb_get_letohl (tvb, offset);
offset += 4;
- if (check_col(pinfo->cinfo, COL_INFO))
- col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
- val_to_str(ntlmssph->type,
- ntlmssp_message_types,
- "Unknown message type"));
+ col_append_sep_fstr(pinfo->cinfo, COL_INFO, ", ","%s",
+ val_to_str(ntlmssph->type,
+ ntlmssp_message_types,
+ "Unknown message type"));
/* Call the appropriate dissector based on the Message Type */
switch (ntlmssph->type) {
default:
/* Unrecognized message type */
proto_tree_add_text (ntlmssp_tree, tvb, offset, -1,
- "Unrecognized NTLMSSP Message");
+ "Unrecognized NTLMSSP Message");
break;
}
} CATCH(BoundsError) {
RETHROW;
} CATCH(ReportedBoundsError) {
+ /* Restore the private_data structure in case one of the
+ * called dissectors modified it (and, due to the exception,
+ * was unable to restore it).
+ */
+ pinfo->private_data = pd_save;
show_reported_bounds_error(tvb, pinfo, tree);
} ENDTRY;
/*tap_queue_packet(ntlmssp_tap, pinfo, ntlmssph);*/
}
+static gboolean
+dissect_ntlmssp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
+{
+
+ if(tvb_memeql(tvb, 0, "NTLMSSP", 8) == 0) {
+
+ dissect_ntlmssp(tvb, pinfo, parent_tree);
+ return TRUE;
+ }
+
+ return FALSE;
+}
/*
*/
static void
decrypt_verifier(tvbuff_t *tvb, int offset, guint32 encrypted_block_length,
- packet_info *pinfo, proto_tree *tree,gpointer key)
+ packet_info *pinfo, proto_tree *tree,gpointer key)
{
proto_tree *decr_tree = NULL;
proto_item *tf = NULL;
return;
}
conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
- pinfo->ptype, pinfo->srcport,
- pinfo->destport, 0);
+ pinfo->ptype, pinfo->srcport,
+ pinfo->destport, 0);
if (conversation == NULL) {
/* There is no conversation, thus no encryption state */
return;
}
conv_ntlmssp_info = conversation_get_proto_data(conversation,
- proto_ntlmssp);
+ proto_ntlmssp);
if (conv_ntlmssp_info == NULL) {
/* There is no NTLMSSP state tied to the conversation */
return;
if (!packet_ntlmssp_info->verifier_decrypted) {
if (conv_ntlmssp_info->rc4_state_initialized != 1 ) {
/* The crypto sybsystem is not initialized. This means that either
- the conversation did not include a challenge, or we are doing
- something other than NTLMSSP v1 */
+ the conversation did not include a challenge, or we are doing
+ something other than NTLMSSP v1 */
return;
}
if (conv_ntlmssp_info->server_dest_port == pinfo->destport) {
/* Setup the buffer to decrypt to */
tvb_memcpy(tvb, packet_ntlmssp_info->verifier,
- offset, encrypted_block_length);
+ offset, encrypted_block_length);
/*if( !(NTLMSSP_NEGOTIATE_KEY_EXCH & packet_ntlmssp_info->flags)) {*/
if( conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY ) {
/* The spec says that if we have have a key exchange then we have a the signature that is crypted
* otherwise it's just a hmac_md5(keysign,concat(message,sequence))[0..7]
*/
- crypt_rc4(rc4_state, packet_ntlmssp_info->verifier,
- 8);
+ crypt_rc4(rc4_state, packet_ntlmssp_info->verifier, 8);
}
/*
* Try to check the HMAC MD5 of the message against those calculated works great with LDAP payload but
/* The packet has a PAD then a checksum then a sequence and they are encoded in this order so we can decrypt all at once */
/* Do the actual decryption of the verifier */
crypt_rc4(rc4_state, packet_ntlmssp_info->verifier,
- encrypted_block_length);
+ encrypted_block_length);
}
}
/* Show the decrypted buffer in a new window */
decr_tvb = tvb_new_child_real_data(tvb, packet_ntlmssp_info->verifier,
- encrypted_block_length,
- encrypted_block_length);
+ encrypted_block_length,
+ encrypted_block_length);
add_new_data_source(pinfo, decr_tvb,
- "Decrypted NTLMSSP Verifier");
+ "Decrypted NTLMSSP Verifier");
/* Show the decrypted payload in the tree */
tf = proto_tree_add_text(tree, decr_tvb, 0, -1,
- "Decrypted Verifier (%d byte%s)",
- encrypted_block_length,
- plurality(encrypted_block_length, "", "s"));
+ "Decrypted Verifier (%d byte%s)",
+ encrypted_block_length,
+ plurality(encrypted_block_length, "", "s"));
decr_tree = proto_item_add_subtree (tf, ett_ntlmssp);
if(( conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY )) {
proto_tree_add_item (decr_tree, hf_ntlmssp_verf_hmacmd5,
- decr_tvb, decrypted_offset, 8,TRUE);
+ decr_tvb, decrypted_offset, 8,ENC_NA);
decrypted_offset += 8;
/* Incrementing sequence number of DCE conversation */
proto_tree_add_item (decr_tree, hf_ntlmssp_verf_sequence,
- decr_tvb, decrypted_offset, 4, TRUE);
+ decr_tvb, decrypted_offset, 4, ENC_NA);
decrypted_offset += 4;
}
else {
/* RANDOM PAD usually it's 0 */
proto_tree_add_item (decr_tree, hf_ntlmssp_verf_randompad,
- decr_tvb, decrypted_offset, 4, TRUE);
+ decr_tvb, decrypted_offset, 4, ENC_LITTLE_ENDIAN);
decrypted_offset += 4;
/* CRC32 of the DCE fragment data */
proto_tree_add_item (decr_tree, hf_ntlmssp_verf_crc32,
- decr_tvb, decrypted_offset, 4, TRUE);
+ decr_tvb, decrypted_offset, 4, ENC_LITTLE_ENDIAN);
decrypted_offset += 4;
/* Incrementing sequence number of DCE conversation */
proto_tree_add_item (decr_tree, hf_ntlmssp_verf_sequence,
- decr_tvb, decrypted_offset, 4, TRUE);
+ decr_tvb, decrypted_offset, 4, ENC_NA);
decrypted_offset += 4;
}
}
volatile int offset = 0;
proto_tree *volatile ntlmssp_tree = NULL;
guint32 encrypted_block_length;
+ void *pd_save;
+
/* the magic ntlm is the identifier of a NTLMSSP packet that's 00 00 00 01
*/
encrypted_block_length = tvb_length (tvb);
/* signature + seq + real payload */
/* Setup a new tree for the NTLMSSP payload */
- /*
+#if 0
if (tree) {
tf = proto_tree_add_item (tree,
- hf_ntlmssp_verf,
- tvb, offset, -1, FALSE);
+ hf_ntlmssp_verf,
+ tvb, offset, -1, ENC_NA);
ntlmssp_tree = proto_item_add_subtree (tf,
- ett_ntlmssp);
+ ett_ntlmssp);
}
- */
+#endif
/*
* Catch the ReportedBoundsError exception; the stuff we've been
* handed doesn't necessarily run to the end of the packet, it's
* in the packet after our blob to see, so we just re-throw the
* exception.
*/
+ pd_save = pinfo->private_data;
TRY {
/* Version number */
} CATCH(BoundsError) {
RETHROW;
} CATCH(ReportedBoundsError) {
+ /* Restore the private_data structure in case one of the
+ * called dissectors modified it (and, due to the exception,
+ * was unable to restore it).
+ */
+ pinfo->private_data = pd_save;
show_reported_bounds_error(tvb, pinfo, tree);
} ENDTRY;
return offset;
}
+
/* Used when NTLMSSP is done over DCE/RPC because in this case verifier and real payload are not contigious
* But in fact this function could be merged with wrap_dissect_ntlmssp_verf because it's only used there
*/
proto_item *tf = NULL;
guint32 verifier_length;
guint32 encrypted_block_length;
+ void *pd_save;
verifier_length = tvb_length (tvb);
encrypted_block_length = verifier_length - 4;
/* Setup a new tree for the NTLMSSP payload */
if (tree) {
tf = proto_tree_add_item (tree,
- hf_ntlmssp_verf,
- tvb, offset, -1, FALSE);
+ hf_ntlmssp_verf,
+ tvb, offset, -1, ENC_NA);
ntlmssp_tree = proto_item_add_subtree (tf,
- ett_ntlmssp);
+ ett_ntlmssp);
}
/*
* in the packet after our blob to see, so we just re-throw the
* exception.
*/
+ pd_save = pinfo->private_data;
TRY {
/* Version number */
proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_vers,
- tvb, offset, 4, TRUE);
+ tvb, offset, 4, ENC_LITTLE_ENDIAN);
offset += 4;
/* Encrypted body */
proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_body,
- tvb, offset, encrypted_block_length, TRUE);
+ tvb, offset, encrypted_block_length, ENC_NA);
/* Try to decrypt */
decrypt_verifier (tvb, offset, encrypted_block_length, pinfo, ntlmssp_tree,NULL);
} CATCH(BoundsError) {
RETHROW;
} CATCH(ReportedBoundsError) {
+ /* Restore the private_data structure in case one of the
+ * called dissectors modified it (and, due to the exception,
+ * was unable to restore it).
+ */
+ pinfo->private_data = pd_save;
show_reported_bounds_error(tvb, pinfo, tree);
} ENDTRY;
static tvbuff_t *
wrap_dissect_ntlmssp_payload_only(tvbuff_t *tvb,tvbuff_t *auth_tvb _U_,
- int offset, packet_info *pinfo,dcerpc_auth_info *auth_info _U_)
+ int offset, packet_info *pinfo,dcerpc_auth_info *auth_info _U_)
{
- tvbuff_t *data_tvb;
+ tvbuff_t *data_tvb;
- data_tvb = tvb_new_subset(
- tvb, offset, tvb_length_remaining(tvb, offset),
- tvb_length_remaining(tvb, offset));
- dissect_ntlmssp_payload_only(data_tvb, pinfo, NULL);
+ data_tvb = tvb_new_subset(
+ tvb, offset, tvb_length_remaining(tvb, offset),
+ tvb_length_remaining(tvb, offset));
+ dissect_ntlmssp_payload_only(data_tvb, pinfo, NULL);
return pinfo->gssapi_decrypted_tvb;
}
#if 0
-tvbuff_t *
+static tvbuff_t *
dissect_ntlmssp_encrypted_payload(tvbuff_t *data_tvb,
- tvbuff_t *auth_tvb _U_,
- int offset,
- packet_info *pinfo,
- dcerpc_auth_info *auth_info _U_)
+ tvbuff_t *auth_tvb _U_,
+ int offset,
+ packet_info *pinfo,
+ dcerpc_auth_info *auth_info _U_)
{
- / * gssapi_decrypted_tvb=NULL * /
- tvbuff_t *decr_tvb; / * Used to display decrypted buffer * /
+ /* gssapi_decrypted_tvb=NULL */
+ tvbuff_t *decr_tvb; /* Used to display decrypted buffer */
guint8 *peer_block;
conversation_t *conversation;
guint32 encrypted_block_length;
encrypted_block_length = tvb_length_remaining (data_tvb, offset);
fprintf(stderr,"Called dissect_ntlmssp_encrypted_payload\n");
- / * Check to see if we already have state for this packet * /
+ /* Check to see if we already have state for this packet */
packet_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
if (packet_ntlmssp_info == NULL) {
- / * We don't have any packet state, so create one * /
+ /* We don't have any packet state, so create one */
packet_ntlmssp_info = se_alloc0(sizeof(ntlmssp_packet_info));
p_add_proto_data(pinfo->fd, proto_ntlmssp, packet_ntlmssp_info);
}
if (!packet_ntlmssp_info->payload_decrypted) {
- / * Pull the challenge info from the conversation * /
+ /* Pull the challenge info from the conversation */
conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
- pinfo->ptype, pinfo->srcport,
- pinfo->destport, 0);
+ pinfo->ptype, pinfo->srcport,
+ pinfo->destport, 0);
if (conversation == NULL) {
- / * There is no conversation, thus no encryption state * /
+ /* There is no conversation, thus no encryption state */
return NULL;
}
conv_ntlmssp_info = conversation_get_proto_data(conversation,
- proto_ntlmssp);
+ proto_ntlmssp);
if (conv_ntlmssp_info == NULL) {
- / * There is no NTLMSSP state tied to the conversation * /
+ /* There is no NTLMSSP state tied to the conversation */
return NULL;
}
- / * Get the pair of RC4 state structures. One is used for to decrypt the
+ /* Get the pair of RC4 state structures. One is used for to decrypt the
payload. The other is used to re-encrypt the payload to represent
- the peer * /
+ the peer */
if (conv_ntlmssp_info->server_dest_port == pinfo->destport) {
rc4_state = get_encrypted_state(pinfo, 1);
rc4_state_peer = get_encrypted_state(pinfo, 0);
}
if (rc4_state == NULL || rc4_state_peer == NULL) {
- / * There is no encryption state, so we cannot decrypt * /
+ /* There is no encryption state, so we cannot decrypt */
return NULL;
}
- / * Store the decrypted contents in the packet state struct
- (of course at this point, they aren't decrypted yet) * /
+ /* Store the decrypted contents in the packet state struct
+ (of course at this point, they aren't decrypted yet) */
packet_ntlmssp_info->decrypted_payload = tvb_memdup(data_tvb, offset,
encrypted_block_length);
decrypted_payloads = g_slist_prepend(decrypted_payloads,
packet_ntlmssp_info->decrypted_payload);
- / * Do the decryption of the payload * /
+ /* Do the decryption of the payload */
crypt_rc4(rc4_state, packet_ntlmssp_info->decrypted_payload,
- encrypted_block_length);
+ encrypted_block_length);
- / * We setup a temporary buffer so we can re-encrypt the payload after
- decryption. This is to update the opposite peer's RC4 state * /
+ /* We setup a temporary buffer so we can re-encrypt the payload after
+ decryption. This is to update the opposite peer's RC4 state */
peer_block = ep_memdup(packet_ntlmssp_info->decrypted_payload, encrypted_block_length);
crypt_rc4(rc4_state_peer, peer_block, encrypted_block_length);
packet_ntlmssp_info->payload_decrypted = TRUE;
}
- / * Show the decrypted buffer in a new window * /
+ /* Show the decrypted buffer in a new window */
decr_tvb = tvb_new_child_real_data(data_tvb, packet_ntlmssp_info->decrypted_payload,
- encrypted_block_length,
- encrypted_block_length);
+ encrypted_block_length,
+ encrypted_block_length);
offset += encrypted_block_length;
static void
free_payload(gpointer decrypted_payload, gpointer user_data _U_)
{
- g_free(decrypted_payload);
+ g_free(decrypted_payload);
}
-guint g_header_hash(gconstpointer pointer) {
+static guint
+header_hash(gconstpointer pointer)
+{
guint32 crc = ~crc32c_calculate(pointer,NTLMSSP_KEY_LEN,CRC32C_PRELOAD);
/* Mat TBD fprintf(stderr,"Val: %u\n",crc);*/
return crc;
}
-gboolean g_header_equal(gconstpointer pointer1, gconstpointer pointer2) {
+static gboolean
+header_equal(gconstpointer pointer1, gconstpointer pointer2)
+{
if(!memcmp(pointer1,pointer2,16)) {
return TRUE;
}
static void
ntlmssp_init_protocol(void)
{
- /*
- * Free the decrypted payloads, and then free the list of decrypted
- * payloads.
- */
- if (decrypted_payloads != NULL) {
- g_slist_foreach(decrypted_payloads, free_payload, NULL);
- g_slist_free(decrypted_payloads);
- decrypted_payloads = NULL;
- }
+ /*
+ * Free the decrypted payloads, and then free the list of decrypted
+ * payloads.
+ */
+ if (decrypted_payloads != NULL) {
+ g_slist_foreach(decrypted_payloads, free_payload, NULL);
+ g_slist_free(decrypted_payloads);
+ decrypted_payloads = NULL;
+ }
if(hash_packet == NULL) {
- hash_packet = g_hash_table_new(g_header_hash,g_header_equal);
+ hash_packet = g_hash_table_new(header_hash, header_equal);
}
}
+static int
+wrap_dissect_ntlmssp(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, guint8 *drep _U_)
+{
+ tvbuff_t *auth_tvb;
+
+ auth_tvb = tvb_new_subset(
+ tvb, offset, tvb_length_remaining(tvb, offset),
+ tvb_length_remaining(tvb, offset));
+
+ dissect_ntlmssp(auth_tvb, pinfo, tree);
+
+ return tvb_length_remaining(tvb, offset);
+}
+
+static int
+wrap_dissect_ntlmssp_verf(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, guint8 *drep _U_)
+{
+ tvbuff_t *auth_tvb;
+
+ auth_tvb = tvb_new_subset(
+ tvb, offset, tvb_length_remaining(tvb, offset),
+ tvb_length_remaining(tvb, offset));
+ return dissect_ntlmssp_verf(auth_tvb, pinfo, tree);
+}
+
+static dcerpc_auth_subdissector_fns ntlmssp_sign_fns = {
+ wrap_dissect_ntlmssp, /* Bind */
+ wrap_dissect_ntlmssp, /* Bind ACK */
+ wrap_dissect_ntlmssp, /* AUTH3 */
+ wrap_dissect_ntlmssp_verf, /* Request verifier */
+ wrap_dissect_ntlmssp_verf, /* Response verifier */
+ NULL, /* Request data */
+ NULL /* Response data */
+};
+
+static dcerpc_auth_subdissector_fns ntlmssp_seal_fns = {
+ wrap_dissect_ntlmssp, /* Bind */
+ wrap_dissect_ntlmssp, /* Bind ACK */
+ wrap_dissect_ntlmssp, /* AUTH3 */
+ wrap_dissect_ntlmssp_verf, /* Request verifier */
+ wrap_dissect_ntlmssp_verf, /* Response verifier */
+ wrap_dissect_ntlmssp_payload_only, /* Request data */
+ wrap_dissect_ntlmssp_payload_only /* Response data */
+};
+
void
proto_register_ntlmssp(void)
{
{ "Target Type Server", "ntlmssp.targettypeserver", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_TARGET_TYPE_SERVER, NULL, HFILL }},
{ &hf_ntlmssp_negotiate_flags_40000,
{ "Target Type Share", "ntlmssp.targettypeshare", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_TARGET_TYPE_SHARE, NULL, HFILL }},
+
+/* Negotiate Flags */
{ &hf_ntlmssp_negotiate_flags_80000,
{ "Negotiate Extended Security", "ntlmssp.negotiatentlm2", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_EXTENDED_SECURITY, NULL, HFILL }},
{ &hf_ntlmssp_negotiate_flags_100000,
{ "NTLM Server Challenge", "ntlmssp.ntlmserverchallenge", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_ntlmssp_reserved,
{ "Reserved", "ntlmssp.reserved", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+
{ &hf_ntlmssp_challenge_target_name,
{ "Target Name", "ntlmssp.challenge.target_name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_ntlmssp_auth_domain,
{ "Maxlen", "ntlmssp.blob.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
{ &hf_ntlmssp_blob_offset,
{ "Offset", "ntlmssp.blob.offset", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}},
+ { &hf_ntlmssp_version,
+ { "Version", "ntlmssp.version", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
{ &hf_ntlmssp_version_major,
{ "Major Version", "ntlmssp.version.major", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
{ &hf_ntlmssp_version_minor,
{ "Minor Version", "ntlmssp.version.minor", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
{ &hf_ntlmssp_version_build_number,
- { "Major Version", "ntlmssp.version.build_number", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
+ { "Build Number", "ntlmssp.version.build_number", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
{ &hf_ntlmssp_version_ntlm_current_revision,
{ "NTLM Current Revision", "ntlmssp.version.ntlm_current_revision", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
- { &hf_ntlmssp_address_list,
- { "Address List", "ntlmssp.challenge.addresslist", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
- { &hf_ntlmssp_address_list_len,
- { "Length", "ntlmssp.challenge.addresslist.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
- { &hf_ntlmssp_address_list_maxlen,
- { "Maxlen", "ntlmssp.challenge.addresslist.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
- { &hf_ntlmssp_address_list_offset,
- { "Offset", "ntlmssp.challenge.addresslist.offset", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}},
- { &hf_ntlmssp_address_list_item_type,
- { "Target item type", "ntlmssp.targetitemtype", FT_UINT16, BASE_HEX, VALS(ntlm_name_types), 0x0, NULL, HFILL }},
- { &hf_ntlmssp_address_list_item_len,
- { "Target item Length", "ntlmssp.challenge.addresslist.item.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
- { &hf_ntlmssp_address_list_item_content,
- { "Target item Content", "ntlmssp.challenge.addresslist.item.content", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}},
- { &hf_ntlmssp_address_list_server_nb,
- { "Server NetBIOS Name", "ntlmssp.challenge.addresslist.servernb", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
- { &hf_ntlmssp_address_list_domain_nb,
- { "Domain NetBIOS Name", "ntlmssp.challenge.addresslist.domainnb", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
- { &hf_ntlmssp_address_list_server_dns,
- { "Server DNS Name", "ntlmssp.challenge.addresslist.serverdns", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
- { &hf_ntlmssp_address_list_domain_dns,
- { "Domain DNS Name", "ntlmssp.challenge.addresslist.domaindns", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
- { &hf_ntlmssp_address_list_forest_dns,
- { "Forest DNS Name", "ntlmssp.challenge.addresslist.forestdns", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
- { &hf_ntlmssp_address_list_terminator,
- { "List Terminator", "ntlmssp.challenge.addresslist.terminator", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+
+/* Target Info */
+ { &hf_ntlmssp_challenge_target_info,
+ { "Target Info", "ntlmssp.challenge.target_info", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
+ { &hf_ntlmssp_challenge_target_info_len,
+ { "Length", "ntlmssp.challenge.target_info.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
+ { &hf_ntlmssp_challenge_target_info_maxlen,
+ { "Maxlen", "ntlmssp.challenge.target_info.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
+ { &hf_ntlmssp_challenge_target_info_offset,
+ { "Offset", "ntlmssp.challenge.target_info.offset", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}},
+
+ { &hf_ntlmssp_challenge_target_info_item_type,
+ { "Target Info Item Type", "ntlmssp.challenge.target_info.item.type", FT_UINT16, BASE_HEX, VALS(ntlm_name_types), 0x0, NULL, HFILL }},
+ { &hf_ntlmssp_challenge_target_info_item_len,
+ { "Target Info Item Length", "ntlmssp.challenge.target_info.item.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
+
+ { &hf_ntlmssp_challenge_target_info_end,
+ { "List End", "ntlmssp.challenge.target_info.end", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+ { &hf_ntlmssp_challenge_target_info_nb_computer_name,
+ { "NetBIOS Computer Name", "ntlmssp.challenge.target_info.nb_computer_name", FT_STRING, BASE_NONE, NULL, 0x0, "Server NetBIOS Computer Name", HFILL }},
+ { &hf_ntlmssp_challenge_target_info_nb_domain_name,
+ { "NetBIOS Domain Name", "ntlmssp.challenge.target_info.nb_domain_name", FT_STRING, BASE_NONE, NULL, 0x0, "Server NetBIOS Domain Name", HFILL }},
+ { &hf_ntlmssp_challenge_target_info_dns_computer_name,
+ { "DNS Computer Name", "ntlmssp.challenge.target_info.dns_computer_name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+ { &hf_ntlmssp_challenge_target_info_dns_domain_name,
+ { "DNS Domain Name", "ntlmssp.challenge.target_info.dns_domain_name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+ { &hf_ntlmssp_challenge_target_info_dns_tree_name,
+ { "DNS Tree Name", "ntlmssp.challenge.target_info.dns_tree_name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+ { &hf_ntlmssp_challenge_target_info_flags,
+ { "Flags", "ntlmssp.challenge.target_info.flags", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+ { &hf_ntlmssp_challenge_target_info_timestamp,
+ { "Timestamp", "ntlmssp.challenge.target_info.timestamp", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0, NULL, HFILL }},
+ { &hf_ntlmssp_challenge_target_info_restrictions,
+ { "Restrictions", "ntlmssp.challenge.target_info.restrictions", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
+ { &hf_ntlmssp_challenge_target_info_target_name,
+ { "Target Name", "ntlmssp.challenge.target_info.target_name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+ { &hf_ntlmssp_challenge_target_info_channel_bindings,
+ { "Channel Bindings", "ntlmssp.challenge.target_info.channel_bindings", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+
+ { &hf_ntlmssp_ntlmv2_response_item_type,
+ { "NTLMV2 Response Item Type", "ntlmssp.ntlmv2_response.item.type", FT_UINT16, BASE_HEX, VALS(ntlm_name_types), 0x0, NULL, HFILL }},
+ { &hf_ntlmssp_ntlmv2_response_item_len,
+ { "NTLMV2 Response Item Length", "ntlmssp.ntlmv2_response.item.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
+
+ { &hf_ntlmssp_ntlmv2_response_end,
+ { "List End", "ntlmssp.ntlmv2_response.end", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+ { &hf_ntlmssp_ntlmv2_response_nb_computer_name,
+ { "NetBIOS Computer Name", "ntlmssp.ntlmv2_response.nb_computer_name", FT_STRING, BASE_NONE, NULL, 0x0, "Server NetBIOS Computer Name", HFILL }},
+ { &hf_ntlmssp_ntlmv2_response_nb_domain_name,
+ { "NetBIOS Domain Name", "ntlmssp.ntlmv2_response.nb_domain_name", FT_STRING, BASE_NONE, NULL, 0x0, "Server NetBIOS Domain Name", HFILL }},
+ { &hf_ntlmssp_ntlmv2_response_dns_computer_name,
+ { "DNS Computer Name", "ntlmssp.ntlmv2_response.dns_computer_name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+ { &hf_ntlmssp_ntlmv2_response_dns_domain_name,
+ { "DNS Domain Name", "ntlmssp.ntlmv2_response.dns_domain_name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+ { &hf_ntlmssp_ntlmv2_response_dns_tree_name,
+ { "DNS Tree Name", "ntlmssp.ntlmv2_response.dns_tree_name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+ { &hf_ntlmssp_ntlmv2_response_flags,
+ { "Flags", "ntlmssp.ntlmv2_response.flags", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+ { &hf_ntlmssp_ntlmv2_response_timestamp,
+ { "Timestamp", "ntlmssp.ntlmv2_response.timestamp", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0, NULL, HFILL }},
+ { &hf_ntlmssp_ntlmv2_response_restrictions,
+ { "Restrictions", "ntlmssp.ntlmv2_response.restrictions", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
+ { &hf_ntlmssp_ntlmv2_response_target_name,
+ { "Target Name", "ntlmssp.ntlmv2_response.target_name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+ { &hf_ntlmssp_ntlmv2_response_channel_bindings,
+ { "Channel Bindings", "ntlmssp.ntlmv2_response.channel_bindings", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+
{ &hf_ntlmssp_message_integrity_code,
{ "MIC", "ntlmssp.authenticate.mic", FT_BYTES, BASE_NONE, NULL, 0x0, "Message Integrity Code", HFILL}},
{ &hf_ntlmssp_verf,
{ "HMAC MD5", "ntlmssp.verf.hmacmd5", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_ntlmssp_verf_sequence,
{ "Sequence", "ntlmssp.verf.sequence", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+
{ &hf_ntlmssp_ntlmv2_response,
- { "NTLMv2 Response", "ntlmssp.ntlmv2response", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+ { "NTLMv2 Response", "ntlmssp.ntlmv2_response", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_ntlmssp_ntlmv2_response_hmac,
- { "HMAC", "ntlmssp.ntlmv2response.hmac", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+ { "HMAC", "ntlmssp.ntlmv2_response.hmac", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_ntlmssp_ntlmv2_response_header,
- { "Header", "ntlmssp.ntlmv2response.header", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+ { "Header", "ntlmssp.ntlmv2_response.header", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
{ &hf_ntlmssp_ntlmv2_response_reserved,
- { "Reserved", "ntlmssp.ntlmv2response.reserved", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+ { "Reserved", "ntlmssp.ntlmv2_response.reserved", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
{ &hf_ntlmssp_ntlmv2_response_time,
- { "Time", "ntlmssp.ntlmv2response.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0, NULL, HFILL }},
+ { "Time", "ntlmssp.ntlmv2_response.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0, NULL, HFILL }},
{ &hf_ntlmssp_ntlmv2_response_chal,
- { "Client challenge", "ntlmssp.ntlmv2response.chal", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+ { "Client challenge", "ntlmssp.ntlmv2_response.chal", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_ntlmssp_ntlmv2_response_unknown,
- { "Unknown", "ntlmssp.ntlmv2response.unknown", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
- { &hf_ntlmssp_ntlmv2_response_name,
- { "Attribute", "ntlmssp.ntlmv2response.name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
- { &hf_ntlmssp_ntlmv2_response_name_type,
- { "Attribute type", "ntlmssp.ntlmv2response.name.type", FT_UINT32, BASE_DEC, VALS(ntlm_name_types), 0x0, NULL, HFILL }},
- { &hf_ntlmssp_ntlmv2_response_name_len,
- { "Value len", "ntlmssp.ntlmv2response.name.len", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
- { &hf_ntlmssp_ntlmv2_response_restriction,
- { "Encoding restrictions", "ntlmssp.ntlmv2response.name.restrictions", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
- { &hf_ntlmssp_ntlmv2_response_client_time,
- { "Client Time", "ntlmssp.ntlmv2response.client_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0, NULL, HFILL }}
+ { "Unknown", "ntlmssp.ntlmv2_response.unknown", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }}
};
&ett_ntlmssp_string,
&ett_ntlmssp_blob,
&ett_ntlmssp_version,
- &ett_ntlmssp_address_list,
- &ett_ntlmssp_address_list_item,
+ &ett_ntlmssp_challenge_target_info,
+ &ett_ntlmssp_challenge_target_info_item,
&ett_ntlmssp_ntlmv2_response,
- &ett_ntlmssp_ntlmv2_response_name
+ &ett_ntlmssp_ntlmv2_response_item,
};
module_t *ntlmssp_module;
proto_ntlmssp = proto_register_protocol (
- "NTLM Secure Service Provider", /* name */
- "NTLMSSP", /* short name */
- "ntlmssp" /* abbrev */
- );
+ "NTLM Secure Service Provider", /* name */
+ "NTLMSSP", /* short name */
+ "ntlmssp" /* abbrev */
+ );
proto_register_field_array (proto_ntlmssp, hf, array_length (hf));
proto_register_subtree_array (ett, array_length (ett));
register_init_routine(&ntlmssp_init_protocol);
ntlmssp_module = prefs_register_protocol(proto_ntlmssp, NULL);
prefs_register_string_preference(ntlmssp_module, "nt_password",
- "NT Password",
- "NT Password (used to decrypt payloads)",
- &gbl_nt_password);
+ "NT Password",
+ "NT Password (used to decrypt payloads)",
+ &gbl_nt_password);
register_dissector("ntlmssp", dissect_ntlmssp, proto_ntlmssp);
new_register_dissector("ntlmssp_payload", dissect_ntlmssp_payload, proto_ntlmssp);
new_register_dissector("ntlmssp_verf", dissect_ntlmssp_verf, proto_ntlmssp);
}
-static int wrap_dissect_ntlmssp(tvbuff_t *tvb, int offset, packet_info *pinfo,
- proto_tree *tree, guint8 *drep _U_)
-{
- tvbuff_t *auth_tvb;
-
- auth_tvb = tvb_new_subset(
- tvb, offset, tvb_length_remaining(tvb, offset),
- tvb_length_remaining(tvb, offset));
-
- dissect_ntlmssp(auth_tvb, pinfo, tree);
-
- return tvb_length_remaining(tvb, offset);
-}
-
-static int wrap_dissect_ntlmssp_verf(tvbuff_t *tvb, int offset, packet_info *pinfo,
- proto_tree *tree, guint8 *drep _U_)
-{
- tvbuff_t *auth_tvb;
-
- auth_tvb = tvb_new_subset(
- tvb, offset, tvb_length_remaining(tvb, offset),
- tvb_length_remaining(tvb, offset));
- return dissect_ntlmssp_verf(auth_tvb, pinfo, tree);
-}
-
-static dcerpc_auth_subdissector_fns ntlmssp_sign_fns = {
- wrap_dissect_ntlmssp, /* Bind */
- wrap_dissect_ntlmssp, /* Bind ACK */
- wrap_dissect_ntlmssp, /* AUTH3 */
- wrap_dissect_ntlmssp_verf, /* Request verifier */
- wrap_dissect_ntlmssp_verf, /* Response verifier */
- NULL, /* Request data */
- NULL /* Response data */
-};
-
-static dcerpc_auth_subdissector_fns ntlmssp_seal_fns = {
- wrap_dissect_ntlmssp, /* Bind */
- wrap_dissect_ntlmssp, /* Bind ACK */
- wrap_dissect_ntlmssp, /* AUTH3 */
- wrap_dissect_ntlmssp_verf, /* Request verifier */
- wrap_dissect_ntlmssp_verf, /* Response verifier */
- wrap_dissect_ntlmssp_payload_only, /* Request data */
- wrap_dissect_ntlmssp_payload_only /* Response data */
-};
-
void
proto_reg_handoff_ntlmssp(void)
{
ntlmssp_handle = find_dissector("ntlmssp");
ntlmssp_wrap_handle = find_dissector("ntlmssp_verf");
gssapi_init_oid("1.3.6.1.4.1.311.2.2.10", proto_ntlmssp, ett_ntlmssp,
- ntlmssp_handle, ntlmssp_wrap_handle,
- "NTLMSSP - Microsoft NTLM Security Support Provider");
+ ntlmssp_handle, ntlmssp_wrap_handle,
+ "NTLMSSP - Microsoft NTLM Security Support Provider");
/* Register authenticated pipe dissector */
* any other levels here?
*/
register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_CONNECT,
- DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
- &ntlmssp_sign_fns);
+ DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
+ &ntlmssp_sign_fns);
register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT,
- DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
- &ntlmssp_sign_fns);
+ DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
+ &ntlmssp_sign_fns);
register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_INTEGRITY,
- DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
- &ntlmssp_sign_fns);
+ DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
+ &ntlmssp_sign_fns);
register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_PRIVACY,
- DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
- &ntlmssp_seal_fns);
+ DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
+ &ntlmssp_seal_fns);
ntlmssp_tap = register_tap("ntlmssp");
+
+ heur_dissector_add("credssp", dissect_ntlmssp_heur, proto_ntlmssp);
+
}
/*
* indent-tabs-mode: nil
* End:
*
- * vi: set shiftwidth=2 tabstop=8 expandtab
+ * vi: set shiftwidth=2 tabstop=8 expandtab:
* :indentSize=2:tabSize=8:noTabs=true:
*/