[SCM] Samba Shared Repository - branch master updated

Stefan Metzmacher metze at samba.org
Sun Sep 26 00:16:57 MDT 2010


The branch, master has been updated
       via  95b56aa libcli/ldap: let ldap_full_packet() use asn1_peek_tag_needed_size()
       via  182a69c lib/util/asn1: add asn1_peek_tag_needed_size() and asn1_peek_full_tag()
       via  e628bf1 libcli/util: let tstream_read_pdu_blob_* cope with variable length headers
      from  0b5a556 s4-kerberos Don't segfault if the password isn't specified in keytab generation

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 95b56aabcbfe2754a34eac627a6bc7226cbd3f17
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Sep 24 05:09:15 2010 +0200

    libcli/ldap: let ldap_full_packet() use asn1_peek_tag_needed_size()
    
    This allows us to read a full packet without read byte after byte
    or possible read to much.
    
    metze

commit 182a69c5be7706fbb542694c7be51d499b61c98d
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Sep 23 18:10:28 2010 +0200

    lib/util/asn1: add asn1_peek_tag_needed_size() and asn1_peek_full_tag()
    
    We need a way to ask for the length of a tag without having the full
    buffer yet.
    
    metze

commit e628bf1081929684d888353101296cc17d9f3ae4
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Sep 22 20:31:06 2010 +0200

    libcli/util: let tstream_read_pdu_blob_* cope with variable length headers
    
    metze

-----------------------------------------------------------------------

Summary of changes:
 lib/util/asn1.c            |   83 ++++++++++++++++++++++++++++++++++++++++++++
 lib/util/asn1.h            |    2 +
 libcli/ldap/ldap_message.c |    2 +-
 libcli/util/tstream.c      |   18 +++++++---
 4 files changed, 99 insertions(+), 6 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/util/asn1.c b/lib/util/asn1.c
index 8f30cfe..c492334 100644
--- a/lib/util/asn1.c
+++ b/lib/util/asn1.c
@@ -489,6 +489,65 @@ bool asn1_peek_tag(struct asn1_data *data, uint8_t tag)
 	return (b == tag);
 }
 
