The branch, master has been updated via 77d959f midltests: add midltests-pipe-sync-ndr32-downgrade-02.idl via 45e3e54 midltests: support for fragmented RPC traffic via 6c0a4b6 midltests: print out the alloc_hint for requests and responses via 25e1928 midltests: improve NDR64 downgrade via 437db14 midltests: revert to a simple default midltests.idl from 9dcd5e6 s3-waf: add basic make test infrastructure, not able to test yet.
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 77d959fb157ee72f14d278c25ac33e4d84010222 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Sep 29 10:47:34 2010 +0200 midltests: add midltests-pipe-sync-ndr32-downgrade-02.idl metze commit 45e3e54e087120009a79cb70b3377e63cfc0033e Author: Stefan Metzmacher <me...@samba.org> Date: Wed Sep 29 09:37:05 2010 +0200 midltests: support for fragmented RPC traffic metze commit 6c0a4b6477df872d03696faec1b786ad3352a7ca Author: Stefan Metzmacher <me...@samba.org> Date: Wed Sep 29 09:06:58 2010 +0200 midltests: print out the alloc_hint for requests and responses metze commit 25e19287f01bec1390ef91ce2f617d78175531be Author: Stefan Metzmacher <me...@samba.org> Date: Wed Sep 29 06:03:08 2010 +0200 midltests: improve NDR64 downgrade metze commit 437db1452265a27e30fbba1c046ce14d0cffaa64 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Sep 29 10:28:29 2010 +0200 midltests: revert to a simple default midltests.idl metze ----------------------------------------------------------------------- Summary of changes: testprogs/win32/midltests/midltests.idl | 251 +-- testprogs/win32/midltests/midltests_tcp.c | 95 +- .../midltests-pipe-sync-ndr32-downgrade-02.idl} | 14 +- .../midltests-pipe-sync-ndr32-downgrade-02.txt | 3266 ++++++++++++++++++++ 4 files changed, 3360 insertions(+), 266 deletions(-) copy testprogs/win32/midltests/{midltests.idl => valid/midltests-pipe-sync-ndr32-downgrade-02.idl} (97%) create mode 100644 testprogs/win32/midltests/valid/midltests-pipe-sync-ndr32-downgrade-02.txt Changeset truncated at 500 lines: diff --git a/testprogs/win32/midltests/midltests.idl b/testprogs/win32/midltests/midltests.idl index 26ef939..0c0bbf8 100644 --- a/testprogs/win32/midltests/midltests.idl +++ b/testprogs/win32/midltests/midltests.idl @@ -22,7 +22,7 @@ cpp_quote("#define CONNECT_IP \"172.31.9.1\"") * For testing it might be needed to allow downgrades * to NDR32. This is needed when you use 'pipe'. */ -cpp_quote("#define DONOT_FORCE_NDR64 1") +//cpp_quote("#define DONOT_FORCE_NDR64 1") [ uuid("225b9fcb-eb3d-497b-8b0b-591f049a2507"), @@ -30,267 +30,22 @@ cpp_quote("#define DONOT_FORCE_NDR64 1") ] interface midltests { - typedef pipe char pipe_char; - typedef pipe hyper pipe_hyper; - typedef struct { - long l; - short s; - } structtype; - typedef pipe structtype pipe_structtype; - - struct msg { - long l; - [size_is(l)] char *m; - }; - long midltests_fn( - [out,ref] struct msg *out1, - [out] pipe_structtype outp, - [in] pipe_structtype inp, - [in] struct msg in1 ); - - long midltests_ping( [in] struct msg in1); - } #elif MIDLTESTS_C_CODE -struct pipe_char_state { - const char *name; - unsigned long count; - unsigned long sleep; -}; - -void pipe_char_pull( - char * _state, - unsigned char * buf, - unsigned long esize, - unsigned long * ecount) -{ - struct pipe_char_state *state = (struct pipe_char_state *)_state; - - printf("pull1:%s: esize[%u] ecount[%u]\n", - state->name, esize, *ecount); - *ecount = state->count--; - if (*ecount > esize) { - *ecount = esize; - } - memset(buf, 0xDD, *ecount * sizeof(*buf)); - printf("pull2:%s: esize[%u] ecount[%u]\n", - state->name, esize, *ecount); -} - -void pipe_char_push( - char * _state, - unsigned char * buf, - unsigned long ecount) -{ - struct pipe_char_state *state = (struct pipe_char_state *)_state; - - printf("push:%s: ecount[%u]\n", - state->name, ecount); -} - -void pipe_char_alloc( - char * _state, - unsigned long bsize, - unsigned char * * buf, - unsigned long * bcount) -{ - struct pipe_char_state *state = (struct pipe_char_state *)_state; - - printf("alloc1:%s: bsize[%u], bcount[%u]\n", - state->name, bsize, *bcount); - *bcount = bsize / sizeof(**buf); - *buf = malloc(*bcount * sizeof(**buf)); - printf("alloc2:%s: bsize[%u], bcount[%u]\n", - state->name, bsize, *bcount); -} - -struct pipe_hyper_state { - const char *name; - unsigned long count; - unsigned long sleep; -}; - -void pipe_hyper_pull( - char * _state, - hyper * buf, - unsigned long esize, - unsigned long * ecount) -{ - struct pipe_hyper_state *state = (struct pipe_hyper_state *)_state; - - printf("pull1:%s: esize[%u] ecount[%u]\n", - state->name, esize, *ecount); - *ecount = state->count--; - if (*ecount > esize) { - *ecount = esize; - } - memset(buf, 0xDD, *ecount * sizeof(*buf)); - printf("pull2:%s: esize[%u] ecount[%u]\n", - state->name, esize, *ecount); -} - -void pipe_hyper_push( - char * _state, - hyper * buf, - unsigned long ecount) -{ - struct pipe_hyper_state *state = (struct pipe_hyper_state *)_state; - - printf("push:%s: ecount[%u]\n", - state->name, ecount); -} - -void pipe_hyper_alloc( - char * _state, - unsigned long bsize, - hyper * * buf, - unsigned long * bcount) -{ - struct pipe_hyper_state *state = (struct pipe_hyper_state *)_state; - - printf("alloc1:%s: bsize[%u], bcount[%u]\n", - state->name, bsize, *bcount); - *bcount = bsize / sizeof(**buf); - *buf = malloc(*bcount * sizeof(**buf)); - printf("alloc2:%s: bsize[%u], bcount[%u]\n", - state->name, bsize, *bcount); -} -struct pipe_structtype_state { - const char *name; - unsigned long count; - unsigned long sleep; -}; - -void pipe_structtype_pull( - char * _state, - structtype * buf, - unsigned long esize, - unsigned long * ecount) -{ - struct pipe_structtype_state *state = (struct pipe_structtype_state *)_state; - - printf("pull1:%s: esize[%u] ecount[%u]\n", - state->name, esize, *ecount); - *ecount = state->count--; - if (*ecount > esize) { - *ecount = esize; - } - memset(buf, 0xDD, *ecount * sizeof(*buf)); - printf("pull2:%s: esize[%u] ecount[%u]\n", - state->name, esize, *ecount); -} - -void pipe_structtype_push( - char * _state, - structtype * buf, - unsigned long ecount) -{ - struct pipe_structtype_state *state = (struct pipe_structtype_state *)_state; - - printf("push:%s: ecount[%u]\n", - state->name, ecount); -} - -void pipe_structtype_alloc( - char * _state, - unsigned long bsize, - structtype * * buf, - unsigned long * bcount) -{ - struct pipe_structtype_state *state = (struct pipe_structtype_state *)_state; - - printf("alloc1:%s: bsize[%u], bcount[%u]\n", - state->name, bsize, *bcount); - *bcount = bsize / sizeof(**buf); - *buf = malloc(*bcount * sizeof(**buf)); - printf("alloc2:%s: bsize[%u], bcount[%u]\n", - state->name, bsize, *bcount); -} static void midltests(void) { - struct msg out1; - unsigned char out1b[3]; - struct pipe_structtype_state outs; - pipe_structtype outp; - struct pipe_structtype_state ins; - pipe_structtype inp; - struct msg in1; - unsigned char in1b[3]; - - in1.l = sizeof(in1b); - memset(&in1b, 0xAA, sizeof(in1b)); - in1.m = in1b; - - memset(&outs, 0, sizeof(outs)); - outs.name = "outp"; - memset(&outp, 0, sizeof(outp)); - outp.pull = pipe_structtype_pull; - outp.push = pipe_structtype_push; - outp.alloc = pipe_structtype_alloc; - outp.state = (char *)&outs; - - memset(&ins, 0, sizeof(ins)); - ins.name = "inp"; - ins.count = 1; - memset(&inp, 0, sizeof(inp)); - inp.pull = pipe_structtype_pull; - inp.push = pipe_structtype_push; - inp.alloc = pipe_structtype_alloc; - inp.state = (char *)&ins; - - out1.l = sizeof(out1b); - memset(&out1b, 0xFF, sizeof(out1b)); - out1.m = out1b; - - cli_midltests_ping(in1); - cli_midltests_fn(&out1, outp, inp, in1); + cli_midltests_fn(); } -long srv_midltests_fn( - /* [ref][out] */ struct msg *out1, - /* [out] */ pipe_structtype outp, - /* [in] */ pipe_structtype inp, - /* [in] */ struct msg in1) +long srv_midltests_fn(void) { - structtype inb[500]; - unsigned long inb_len = 0; - structtype *outb = NULL; - unsigned long outb_size = 0; - unsigned long outb_len = 0; - printf("srv_midltests_fn: Start\n"); - - do { - inp.pull(inp.state, inb, sizeof(inb), &inb_len); - printf("pull inp_len[%u]\n", inb_len); - } while (inb_len > 0); - - outb_size = 5; - do { - outp.alloc(outp.state, outb_size, &outb, &outb_len); - memset(outb, 0xCC, outb_len * sizeof(*outb)); - outp.push(outp.state, outb, outb_len); - printf("push outb_len[%u]\n", outb_len); - //Sleep(1000); - outb_size--; - } while (outb_len > 0); - - out1->l = 3; - out1->m = (unsigned char *)malloc(out1->l); - memset(out1->m, 0xBB, out1->l); printf("srv_midltests_fn: End\n"); return 0x65757254; } -long srv_midltests_ping( - /* [in] */ struct msg in1) -{ - printf("srv_midltests_fn: Start\n"); - printf("srv_midltests_fn: End\n"); - return 0x65757254; -} #endif diff --git a/testprogs/win32/midltests/midltests_tcp.c b/testprogs/win32/midltests/midltests_tcp.c index 41a698c..3046f6d 100644 --- a/testprogs/win32/midltests/midltests_tcp.c +++ b/testprogs/win32/midltests/midltests_tcp.c @@ -101,18 +101,18 @@ static void dump_packet(const char *ctx, const char *direction, switch (hdr->ptype) { case 0: /* request */ - printf("%s:%s: ptype[request] flen[%d] plen[%d]\n\n", + printf("%s:%s: ptype[request] flen[%d] plen[%d] ahint[%d]\n\n", ctx, direction, hdr->frag_length, - len - 24); + len - 24, *(DWORD *)(&buf[0x10])); dump_data(buf + 24, len - 24); printf("\n"); fflush(stdout); break; case 2: /* response */ - printf("\n%s:%s: ptype[response] flen[%d] plen[%d]\n\n", + printf("\n%s:%s: ptype[response] flen[%d] plen[%d] ahint[%d]\n\n", ctx, direction, hdr->frag_length, - len - 24); + len - 24, *(DWORD *)(&buf[0x10])); dump_data(buf + 24, len - 24); printf("\n"); fflush(stdout); @@ -168,6 +168,11 @@ static void change_packet(const char *ctx, BOOL ndr64, unsigned char *buf, int len) { struct dcerpc_header *hdr = (struct dcerpc_header *)buf; + BOOL is_ndr64 = FALSE; + const unsigned char ndr64_buf[] = { + 0x33, 0x05, 0x71, 0x71, 0xBA, 0xBE, 0x37, 0x49, + 0x83, 0x19, 0xB5, 0xDB, 0xEF, 0x9C, 0xCC, 0x36 + }; if (len < sizeof(struct dcerpc_header)) { printf("%s: invalid dcerpc pdu len(%d)\n", @@ -193,18 +198,30 @@ static void change_packet(const char *ctx, BOOL ndr64, switch (hdr->ptype) { case 11: /* bind */ - if (buf[24] == 3 && !ndr64) { + case 14: /* alter_req */ + + if (buf[24] >= 2) { + int ret; + + ret = memcmp(&buf[0x60], ndr64_buf, 16); + if (ret == 0) { + is_ndr64 = TRUE; + } + } + + if (is_ndr64 && !ndr64) { buf[24+0x48] = 0xFF; + memset(&buf[0x60], 0xFF, 16); printf("%s: disable NDR64\n\n", ctx); - } else if (buf[24] < 3 && ndr64) { + } else if (!is_ndr64 && ndr64) { printf("\n%s: got NDR32 downgrade\n\n", ctx); #ifndef DONOT_FORCE_NDR64 printf("\n\tERROR!!!\n\n"); - buf[24] = 0x00; + memset(&buf[0x34], 0xFF, 16); printf("You may need to run 'vcvarsall.bat amd64' before 'nmake tcp'\n"); #endif printf("\n"); - } else if (buf[24] == 3 && ndr64) { + } else if (is_ndr64) { printf("%s: got NDR64\n\n", ctx); } else { printf("%s: got NDR32\n\n", ctx); @@ -215,6 +232,44 @@ static void change_packet(const char *ctx, BOOL ndr64, } } +static int sock_pending(SOCKET s) +{ + int ret, error; + int value = 0; + int len; + + ret = ioctlsocket(s, FIONREAD, &value); + if (ret == -1) { + return ret; + } + + if (ret != 0) { + /* this should not be reached */ + return -1; + } + + if (value != 0) { + return value; + } + + error = 0; + len = sizeof(error); + + /* + * if no data is available check if the socket is in error state. For + * dgram sockets it's the way to return ICMP error messages of + * connected sockets to the caller. + */ + ret = getsockopt(s, SOL_SOCKET, SO_ERROR, (char *)&error, &len); + if (ret == -1) { + return ret; + } + if (error != 0) { + return -1; + } + return 0; +} + DWORD WINAPI NDRProxyThread(LPVOID lpParameter) { struct NDRProxyThreadCtx *p = (struct NDRProxyThreadCtx *)lpParameter; @@ -224,12 +279,19 @@ DWORD WINAPI NDRProxyThread(LPVOID lpParameter) int ret = -1; BYTE buf[5840]; + Sleep(250); + + ret = sock_pending(p->InSocket); + if (ret == 0) { + goto out; + } + r = recv(p->InSocket, buf, sizeof(buf), 0); if (r <= 0) { ret = WSAGetLastError(); printf("%s: recv(in) failed[%d][%d]\n", p->ctx->name, r, ret); fflush(stdout); - goto next; + goto stop; } change_packet(p->ctx->name, p->ctx->ndr64, buf, r); @@ -238,11 +300,17 @@ DWORD WINAPI NDRProxyThread(LPVOID lpParameter) dump_packet(p->ctx->name, "in => out", buf, r); fflush(stdout); +out: s = send(p->OutSocket, buf, r, 0); if (s <= 0) { ret = WSAGetLastError(); printf("%s: send(out) failed[%d][%d]\n", p->ctx->name, s, ret); fflush(stdout); + goto stop; + } + + ret = sock_pending(p->OutSocket); + if (ret == 0) { goto next; } @@ -251,7 +319,7 @@ DWORD WINAPI NDRProxyThread(LPVOID lpParameter) ret = WSAGetLastError(); printf("%s: recv(out) failed[%d][%d]\n", p->ctx->name, r, ret); fflush(stdout); - goto next; + goto stop; } dump_packet(p->ctx->name, "out => in", buf, r); @@ -262,11 +330,12 @@ DWORD WINAPI NDRProxyThread(LPVOID lpParameter) ret = WSAGetLastError(); printf("%s: send(in) failed[%d][%d]\n", p->ctx->name, s, ret); fflush(stdout); - goto next; + goto stop; } - - } next: + continue; + } +stop: closesocket(p->InSocket); closesocket(p->OutSocket); diff --git a/testprogs/win32/midltests/midltests.idl b/testprogs/win32/midltests/valid/midltests-pipe-sync-ndr32-downgrade-02.idl similarity index 97% copy from testprogs/win32/midltests/midltests.idl copy to testprogs/win32/midltests/valid/midltests-pipe-sync-ndr32-downgrade-02.idl index 26ef939..888ba79 100644 --- a/testprogs/win32/midltests/midltests.idl +++ b/testprogs/win32/midltests/valid/midltests-pipe-sync-ndr32-downgrade-02.idl @@ -219,7 +219,7 @@ static void midltests(void) struct pipe_structtype_state ins; pipe_structtype inp; struct msg in1; - unsigned char in1b[3]; + unsigned char in1b[3000]; in1.l = sizeof(in1b); memset(&in1b, 0xAA, sizeof(in1b)); @@ -235,7 +235,7 @@ static void midltests(void) memset(&ins, 0, sizeof(ins)); ins.name = "inp"; - ins.count = 1; + ins.count = 35; memset(&inp, 0, sizeof(inp)); inp.pull = pipe_structtype_pull; inp.push = pipe_structtype_push; @@ -256,25 +256,28 @@ long srv_midltests_fn( /* [in] */ pipe_structtype inp, /* [in] */ struct msg in1) { - structtype inb[500]; + structtype inb[2500]; unsigned long inb_len = 0; structtype *outb = NULL; unsigned long outb_size = 0; -- Samba Shared Repository