aboutsummaryrefslogtreecommitdiffstats
path: root/asn1/ldap
diff options
context:
space:
mode:
authorGraeme Lunt <graeme.lunt@smhs.co.uk>2008-01-13 14:12:47 +0000
committerGraeme Lunt <graeme.lunt@smhs.co.uk>2008-01-13 14:12:47 +0000
commit8563c0213789a8a73ca0b9f5ca0e240297cc49d8 (patch)
tree1316582dca6efc2f08c3614375cd7e0722181c77 /asn1/ldap
parentabdadc9eaeda078c327cd8ff0ea058954a864ca9 (diff)
Basic support for the LDAP start_tls extended operation and fix to match up extended operation arguments and results.
svn path=/trunk/; revision=24076
Diffstat (limited to 'asn1/ldap')
-rw-r--r--asn1/ldap/ldap.cnf42
-rw-r--r--asn1/ldap/packet-ldap-template.c52
2 files changed, 86 insertions, 8 deletions
diff --git a/asn1/ldap/ldap.cnf b/asn1/ldap/ldap.cnf
index d7aa23da82..986603ab61 100644
--- a/asn1/ldap/ldap.cnf
+++ b/asn1/ldap/ldap.cnf
@@ -57,11 +57,33 @@ ReplControlValue B "1.2.840.113556.1.4.841" "replControlValue"
name = oid_resolved_from_string(object_identifier_id);
if(name){
-
proto_item_append_text(actx->created_item, " (%s)", name);
- proto_item_append_text(actx->created_item, " %s", name);
+
+ if((hf_index == hf_ldap_requestName) || (hf_index == hf_ldap_responseName)) {
+ ldap_do_protocolop(actx->pinfo);
+
+ if(check_col(actx->pinfo->cinfo, COL_INFO))
+ col_append_fstr(actx->pinfo->cinfo, COL_INFO, "%s ", name);
+ }
}
+ if(((hf_index == hf_ldap_responseName) || (hf_index == hf_ldap_requestName)) &&
+ !strcmp(object_identifier_id, "1.3.6.1.4.1.1466.20037")) {
+
+ /* we have agreed start_tls */
+ ldap_conv_info_t *ldap_info = NULL;
+
+ ldap_info = (ldap_conv_info_t *)actx->pinfo->private_data;
+
+ if(ldap_info) {
+ if(hf_index == hf_ldap_responseName)
+ /* TLS in the next frame */
+ ldap_info->start_tls_frame = (actx->pinfo->fd->num) + 1;
+ else
+ /* remember we have asked to start_tls */
+ ldap_info->start_tls_pending = TRUE;
+ }
+ }
#.FN_BODY MessageID VAL_PTR = &MessageID
@@ -84,7 +106,7 @@ ReplControlValue B "1.2.840.113556.1.4.841" "replControlValue"
}
/* ProtocolOp is the index, not the tag so convert it to the tag value */
- ProtocolOp = ldap_ProtocolOp_choice_vals[ProtocolOp].value;
+ ProtocolOp = ldap_ProtocolOp_vals[ProtocolOp].value;
lcrp=ldap_match_call_response(tvb, actx->pinfo, tree, MessageID, ProtocolOp);
if(lcrp){
@@ -119,6 +141,20 @@ ReplControlValue B "1.2.840.113556.1.4.841" "replControlValue"
break;
}
}
+
+ if(ldap_info && (ProtocolOp == LDAP_RES_EXTENDED)) {
+ /* this is an extend result */
+
+ if(ldap_info->start_tls_pending && !ldap_info->start_tls_frame) {
+ /* XXX: some directories do not correctly return the responseName in the extendedResponse so we don't know start_tls has been negotiated */
+
+ if(check_col(actx->pinfo->cinfo, COL_INFO))
+ col_append_fstr(actx->pinfo->cinfo, COL_INFO, "[LDAP_START_TLS_OID responseName missing] ");
+ ldap_info->start_tls_frame = (actx->pinfo->fd->num) + 1;
+ }
+
+ ldap_info->start_tls_pending = FALSE;
+ }
#.FN_BODY Simple
ldap_conv_info_t *ldap_info;
diff --git a/asn1/ldap/packet-ldap-template.c b/asn1/ldap/packet-ldap-template.c
index 164a3279af..147c1b89b2 100644
--- a/asn1/ldap/packet-ldap-template.c
+++ b/asn1/ldap/packet-ldap-template.c
@@ -92,6 +92,7 @@
#include "packet-frame.h"
#include "packet-ldap.h"
#include "packet-ntlmssp.h"
+#include "packet-ssl.h"
#include "packet-ber.h"
#include "packet-per.h"
@@ -172,10 +173,12 @@ static gboolean is_binary_attr_type = FALSE;
#define UDP_PORT_CLDAP 389
#define TCP_PORT_GLOBALCAT_LDAP 3268 /* Windows 2000 Global Catalog */
-static dissector_handle_t gssapi_handle;
-static dissector_handle_t gssapi_wrap_handle;
+static dissector_handle_t gssapi_handle = NULL;
+static dissector_handle_t gssapi_wrap_handle = NULL;
static dissector_handle_t ntlmssp_handle = NULL;
-static dissector_handle_t spnego_handle;
+static dissector_handle_t spnego_handle = NULL;
+static dissector_handle_t ssl_handle = NULL;
+static dissector_handle_t ldap_handle = NULL;
/* different types of rpc calls ontop of ms cldap */
#define MSCLDAP_RPC_NETLOGON 1
@@ -219,6 +222,8 @@ typedef struct ldap_conv_info_t {
GHashTable *matched;
gboolean is_mscldap;
guint32 num_results;
+ gboolean start_tls_pending;
+ guint32 start_tls_frame;
} ldap_conv_info_t;
static ldap_conv_info_t *ldap_info_items;
@@ -429,6 +434,7 @@ ldap_match_call_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gu
case LDAP_REQ_DELETE:
case LDAP_REQ_MODRDN:
case LDAP_REQ_COMPARE:
+ case LDAP_REQ_EXTENDED:
lcr.is_request=TRUE;
lcr.req_frame=pinfo->fd->num;
lcr.rep_frame=0;
@@ -442,6 +448,7 @@ ldap_match_call_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gu
case LDAP_RES_DELETE:
case LDAP_RES_MODRDN:
case LDAP_RES_COMPARE:
+ case LDAP_RES_EXTENDED:
lcr.is_request=FALSE;
lcr.req_frame=0;
lcr.rep_frame=pinfo->fd->num;
@@ -465,6 +472,7 @@ ldap_match_call_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gu
case LDAP_REQ_DELETE:
case LDAP_REQ_MODRDN:
case LDAP_REQ_COMPARE:
+ case LDAP_REQ_EXTENDED:
/* this a a request - add it to the unmatched list */
@@ -498,6 +506,7 @@ ldap_match_call_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gu
case LDAP_RES_DELETE:
case LDAP_RES_MODRDN:
case LDAP_RES_COMPARE:
+ case LDAP_RES_EXTENDED:
/* this is a result - it should be in our unmatched list */
@@ -682,6 +691,8 @@ dissect_ldap_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean i
ldap_info->matched=g_hash_table_new(ldap_info_hash_matched, ldap_info_equal_matched);
ldap_info->unmatched=g_hash_table_new(ldap_info_hash_unmatched, ldap_info_equal_unmatched);
ldap_info->num_results = 0;
+ ldap_info->start_tls_frame = 0;
+ ldap_info->start_tls_pending = FALSE;
conversation_add_proto_data(conversation, proto_ldap, ldap_info);
@@ -689,7 +700,7 @@ dissect_ldap_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean i
ldap_info_items = ldap_info;
}
-
+
switch (ldap_info->auth_type) {
case LDAP_AUTH_SASL:
/*
@@ -1399,9 +1410,38 @@ this_was_not_sasl:
tcp_dissect_pdus(tvb, pinfo, tree, ldap_desegment, 4, get_normal_ldap_pdu_len, dissect_normal_ldap_pdu);
+ goto end;
this_was_not_normal_ldap:
+ /* perhaps it was SSL? */
+ if(ldap_info &&
+ ldap_info->start_tls_frame &&
+ ( pinfo->fd->num >= ldap_info->start_tls_frame)) {
+
+ /* we have started TLS and so this may be an SSL layer */
+ guint32 old_start_tls_frame;
+
+ /* temporarily dissect this port as SSL */
+ dissector_delete("tcp.port", ldap_tcp_port, ldap_handle);
+ ssl_dissector_add(ldap_tcp_port, "ldap", TRUE);
+
+ old_start_tls_frame = ldap_info->start_tls_frame;
+ ldap_info->start_tls_frame = 0; /* make sure we don't call SSL again */
+ pinfo->can_desegment++; /* ignore this LDAP layer so SSL can use the TCP resegment */
+
+ offset = call_dissector(ssl_handle, tvb, pinfo, tree);
+
+ ldap_info->start_tls_frame = old_start_tls_frame;
+ ssl_dissector_delete(ldap_tcp_port, "ldap", TRUE);
+
+ /* restore ldap as the dissector for this port */
+ dissector_add("tcp.port", ldap_tcp_port, ldap_handle);
+
+ /* we are done */
+ return;
+ }
+ end:
return;
}
@@ -1674,7 +1714,7 @@ void proto_register_ldap(void) {
void
proto_reg_handoff_ldap(void)
{
- dissector_handle_t ldap_handle, cldap_handle;
+ dissector_handle_t cldap_handle;
ldap_handle = create_dissector_handle(dissect_ldap_tcp, proto_ldap);
dissector_add("tcp.port", ldap_tcp_port, ldap_handle);
@@ -1689,6 +1729,8 @@ proto_reg_handoff_ldap(void)
ntlmssp_handle = find_dissector("ntlmssp");
+ ssl_handle = find_dissector("ssl");
+
/* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dsml/dsml/ldap_controls_and_session_support.asp */
oid_add_from_string("LDAP_PAGED_RESULT_OID_STRING","1.2.840.113556.1.4.319");
oid_add_from_string("LDAP_SERVER_SHOW_DELETED_OID","1.2.840.113556.1.4.417");