1999-12-09 04:06:54 +00:00
|
|
|
/* packet-ldap.c
|
|
|
|
* Routines for ldap packet dissection
|
|
|
|
*
|
2002-05-06 02:12:36 +00:00
|
|
|
* $Id: packet-ldap.c,v 1.42 2002/05/06 02:12:36 guy Exp $
|
1999-12-09 04:06:54 +00:00
|
|
|
*
|
|
|
|
* Ethereal - Network traffic analyzer
|
2001-12-03 04:00:26 +00:00
|
|
|
* By Gerald Combs <gerald@ethereal.com>
|
1999-12-09 04:06:54 +00:00
|
|
|
* Copyright 1998 Gerald Combs
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
2000-03-28 07:12:36 +00:00
|
|
|
/*
|
|
|
|
* This is not a complete implementation. It doesn't handle the full version 3, more specifically,
|
|
|
|
* it handles only the commands of version 2, but any additional characteristics of the ver3 command are supported.
|
2000-05-12 08:04:29 +00:00
|
|
|
* It's also missing extensible search filters.
|
2000-03-28 07:12:36 +00:00
|
|
|
*
|
|
|
|
* There should probably be alot more error checking, I simply assume that if we have a full packet, it will be a complete
|
|
|
|
* and correct packet.
|
|
|
|
*
|
|
|
|
* AFAIK, it will handle all messages used by the OpenLDAP 1.2.9 server and libraries which was my goal. I do plan to add
|
|
|
|
* the remaining commands as time permits but this is not a priority to me. Send me an email if you need it and I'll see what
|
|
|
|
* I can do.
|
|
|
|
*
|
|
|
|
* Doug Nazar
|
|
|
|
* nazard@dragoninc.on.ca
|
|
|
|
*/
|
|
|
|
|
1999-12-09 04:06:54 +00:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include "config.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
#ifdef HAVE_SYS_TYPES_H
|
|
|
|
# include <sys/types.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_NETINET_IN_H
|
|
|
|
# include <netinet/in.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
#include <glib.h>
|
2000-04-06 03:59:28 +00:00
|
|
|
|
|
|
|
#ifdef NEED_SNPRINTF_H
|
|
|
|
# include "snprintf.h"
|
|
|
|
#endif
|
|
|
|
|
2002-01-21 07:37:49 +00:00
|
|
|
#include <epan/packet.h>
|
1999-12-09 04:06:54 +00:00
|
|
|
|
2000-03-28 07:12:36 +00:00
|
|
|
#include "packet-ldap.h"
|
|
|
|
#include "asn1.h"
|
2002-01-14 02:50:28 +00:00
|
|
|
#include "prefs.h"
|
2000-03-28 07:12:36 +00:00
|
|
|
|
1999-12-09 04:06:54 +00:00
|
|
|
static int proto_ldap = -1;
|
2000-03-28 07:12:36 +00:00
|
|
|
static int hf_ldap_length = -1;
|
|
|
|
static int hf_ldap_message_id = -1;
|
|
|
|
static int hf_ldap_message_type = -1;
|
|
|
|
static int hf_ldap_message_length = -1;
|
|
|
|
|
|
|
|
static int hf_ldap_message_result = -1;
|
|
|
|
static int hf_ldap_message_result_matcheddn = -1;
|
|
|
|
static int hf_ldap_message_result_errormsg = -1;
|
|
|
|
static int hf_ldap_message_result_referral = -1;
|
|
|
|
|
|
|
|
static int hf_ldap_message_bind_version = -1;
|
|
|
|
static int hf_ldap_message_bind_dn = -1;
|
|
|
|
static int hf_ldap_message_bind_auth = -1;
|
|
|
|
static int hf_ldap_message_bind_auth_password = -1;
|
|
|
|
|
|
|
|
static int hf_ldap_message_search_base = -1;
|
|
|
|
static int hf_ldap_message_search_scope = -1;
|
|
|
|
static int hf_ldap_message_search_deref = -1;
|
|
|
|
static int hf_ldap_message_search_sizeLimit = -1;
|
|
|
|
static int hf_ldap_message_search_timeLimit = -1;
|
|
|
|
static int hf_ldap_message_search_typesOnly = -1;
|
|
|
|
static int hf_ldap_message_search_filter = -1;
|
|
|
|
|
|
|
|
static int hf_ldap_message_dn = -1;
|
|
|
|
static int hf_ldap_message_attribute = -1;
|
|
|
|
static int hf_ldap_message_value = -1;
|
|
|
|
|
|
|
|
static int hf_ldap_message_modrdn_name = -1;
|
|
|
|
static int hf_ldap_message_modrdn_delete = -1;
|
|
|
|
static int hf_ldap_message_modrdn_superior = -1;
|
|
|
|
|
|
|
|
static int hf_ldap_message_compare = -1;
|
|
|
|
|
|
|
|
static int hf_ldap_message_modify_add = -1;
|
|
|
|
static int hf_ldap_message_modify_replace = -1;
|
|
|
|
static int hf_ldap_message_modify_delete = -1;
|
|
|
|
|
|
|
|
static int hf_ldap_message_abandon_msgid = -1;
|
1999-12-09 04:06:54 +00:00
|
|
|
|
|
|
|
static gint ett_ldap = -1;
|
2000-03-28 07:12:36 +00:00
|
|
|
static gint ett_ldap_message = -1;
|
|
|
|
static gint ett_ldap_referrals = -1;
|
|
|
|
static gint ett_ldap_attribute = -1;
|
|
|
|
|
2002-01-14 02:50:28 +00:00
|
|
|
/* desegmentation of LDAP */
|
|
|
|
static gboolean ldap_desegment = TRUE;
|
|
|
|
|
2000-04-08 07:07:42 +00:00
|
|
|
#define TCP_PORT_LDAP 389
|
|
|
|
|
2000-03-28 07:12:36 +00:00
|
|
|
static value_string msgTypes [] = {
|
|
|
|
{LDAP_REQ_BIND, "Bind Request"},
|
|
|
|
{LDAP_REQ_UNBIND, "Unbind Request"},
|
|
|
|
{LDAP_REQ_SEARCH, "Search Request"},
|
|
|
|
{LDAP_REQ_MODIFY, "Modify Request"},
|
|
|
|
{LDAP_REQ_ADD, "Add Request"},
|
|
|
|
{LDAP_REQ_DELETE, "Delete Request"},
|
|
|
|
{LDAP_REQ_MODRDN, "Modify RDN Request"},
|
|
|
|
{LDAP_REQ_COMPARE, "Compare Request"},
|
|
|
|
{LDAP_REQ_ABANDON, "Abandon Request"},
|
2000-03-29 09:25:21 +00:00
|
|
|
{LDAP_REQ_EXTENDED, "Extended Request"},
|
2000-03-28 07:12:36 +00:00
|
|
|
|
|
|
|
{LDAP_RES_BIND, "Bind Result"},
|
|
|
|
{LDAP_RES_SEARCH_ENTRY, "Search Entry"},
|
|
|
|
{LDAP_RES_SEARCH_RESULT, "Search Result"},
|
2000-03-29 09:25:21 +00:00
|
|
|
{LDAP_RES_SEARCH_REF, "Search Result Reference"},
|
2000-03-28 07:12:36 +00:00
|
|
|
{LDAP_RES_MODIFY, "Modify Result"},
|
|
|
|
{LDAP_RES_ADD, "Add Result"},
|
|
|
|
{LDAP_RES_DELETE, "Delete Result"},
|
|
|
|
{LDAP_RES_MODRDN, "Modify RDN Result"},
|
2000-03-29 09:25:21 +00:00
|
|
|
{LDAP_RES_COMPARE, "Compare Result"},
|
|
|
|
{LDAP_REQ_EXTENDED, "Extended Response"},
|
2001-01-03 16:41:08 +00:00
|
|
|
{0, NULL},
|
2000-03-28 07:12:36 +00:00
|
|
|
};
|
1999-12-09 04:06:54 +00:00
|
|
|
|
2000-03-28 07:12:36 +00:00
|
|
|
static int read_length(ASN1_SCK *a, proto_tree *tree, int hf_id, guint *len)
|
1999-12-09 04:06:54 +00:00
|
|
|
{
|
2000-03-28 07:12:36 +00:00
|
|
|
guint length = 0;
|
|
|
|
gboolean def = FALSE;
|
2001-04-15 07:30:03 +00:00
|
|
|
int start = a->offset;
|
2002-03-01 02:48:10 +00:00
|
|
|
int ret;
|
2000-03-28 07:12:36 +00:00
|
|
|
|
2002-03-01 02:48:10 +00:00
|
|
|
ret = asn1_length_decode(a, &def, &length);
|
2002-03-03 01:26:01 +00:00
|
|
|
if (ret != ASN1_ERR_NOERROR) {
|
|
|
|
if (tree) {
|
|
|
|
proto_tree_add_text(tree, a->tvb, start, 0,
|
|
|
|
"%s: ERROR: Couldn't parse length: %s",
|
|
|
|
proto_registrar_get_name(hf_id), asn1_err_to_str(ret));
|
|
|
|
}
|
2002-03-01 02:48:10 +00:00
|
|
|
return ret;
|
2002-03-03 01:26:01 +00:00
|
|
|
}
|
2000-03-28 07:12:36 +00:00
|
|
|
|
|
|
|
if (len)
|
|
|
|
*len = length;
|
|
|
|
|
|
|
|
if (tree)
|
2001-04-15 07:30:03 +00:00
|
|
|
proto_tree_add_uint(tree, hf_id, a->tvb, start, a->offset-start, length);
|
2000-03-28 07:12:36 +00:00
|
|
|
|
2002-03-01 02:48:10 +00:00
|
|
|
return ASN1_ERR_NOERROR;
|
2000-03-28 07:12:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int read_sequence(ASN1_SCK *a, guint *len)
|
|
|
|
{
|
2000-03-29 09:25:21 +00:00
|
|
|
guint cls, con, tag;
|
|
|
|
gboolean def;
|
|
|
|
guint length;
|
2002-03-01 02:48:10 +00:00
|
|
|
int ret;
|
2000-03-28 07:12:36 +00:00
|
|
|
|
2002-03-01 02:48:10 +00:00
|
|
|
ret = asn1_header_decode(a, &cls, &con, &tag, &def, &length);
|
|
|
|
if (ret != ASN1_ERR_NOERROR)
|
|
|
|
return ret;
|
2000-03-29 09:25:21 +00:00
|
|
|
if (cls != ASN1_UNI || con != ASN1_CON || tag != ASN1_SEQ)
|
2002-03-01 02:48:10 +00:00
|
|
|
return ASN1_ERR_WRONG_TYPE;
|
2001-04-15 07:30:03 +00:00
|
|
|
|
2000-03-28 07:12:36 +00:00
|
|
|
if (len)
|
|
|
|
*len = length;
|
|
|
|
|
2002-03-01 02:48:10 +00:00
|
|
|
return ASN1_ERR_NOERROR;
|
2000-03-28 07:12:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int read_set(ASN1_SCK *a, guint *len)
|
|
|
|
{
|
2000-03-29 09:25:21 +00:00
|
|
|
guint cls, con, tag;
|
|
|
|
gboolean def;
|
|
|
|
guint length;
|
2002-03-01 02:48:10 +00:00
|
|
|
int ret;
|
2000-03-28 07:12:36 +00:00
|
|
|
|
2002-03-01 02:48:10 +00:00
|
|
|
ret = asn1_header_decode(a, &cls, &con, &tag, &def, &length);
|
|
|
|
if (ret != ASN1_ERR_NOERROR)
|
|
|
|
return ret;
|
2000-03-29 09:25:21 +00:00
|
|
|
if (cls != ASN1_UNI || con != ASN1_CON || tag != ASN1_SET)
|
2002-03-01 02:48:10 +00:00
|
|
|
return ASN1_ERR_WRONG_TYPE;
|
2000-03-28 07:12:36 +00:00
|
|
|
|
|
|
|
if (len)
|
|
|
|
*len = length;
|
|
|
|
|
2002-03-01 02:48:10 +00:00
|
|
|
return ASN1_ERR_NOERROR;
|
2000-03-28 07:12:36 +00:00
|
|
|
}
|
|
|
|
|
2000-03-29 09:25:21 +00:00
|
|
|
static int read_integer_value(ASN1_SCK *a, proto_tree *tree, int hf_id,
|
2002-03-01 02:48:10 +00:00
|
|
|
proto_item **new_item, guint *i, int start, guint length)
|
2000-03-28 07:12:36 +00:00
|
|
|
{
|
|
|
|
guint integer = 0;
|
2002-03-01 03:02:36 +00:00
|
|
|
proto_item *temp_item = NULL;
|
2002-03-01 02:48:10 +00:00
|
|
|
int ret;
|
2000-03-28 07:12:36 +00:00
|
|
|
|
2002-03-01 02:48:10 +00:00
|
|
|
ret = asn1_uint32_value_decode(a, length, &integer);
|
2002-03-03 01:26:01 +00:00
|
|
|
if (ret != ASN1_ERR_NOERROR) {
|
|
|
|
if (tree) {
|
|
|
|
proto_tree_add_text(tree, a->tvb, start, 0,
|
|
|
|
"%s: ERROR: Couldn't parse value: %s",
|
|
|
|
proto_registrar_get_name(hf_id), asn1_err_to_str(ret));
|
|
|
|
}
|
2002-03-01 02:48:10 +00:00
|
|
|
return ret;
|
2002-03-03 01:26:01 +00:00
|
|
|
}
|
2000-03-28 07:12:36 +00:00
|
|
|
|
|
|
|
if (i)
|
|
|
|
*i = integer;
|
|
|
|
|
|
|
|
if (tree)
|
2002-03-01 02:48:10 +00:00
|
|
|
temp_item = proto_tree_add_uint(tree, hf_id, a->tvb, start, a->offset-start, integer);
|
2002-03-01 03:02:36 +00:00
|
|
|
|
|
|
|
if (new_item)
|
|
|
|
*new_item = temp_item;
|
2000-03-28 07:12:36 +00:00
|
|
|
|
2002-03-01 02:48:10 +00:00
|
|
|
return ASN1_ERR_NOERROR;
|
2000-03-28 07:12:36 +00:00
|
|
|
}
|
|
|
|
|
2000-03-29 09:25:21 +00:00
|
|
|
static int read_integer(ASN1_SCK *a, proto_tree *tree, int hf_id,
|
2002-03-01 02:48:10 +00:00
|
|
|
proto_item **new_item, guint *i, guint expected_tag)
|
2000-03-28 07:12:36 +00:00
|
|
|
{
|
2000-03-29 09:25:21 +00:00
|
|
|
guint cls, con, tag;
|
|
|
|
gboolean def;
|
|
|
|
guint length;
|
2001-04-15 07:30:03 +00:00
|
|
|
int start = a->offset;
|
2002-03-01 02:48:10 +00:00
|
|
|
int ret;
|
2000-03-28 07:12:36 +00:00
|
|
|
|
2002-03-01 02:48:10 +00:00
|
|
|
ret = asn1_header_decode(a, &cls, &con, &tag, &def, &length);
|
2002-03-03 01:26:01 +00:00
|
|
|
if (ret == ASN1_ERR_NOERROR) {
|
|
|
|
if (cls != ASN1_UNI || con != ASN1_PRI || tag != expected_tag)
|
|
|
|
ret = ASN1_ERR_WRONG_TYPE;
|
|
|
|
}
|
|
|
|
if (ret != ASN1_ERR_NOERROR) {
|
|
|
|
if (tree) {
|
|
|
|
proto_tree_add_text(tree, a->tvb, start, 0,
|
|
|
|
"%s: ERROR: Couldn't parse header: %s",
|
|
|
|
(hf_id != -1) ? proto_registrar_get_name(hf_id) : "LDAP message",
|
|
|
|
asn1_err_to_str(ret));
|
|
|
|
}
|
2002-03-01 02:48:10 +00:00
|
|
|
return ret;
|
2002-03-03 01:26:01 +00:00
|
|
|
}
|
2000-03-28 07:12:36 +00:00
|
|
|
|
2002-03-01 02:48:10 +00:00
|
|
|
return read_integer_value(a, tree, hf_id, new_item, i, start, length);
|
2000-03-29 09:25:21 +00:00
|
|
|
}
|
2000-03-28 07:12:36 +00:00
|
|
|
|
2000-05-31 05:09:07 +00:00
|
|
|
static int read_boolean_value(ASN1_SCK *a, proto_tree *tree, int hf_id,
|
2002-03-01 02:48:10 +00:00
|
|
|
proto_item **new_item, guint *i, int start, guint length)
|
2000-05-31 05:09:07 +00:00
|
|
|
{
|
|
|
|
guint integer = 0;
|
2002-03-01 03:02:36 +00:00
|
|
|
proto_item *temp_item = NULL;
|
2002-03-03 01:26:01 +00:00
|
|
|
int ret;
|
2000-05-31 05:09:07 +00:00
|
|
|
|
2002-03-03 01:26:01 +00:00
|
|
|
ret = asn1_uint32_value_decode(a, length, &integer);
|
|
|
|
if (ret != ASN1_ERR_NOERROR) {
|
|
|
|
if (tree) {
|
|
|
|
proto_tree_add_text(tree, a->tvb, start, 0,
|
|
|
|
"%s: ERROR: Couldn't parse value: %s",
|
|
|
|
proto_registrar_get_name(hf_id), asn1_err_to_str(ret));
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
2000-05-31 05:09:07 +00:00
|
|
|
|
|
|
|
if (i)
|
|
|
|
*i = integer;
|
|
|
|
|
|
|
|
if (tree)
|
2002-03-01 02:48:10 +00:00
|
|
|
temp_item = proto_tree_add_boolean(tree, hf_id, a->tvb, start, a->offset-start, integer);
|
2002-03-01 03:02:36 +00:00
|
|
|
if (new_item)
|
|
|
|
*new_item = temp_item;
|
2000-05-31 05:09:07 +00:00
|
|
|
|
2002-03-01 02:48:10 +00:00
|
|
|
return ASN1_ERR_NOERROR;
|
2000-05-31 05:09:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int read_boolean(ASN1_SCK *a, proto_tree *tree, int hf_id,
|
2002-03-01 02:48:10 +00:00
|
|
|
proto_item **new_item, guint *i)
|
2000-05-31 05:09:07 +00:00
|
|
|
{
|
|
|
|
guint cls, con, tag;
|
|
|
|
gboolean def;
|
|
|
|
guint length;
|
2001-04-15 07:30:03 +00:00
|
|
|
int start = a->offset;
|
2002-03-01 02:48:10 +00:00
|
|
|
int ret;
|
2000-05-31 05:09:07 +00:00
|
|
|
|
2002-03-01 02:48:10 +00:00
|
|
|
ret = asn1_header_decode(a, &cls, &con, &tag, &def, &length);
|
2002-03-03 01:26:01 +00:00
|
|
|
if (ret == ASN1_ERR_NOERROR) {
|
|
|
|
if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_BOL)
|
|
|
|
ret = ASN1_ERR_WRONG_TYPE;
|
|
|
|
}
|
|
|
|
if (ret != ASN1_ERR_NOERROR) {
|
|
|
|
if (tree) {
|
|
|
|
proto_tree_add_text(tree, a->tvb, start, 0,
|
|
|
|
"%s: ERROR: Couldn't parse header: %s",
|
|
|
|
proto_registrar_get_name(hf_id), asn1_err_to_str(ret));
|
|
|
|
}
|
2002-03-01 02:48:10 +00:00
|
|
|
return ret;
|
2002-03-03 01:26:01 +00:00
|
|
|
}
|
2000-05-31 05:09:07 +00:00
|
|
|
|
2002-03-01 02:48:10 +00:00
|
|
|
return read_boolean_value(a, tree, hf_id, new_item, i, start, length);
|
2000-05-31 05:09:07 +00:00
|
|
|
}
|
|
|
|
|
2002-03-01 02:48:10 +00:00
|
|
|
static int read_string_value(ASN1_SCK *a, proto_tree *tree, int hf_id,
|
|
|
|
proto_item **new_item, char **s, int start, guint length)
|
2000-03-29 09:25:21 +00:00
|
|
|
{
|
|
|
|
guchar *string;
|
2002-03-01 03:02:36 +00:00
|
|
|
proto_item *temp_item = NULL;
|
2002-03-01 02:48:10 +00:00
|
|
|
int ret;
|
2000-03-29 09:25:21 +00:00
|
|
|
|
2000-03-28 07:12:36 +00:00
|
|
|
if (length)
|
|
|
|
{
|
2002-03-01 02:48:10 +00:00
|
|
|
ret = asn1_string_value_decode(a, length, &string);
|
2002-03-03 01:26:01 +00:00
|
|
|
if (ret != ASN1_ERR_NOERROR) {
|
|
|
|
if (tree) {
|
|
|
|
proto_tree_add_text(tree, a->tvb, start, 0,
|
|
|
|
"%s: ERROR: Couldn't parse value: %s",
|
|
|
|
proto_registrar_get_name(hf_id), asn1_err_to_str(ret));
|
|
|
|
}
|
2002-03-01 02:48:10 +00:00
|
|
|
return ret;
|
2002-03-03 01:26:01 +00:00
|
|
|
}
|
2000-03-28 07:12:36 +00:00
|
|
|
string = g_realloc(string, length + 1);
|
|
|
|
string[length] = '\0';
|
|
|
|
}
|
|
|
|
else
|
|
|
|
string = "(null)";
|
|
|
|
|
|
|
|
if (tree)
|
2002-03-01 02:48:10 +00:00
|
|
|
temp_item = proto_tree_add_string(tree, hf_id, a->tvb, start, a->offset - start, string);
|
2002-03-01 03:02:36 +00:00
|
|
|
if (new_item)
|
|
|
|
*new_item = temp_item;
|
2000-03-28 07:12:36 +00:00
|
|
|
|
|
|
|
if (s && length)
|
|
|
|
*s = string;
|
|
|
|
else if (length)
|
|
|
|
g_free(string);
|
2002-03-01 02:48:10 +00:00
|
|
|
|
|
|
|
return ASN1_ERR_NOERROR;
|
2000-03-28 07:12:36 +00:00
|
|
|
}
|
|
|
|
|
2000-03-29 09:25:21 +00:00
|
|
|
static int read_string(ASN1_SCK *a, proto_tree *tree, int hf_id,
|
2002-03-01 02:48:10 +00:00
|
|
|
proto_item **new_item, char **s, guint expected_cls, guint expected_tag)
|
2000-03-29 09:25:21 +00:00
|
|
|
{
|
|
|
|
guint cls, con, tag;
|
|
|
|
gboolean def;
|
|
|
|
guint length;
|
2001-04-15 07:30:03 +00:00
|
|
|
int start = a->offset;
|
Put in the beginnings of checks for ASN.1 dissection errors.
The "present" choice in the type Filter is, in LDAP V2,
AttributeType, and, in LDAP V3, it's AttributeDescription. Both of
those are just LDAPString, which is, in turn, OCTET STRING, so it should
be required to have the primitive representation (unless and until we
add support for the constructed representation of octet strings - but
RFC 1777, the LDAP V2 spec, says
(2) Bitstrings and octet strings and all character string types
will be encoded in the primitive form only.
and RFC 2251, the LDAP V3 spec, says
(2) OCTET STRING values will be encoded in the primitive form only.
so we shouldn't ever see it with the constructed representation), and be
parsed with "asn1_octet_string_value_decode()", as, by that point, we've
already dissected the ASN.1 id and length.
Put the bind authorization type into the protocol tree before switching
on the type, so that it goes in even if it's not something we yet
dissect, and actually pass it as an argument to "proto_tree_add_item()"
(alas, "proto_tree_add_item()" is a varargs function, so this error
couldn't have been detected by the compiler).
When not constructing a protocol tree, quit "dissect_ldap()" after
dissecting the first operation - we don't need to dissect the others.
svn path=/trunk/; revision=1768
2000-03-31 10:22:24 +00:00
|
|
|
int ret;
|
2000-03-29 09:25:21 +00:00
|
|
|
|
Put in the beginnings of checks for ASN.1 dissection errors.
The "present" choice in the type Filter is, in LDAP V2,
AttributeType, and, in LDAP V3, it's AttributeDescription. Both of
those are just LDAPString, which is, in turn, OCTET STRING, so it should
be required to have the primitive representation (unless and until we
add support for the constructed representation of octet strings - but
RFC 1777, the LDAP V2 spec, says
(2) Bitstrings and octet strings and all character string types
will be encoded in the primitive form only.
and RFC 2251, the LDAP V3 spec, says
(2) OCTET STRING values will be encoded in the primitive form only.
so we shouldn't ever see it with the constructed representation), and be
parsed with "asn1_octet_string_value_decode()", as, by that point, we've
already dissected the ASN.1 id and length.
Put the bind authorization type into the protocol tree before switching
on the type, so that it goes in even if it's not something we yet
dissect, and actually pass it as an argument to "proto_tree_add_item()"
(alas, "proto_tree_add_item()" is a varargs function, so this error
couldn't have been detected by the compiler).
When not constructing a protocol tree, quit "dissect_ldap()" after
dissecting the first operation - we don't need to dissect the others.
svn path=/trunk/; revision=1768
2000-03-31 10:22:24 +00:00
|
|
|
ret = asn1_header_decode(a, &cls, &con, &tag, &def, &length);
|
2002-03-03 01:26:01 +00:00
|
|
|
if (ret == ASN1_ERR_NOERROR) {
|
|
|
|
if (cls != expected_cls || con != ASN1_PRI || tag != expected_tag)
|
|
|
|
ret = ASN1_ERR_WRONG_TYPE;
|
|
|
|
}
|
|
|
|
if (ret != ASN1_ERR_NOERROR) {
|
|
|
|
if (tree) {
|
|
|
|
proto_tree_add_text(tree, a->tvb, start, 0,
|
|
|
|
"%s: ERROR: Couldn't parse header: %s",
|
|
|
|
proto_registrar_get_name(hf_id), asn1_err_to_str(ret));
|
|
|
|
}
|
Put in the beginnings of checks for ASN.1 dissection errors.
The "present" choice in the type Filter is, in LDAP V2,
AttributeType, and, in LDAP V3, it's AttributeDescription. Both of
those are just LDAPString, which is, in turn, OCTET STRING, so it should
be required to have the primitive representation (unless and until we
add support for the constructed representation of octet strings - but
RFC 1777, the LDAP V2 spec, says
(2) Bitstrings and octet strings and all character string types
will be encoded in the primitive form only.
and RFC 2251, the LDAP V3 spec, says
(2) OCTET STRING values will be encoded in the primitive form only.
so we shouldn't ever see it with the constructed representation), and be
parsed with "asn1_octet_string_value_decode()", as, by that point, we've
already dissected the ASN.1 id and length.
Put the bind authorization type into the protocol tree before switching
on the type, so that it goes in even if it's not something we yet
dissect, and actually pass it as an argument to "proto_tree_add_item()"
(alas, "proto_tree_add_item()" is a varargs function, so this error
couldn't have been detected by the compiler).
When not constructing a protocol tree, quit "dissect_ldap()" after
dissecting the first operation - we don't need to dissect the others.
svn path=/trunk/; revision=1768
2000-03-31 10:22:24 +00:00
|
|
|
return ret;
|
2002-03-03 01:26:01 +00:00
|
|
|
}
|
2000-03-29 09:25:21 +00:00
|
|
|
|
2002-03-01 02:48:10 +00:00
|
|
|
return read_string_value(a, tree, hf_id, new_item, s, start, length);
|
2000-03-29 09:25:21 +00:00
|
|
|
}
|
|
|
|
|
Put in the beginnings of checks for ASN.1 dissection errors.
The "present" choice in the type Filter is, in LDAP V2,
AttributeType, and, in LDAP V3, it's AttributeDescription. Both of
those are just LDAPString, which is, in turn, OCTET STRING, so it should
be required to have the primitive representation (unless and until we
add support for the constructed representation of octet strings - but
RFC 1777, the LDAP V2 spec, says
(2) Bitstrings and octet strings and all character string types
will be encoded in the primitive form only.
and RFC 2251, the LDAP V3 spec, says
(2) OCTET STRING values will be encoded in the primitive form only.
so we shouldn't ever see it with the constructed representation), and be
parsed with "asn1_octet_string_value_decode()", as, by that point, we've
already dissected the ASN.1 id and length.
Put the bind authorization type into the protocol tree before switching
on the type, so that it goes in even if it's not something we yet
dissect, and actually pass it as an argument to "proto_tree_add_item()"
(alas, "proto_tree_add_item()" is a varargs function, so this error
couldn't have been detected by the compiler).
When not constructing a protocol tree, quit "dissect_ldap()" after
dissecting the first operation - we don't need to dissect the others.
svn path=/trunk/; revision=1768
2000-03-31 10:22:24 +00:00
|
|
|
static int parse_filter_strings(ASN1_SCK *a, char **filter, guint *filter_length, const guchar *operation)
|
2000-03-28 07:12:36 +00:00
|
|
|
{
|
|
|
|
guchar *string;
|
|
|
|
guchar *string2;
|
2000-08-24 05:40:50 +00:00
|
|
|
guint string_length;
|
|
|
|
guint string2_length;
|
2000-03-28 07:12:36 +00:00
|
|
|
guint string_bytes;
|
2000-08-24 05:40:50 +00:00
|
|
|
char *filterp;
|
Put in the beginnings of checks for ASN.1 dissection errors.
The "present" choice in the type Filter is, in LDAP V2,
AttributeType, and, in LDAP V3, it's AttributeDescription. Both of
those are just LDAPString, which is, in turn, OCTET STRING, so it should
be required to have the primitive representation (unless and until we
add support for the constructed representation of octet strings - but
RFC 1777, the LDAP V2 spec, says
(2) Bitstrings and octet strings and all character string types
will be encoded in the primitive form only.
and RFC 2251, the LDAP V3 spec, says
(2) OCTET STRING values will be encoded in the primitive form only.
so we shouldn't ever see it with the constructed representation), and be
parsed with "asn1_octet_string_value_decode()", as, by that point, we've
already dissected the ASN.1 id and length.
Put the bind authorization type into the protocol tree before switching
on the type, so that it goes in even if it's not something we yet
dissect, and actually pass it as an argument to "proto_tree_add_item()"
(alas, "proto_tree_add_item()" is a varargs function, so this error
couldn't have been detected by the compiler).
When not constructing a protocol tree, quit "dissect_ldap()" after
dissecting the first operation - we don't need to dissect the others.
svn path=/trunk/; revision=1768
2000-03-31 10:22:24 +00:00
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = asn1_octet_string_decode(a, &string, &string_length, &string_bytes);
|
|
|
|
if (ret != ASN1_ERR_NOERROR)
|
|
|
|
return ret;
|
|
|
|
ret = asn1_octet_string_decode(a, &string2, &string2_length, &string_bytes);
|
|
|
|
if (ret != ASN1_ERR_NOERROR)
|
|
|
|
return ret;
|
2000-03-29 09:25:21 +00:00
|
|
|
*filter_length += 2 + strlen(operation) + string_length + string2_length;
|
2000-03-28 07:12:36 +00:00
|
|
|
*filter = g_realloc(*filter, *filter_length);
|
2000-08-24 05:40:50 +00:00
|
|
|
filterp = *filter + strlen(*filter);
|
|
|
|
*filterp++ = '(';
|
|
|
|
if (string_length != 0) {
|
|
|
|
memcpy(filterp, string, string_length);
|
|
|
|
filterp += string_length;
|
|
|
|
}
|
|
|
|
strcpy(filterp, operation);
|
|
|
|
filterp += strlen(operation);
|
|
|
|
if (string2_length != 0) {
|
|
|
|
memcpy(filterp, string2, string2_length);
|
|
|
|
filterp += string2_length;
|
|
|
|
}
|
|
|
|
*filterp++ = ')';
|
|
|
|
*filterp = '\0';
|
2000-03-28 07:12:36 +00:00
|
|
|
g_free(string);
|
|
|
|
g_free(string2);
|
Put in the beginnings of checks for ASN.1 dissection errors.
The "present" choice in the type Filter is, in LDAP V2,
AttributeType, and, in LDAP V3, it's AttributeDescription. Both of
those are just LDAPString, which is, in turn, OCTET STRING, so it should
be required to have the primitive representation (unless and until we
add support for the constructed representation of octet strings - but
RFC 1777, the LDAP V2 spec, says
(2) Bitstrings and octet strings and all character string types
will be encoded in the primitive form only.
and RFC 2251, the LDAP V3 spec, says
(2) OCTET STRING values will be encoded in the primitive form only.
so we shouldn't ever see it with the constructed representation), and be
parsed with "asn1_octet_string_value_decode()", as, by that point, we've
already dissected the ASN.1 id and length.
Put the bind authorization type into the protocol tree before switching
on the type, so that it goes in even if it's not something we yet
dissect, and actually pass it as an argument to "proto_tree_add_item()"
(alas, "proto_tree_add_item()" is a varargs function, so this error
couldn't have been detected by the compiler).
When not constructing a protocol tree, quit "dissect_ldap()" after
dissecting the first operation - we don't need to dissect the others.
svn path=/trunk/; revision=1768
2000-03-31 10:22:24 +00:00
|
|
|
return ASN1_ERR_NOERROR;
|
2000-03-28 07:12:36 +00:00
|
|
|
}
|
|
|
|
|
2000-05-12 08:04:29 +00:00
|
|
|
/* Richard Dawe: To parse substring filters, I added this function. */
|
|
|
|
static int parse_filter_substrings(ASN1_SCK *a, char **filter, guint *filter_length)
|
|
|
|
{
|
2001-04-15 07:30:03 +00:00
|
|
|
int end;
|
2000-08-24 05:40:50 +00:00
|
|
|
guchar *string;
|
|
|
|
char *filterp;
|
|
|
|
guint string_length;
|
2000-05-12 08:04:29 +00:00
|
|
|
guint string_bytes;
|
|
|
|
guint seq_len;
|
|
|
|
guint header_bytes;
|
|
|
|
int ret, any_valued;
|
|
|
|
|
|
|
|
/* For ASN.1 parsing of octet strings */
|
|
|
|
guint cls;
|
|
|
|
guint con;
|
|
|
|
guint tag;
|
|
|
|
gboolean def;
|
|
|
|
|
|
|
|
ret = asn1_octet_string_decode(a, &string, &string_length, &string_bytes);
|
|
|
|
if (ret != ASN1_ERR_NOERROR)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
ret = asn1_sequence_decode(a, &seq_len, &header_bytes);
|
|
|
|
if (ret != ASN1_ERR_NOERROR)
|
|
|
|
return ret;
|
|
|
|
|
2000-08-24 05:40:50 +00:00
|
|
|
*filter_length += 2 + 1 + string_length;
|
2000-05-12 08:04:29 +00:00
|
|
|
*filter = g_realloc(*filter, *filter_length);
|
2000-08-24 05:40:50 +00:00
|
|
|
|
|
|
|
filterp = *filter + strlen(*filter);
|
|
|
|
*filterp++ = '(';
|
|
|
|
if (string_length != 0) {
|
|
|
|
memcpy(filterp, string, string_length);
|
|
|
|
filterp += string_length;
|
|
|
|
}
|
|
|
|
*filterp++ = '=';
|
|
|
|
*filterp = '\0';
|
2000-05-12 08:04:29 +00:00
|
|
|
g_free(string);
|
|
|
|
|
|
|
|
/* Now decode seq_len's worth of octet strings. */
|
|
|
|
any_valued = 0;
|
2001-04-15 07:30:03 +00:00
|
|
|
end = a->offset + seq_len;
|
2000-05-12 08:04:29 +00:00
|
|
|
|
2001-04-15 07:30:03 +00:00
|
|
|
while (a->offset < end) {
|
2000-05-12 08:04:29 +00:00
|
|
|
/* Octet strings here are context-specific, which
|
|
|
|
* asn1_octet_string_decode() barfs on. Emulate it, but don't barf. */
|
|
|
|
ret = asn1_header_decode (a, &cls, &con, &tag, &def, &string_length);
|
|
|
|
if (ret != ASN1_ERR_NOERROR)
|
|
|
|
return ret;
|
|
|
|
|
2000-12-24 09:10:12 +00:00
|
|
|
/* XXX - check the tag? */
|
2000-05-12 08:04:29 +00:00
|
|
|
if (cls != ASN1_CTX || con != ASN1_PRI) {
|
|
|
|
/* XXX - handle the constructed encoding? */
|
|
|
|
return ASN1_ERR_WRONG_TYPE;
|
|
|
|
}
|
|
|
|
if (!def)
|
|
|
|
return ASN1_ERR_LENGTH_NOT_DEFINITE;
|
|
|
|
|
2000-12-24 09:10:12 +00:00
|
|
|
ret = asn1_string_value_decode(a, (int) string_length, &string);
|
2000-05-12 08:04:29 +00:00
|
|
|
if (ret != ASN1_ERR_NOERROR)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
/* If we have an 'any' component with a string value, we need to append
|
|
|
|
* an extra asterisk before final component. */
|
2000-08-24 05:40:50 +00:00
|
|
|
if ((tag == 1) && (string_length != 0))
|
2000-05-12 08:04:29 +00:00
|
|
|
any_valued = 1;
|
|
|
|
|
|
|
|
if ( (tag == 1) || ((tag == 2) && any_valued) )
|
|
|
|
(*filter_length)++;
|
2000-08-24 05:40:50 +00:00
|
|
|
*filter_length += string_length;
|
2000-05-12 08:04:29 +00:00
|
|
|
*filter = g_realloc(*filter, *filter_length);
|
|
|
|
|
2000-08-24 05:40:50 +00:00
|
|
|
filterp = *filter + strlen(*filter);
|
2000-05-12 08:04:29 +00:00
|
|
|
if ( (tag == 1) || ((tag == 2) && any_valued) )
|
2000-08-24 05:40:50 +00:00
|
|
|
*filterp++ = '*';
|
2000-05-12 08:04:29 +00:00
|
|
|
if (tag == 2)
|
|
|
|
any_valued = 0;
|
2000-08-24 05:40:50 +00:00
|
|
|
if (string_length != 0) {
|
|
|
|
memcpy(filterp, string, string_length);
|
|
|
|
filterp += string_length;
|
|
|
|
}
|
|
|
|
*filterp = '\0';
|
2000-05-12 08:04:29 +00:00
|
|
|
g_free(string);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (any_valued)
|
|
|
|
{
|
|
|
|
(*filter_length)++;
|
|
|
|
*filter = g_realloc(*filter, *filter_length);
|
2000-08-24 05:40:50 +00:00
|
|
|
filterp = *filter + strlen(*filter);
|
|
|
|
*filterp++ = '*';
|
2000-05-12 08:04:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* NB: Allocated byte for this earlier */
|
2000-08-24 05:40:50 +00:00
|
|
|
*filterp++ = ')';
|
|
|
|
*filterp = '\0';
|
2000-05-12 08:04:29 +00:00
|
|
|
|
|
|
|
return ASN1_ERR_NOERROR;
|
|
|
|
}
|
|
|
|
|
Put in the beginnings of checks for ASN.1 dissection errors.
The "present" choice in the type Filter is, in LDAP V2,
AttributeType, and, in LDAP V3, it's AttributeDescription. Both of
those are just LDAPString, which is, in turn, OCTET STRING, so it should
be required to have the primitive representation (unless and until we
add support for the constructed representation of octet strings - but
RFC 1777, the LDAP V2 spec, says
(2) Bitstrings and octet strings and all character string types
will be encoded in the primitive form only.
and RFC 2251, the LDAP V3 spec, says
(2) OCTET STRING values will be encoded in the primitive form only.
so we shouldn't ever see it with the constructed representation), and be
parsed with "asn1_octet_string_value_decode()", as, by that point, we've
already dissected the ASN.1 id and length.
Put the bind authorization type into the protocol tree before switching
on the type, so that it goes in even if it's not something we yet
dissect, and actually pass it as an argument to "proto_tree_add_item()"
(alas, "proto_tree_add_item()" is a varargs function, so this error
couldn't have been detected by the compiler).
When not constructing a protocol tree, quit "dissect_ldap()" after
dissecting the first operation - we don't need to dissect the others.
svn path=/trunk/; revision=1768
2000-03-31 10:22:24 +00:00
|
|
|
/* Returns -1 if we're at the end, returns an ASN1_ERR value otherwise. */
|
2001-04-15 07:30:03 +00:00
|
|
|
static int parse_filter(ASN1_SCK *a, char **filter, guint *filter_length,
|
|
|
|
int *end)
|
2000-03-28 07:12:36 +00:00
|
|
|
{
|
2000-03-29 09:25:21 +00:00
|
|
|
guint cls, con, tag;
|
2000-03-28 07:12:36 +00:00
|
|
|
guint length;
|
|
|
|
gboolean def;
|
Put in the beginnings of checks for ASN.1 dissection errors.
The "present" choice in the type Filter is, in LDAP V2,
AttributeType, and, in LDAP V3, it's AttributeDescription. Both of
those are just LDAPString, which is, in turn, OCTET STRING, so it should
be required to have the primitive representation (unless and until we
add support for the constructed representation of octet strings - but
RFC 1777, the LDAP V2 spec, says
(2) Bitstrings and octet strings and all character string types
will be encoded in the primitive form only.
and RFC 2251, the LDAP V3 spec, says
(2) OCTET STRING values will be encoded in the primitive form only.
so we shouldn't ever see it with the constructed representation), and be
parsed with "asn1_octet_string_value_decode()", as, by that point, we've
already dissected the ASN.1 id and length.
Put the bind authorization type into the protocol tree before switching
on the type, so that it goes in even if it's not something we yet
dissect, and actually pass it as an argument to "proto_tree_add_item()"
(alas, "proto_tree_add_item()" is a varargs function, so this error
couldn't have been detected by the compiler).
When not constructing a protocol tree, quit "dissect_ldap()" after
dissecting the first operation - we don't need to dissect the others.
svn path=/trunk/; revision=1768
2000-03-31 10:22:24 +00:00
|
|
|
int ret;
|
2000-03-28 07:12:36 +00:00
|
|
|
|
Put in the beginnings of checks for ASN.1 dissection errors.
The "present" choice in the type Filter is, in LDAP V2,
AttributeType, and, in LDAP V3, it's AttributeDescription. Both of
those are just LDAPString, which is, in turn, OCTET STRING, so it should
be required to have the primitive representation (unless and until we
add support for the constructed representation of octet strings - but
RFC 1777, the LDAP V2 spec, says
(2) Bitstrings and octet strings and all character string types
will be encoded in the primitive form only.
and RFC 2251, the LDAP V3 spec, says
(2) OCTET STRING values will be encoded in the primitive form only.
so we shouldn't ever see it with the constructed representation), and be
parsed with "asn1_octet_string_value_decode()", as, by that point, we've
already dissected the ASN.1 id and length.
Put the bind authorization type into the protocol tree before switching
on the type, so that it goes in even if it's not something we yet
dissect, and actually pass it as an argument to "proto_tree_add_item()"
(alas, "proto_tree_add_item()" is a varargs function, so this error
couldn't have been detected by the compiler).
When not constructing a protocol tree, quit "dissect_ldap()" after
dissecting the first operation - we don't need to dissect the others.
svn path=/trunk/; revision=1768
2000-03-31 10:22:24 +00:00
|
|
|
ret = asn1_header_decode(a, &cls, &con, &tag, &def, &length);
|
|
|
|
if (ret != ASN1_ERR_NOERROR)
|
|
|
|
return ret;
|
2000-03-28 07:12:36 +00:00
|
|
|
|
|
|
|
if (*end == 0)
|
|
|
|
{
|
2001-04-15 07:30:03 +00:00
|
|
|
*end = a->offset + length;
|
2000-03-28 07:12:36 +00:00
|
|
|
*filter_length = 1;
|
|
|
|
*filter = g_malloc0(*filter_length);
|
|
|
|
}
|
|
|
|
|
2000-03-29 09:25:21 +00:00
|
|
|
if (cls == ASN1_CTX) /* XXX - handle other types as errors? */
|
2000-03-28 07:12:36 +00:00
|
|
|
{
|
2000-03-29 09:25:21 +00:00
|
|
|
switch (tag)
|
2000-03-28 07:12:36 +00:00
|
|
|
{
|
2000-03-29 09:25:21 +00:00
|
|
|
case LDAP_FILTER_AND:
|
|
|
|
{
|
2001-04-15 07:30:03 +00:00
|
|
|
int add_end;
|
2000-03-29 09:25:21 +00:00
|
|
|
|
|
|
|
if (con != ASN1_CON)
|
Put in the beginnings of checks for ASN.1 dissection errors.
The "present" choice in the type Filter is, in LDAP V2,
AttributeType, and, in LDAP V3, it's AttributeDescription. Both of
those are just LDAPString, which is, in turn, OCTET STRING, so it should
be required to have the primitive representation (unless and until we
add support for the constructed representation of octet strings - but
RFC 1777, the LDAP V2 spec, says
(2) Bitstrings and octet strings and all character string types
will be encoded in the primitive form only.
and RFC 2251, the LDAP V3 spec, says
(2) OCTET STRING values will be encoded in the primitive form only.
so we shouldn't ever see it with the constructed representation), and be
parsed with "asn1_octet_string_value_decode()", as, by that point, we've
already dissected the ASN.1 id and length.
Put the bind authorization type into the protocol tree before switching
on the type, so that it goes in even if it's not something we yet
dissect, and actually pass it as an argument to "proto_tree_add_item()"
(alas, "proto_tree_add_item()" is a varargs function, so this error
couldn't have been detected by the compiler).
When not constructing a protocol tree, quit "dissect_ldap()" after
dissecting the first operation - we don't need to dissect the others.
svn path=/trunk/; revision=1768
2000-03-31 10:22:24 +00:00
|
|
|
return ASN1_ERR_WRONG_TYPE;
|
2001-04-15 07:30:03 +00:00
|
|
|
add_end = a->offset + length;
|
2000-03-29 09:25:21 +00:00
|
|
|
*filter_length += 3;
|
|
|
|
*filter = g_realloc(*filter, *filter_length);
|
|
|
|
strcat(*filter, "(&");
|
Put in the beginnings of checks for ASN.1 dissection errors.
The "present" choice in the type Filter is, in LDAP V2,
AttributeType, and, in LDAP V3, it's AttributeDescription. Both of
those are just LDAPString, which is, in turn, OCTET STRING, so it should
be required to have the primitive representation (unless and until we
add support for the constructed representation of octet strings - but
RFC 1777, the LDAP V2 spec, says
(2) Bitstrings and octet strings and all character string types
will be encoded in the primitive form only.
and RFC 2251, the LDAP V3 spec, says
(2) OCTET STRING values will be encoded in the primitive form only.
so we shouldn't ever see it with the constructed representation), and be
parsed with "asn1_octet_string_value_decode()", as, by that point, we've
already dissected the ASN.1 id and length.
Put the bind authorization type into the protocol tree before switching
on the type, so that it goes in even if it's not something we yet
dissect, and actually pass it as an argument to "proto_tree_add_item()"
(alas, "proto_tree_add_item()" is a varargs function, so this error
couldn't have been detected by the compiler).
When not constructing a protocol tree, quit "dissect_ldap()" after
dissecting the first operation - we don't need to dissect the others.
svn path=/trunk/; revision=1768
2000-03-31 10:22:24 +00:00
|
|
|
while ((ret = parse_filter(a, filter, filter_length, &add_end))
|
|
|
|
== ASN1_ERR_NOERROR)
|
2000-03-29 09:25:21 +00:00
|
|
|
continue;
|
Put in the beginnings of checks for ASN.1 dissection errors.
The "present" choice in the type Filter is, in LDAP V2,
AttributeType, and, in LDAP V3, it's AttributeDescription. Both of
those are just LDAPString, which is, in turn, OCTET STRING, so it should
be required to have the primitive representation (unless and until we
add support for the constructed representation of octet strings - but
RFC 1777, the LDAP V2 spec, says
(2) Bitstrings and octet strings and all character string types
will be encoded in the primitive form only.
and RFC 2251, the LDAP V3 spec, says
(2) OCTET STRING values will be encoded in the primitive form only.
so we shouldn't ever see it with the constructed representation), and be
parsed with "asn1_octet_string_value_decode()", as, by that point, we've
already dissected the ASN.1 id and length.
Put the bind authorization type into the protocol tree before switching
on the type, so that it goes in even if it's not something we yet
dissect, and actually pass it as an argument to "proto_tree_add_item()"
(alas, "proto_tree_add_item()" is a varargs function, so this error
couldn't have been detected by the compiler).
When not constructing a protocol tree, quit "dissect_ldap()" after
dissecting the first operation - we don't need to dissect the others.
svn path=/trunk/; revision=1768
2000-03-31 10:22:24 +00:00
|
|
|
if (ret != -1)
|
|
|
|
return ret;
|
2000-03-29 09:25:21 +00:00
|
|
|
strcat(*filter, ")");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case LDAP_FILTER_OR:
|
|
|
|
{
|
2001-04-15 07:30:03 +00:00
|
|
|
int or_end;
|
2000-03-29 09:25:21 +00:00
|
|
|
|
|
|
|
if (con != ASN1_CON)
|
Put in the beginnings of checks for ASN.1 dissection errors.
The "present" choice in the type Filter is, in LDAP V2,
AttributeType, and, in LDAP V3, it's AttributeDescription. Both of
those are just LDAPString, which is, in turn, OCTET STRING, so it should
be required to have the primitive representation (unless and until we
add support for the constructed representation of octet strings - but
RFC 1777, the LDAP V2 spec, says
(2) Bitstrings and octet strings and all character string types
will be encoded in the primitive form only.
and RFC 2251, the LDAP V3 spec, says
(2) OCTET STRING values will be encoded in the primitive form only.
so we shouldn't ever see it with the constructed representation), and be
parsed with "asn1_octet_string_value_decode()", as, by that point, we've
already dissected the ASN.1 id and length.
Put the bind authorization type into the protocol tree before switching
on the type, so that it goes in even if it's not something we yet
dissect, and actually pass it as an argument to "proto_tree_add_item()"
(alas, "proto_tree_add_item()" is a varargs function, so this error
couldn't have been detected by the compiler).
When not constructing a protocol tree, quit "dissect_ldap()" after
dissecting the first operation - we don't need to dissect the others.
svn path=/trunk/; revision=1768
2000-03-31 10:22:24 +00:00
|
|
|
return ASN1_ERR_WRONG_TYPE;
|
2001-04-15 07:30:03 +00:00
|
|
|
or_end = a->offset + length;
|
2000-03-29 09:25:21 +00:00
|
|
|
*filter_length += 3;
|
|
|
|
*filter = g_realloc(*filter, *filter_length);
|
|
|
|
strcat(*filter, "(|");
|
Put in the beginnings of checks for ASN.1 dissection errors.
The "present" choice in the type Filter is, in LDAP V2,
AttributeType, and, in LDAP V3, it's AttributeDescription. Both of
those are just LDAPString, which is, in turn, OCTET STRING, so it should
be required to have the primitive representation (unless and until we
add support for the constructed representation of octet strings - but
RFC 1777, the LDAP V2 spec, says
(2) Bitstrings and octet strings and all character string types
will be encoded in the primitive form only.
and RFC 2251, the LDAP V3 spec, says
(2) OCTET STRING values will be encoded in the primitive form only.
so we shouldn't ever see it with the constructed representation), and be
parsed with "asn1_octet_string_value_decode()", as, by that point, we've
already dissected the ASN.1 id and length.
Put the bind authorization type into the protocol tree before switching
on the type, so that it goes in even if it's not something we yet
dissect, and actually pass it as an argument to "proto_tree_add_item()"
(alas, "proto_tree_add_item()" is a varargs function, so this error
couldn't have been detected by the compiler).
When not constructing a protocol tree, quit "dissect_ldap()" after
dissecting the first operation - we don't need to dissect the others.
svn path=/trunk/; revision=1768
2000-03-31 10:22:24 +00:00
|
|
|
while ((ret = parse_filter(a, filter, filter_length, &or_end))
|
|
|
|
== ASN1_ERR_NOERROR)
|
2000-03-29 09:25:21 +00:00
|
|
|
continue;
|
Put in the beginnings of checks for ASN.1 dissection errors.
The "present" choice in the type Filter is, in LDAP V2,
AttributeType, and, in LDAP V3, it's AttributeDescription. Both of
those are just LDAPString, which is, in turn, OCTET STRING, so it should
be required to have the primitive representation (unless and until we
add support for the constructed representation of octet strings - but
RFC 1777, the LDAP V2 spec, says
(2) Bitstrings and octet strings and all character string types
will be encoded in the primitive form only.
and RFC 2251, the LDAP V3 spec, says
(2) OCTET STRING values will be encoded in the primitive form only.
so we shouldn't ever see it with the constructed representation), and be
parsed with "asn1_octet_string_value_decode()", as, by that point, we've
already dissected the ASN.1 id and length.
Put the bind authorization type into the protocol tree before switching
on the type, so that it goes in even if it's not something we yet
dissect, and actually pass it as an argument to "proto_tree_add_item()"
(alas, "proto_tree_add_item()" is a varargs function, so this error
couldn't have been detected by the compiler).
When not constructing a protocol tree, quit "dissect_ldap()" after
dissecting the first operation - we don't need to dissect the others.
svn path=/trunk/; revision=1768
2000-03-31 10:22:24 +00:00
|
|
|
if (ret != -1)
|
|
|
|
return ret;
|
2000-03-29 09:25:21 +00:00
|
|
|
strcat(*filter, ")");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case LDAP_FILTER_NOT:
|
|
|
|
{
|
2001-04-15 07:30:03 +00:00
|
|
|
int not_end;
|
2000-03-29 09:25:21 +00:00
|
|
|
|
|
|
|
if (con != ASN1_CON)
|
Put in the beginnings of checks for ASN.1 dissection errors.
The "present" choice in the type Filter is, in LDAP V2,
AttributeType, and, in LDAP V3, it's AttributeDescription. Both of
those are just LDAPString, which is, in turn, OCTET STRING, so it should
be required to have the primitive representation (unless and until we
add support for the constructed representation of octet strings - but
RFC 1777, the LDAP V2 spec, says
(2) Bitstrings and octet strings and all character string types
will be encoded in the primitive form only.
and RFC 2251, the LDAP V3 spec, says
(2) OCTET STRING values will be encoded in the primitive form only.
so we shouldn't ever see it with the constructed representation), and be
parsed with "asn1_octet_string_value_decode()", as, by that point, we've
already dissected the ASN.1 id and length.
Put the bind authorization type into the protocol tree before switching
on the type, so that it goes in even if it's not something we yet
dissect, and actually pass it as an argument to "proto_tree_add_item()"
(alas, "proto_tree_add_item()" is a varargs function, so this error
couldn't have been detected by the compiler).
When not constructing a protocol tree, quit "dissect_ldap()" after
dissecting the first operation - we don't need to dissect the others.
svn path=/trunk/; revision=1768
2000-03-31 10:22:24 +00:00
|
|
|
return ASN1_ERR_WRONG_TYPE;
|
2001-04-15 07:30:03 +00:00
|
|
|
not_end = a->offset + length;
|
2000-03-29 09:25:21 +00:00
|
|
|
*filter_length += 3;
|
|
|
|
*filter = g_realloc(*filter, *filter_length);
|
|
|
|
strcat(*filter, "(!");
|
Put in the beginnings of checks for ASN.1 dissection errors.
The "present" choice in the type Filter is, in LDAP V2,
AttributeType, and, in LDAP V3, it's AttributeDescription. Both of
those are just LDAPString, which is, in turn, OCTET STRING, so it should
be required to have the primitive representation (unless and until we
add support for the constructed representation of octet strings - but
RFC 1777, the LDAP V2 spec, says
(2) Bitstrings and octet strings and all character string types
will be encoded in the primitive form only.
and RFC 2251, the LDAP V3 spec, says
(2) OCTET STRING values will be encoded in the primitive form only.
so we shouldn't ever see it with the constructed representation), and be
parsed with "asn1_octet_string_value_decode()", as, by that point, we've
already dissected the ASN.1 id and length.
Put the bind authorization type into the protocol tree before switching
on the type, so that it goes in even if it's not something we yet
dissect, and actually pass it as an argument to "proto_tree_add_item()"
(alas, "proto_tree_add_item()" is a varargs function, so this error
couldn't have been detected by the compiler).
When not constructing a protocol tree, quit "dissect_ldap()" after
dissecting the first operation - we don't need to dissect the others.
svn path=/trunk/; revision=1768
2000-03-31 10:22:24 +00:00
|
|
|
ret = parse_filter(a, filter, filter_length, ¬_end);
|
|
|
|
if (ret != -1 && ret != ASN1_ERR_NOERROR)
|
|
|
|
return ret;
|
2000-03-29 09:25:21 +00:00
|
|
|
strcat(*filter, ")");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case LDAP_FILTER_EQUALITY:
|
|
|
|
if (con != ASN1_CON)
|
Put in the beginnings of checks for ASN.1 dissection errors.
The "present" choice in the type Filter is, in LDAP V2,
AttributeType, and, in LDAP V3, it's AttributeDescription. Both of
those are just LDAPString, which is, in turn, OCTET STRING, so it should
be required to have the primitive representation (unless and until we
add support for the constructed representation of octet strings - but
RFC 1777, the LDAP V2 spec, says
(2) Bitstrings and octet strings and all character string types
will be encoded in the primitive form only.
and RFC 2251, the LDAP V3 spec, says
(2) OCTET STRING values will be encoded in the primitive form only.
so we shouldn't ever see it with the constructed representation), and be
parsed with "asn1_octet_string_value_decode()", as, by that point, we've
already dissected the ASN.1 id and length.
Put the bind authorization type into the protocol tree before switching
on the type, so that it goes in even if it's not something we yet
dissect, and actually pass it as an argument to "proto_tree_add_item()"
(alas, "proto_tree_add_item()" is a varargs function, so this error
couldn't have been detected by the compiler).
When not constructing a protocol tree, quit "dissect_ldap()" after
dissecting the first operation - we don't need to dissect the others.
svn path=/trunk/; revision=1768
2000-03-31 10:22:24 +00:00
|
|
|
return ASN1_ERR_WRONG_TYPE;
|
|
|
|
ret = parse_filter_strings(a, filter, filter_length, "=");
|
2002-03-01 02:48:10 +00:00
|
|
|
if (ret != ASN1_ERR_NOERROR)
|
Put in the beginnings of checks for ASN.1 dissection errors.
The "present" choice in the type Filter is, in LDAP V2,
AttributeType, and, in LDAP V3, it's AttributeDescription. Both of
those are just LDAPString, which is, in turn, OCTET STRING, so it should
be required to have the primitive representation (unless and until we
add support for the constructed representation of octet strings - but
RFC 1777, the LDAP V2 spec, says
(2) Bitstrings and octet strings and all character string types
will be encoded in the primitive form only.
and RFC 2251, the LDAP V3 spec, says
(2) OCTET STRING values will be encoded in the primitive form only.
so we shouldn't ever see it with the constructed representation), and be
parsed with "asn1_octet_string_value_decode()", as, by that point, we've
already dissected the ASN.1 id and length.
Put the bind authorization type into the protocol tree before switching
on the type, so that it goes in even if it's not something we yet
dissect, and actually pass it as an argument to "proto_tree_add_item()"
(alas, "proto_tree_add_item()" is a varargs function, so this error
couldn't have been detected by the compiler).
When not constructing a protocol tree, quit "dissect_ldap()" after
dissecting the first operation - we don't need to dissect the others.
svn path=/trunk/; revision=1768
2000-03-31 10:22:24 +00:00
|
|
|
return ret;
|
2000-03-29 09:25:21 +00:00
|
|
|
break;
|
|
|
|
case LDAP_FILTER_GE:
|
|
|
|
if (con != ASN1_CON)
|
Put in the beginnings of checks for ASN.1 dissection errors.
The "present" choice in the type Filter is, in LDAP V2,
AttributeType, and, in LDAP V3, it's AttributeDescription. Both of
those are just LDAPString, which is, in turn, OCTET STRING, so it should
be required to have the primitive representation (unless and until we
add support for the constructed representation of octet strings - but
RFC 1777, the LDAP V2 spec, says
(2) Bitstrings and octet strings and all character string types
will be encoded in the primitive form only.
and RFC 2251, the LDAP V3 spec, says
(2) OCTET STRING values will be encoded in the primitive form only.
so we shouldn't ever see it with the constructed representation), and be
parsed with "asn1_octet_string_value_decode()", as, by that point, we've
already dissected the ASN.1 id and length.
Put the bind authorization type into the protocol tree before switching
on the type, so that it goes in even if it's not something we yet
dissect, and actually pass it as an argument to "proto_tree_add_item()"
(alas, "proto_tree_add_item()" is a varargs function, so this error
couldn't have been detected by the compiler).
When not constructing a protocol tree, quit "dissect_ldap()" after
dissecting the first operation - we don't need to dissect the others.
svn path=/trunk/; revision=1768
2000-03-31 10:22:24 +00:00
|
|
|
return ASN1_ERR_WRONG_TYPE;
|
|
|
|
ret = parse_filter_strings(a, filter, filter_length, ">=");
|
2002-03-01 02:48:10 +00:00
|
|
|
if (ret != ASN1_ERR_NOERROR)
|
Put in the beginnings of checks for ASN.1 dissection errors.
The "present" choice in the type Filter is, in LDAP V2,
AttributeType, and, in LDAP V3, it's AttributeDescription. Both of
those are just LDAPString, which is, in turn, OCTET STRING, so it should
be required to have the primitive representation (unless and until we
add support for the constructed representation of octet strings - but
RFC 1777, the LDAP V2 spec, says
(2) Bitstrings and octet strings and all character string types
will be encoded in the primitive form only.
and RFC 2251, the LDAP V3 spec, says
(2) OCTET STRING values will be encoded in the primitive form only.
so we shouldn't ever see it with the constructed representation), and be
parsed with "asn1_octet_string_value_decode()", as, by that point, we've
already dissected the ASN.1 id and length.
Put the bind authorization type into the protocol tree before switching
on the type, so that it goes in even if it's not something we yet
dissect, and actually pass it as an argument to "proto_tree_add_item()"
(alas, "proto_tree_add_item()" is a varargs function, so this error
couldn't have been detected by the compiler).
When not constructing a protocol tree, quit "dissect_ldap()" after
dissecting the first operation - we don't need to dissect the others.
svn path=/trunk/; revision=1768
2000-03-31 10:22:24 +00:00
|
|
|
return ret;
|
2000-03-29 09:25:21 +00:00
|
|
|
break;
|
|
|
|
case LDAP_FILTER_LE:
|
|
|
|
if (con != ASN1_CON)
|
Put in the beginnings of checks for ASN.1 dissection errors.
The "present" choice in the type Filter is, in LDAP V2,
AttributeType, and, in LDAP V3, it's AttributeDescription. Both of
those are just LDAPString, which is, in turn, OCTET STRING, so it should
be required to have the primitive representation (unless and until we
add support for the constructed representation of octet strings - but
RFC 1777, the LDAP V2 spec, says
(2) Bitstrings and octet strings and all character string types
will be encoded in the primitive form only.
and RFC 2251, the LDAP V3 spec, says
(2) OCTET STRING values will be encoded in the primitive form only.
so we shouldn't ever see it with the constructed representation), and be
parsed with "asn1_octet_string_value_decode()", as, by that point, we've
already dissected the ASN.1 id and length.
Put the bind authorization type into the protocol tree before switching
on the type, so that it goes in even if it's not something we yet
dissect, and actually pass it as an argument to "proto_tree_add_item()"
(alas, "proto_tree_add_item()" is a varargs function, so this error
couldn't have been detected by the compiler).
When not constructing a protocol tree, quit "dissect_ldap()" after
dissecting the first operation - we don't need to dissect the others.
svn path=/trunk/; revision=1768
2000-03-31 10:22:24 +00:00
|
|
|
return ASN1_ERR_WRONG_TYPE;
|
|
|
|
ret = parse_filter_strings(a, filter, filter_length, "<=");
|
|
|
|
if (ret != -1 && ret != ASN1_ERR_NOERROR)
|
|
|
|
return ret;
|
2000-03-29 09:25:21 +00:00
|
|
|
break;
|
|
|
|
case LDAP_FILTER_APPROX:
|
|
|
|
if (con != ASN1_CON)
|
Put in the beginnings of checks for ASN.1 dissection errors.
The "present" choice in the type Filter is, in LDAP V2,
AttributeType, and, in LDAP V3, it's AttributeDescription. Both of
those are just LDAPString, which is, in turn, OCTET STRING, so it should
be required to have the primitive representation (unless and until we
add support for the constructed representation of octet strings - but
RFC 1777, the LDAP V2 spec, says
(2) Bitstrings and octet strings and all character string types
will be encoded in the primitive form only.
and RFC 2251, the LDAP V3 spec, says
(2) OCTET STRING values will be encoded in the primitive form only.
so we shouldn't ever see it with the constructed representation), and be
parsed with "asn1_octet_string_value_decode()", as, by that point, we've
already dissected the ASN.1 id and length.
Put the bind authorization type into the protocol tree before switching
on the type, so that it goes in even if it's not something we yet
dissect, and actually pass it as an argument to "proto_tree_add_item()"
(alas, "proto_tree_add_item()" is a varargs function, so this error
couldn't have been detected by the compiler).
When not constructing a protocol tree, quit "dissect_ldap()" after
dissecting the first operation - we don't need to dissect the others.
svn path=/trunk/; revision=1768
2000-03-31 10:22:24 +00:00
|
|
|
return ASN1_ERR_WRONG_TYPE;
|
|
|
|
ret = parse_filter_strings(a, filter, filter_length, "~=");
|
2002-03-01 02:48:10 +00:00
|
|
|
if (ret != ASN1_ERR_NOERROR)
|
Put in the beginnings of checks for ASN.1 dissection errors.
The "present" choice in the type Filter is, in LDAP V2,
AttributeType, and, in LDAP V3, it's AttributeDescription. Both of
those are just LDAPString, which is, in turn, OCTET STRING, so it should
be required to have the primitive representation (unless and until we
add support for the constructed representation of octet strings - but
RFC 1777, the LDAP V2 spec, says
(2) Bitstrings and octet strings and all character string types
will be encoded in the primitive form only.
and RFC 2251, the LDAP V3 spec, says
(2) OCTET STRING values will be encoded in the primitive form only.
so we shouldn't ever see it with the constructed representation), and be
parsed with "asn1_octet_string_value_decode()", as, by that point, we've
already dissected the ASN.1 id and length.
Put the bind authorization type into the protocol tree before switching
on the type, so that it goes in even if it's not something we yet
dissect, and actually pass it as an argument to "proto_tree_add_item()"
(alas, "proto_tree_add_item()" is a varargs function, so this error
couldn't have been detected by the compiler).
When not constructing a protocol tree, quit "dissect_ldap()" after
dissecting the first operation - we don't need to dissect the others.
svn path=/trunk/; revision=1768
2000-03-31 10:22:24 +00:00
|
|
|
return ret;
|
2000-03-29 09:25:21 +00:00
|
|
|
break;
|
|
|
|
case LDAP_FILTER_PRESENT:
|
|
|
|
{
|
|
|
|
guchar *string;
|
2000-08-24 05:40:50 +00:00
|
|
|
char *filterp;
|
2000-03-28 07:12:36 +00:00
|
|
|
|
Put in the beginnings of checks for ASN.1 dissection errors.
The "present" choice in the type Filter is, in LDAP V2,
AttributeType, and, in LDAP V3, it's AttributeDescription. Both of
those are just LDAPString, which is, in turn, OCTET STRING, so it should
be required to have the primitive representation (unless and until we
add support for the constructed representation of octet strings - but
RFC 1777, the LDAP V2 spec, says
(2) Bitstrings and octet strings and all character string types
will be encoded in the primitive form only.
and RFC 2251, the LDAP V3 spec, says
(2) OCTET STRING values will be encoded in the primitive form only.
so we shouldn't ever see it with the constructed representation), and be
parsed with "asn1_octet_string_value_decode()", as, by that point, we've
already dissected the ASN.1 id and length.
Put the bind authorization type into the protocol tree before switching
on the type, so that it goes in even if it's not something we yet
dissect, and actually pass it as an argument to "proto_tree_add_item()"
(alas, "proto_tree_add_item()" is a varargs function, so this error
couldn't have been detected by the compiler).
When not constructing a protocol tree, quit "dissect_ldap()" after
dissecting the first operation - we don't need to dissect the others.
svn path=/trunk/; revision=1768
2000-03-31 10:22:24 +00:00
|
|
|
if (con != ASN1_PRI)
|
|
|
|
return ASN1_ERR_WRONG_TYPE;
|
2000-12-24 09:10:12 +00:00
|
|
|
ret = asn1_string_value_decode(a, length, &string);
|
Put in the beginnings of checks for ASN.1 dissection errors.
The "present" choice in the type Filter is, in LDAP V2,
AttributeType, and, in LDAP V3, it's AttributeDescription. Both of
those are just LDAPString, which is, in turn, OCTET STRING, so it should
be required to have the primitive representation (unless and until we
add support for the constructed representation of octet strings - but
RFC 1777, the LDAP V2 spec, says
(2) Bitstrings and octet strings and all character string types
will be encoded in the primitive form only.
and RFC 2251, the LDAP V3 spec, says
(2) OCTET STRING values will be encoded in the primitive form only.
so we shouldn't ever see it with the constructed representation), and be
parsed with "asn1_octet_string_value_decode()", as, by that point, we've
already dissected the ASN.1 id and length.
Put the bind authorization type into the protocol tree before switching
on the type, so that it goes in even if it's not something we yet
dissect, and actually pass it as an argument to "proto_tree_add_item()"
(alas, "proto_tree_add_item()" is a varargs function, so this error
couldn't have been detected by the compiler).
When not constructing a protocol tree, quit "dissect_ldap()" after
dissecting the first operation - we don't need to dissect the others.
svn path=/trunk/; revision=1768
2000-03-31 10:22:24 +00:00
|
|
|
if (ret != ASN1_ERR_NOERROR)
|
|
|
|
return ret;
|
2000-04-03 09:00:31 +00:00
|
|
|
*filter_length += 4 + length;
|
2000-03-29 09:25:21 +00:00
|
|
|
*filter = g_realloc(*filter, *filter_length);
|
2000-08-24 05:40:50 +00:00
|
|
|
filterp = *filter + strlen(*filter);
|
|
|
|
*filterp++ = '(';
|
|
|
|
if (length != 0) {
|
|
|
|
memcpy(filterp, string, length);
|
|
|
|
filterp += length;
|
|
|
|
}
|
|
|
|
*filterp++ = '=';
|
|
|
|
*filterp++ = '*';
|
|
|
|
*filterp++ = ')';
|
|
|
|
*filterp = '\0';
|
2000-03-29 09:25:21 +00:00
|
|
|
g_free(string);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case LDAP_FILTER_SUBSTRINGS:
|
|
|
|
if (con != ASN1_CON)
|
Put in the beginnings of checks for ASN.1 dissection errors.
The "present" choice in the type Filter is, in LDAP V2,
AttributeType, and, in LDAP V3, it's AttributeDescription. Both of
those are just LDAPString, which is, in turn, OCTET STRING, so it should
be required to have the primitive representation (unless and until we
add support for the constructed representation of octet strings - but
RFC 1777, the LDAP V2 spec, says
(2) Bitstrings and octet strings and all character string types
will be encoded in the primitive form only.
and RFC 2251, the LDAP V3 spec, says
(2) OCTET STRING values will be encoded in the primitive form only.
so we shouldn't ever see it with the constructed representation), and be
parsed with "asn1_octet_string_value_decode()", as, by that point, we've
already dissected the ASN.1 id and length.
Put the bind authorization type into the protocol tree before switching
on the type, so that it goes in even if it's not something we yet
dissect, and actually pass it as an argument to "proto_tree_add_item()"
(alas, "proto_tree_add_item()" is a varargs function, so this error
couldn't have been detected by the compiler).
When not constructing a protocol tree, quit "dissect_ldap()" after
dissecting the first operation - we don't need to dissect the others.
svn path=/trunk/; revision=1768
2000-03-31 10:22:24 +00:00
|
|
|
return ASN1_ERR_WRONG_TYPE;
|
2000-05-12 08:04:29 +00:00
|
|
|
/* Richard Dawe: Handle substrings */
|
|
|
|
ret = parse_filter_substrings(a, filter, filter_length);
|
2002-03-01 02:48:10 +00:00
|
|
|
if (ret != ASN1_ERR_NOERROR)
|
2000-05-12 08:04:29 +00:00
|
|
|
return ret;
|
2000-03-29 09:25:21 +00:00
|
|
|
break;
|
|
|
|
default:
|
Put in the beginnings of checks for ASN.1 dissection errors.
The "present" choice in the type Filter is, in LDAP V2,
AttributeType, and, in LDAP V3, it's AttributeDescription. Both of
those are just LDAPString, which is, in turn, OCTET STRING, so it should
be required to have the primitive representation (unless and until we
add support for the constructed representation of octet strings - but
RFC 1777, the LDAP V2 spec, says
(2) Bitstrings and octet strings and all character string types
will be encoded in the primitive form only.
and RFC 2251, the LDAP V3 spec, says
(2) OCTET STRING values will be encoded in the primitive form only.
so we shouldn't ever see it with the constructed representation), and be
parsed with "asn1_octet_string_value_decode()", as, by that point, we've
already dissected the ASN.1 id and length.
Put the bind authorization type into the protocol tree before switching
on the type, so that it goes in even if it's not something we yet
dissect, and actually pass it as an argument to "proto_tree_add_item()"
(alas, "proto_tree_add_item()" is a varargs function, so this error
couldn't have been detected by the compiler).
When not constructing a protocol tree, quit "dissect_ldap()" after
dissecting the first operation - we don't need to dissect the others.
svn path=/trunk/; revision=1768
2000-03-31 10:22:24 +00:00
|
|
|
return ASN1_ERR_WRONG_TYPE;
|
2000-03-28 07:12:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-04-15 07:30:03 +00:00
|
|
|
if (a->offset == *end)
|
Put in the beginnings of checks for ASN.1 dissection errors.
The "present" choice in the type Filter is, in LDAP V2,
AttributeType, and, in LDAP V3, it's AttributeDescription. Both of
those are just LDAPString, which is, in turn, OCTET STRING, so it should
be required to have the primitive representation (unless and until we
add support for the constructed representation of octet strings - but
RFC 1777, the LDAP V2 spec, says
(2) Bitstrings and octet strings and all character string types
will be encoded in the primitive form only.
and RFC 2251, the LDAP V3 spec, says
(2) OCTET STRING values will be encoded in the primitive form only.
so we shouldn't ever see it with the constructed representation), and be
parsed with "asn1_octet_string_value_decode()", as, by that point, we've
already dissected the ASN.1 id and length.
Put the bind authorization type into the protocol tree before switching
on the type, so that it goes in even if it's not something we yet
dissect, and actually pass it as an argument to "proto_tree_add_item()"
(alas, "proto_tree_add_item()" is a varargs function, so this error
couldn't have been detected by the compiler).
When not constructing a protocol tree, quit "dissect_ldap()" after
dissecting the first operation - we don't need to dissect the others.
svn path=/trunk/; revision=1768
2000-03-31 10:22:24 +00:00
|
|
|
return -1;
|
|
|
|
else
|
|
|
|
return ret;
|
2000-03-28 07:12:36 +00:00
|
|
|
}
|
|
|
|
|
2002-03-03 01:26:01 +00:00
|
|
|
static gboolean read_filter(ASN1_SCK *a, proto_tree *tree, int hf_id)
|
2000-03-28 07:12:36 +00:00
|
|
|
{
|
2001-04-15 07:30:03 +00:00
|
|
|
int start = a->offset;
|
2000-03-28 07:12:36 +00:00
|
|
|
char *filter = 0;
|
|
|
|
guint filter_length = 0;
|
2001-04-15 07:30:03 +00:00
|
|
|
int end = 0;
|
Put in the beginnings of checks for ASN.1 dissection errors.
The "present" choice in the type Filter is, in LDAP V2,
AttributeType, and, in LDAP V3, it's AttributeDescription. Both of
those are just LDAPString, which is, in turn, OCTET STRING, so it should
be required to have the primitive representation (unless and until we
add support for the constructed representation of octet strings - but
RFC 1777, the LDAP V2 spec, says
(2) Bitstrings and octet strings and all character string types
will be encoded in the primitive form only.
and RFC 2251, the LDAP V3 spec, says
(2) OCTET STRING values will be encoded in the primitive form only.
so we shouldn't ever see it with the constructed representation), and be
parsed with "asn1_octet_string_value_decode()", as, by that point, we've
already dissected the ASN.1 id and length.
Put the bind authorization type into the protocol tree before switching
on the type, so that it goes in even if it's not something we yet
dissect, and actually pass it as an argument to "proto_tree_add_item()"
(alas, "proto_tree_add_item()" is a varargs function, so this error
couldn't have been detected by the compiler).
When not constructing a protocol tree, quit "dissect_ldap()" after
dissecting the first operation - we don't need to dissect the others.
svn path=/trunk/; revision=1768
2000-03-31 10:22:24 +00:00
|
|
|
int ret;
|
2000-03-28 07:12:36 +00:00
|
|
|
|
Put in the beginnings of checks for ASN.1 dissection errors.
The "present" choice in the type Filter is, in LDAP V2,
AttributeType, and, in LDAP V3, it's AttributeDescription. Both of
those are just LDAPString, which is, in turn, OCTET STRING, so it should
be required to have the primitive representation (unless and until we
add support for the constructed representation of octet strings - but
RFC 1777, the LDAP V2 spec, says
(2) Bitstrings and octet strings and all character string types
will be encoded in the primitive form only.
and RFC 2251, the LDAP V3 spec, says
(2) OCTET STRING values will be encoded in the primitive form only.
so we shouldn't ever see it with the constructed representation), and be
parsed with "asn1_octet_string_value_decode()", as, by that point, we've
already dissected the ASN.1 id and length.
Put the bind authorization type into the protocol tree before switching
on the type, so that it goes in even if it's not something we yet
dissect, and actually pass it as an argument to "proto_tree_add_item()"
(alas, "proto_tree_add_item()" is a varargs function, so this error
couldn't have been detected by the compiler).
When not constructing a protocol tree, quit "dissect_ldap()" after
dissecting the first operation - we don't need to dissect the others.
svn path=/trunk/; revision=1768
2000-03-31 10:22:24 +00:00
|
|
|
while ((ret = parse_filter(a, &filter, &filter_length, &end))
|
|
|
|
== ASN1_ERR_NOERROR)
|
2000-03-28 07:12:36 +00:00
|
|
|
continue;
|
Put in the beginnings of checks for ASN.1 dissection errors.
The "present" choice in the type Filter is, in LDAP V2,
AttributeType, and, in LDAP V3, it's AttributeDescription. Both of
those are just LDAPString, which is, in turn, OCTET STRING, so it should
be required to have the primitive representation (unless and until we
add support for the constructed representation of octet strings - but
RFC 1777, the LDAP V2 spec, says
(2) Bitstrings and octet strings and all character string types
will be encoded in the primitive form only.
and RFC 2251, the LDAP V3 spec, says
(2) OCTET STRING values will be encoded in the primitive form only.
so we shouldn't ever see it with the constructed representation), and be
parsed with "asn1_octet_string_value_decode()", as, by that point, we've
already dissected the ASN.1 id and length.
Put the bind authorization type into the protocol tree before switching
on the type, so that it goes in even if it's not something we yet
dissect, and actually pass it as an argument to "proto_tree_add_item()"
(alas, "proto_tree_add_item()" is a varargs function, so this error
couldn't have been detected by the compiler).
When not constructing a protocol tree, quit "dissect_ldap()" after
dissecting the first operation - we don't need to dissect the others.
svn path=/trunk/; revision=1768
2000-03-31 10:22:24 +00:00
|
|
|
|
|
|
|
if (tree) {
|
|
|
|
if (ret != -1) {
|
2001-04-15 07:30:03 +00:00
|
|
|
proto_tree_add_text(tree, a->tvb, start, 0,
|
2002-03-03 01:26:01 +00:00
|
|
|
"%s: ERROR: Can't parse filter: %s",
|
|
|
|
proto_registrar_get_name(hf_id), asn1_err_to_str(ret));
|
Put in the beginnings of checks for ASN.1 dissection errors.
The "present" choice in the type Filter is, in LDAP V2,
AttributeType, and, in LDAP V3, it's AttributeDescription. Both of
those are just LDAPString, which is, in turn, OCTET STRING, so it should
be required to have the primitive representation (unless and until we
add support for the constructed representation of octet strings - but
RFC 1777, the LDAP V2 spec, says
(2) Bitstrings and octet strings and all character string types
will be encoded in the primitive form only.
and RFC 2251, the LDAP V3 spec, says
(2) OCTET STRING values will be encoded in the primitive form only.
so we shouldn't ever see it with the constructed representation), and be
parsed with "asn1_octet_string_value_decode()", as, by that point, we've
already dissected the ASN.1 id and length.
Put the bind authorization type into the protocol tree before switching
on the type, so that it goes in even if it's not something we yet
dissect, and actually pass it as an argument to "proto_tree_add_item()"
(alas, "proto_tree_add_item()" is a varargs function, so this error
couldn't have been detected by the compiler).
When not constructing a protocol tree, quit "dissect_ldap()" after
dissecting the first operation - we don't need to dissect the others.
svn path=/trunk/; revision=1768
2000-03-31 10:22:24 +00:00
|
|
|
} else
|
2001-04-15 07:30:03 +00:00
|
|
|
proto_tree_add_string(tree, hf_id, a->tvb, start, a->offset-start, filter);
|
Put in the beginnings of checks for ASN.1 dissection errors.
The "present" choice in the type Filter is, in LDAP V2,
AttributeType, and, in LDAP V3, it's AttributeDescription. Both of
those are just LDAPString, which is, in turn, OCTET STRING, so it should
be required to have the primitive representation (unless and until we
add support for the constructed representation of octet strings - but
RFC 1777, the LDAP V2 spec, says
(2) Bitstrings and octet strings and all character string types
will be encoded in the primitive form only.
and RFC 2251, the LDAP V3 spec, says
(2) OCTET STRING values will be encoded in the primitive form only.
so we shouldn't ever see it with the constructed representation), and be
parsed with "asn1_octet_string_value_decode()", as, by that point, we've
already dissected the ASN.1 id and length.
Put the bind authorization type into the protocol tree before switching
on the type, so that it goes in even if it's not something we yet
dissect, and actually pass it as an argument to "proto_tree_add_item()"
(alas, "proto_tree_add_item()" is a varargs function, so this error
couldn't have been detected by the compiler).
When not constructing a protocol tree, quit "dissect_ldap()" after
dissecting the first operation - we don't need to dissect the others.
svn path=/trunk/; revision=1768
2000-03-31 10:22:24 +00:00
|
|
|
}
|
2000-03-28 07:12:36 +00:00
|
|
|
|
|
|
|
g_free(filter);
|
|
|
|
|
2002-03-03 01:26:01 +00:00
|
|
|
return (ret == -1) ? TRUE : FALSE;
|
2000-03-28 07:12:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************************************/
|
|
|
|
|
2002-03-03 01:26:01 +00:00
|
|
|
static void dissect_ldap_result(ASN1_SCK *a, proto_tree *tree)
|
2000-03-28 07:12:36 +00:00
|
|
|
{
|
|
|
|
guint resultCode = 0;
|
2002-03-01 02:48:10 +00:00
|
|
|
int ret;
|
2000-03-28 07:12:36 +00:00
|
|
|
|
2002-03-03 01:26:01 +00:00
|
|
|
if (read_integer(a, tree, hf_ldap_message_result, 0, &resultCode, ASN1_ENUM) != ASN1_ERR_NOERROR)
|
|
|
|
return;
|
|
|
|
if (read_string(a, tree, hf_ldap_message_result_matcheddn, 0, 0, ASN1_UNI, ASN1_OTS) != ASN1_ERR_NOERROR)
|
|
|
|
return;
|
|
|
|
if (read_string(a, tree, hf_ldap_message_result_errormsg, 0, 0, ASN1_UNI, ASN1_OTS) != ASN1_ERR_NOERROR)
|
|
|
|
return;
|
2000-03-28 07:12:36 +00:00
|
|
|
|
|
|
|
if (resultCode == 10) /* Referral */
|
|
|
|
{
|
2001-04-15 07:30:03 +00:00
|
|
|
int start = a->offset;
|
|
|
|
int end;
|
2000-03-28 07:12:36 +00:00
|
|
|
guint length;
|
2002-03-01 02:48:10 +00:00
|
|
|
proto_item *ti;
|
|
|
|
proto_tree *referralTree;
|
2000-03-28 07:12:36 +00:00
|
|
|
|
2002-03-01 02:48:10 +00:00
|
|
|
ret = read_sequence(a, &length);
|
2002-03-03 01:26:01 +00:00
|
|
|
if (ret != ASN1_ERR_NOERROR) {
|
|
|
|
if (tree) {
|
|
|
|
proto_tree_add_text(tree, a->tvb, start, 0,
|
|
|
|
"ERROR: Couldn't parse referral URL sequence header: %s",
|
|
|
|
asn1_err_to_str(ret));
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
2002-03-01 02:48:10 +00:00
|
|
|
ti = proto_tree_add_text(tree, a->tvb, start, length, "Referral URLs");
|
|
|
|
referralTree = proto_item_add_subtree(ti, ett_ldap_referrals);
|
2000-03-28 07:12:36 +00:00
|
|
|
|
2001-04-15 07:30:03 +00:00
|
|
|
end = a->offset + length;
|
2002-03-01 02:48:10 +00:00
|
|
|
while (a->offset < end) {
|
2002-03-03 01:26:01 +00:00
|
|
|
if (read_string(a, referralTree, hf_ldap_message_result_referral, 0, 0, ASN1_UNI, ASN1_OTS) != ASN1_ERR_NOERROR)
|
|
|
|
return;
|
2002-03-01 02:48:10 +00:00
|
|
|
}
|
2000-03-28 07:12:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-03-03 01:26:01 +00:00
|
|
|
static void dissect_ldap_request_bind(ASN1_SCK *a, proto_tree *tree)
|
2000-03-28 07:12:36 +00:00
|
|
|
{
|
2000-03-29 09:25:21 +00:00
|
|
|
guint cls, con, tag;
|
|
|
|
guint def, length;
|
2001-04-15 07:30:03 +00:00
|
|
|
int start;
|
2002-03-01 02:48:10 +00:00
|
|
|
int ret;
|
2000-03-28 07:12:36 +00:00
|
|
|
|
2002-03-03 01:26:01 +00:00
|
|
|
if (read_integer(a, tree, hf_ldap_message_bind_version, 0, 0, ASN1_INT) != ASN1_ERR_NOERROR)
|
|
|
|
return;
|
|
|
|
if (read_string(a, tree, hf_ldap_message_bind_dn, 0, 0, ASN1_UNI, ASN1_OTS) != ASN1_ERR_NOERROR)
|
|
|
|
return;
|
2000-03-29 09:25:21 +00:00
|
|
|
|
2001-04-15 07:30:03 +00:00
|
|
|
start = a->offset;
|
2002-03-01 02:48:10 +00:00
|
|
|
ret = asn1_header_decode(a, &cls, &con, &tag, &def, &length);
|
2002-03-03 01:26:01 +00:00
|
|
|
if (ret == ASN1_ERR_NOERROR) {
|
|
|
|
if (cls != ASN1_CTX) {
|
|
|
|
/* RFCs 1777 and 2251 say these are context-specific types */
|
|
|
|
ret = ASN1_ERR_WRONG_TYPE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (ret != ASN1_ERR_NOERROR) {
|
|
|
|
proto_tree_add_text(tree, a->tvb, start, 0,
|
|
|
|
"%s: ERROR: Couldn't parse header: %s",
|
|
|
|
proto_registrar_get_name(hf_ldap_message_bind_auth),
|
|
|
|
asn1_err_to_str(ret));
|
|
|
|
return;
|
|
|
|
}
|
2001-04-15 07:30:03 +00:00
|
|
|
proto_tree_add_uint(tree, hf_ldap_message_bind_auth, a->tvb, start,
|
|
|
|
a->offset - start, tag);
|
2000-03-29 09:25:21 +00:00
|
|
|
switch (tag)
|
2000-03-28 07:12:36 +00:00
|
|
|
{
|
|
|
|
case LDAP_AUTH_SIMPLE:
|
2002-03-03 01:26:01 +00:00
|
|
|
if (read_string_value(a, tree, hf_ldap_message_bind_auth_password, NULL,
|
|
|
|
NULL, start, length) != ASN1_ERR_NOERROR)
|
|
|
|
return;
|
2000-03-28 07:12:36 +00:00
|
|
|
break;
|
2000-03-29 09:25:21 +00:00
|
|
|
|
|
|
|
/* For Kerberos V4, dissect it as a ticket. */
|
|
|
|
/* For SASL, dissect it as SaslCredentials. */
|
2000-03-28 07:12:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-03-03 01:26:01 +00:00
|
|
|
static void dissect_ldap_response_bind(ASN1_SCK *a, proto_tree *tree)
|
2000-03-28 07:12:36 +00:00
|
|
|
{
|
|
|
|
/* FIXME: handle SASL data */
|
2002-03-03 01:26:01 +00:00
|
|
|
dissect_ldap_result(a, tree);
|
2000-03-28 07:12:36 +00:00
|
|
|
}
|
|
|
|
|
2002-03-03 01:26:01 +00:00
|
|
|
static void dissect_ldap_request_search(ASN1_SCK *a, proto_tree *tree)
|
2000-03-28 07:12:36 +00:00
|
|
|
{
|
|
|
|
guint seq_length;
|
2001-04-15 07:30:03 +00:00
|
|
|
int end;
|
Put in the beginnings of checks for ASN.1 dissection errors.
The "present" choice in the type Filter is, in LDAP V2,
AttributeType, and, in LDAP V3, it's AttributeDescription. Both of
those are just LDAPString, which is, in turn, OCTET STRING, so it should
be required to have the primitive representation (unless and until we
add support for the constructed representation of octet strings - but
RFC 1777, the LDAP V2 spec, says
(2) Bitstrings and octet strings and all character string types
will be encoded in the primitive form only.
and RFC 2251, the LDAP V3 spec, says
(2) OCTET STRING values will be encoded in the primitive form only.
so we shouldn't ever see it with the constructed representation), and be
parsed with "asn1_octet_string_value_decode()", as, by that point, we've
already dissected the ASN.1 id and length.
Put the bind authorization type into the protocol tree before switching
on the type, so that it goes in even if it's not something we yet
dissect, and actually pass it as an argument to "proto_tree_add_item()"
(alas, "proto_tree_add_item()" is a varargs function, so this error
couldn't have been detected by the compiler).
When not constructing a protocol tree, quit "dissect_ldap()" after
dissecting the first operation - we don't need to dissect the others.
svn path=/trunk/; revision=1768
2000-03-31 10:22:24 +00:00
|
|
|
int ret;
|
2000-03-28 07:12:36 +00:00
|
|
|
|
2002-03-03 01:26:01 +00:00
|
|
|
if (read_string(a, tree, hf_ldap_message_search_base, 0, 0, ASN1_UNI, ASN1_OTS) != ASN1_ERR_NOERROR)
|
|
|
|
return;
|
|
|
|
if (read_integer(a, tree, hf_ldap_message_search_scope, 0, 0, ASN1_ENUM) != ASN1_ERR_NOERROR)
|
|
|
|
return;
|
|
|
|
if (read_integer(a, tree, hf_ldap_message_search_deref, 0, 0, ASN1_ENUM) != ASN1_ERR_NOERROR)
|
|
|
|
return;
|
|
|
|
if (read_integer(a, tree, hf_ldap_message_search_sizeLimit, 0, 0, ASN1_INT) != ASN1_ERR_NOERROR)
|
|
|
|
return;
|
|
|
|
if (read_integer(a, tree, hf_ldap_message_search_timeLimit, 0, 0, ASN1_INT) != ASN1_ERR_NOERROR)
|
|
|
|
return;
|
|
|
|
if (read_boolean(a, tree, hf_ldap_message_search_typesOnly, 0, 0) != ASN1_ERR_NOERROR)
|
|
|
|
return;
|
|
|
|
if (!read_filter(a, tree, hf_ldap_message_search_filter))
|
|
|
|
return;
|
2002-03-01 02:48:10 +00:00
|
|
|
ret = read_sequence(a, &seq_length);
|
2002-03-03 01:26:01 +00:00
|
|
|
if (ret != ASN1_ERR_NOERROR) {
|
|
|
|
if (tree) {
|
|
|
|
proto_tree_add_text(tree, a->tvb, a->offset, 0,
|
|
|
|
"ERROR: Couldn't parse LDAP attribute sequence header: %s",
|
|
|
|
asn1_err_to_str(ret));
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
2001-04-15 07:30:03 +00:00
|
|
|
end = a->offset + seq_length;
|
|
|
|
while (a->offset < end) {
|
2002-03-03 01:26:01 +00:00
|
|
|
if (read_string(a, tree, hf_ldap_message_attribute, 0, 0, ASN1_UNI,
|
|
|
|
ASN1_OTS) != ASN1_ERR_NOERROR)
|
|
|
|
return;
|
Put in the beginnings of checks for ASN.1 dissection errors.
The "present" choice in the type Filter is, in LDAP V2,
AttributeType, and, in LDAP V3, it's AttributeDescription. Both of
those are just LDAPString, which is, in turn, OCTET STRING, so it should
be required to have the primitive representation (unless and until we
add support for the constructed representation of octet strings - but
RFC 1777, the LDAP V2 spec, says
(2) Bitstrings and octet strings and all character string types
will be encoded in the primitive form only.
and RFC 2251, the LDAP V3 spec, says
(2) OCTET STRING values will be encoded in the primitive form only.
so we shouldn't ever see it with the constructed representation), and be
parsed with "asn1_octet_string_value_decode()", as, by that point, we've
already dissected the ASN.1 id and length.
Put the bind authorization type into the protocol tree before switching
on the type, so that it goes in even if it's not something we yet
dissect, and actually pass it as an argument to "proto_tree_add_item()"
(alas, "proto_tree_add_item()" is a varargs function, so this error
couldn't have been detected by the compiler).
When not constructing a protocol tree, quit "dissect_ldap()" after
dissecting the first operation - we don't need to dissect the others.
svn path=/trunk/; revision=1768
2000-03-31 10:22:24 +00:00
|
|
|
}
|
2000-03-28 07:12:36 +00:00
|
|
|
}
|
|
|
|
|
2002-03-03 01:26:01 +00:00
|
|
|
static void dissect_ldap_response_search_entry(ASN1_SCK *a, proto_tree *tree)
|
2000-03-28 07:12:36 +00:00
|
|
|
{
|
|
|
|
guint seq_length;
|
2001-04-15 07:30:03 +00:00
|
|
|
int end_of_sequence;
|
2002-03-01 02:48:10 +00:00
|
|
|
int ret;
|
2000-03-28 07:12:36 +00:00
|
|
|
|
2002-03-03 01:26:01 +00:00
|
|
|
if (read_string(a, tree, hf_ldap_message_dn, 0, 0, ASN1_UNI, ASN1_OTS) != ASN1_ERR_NOERROR)
|
|
|
|
return;
|
2002-03-01 02:48:10 +00:00
|
|
|
ret = read_sequence(a, &seq_length);
|
2002-03-03 01:26:01 +00:00
|
|
|
if (ret != ASN1_ERR_NOERROR) {
|
|
|
|
if (tree) {
|
|
|
|
proto_tree_add_text(tree, a->tvb, a->offset, 0,
|
|
|
|
"ERROR: Couldn't parse search entry response sequence header: %s",
|
|
|
|
asn1_err_to_str(ret));
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
2000-03-28 07:12:36 +00:00
|
|
|
|
2001-04-15 07:30:03 +00:00
|
|
|
end_of_sequence = a->offset + seq_length;
|
|
|
|
while (a->offset < end_of_sequence)
|
2000-03-28 07:12:36 +00:00
|
|
|
{
|
2002-03-01 02:48:10 +00:00
|
|
|
proto_item *ti;
|
|
|
|
proto_tree *attr_tree;
|
2000-03-28 07:12:36 +00:00
|
|
|
guint set_length;
|
2001-04-15 07:30:03 +00:00
|
|
|
int end_of_set;
|
2000-03-28 07:12:36 +00:00
|
|
|
|
2002-03-01 02:48:10 +00:00
|
|
|
ret = read_sequence(a, 0);
|
2002-03-03 01:26:01 +00:00
|
|
|
if (ret != ASN1_ERR_NOERROR) {
|
|
|
|
if (tree) {
|
|
|
|
proto_tree_add_text(tree, a->tvb, a->offset, 0,
|
|
|
|
"ERROR: Couldn't parse LDAP attribute sequence header: %s",
|
|
|
|
asn1_err_to_str(ret));
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (read_string(a, tree, hf_ldap_message_attribute, &ti, 0, ASN1_UNI, ASN1_OTS) != ASN1_ERR_NOERROR)
|
|
|
|
return;
|
2002-03-01 02:48:10 +00:00
|
|
|
attr_tree = proto_item_add_subtree(ti, ett_ldap_attribute);
|
2000-03-28 07:12:36 +00:00
|
|
|
|
2002-03-01 02:48:10 +00:00
|
|
|
ret = read_set(a, &set_length);
|
2002-03-03 01:26:01 +00:00
|
|
|
if (ret != ASN1_ERR_NOERROR) {
|
|
|
|
if (tree) {
|
|
|
|
proto_tree_add_text(attr_tree, a->tvb, a->offset, 0,
|
|
|
|
"ERROR: Couldn't parse LDAP value set header: %s",
|
|
|
|
asn1_err_to_str(ret));
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
2001-04-15 07:30:03 +00:00
|
|
|
end_of_set = a->offset + set_length;
|
2002-03-01 02:48:10 +00:00
|
|
|
while (a->offset < end_of_set) {
|
2002-03-03 01:26:01 +00:00
|
|
|
if (read_string(a, attr_tree, hf_ldap_message_value, 0, 0, ASN1_UNI,
|
|
|
|
ASN1_OTS) != ASN1_ERR_NOERROR)
|
|
|
|
return;
|
2002-03-01 02:48:10 +00:00
|
|
|
}
|
2000-03-28 07:12:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-03-03 01:26:01 +00:00
|
|
|
static void dissect_ldap_request_add(ASN1_SCK *a, proto_tree *tree)
|
2000-03-28 07:12:36 +00:00
|
|
|
{
|
|
|
|
guint seq_length;
|
2001-04-15 07:30:03 +00:00
|
|
|
int end_of_sequence;
|
2002-03-01 02:48:10 +00:00
|
|
|
int ret;
|
2000-03-28 07:12:36 +00:00
|
|
|
|
2002-03-03 01:26:01 +00:00
|
|
|
if (read_string(a, tree, hf_ldap_message_dn, 0, 0, ASN1_UNI, ASN1_OTS) != ASN1_ERR_NOERROR)
|
|
|
|
return;
|
2000-03-28 07:12:36 +00:00
|
|
|
|
2002-03-01 02:48:10 +00:00
|
|
|
ret = read_sequence(a, &seq_length);
|
2002-03-03 01:26:01 +00:00
|
|
|
if (ret != ASN1_ERR_NOERROR) {
|
|
|
|
if (tree) {
|
|
|
|
proto_tree_add_text(tree, a->tvb, a->offset, 0,
|
|
|
|
"ERROR: Couldn't parse add request sequence header: %s",
|
|
|
|
asn1_err_to_str(ret));
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2001-04-15 07:30:03 +00:00
|
|
|
end_of_sequence = a->offset + seq_length;
|
|
|
|
while (a->offset < end_of_sequence)
|
2000-03-28 07:12:36 +00:00
|
|
|
{
|
2002-03-01 02:48:10 +00:00
|
|
|
proto_item *ti;
|
|
|
|
proto_tree *attr_tree;
|
2000-03-28 07:12:36 +00:00
|
|
|
guint set_length;
|
2001-04-15 07:30:03 +00:00
|
|
|
int end_of_set;
|
2000-03-28 07:12:36 +00:00
|
|
|
|
2002-03-01 02:48:10 +00:00
|
|
|
ret = read_sequence(a, 0);
|
2002-03-03 01:26:01 +00:00
|
|
|
if (ret != ASN1_ERR_NOERROR) {
|
|
|
|
if (tree) {
|
|
|
|
proto_tree_add_text(tree, a->tvb, a->offset, 0,
|
|
|
|
"ERROR: Couldn't parse LDAP attribute sequence header: %s",
|
|
|
|
asn1_err_to_str(ret));
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (read_string(a, tree, hf_ldap_message_attribute, &ti, 0, ASN1_UNI,
|
|
|
|
ASN1_OTS) != ASN1_ERR_NOERROR)
|
|
|
|
return;
|
2002-03-01 02:48:10 +00:00
|
|
|
attr_tree = proto_item_add_subtree(ti, ett_ldap_attribute);
|
2000-03-28 07:12:36 +00:00
|
|
|
|
2002-03-01 02:48:10 +00:00
|
|
|
ret = read_set(a, &set_length);
|
2002-03-03 01:26:01 +00:00
|
|
|
if (ret != ASN1_ERR_NOERROR) {
|
|
|
|
if (tree) {
|
|
|
|
proto_tree_add_text(attr_tree, a->tvb, a->offset, 0,
|
|
|
|
"ERROR: Couldn't parse LDAP value set header: %s",
|
|
|
|
asn1_err_to_str(ret));
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
2001-04-15 07:30:03 +00:00
|
|
|
end_of_set = a->offset + set_length;
|
2002-03-01 02:48:10 +00:00
|
|
|
while (a->offset < end_of_set) {
|
2002-03-03 01:26:01 +00:00
|
|
|
if (read_string(a, attr_tree, hf_ldap_message_value, 0, 0, ASN1_UNI, ASN1_OTS) != ASN1_ERR_NOERROR)
|
|
|
|
return;
|
2002-03-01 02:48:10 +00:00
|
|
|
}
|
2000-03-28 07:12:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-03-03 01:26:01 +00:00
|
|
|
static void dissect_ldap_request_delete(ASN1_SCK *a, proto_tree *tree,
|
2001-04-15 07:30:03 +00:00
|
|
|
int start, guint length)
|
2000-03-28 07:12:36 +00:00
|
|
|
{
|
2002-03-03 01:26:01 +00:00
|
|
|
read_string_value(a, tree, hf_ldap_message_dn, NULL, NULL, start, length);
|
2000-03-28 07:12:36 +00:00
|
|
|
}
|
|
|
|
|
2002-03-03 01:26:01 +00:00
|
|
|
static void dissect_ldap_request_modifyrdn(ASN1_SCK *a, proto_tree *tree,
|
2000-03-29 09:25:21 +00:00
|
|
|
guint length)
|
2000-03-28 07:12:36 +00:00
|
|
|
{
|
2001-04-15 07:30:03 +00:00
|
|
|
int start = a->offset;
|
2000-03-28 07:12:36 +00:00
|
|
|
|
2002-03-03 01:26:01 +00:00
|
|
|
if (read_string(a, tree, hf_ldap_message_dn, 0, 0, ASN1_UNI, ASN1_OTS) != ASN1_ERR_NOERROR)
|
|
|
|
return;
|
|
|
|
if (read_string(a, tree, hf_ldap_message_modrdn_name, 0, 0, ASN1_UNI, ASN1_OTS) != ASN1_ERR_NOERROR)
|
|
|
|
return;
|
|
|
|
if (read_boolean(a, tree, hf_ldap_message_modrdn_delete, 0, 0) != ASN1_ERR_NOERROR)
|
|
|
|
return;
|
2000-03-28 07:12:36 +00:00
|
|
|
|
2001-10-26 18:28:17 +00:00
|
|
|
if (a->offset < (int) (start + length)) {
|
2000-03-29 09:25:21 +00:00
|
|
|
/* LDAP V3 Modify DN operation, with newSuperior */
|
2002-03-03 01:26:01 +00:00
|
|
|
if (read_string(a, tree, hf_ldap_message_modrdn_superior, 0, 0, ASN1_UNI, ASN1_OTS) != ASN1_ERR_NOERROR)
|
|
|
|
return;
|
2000-03-29 09:25:21 +00:00
|
|
|
}
|
2000-03-28 07:12:36 +00:00
|
|
|
}
|
|
|
|
|
2002-03-03 01:26:01 +00:00
|
|
|
static void dissect_ldap_request_compare(ASN1_SCK *a, proto_tree *tree)
|
2000-03-28 07:12:36 +00:00
|
|
|
{
|
2001-04-15 07:30:03 +00:00
|
|
|
int start;
|
2000-03-28 07:12:36 +00:00
|
|
|
int length;
|
|
|
|
char *string1 = 0;
|
|
|
|
char *string2 = 0;
|
|
|
|
char *compare;
|
2002-03-01 02:48:10 +00:00
|
|
|
int ret;
|
2000-03-28 07:12:36 +00:00
|
|
|
|
2002-03-03 01:26:01 +00:00
|
|
|
if (read_string(a, tree, hf_ldap_message_dn, 0, 0, ASN1_UNI, ASN1_OTS) != ASN1_ERR_NOERROR)
|
|
|
|
return;
|
2002-03-01 02:48:10 +00:00
|
|
|
ret = read_sequence(a, 0);
|
2002-03-03 01:26:01 +00:00
|
|
|
if (ret != ASN1_ERR_NOERROR) {
|
|
|
|
if (tree) {
|
|
|
|
proto_tree_add_text(tree, a->tvb, a->offset, 0,
|
|
|
|
"ERROR: Couldn't parse compare request sequence header: %s",
|
|
|
|
asn1_err_to_str(ret));
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
2000-03-28 07:12:36 +00:00
|
|
|
|
2001-04-15 07:30:03 +00:00
|
|
|
start = a->offset;
|
2002-03-01 02:48:10 +00:00
|
|
|
ret = read_string(a, 0, -1, 0, &string1, ASN1_UNI, ASN1_OTS);
|
2002-03-03 01:26:01 +00:00
|
|
|
if (ret != ASN1_ERR_NOERROR) {
|
|
|
|
if (tree) {
|
|
|
|
proto_tree_add_text(tree, a->tvb, start, 0,
|
|
|
|
"ERROR: Couldn't parse compare type: %s", asn1_err_to_str(ret));
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
2002-03-01 02:48:10 +00:00
|
|
|
ret = read_string(a, 0, -1, 0, &string2, ASN1_UNI, ASN1_OTS);
|
2002-03-03 01:26:01 +00:00
|
|
|
if (ret != ASN1_ERR_NOERROR) {
|
|
|
|
if (tree) {
|
|
|
|
proto_tree_add_text(tree, a->tvb, start, 0,
|
|
|
|
"ERROR: Couldn't parse compare value: %s", asn1_err_to_str(ret));
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
2001-05-08 19:46:32 +00:00
|
|
|
|
2000-03-28 07:12:36 +00:00
|
|
|
length = 2 + strlen(string1) + strlen(string2);
|
|
|
|
compare = g_malloc0(length);
|
|
|
|
snprintf(compare, length, "%s=%s", string1, string2);
|
2001-04-15 07:30:03 +00:00
|
|
|
proto_tree_add_string(tree, hf_ldap_message_compare, a->tvb, start,
|
|
|
|
a->offset-start, compare);
|
2000-03-28 07:12:36 +00:00
|
|
|
|
|
|
|
g_free(string1);
|
|
|
|
g_free(string2);
|
|
|
|
g_free(compare);
|
|
|
|
|
2002-03-03 01:26:01 +00:00
|
|
|
return;
|
2000-03-28 07:12:36 +00:00
|
|
|
}
|
|
|
|
|
2002-03-03 01:26:01 +00:00
|
|
|
static void dissect_ldap_request_modify(ASN1_SCK *a, proto_tree *tree)
|
2000-03-28 07:12:36 +00:00
|
|
|
{
|
|
|
|
guint seq_length;
|
2001-04-15 07:30:03 +00:00
|
|
|
int end_of_sequence;
|
2002-03-01 02:48:10 +00:00
|
|
|
int ret;
|
2000-03-28 07:12:36 +00:00
|
|
|
|
2002-03-03 01:26:01 +00:00
|
|
|
if (read_string(a, tree, hf_ldap_message_dn, 0, 0, ASN1_UNI, ASN1_OTS) != ASN1_ERR_NOERROR)
|
|
|
|
return;
|
2002-03-01 02:48:10 +00:00
|
|
|
ret = read_sequence(a, &seq_length);
|
2002-03-03 01:26:01 +00:00
|
|
|
if (ret != ASN1_ERR_NOERROR) {
|
|
|
|
if (tree) {
|
|
|
|
proto_tree_add_text(tree, a->tvb, a->offset, 0,
|
|
|
|
"ERROR: Couldn't parse modify request sequence header: %s",
|
|
|
|
asn1_err_to_str(ret));
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
2001-04-15 07:30:03 +00:00
|
|
|
end_of_sequence = a->offset + seq_length;
|
|
|
|
while (a->offset < end_of_sequence)
|
2000-03-28 07:12:36 +00:00
|
|
|
{
|
2002-03-01 02:48:10 +00:00
|
|
|
proto_item *ti;
|
|
|
|
proto_tree *attr_tree;
|
2000-03-28 07:12:36 +00:00
|
|
|
guint set_length;
|
2001-04-15 07:30:03 +00:00
|
|
|
int end_of_set;
|
2000-03-28 07:12:36 +00:00
|
|
|
guint operation;
|
|
|
|
|
2002-03-01 02:48:10 +00:00
|
|
|
ret = read_sequence(a, 0);
|
2002-03-03 01:26:01 +00:00
|
|
|
if (ret != ASN1_ERR_NOERROR) {
|
|
|
|
if (tree) {
|
|
|
|
proto_tree_add_text(tree, a->tvb, a->offset, 0,
|
|
|
|
"ERROR: Couldn't parse modify request item sequence header: %s",
|
|
|
|
asn1_err_to_str(ret));
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
2002-03-01 02:48:10 +00:00
|
|
|
ret = read_integer(a, 0, -1, 0, &operation, ASN1_ENUM);
|
2002-03-03 01:26:01 +00:00
|
|
|
if (ret != ASN1_ERR_NOERROR) {
|
|
|
|
if (tree) {
|
|
|
|
proto_tree_add_text(tree, a->tvb, a->offset, 0,
|
|
|
|
"ERROR: Couldn't parse modify operation: %s",
|
|
|
|
asn1_err_to_str(ret));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2002-03-01 02:48:10 +00:00
|
|
|
ret = read_sequence(a, 0);
|
2002-03-03 01:26:01 +00:00
|
|
|
if (ret != ASN1_ERR_NOERROR) {
|
|
|
|
if (tree) {
|
|
|
|
proto_tree_add_text(tree, a->tvb, a->offset, 0,
|
|
|
|
"ERROR: Couldn't parse modify request operation sequence header: %s",
|
|
|
|
asn1_err_to_str(ret));
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
2000-03-28 07:12:36 +00:00
|
|
|
|
|
|
|
switch (operation)
|
|
|
|
{
|
|
|
|
case LDAP_MOD_ADD:
|
2002-03-03 01:26:01 +00:00
|
|
|
if (read_string(a, tree, hf_ldap_message_modify_add, &ti, 0, ASN1_UNI,
|
|
|
|
ASN1_OTS) != ASN1_ERR_NOERROR)
|
|
|
|
return;
|
2000-03-28 07:12:36 +00:00
|
|
|
break;
|
2002-03-01 03:02:36 +00:00
|
|
|
|
2000-03-28 07:12:36 +00:00
|
|
|
case LDAP_MOD_REPLACE:
|
2002-03-03 01:26:01 +00:00
|
|
|
if (read_string(a, tree, hf_ldap_message_modify_replace, &ti, 0,
|
|
|
|
ASN1_UNI, ASN1_OTS) != ASN1_ERR_NOERROR)
|
|
|
|
return;
|
2000-03-28 07:12:36 +00:00
|
|
|
break;
|
2002-03-01 03:02:36 +00:00
|
|
|
|
2000-03-28 07:12:36 +00:00
|
|
|
case LDAP_MOD_DELETE:
|
2002-03-03 01:26:01 +00:00
|
|
|
if (read_string(a, tree, hf_ldap_message_modify_delete, &ti, 0,
|
|
|
|
ASN1_UNI, ASN1_OTS) != ASN1_ERR_NOERROR)
|
|
|
|
return;
|
2000-03-28 07:12:36 +00:00
|
|
|
break;
|
2002-03-01 03:02:36 +00:00
|
|
|
|
|
|
|
default:
|
|
|
|
proto_tree_add_text(tree, a->tvb, a->offset, 0,
|
|
|
|
"Unknown LDAP modify operation (%u)", operation);
|
2002-03-03 01:26:01 +00:00
|
|
|
return;
|
2000-03-28 07:12:36 +00:00
|
|
|
}
|
2002-03-01 02:48:10 +00:00
|
|
|
attr_tree = proto_item_add_subtree(ti, ett_ldap_attribute);
|
2000-03-28 07:12:36 +00:00
|
|
|
|
2002-03-01 02:48:10 +00:00
|
|
|
ret = read_set(a, &set_length);
|
2002-03-03 01:26:01 +00:00
|
|
|
if (ret != ASN1_ERR_NOERROR) {
|
|
|
|
if (tree) {
|
|
|
|
proto_tree_add_text(attr_tree, a->tvb, a->offset, 0,
|
|
|
|
"ERROR: Couldn't parse LDAP value set header: %s",
|
|
|
|
asn1_err_to_str(ret));
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
2001-04-15 07:30:03 +00:00
|
|
|
end_of_set = a->offset + set_length;
|
2002-03-01 02:48:10 +00:00
|
|
|
while (a->offset < end_of_set) {
|
2002-03-03 01:26:01 +00:00
|
|
|
if (read_string(a, attr_tree, hf_ldap_message_value, 0, 0, ASN1_UNI,
|
|
|
|
ASN1_OTS) != ASN1_ERR_NOERROR)
|
|
|
|
return;
|
2002-03-01 02:48:10 +00:00
|
|
|
}
|
2000-03-28 07:12:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-03-03 01:26:01 +00:00
|
|
|
static void dissect_ldap_request_abandon(ASN1_SCK *a, proto_tree *tree,
|
2001-04-15 07:30:03 +00:00
|
|
|
int start, guint length)
|
2000-03-28 07:12:36 +00:00
|
|
|
{
|
2002-03-03 01:26:01 +00:00
|
|
|
read_integer_value(a, tree, hf_ldap_message_abandon_msgid, NULL, NULL,
|
2002-03-01 02:48:10 +00:00
|
|
|
start, length);
|
1999-12-09 04:06:54 +00:00
|
|
|
}
|
|
|
|
|
2000-04-08 07:07:42 +00:00
|
|
|
static void
|
2001-04-15 07:30:03 +00:00
|
|
|
dissect_ldap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
1999-12-09 04:06:54 +00:00
|
|
|
{
|
2000-03-28 07:12:36 +00:00
|
|
|
proto_tree *ldap_tree = 0, *ti, *msg_tree;
|
|
|
|
guint messageLength;
|
|
|
|
guint messageId;
|
2002-01-14 02:50:28 +00:00
|
|
|
int next_offset;
|
2000-03-29 09:25:21 +00:00
|
|
|
guint protocolOpCls, protocolOpCon, protocolOpTag;
|
|
|
|
gchar *typestr;
|
|
|
|
guint opLen;
|
2000-03-28 07:12:36 +00:00
|
|
|
ASN1_SCK a;
|
2001-04-15 07:30:03 +00:00
|
|
|
int start;
|
2002-01-14 02:50:28 +00:00
|
|
|
gboolean first_time = TRUE;
|
Put in the beginnings of checks for ASN.1 dissection errors.
The "present" choice in the type Filter is, in LDAP V2,
AttributeType, and, in LDAP V3, it's AttributeDescription. Both of
those are just LDAPString, which is, in turn, OCTET STRING, so it should
be required to have the primitive representation (unless and until we
add support for the constructed representation of octet strings - but
RFC 1777, the LDAP V2 spec, says
(2) Bitstrings and octet strings and all character string types
will be encoded in the primitive form only.
and RFC 2251, the LDAP V3 spec, says
(2) OCTET STRING values will be encoded in the primitive form only.
so we shouldn't ever see it with the constructed representation), and be
parsed with "asn1_octet_string_value_decode()", as, by that point, we've
already dissected the ASN.1 id and length.
Put the bind authorization type into the protocol tree before switching
on the type, so that it goes in even if it's not something we yet
dissect, and actually pass it as an argument to "proto_tree_add_item()"
(alas, "proto_tree_add_item()" is a varargs function, so this error
couldn't have been detected by the compiler).
When not constructing a protocol tree, quit "dissect_ldap()" after
dissecting the first operation - we don't need to dissect the others.
svn path=/trunk/; revision=1768
2000-03-31 10:22:24 +00:00
|
|
|
int ret;
|
2000-03-28 07:12:36 +00:00
|
|
|
|
2001-04-15 07:30:03 +00:00
|
|
|
asn1_open(&a, tvb, 0);
|
2000-03-28 07:12:36 +00:00
|
|
|
|
2002-01-14 02:50:28 +00:00
|
|
|
while (tvb_reported_length_remaining(tvb, a.offset) > 0)
|
2000-03-28 07:12:36 +00:00
|
|
|
{
|
2000-03-29 09:25:21 +00:00
|
|
|
int message_id_start;
|
|
|
|
int message_id_length;
|
|
|
|
int message_start;
|
|
|
|
|
2002-01-14 02:50:28 +00:00
|
|
|
/*
|
|
|
|
* XXX - should handle the initial sequence specifier split across
|
|
|
|
* segment boundaries.
|
|
|
|
*/
|
2001-04-15 07:30:03 +00:00
|
|
|
message_start = a.offset;
|
2002-03-01 02:48:10 +00:00
|
|
|
ret = read_sequence(&a, &messageLength);
|
|
|
|
if (ret != ASN1_ERR_NOERROR)
|
2000-03-29 09:25:21 +00:00
|
|
|
{
|
2002-01-14 03:01:13 +00:00
|
|
|
if (first_time)
|
|
|
|
{
|
|
|
|
if (check_col(pinfo->cinfo, COL_PROTOCOL))
|
|
|
|
col_set_str(pinfo->cinfo, COL_PROTOCOL, "LDAP");
|
|
|
|
if (check_col(pinfo->cinfo, COL_INFO))
|
2002-03-03 01:26:01 +00:00
|
|
|
{
|
|
|
|
col_add_fstr(pinfo->cinfo, COL_INFO,
|
|
|
|
"Invalid LDAP message (Can't parse sequence header: %s)",
|
|
|
|
asn1_err_to_str(ret));
|
|
|
|
}
|
2002-01-14 03:01:13 +00:00
|
|
|
}
|
|
|
|
if (tree)
|
|
|
|
{
|
2002-01-24 09:20:54 +00:00
|
|
|
ti = proto_tree_add_item(tree, proto_ldap, tvb, message_start, -1,
|
|
|
|
FALSE);
|
2002-01-14 03:01:13 +00:00
|
|
|
ldap_tree = proto_item_add_subtree(ti, ett_ldap);
|
2002-01-24 09:20:54 +00:00
|
|
|
proto_tree_add_text(ldap_tree, tvb, message_start, -1,
|
2002-03-03 01:26:01 +00:00
|
|
|
"Invalid LDAP message (Can't parse sequence header: %s)",
|
|
|
|
asn1_err_to_str(ret));
|
2002-01-14 03:01:13 +00:00
|
|
|
}
|
2000-03-29 09:25:21 +00:00
|
|
|
break;
|
|
|
|
}
|
2000-03-28 07:12:36 +00:00
|
|
|
|
2002-01-14 02:50:28 +00:00
|
|
|
/*
|
|
|
|
* Desegmentation check.
|
|
|
|
*/
|
|
|
|
if (ldap_desegment) {
|
|
|
|
if (pinfo->can_desegment
|
|
|
|
&& messageLength > (guint)tvb_length_remaining(tvb, a.offset)) {
|
|
|
|
/*
|
|
|
|
* This frame doesn't have all of the data for this message,
|
|
|
|
* but we can do reassembly on it.
|
|
|
|
*
|
|
|
|
* Tell the TCP dissector where the data for this message
|
|
|
|
* starts in the data it handed us, and how many more bytes
|
|
|
|
* we need, and return.
|
|
|
|
*/
|
|
|
|
pinfo->desegment_offset = message_start;
|
|
|
|
pinfo->desegment_len = messageLength -
|
|
|
|
tvb_length_remaining(tvb, a.offset);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
next_offset = a.offset + messageLength;
|
|
|
|
|
2002-01-14 03:01:13 +00:00
|
|
|
if (first_time)
|
|
|
|
{
|
|
|
|
if (check_col(pinfo->cinfo, COL_PROTOCOL))
|
|
|
|
col_set_str(pinfo->cinfo, COL_PROTOCOL, "LDAP");
|
|
|
|
if (check_col(pinfo->cinfo, COL_INFO))
|
|
|
|
col_clear(pinfo->cinfo, COL_INFO);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (tree)
|
|
|
|
{
|
|
|
|
ti = proto_tree_add_item(tree, proto_ldap, tvb, message_start,
|
|
|
|
next_offset - message_start, FALSE);
|
|
|
|
ldap_tree = proto_item_add_subtree(ti, ett_ldap);
|
|
|
|
}
|
|
|
|
|
2001-04-15 07:30:03 +00:00
|
|
|
message_id_start = a.offset;
|
2002-03-03 01:26:01 +00:00
|
|
|
ret = read_integer(&a, 0, hf_ldap_message_id, 0, &messageId, ASN1_INT);
|
2002-03-01 02:48:10 +00:00
|
|
|
if (ret != ASN1_ERR_NOERROR)
|
2001-05-08 19:46:32 +00:00
|
|
|
{
|
2001-12-10 00:26:21 +00:00
|
|
|
if (first_time && check_col(pinfo->cinfo, COL_INFO))
|
2002-03-03 01:26:01 +00:00
|
|
|
col_add_fstr(pinfo->cinfo, COL_INFO, "Invalid LDAP packet (Can't parse Message ID: %s)",
|
|
|
|
asn1_err_to_str(ret));
|
2001-05-08 19:46:32 +00:00
|
|
|
if (ldap_tree)
|
|
|
|
proto_tree_add_text(ldap_tree, tvb, message_id_start, 1,
|
2002-03-03 01:26:01 +00:00
|
|
|
"Invalid LDAP packet (Can't parse Message ID: %s)",
|
|
|
|
asn1_err_to_str(ret));
|
2001-05-08 19:46:32 +00:00
|
|
|
break;
|
|
|
|
}
|
2001-04-15 07:30:03 +00:00
|
|
|
message_id_length = a.offset - message_id_start;
|
2000-03-29 09:25:21 +00:00
|
|
|
|
2001-04-15 07:30:03 +00:00
|
|
|
start = a.offset;
|
2000-03-29 09:25:21 +00:00
|
|
|
asn1_id_decode(&a, &protocolOpCls, &protocolOpCon, &protocolOpTag);
|
|
|
|
if (protocolOpCls != ASN1_APL)
|
|
|
|
typestr = "Bad message type (not Application)";
|
|
|
|
else
|
2002-03-02 21:28:19 +00:00
|
|
|
typestr = val_to_str(protocolOpTag, msgTypes, "Unknown message type (%u)");
|
2000-03-29 09:25:21 +00:00
|
|
|
|
|
|
|
if (first_time)
|
|
|
|
{
|
2001-12-10 00:26:21 +00:00
|
|
|
if (check_col(pinfo->cinfo, COL_INFO))
|
|
|
|
col_add_fstr(pinfo->cinfo, COL_INFO, "MsgId=%u MsgType=%s",
|
2000-03-29 09:25:21 +00:00
|
|
|
messageId, typestr);
|
2002-01-14 02:50:28 +00:00
|
|
|
first_time = FALSE;
|
2000-03-29 09:25:21 +00:00
|
|
|
}
|
2000-03-28 07:12:36 +00:00
|
|
|
|
2000-04-03 07:48:55 +00:00
|
|
|
if (ldap_tree)
|
2000-03-28 07:12:36 +00:00
|
|
|
{
|
2001-04-15 07:30:03 +00:00
|
|
|
proto_tree_add_uint_hidden(ldap_tree, hf_ldap_message_id, tvb, message_id_start, message_id_length, messageId);
|
|
|
|
proto_tree_add_uint_hidden(ldap_tree, hf_ldap_message_type, tvb,
|
|
|
|
start, a.offset - start, protocolOpTag);
|
|
|
|
ti = proto_tree_add_text(ldap_tree, tvb, message_id_start, messageLength, "Message: Id=%u %s", messageId, typestr);
|
2000-03-29 09:25:21 +00:00
|
|
|
msg_tree = proto_item_add_subtree(ti, ett_ldap_message);
|
2001-04-15 07:30:03 +00:00
|
|
|
start = a.offset;
|
2002-03-03 01:26:01 +00:00
|
|
|
if (read_length(&a, msg_tree, hf_ldap_message_length, &opLen) != ASN1_ERR_NOERROR)
|
2002-03-01 02:48:10 +00:00
|
|
|
return;
|
2000-03-29 09:25:21 +00:00
|
|
|
|
2002-03-02 21:28:19 +00:00
|
|
|
if (protocolOpCls != ASN1_APL)
|
2000-03-29 09:25:21 +00:00
|
|
|
{
|
2002-03-02 21:28:19 +00:00
|
|
|
proto_tree_add_text(msg_tree, a.tvb, a.offset, opLen,
|
|
|
|
"%s", typestr);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
switch (protocolOpTag)
|
|
|
|
{
|
|
|
|
case LDAP_REQ_BIND:
|
2002-03-03 01:26:01 +00:00
|
|
|
dissect_ldap_request_bind(&a, msg_tree);
|
2002-03-02 21:28:19 +00:00
|
|
|
break;
|
|
|
|
case LDAP_REQ_UNBIND:
|
|
|
|
/* Nothing to dissect */
|
|
|
|
break;
|
|
|
|
case LDAP_REQ_SEARCH:
|
2002-03-03 01:26:01 +00:00
|
|
|
dissect_ldap_request_search(&a, msg_tree);
|
2002-03-02 21:28:19 +00:00
|
|
|
break;
|
|
|
|
case LDAP_REQ_MODIFY:
|
2002-03-03 01:26:01 +00:00
|
|
|
dissect_ldap_request_modify(&a, msg_tree);
|
2002-03-02 21:28:19 +00:00
|
|
|
break;
|
|
|
|
case LDAP_REQ_ADD:
|
2002-03-03 01:26:01 +00:00
|
|
|
dissect_ldap_request_add(&a, msg_tree);
|
2002-03-02 21:28:19 +00:00
|
|
|
break;
|
|
|
|
case LDAP_REQ_DELETE:
|
2002-03-03 01:26:01 +00:00
|
|
|
dissect_ldap_request_delete(&a, msg_tree, start, opLen);
|
2002-03-02 21:28:19 +00:00
|
|
|
break;
|
|
|
|
case LDAP_REQ_MODRDN:
|
2002-03-03 01:26:01 +00:00
|
|
|
dissect_ldap_request_modifyrdn(&a, msg_tree, opLen);
|
2002-03-02 21:28:19 +00:00
|
|
|
break;
|
|
|
|
case LDAP_REQ_COMPARE:
|
2002-03-03 01:26:01 +00:00
|
|
|
dissect_ldap_request_compare(&a, msg_tree);
|
2002-03-02 21:28:19 +00:00
|
|
|
break;
|
|
|
|
case LDAP_REQ_ABANDON:
|
2002-03-03 01:26:01 +00:00
|
|
|
dissect_ldap_request_abandon(&a, msg_tree, start, opLen);
|
2002-03-02 21:28:19 +00:00
|
|
|
break;
|
|
|
|
case LDAP_RES_BIND:
|
2002-03-03 01:26:01 +00:00
|
|
|
dissect_ldap_response_bind(&a, msg_tree);
|
2002-03-02 21:28:19 +00:00
|
|
|
break;
|
|
|
|
case LDAP_RES_SEARCH_ENTRY:
|
2002-03-03 01:26:01 +00:00
|
|
|
dissect_ldap_response_search_entry(&a, msg_tree);
|
2002-03-02 21:28:19 +00:00
|
|
|
break;
|
|
|
|
case LDAP_RES_SEARCH_RESULT:
|
|
|
|
case LDAP_RES_MODIFY:
|
|
|
|
case LDAP_RES_ADD:
|
|
|
|
case LDAP_RES_DELETE:
|
|
|
|
case LDAP_RES_MODRDN:
|
|
|
|
case LDAP_RES_COMPARE:
|
2002-03-03 01:26:01 +00:00
|
|
|
dissect_ldap_result(&a, msg_tree);
|
2002-03-02 21:28:19 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
proto_tree_add_text(msg_tree, a.tvb, a.offset, opLen,
|
|
|
|
"Unknown LDAP operation (%u)", protocolOpTag);
|
|
|
|
break;
|
|
|
|
}
|
2002-03-01 02:48:10 +00:00
|
|
|
}
|
2000-03-28 07:12:36 +00:00
|
|
|
}
|
2002-01-14 02:50:28 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* XXX - what if "a.offset" is past the offset of the next top-level
|
|
|
|
* sequence? Show that as an error?
|
|
|
|
*/
|
|
|
|
a.offset = next_offset;
|
2000-03-28 07:12:36 +00:00
|
|
|
}
|
1999-12-09 04:06:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
proto_register_ldap(void)
|
|
|
|
{
|
2000-03-28 07:12:36 +00:00
|
|
|
static value_string result_codes[] = {
|
|
|
|
{0, "Success"},
|
|
|
|
{1, "Operations error"},
|
|
|
|
{2, "Protocol error"},
|
|
|
|
{3, "Time limit exceeded"},
|
|
|
|
{4, "Size limit exceeded"},
|
|
|
|
{5, "Compare false"},
|
|
|
|
{6, "Compare true"},
|
|
|
|
{7, "Authentication method not supported"},
|
|
|
|
{8, "Strong authentication required"},
|
|
|
|
{10, "Referral"},
|
|
|
|
{11, "Administrative limit exceeded"},
|
|
|
|
{12, "Unavailable critical extension"},
|
|
|
|
{13, "Confidentiality required"},
|
|
|
|
{14, "SASL bind in progress"},
|
|
|
|
{16, "No such attribute"},
|
|
|
|
{17, "Undefined attribute type"},
|
|
|
|
{18, "Inappropriate matching"},
|
|
|
|
{19, "Constraint violation"},
|
|
|
|
{20, "Attribute or value exists"},
|
|
|
|
{21, "Invalid attribute syntax"},
|
|
|
|
{32, "No such object"},
|
|
|
|
{33, "Alias problem"},
|
|
|
|
{34, "Invalid DN syntax"},
|
|
|
|
{36, "Alias derefetencing problem"},
|
|
|
|
{48, "Inappropriate authentication"},
|
|
|
|
{49, "Invalid credentials"},
|
|
|
|
{50, "Insufficient access rights"},
|
|
|
|
{51, "Busy"},
|
|
|
|
{52, "Unavailable"},
|
|
|
|
{53, "Unwilling to perform"},
|
|
|
|
{54, "Loop detected"},
|
|
|
|
{64, "Naming violation"},
|
|
|
|
{65, "Objectclass violation"},
|
|
|
|
{66, "Not allowed on non-leaf"},
|
|
|
|
{67, "Not allowed on RDN"},
|
|
|
|
{68, "Entry already exists"},
|
|
|
|
{69, "Objectclass modification prohibited"},
|
|
|
|
{71, "Affects multiple DSAs"},
|
|
|
|
{80, "Other"},
|
2001-01-03 16:41:08 +00:00
|
|
|
{0, NULL},
|
2000-03-28 07:12:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static value_string auth_types[] = {
|
2000-03-29 09:25:21 +00:00
|
|
|
{LDAP_AUTH_SIMPLE, "Simple"},
|
|
|
|
{LDAP_AUTH_KRBV4LDAP, "Kerberos V4 to the LDAP server"},
|
|
|
|
{LDAP_AUTH_KRBV4DSA, "Kerberos V4 to the DSA"},
|
|
|
|
{LDAP_AUTH_SASL, "SASL"},
|
2001-01-03 16:41:08 +00:00
|
|
|
{0, NULL},
|
2000-03-28 07:12:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static value_string search_scope[] = {
|
|
|
|
{0x00, "Base"},
|
|
|
|
{0x01, "Single"},
|
|
|
|
{0x02, "Subtree"},
|
2001-01-03 16:41:08 +00:00
|
|
|
{0x00, NULL},
|
2000-03-28 07:12:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static value_string search_dereference[] = {
|
|
|
|
{0x00, "Never"},
|
|
|
|
{0x01, "Searching"},
|
|
|
|
{0x02, "Base Object"},
|
|
|
|
{0x03, "Always"},
|
2001-01-03 16:41:08 +00:00
|
|
|
{0x00, NULL},
|
2000-03-28 07:12:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static hf_register_info hf[] = {
|
|
|
|
{ &hf_ldap_length,
|
|
|
|
{ "Length", "ldap.length",
|
2000-05-31 05:09:07 +00:00
|
|
|
FT_UINT32, BASE_DEC, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"LDAP Length", HFILL }},
|
1999-12-09 04:06:54 +00:00
|
|
|
|
2000-03-28 07:12:36 +00:00
|
|
|
{ &hf_ldap_message_id,
|
|
|
|
{ "Message Id", "ldap.message_id",
|
2000-05-31 05:09:07 +00:00
|
|
|
FT_UINT32, BASE_DEC, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"LDAP Message Id", HFILL }},
|
2000-03-28 07:12:36 +00:00
|
|
|
{ &hf_ldap_message_type,
|
|
|
|
{ "Message Type", "ldap.message_type",
|
|
|
|
FT_UINT8, BASE_HEX, &msgTypes, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"LDAP Message Type", HFILL }},
|
2000-03-28 07:12:36 +00:00
|
|
|
{ &hf_ldap_message_length,
|
|
|
|
{ "Message Length", "ldap.message_length",
|
2000-05-31 05:09:07 +00:00
|
|
|
FT_UINT32, BASE_DEC, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"LDAP Message Length", HFILL }},
|
2000-03-28 07:12:36 +00:00
|
|
|
|
|
|
|
{ &hf_ldap_message_result,
|
|
|
|
{ "Result Code", "ldap.result.code",
|
2000-05-31 05:09:07 +00:00
|
|
|
FT_UINT8, BASE_HEX, result_codes, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"LDAP Result Code", HFILL }},
|
2000-03-28 07:12:36 +00:00
|
|
|
{ &hf_ldap_message_result_matcheddn,
|
|
|
|
{ "Matched DN", "ldap.result.matcheddn",
|
|
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"LDAP Result Matched DN", HFILL }},
|
2000-03-28 07:12:36 +00:00
|
|
|
{ &hf_ldap_message_result_errormsg,
|
|
|
|
{ "Error Message", "ldap.result.errormsg",
|
|
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"LDAP Result Error Message", HFILL }},
|
2000-03-28 07:12:36 +00:00
|
|
|
{ &hf_ldap_message_result_referral,
|
|
|
|
{ "Referral", "ldap.result.referral",
|
|
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"LDAP Result Referral URL", HFILL }},
|
2000-03-28 07:12:36 +00:00
|
|
|
|
|
|
|
{ &hf_ldap_message_bind_version,
|
|
|
|
{ "Version", "ldap.bind.version",
|
2000-05-31 05:09:07 +00:00
|
|
|
FT_UINT32, BASE_DEC, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"LDAP Bind Version", HFILL }},
|
2000-03-28 07:12:36 +00:00
|
|
|
{ &hf_ldap_message_bind_dn,
|
|
|
|
{ "DN", "ldap.bind.dn",
|
|
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"LDAP Bind Distinguished Name", HFILL }},
|
2000-03-28 07:12:36 +00:00
|
|
|
{ &hf_ldap_message_bind_auth,
|
|
|
|
{ "Auth Type", "ldap.bind.auth_type",
|
2000-03-29 09:25:21 +00:00
|
|
|
FT_UINT8, BASE_HEX, auth_types, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"LDAP Bind Auth Type", HFILL }},
|
2000-03-28 07:12:36 +00:00
|
|
|
{ &hf_ldap_message_bind_auth_password,
|
|
|
|
{ "Password", "ldap.bind.password",
|
|
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"LDAP Bind Password", HFILL }},
|
2000-03-28 07:12:36 +00:00
|
|
|
|
|
|
|
{ &hf_ldap_message_search_base,
|
|
|
|
{ "Base DN", "ldap.search.basedn",
|
|
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"LDAP Search Base Distinguished Name", HFILL }},
|
2000-03-28 07:12:36 +00:00
|
|
|
{ &hf_ldap_message_search_scope,
|
|
|
|
{ "Scope", "ldap.search.scope",
|
|
|
|
FT_UINT8, BASE_HEX, search_scope, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"LDAP Search Scope", HFILL }},
|
2000-03-28 07:12:36 +00:00
|
|
|
{ &hf_ldap_message_search_deref,
|
|
|
|
{ "Dereference", "ldap.search.dereference",
|
|
|
|
FT_UINT8, BASE_HEX, search_dereference, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"LDAP Search Dereference", HFILL }},
|
2000-03-28 07:12:36 +00:00
|
|
|
{ &hf_ldap_message_search_sizeLimit,
|
|
|
|
{ "Size Limit", "ldap.search.sizelimit",
|
2000-05-31 05:09:07 +00:00
|
|
|
FT_UINT32, BASE_DEC, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"LDAP Search Size Limit", HFILL }},
|
2000-03-28 07:12:36 +00:00
|
|
|
{ &hf_ldap_message_search_timeLimit,
|
|
|
|
{ "Time Limit", "ldap.search.timelimit",
|
2000-05-31 05:09:07 +00:00
|
|
|
FT_UINT32, BASE_DEC, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"LDAP Search Time Limit", HFILL }},
|
2000-03-28 07:12:36 +00:00
|
|
|
{ &hf_ldap_message_search_typesOnly,
|
|
|
|
{ "Attributes Only", "ldap.search.typesonly",
|
|
|
|
FT_BOOLEAN, BASE_NONE, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"LDAP Search Attributes Only", HFILL }},
|
2000-03-28 07:12:36 +00:00
|
|
|
{ &hf_ldap_message_search_filter,
|
|
|
|
{ "Filter", "ldap.search.filter",
|
|
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"LDAP Search Filter", HFILL }},
|
2000-03-28 07:12:36 +00:00
|
|
|
{ &hf_ldap_message_dn,
|
|
|
|
{ "Distinguished Name", "ldap.dn",
|
|
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"LDAP Distinguished Name", HFILL }},
|
2000-03-28 07:12:36 +00:00
|
|
|
{ &hf_ldap_message_attribute,
|
|
|
|
{ "Attribute", "ldap.attribute",
|
|
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"LDAP Attribute", HFILL }},
|
2002-05-06 02:12:36 +00:00
|
|
|
/*
|
|
|
|
* XXX - not all LDAP values are text strings; we'd need a file
|
|
|
|
* describing which values (by name) are text strings and which are
|
|
|
|
* binary.
|
|
|
|
*
|
|
|
|
* Some values that are, at least in Microsoft's schema, binary
|
|
|
|
* are:
|
|
|
|
*
|
|
|
|
* invocationId
|
|
|
|
* nTSecurityDescriptor
|
|
|
|
* objectGUID
|
|
|
|
*/
|
2000-03-28 07:12:36 +00:00
|
|
|
{ &hf_ldap_message_value,
|
|
|
|
{ "Value", "ldap.value",
|
|
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"LDAP Value", HFILL }},
|
2000-03-28 07:12:36 +00:00
|
|
|
|
|
|
|
{ &hf_ldap_message_modrdn_name,
|
|
|
|
{ "New Name", "ldap.modrdn.name",
|
|
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"LDAP New Name", HFILL }},
|
2000-03-28 07:12:36 +00:00
|
|
|
{ &hf_ldap_message_modrdn_delete,
|
|
|
|
{ "Delete Values", "ldap.modrdn.delete",
|
|
|
|
FT_BOOLEAN, BASE_NONE, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"LDAP Modify RDN - Delete original values", HFILL }},
|
2000-03-28 07:12:36 +00:00
|
|
|
{ &hf_ldap_message_modrdn_superior,
|
|
|
|
{ "New Location", "ldap.modrdn.superior",
|
|
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"LDAP Modify RDN - New Location", HFILL }},
|
2000-03-28 07:12:36 +00:00
|
|
|
|
|
|
|
{ &hf_ldap_message_compare,
|
|
|
|
{ "Test", "ldap.compare.test",
|
|
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"LDAP Compare Test", HFILL }},
|
2000-03-28 07:12:36 +00:00
|
|
|
|
|
|
|
{ &hf_ldap_message_modify_add,
|
|
|
|
{ "Add", "ldap.modify.add",
|
|
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"LDAP Add", HFILL }},
|
2000-03-28 07:12:36 +00:00
|
|
|
{ &hf_ldap_message_modify_replace,
|
|
|
|
{ "Replace", "ldap.modify.replace",
|
|
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"LDAP Replace", HFILL }},
|
2000-03-28 07:12:36 +00:00
|
|
|
{ &hf_ldap_message_modify_delete,
|
|
|
|
{ "Delete", "ldap.modify.delete",
|
|
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"LDAP Delete", HFILL }},
|
2000-03-28 07:12:36 +00:00
|
|
|
|
|
|
|
{ &hf_ldap_message_abandon_msgid,
|
|
|
|
{ "Abandon Msg Id", "ldap.abandon.msgid",
|
2000-05-31 05:09:07 +00:00
|
|
|
FT_UINT32, BASE_DEC, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"LDAP Abandon Msg Id", HFILL }},
|
2000-03-28 07:12:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static gint *ett[] = {
|
|
|
|
&ett_ldap,
|
|
|
|
&ett_ldap_message,
|
|
|
|
&ett_ldap_referrals,
|
|
|
|
&ett_ldap_attribute
|
|
|
|
};
|
2002-01-14 02:50:28 +00:00
|
|
|
module_t *ldap_module;
|
2000-03-28 07:12:36 +00:00
|
|
|
|
2001-01-03 06:56:03 +00:00
|
|
|
proto_ldap = proto_register_protocol("Lightweight Directory Access Protocol",
|
|
|
|
"LDAP", "ldap");
|
2000-03-28 07:12:36 +00:00
|
|
|
proto_register_field_array(proto_ldap, hf, array_length(hf));
|
|
|
|
proto_register_subtree_array(ett, array_length(ett));
|
2002-01-14 02:50:28 +00:00
|
|
|
|
|
|
|
ldap_module = prefs_register_protocol(proto_ldap, NULL);
|
|
|
|
prefs_register_bool_preference(ldap_module, "desegment_ldap_messages",
|
|
|
|
"Desegment all LDAP messages spanning multiple TCP segments",
|
|
|
|
"Whether the LDAP dissector should desegment all messages spanning multiple TCP segments",
|
|
|
|
&ldap_desegment);
|
1999-12-09 04:06:54 +00:00
|
|
|
}
|
2000-04-08 07:07:42 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
proto_reg_handoff_ldap(void)
|
|
|
|
{
|
2001-12-03 04:00:26 +00:00
|
|
|
dissector_handle_t ldap_handle;
|
|
|
|
|
|
|
|
ldap_handle = create_dissector_handle(dissect_ldap, proto_ldap);
|
|
|
|
dissector_add("tcp.port", TCP_PORT_LDAP, ldap_handle);
|
2000-04-08 07:07:42 +00:00
|
|
|
}
|