00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "includes.h"
00025
00026 #undef DBGC_CLASS
00027 #define DBGC_CLASS DBGC_RPC_PARSE
00028
00029
00030
00031
00032 void prs_dump(char *name, int v, prs_struct *ps)
00033 {
00034 prs_dump_region(name, v, ps, ps->data_offset, ps->buffer_size);
00035 }
00036
00037
00038
00039
00040 void prs_dump_before(char *name, int v, prs_struct *ps)
00041 {
00042 prs_dump_region(name, v, ps, 0, ps->data_offset);
00043 }
00044
00045
00046
00047
00048 void prs_dump_region(char *name, int v, prs_struct *ps,
00049 int from_off, int to_off)
00050 {
00051 int fd, i;
00052 pstring fname;
00053 ssize_t sz;
00054 if (DEBUGLEVEL < 50) return;
00055 for (i=1;i<100;i++) {
00056 if (v != -1) {
00057 slprintf(fname,sizeof(fname)-1, "/tmp/%s_%d.%d.prs", name, v, i);
00058 } else {
00059 slprintf(fname,sizeof(fname)-1, "/tmp/%s.%d.prs", name, i);
00060 }
00061 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
00062 if (fd != -1 || errno != EEXIST) break;
00063 }
00064 if (fd != -1) {
00065 sz = write(fd, ps->data_p + from_off, to_off - from_off);
00066 i = close(fd);
00067 if ( (sz != to_off-from_off) || (i != 0) ) {
00068 DEBUG(0,("Error writing/closing %s: %ld!=%ld %d\n", fname, (unsigned long)sz, (unsigned long)to_off-from_off, i ));
00069 } else {
00070 DEBUG(0,("created %s\n", fname));
00071 }
00072 }
00073 }
00074
00075
00076
00077
00078
00079
00080
00081
00082 void prs_debug(prs_struct *ps, int depth, const char *desc, const char *fn_name)
00083 {
00084 DEBUG(5+depth, ("%s%06x %s %s\n", tab_depth(depth), ps->data_offset, fn_name, desc));
00085 }
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096 BOOL prs_init(prs_struct *ps, uint32 size, TALLOC_CTX *ctx, BOOL io)
00097 {
00098 ZERO_STRUCTP(ps);
00099 ps->io = io;
00100 ps->bigendian_data = RPC_LITTLE_ENDIAN;
00101 ps->align = RPC_PARSE_ALIGN;
00102 ps->is_dynamic = False;
00103 ps->data_offset = 0;
00104 ps->buffer_size = 0;
00105 ps->data_p = NULL;
00106 ps->mem_ctx = ctx;
00107
00108 if (size != 0) {
00109 ps->buffer_size = size;
00110 if((ps->data_p = (char *)SMB_MALLOC((size_t)size)) == NULL) {
00111 DEBUG(0,("prs_init: malloc fail for %u bytes.\n", (unsigned int)size));
00112 return False;
00113 }
00114 memset(ps->data_p, '\0', (size_t)size);
00115 ps->is_dynamic = True;
00116 } else if (MARSHALLING(ps)) {
00117
00118 ps->is_dynamic = True;
00119 }
00120
00121 return True;
00122 }
00123
00124
00125
00126
00127
00128 void prs_mem_free(prs_struct *ps)
00129 {
00130 if(ps->is_dynamic)
00131 SAFE_FREE(ps->data_p);
00132 ps->is_dynamic = False;
00133 ps->buffer_size = 0;
00134 ps->data_offset = 0;
00135 }
00136
00137
00138
00139
00140
00141 void prs_mem_clear(prs_struct *ps)
00142 {
00143 if (ps->buffer_size)
00144 memset(ps->data_p, '\0', (size_t)ps->buffer_size);
00145 }
00146
00147
00148
00149
00150
00151 #if defined(PARANOID_MALLOC_CHECKER)
00152 char *prs_alloc_mem_(prs_struct *ps, size_t size, unsigned int count)
00153 #else
00154 char *prs_alloc_mem(prs_struct *ps, size_t size, unsigned int count)
00155 #endif
00156 {
00157 char *ret = NULL;
00158
00159 if (size && count) {
00160
00161 ret = (char *)_talloc_zero_array_zeronull(ps->mem_ctx, size, count,
00162 "parse_prs");
00163 }
00164 return ret;
00165 }
00166
00167
00168
00169
00170
00171 TALLOC_CTX *prs_get_mem_context(prs_struct *ps)
00172 {
00173 return ps->mem_ctx;
00174 }
00175
00176
00177
00178
00179
00180 void prs_give_memory(prs_struct *ps, char *buf, uint32 size, BOOL is_dynamic)
00181 {
00182 ps->is_dynamic = is_dynamic;
00183 ps->data_p = buf;
00184 ps->buffer_size = size;
00185 }
00186
00187
00188
00189
00190
00191 char *prs_take_memory(prs_struct *ps, uint32 *psize)
00192 {
00193 char *ret = ps->data_p;
00194 if(psize)
00195 *psize = ps->buffer_size;
00196 ps->is_dynamic = False;
00197 prs_mem_free(ps);
00198 return ret;
00199 }
00200
00201
00202
00203
00204
00205 BOOL prs_set_buffer_size(prs_struct *ps, uint32 newsize)
00206 {
00207 if (newsize > ps->buffer_size)
00208 return prs_force_grow(ps, newsize - ps->buffer_size);
00209
00210 if (newsize < ps->buffer_size) {
00211 ps->buffer_size = newsize;
00212
00213
00214 if (newsize == 0) {
00215 SAFE_FREE(ps->data_p);
00216 } else {
00217 ps->data_p = (char *)SMB_REALLOC(ps->data_p, newsize);
00218
00219 if (ps->data_p == NULL) {
00220 DEBUG(0,("prs_set_buffer_size: Realloc failure for size %u.\n",
00221 (unsigned int)newsize));
00222 DEBUG(0,("prs_set_buffer_size: Reason %s\n",strerror(errno)));
00223 return False;
00224 }
00225 }
00226 }
00227
00228 return True;
00229 }
00230
00231
00232
00233
00234
00235
00236 BOOL prs_grow(prs_struct *ps, uint32 extra_space)
00237 {
00238 uint32 new_size;
00239
00240 ps->grow_size = MAX(ps->grow_size, ps->data_offset + extra_space);
00241
00242 if(ps->data_offset + extra_space <= ps->buffer_size)
00243 return True;
00244
00245
00246
00247
00248
00249
00250 if(UNMARSHALLING(ps) || !ps->is_dynamic) {
00251 DEBUG(0,("prs_grow: Buffer overflow - unable to expand buffer by %u bytes.\n",
00252 (unsigned int)extra_space));
00253 return False;
00254 }
00255
00256
00257
00258
00259
00260 extra_space -= (ps->buffer_size - ps->data_offset);
00261 if(ps->buffer_size == 0) {
00262
00263
00264
00265
00266
00267 new_size = MAX(RPC_MAX_PDU_FRAG_LEN,extra_space);
00268
00269 if((ps->data_p = (char *)SMB_MALLOC(new_size)) == NULL) {
00270 DEBUG(0,("prs_grow: Malloc failure for size %u.\n", (unsigned int)new_size));
00271 return False;
00272 }
00273 memset(ps->data_p, '\0', (size_t)new_size );
00274 } else {
00275
00276
00277
00278
00279 new_size = MAX(ps->buffer_size*2, ps->buffer_size + extra_space);
00280
00281 if ((ps->data_p = (char *)SMB_REALLOC(ps->data_p, new_size)) == NULL) {
00282 DEBUG(0,("prs_grow: Realloc failure for size %u.\n",
00283 (unsigned int)new_size));
00284 return False;
00285 }
00286
00287 memset(&ps->data_p[ps->buffer_size], '\0', (size_t)(new_size - ps->buffer_size));
00288 }
00289 ps->buffer_size = new_size;
00290
00291 return True;
00292 }
00293
00294
00295
00296
00297
00298
00299
00300 BOOL prs_force_grow(prs_struct *ps, uint32 extra_space)
00301 {
00302 uint32 new_size = ps->buffer_size + extra_space;
00303
00304 if(!UNMARSHALLING(ps) || !ps->is_dynamic) {
00305 DEBUG(0,("prs_force_grow: Buffer overflow - unable to expand buffer by %u bytes.\n",
00306 (unsigned int)extra_space));
00307 return False;
00308 }
00309
00310 if((ps->data_p = (char *)SMB_REALLOC(ps->data_p, new_size)) == NULL) {
00311 DEBUG(0,("prs_force_grow: Realloc failure for size %u.\n",
00312 (unsigned int)new_size));
00313 return False;
00314 }
00315
00316 memset(&ps->data_p[ps->buffer_size], '\0', (size_t)(new_size - ps->buffer_size));
00317
00318 ps->buffer_size = new_size;
00319
00320 return True;
00321 }
00322
00323
00324
00325
00326
00327 char *prs_data_p(prs_struct *ps)
00328 {
00329 return ps->data_p;
00330 }
00331
00332
00333
00334
00335
00336 uint32 prs_data_size(prs_struct *ps)
00337 {
00338 return ps->buffer_size;
00339 }
00340
00341
00342
00343
00344
00345 uint32 prs_offset(prs_struct *ps)
00346 {
00347 return ps->data_offset;
00348 }
00349
00350
00351
00352
00353
00354 BOOL prs_set_offset(prs_struct *ps, uint32 offset)
00355 {
00356 if(offset <= ps->data_offset) {
00357 ps->data_offset = offset;
00358 return True;
00359 }
00360
00361 if(!prs_grow(ps, offset - ps->data_offset))
00362 return False;
00363
00364 ps->data_offset = offset;
00365 return True;
00366 }
00367
00368
00369
00370
00371
00372 BOOL prs_append_prs_data(prs_struct *dst, prs_struct *src)
00373 {
00374 if (prs_offset(src) == 0)
00375 return True;
00376
00377 if(!prs_grow(dst, prs_offset(src)))
00378 return False;
00379
00380 memcpy(&dst->data_p[dst->data_offset], src->data_p, (size_t)prs_offset(src));
00381 dst->data_offset += prs_offset(src);
00382
00383 return True;
00384 }
00385
00386
00387
00388
00389
00390 BOOL prs_append_some_prs_data(prs_struct *dst, prs_struct *src, int32 start, uint32 len)
00391 {
00392 if (len == 0)
00393 return True;
00394
00395 if(!prs_grow(dst, len))
00396 return False;
00397
00398 memcpy(&dst->data_p[dst->data_offset], src->data_p + start, (size_t)len);
00399 dst->data_offset += len;
00400
00401 return True;
00402 }
00403
00404
00405
00406
00407
00408 BOOL prs_copy_data_in(prs_struct *dst, const char *src, uint32 len)
00409 {
00410 if (len == 0)
00411 return True;
00412
00413 if(!prs_grow(dst, len))
00414 return False;
00415
00416 memcpy(&dst->data_p[dst->data_offset], src, (size_t)len);
00417 dst->data_offset += len;
00418
00419 return True;
00420 }
00421
00422
00423
00424
00425
00426 BOOL prs_copy_data_out(char *dst, prs_struct *src, uint32 len)
00427 {
00428 if (len == 0)
00429 return True;
00430
00431 if(!prs_mem_get(src, len))
00432 return False;
00433
00434 memcpy(dst, &src->data_p[src->data_offset], (size_t)len);
00435 src->data_offset += len;
00436
00437 return True;
00438 }
00439
00440
00441
00442
00443
00444 BOOL prs_copy_all_data_out(char *dst, prs_struct *src)
00445 {
00446 uint32 len = prs_offset(src);
00447
00448 if (!len)
00449 return True;
00450
00451 prs_set_offset(src, 0);
00452 return prs_copy_data_out(dst, src, len);
00453 }
00454
00455
00456
00457
00458
00459 void prs_set_endian_data(prs_struct *ps, BOOL endian)
00460 {
00461 ps->bigendian_data = endian;
00462 }
00463
00464
00465
00466
00467
00468
00469 BOOL prs_align(prs_struct *ps)
00470 {
00471 uint32 mod = ps->data_offset & (ps->align-1);
00472
00473 if (ps->align != 0 && mod != 0) {
00474 uint32 extra_space = (ps->align - mod);
00475 if(!prs_grow(ps, extra_space))
00476 return False;
00477 memset(&ps->data_p[ps->data_offset], '\0', (size_t)extra_space);
00478 ps->data_offset += extra_space;
00479 }
00480
00481 return True;
00482 }
00483
00484
00485
00486
00487
00488 BOOL prs_align_uint16(prs_struct *ps)
00489 {
00490 BOOL ret;
00491 uint8 old_align = ps->align;
00492
00493 ps->align = 2;
00494 ret = prs_align(ps);
00495 ps->align = old_align;
00496
00497 return ret;
00498 }
00499
00500
00501
00502
00503
00504 BOOL prs_align_uint64(prs_struct *ps)
00505 {
00506 BOOL ret;
00507 uint8 old_align = ps->align;
00508
00509 ps->align = 8;
00510 ret = prs_align(ps);
00511 ps->align = old_align;
00512
00513 return ret;
00514 }
00515
00516
00517
00518
00519
00520 BOOL prs_align_custom(prs_struct *ps, uint8 boundary)
00521 {
00522 BOOL ret;
00523 uint8 old_align = ps->align;
00524
00525 ps->align = boundary;
00526 ret = prs_align(ps);
00527 ps->align = old_align;
00528
00529 return ret;
00530 }
00531
00532
00533
00534
00535
00536
00537
00538 BOOL prs_align_needed(prs_struct *ps, uint32 needed)
00539 {
00540 if (needed==0)
00541 return True;
00542 else
00543 return prs_align(ps);
00544 }
00545
00546
00547
00548
00549
00550 char *prs_mem_get(prs_struct *ps, uint32 extra_size)
00551 {
00552 if(UNMARSHALLING(ps)) {
00553
00554
00555
00556 if (ps->data_offset + extra_size > ps->buffer_size) {
00557 DEBUG(0,("prs_mem_get: reading data of size %u would overrun "
00558 "buffer by %u bytes.\n",
00559 (unsigned int)extra_size,
00560 (unsigned int)(ps->data_offset + extra_size - ps->buffer_size) ));
00561 return NULL;
00562 }
00563 } else {
00564
00565
00566
00567 if(!prs_grow(ps, extra_size))
00568 return NULL;
00569 }
00570 return &ps->data_p[ps->data_offset];
00571 }
00572
00573
00574
00575
00576
00577 void prs_switch_type(prs_struct *ps, BOOL io)
00578 {
00579 if ((ps->io ^ io) == True)
00580 ps->io=io;
00581 }
00582
00583
00584
00585
00586
00587 void prs_force_dynamic(prs_struct *ps)
00588 {
00589 ps->is_dynamic=True;
00590 }
00591
00592
00593
00594
00595
00596 void prs_set_session_key(prs_struct *ps, const char sess_key[16])
00597 {
00598 ps->sess_key = sess_key;
00599 }
00600
00601
00602
00603
00604
00605 BOOL prs_uint8(const char *name, prs_struct *ps, int depth, uint8 *data8)
00606 {
00607 char *q = prs_mem_get(ps, 1);
00608 if (q == NULL)
00609 return False;
00610
00611 if (UNMARSHALLING(ps))
00612 *data8 = CVAL(q,0);
00613 else
00614 SCVAL(q,0,*data8);
00615
00616 DEBUG(5,("%s%04x %s: %02x\n", tab_depth(depth), ps->data_offset, name, *data8));
00617
00618 ps->data_offset += 1;
00619
00620 return True;
00621 }
00622
00623
00624
00625
00626
00627 BOOL prs_pointer( const char *name, prs_struct *ps, int depth,
00628 void *dta, size_t data_size,
00629 BOOL(*prs_fn)(const char*, prs_struct*, int, void*) )
00630 {
00631 void ** data = (void **)dta;
00632 uint32 data_p;
00633
00634
00635
00636 data_p = *data ? 0xf000baaa : 0;
00637
00638 if ( !prs_uint32("ptr", ps, depth, &data_p ))
00639 return False;
00640
00641
00642
00643 if ( !data_p )
00644 return True;
00645
00646 if (UNMARSHALLING(ps)) {
00647 if (data_size) {
00648 if ( !(*data = PRS_ALLOC_MEM(ps, char, data_size)) )
00649 return False;
00650 } else {
00651 *data = NULL;
00652 }
00653 }
00654
00655 return prs_fn(name, ps, depth, *data);
00656 }
00657
00658
00659
00660
00661
00662
00663 BOOL prs_uint16(const char *name, prs_struct *ps, int depth, uint16 *data16)
00664 {
00665 char *q = prs_mem_get(ps, sizeof(uint16));
00666 if (q == NULL)
00667 return False;
00668
00669 if (UNMARSHALLING(ps)) {
00670 if (ps->bigendian_data)
00671 *data16 = RSVAL(q,0);
00672 else
00673 *data16 = SVAL(q,0);
00674 } else {
00675 if (ps->bigendian_data)
00676 RSSVAL(q,0,*data16);
00677 else
00678 SSVAL(q,0,*data16);
00679 }
00680
00681 DEBUG(5,("%s%04x %s: %04x\n", tab_depth(depth), ps->data_offset, name, *data16));
00682
00683 ps->data_offset += sizeof(uint16);
00684
00685 return True;
00686 }
00687
00688
00689
00690
00691
00692 BOOL prs_uint32(const char *name, prs_struct *ps, int depth, uint32 *data32)
00693 {
00694 char *q = prs_mem_get(ps, sizeof(uint32));
00695 if (q == NULL)
00696 return False;
00697
00698 if (UNMARSHALLING(ps)) {
00699 if (ps->bigendian_data)
00700 *data32 = RIVAL(q,0);
00701 else
00702 *data32 = IVAL(q,0);
00703 } else {
00704 if (ps->bigendian_data)
00705 RSIVAL(q,0,*data32);
00706 else
00707 SIVAL(q,0,*data32);
00708 }
00709
00710 DEBUG(5,("%s%04x %s: %08x\n", tab_depth(depth), ps->data_offset, name, *data32));
00711
00712 ps->data_offset += sizeof(uint32);
00713
00714 return True;
00715 }
00716
00717
00718
00719
00720
00721 BOOL prs_int32(const char *name, prs_struct *ps, int depth, int32 *data32)
00722 {
00723 char *q = prs_mem_get(ps, sizeof(int32));
00724 if (q == NULL)
00725 return False;
00726
00727 if (UNMARSHALLING(ps)) {
00728 if (ps->bigendian_data)
00729 *data32 = RIVALS(q,0);
00730 else
00731 *data32 = IVALS(q,0);
00732 } else {
00733 if (ps->bigendian_data)
00734 RSIVALS(q,0,*data32);
00735 else
00736 SIVALS(q,0,*data32);
00737 }
00738
00739 DEBUG(5,("%s%04x %s: %08x\n", tab_depth(depth), ps->data_offset, name, *data32));
00740
00741 ps->data_offset += sizeof(int32);
00742
00743 return True;
00744 }
00745
00746
00747
00748
00749
00750 BOOL prs_ntstatus(const char *name, prs_struct *ps, int depth, NTSTATUS *status)
00751 {
00752 char *q = prs_mem_get(ps, sizeof(uint32));
00753 if (q == NULL)
00754 return False;
00755
00756 if (UNMARSHALLING(ps)) {
00757 if (ps->bigendian_data)
00758 *status = NT_STATUS(RIVAL(q,0));
00759 else
00760 *status = NT_STATUS(IVAL(q,0));
00761 } else {
00762 if (ps->bigendian_data)
00763 RSIVAL(q,0,NT_STATUS_V(*status));
00764 else
00765 SIVAL(q,0,NT_STATUS_V(*status));
00766 }
00767
00768 DEBUG(5,("%s%04x %s: %s\n", tab_depth(depth), ps->data_offset, name,
00769 nt_errstr(*status)));
00770
00771 ps->data_offset += sizeof(uint32);
00772
00773 return True;
00774 }
00775
00776
00777
00778
00779
00780 BOOL prs_dcerpc_status(const char *name, prs_struct *ps, int depth, NTSTATUS *status)
00781 {
00782 char *q = prs_mem_get(ps, sizeof(uint32));
00783 if (q == NULL)
00784 return False;
00785
00786 if (UNMARSHALLING(ps)) {
00787 if (ps->bigendian_data)
00788 *status = NT_STATUS(RIVAL(q,0));
00789 else
00790 *status = NT_STATUS(IVAL(q,0));
00791 } else {
00792 if (ps->bigendian_data)
00793 RSIVAL(q,0,NT_STATUS_V(*status));
00794 else
00795 SIVAL(q,0,NT_STATUS_V(*status));
00796 }
00797
00798 DEBUG(5,("%s%04x %s: %s\n", tab_depth(depth), ps->data_offset, name,
00799 dcerpc_errstr(NT_STATUS_V(*status))));
00800
00801 ps->data_offset += sizeof(uint32);
00802
00803 return True;
00804 }
00805
00806
00807
00808
00809
00810
00811 BOOL prs_werror(const char *name, prs_struct *ps, int depth, WERROR *status)
00812 {
00813 char *q = prs_mem_get(ps, sizeof(uint32));
00814 if (q == NULL)
00815 return False;
00816
00817 if (UNMARSHALLING(ps)) {
00818 if (ps->bigendian_data)
00819 *status = W_ERROR(RIVAL(q,0));
00820 else
00821 *status = W_ERROR(IVAL(q,0));
00822 } else {
00823 if (ps->bigendian_data)
00824 RSIVAL(q,0,W_ERROR_V(*status));
00825 else
00826 SIVAL(q,0,W_ERROR_V(*status));
00827 }
00828
00829 DEBUG(5,("%s%04x %s: %s\n", tab_depth(depth), ps->data_offset, name,
00830 dos_errstr(*status)));
00831
00832 ps->data_offset += sizeof(uint32);
00833
00834 return True;
00835 }
00836
00837
00838
00839
00840
00841
00842 BOOL prs_uint8s(BOOL charmode, const char *name, prs_struct *ps, int depth, uint8 *data8s, int len)
00843 {
00844 int i;
00845 char *q = prs_mem_get(ps, len);
00846 if (q == NULL)
00847 return False;
00848
00849 if (UNMARSHALLING(ps)) {
00850 for (i = 0; i < len; i++)
00851 data8s[i] = CVAL(q,i);
00852 } else {
00853 for (i = 0; i < len; i++)
00854 SCVAL(q, i, data8s[i]);
00855 }
00856
00857 DEBUG(5,("%s%04x %s: ", tab_depth(depth), ps->data_offset ,name));
00858 if (charmode)
00859 print_asc(5, (unsigned char*)data8s, len);
00860 else {
00861 for (i = 0; i < len; i++)
00862 DEBUG(5,("%02x ", data8s[i]));
00863 }
00864 DEBUG(5,("\n"));
00865
00866 ps->data_offset += len;
00867
00868 return True;
00869 }
00870
00871
00872
00873
00874
00875 BOOL prs_uint16s(BOOL charmode, const char *name, prs_struct *ps, int depth, uint16 *data16s, int len)
00876 {
00877 int i;
00878 char *q = prs_mem_get(ps, len * sizeof(uint16));
00879 if (q == NULL)
00880 return False;
00881
00882 if (UNMARSHALLING(ps)) {
00883 if (ps->bigendian_data) {
00884 for (i = 0; i < len; i++)
00885 data16s[i] = RSVAL(q, 2*i);
00886 } else {
00887 for (i = 0; i < len; i++)
00888 data16s[i] = SVAL(q, 2*i);
00889 }
00890 } else {
00891 if (ps->bigendian_data) {
00892 for (i = 0; i < len; i++)
00893 RSSVAL(q, 2*i, data16s[i]);
00894 } else {
00895 for (i = 0; i < len; i++)
00896 SSVAL(q, 2*i, data16s[i]);
00897 }
00898 }
00899
00900 DEBUG(5,("%s%04x %s: ", tab_depth(depth), ps->data_offset, name));
00901 if (charmode)
00902 print_asc(5, (unsigned char*)data16s, 2*len);
00903 else {
00904 for (i = 0; i < len; i++)
00905 DEBUG(5,("%04x ", data16s[i]));
00906 }
00907 DEBUG(5,("\n"));
00908
00909 ps->data_offset += (len * sizeof(uint16));
00910
00911 return True;
00912 }
00913
00914
00915
00916
00917
00918
00919 static void dbg_rw_punival(BOOL charmode, const char *name, int depth, prs_struct *ps,
00920 char *in_buf, char *out_buf, int len)
00921 {
00922 int i;
00923
00924 if (UNMARSHALLING(ps)) {
00925 if (ps->bigendian_data) {
00926 for (i = 0; i < len; i++)
00927 SSVAL(out_buf,2*i,RSVAL(in_buf, 2*i));
00928 } else {
00929 for (i = 0; i < len; i++)
00930 SSVAL(out_buf, 2*i, SVAL(in_buf, 2*i));
00931 }
00932 } else {
00933 if (ps->bigendian_data) {
00934 for (i = 0; i < len; i++)
00935 RSSVAL(in_buf, 2*i, SVAL(out_buf,2*i));
00936 } else {
00937 for (i = 0; i < len; i++)
00938 SSVAL(in_buf, 2*i, SVAL(out_buf,2*i));
00939 }
00940 }
00941
00942 DEBUG(5,("%s%04x %s: ", tab_depth(depth), ps->data_offset, name));
00943 if (charmode)
00944 print_asc(5, (unsigned char*)out_buf, 2*len);
00945 else {
00946 for (i = 0; i < len; i++)
00947 DEBUG(5,("%04x ", out_buf[i]));
00948 }
00949 DEBUG(5,("\n"));
00950 }
00951
00952
00953
00954
00955
00956 BOOL prs_uint16uni(BOOL charmode, const char *name, prs_struct *ps, int depth, uint16 *data16s, int len)
00957 {
00958 char *q = prs_mem_get(ps, len * sizeof(uint16));
00959 if (q == NULL)
00960 return False;
00961
00962 dbg_rw_punival(charmode, name, depth, ps, q, (char *)data16s, len);
00963 ps->data_offset += (len * sizeof(uint16));
00964
00965 return True;
00966 }
00967
00968
00969
00970
00971
00972 BOOL prs_uint32s(BOOL charmode, const char *name, prs_struct *ps, int depth, uint32 *data32s, int len)
00973 {
00974 int i;
00975 char *q = prs_mem_get(ps, len * sizeof(uint32));
00976 if (q == NULL)
00977 return False;
00978
00979 if (UNMARSHALLING(ps)) {
00980 if (ps->bigendian_data) {
00981 for (i = 0; i < len; i++)
00982 data32s[i] = RIVAL(q, 4*i);
00983 } else {
00984 for (i = 0; i < len; i++)
00985 data32s[i] = IVAL(q, 4*i);
00986 }
00987 } else {
00988 if (ps->bigendian_data) {
00989 for (i = 0; i < len; i++)
00990 RSIVAL(q, 4*i, data32s[i]);
00991 } else {
00992 for (i = 0; i < len; i++)
00993 SIVAL(q, 4*i, data32s[i]);
00994 }
00995 }
00996
00997 DEBUG(5,("%s%04x %s: ", tab_depth(depth), ps->data_offset, name));
00998 if (charmode)
00999 print_asc(5, (unsigned char*)data32s, 4*len);
01000 else {
01001 for (i = 0; i < len; i++)
01002 DEBUG(5,("%08x ", data32s[i]));
01003 }
01004 DEBUG(5,("\n"));
01005
01006 ps->data_offset += (len * sizeof(uint32));
01007
01008 return True;
01009 }
01010
01011
01012
01013
01014
01015
01016 BOOL prs_buffer5(BOOL charmode, const char *name, prs_struct *ps, int depth, BUFFER5 *str)
01017 {
01018 char *p;
01019 char *q = prs_mem_get(ps, str->buf_len * sizeof(uint16));
01020 if (q == NULL)
01021 return False;
01022
01023
01024 if (str->buf_len==0)
01025 return True;
01026
01027 if (UNMARSHALLING(ps)) {
01028 str->buffer = PRS_ALLOC_MEM(ps,uint16,str->buf_len);
01029 if (str->buffer == NULL)
01030 return False;
01031 }
01032
01033 p = (char *)str->buffer;
01034
01035 dbg_rw_punival(charmode, name, depth, ps, q, p, str->buf_len);
01036
01037 ps->data_offset += (str->buf_len * sizeof(uint16));
01038
01039 return True;
01040 }
01041
01042
01043
01044
01045
01046
01047 BOOL prs_regval_buffer(BOOL charmode, const char *name, prs_struct *ps, int depth, REGVAL_BUFFER *buf)
01048 {
01049 char *p;
01050 char *q = prs_mem_get(ps, buf->buf_len);
01051 if (q == NULL)
01052 return False;
01053
01054 if (UNMARSHALLING(ps)) {
01055 if (buf->buf_len > buf->buf_max_len) {
01056 return False;
01057 }
01058 if ( buf->buf_max_len ) {
01059 buf->buffer = PRS_ALLOC_MEM(ps, uint16, buf->buf_max_len);
01060 if ( buf->buffer == NULL )
01061 return False;
01062 } else {
01063 buf->buffer = NULL;
01064 }
01065 }
01066
01067 p = (char *)buf->buffer;
01068
01069 dbg_rw_punival(charmode, name, depth, ps, q, p, buf->buf_len/2);
01070 ps->data_offset += buf->buf_len;
01071
01072 return True;
01073 }
01074
01075
01076
01077
01078
01079
01080 BOOL prs_string2(BOOL charmode, const char *name, prs_struct *ps, int depth, STRING2 *str)
01081 {
01082 unsigned int i;
01083 char *q = prs_mem_get(ps, str->str_str_len);
01084 if (q == NULL)
01085 return False;
01086
01087 if (UNMARSHALLING(ps)) {
01088 if (str->str_str_len > str->str_max_len) {
01089 return False;
01090 }
01091 if (str->str_max_len) {
01092 str->buffer = PRS_ALLOC_MEM(ps,unsigned char, str->str_max_len);
01093 if (str->buffer == NULL)
01094 return False;
01095 } else {
01096 str->buffer = NULL;
01097
01098 DEBUG(5,("%s%04x %s: \n", tab_depth(depth), ps->data_offset, name));
01099 return True;
01100 }
01101 }
01102
01103 if (UNMARSHALLING(ps)) {
01104 for (i = 0; i < str->str_str_len; i++)
01105 str->buffer[i] = CVAL(q,i);
01106 } else {
01107 for (i = 0; i < str->str_str_len; i++)
01108 SCVAL(q, i, str->buffer[i]);
01109 }
01110
01111 DEBUG(5,("%s%04x %s: ", tab_depth(depth), ps->data_offset, name));
01112 if (charmode)
01113 print_asc(5, (unsigned char*)str->buffer, str->str_str_len);
01114 else {
01115 for (i = 0; i < str->str_str_len; i++)
01116 DEBUG(5,("%02x ", str->buffer[i]));
01117 }
01118 DEBUG(5,("\n"));
01119
01120 ps->data_offset += str->str_str_len;
01121
01122 return True;
01123 }
01124
01125
01126
01127
01128
01129
01130 BOOL prs_unistr2(BOOL charmode, const char *name, prs_struct *ps, int depth, UNISTR2 *str)
01131 {
01132 char *p;
01133 char *q = prs_mem_get(ps, str->uni_str_len * sizeof(uint16));
01134 if (q == NULL)
01135 return False;
01136
01137
01138 if (str->uni_str_len==0)
01139 return True;
01140
01141 if (UNMARSHALLING(ps)) {
01142 if (str->uni_str_len > str->uni_max_len) {
01143 return False;
01144 }
01145 if (str->uni_max_len) {
01146 str->buffer = PRS_ALLOC_MEM(ps,uint16,str->uni_max_len);
01147 if (str->buffer == NULL)
01148 return False;
01149 } else {
01150 str->buffer = NULL;
01151 }
01152 }
01153
01154 p = (char *)str->buffer;
01155
01156 dbg_rw_punival(charmode, name, depth, ps, q, p, str->uni_str_len);
01157
01158 ps->data_offset += (str->uni_str_len * sizeof(uint16));
01159
01160 return True;
01161 }
01162
01163
01164
01165
01166
01167
01168 BOOL prs_unistr3(BOOL charmode, const char *name, UNISTR3 *str, prs_struct *ps, int depth)
01169 {
01170 char *p;
01171 char *q = prs_mem_get(ps, str->uni_str_len * sizeof(uint16));
01172 if (q == NULL)
01173 return False;
01174
01175 if (UNMARSHALLING(ps)) {
01176 if (str->uni_str_len) {
01177 str->str.buffer = PRS_ALLOC_MEM(ps,uint16,str->uni_str_len);
01178 if (str->str.buffer == NULL)
01179 return False;
01180 } else {
01181 str->str.buffer = NULL;
01182 }
01183 }
01184
01185 p = (char *)str->str.buffer;
01186
01187 dbg_rw_punival(charmode, name, depth, ps, q, p, str->uni_str_len);
01188 ps->data_offset += (str->uni_str_len * sizeof(uint16));
01189
01190 return True;
01191 }
01192
01193
01194
01195
01196
01197
01198 BOOL prs_unistr(const char *name, prs_struct *ps, int depth, UNISTR *str)
01199 {
01200 unsigned int len = 0;
01201 unsigned char *p = (unsigned char *)str->buffer;
01202 uint8 *start;
01203 char *q;
01204 uint32 max_len;
01205 uint16* ptr;
01206
01207 if (MARSHALLING(ps)) {
01208
01209 for(len = 0; str->buffer[len] != 0; len++)
01210 ;
01211
01212 q = prs_mem_get(ps, (len+1)*2);
01213 if (q == NULL)
01214 return False;
01215
01216 start = (uint8*)q;
01217
01218 for(len = 0; str->buffer[len] != 0; len++) {
01219 if(ps->bigendian_data) {
01220
01221 q[0] = (char)p[1];
01222 q[1] = (char)p[0];
01223 p += 2;
01224 q += 2;
01225 }
01226 else
01227 {
01228 q[0] = (char)p[0];
01229 q[1] = (char)p[1];
01230 p += 2;
01231 q += 2;
01232 }
01233 }
01234
01235
01236
01237
01238
01239
01240
01241 q[0] = 0;
01242 q[1] = 0;
01243 q += 2;
01244
01245 len++;
01246
01247 DEBUG(5,("%s%04x %s: ", tab_depth(depth), ps->data_offset, name));
01248 print_asc(5, (unsigned char*)start, 2*len);
01249 DEBUG(5, ("\n"));
01250 }
01251 else {
01252
01253 uint32 alloc_len = 0;
01254 q = ps->data_p + prs_offset(ps);
01255
01256
01257
01258
01259 max_len = (ps->buffer_size - ps->data_offset)/sizeof(uint16);
01260
01261
01262
01263 for ( ptr = (uint16 *)q; *ptr++ && (alloc_len <= max_len); alloc_len++)
01264
01265 ;
01266
01267 if (alloc_len < max_len)
01268 alloc_len += 1;
01269
01270
01271 str->buffer = PRS_ALLOC_MEM(ps,uint16,alloc_len);
01272 if ((str->buffer == NULL) && (alloc_len > 0))
01273 return False;
01274
01275 p = (unsigned char *)str->buffer;
01276
01277 len = 0;
01278
01279
01280
01281 while ((len < alloc_len) && (*(uint16 *)q != 0)) {
01282 if(ps->bigendian_data)
01283 {
01284
01285 p[0] = (unsigned char)q[1];
01286 p[1] = (unsigned char)q[0];
01287 p += 2;
01288 q += 2;
01289 } else {
01290
01291 p[0] = (unsigned char)q[0];
01292 p[1] = (unsigned char)q[1];
01293 p += 2;
01294 q += 2;
01295 }
01296
01297 len++;
01298 }
01299 if (len < alloc_len) {
01300
01301 str->buffer[len++] = '\0';
01302 }
01303
01304 DEBUG(5,("%s%04x %s: ", tab_depth(depth), ps->data_offset, name));
01305 print_asc(5, (unsigned char*)str->buffer, 2*len);
01306 DEBUG(5, ("\n"));
01307 }
01308
01309
01310
01311
01312 ps->data_offset += (len)*2;
01313
01314 return True;
01315 }
01316
01317
01318
01319
01320
01321
01322
01323 BOOL prs_string(const char *name, prs_struct *ps, int depth, char *str, int max_buf_size)
01324 {
01325 char *q;
01326 int i;
01327 int len;
01328
01329 if (UNMARSHALLING(ps))
01330 len = strlen(&ps->data_p[ps->data_offset]);
01331 else
01332 len = strlen(str);
01333
01334 len = MIN(len, (max_buf_size-1));
01335
01336 q = prs_mem_get(ps, len+1);
01337 if (q == NULL)
01338 return False;
01339
01340 for(i = 0; i < len; i++) {
01341 if (UNMARSHALLING(ps))
01342 str[i] = q[i];
01343 else
01344 q[i] = str[i];
01345 }
01346
01347
01348 str[i] = '\0';
01349
01350 if (MARSHALLING(ps)) {
01351 q[i] = '\0';
01352 }
01353
01354 ps->data_offset += len+1;
01355
01356 dump_data(5+depth, q, len);
01357
01358 return True;
01359 }
01360
01361 BOOL prs_string_alloc(const char *name, prs_struct *ps, int depth, const char **str)
01362 {
01363 size_t len;
01364 char *tmp_str;
01365
01366 if (UNMARSHALLING(ps)) {
01367 len = strlen(&ps->data_p[ps->data_offset]);
01368 } else {
01369 len = strlen(*str);
01370 }
01371
01372 tmp_str = PRS_ALLOC_MEM(ps, char, len+1);
01373
01374 if (tmp_str == NULL) {
01375 return False;
01376 }
01377
01378 if (MARSHALLING(ps)) {
01379 strncpy(tmp_str, *str, len);
01380 }
01381
01382 if (!prs_string(name, ps, depth, tmp_str, len+1)) {
01383 return False;
01384 }
01385
01386 *str = tmp_str;
01387 return True;
01388 }
01389
01390
01391
01392
01393
01394
01395 BOOL prs_uint16_pre(const char *name, prs_struct *ps, int depth, uint16 *data16, uint32 *offset)
01396 {
01397 *offset = ps->data_offset;
01398 if (UNMARSHALLING(ps)) {
01399
01400 return prs_uint16(name, ps, depth, data16);
01401 } else {
01402 char *q = prs_mem_get(ps, sizeof(uint16));
01403 if(q ==NULL)
01404 return False;
01405 ps->data_offset += sizeof(uint16);
01406 }
01407 return True;
01408 }
01409
01410
01411
01412
01413
01414
01415 BOOL prs_uint16_post(const char *name, prs_struct *ps, int depth, uint16 *data16,
01416 uint32 ptr_uint16, uint32 start_offset)
01417 {
01418 if (MARSHALLING(ps)) {
01419
01420
01421
01422 uint16 data_size = ps->data_offset - start_offset;
01423 uint32 old_offset = ps->data_offset;
01424
01425 ps->data_offset = ptr_uint16;
01426 if(!prs_uint16(name, ps, depth, &data_size)) {
01427 ps->data_offset = old_offset;
01428 return False;
01429 }
01430 ps->data_offset = old_offset;
01431 } else {
01432 ps->data_offset = start_offset + (uint32)(*data16);
01433 }
01434 return True;
01435 }
01436
01437
01438
01439
01440
01441
01442 BOOL prs_uint32_pre(const char *name, prs_struct *ps, int depth, uint32 *data32, uint32 *offset)
01443 {
01444 *offset = ps->data_offset;
01445 if (UNMARSHALLING(ps) && (data32 != NULL)) {
01446
01447 return prs_uint32(name, ps, depth, data32);
01448 } else {
01449 ps->data_offset += sizeof(uint32);
01450 }
01451 return True;
01452 }
01453
01454
01455
01456
01457
01458
01459 BOOL prs_uint32_post(const char *name, prs_struct *ps, int depth, uint32 *data32,
01460 uint32 ptr_uint32, uint32 data_size)
01461 {
01462 if (MARSHALLING(ps)) {
01463
01464
01465
01466 uint32 old_offset = ps->data_offset;
01467 ps->data_offset = ptr_uint32;
01468 if(!prs_uint32(name, ps, depth, &data_size)) {
01469 ps->data_offset = old_offset;
01470 return False;
01471 }
01472 ps->data_offset = old_offset;
01473 }
01474 return True;
01475 }
01476
01477
01478 int tdb_prs_store(TDB_CONTEXT *tdb, char *keystr, prs_struct *ps)
01479 {
01480 TDB_DATA kbuf, dbuf;
01481 kbuf.dptr = keystr;
01482 kbuf.dsize = strlen(keystr)+1;
01483 dbuf.dptr = ps->data_p;
01484 dbuf.dsize = prs_offset(ps);
01485 return tdb_trans_store(tdb, kbuf, dbuf, TDB_REPLACE);
01486 }
01487
01488
01489 int tdb_prs_fetch(TDB_CONTEXT *tdb, char *keystr, prs_struct *ps, TALLOC_CTX *mem_ctx)
01490 {
01491 TDB_DATA kbuf, dbuf;
01492 kbuf.dptr = keystr;
01493 kbuf.dsize = strlen(keystr)+1;
01494
01495 prs_init(ps, 0, mem_ctx, UNMARSHALL);
01496
01497 dbuf = tdb_fetch(tdb, kbuf);
01498 if (!dbuf.dptr)
01499 return -1;
01500
01501 prs_give_memory(ps, dbuf.dptr, dbuf.dsize, True);
01502
01503 return 0;
01504 }
01505
01506
01507
01508
01509
01510 BOOL prs_hash1(prs_struct *ps, uint32 offset, int len)
01511 {
01512 char *q;
01513
01514 q = ps->data_p;
01515 q = &q[offset];
01516
01517 #ifdef DEBUG_PASSWORD
01518 DEBUG(100, ("prs_hash1\n"));
01519 dump_data(100, ps->sess_key, 16);
01520 dump_data(100, q, len);
01521 #endif
01522 SamOEMhash((uchar *) q, (const unsigned char *)ps->sess_key, len);
01523
01524 #ifdef DEBUG_PASSWORD
01525 dump_data(100, q, len);
01526 #endif
01527
01528 return True;
01529 }
01530
01531
01532
01533
01534
01535
01536 static void schannel_digest(struct schannel_auth_struct *a,
01537 enum pipe_auth_level auth_level,
01538 RPC_AUTH_SCHANNEL_CHK * verf,
01539 char *data, size_t data_len,
01540 uchar digest_final[16])
01541 {
01542 uchar whole_packet_digest[16];
01543 static uchar zeros[4];
01544 struct MD5Context ctx3;
01545
01546
01547 MD5Init(&ctx3);
01548
01549
01550 MD5Update(&ctx3, zeros, sizeof(zeros));
01551 MD5Update(&ctx3, verf->sig, sizeof(verf->sig));
01552 if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
01553 MD5Update(&ctx3, verf->confounder, sizeof(verf->confounder));
01554 }
01555 MD5Update(&ctx3, (const unsigned char *)data, data_len);
01556 MD5Final(whole_packet_digest, &ctx3);
01557 dump_data_pw("whole_packet_digest:\n", whole_packet_digest, sizeof(whole_packet_digest));
01558
01559
01560
01561 hmac_md5(a->sess_key, whole_packet_digest, sizeof(whole_packet_digest), digest_final);
01562 }
01563
01564
01565
01566
01567
01568 static void schannel_get_sealing_key(struct schannel_auth_struct *a,
01569 RPC_AUTH_SCHANNEL_CHK *verf,
01570 uchar sealing_key[16])
01571 {
01572 static uchar zeros[4];
01573 uchar digest2[16];
01574 uchar sess_kf0[16];
01575 int i;
01576
01577 for (i = 0; i < sizeof(sess_kf0); i++) {
01578 sess_kf0[i] = a->sess_key[i] ^ 0xf0;
01579 }
01580
01581 dump_data_pw("sess_kf0:\n", sess_kf0, sizeof(sess_kf0));
01582
01583
01584 hmac_md5(sess_kf0, zeros, 0x4, digest2);
01585 dump_data_pw("digest2:\n", digest2, sizeof(digest2));
01586
01587
01588 hmac_md5(digest2, verf->seq_num, sizeof(verf->seq_num), sealing_key);
01589 dump_data_pw("sealing_key:\n", sealing_key, 16);
01590 }
01591
01592
01593
01594
01595
01596 static void schannel_deal_with_seq_num(struct schannel_auth_struct *a,
01597 RPC_AUTH_SCHANNEL_CHK *verf)
01598 {
01599 static uchar zeros[4];
01600 uchar sequence_key[16];
01601 uchar digest1[16];
01602
01603 hmac_md5(a->sess_key, zeros, sizeof(zeros), digest1);
01604 dump_data_pw("(sequence key) digest1:\n", digest1, sizeof(digest1));
01605
01606 hmac_md5(digest1, verf->packet_digest, 8, sequence_key);
01607
01608 dump_data_pw("sequence_key:\n", sequence_key, sizeof(sequence_key));
01609
01610 dump_data_pw("seq_num (before):\n", verf->seq_num, sizeof(verf->seq_num));
01611 SamOEMhash(verf->seq_num, sequence_key, 8);
01612 dump_data_pw("seq_num (after):\n", verf->seq_num, sizeof(verf->seq_num));
01613 }
01614
01615
01616
01617
01618
01619 static BOOL init_rpc_auth_schannel_chk(RPC_AUTH_SCHANNEL_CHK * chk,
01620 const uchar sig[8],
01621 const uchar packet_digest[8],
01622 const uchar seq_num[8], const uchar confounder[8])
01623 {
01624 if (chk == NULL)
01625 return False;
01626
01627 memcpy(chk->sig, sig, sizeof(chk->sig));
01628 memcpy(chk->packet_digest, packet_digest, sizeof(chk->packet_digest));
01629 memcpy(chk->seq_num, seq_num, sizeof(chk->seq_num));
01630 memcpy(chk->confounder, confounder, sizeof(chk->confounder));
01631
01632 return True;
01633 }
01634
01635
01636
01637
01638
01639
01640
01641
01642 void schannel_encode(struct schannel_auth_struct *a, enum pipe_auth_level auth_level,
01643 enum schannel_direction direction,
01644 RPC_AUTH_SCHANNEL_CHK * verf,
01645 char *data, size_t data_len)
01646 {
01647 uchar digest_final[16];
01648 uchar confounder[8];
01649 uchar seq_num[8];
01650 static const uchar nullbytes[8] = { 0, };
01651
01652 static const uchar schannel_seal_sig[8] = SCHANNEL_SEAL_SIGNATURE;
01653 static const uchar schannel_sign_sig[8] = SCHANNEL_SIGN_SIGNATURE;
01654 const uchar *schannel_sig = NULL;
01655
01656 DEBUG(10,("SCHANNEL: schannel_encode seq_num=%d data_len=%lu\n", a->seq_num, (unsigned long)data_len));
01657
01658 if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
01659 schannel_sig = schannel_seal_sig;
01660 } else {
01661 schannel_sig = schannel_sign_sig;
01662 }
01663
01664
01665 generate_random_buffer(confounder, sizeof(confounder));
01666
01667 dump_data_pw("a->sess_key:\n", a->sess_key, sizeof(a->sess_key));
01668
01669 RSIVAL(seq_num, 0, a->seq_num);
01670
01671 switch (direction) {
01672 case SENDER_IS_INITIATOR:
01673 SIVAL(seq_num, 4, 0x80);
01674 break;
01675 case SENDER_IS_ACCEPTOR:
01676 SIVAL(seq_num, 4, 0x0);
01677 break;
01678 }
01679
01680 dump_data_pw("verf->seq_num:\n", seq_num, sizeof(verf->seq_num));
01681
01682 init_rpc_auth_schannel_chk(verf, schannel_sig, nullbytes,
01683 seq_num, confounder);
01684
01685
01686 schannel_digest(a, auth_level, verf, data, data_len, digest_final);
01687 memcpy(verf->packet_digest, digest_final, sizeof(verf->packet_digest));
01688
01689 if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
01690 uchar sealing_key[16];
01691
01692
01693 schannel_get_sealing_key(a, verf, sealing_key);
01694
01695
01696 dump_data_pw("verf->confounder:\n", verf->confounder, sizeof(verf->confounder));
01697 SamOEMhash(verf->confounder, sealing_key, 8);
01698
01699 dump_data_pw("verf->confounder_enc:\n", verf->confounder, sizeof(verf->confounder));
01700
01701
01702 dump_data_pw("data:\n", (const unsigned char *)data, data_len);
01703 SamOEMhash((unsigned char *)data, sealing_key, data_len);
01704 dump_data_pw("data_enc:\n", (const unsigned char *)data, data_len);
01705 }
01706
01707
01708
01709
01710 schannel_deal_with_seq_num(a, verf);
01711
01712 return;
01713 }
01714
01715
01716
01717
01718
01719
01720
01721 BOOL schannel_decode(struct schannel_auth_struct *a, enum pipe_auth_level auth_level,
01722 enum schannel_direction direction,
01723 RPC_AUTH_SCHANNEL_CHK * verf, char *data, size_t data_len)
01724 {
01725 uchar digest_final[16];
01726
01727 static const uchar schannel_seal_sig[8] = SCHANNEL_SEAL_SIGNATURE;
01728 static const uchar schannel_sign_sig[8] = SCHANNEL_SIGN_SIGNATURE;
01729 const uchar *schannel_sig = NULL;
01730
01731 uchar seq_num[8];
01732
01733 DEBUG(10,("SCHANNEL: schannel_decode seq_num=%d data_len=%lu\n", a->seq_num, (unsigned long)data_len));
01734
01735 if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
01736 schannel_sig = schannel_seal_sig;
01737 } else {
01738 schannel_sig = schannel_sign_sig;
01739 }
01740
01741
01742 RSIVAL(seq_num, 0, a->seq_num);
01743
01744 switch (direction) {
01745 case SENDER_IS_INITIATOR:
01746 SIVAL(seq_num, 4, 0x80);
01747 break;
01748 case SENDER_IS_ACCEPTOR:
01749 SIVAL(seq_num, 4, 0x0);
01750 break;
01751 }
01752
01753 DEBUG(10,("SCHANNEL: schannel_decode seq_num=%d data_len=%lu\n", a->seq_num, (unsigned long)data_len));
01754 dump_data_pw("a->sess_key:\n", a->sess_key, sizeof(a->sess_key));
01755
01756 dump_data_pw("seq_num:\n", seq_num, sizeof(seq_num));
01757
01758
01759
01760
01761 schannel_deal_with_seq_num(a, verf);
01762
01763 if (memcmp(verf->seq_num, seq_num, sizeof(seq_num))) {
01764
01765
01766
01767
01768
01769 DEBUG(2, ("schannel_decode: FAILED: packet sequence number:\n"));
01770 dump_data(2, (const char*)verf->seq_num, sizeof(verf->seq_num));
01771 DEBUG(2, ("should be:\n"));
01772 dump_data(2, (const char*)seq_num, sizeof(seq_num));
01773
01774 return False;
01775 }
01776
01777 if (memcmp(verf->sig, schannel_sig, sizeof(verf->sig))) {
01778
01779 DEBUG(2, ("schannel_decode: FAILED: packet header:\n"));
01780 dump_data(2, (const char*)verf->sig, sizeof(verf->sig));
01781 DEBUG(2, ("should be:\n"));
01782 dump_data(2, (const char*)schannel_sig, sizeof(schannel_sig));
01783 return False;
01784 }
01785
01786 if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
01787 uchar sealing_key[16];
01788
01789
01790 schannel_get_sealing_key(a, verf, sealing_key);
01791
01792
01793 dump_data_pw("verf->confounder:\n", verf->confounder,
01794 sizeof(verf->confounder));
01795 SamOEMhash(verf->confounder, sealing_key, 8);
01796
01797 dump_data_pw("verf->confounder_dec:\n", verf->confounder,
01798 sizeof(verf->confounder));
01799
01800
01801 dump_data_pw("data :\n", (const unsigned char *)data, data_len);
01802 SamOEMhash((unsigned char *)data, sealing_key, data_len);
01803 dump_data_pw("datadec:\n", (const unsigned char *)data, data_len);
01804 }
01805
01806
01807 schannel_digest(a, auth_level, verf, data, data_len, digest_final);
01808
01809 dump_data_pw("Calculated digest:\n", digest_final,
01810 sizeof(digest_final));
01811 dump_data_pw("verf->packet_digest:\n", verf->packet_digest,
01812 sizeof(verf->packet_digest));
01813
01814
01815
01816 return (memcmp(digest_final, verf->packet_digest,
01817 sizeof(verf->packet_digest)) == 0);
01818 }
01819
01820
01821
01822
01823 BOOL prs_init_data_blob(prs_struct *prs, DATA_BLOB *blob, TALLOC_CTX *mem_ctx)
01824 {
01825 if (!prs_init( prs, RPC_MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL ))
01826 return False;
01827
01828
01829 if (!prs_copy_data_in(prs, (char *)blob->data, blob->length))
01830 return False;
01831
01832 return True;
01833 }
01834
01835
01836
01837
01838 BOOL prs_data_blob(prs_struct *prs, DATA_BLOB *blob, TALLOC_CTX *mem_ctx)
01839 {
01840 blob->length = prs_data_size(prs);
01841 blob->data = (uint8 *)TALLOC_ZERO_SIZE(mem_ctx, blob->length);
01842
01843
01844 prs_set_offset( prs, prs_data_size(prs) );
01845
01846 if (!prs_copy_all_data_out((char *)blob->data, prs))
01847 return False;
01848
01849 return True;
01850 }