Split get_dns_name() into get_dns_name() and expand_dns_name().

In dissect_ms_compressed_string() dissect_mscldap_string() simply call
expand_dns_name() instead of using duplicate (and insecure) code. This
*might* break CLDAP and SMB dissection. If that's the case we should
probably revert get_dns_name() and simplify expand_dns_name().

Fixes infinite recursion errors found by joernchen of Phenoelit.

svn path=/trunk/; revision=36029
This commit is contained in:
Gerald Combs 2011-02-23 00:51:02 +00:00
parent 740c1c4aeb
commit 4783795690
9 changed files with 68 additions and 202 deletions

View File

@ -111,6 +111,7 @@
#include "packet-ber.h"
#include "packet-per.h"
#include "packet-dns.h"
#define PNAME "Lightweight Directory Access Protocol"
#define PSNAME "LDAP"
@ -1112,64 +1113,19 @@ dissect_ldap_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean i
}
}
int dissect_mscldap_string(tvbuff_t *tvb, int offset, char *str, int maxlen, gboolean prepend_dot)
/*
* prepend_dot is no longer used, but is being left in place in order to
* maintain ABI compatibility.
*/
int dissect_mscldap_string(tvbuff_t *tvb, int offset, char *str, int max_len, gboolean prepend_dot _U_)
{
guint8 len;
int compr_len;
const guchar *name;
len=tvb_get_guint8(tvb, offset);
offset+=1;
*str=0;
attributedesc_string=NULL;
while(len){
/* add potential field separation dot */
if(prepend_dot){
if(!maxlen){
*str=0;
return offset;
}
maxlen--;
*str++='.';
*str=0;
}
if(len==0xc0){
int new_offset;
/* ops its a mscldap compressed string */
new_offset=tvb_get_guint8(tvb, offset);
if (new_offset == offset - 1)
THROW(ReportedBoundsError);
offset+=1;
dissect_mscldap_string(tvb, new_offset, str, maxlen, FALSE);
return offset;
}
prepend_dot=TRUE;
if(maxlen<=len){
if(maxlen>3){
*str++='.';
*str++='.';
*str++='.';
}
*str=0;
return offset; /* will mess up offset in caller, is unlikely */
}
tvb_memcpy(tvb, str, offset, len);
str+=len;
*str=0;
maxlen-=len;
offset+=len;
len=tvb_get_guint8(tvb, offset);
offset+=1;
}
*str=0;
return offset;
/* The name data MUST start at offset 0 of the tvb */
compr_len = expand_dns_name(tvb, offset, max_len, 0, &name);
g_strlcpy(str, name, max_len);
return offset + compr_len;
}

View File

