From bd0102fc6424b79a2f12c4ed345bbf07dc5899aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Valverde?= Date: Wed, 19 Oct 2022 14:51:32 +0100 Subject: [PATCH] LDAP: Validate DNS name string encoding --- .../asn1/ldap/packet-ldap-template.c | 33 +++++++------- .../asn1/ldap/packet-ldap-template.h | 2 +- epan/dissectors/packet-dcerpc-netlogon.c | 12 ++--- epan/dissectors/packet-ldap.c | 45 +++++++++---------- epan/dissectors/packet-ldap.h | 2 +- 5 files changed, 44 insertions(+), 50 deletions(-) diff --git a/epan/dissectors/asn1/ldap/packet-ldap-template.c b/epan/dissectors/asn1/ldap/packet-ldap-template.c index fa06939487..b450c7e645 100644 --- a/epan/dissectors/asn1/ldap/packet-ldap-template.c +++ b/epan/dissectors/asn1/ldap/packet-ldap-template.c @@ -82,6 +82,7 @@ #include #include #include +#include #include #include "packet-frame.h" #include "packet-tcp.h" @@ -1312,11 +1313,7 @@ static void } } -/* - * 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_) +int dissect_mscldap_string(tvbuff_t *tvb, int offset, int max_len, char **str) { int compr_len; const gchar *name; @@ -1324,7 +1321,7 @@ int dissect_mscldap_string(tvbuff_t *tvb, int offset, char *str, int max_len, gb /* The name data MUST start at offset 0 of the tvb */ compr_len = get_dns_name(tvb, offset, max_len, 0, &name, &name_len); - (void) g_strlcpy(str, name, max_len); + *str = get_utf_8_string(wmem_packet_scope(), name, name_len); return offset + compr_len; } @@ -1423,7 +1420,7 @@ static int dissect_mscldap_netlogon_flags(proto_tree *parent_tree, tvbuff_t *tvb static int dissect_NetLogon_PDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_) { int old_offset, offset=0; - char str[256]; + char *str; guint16 itype; guint16 len; guint32 version; @@ -1487,17 +1484,17 @@ static int dissect_NetLogon_PDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tre /* Forest */ old_offset=offset; - offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE); + offset=dissect_mscldap_string(tvb, offset, 255, &str); proto_tree_add_string(tree, hf_mscldap_forest, tvb, old_offset, offset-old_offset, str); /* Domain */ old_offset=offset; - offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE); + offset=dissect_mscldap_string(tvb, offset, 255, &str); proto_tree_add_string(tree, hf_mscldap_domain, tvb, old_offset, offset-old_offset, str); /* Hostname */ old_offset=offset; - offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE); + offset=dissect_mscldap_string(tvb, offset, 255, &str); proto_tree_add_string(tree, hf_mscldap_hostname, tvb, old_offset, offset-old_offset, str); /* DC IP Address */ @@ -1523,42 +1520,42 @@ static int dissect_NetLogon_PDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tre /* Forest */ old_offset=offset; - offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE); + offset=dissect_mscldap_string(tvb, offset, 255, &str); proto_tree_add_string(tree, hf_mscldap_forest, tvb, old_offset, offset-old_offset, str); /* Domain */ old_offset=offset; - offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE); + offset=dissect_mscldap_string(tvb, offset, 255, &str); proto_tree_add_string(tree, hf_mscldap_domain, tvb, old_offset, offset-old_offset, str); /* Hostname */ old_offset=offset; - offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE); + offset=dissect_mscldap_string(tvb, offset, 255, &str); proto_tree_add_string(tree, hf_mscldap_hostname, tvb, old_offset, offset-old_offset, str); /* NetBIOS Domain */ old_offset=offset; - offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE); + offset=dissect_mscldap_string(tvb, offset, 255, &str); proto_tree_add_string(tree, hf_mscldap_nb_domain, tvb, old_offset, offset-old_offset, str); /* NetBIOS Hostname */ old_offset=offset; - offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE); + offset=dissect_mscldap_string(tvb, offset, 255, &str); proto_tree_add_string(tree, hf_mscldap_nb_hostname, tvb, old_offset, offset-old_offset, str); /* User */ old_offset=offset; - offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE); + offset=dissect_mscldap_string(tvb, offset, 255, &str); proto_tree_add_string(tree, hf_mscldap_username, tvb, old_offset, offset-old_offset, str); /* Server Site */ old_offset=offset; - offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE); + offset=dissect_mscldap_string(tvb, offset, 255, &str); proto_tree_add_string(tree, hf_mscldap_sitename, tvb, old_offset, offset-old_offset, str); /* Client Site */ old_offset=offset; - offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE); + offset=dissect_mscldap_string(tvb, offset, 255, &str); proto_tree_add_string(tree, hf_mscldap_clientsitename, tvb, old_offset, offset-old_offset, str); /* get the version number from the end of the buffer, as the diff --git a/epan/dissectors/asn1/ldap/packet-ldap-template.h b/epan/dissectors/asn1/ldap/packet-ldap-template.h index 9ae08f80fc..0116c0cba1 100644 --- a/epan/dissectors/asn1/ldap/packet-ldap-template.h +++ b/epan/dissectors/asn1/ldap/packet-ldap-template.h @@ -89,7 +89,7 @@ typedef struct ldap_call_response { } ldap_call_response_t; WS_DLL_PUBLIC -int dissect_mscldap_string(tvbuff_t *tvb, int offset, char *str, int max_len, gboolean prepend_dot _U_); +int dissect_mscldap_string(tvbuff_t *tvb, int offset, int max_len, char **str); WS_DLL_PUBLIC const value_string ldap_procedure_names[]; diff --git a/epan/dissectors/packet-dcerpc-netlogon.c b/epan/dissectors/packet-dcerpc-netlogon.c index 4fbeffaba1..8eaa440dc6 100644 --- a/epan/dissectors/packet-dcerpc-netlogon.c +++ b/epan/dissectors/packet-dcerpc-netlogon.c @@ -7667,27 +7667,27 @@ static int dissect_secchan_nl_auth_message(tvbuff_t *tvb, int offset, /* DNS domain name */ if (messageflags&0x00000004) { int old_offset=offset; - char str[256]; + char *str; - offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE); + offset=dissect_mscldap_string(tvb, offset, 255, &str); proto_tree_add_string(subtree, hf_netlogon_secchan_nl_dns_domain, tvb, old_offset, offset-old_offset, str); } /* DNS host name */ if (messageflags&0x00000008) { int old_offset=offset; - char str[256]; + char *str; - offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE); + offset=dissect_mscldap_string(tvb, offset, 255, &str); proto_tree_add_string(subtree, hf_netlogon_secchan_nl_dns_host, tvb, old_offset, offset-old_offset, str); } /* NetBios host name (UTF8) */ if (messageflags&0x00000010) { int old_offset=offset; - char str[256]; + char *str; - offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE); + offset=dissect_mscldap_string(tvb, offset, 255, &str); proto_tree_add_string(subtree, hf_netlogon_secchan_nl_nb_host_utf8, tvb, old_offset, offset-old_offset, str); } diff --git a/epan/dissectors/packet-ldap.c b/epan/dissectors/packet-ldap.c index 88bb3f09ba..76aede8ad0 100644 --- a/epan/dissectors/packet-ldap.c +++ b/epan/dissectors/packet-ldap.c @@ -90,6 +90,7 @@ #include #include #include +#include #include #include "packet-frame.h" #include "packet-tcp.h" @@ -336,7 +337,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 "./asn1/ldap/packet-ldap-template.c" +#line 187 "./asn1/ldap/packet-ldap-template.c" /* Initialize the subtree pointers */ static gint ett_ldap = -1; @@ -408,7 +409,7 @@ static gint ett_ldap_PasswordPolicyResponseValue = -1; static gint ett_ldap_T_warning = -1; /*--- End of included file: packet-ldap-ett.c ---*/ -#line 198 "./asn1/ldap/packet-ldap-template.c" +#line 199 "./asn1/ldap/packet-ldap-template.c" static expert_field ei_ldap_exceeded_filter_length = EI_INIT; static expert_field ei_ldap_too_many_filter_elements = EI_INIT; @@ -3816,7 +3817,7 @@ static int dissect_PasswordPolicyResponseValue_PDU(tvbuff_t *tvb _U_, packet_inf /*--- End of included file: packet-ldap-fn.c ---*/ -#line 910 "./asn1/ldap/packet-ldap-template.c" +#line 911 "./asn1/ldap/packet-ldap-template.c" static int dissect_LDAPMessage_PDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, ldap_conv_info_t *ldap_info) { int offset = 0; @@ -4222,11 +4223,7 @@ static void } } -/* - * 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_) +int dissect_mscldap_string(tvbuff_t *tvb, int offset, int max_len, char **str) { int compr_len; const gchar *name; @@ -4234,7 +4231,7 @@ int dissect_mscldap_string(tvbuff_t *tvb, int offset, char *str, int max_len, gb /* The name data MUST start at offset 0 of the tvb */ compr_len = get_dns_name(tvb, offset, max_len, 0, &name, &name_len); - (void) g_strlcpy(str, name, max_len); + *str = get_utf_8_string(wmem_packet_scope(), name, name_len); return offset + compr_len; } @@ -4333,7 +4330,7 @@ static int dissect_mscldap_netlogon_flags(proto_tree *parent_tree, tvbuff_t *tvb static int dissect_NetLogon_PDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_) { int old_offset, offset=0; - char str[256]; + char *str; guint16 itype; guint16 len; guint32 version; @@ -4397,17 +4394,17 @@ static int dissect_NetLogon_PDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tre /* Forest */ old_offset=offset; - offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE); + offset=dissect_mscldap_string(tvb, offset, 255, &str); proto_tree_add_string(tree, hf_mscldap_forest, tvb, old_offset, offset-old_offset, str); /* Domain */ old_offset=offset; - offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE); + offset=dissect_mscldap_string(tvb, offset, 255, &str); proto_tree_add_string(tree, hf_mscldap_domain, tvb, old_offset, offset-old_offset, str); /* Hostname */ old_offset=offset; - offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE); + offset=dissect_mscldap_string(tvb, offset, 255, &str); proto_tree_add_string(tree, hf_mscldap_hostname, tvb, old_offset, offset-old_offset, str); /* DC IP Address */ @@ -4433,42 +4430,42 @@ static int dissect_NetLogon_PDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tre /* Forest */ old_offset=offset; - offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE); + offset=dissect_mscldap_string(tvb, offset, 255, &str); proto_tree_add_string(tree, hf_mscldap_forest, tvb, old_offset, offset-old_offset, str); /* Domain */ old_offset=offset; - offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE); + offset=dissect_mscldap_string(tvb, offset, 255, &str); proto_tree_add_string(tree, hf_mscldap_domain, tvb, old_offset, offset-old_offset, str); /* Hostname */ old_offset=offset; - offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE); + offset=dissect_mscldap_string(tvb, offset, 255, &str); proto_tree_add_string(tree, hf_mscldap_hostname, tvb, old_offset, offset-old_offset, str); /* NetBIOS Domain */ old_offset=offset; - offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE); + offset=dissect_mscldap_string(tvb, offset, 255, &str); proto_tree_add_string(tree, hf_mscldap_nb_domain, tvb, old_offset, offset-old_offset, str); /* NetBIOS Hostname */ old_offset=offset; - offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE); + offset=dissect_mscldap_string(tvb, offset, 255, &str); proto_tree_add_string(tree, hf_mscldap_nb_hostname, tvb, old_offset, offset-old_offset, str); /* User */ old_offset=offset; - offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE); + offset=dissect_mscldap_string(tvb, offset, 255, &str); proto_tree_add_string(tree, hf_mscldap_username, tvb, old_offset, offset-old_offset, str); /* Server Site */ old_offset=offset; - offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE); + offset=dissect_mscldap_string(tvb, offset, 255, &str); proto_tree_add_string(tree, hf_mscldap_sitename, tvb, old_offset, offset-old_offset, str); /* Client Site */ old_offset=offset; - offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE); + offset=dissect_mscldap_string(tvb, offset, 255, &str); proto_tree_add_string(tree, hf_mscldap_clientsitename, tvb, old_offset, offset-old_offset, str); /* get the version number from the end of the buffer, as the @@ -5654,7 +5651,7 @@ void proto_register_ldap(void) { NULL, HFILL }}, /*--- End of included file: packet-ldap-hfarr.c ---*/ -#line 2179 "./asn1/ldap/packet-ldap-template.c" +#line 2176 "./asn1/ldap/packet-ldap-template.c" }; /* List of subtrees */ @@ -5728,7 +5725,7 @@ void proto_register_ldap(void) { &ett_ldap_T_warning, /*--- End of included file: packet-ldap-ettarr.c ---*/ -#line 2193 "./asn1/ldap/packet-ldap-template.c" +#line 2190 "./asn1/ldap/packet-ldap-template.c" }; /* UAT for header fields */ static uat_field_t custom_attribute_types_uat_fields[] = { @@ -5937,7 +5934,7 @@ proto_reg_handoff_ldap(void) /*--- End of included file: packet-ldap-dis-tab.c ---*/ -#line 2385 "./asn1/ldap/packet-ldap-template.c" +#line 2382 "./asn1/ldap/packet-ldap-template.c" dissector_add_uint_range_with_preference("tcp.port", TCP_PORT_RANGE_LDAP, ldap_handle); diff --git a/epan/dissectors/packet-ldap.h b/epan/dissectors/packet-ldap.h index 70936a74c4..1c9efa5171 100644 --- a/epan/dissectors/packet-ldap.h +++ b/epan/dissectors/packet-ldap.h @@ -97,7 +97,7 @@ typedef struct ldap_call_response { } ldap_call_response_t; WS_DLL_PUBLIC -int dissect_mscldap_string(tvbuff_t *tvb, int offset, char *str, int max_len, gboolean prepend_dot _U_); +int dissect_mscldap_string(tvbuff_t *tvb, int offset, int max_len, char **str); WS_DLL_PUBLIC const value_string ldap_procedure_names[];