wireshark/asn1/ldap/ldap.cnf

677 lines
19 KiB
Plaintext
Raw Normal View History

# ldap.cnf
# LDAP conformation file
# Copyright 2005 Anders Broman
# $Id$
#.PDU
LDAPMessage
#.TYPE_RENAME
BindResponse/resultCode BindResponse_resultCode
ExtendedResponse/resultCode ExtendedResponse_resultCode
ModifyRequest/modification ModifyRequest_modification
#.FIELD_RENAME
BindResponse/resultCode bindResponse_resultCode
ExtendedResponse/resultCode extendedResponse_resultCode
SearchRequest/attributes searchRequest_attributes
SearchResultEntry/attributes searchResultEntry_attributes
ModifyRequest/modification modifyRequest_modification
SubstringFilter/substrings substringFilter_substrings
#.TYPE_ATTR
LDAPString TYPE = FT_STRING DISPLAY = BASE_NONE STRINGS = NULL
LDAPURL TYPE = FT_STRING DISPLAY = BASE_NONE STRINGS = NULL
LDAPOID TYPE = FT_STRING DISPLAY = BASE_NONE STRINGS = NULL
Mechanism TYPE = FT_STRING DISPLAY = BASE_NONE STRINGS = NULL
AssertionValue TYPE = FT_STRING DISPLAY = BASE_NONE STRINGS = NULL
#.REGISTER
SearchControlValue B "1.2.840.113556.1.4.319" "pagedResultsControl"
SortKeyList B "1.2.840.113556.1.4.473" "sortKeyList"
SortResult B "1.2.840.113556.1.4.474" "sortResult"
ReplControlValue B "1.2.840.113556.1.4.841" "replControlValue"
#.FN_FTR LDAPURL
PROTO_ITEM_SET_URL(get_ber_last_created_item());
#.FN_PARS LDAPOID VAL_PTR = &parameter_tvb
#.FN_HDR LDAPOID
tvbuff_t *parameter_tvb;
const gchar *name;
proto_item *item = NULL;
#.FN_FTR LDAPOID
object_identifier_id = NULL;
if (!parameter_tvb)
return offset;
object_identifier_id = tvb_get_string(parameter_tvb, 0, tvb_length_remaining(parameter_tvb,0));
name = get_oid_str_name(object_identifier_id);
if(name){
item = get_ber_last_created_item();
proto_item_append_text(item, " (%s)", name);
proto_item_append_text(tree, " %s", name);
}
#.FN_PARS MessageID VAL_PTR = &MessageID
#.FN_BODY MessageID
%(DEFAULT_BODY)s
ldm_tree = tree;
#.FN_PARS ProtocolOp VAL_PTR = &ProtocolOp
#.FN_HDR ProtocolOp
ldap_call_response_t *lcrp;
ldap_conv_info_t *ldap_info = (ldap_conv_info_t *)actx->pinfo->private_data;
do_protocolop = TRUE;
#.FN_FTR ProtocolOp
lcrp=ldap_match_call_response(tvb, actx->pinfo, tree, MessageID, ProtocolOp);
if(lcrp){
tap_queue_packet(ldap_tap, actx->pinfo, lcrp);
}
/* XXX: the count will not work if the results span multiple TCP packets */
if(ldap_info && tree) { /* only count once - on tree pass */
switch(ProtocolOp) {
case LDAP_RES_SEARCH_ENTRY:
ldap_info->num_results++;
proto_item_append_text(tree, " [%d result%s]",
ldap_info->num_results, ldap_info->num_results == 1 ? "" : "s");
break;
case LDAP_RES_SEARCH_RESULT:
if (check_col(actx->pinfo->cinfo, COL_INFO))
col_append_fstr(actx->pinfo->cinfo, COL_INFO, " [%d result%s]",
ldap_info->num_results, ldap_info->num_results == 1 ? "" : "s");
proto_item_append_text(tree, " [%d result%s]",
ldap_info->num_results, ldap_info->num_results == 1 ? "" : "s");
ldap_info->num_results = 0;
break;
default:
break;
}
}
#.FN_BODY Simple
ldap_conv_info_t *ldap_info;
%(DEFAULT_BODY)s
ldap_info = actx->pinfo->private_data;
ldap_info->auth_type = LDAP_AUTH_SIMPLE;
actx->pinfo->private_data = ldap_info;
#.FN_PARS Mechanism VAL_PTR = &parameter_tvb
#.FN_BODY Mechanism
ldap_conv_info_t *ldap_info;
tvbuff_t *parameter_tvb;
char *mechanism = NULL;
%(DEFAULT_BODY)s
ldap_info = actx->pinfo->private_data;
ldap_info->auth_type = LDAP_AUTH_SASL;
if (!parameter_tvb)
return offset;
/*
* We need to remember the authentication type and mechanism for this
* conversation.
*
* XXX - actually, we might need to remember more than one
* type and mechanism, if you can unbind and rebind with a
* different type and/or mechanism.
*/
mechanism = tvb_get_string(parameter_tvb, 0, tvb_length_remaining(parameter_tvb,0));
ldap_info->first_auth_frame = 0; /* not known until we see the bind reply */
/*
* If the mechanism in this request is an empty string (which is
* returned as a null pointer), use the saved mechanism instead.
* Otherwise, if the saved mechanism is an empty string (null),
* save this mechanism.
*/
if (mechanism == NULL)
mechanism = ldap_info->auth_mech;
else {
if (ldap_info->auth_mech == NULL) {
g_free(ldap_info->auth_mech);
}
ldap_info->auth_mech = mechanism;
}
actx->pinfo->private_data = ldap_info;
#.FN_PARS Credentials VAL_PTR = &parameter_tvb
#.FN_BODY Credentials
tvbuff_t *parameter_tvb;
ldap_conv_info_t *ldap_info;
%(DEFAULT_BODY)s
if (!parameter_tvb)
return offset;
ldap_info = actx->pinfo->private_data;
if (ldap_info->auth_mech != NULL && strcmp(ldap_info->auth_mech, "GSS-SPNEGO") == 0) {
/*
* This is a GSS-API token ancapsulated within GSS-SPNEGO.
*/
if (parameter_tvb && (tvb_length(parameter_tvb) > 0))
call_dissector(spnego_handle, parameter_tvb, actx->pinfo, tree);
} else if (ldap_info->auth_mech != NULL && strcmp(ldap_info->auth_mech, "GSSAPI") == 0) {
/*
* This is a raw GSS-API token.
*/
if (parameter_tvb && (tvb_length(parameter_tvb) > 0))
call_dissector(gssapi_handle, parameter_tvb, actx->pinfo, tree);
}
actx->pinfo->private_data = ldap_info;
#.FN_PARS ServerSaslCreds VAL_PTR = &parameter_tvb
#.FN_BODY ServerSaslCreds
tvbuff_t *parameter_tvb;
ldap_conv_info_t *ldap_info;
%(DEFAULT_BODY)s
if (!parameter_tvb)
return offset;
ldap_info = actx->pinfo->private_data;
switch (ldap_info->auth_type) {
/* For Kerberos V4, dissect it as a ticket. */
/* XXX - what about LDAP_AUTH_SIMPLE? */
case LDAP_AUTH_SASL:
/*
* All frames after this are assumed to use a security layer.
*
* XXX - won't work if there's another reply, with the security
* layer, starting in the same TCP segment that ends this
* reply, but as LDAP is a request/response protocol, and
* as the client probably can't start using authentication until
* it gets the bind reply and the server won't send a reply until
* it gets a request, that probably won't happen.
*
* XXX - that assumption is invalid; it's not clear where the
* hell you find out whether there's any security layer. In
* one capture, we have two GSS-SPNEGO negotiations, both of
* which select MS KRB5, and the only differences in the tokens
* is in the RC4-HMAC ciphertext. The various
* draft-ietf--cat-sasl-gssapi-NN.txt drafts seem to imply
* that the RFC 2222 spoo with the bitmask and maximum
* output message size stuff is done - but where does that
* stuff show up? Is it in the ciphertext, which means it's
* presumably encrypted?
*
* Grrr. We have to do a gross heuristic, checking whether the
* putative LDAP message begins with 0x00 or not, making the
* assumption that we won't have more than 2^24 bytes of
* encapsulated stuff.
*/
ldap_info->first_auth_frame = actx->pinfo->fd->num + 1;
if (ldap_info->auth_mech != NULL &&
strcmp(ldap_info->auth_mech, "GSS-SPNEGO") == 0) {
/*
* This is a GSS-API token.
*/
if(parameter_tvb && (tvb_length(parameter_tvb) > 0))
call_dissector(spnego_handle, parameter_tvb, actx->pinfo, tree);
} else if (ldap_info->auth_mech != NULL &&
strcmp(ldap_info->auth_mech, "GSSAPI") == 0) {
/*
* This is a GSS-API token.
*/
if(parameter_tvb && (tvb_length(parameter_tvb) > 0))
call_dissector(gssapi_handle, parameter_tvb, actx->pinfo, tree);
}
break;
}
actx->pinfo->private_data = ldap_info;
#.FN_PARS LDAPString VAL_PTR = &parameter_tvb
#.FN_BODY LDAPString
tvbuff_t *parameter_tvb = NULL;
char *ldapstring;
gchar *sc = NULL; /* semi-colon pointer */
%(DEFAULT_BODY)s
if (parameter_tvb || (hf_index == hf_ldap_baseObject)) {
ldap_do_protocolop(actx->pinfo);
if(parameter_tvb)
ldapstring = tvb_get_ephemeral_string(parameter_tvb, 0, tvb_length_remaining(parameter_tvb, 0));
else
ldapstring = "<ROOT>";
if(hf_index == hf_ldap_baseObject) {
/* this is search - put it on the scanline */
if(check_col(actx->pinfo->cinfo, COL_INFO))
col_append_fstr(actx->pinfo->cinfo, COL_INFO, "\"%%s\" ", ldapstring);
if(ldm_tree)
proto_item_append_text(ldm_tree, " \"%%s\"", ldapstring);
if(!parameter_tvb) {
proto_item_append_text(ber_last_created_item, " (%%s)", ldapstring);
}
} else if ((hf_index == hf_ldap_errorMessage) && result) { /* only show message if not success */
if(check_col(actx->pinfo->cinfo, COL_INFO))
col_append_fstr(actx->pinfo->cinfo, COL_INFO, "(%%s) ", ldapstring);
if(ldm_tree)
proto_item_append_text(ldm_tree, " (%%s)", ldapstring);
} else if (hf_index == hf_ldap_objectName) {
if(check_col(actx->pinfo->cinfo, COL_INFO))
col_append_fstr(actx->pinfo->cinfo, COL_INFO, "\"%%s\" ", ldapstring);
if(ldm_tree)
proto_item_append_text(ldm_tree, " \"%%s\"", ldapstring);
} else if (hf_index == hf_ldap_attributeDesc){
/* remember the attribute description */
attributedesc_string=ldapstring;
} else if (hf_index == hf_ldap_initial){
/* remember the substring item */
substring_item_init=ldapstring;
} else if (hf_index == hf_ldap_any){
/* remember the substring item */
substring_item_any=ldapstring;
} else if (hf_index == hf_ldap_final){
/* remember the substring item */
substring_item_final=ldapstring;
} else if (hf_index == hf_ldap_matchingRule){
/* remember the matching rule */
matching_rule_string=ldapstring;
} else if (hf_index == hf_ldap_present){
/* remember the present name */
Filter_string=ldapstring;
} else if (hf_index == hf_ldap_type) {
/* remember attribute type name */
attr_type = ep_strdup(ldapstring);
/* append it to the parent entry */
proto_item_append_text(tree, " %%s", attr_type);
/* remove the ";binary" component if present */
if((sc = strchr(attr_type, ';')) != NULL) {
if(!strcmp(sc, ";binary")) {
*sc = '\0'; /* terminate the string */
is_binary_attr_type = TRUE;
}
} else {
is_binary_attr_type = FALSE;
}
}
}
#.FN_PARS T_scope VAL_PTR = &scope
#.FN_BODY T_scope
gint scope;
const gchar *valstr;
%(DEFAULT_BODY)s
ldap_do_protocolop(actx->pinfo);
valstr = val_to_str(scope, ldap_T_scope_vals, "Unknown scope(%%u)");
if (check_col(actx->pinfo->cinfo, COL_INFO))
col_append_fstr(actx->pinfo->cinfo, COL_INFO, "%%s ", valstr);
if(ldm_tree)
proto_item_append_text(ldm_tree, " %%s", valstr);
#.FN_PARS T_resultCode VAL_PTR = &result
#.FN_BODY T_resultCode
const gchar *valstr;
%(DEFAULT_BODY)s
ldap_do_protocolop(actx->pinfo);
if(result) {
valstr = val_to_str(result, ldap_T_resultCode_vals, "Unknown result(%%u)");
if (check_col(actx->pinfo->cinfo, COL_INFO))
col_append_fstr(actx->pinfo->cinfo, COL_INFO, "%%s ", valstr);
if(ldm_tree)
proto_item_append_text(ldm_tree, " %%s", valstr);
}
#.FN_PARS BindResponse_resultCode VAL_PTR = &result
#.FN_BODY BindResponse_resultCode
const gchar *valstr;
%(DEFAULT_BODY)s
ldap_do_protocolop(actx->pinfo);
if(result) {
valstr = val_to_str(result, ldap_BindResponse_resultCode_vals, "Unknown result(%%u)");
if (check_col(actx->pinfo->cinfo, COL_INFO))
col_append_fstr(actx->pinfo->cinfo, COL_INFO, "%%s ", valstr);
if(ldm_tree)
proto_item_append_text(ldm_tree, " %%s", valstr);
}
#.FN_BODY AttributeValue
tvbuff_t *next_tvb;
gchar *string;
guint32 i, len;
proto_item *pi;
int old_offset = offset;
/* extract the value of the octetstring */
offset = dissect_ber_octet_string(FALSE, actx->pinfo, NULL, tvb, offset, hf_index, &next_tvb);
/* if we have an attribute type that isn't binary see if there is a better dissector */
if(!attr_type || !dissector_try_string(ldap_name_dissector_table, attr_type, next_tvb, actx->pinfo, tree)) {
offset = old_offset;
/* do the default thing */
%(DEFAULT_BODY)s
}
len = tvb_length_remaining(next_tvb, 0);
for(i = 0; i < len; i++)
if(!g_ascii_isprint(tvb_get_guint8(next_tvb, i)))
break;
if(i == len) {
string = tvb_get_string(next_tvb, 0, tvb_length_remaining(next_tvb, 0));
pi = get_ber_last_created_item();
proto_item_set_text(pi, "%%s", string);
}
#.FN_PARS AuthenticationChoice VAL_PTR = &branch
#.FN_BODY AuthenticationChoice
gint branch = -1;
gint auth = -1;
const gchar *valstr;
%(DEFAULT_BODY)s
ldap_do_protocolop(actx->pinfo);
if((branch > -1) && (branch < (gint)(sizeof AuthenticationChoice_choice/sizeof AuthenticationChoice_choice[0])))
auth = AuthenticationChoice_choice[branch].value;
valstr = val_to_str(auth, ldap_AuthenticationChoice_vals, "Unknown auth(%%u)");
/* If auth is NTLM (10 or 11) don't add to column as the NTLM dissection will do this */
if (check_col(actx->pinfo->cinfo, COL_INFO) && (auth != 10) && (auth != 11))
col_append_fstr(actx->pinfo->cinfo, COL_INFO, "%%s ", valstr);
if(ldm_tree)
proto_item_append_text(ldm_tree, " %%s", valstr);
#.FN_BODY UnbindRequest
implicit_tag = TRUE; /* correct problem with asn2wrs */
%(DEFAULT_BODY)s
ldap_do_protocolop(actx->pinfo);
#.FN_HDR SearchRequest/filter
Filter_string=NULL;
#.FN_FTR SearchRequest/filter
Filter_string=NULL;
and_filter_string=NULL;
#.FN_FTR Filter/equalityMatch
Filter_string=ep_strdup_printf("(%s=%s)",attributedesc_string,ldapvalue_string);
#.FN_FTR Filter/greaterOrEqual
Filter_string=ep_strdup_printf("(%s>=%s)",attributedesc_string,ldapvalue_string);
#.FN_FTR Filter/lessOrEqual
Filter_string=ep_strdup_printf("(%s<=%s)",attributedesc_string,ldapvalue_string);
#.FN_FTR Filter/approxMatch
Filter_string=ep_strdup_printf("(%s~=%s)",attributedesc_string,ldapvalue_string);
#.FN_FTR Filter/and/_item
if(and_filter_string){
and_filter_string=ep_strdup_printf("(&%s%s)",and_filter_string,Filter_string);
} else {
and_filter_string=Filter_string;
}
#.FN_BODY Filter/and
const ber_sequence_t and_set_of[1] = { { BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_and_item },
};
proto_tree *tr=NULL;
proto_item *it=NULL;
char *old_and_filter_string=and_filter_string;
and_filter_string=NULL;
if(tree){
it=proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), "and: ");
tr=proto_item_add_subtree(it, ett_ldap_T_and);
}
offset = dissect_ber_set_of(implicit_tag, actx, tr, tvb, offset,
and_set_of, -1, ett_ldap_T_and);
proto_item_append_text(it, "%%s", and_filter_string);
Filter_string=ep_strdup_printf("%%s",and_filter_string);
and_filter_string=old_and_filter_string;
#.FN_FTR Filter/or/_item
if(or_filter_string){
or_filter_string=ep_strdup_printf("(|%s%s)",or_filter_string,Filter_string);
} else {
or_filter_string=Filter_string;
}
#.FN_BODY Filter/or
const ber_sequence_t or_set_of[1] = { { BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_or_item },
};
proto_tree *tr=NULL;
proto_item *it=NULL;
char *old_or_filter_string=or_filter_string;
or_filter_string=NULL;
if(tree){
it=proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), "or: ");
tr=proto_item_add_subtree(it, ett_ldap_T_or);
}
offset = dissect_ber_set_of(implicit_tag, actx, tr, tvb, offset,
or_set_of, -1, ett_ldap_T_or);
proto_item_append_text(it, "%%s", or_filter_string);
Filter_string=ep_strdup_printf("%%s",or_filter_string);
or_filter_string=old_or_filter_string;
#.FN_FTR Filter/present
Filter_string=ep_strdup_printf("(%s=*)",Filter_string);
#.FN_FTR Filter/not
Filter_string=ep_strdup_printf("(!%s)",Filter_string);
#.FN_BODY BOOLEAN
gboolean val;
offset = dissect_ber_boolean_value(implicit_tag, actx->pinfo, tree, tvb, offset, hf_index, &val);
if (hf_index == hf_ldap_dnAttributes) {
matching_rule_dnattr = val;
}
#.FN_HDR Filter/extensibleMatch
attr_type=NULL;
matching_rule_string=NULL;
ldapvalue_string=NULL;
matching_rule_dnattr=FALSE;
#.FN_FTR Filter/extensibleMatch
Filter_string=ep_strdup_printf("(%s:%s%s%s=%s)",
(attr_type?attr_type:""),
(matching_rule_dnattr?"dn:":""),
(matching_rule_string?matching_rule_string:""),
(matching_rule_string?":":""),
ldapvalue_string);
#.FN_FTR SubstringFilter/substrings/_item
if (substring_item_final) {
substring_value=ep_strdup_printf("%s%s",
(substring_value?substring_value:"*"),
substring_item_final);
} else if (substring_item_any) {
substring_value=ep_strdup_printf("%s%s*",
(substring_value?substring_value:"*"),
substring_item_any);
} else if (substring_item_init) {
substring_value=ep_strdup_printf("%s*",
substring_item_init);
}
#.FN_BODY SubstringFilter
proto_tree *tr=NULL;
proto_item *it=NULL;
char *old_substring_value=substring_value;
substring_value=NULL;
substring_item_init=NULL;
substring_item_any=NULL;
substring_item_final=NULL;
if(tree){
it=proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), "substring: ");
tr=proto_item_add_subtree(it, ett_ldap_SubstringFilter);
}
offset = dissect_ber_sequence(implicit_tag, actx, tr, tvb, offset,
SubstringFilter_sequence, hf_index,
ett_ldap_SubstringFilter);
Filter_string=ep_strdup_printf("(%%s=%%s)",attr_type,substring_value);
proto_item_append_text(it, "%%s", Filter_string);
substring_value=old_substring_value;
#.FN_BODY Filter
proto_tree *tr=NULL;
proto_item *it=NULL;
if(tree){
it=proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), "Filter: ");
tr=proto_item_add_subtree(it, ett_ldap_Filter);
}
offset = dissect_ber_choice(actx, tr, tvb, offset,
Filter_choice, -1, ett_ldap_Filter,
NULL);
proto_item_append_text(it, "%%s", Filter_string);
#.FN_BODY AuthenticationChoice/ntlmsspNegotiate
/* make sure the protocol op comes first */
ldap_do_protocolop(actx->pinfo);
call_dissector(ntlmssp_handle, tvb, actx->pinfo, tree);
offset+=tvb_length_remaining(tvb, offset);
#.FN_BODY AuthenticationChoice/ntlmsspAuth
/* make sure the protocol op comes first */
ldap_do_protocolop(actx->pinfo);
call_dissector(ntlmssp_handle, tvb, actx->pinfo, tree);
offset+=tvb_length_remaining(tvb, offset);
#.FN_BODY BindResponse/matchedDN
tvbuff_t *new_tvb=NULL;
offset = dissect_ber_octet_string(FALSE, actx->pinfo, tree, tvb, offset, hf_ldap_matchedDN, &new_tvb);
if( new_tvb
&& (tvb_length(new_tvb)>=7)
&& (!tvb_memeql(new_tvb, 0, "NTLMSSP", 7))){
/* make sure the protocol op comes first */
ldap_do_protocolop(actx->pinfo);
call_dissector(ntlmssp_handle, new_tvb, actx->pinfo, tree);
}
return offset;
#.FN_BODY Control/controlValue
gint8 class;
gboolean pc, ind;
gint32 tag;
guint32 len;
if((object_identifier_id != NULL) && oid_has_dissector(object_identifier_id)) {
/* remove the OCTET STRING encoding */
offset=dissect_ber_identifier(actx->pinfo, NULL, tvb, offset, &class, &pc, &tag);
offset=dissect_ber_length(actx->pinfo, NULL, tvb, offset, &len, &ind);
call_ber_oid_callback(object_identifier_id, tvb, offset, actx->pinfo, tree);
offset += len;
} else {
%(DEFAULT_BODY)s
}
#.NO_EMIT
AttributeType
Attribute
AssertionValue