[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