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 <me...@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 <me...@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 <me...@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

Reply via email to