Ethereal-dev: [Ethereal-dev] Updates to spoolss dissector
Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.
From: Tim Potter <tpot@xxxxxxxxx>
Date: Fri, 4 Jan 2002 17:05:43 +1100
Hello again. This patch fixes some crash bugs in the spoolss dissector and adds a few more random things. Tim. - functions that return a range of uint8,16,32 bytes have a check so as not to pass a negative count value to tvb_get_ptr() - when iterating over a list of defered pointers, don't return a zero length list of return values but rather NULL - handle NULL relative strings - start of dissector for a PRINTER_INFO_2 structure - when parsing the data in a BUFFER_DATA structure, insert the data item in the correct subtree and pass the correct item pointer back in the return value - don't crash if no buffer data is returned in a GetPrinter response - dissect AddPrinterEx, AddPrinterDriver query - dissect AddPrinterDriver, AddForm reply - display value data in EnumPrinterData reply - don't forget to register SPOOL_PRINTER_INFO_LEVEL subtree
? diff.out Index: packet-dcerpc-nt.c =================================================================== RCS file: /cvsroot/ethereal/packet-dcerpc-nt.c,v retrieving revision 1.2 diff -u -r1.2 packet-dcerpc-nt.c --- packet-dcerpc-nt.c 2002/01/03 20:42:40 1.2 +++ packet-dcerpc-nt.c 2002/01/04 05:53:16 @@ -75,6 +75,11 @@ { const guint8 *ptr; + /* The tvb_get_ptr() function fails an assertion if count < -1 */ + + if (count < -1) + THROW(BoundsError); + /* No alignment required */ ptr = tvb_get_ptr(tvb, offset, count); @@ -118,6 +123,11 @@ { const guint8 *ptr; + /* The tvb_get_ptr() function fails an assertion if count < -1 */ + + if (count < -1) + THROW(BoundsError); + offset = prs_align(offset, 2); ptr = tvb_get_ptr(tvb, offset, count * 2); @@ -162,6 +172,11 @@ { const guint8 *ptr; + /* The tvb_get_ptr() function fails an assertion if count < -1 */ + + if (count < -1) + THROW(BoundsError); + offset = prs_align(offset, 4); ptr = tvb_get_ptr(tvb, offset, count * 4); Index: packet-dcerpc-spoolss.c =================================================================== RCS file: /cvsroot/ethereal/packet-dcerpc-spoolss.c,v retrieving revision 1.2 diff -u -r1.2 packet-dcerpc-spoolss.c --- packet-dcerpc-spoolss.c 2002/01/03 20:42:40 1.2 +++ packet-dcerpc-spoolss.c 2002/01/04 05:53:16 @@ -426,13 +426,18 @@ void ***ptr_data) { struct deferred_ptr_state s; - int new_offset = offset, list_len; + int new_offset = offset; /* Create a list of void pointers to store return data */ if (ptr_data) { - list_len = g_list_length(*dp_list); - *ptr_data = malloc(list_len * sizeof(void *)); + int len = g_list_length(*dp_list) * sizeof(void *); + + if (len > 0) { + *ptr_data = malloc(len); + memset(*ptr_data, 0, len); + } else + *ptr_data = NULL; } /* Set up iterator data */ @@ -1108,16 +1113,21 @@ proto_tree *subtree; guint32 relstr_offset, relstr_start, relstr_end; guint16 *ptr; - char *text; + char *text = strdup("NULL"); gint len = 0, remaining, i; offset = prs_uint32(tvb, offset, pinfo, tree, &relstr_offset, NULL); - relstr_start = relstr_offset + struct_start; + /* A relative offset of zero is a NULL string */ - relstr_end = prs_uint16uni(tvb, relstr_start, pinfo, tree, - (void **)&text, NULL); - + relstr_start = relstr_offset + struct_start; + + if (relstr_offset) + relstr_end = prs_uint16uni(tvb, relstr_start, pinfo, tree, + (void **)&text, NULL); + else + relstr_end = offset; + item = proto_tree_add_text(tree, tvb, relstr_start, relstr_end - relstr_start, "%s: %s", name ? name : "RELSTR", text); @@ -1222,6 +1232,29 @@ static int prs_PRINTER_INFO_2(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, GList **dp_list, void **data) { + int struct_start = offset; + + offset = prs_relstr(tvb, offset, pinfo, tree, dp_list, struct_start, + NULL, "Server name"); + + offset = prs_relstr(tvb, offset, pinfo, tree, dp_list, struct_start, + NULL, "Printer name"); + + offset = prs_relstr(tvb, offset, pinfo, tree, dp_list, struct_start, + NULL, "Share name"); + + offset = prs_relstr(tvb, offset, pinfo, tree, dp_list, struct_start, + NULL, "Port name"); + + offset = prs_relstr(tvb, offset, pinfo, tree, dp_list, struct_start, + NULL, "Driver name"); + + offset = prs_relstr(tvb, offset, pinfo, tree, dp_list, struct_start, + NULL, "Comment"); + + offset = prs_relstr(tvb, offset, pinfo, tree, dp_list, struct_start, + NULL, "Location"); + return offset; } @@ -1825,7 +1858,7 @@ static int prs_BUFFER_DATA(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, GList **dp_list, void **data) { - proto_item *item; + proto_item *item, *subitem; proto_tree *subtree, *subsubtree; guint32 ptr = 0, size; guint8 *data8; @@ -1836,9 +1869,9 @@ offset = prs_uint32(tvb, offset, pinfo, subtree, &size, "Size"); - item = proto_tree_add_text(subtree, tvb, offset, size, "Data"); + subitem = proto_tree_add_text(subtree, tvb, offset, size, "Data"); - subsubtree = proto_item_add_subtree(item, ett_BUFFER_DATA_BUFFER); + subsubtree = proto_item_add_subtree(subitem, ett_BUFFER_DATA_BUFFER); offset = prs_uint8s(tvb, offset, pinfo, subsubtree, size, &data8, NULL); @@ -1852,7 +1885,7 @@ bd = (struct BUFFER_DATA *)malloc(sizeof(struct BUFFER_DATA)); bd->data8 = data8; - bd->item = item; + bd->item = subitem; bd->tree = subsubtree; bd->tvb = tvb; bd->offset = offset - size; @@ -1949,7 +1982,7 @@ request_hash_value *request_info; GList *dp_list = NULL; void **data_list; - struct BUFFER_DATA *bd; + struct BUFFER_DATA *bd = NULL; guint8 *data8; /* Update informational fields */ @@ -1969,9 +2002,10 @@ prs_BUFFER, (void **)&data8, &data_list); - bd = (struct BUFFER_DATA *)data_list[0]; + if (data_list) + bd = (struct BUFFER_DATA *)data_list[0]; - if (bd->tree && request_info) { + if (bd && bd->tree && request_info) { gint16 level = request_info->data.GetPrinter.level; proto_item_append_text(bd->item, ", PRINTER_INFO_%d", level); @@ -1981,6 +2015,11 @@ prs_PRINTER_INFO_0(bd->tvb, bd->offset, pinfo, bd->tree, &dp_list, NULL); break; + + case 2: + prs_PRINTER_INFO_2(bd->tvb, bd->offset, pinfo, + bd->tree, &dp_list, NULL); + break; default: proto_tree_add_text(tree, tvb, offset, 0, @@ -2273,6 +2312,58 @@ * AddPrinterEx */ +static int SpoolssAddPrinterEx_q(tvbuff_t *tvb, int offset, + packet_info *pinfo, proto_tree *tree, + char *drep) +{ + dcerpc_info *di = (dcerpc_info *)pinfo->private_data; + request_hash_value *request_info; + guint32 ptr; + char *printer_name; + + /* Update informational fields */ + + if (check_col(pinfo->cinfo, COL_INFO)) + col_set_str(pinfo->cinfo, COL_INFO, "AddPrinterEx request"); + + request_info = fetch_request_info(pinfo, di, SPOOLSS_DUMMY); + + if (request_info) + add_request_text(tree, tvb, offset, request_info); + else + store_request_info_none(pinfo, di); + + /* Parse packet */ + + offset = prs_ptr(tvb, offset, pinfo, tree, &ptr, "Server name"); + + if (ptr) { + offset = prs_struct_and_referents(tvb, offset, pinfo, tree, + prs_UNISTR2_dp, + (void *)&printer_name, NULL); + } + + offset = prs_uint32(tvb, offset, pinfo, tree, NULL, "Level"); + + /* PRINTER INFO LEVEL */ + + offset = prs_uint32(tvb, offset, pinfo, tree, NULL, "Unknown"); + offset = prs_uint32(tvb, offset, pinfo, tree, NULL, "Unknown"); + offset = prs_uint32(tvb, offset, pinfo, tree, NULL, "Unknown"); + offset = prs_uint32(tvb, offset, pinfo, tree, NULL, "Unknown"); + + offset = prs_uint32(tvb, offset, pinfo, tree, NULL, "User switch"); + + /* USER LEVEL */ + + if (tvb_length_remaining(tvb, offset) != 0) + proto_tree_add_text(tree, tvb, offset, 0, + "[Long frame (%d bytes): SPOOLSS]", + tvb_length_remaining(tvb, offset)); + + return offset; +} + static int SpoolssAddPrinterEx_r(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, char *drep) { @@ -2375,7 +2466,9 @@ { dcerpc_info *di = (dcerpc_info *)pinfo->private_data; request_hash_value *request_info; - guint32 data_size, type; + guint32 data_size, type, value_size; + guint16 *uint16s; + char *text; /* Update informational fields */ @@ -2390,10 +2483,22 @@ request_info->response_num = pinfo->fd->num; /* Parse packet */ - - offset = prs_uint32(tvb, offset, pinfo, tree, NULL, "Value size"); - /* unistr2_dp */ + offset = prs_uint32(tvb, offset, pinfo, tree, &value_size, + "Value size"); + + offset = prs_uint16s(tvb, offset, pinfo, tree, value_size, &uint16s, + NULL); + + text = fake_unicode(uint16s, value_size); + + proto_tree_add_text(tree, tvb, offset - value_size * 2, + value_size * 2, "Value: %s", text); + + if (text[0] && check_col(pinfo->cinfo, COL_INFO)) + col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", text); + + free(text); offset = prs_uint32(tvb, offset, pinfo, tree, NULL, "Real value size"); @@ -2506,6 +2611,104 @@ return offset; } +/* + * AddPrinterDriver + */ + +static int SpoolssAddPrinterDriver_q(tvbuff_t *tvb, int offset, + packet_info *pinfo, proto_tree *tree, + char *drep) +{ + dcerpc_info *di = (dcerpc_info *)pinfo->private_data; + request_hash_value *request_info; + + /* Update informational fields */ + + if (check_col(pinfo->cinfo, COL_INFO)) + col_set_str(pinfo->cinfo, COL_INFO, + "AddPrinterDriver request"); + + request_info = fetch_request_info(pinfo, di, SPOOLSS_DUMMY); + + if (request_info) + add_request_text(tree, tvb, offset, request_info); + else + store_request_info_none(pinfo, di); + + /* Parse packet */ + + if (tvb_length_remaining(tvb, offset) != 0) + proto_tree_add_text(tree, tvb, offset, 0, + "[Long frame (%d bytes): SPOOLSS]", + tvb_length_remaining(tvb, offset)); + + return offset; +} + +static int SpoolssAddPrinterDriver_r(tvbuff_t *tvb, int offset, + packet_info *pinfo, proto_tree *tree, + char *drep) +{ + dcerpc_info *di = (dcerpc_info *)pinfo->private_data; + request_hash_value *request_info; + + /* Update informational fields */ + + if (check_col(pinfo->cinfo, COL_INFO)) + col_set_str(pinfo->cinfo, COL_INFO, + "AddPrinterDriver response"); + + request_info = fetch_request_info(pinfo, di, SPOOLSS_DUMMY); + add_response_text(tree, tvb, offset, request_info); + + if (request_info) + request_info->response_num = pinfo->fd->num; + + /* Parse packet */ + + offset = prs_werror(tvb, offset, pinfo, tree, NULL); + + if (tvb_length_remaining(tvb, offset) != 0) + proto_tree_add_text(tree, tvb, offset, 0, + "[Long frame (%d bytes): SPOOLSS]", + tvb_length_remaining(tvb, offset)); + + return offset; +} + +/* + * AddForm + */ + +static int SpoolssAddForm_r(tvbuff_t *tvb, int offset, packet_info *pinfo, + proto_tree *tree, char *drep) +{ + dcerpc_info *di = (dcerpc_info *)pinfo->private_data; + request_hash_value *request_info; + + /* Update informational fields */ + + if (check_col(pinfo->cinfo, COL_INFO)) + col_set_str(pinfo->cinfo, COL_INFO, "AddForm response"); + + request_info = fetch_request_info(pinfo, di, SPOOLSS_DUMMY); + add_response_text(tree, tvb, offset, request_info); + + if (request_info) + request_info->response_num = pinfo->fd->num; + + /* Parse packet */ + + offset = prs_werror(tvb, offset, pinfo, tree, NULL); + + if (tvb_length_remaining(tvb, offset) != 0) + proto_tree_add_text(tree, tvb, offset, 0, + "[Long frame (%d bytes): SPOOLSS]", + tvb_length_remaining(tvb, offset)); + + return offset; +} + #if 0 /* Templates for new subdissectors */ @@ -2588,7 +2791,8 @@ SpoolssSetPrinter_q, SpoolssSetPrinter_r }, { SPOOLSS_GETPRINTER, "SPOOLSS_GETPRINTER", SpoolssGetPrinter_q, SpoolssGetPrinter_r }, - { SPOOLSS_ADDPRINTERDRIVER, "SPOOLSS_ADDPRINTERDRIVER", NULL, NULL }, + { SPOOLSS_ADDPRINTERDRIVER, "SPOOLSS_ADDPRINTERDRIVER", + NULL, SpoolssAddPrinterDriver_r }, { SPOOLSS_ENUMPRINTERDRIVERS, "SPOOLSS_ENUMPRINTERDRIVERS", NULL, NULL }, { SPOOLSS_GETPRINTERDRIVERDIRECTORY, "SPOOLSS_GETPRINTERDRIVERDIRECTORY", NULL, NULL }, { SPOOLSS_DELETEPRINTERDRIVER, "SPOOLSS_DELETEPRINTERDRIVER", NULL, NULL }, @@ -2608,7 +2812,8 @@ SpoolssSetPrinterData_q, SpoolssSetPrinterData_r }, { SPOOLSS_CLOSEPRINTER, "SPOOLSS_CLOSEPRINTER", SpoolssClosePrinter_q, SpoolssClosePrinter_r }, - { SPOOLSS_ADDFORM, "SPOOLSS_ADDFORM", NULL, NULL }, + { SPOOLSS_ADDFORM, "SPOOLSS_ADDFORM", + NULL, SpoolssAddForm_r }, { SPOOLSS_DELETEFORM, "SPOOLSS_DELETEFORM", NULL, NULL }, { SPOOLSS_GETFORM, "SPOOLSS_GETFORM", NULL, NULL }, { SPOOLSS_SETFORM, "SPOOLSS_SETFORM", NULL, NULL }, @@ -2709,6 +2914,7 @@ &ett_BUFFER_DATA, &ett_BUFFER_DATA_BUFFER, &ett_UNISTR2, + &ett_SPOOL_PRINTER_INFO_LEVEL, &ett_PRINTER_INFO_0, &ett_PRINTER_INFO_1, &ett_PRINTER_INFO_2,
- Follow-Ups:
- Re: [Ethereal-dev] Updates to spoolss dissector
- From: Gilbert Ramirez
- Re: [Ethereal-dev] Updates to spoolss dissector
- From: Guy Harris
- Re: [Ethereal-dev] Updates to spoolss dissector
- Prev by Date: Re: [Ethereal-dev] cannot link 0.9.0 command too long
- Next by Date: Re: [Ethereal-dev] Updates to spoolss dissector
- Previous by thread: RE: [Ethereal-dev] cannot link 0.9.0 command too long
- Next by thread: Re: [Ethereal-dev] Updates to spoolss dissector
- Index(es):