+/*
+ * just get the needed size the tag would consume
+ */
+bool asn1_peek_tag_needed_size(struct asn1_data *data, uint8_t tag, size_t *size)
+{
+	off_t start_ofs = data->ofs;
+	uint8_t b;
+	size_t taglen = 0;
+
+	if (data->has_error) {
+		return false;
+	}
+
+	if (!asn1_read_uint8(data, &b)) {
+		data->ofs = start_ofs;
+		data->has_error = false;
+		return false;
+	}
+
+	if (b != tag) {
+		data->ofs = start_ofs;
+		data->has_error = false;
+		return false;
+	}
+
+	if (!asn1_read_uint8(data, &b)) {
+		data->ofs = start_ofs;
+		data->has_error = false;
+		return false;
+	}
+
+	if (b & 0x80) {
+		int n = b & 0x7f;
+		if (!asn1_read_uint8(data, &b)) {
+			data->ofs = start_ofs;
+			data->has_error = false;
+			return false;
+		}
+		taglen = b;
+		while (n > 1) {
+			if (!asn1_read_uint8(data, &b)) {
+				data->ofs = start_ofs;
+				data->has_error = false;
+				return false;
+			}
+			taglen = (taglen << 8) | b;
+			n--;
+		}
+	} else {
+		taglen = b;
+	}
+
+	*size = (data->ofs - start_ofs) + taglen;
+
+	data->ofs = start_ofs;
+	data->has_error = false;
+	return true;
+}
+
 /* start reading a nested asn1 structure */
 bool asn1_start_tag(struct asn1_data *data, uint8_t tag)
 {
@@ -943,6 +1002,30 @@ NTSTATUS asn1_full_tag(DATA_BLOB blob, uint8_t tag, size_t *packet_size)
 
 	if (size > blob.length) {
 		return STATUS_MORE_ENTRIES;
+	}
+
+	*packet_size = size;
+	return NT_STATUS_OK;
+}
+
+NTSTATUS asn1_peek_full_tag(DATA_BLOB blob, uint8_t tag, size_t *packet_size)
+{
+	struct asn1_data asn1;
+	uint32_t size;
+	bool ok;
+
+	ZERO_STRUCT(asn1);
+	asn1.data = blob.data;
+	asn1.length = blob.length;
+
+	ok = asn1_peek_tag_needed_size(&asn1, tag, &size);
+	if (!ok) {
+		return STATUS_MORE_ENTRIES;
+	}
+
+	if (size > blob.length) {
+		*packet_size = size;
+		return STATUS_MORE_ENTRIES;
 	}		
 
 	*packet_size = size;
diff --git a/lib/util/asn1.h b/lib/util/asn1.h
index ded3244..266a9a3 100644
--- a/lib/util/asn1.h
+++ b/lib/util/asn1.h
@@ -79,6 +79,7 @@ bool asn1_peek(struct asn1_data *data, void *p, int len);
 bool asn1_read(struct asn1_data *data, void *p, int len);
 bool asn1_read_uint8(struct asn1_data *data, uint8_t *v);
 bool asn1_peek_uint8(struct asn1_data *data, uint8_t *v);
+bool asn1_peek_tag_needed_size(struct asn1_data *data, uint8_t tag, size_t *size);
 bool asn1_peek_tag(struct asn1_data *data, uint8_t tag);
 bool asn1_start_tag(struct asn1_data *data, uint8_t tag);
 bool asn1_end_tag(struct asn1_data *data);
@@ -100,5 +101,6 @@ bool asn1_write_enumerated(struct asn1_data *data, uint8_t v);
 bool asn1_blob(const struct asn1_data *asn1, DATA_BLOB *blob);
 void asn1_load_nocopy(struct asn1_data *data, uint8_t *buf, size_t len);
 NTSTATUS asn1_full_tag(DATA_BLOB blob, uint8_t tag, size_t *packet_size);
+NTSTATUS asn1_peek_full_tag(DATA_BLOB blob, uint8_t tag, size_t *packet_size);
 
 #endif /* _ASN_1_H */
diff --git a/libcli/ldap/ldap_message.c b/libcli/ldap/ldap_message.c
index 1e44214..3941518 100644
--- a/libcli/ldap/ldap_message.c
+++ b/libcli/ldap/ldap_message.c
@@ -1609,5 +1609,5 @@ _PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data,
 */
 NTSTATUS ldap_full_packet(void *private_data, DATA_BLOB blob, size_t *packet_size)
 {
-	return asn1_full_tag(blob, ASN1_SEQUENCE(0), packet_size);
+	return asn1_peek_full_tag(blob, ASN1_SEQUENCE(0), packet_size);
 }
diff --git a/libcli/util/tstream.c b/libcli/util/tstream.c
index 5d0e561..b287597 100644
--- a/libcli/util/tstream.c
+++ b/libcli/util/tstream.c
@@ -97,7 +97,9 @@ static void tstream_read_pdu_blob_done(struct tevent_req *subreq)
 		struct tstream_read_pdu_blob_state);
 	ssize_t ret;
 	int sys_errno;
-	size_t pdu_size;
+	size_t old_buf_size = state->pdu_blob.length;
+	size_t new_buf_size = 0;
+	size_t pdu_size = 0;
 	NTSTATUS status;
 	uint8_t *buf;
 
@@ -116,20 +118,26 @@ static void tstream_read_pdu_blob_done(struct tevent_req *subreq)
 		return;
 	} else if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
 		/* more to get */
+		if (pdu_size > 0) {
+			new_buf_size = pdu_size;
+		} else {
+			/* we don't know the size yet, so get one more byte */
+			new_buf_size = old_buf_size + 1;
+		}
 	} else if (!NT_STATUS_IS_OK(status)) {
 		tevent_req_nterror(req, status);
 		return;
 	}
 
-	buf = talloc_realloc(state, state->pdu_blob.data, uint8_t, pdu_size);
+	buf = talloc_realloc(state, state->pdu_blob.data, uint8_t, new_buf_size);
 	if (tevent_req_nomem(buf, req)) {
 		return;
 	}
 	state->pdu_blob.data = buf;
-	state->pdu_blob.length = pdu_size;
+	state->pdu_blob.length = new_buf_size;
 
-	state->tmp_vector.iov_base = (char *) (buf + state->tmp_vector.iov_len);
-	state->tmp_vector.iov_len = pdu_size - state->tmp_vector.iov_len;
+	state->tmp_vector.iov_base = (char *) (buf + old_buf_size);
+	state->tmp_vector.iov_len = new_buf_size - old_buf_size;
 
 	subreq = tstream_readv_send(state,
 				    state->caller.ev,


-- 
Samba Shared Repository


More information about the samba-cvs mailing list