@ -103,7 +103,7 @@ typedef struct ldap_call_response {
void register_ldap_name_dissector_handle(const char *attr_type, dissector_handle_t dissector);
void register_ldap_name_dissector(const char *attr_type, dissector_t dissector, int proto);
int dissect_mscldap_string(tvbuff_t *tvb, int offset, char *str, int maxlen, gboolean prepend_dot);
int dissect_mscldap_string(tvbuff_t *tvb, int offset, char *str, int max_len, gboolean prepend_dot _U_);
/*#include "packet-ldap-exp.h" */

View File

@ -656,7 +656,7 @@ dns_class_name(int class)
* it will be automatically free()d when the packet has been dissected.
*/
int
get_dns_name(tvbuff_t *tvb, int offset, int max_len, int dns_data_offset,
expand_dns_name(tvbuff_t *tvb, int offset, int max_len, int dns_data_offset,
const guchar **name)
{
int start_offset = offset;
@ -818,14 +818,25 @@ get_dns_name(tvbuff_t *tvb, int offset, int max_len, int dns_data_offset,
set the length, so set it. */
if (len < 0)
len = offset - start_offset;
/* Zero-length name means "root server" */
if (**name == '\0')
*name="<Root>";
if (len < min_len)
THROW(ReportedBoundsError);
return len;
}
int
get_dns_name(tvbuff_t *tvb, int offset, int max_len, int dns_data_offset,
const guchar **name)
{
int len;
len = expand_dns_name(tvb, offset, max_len, dns_data_offset, name);
/* Zero-length name means "root server" */
if (**name == '\0')
*name="<Root>";
return len;
}
static int
get_dns_name_type_class(tvbuff_t *tvb, int offset, int dns_data_offset,

View File

@ -29,6 +29,8 @@
const char *dns_class_name(int class);
int expand_dns_name(tvbuff_t *, int, int, int, const guchar **);
/* Just like expand_dns_name, but pretty-prints empty names. */
int get_dns_name(tvbuff_t *, int, int, int, const guchar **);
#define MAXDNAME 1025 /* maximum domain name length */

View File

@ -119,6 +119,7 @@
#include "packet-ber.h"
#include "packet-per.h"
#include "packet-dns.h"
#define PNAME "Lightweight Directory Access Protocol"
#define PSNAME "LDAP"
@ -339,7 +340,7 @@ static int hf_ldap_graceAuthNsRemaining = -1; /* INTEGER_0_maxInt */
static int hf_ldap_error = -1; /* T_error */
/*--- End of included file: packet-ldap-hf.c ---*/
#line 186 "packet-ldap-template.c"
#line 187 "packet-ldap-template.c"
/* Initialize the subtree pointers */
static gint ett_ldap = -1;
@ -412,7 +413,7 @@ static gint ett_ldap_PasswordPolicyResponseValue = -1;
static gint ett_ldap_T_warning = -1;
/*--- End of included file: packet-ldap-ett.c ---*/
#line 197 "packet-ldap-template.c"
#line 198 "packet-ldap-template.c"
static dissector_table_t ldap_name_dissector_table=NULL;
static const char *object_identifier_id = NULL; /* LDAP OID */
@ -3683,7 +3684,7 @@ static void dissect_PasswordPolicyResponseValue_PDU(tvbuff_t *tvb _U_, packet_in
/*--- End of included file: packet-ldap-fn.c ---*/
#line 737 "packet-ldap-template.c"
#line 738 "packet-ldap-template.c"
static void
dissect_ldap_payload(tvbuff_t *tvb, packet_info *pinfo,
@ -4062,64 +4063,19 @@ dissect_ldap_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean i
}
}
int dissect_mscldap_string(tvbuff_t *tvb, int offset, char *str, int maxlen, gboolean prepend_dot)
/*
* prepend_dot is no longer used, but is being left in place in order to
* maintain ABI compatibility.
*/
int dissect_mscldap_string(tvbuff_t *tvb, int offset, char *str, int max_len, gboolean prepend_dot _U_)
{
guint8 len;
int compr_len;
const guchar *name;
len=tvb_get_guint8(tvb, offset);
offset+=1;
*str=0;
attributedesc_string=NULL;
while(len){
/* add potential field separation dot */
if(prepend_dot){
if(!maxlen){
*str=0;
return offset;
}
maxlen--;
*str++='.';
*str=0;
}
if(len==0xc0){
int new_offset;
/* ops its a mscldap compressed string */
new_offset=tvb_get_guint8(tvb, offset);
if (new_offset == offset - 1)
THROW(ReportedBoundsError);
offset+=1;
dissect_mscldap_string(tvb, new_offset, str, maxlen, FALSE);
return offset;
}
prepend_dot=TRUE;
if(maxlen<=len){
if(maxlen>3){
*str++='.';
*str++='.';
*str++='.';
}
*str=0;
return offset; /* will mess up offset in caller, is unlikely */
}
tvb_memcpy(tvb, str, offset, len);
str+=len;
*str=0;
maxlen-=len;
offset+=len;
len=tvb_get_guint8(tvb, offset);
offset+=1;
}
*str=0;
return offset;
/* The name data MUST start at offset 0 of the tvb */
compr_len = expand_dns_name(tvb, offset, max_len, 0, &name);
g_strlcpy(str, name, max_len);
return offset + compr_len;
}
@ -5606,7 +5562,7 @@ void proto_register_ldap(void) {
NULL, HFILL }},
/*--- End of included file: packet-ldap-hfarr.c ---*/
#line 2079 "packet-ldap-template.c"
#line 2035 "packet-ldap-template.c"
};
/* List of subtrees */
@ -5681,7 +5637,7 @@ void proto_register_ldap(void) {
&ett_ldap_T_warning,
/*--- End of included file: packet-ldap-ettarr.c ---*/
#line 2092 "packet-ldap-template.c"
#line 2048 "packet-ldap-template.c"
};
module_t *ldap_module;
@ -5812,7 +5768,7 @@ proto_reg_handoff_ldap(void)
/*--- End of included file: packet-ldap-dis-tab.c ---*/
#line 2206 "packet-ldap-template.c"
#line 2162 "packet-ldap-template.c"
}

View File

@ -111,7 +111,7 @@ typedef struct ldap_call_response {
void register_ldap_name_dissector_handle(const char *attr_type, dissector_handle_t dissector);
void register_ldap_name_dissector(const char *attr_type, dissector_t dissector, int proto);
int dissect_mscldap_string(tvbuff_t *tvb, int offset, char *str, int maxlen, gboolean prepend_dot);
int dissect_mscldap_string(tvbuff_t *tvb, int offset, char *str, int max_len, gboolean prepend_dot _U_);
/*#include "packet-ldap-exp.h" */

View File

@ -36,6 +36,8 @@
#include <epan/strutil.h>
#include "packet-smb-common.h"
#include "packet-dns.h"
/*
* Share type values - used in LANMAN and in SRVSVC.
*
@ -124,84 +126,23 @@ int display_unicode_string(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_i
return offset+len;
}
static int dissect_ms_compressed_string_internal(tvbuff_t *tvb, int offset, char *str, int maxlen, gboolean prepend_dot)
{
guint8 len;
len=tvb_get_guint8(tvb, offset);
offset+=1;
*str=0;
/* XXX: Reserve 4 chars for "...\0" */
while(len){
/* add potential field separation dot */
if(prepend_dot){
if(maxlen<=4){
*str=0;
return offset;
}
maxlen--;
*str++='.';
*str=0;
}
if(len==0xc0){
int new_offset;
/* ops its a mscldap compressed string */
new_offset=tvb_get_guint8(tvb, offset);
if (new_offset == offset - 1)
THROW(ReportedBoundsError);
offset+=1;
dissect_ms_compressed_string_internal(tvb, new_offset, str, maxlen, FALSE);
return offset;
}
prepend_dot=TRUE;
if(len>(maxlen-4)){
*str++='.';
*str++='.';
*str++='.';
*str=0;
return offset; /* will mess up offset in caller, is unlikely */
}
tvb_memcpy(tvb, str, offset, len);
str+=len;
*str=0;
maxlen-=len;
offset+=len;
len=tvb_get_guint8(tvb, offset);
offset+=1;
}
*str=0;
return offset;
}
/* Max string length for displaying Unicode strings. */
#define MAX_UNICODE_STR_LEN 256
int dissect_ms_compressed_string(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_index,
gboolean prepend_dot, char **data)
char **data)
{
int old_offset=offset;
char *str;
int len;
int compr_len;
const guchar *str = NULL;
len = MAX_UNICODE_STR_LEN+3+1;
str=ep_alloc(len);
offset=dissect_ms_compressed_string_internal(tvb, offset, str, len, prepend_dot);
proto_tree_add_string(tree, hf_index, tvb, old_offset, offset-old_offset, str);
/* The name data MUST start at offset 0 of the tvb */
compr_len = expand_dns_name(tvb, offset, MAX_UNICODE_STR_LEN+3+1, 0, &str);
proto_tree_add_string(tree, hf_index, tvb, offset, compr_len, str);
if (data)
*data = str;
*data = (char*) str;
return offset;
return offset + compr_len;
}
/* Turn a little-endian Unicode '\0'-terminated string into a string we

View File

@ -37,7 +37,7 @@ int display_unicode_string(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_i
int display_ms_string(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_index, char **data);
int dissect_ms_compressed_string(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_index,
gboolean prepend_dot, char **data);
char **data);
const gchar *get_unicode_or_ascii_string(tvbuff_t *tvb, int *offsetp,
gboolean useunicode, int *len, gboolean nopad, gboolean exactlen,

View File

@ -759,28 +759,28 @@ dissect_smb_pdc_response_ads(tvbuff_t *tvb, packet_info *pinfo _U_,
offset += 16;
/* forest dns name */
offset=dissect_ms_compressed_string(tvb, tree, offset, hf_forest_dns_name, FALSE, NULL);
offset=dissect_ms_compressed_string(tvb, tree, offset, hf_forest_dns_name, NULL);
/* domain dns name */
offset=dissect_ms_compressed_string(tvb, tree, offset, hf_domain_dns_name, FALSE, NULL);
offset=dissect_ms_compressed_string(tvb, tree, offset, hf_domain_dns_name, NULL);
/* server dns name */
offset=dissect_ms_compressed_string(tvb, tree, offset, hf_server_dns_name, FALSE, NULL);
offset=dissect_ms_compressed_string(tvb, tree, offset, hf_server_dns_name, NULL);
/* domain name */
offset=dissect_ms_compressed_string(tvb, tree, offset, hf_domain_name, FALSE, NULL);
offset=dissect_ms_compressed_string(tvb, tree, offset, hf_domain_name, NULL);
/* server name */
offset=dissect_ms_compressed_string(tvb, tree, offset, hf_server_name, FALSE, NULL);
offset=dissect_ms_compressed_string(tvb, tree, offset, hf_server_name, NULL);
/* user name */
offset=dissect_ms_compressed_string(tvb, tree, offset, hf_user_name, FALSE, NULL);
offset=dissect_ms_compressed_string(tvb, tree, offset, hf_user_name, NULL);
/* server_site name */
offset=dissect_ms_compressed_string(tvb, tree, offset, hf_server_site_name, FALSE, NULL);
offset=dissect_ms_compressed_string(tvb, tree, offset, hf_server_site_name, NULL);
/* client_site name */
offset=dissect_ms_compressed_string(tvb, tree, offset, hf_client_site_name, FALSE, NULL);
offset=dissect_ms_compressed_string(tvb, tree, offset, hf_client_site_name, NULL);
/* unknown uint8 type */
proto_tree_add_item(tree, hf_unknown8, tvb, offset, 1, TRUE);