summaryrefslogtreecommitdiff
path: root/source3/rpc_parse/parse_prs.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/rpc_parse/parse_prs.c')
-rw-r--r--source3/rpc_parse/parse_prs.c146
1 files changed, 80 insertions, 66 deletions
diff --git a/source3/rpc_parse/parse_prs.c b/source3/rpc_parse/parse_prs.c
index 709a5d39af..d174bad444 100644
--- a/source3/rpc_parse/parse_prs.c
+++ b/source3/rpc_parse/parse_prs.c
@@ -34,7 +34,6 @@ void prs_dump(char *name, int v, prs_struct *ps)
prs_dump_region(name, v, ps, ps->data_offset, ps->buffer_size);
}
-
/**
* Dump from the start of the prs to the current location.
**/
@@ -43,7 +42,6 @@ void prs_dump_before(char *name, int v, prs_struct *ps)
prs_dump_region(name, v, ps, 0, ps->data_offset);
}
-
/**
* Dump everything from the start of the prs up to the current location.
**/
@@ -52,6 +50,7 @@ void prs_dump_region(char *name, int v, prs_struct *ps,
{
int fd, i;
pstring fname;
+ ssize_t sz;
if (DEBUGLEVEL < 50) return;
for (i=1;i<100;i++) {
if (v != -1) {
@@ -63,26 +62,28 @@ void prs_dump_region(char *name, int v, prs_struct *ps,
if (fd != -1 || errno != EEXIST) break;
}
if (fd != -1) {
- write(fd, ps->data_p + from_off, to_off - from_off);
- close(fd);
- DEBUG(0,("created %s\n", fname));
+ sz = write(fd, ps->data_p + from_off, to_off - from_off);
+ i = close(fd);
+ if ( (sz != to_off-from_off) || (i != 0) ) {
+ DEBUG(0,("Error writing/closing %s: %ld!=%ld %d\n", fname, (unsigned long)sz, (unsigned long)to_off-from_off, i ));
+ } else {
+ DEBUG(0,("created %s\n", fname));
+ }
}
}
-
-
/*******************************************************************
- debug output for parsing info.
+ Debug output for parsing info
- XXXX side-effect of this function is to increase the debug depth XXXX
+ XXXX side-effect of this function is to increase the debug depth XXXX.
+
+********************************************************************/
- ********************************************************************/
void prs_debug(prs_struct *ps, int depth, const char *desc, const char *fn_name)
{
DEBUG(5+depth, ("%s%06x %s %s\n", tab_depth(depth), ps->data_offset, fn_name, desc));
}
-
/**
* Initialise an expandable parse structure.
*
@@ -91,6 +92,7 @@ void prs_debug(prs_struct *ps, int depth, const char *desc, const char *fn_name)
*
* @return False if allocation fails, otherwise True.
**/
+
BOOL prs_init(prs_struct *ps, uint32 size, TALLOC_CTX *ctx, BOOL io)
{
ZERO_STRUCTP(ps);
@@ -111,6 +113,9 @@ BOOL prs_init(prs_struct *ps, uint32 size, TALLOC_CTX *ctx, BOOL io)
}
memset(ps->data_p, '\0', (size_t)size);
ps->is_dynamic = True; /* We own this memory. */
+ } else if (MARSHALLING(ps)) {
+ /* If size is zero and we're marshalling we should allocate memory on demand. */
+ ps->is_dynamic = True;
}
return True;
@@ -254,7 +259,7 @@ BOOL prs_grow(prs_struct *ps, uint32 extra_space)
* is greater.
*/
- new_size = MAX(MAX_PDU_FRAG_LEN,extra_space);
+ new_size = MAX(RPC_MAX_PDU_FRAG_LEN,extra_space);
if((new_data = SMB_MALLOC(new_size)) == NULL) {
DEBUG(0,("prs_grow: Malloc failure for size %u.\n", (unsigned int)new_size));
@@ -398,7 +403,7 @@ BOOL prs_append_some_prs_data(prs_struct *dst, prs_struct *src, int32 start, uin
Append the data from a buffer into a parse_struct.
********************************************************************/
-BOOL prs_copy_data_in(prs_struct *dst, char *src, uint32 len)
+BOOL prs_copy_data_in(prs_struct *dst, const char *src, uint32 len)
{
if (len == 0)
return True;
@@ -565,6 +570,15 @@ void prs_force_dynamic(prs_struct *ps)
}
/*******************************************************************
+ Associate a session key with a parse struct.
+ ********************************************************************/
+
+void prs_set_session_key(prs_struct *ps, const char sess_key[16])
+{
+ ps->sess_key = sess_key;
+}
+
+/*******************************************************************
Stream a uint8.
********************************************************************/
@@ -596,9 +610,9 @@ BOOL prs_pointer( const char *name, prs_struct *ps, int depth,
{
uint32 data_p;
- /* caputure the pointer value to stream */
+ /* output f000baaa to stream if the pointer is non-zero. */
- data_p = (uint32) *data;
+ data_p = *data ? 0xf000baaa : 0;
if ( !prs_uint32("ptr", ps, depth, &data_p ))
return False;
@@ -1387,7 +1401,7 @@ int tdb_prs_fetch(TDB_CONTEXT *tdb, char *keystr, prs_struct *ps, TALLOC_CTX *me
hash a stream.
********************************************************************/
-BOOL prs_hash1(prs_struct *ps, uint32 offset, uint8 sess_key[16], int len)
+BOOL prs_hash1(prs_struct *ps, uint32 offset, int len)
{
char *q;
@@ -1396,10 +1410,10 @@ BOOL prs_hash1(prs_struct *ps, uint32 offset, uint8 sess_key[16], int len)
#ifdef DEBUG_PASSWORD
DEBUG(100, ("prs_hash1\n"));
- dump_data(100, sess_key, 16);
+ dump_data(100, ps->sess_key, 16);
dump_data(100, q, len);
#endif
- SamOEMhash((uchar *) q, sess_key, len);
+ SamOEMhash((uchar *) q, ps->sess_key, len);
#ifdef DEBUG_PASSWORD
dump_data(100, q, len);
@@ -1413,9 +1427,9 @@ BOOL prs_hash1(prs_struct *ps, uint32 offset, uint8 sess_key[16], int len)
MD5 it with the session key.
********************************************************************/
-static void netsec_digest(struct netsec_auth_struct *a,
- int auth_flags,
- RPC_AUTH_NETSEC_CHK * verf,
+static void schannel_digest(struct schannel_auth_struct *a,
+ enum pipe_auth_level auth_level,
+ RPC_AUTH_SCHANNEL_CHK * verf,
char *data, size_t data_len,
uchar digest_final[16])
{
@@ -1429,7 +1443,7 @@ static void netsec_digest(struct netsec_auth_struct *a,
out of order */
MD5Update(&ctx3, zeros, sizeof(zeros));
MD5Update(&ctx3, verf->sig, sizeof(verf->sig));
- if (auth_flags & AUTH_PIPE_SEAL) {
+ if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
MD5Update(&ctx3, verf->confounder, sizeof(verf->confounder));
}
MD5Update(&ctx3, (const unsigned char *)data, data_len);
@@ -1445,8 +1459,8 @@ static void netsec_digest(struct netsec_auth_struct *a,
Calculate the key with which to encode the data payload
********************************************************************/
-static void netsec_get_sealing_key(struct netsec_auth_struct *a,
- RPC_AUTH_NETSEC_CHK *verf,
+static void schannel_get_sealing_key(struct schannel_auth_struct *a,
+ RPC_AUTH_SCHANNEL_CHK *verf,
uchar sealing_key[16])
{
static uchar zeros[4];
@@ -1473,8 +1487,8 @@ static void netsec_get_sealing_key(struct netsec_auth_struct *a,
Encode or Decode the sequence number (which is symmetric)
********************************************************************/
-static void netsec_deal_with_seq_num(struct netsec_auth_struct *a,
- RPC_AUTH_NETSEC_CHK *verf)
+static void schannel_deal_with_seq_num(struct schannel_auth_struct *a,
+ RPC_AUTH_SCHANNEL_CHK *verf)
{
static uchar zeros[4];
uchar sequence_key[16];
@@ -1493,10 +1507,10 @@ static void netsec_deal_with_seq_num(struct netsec_auth_struct *a,
}
/*******************************************************************
-creates an RPC_AUTH_NETSEC_CHK structure.
+creates an RPC_AUTH_SCHANNEL_CHK structure.
********************************************************************/
-static BOOL init_rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK * chk,
+static BOOL init_rpc_auth_schannel_chk(RPC_AUTH_SCHANNEL_CHK * chk,
const uchar sig[8],
const uchar packet_digest[8],
const uchar seq_num[8], const uchar confounder[8])
@@ -1513,15 +1527,15 @@ static BOOL init_rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK * chk,
}
/*******************************************************************
- Encode a blob of data using the netsec (schannel) alogrithm, also produceing
+ Encode a blob of data using the schannel alogrithm, also produceing
a checksum over the original data. We currently only support
signing and sealing togeather - the signing-only code is close, but not
quite compatible with what MS does.
********************************************************************/
-void netsec_encode(struct netsec_auth_struct *a, int auth_flags,
- enum netsec_direction direction,
- RPC_AUTH_NETSEC_CHK * verf,
+void schannel_encode(struct schannel_auth_struct *a, enum pipe_auth_level auth_level,
+ enum schannel_direction direction,
+ RPC_AUTH_SCHANNEL_CHK * verf,
char *data, size_t data_len)
{
uchar digest_final[16];
@@ -1529,16 +1543,16 @@ void netsec_encode(struct netsec_auth_struct *a, int auth_flags,
uchar seq_num[8];
static const uchar nullbytes[8];
- static const uchar netsec_seal_sig[8] = NETSEC_SEAL_SIGNATURE;
- static const uchar netsec_sign_sig[8] = NETSEC_SIGN_SIGNATURE;
- const uchar *netsec_sig = NULL;
+ static const uchar schannel_seal_sig[8] = SCHANNEL_SEAL_SIGNATURE;
+ static const uchar schannel_sign_sig[8] = SCHANNEL_SIGN_SIGNATURE;
+ const uchar *schannel_sig = NULL;
- DEBUG(10,("SCHANNEL: netsec_encode seq_num=%d data_len=%lu\n", a->seq_num, (unsigned long)data_len));
+ DEBUG(10,("SCHANNEL: schannel_encode seq_num=%d data_len=%lu\n", a->seq_num, (unsigned long)data_len));
- if (auth_flags & AUTH_PIPE_SEAL) {
- netsec_sig = netsec_seal_sig;
- } else if (auth_flags & AUTH_PIPE_SIGN) {
- netsec_sig = netsec_sign_sig;
+ if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
+ schannel_sig = schannel_seal_sig;
+ } else {
+ schannel_sig = schannel_sign_sig;
}
/* fill the 'confounder' with random data */
@@ -1559,18 +1573,18 @@ void netsec_encode(struct netsec_auth_struct *a, int auth_flags,
dump_data_pw("verf->seq_num:\n", seq_num, sizeof(verf->seq_num));
- init_rpc_auth_netsec_chk(verf, netsec_sig, nullbytes,
+ init_rpc_auth_schannel_chk(verf, schannel_sig, nullbytes,
seq_num, confounder);
/* produce a digest of the packet to prove it's legit (before we seal it) */
- netsec_digest(a, auth_flags, verf, data, data_len, digest_final);
+ schannel_digest(a, auth_level, verf, data, data_len, digest_final);
memcpy(verf->packet_digest, digest_final, sizeof(verf->packet_digest));
- if (auth_flags & AUTH_PIPE_SEAL) {
+ if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
uchar sealing_key[16];
/* get the key to encode the data with */
- netsec_get_sealing_key(a, verf, sealing_key);
+ schannel_get_sealing_key(a, verf, sealing_key);
/* encode the verification data */
dump_data_pw("verf->confounder:\n", verf->confounder, sizeof(verf->confounder));
@@ -1587,35 +1601,35 @@ void netsec_encode(struct netsec_auth_struct *a, int auth_flags,
/* encode the sequence number (key based on packet digest) */
/* needs to be done after the sealing, as the original version
is used in the sealing stuff... */
- netsec_deal_with_seq_num(a, verf);
+ schannel_deal_with_seq_num(a, verf);
return;
}
/*******************************************************************
- Decode a blob of data using the netsec (schannel) alogrithm, also verifiying
+ Decode a blob of data using the schannel alogrithm, also verifiying
a checksum over the original data. We currently can verify signed messages,
as well as decode sealed messages
********************************************************************/
-BOOL netsec_decode(struct netsec_auth_struct *a, int auth_flags,
- enum netsec_direction direction,
- RPC_AUTH_NETSEC_CHK * verf, char *data, size_t data_len)
+BOOL schannel_decode(struct schannel_auth_struct *a, enum pipe_auth_level auth_level,
+ enum schannel_direction direction,
+ RPC_AUTH_SCHANNEL_CHK * verf, char *data, size_t data_len)
{
uchar digest_final[16];
- static const uchar netsec_seal_sig[8] = NETSEC_SEAL_SIGNATURE;
- static const uchar netsec_sign_sig[8] = NETSEC_SIGN_SIGNATURE;
- const uchar *netsec_sig = NULL;
+ static const uchar schannel_seal_sig[8] = SCHANNEL_SEAL_SIGNATURE;
+ static const uchar schannel_sign_sig[8] = SCHANNEL_SIGN_SIGNATURE;
+ const uchar *schannel_sig = NULL;
uchar seq_num[8];
- DEBUG(10,("SCHANNEL: netsec_encode seq_num=%d data_len=%lu\n", a->seq_num, (unsigned long)data_len));
+ DEBUG(10,("SCHANNEL: schannel_decode seq_num=%d data_len=%lu\n", a->seq_num, (unsigned long)data_len));
- if (auth_flags & AUTH_PIPE_SEAL) {
- netsec_sig = netsec_seal_sig;
- } else if (auth_flags & AUTH_PIPE_SIGN) {
- netsec_sig = netsec_sign_sig;
+ if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
+ schannel_sig = schannel_seal_sig;
+ } else {
+ schannel_sig = schannel_sign_sig;
}
/* Create the expected sequence number for comparison */
@@ -1630,7 +1644,7 @@ BOOL netsec_decode(struct netsec_auth_struct *a, int auth_flags,
break;
}
- DEBUG(10,("SCHANNEL: netsec_decode seq_num=%d data_len=%lu\n", a->seq_num, (unsigned long)data_len));
+ DEBUG(10,("SCHANNEL: schannel_decode seq_num=%d data_len=%lu\n", a->seq_num, (unsigned long)data_len));
dump_data_pw("a->sess_key:\n", a->sess_key, sizeof(a->sess_key));
dump_data_pw("seq_num:\n", seq_num, sizeof(seq_num));
@@ -1638,7 +1652,7 @@ BOOL netsec_decode(struct netsec_auth_struct *a, int auth_flags,
/* extract the sequence number (key based on supplied packet digest) */
/* needs to be done before the sealing, as the original version
is used in the sealing stuff... */
- netsec_deal_with_seq_num(a, verf);
+ schannel_deal_with_seq_num(a, verf);
if (memcmp(verf->seq_num, seq_num, sizeof(seq_num))) {
/* don't even bother with the below if the sequence number is out */
@@ -1646,7 +1660,7 @@ BOOL netsec_decode(struct netsec_auth_struct *a, int auth_flags,
digest, as supplied by the client. We check that it's a valid
checksum after the decode, below
*/
- DEBUG(2, ("netsec_decode: FAILED: packet sequence number:\n"));
+ DEBUG(2, ("schannel_decode: FAILED: packet sequence number:\n"));
dump_data(2, (const char*)verf->seq_num, sizeof(verf->seq_num));
DEBUG(2, ("should be:\n"));
dump_data(2, (const char*)seq_num, sizeof(seq_num));
@@ -1654,20 +1668,20 @@ BOOL netsec_decode(struct netsec_auth_struct *a, int auth_flags,
return False;
}
- if (memcmp(verf->sig, netsec_sig, sizeof(verf->sig))) {
+ if (memcmp(verf->sig, schannel_sig, sizeof(verf->sig))) {
/* Validate that the other end sent the expected header */
- DEBUG(2, ("netsec_decode: FAILED: packet header:\n"));
+ DEBUG(2, ("schannel_decode: FAILED: packet header:\n"));
dump_data(2, (const char*)verf->sig, sizeof(verf->sig));
DEBUG(2, ("should be:\n"));
- dump_data(2, (const char*)netsec_sig, sizeof(netsec_sig));
+ dump_data(2, (const char*)schannel_sig, sizeof(schannel_sig));
return False;
}
- if (auth_flags & AUTH_PIPE_SEAL) {
+ if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
uchar sealing_key[16];
/* get the key to extract the data with */
- netsec_get_sealing_key(a, verf, sealing_key);
+ schannel_get_sealing_key(a, verf, sealing_key);
/* extract the verification data */
dump_data_pw("verf->confounder:\n", verf->confounder,
@@ -1684,7 +1698,7 @@ BOOL netsec_decode(struct netsec_auth_struct *a, int auth_flags,
}
/* digest includes 'data' after unsealing */
- netsec_digest(a, auth_flags, verf, data, data_len, digest_final);
+ schannel_digest(a, auth_level, verf, data, data_len, digest_final);
dump_data_pw("Calculated digest:\n", digest_final,
sizeof(digest_final));