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,

Reply via email to