ndrdump: Add the option --hex-input for hexdump parsing
authorCody Harrington <cody@harringtonca.com>
Sat, 27 Aug 2016 15:01:18 +0000 (03:01 +1200)
committerAndrew Bartlett <abartlet@samba.org>
Tue, 14 Feb 2017 08:46:23 +0000 (09:46 +0100)
This allows the user to input a hexdump that has been generated by the dump option.

Signed-off-by: Cody Harrington <cody@harringtonca.com>
Reviewed-by: Garming Sam <garming@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
lib/util/samba_util.h
lib/util/util.c
librpc/tools/ndrdump.c

index 3f663690247760ee7e5a34e39df2505991ab177b..8aa8ebae3b987efd25aff1f1f9399b2f894d18c4 100644 (file)
@@ -122,7 +122,7 @@ _PUBLIC_ char *generate_random_str(TALLOC_CTX *mem_ctx, size_t len);
  * Characters used are: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+_-#.,
  */
 _PUBLIC_ char** generate_unique_strs(TALLOC_CTX *mem_ctx, size_t len,
-                                         uint32_t num);
+                                        uint32_t num);
 
 /* The following definitions come from lib/util/dprintf.c  */
 
@@ -175,6 +175,11 @@ _PUBLIC_ size_t strhex_to_str(char *p, size_t p_len, const char *strhex, size_t
  */
 _PUBLIC_ _PURE_ DATA_BLOB strhex_to_data_blob(TALLOC_CTX *mem_ctx, const char *strhex) ;
 
+/**
+ * Parse a hex dump and return a data blob
+ */
+_PUBLIC_ _PURE_ DATA_BLOB hexdump_to_data_blob(TALLOC_CTX *mem_ctx, const char *hexdump, size_t len);
+
 /**
  * Print a buf in hex. Assumes dst is at least (srclen*2)+1 large.
  */
@@ -587,7 +592,7 @@ _PUBLIC_ void daemon_status(const char *name, const char *msg);
  * @param[in]  prompt   The prompt to show to ask for the password.
  *
  * @param[out] buf    The buffer the password should be stored. It NEEDS to be
- *                      empty or filled out.
+ *                   empty or filled out.
  *
  * @param[in]  len      The length of the buffer.
  *
@@ -604,8 +609,8 @@ _PUBLIC_ int samba_getpass(const char *prompt, char *buf, size_t len,
  * Load a ini-style file.
  */
 bool pm_process( const char *fileName,
-                 bool (*sfunc)(const char *, void *),
-                 bool (*pfunc)(const char *, const char *, void *),
+                bool (*sfunc)(const char *, void *),
+                bool (*pfunc)(const char *, const char *, void *),
                                 void *userdata);
 bool pm_process_with_flags(const char *filename,
                           bool allow_empty_values,
index 56056a3403ce7c442833748a0de2e3769ad9e0bf..a8f2e00a82d081cbe900e5bb30b71b039dce3738 100644 (file)
@@ -903,8 +903,8 @@ _PUBLIC_ size_t strhex_to_str(char *p, size_t p_len, const char *strhex, size_t
        return num_chars;
 }
 
-/** 
- * Parse a hex string and return a data blob. 
+/**
+ * Parse a hex string and return a data blob.
  */
 _PUBLIC_ _PURE_ DATA_BLOB strhex_to_data_blob(TALLOC_CTX *mem_ctx, const char *strhex) 
 {
@@ -917,6 +917,46 @@ _PUBLIC_ _PURE_ DATA_BLOB strhex_to_data_blob(TALLOC_CTX *mem_ctx, const char *s
        return ret_blob;
 }
 
+/**
+ * Parse a hex dump and return a data blob. Hex dump is structured as 
+ * is generated from dump_data_cb() elsewhere in this file
+ * 
+ */
+_PUBLIC_ _PURE_ DATA_BLOB hexdump_to_data_blob(TALLOC_CTX *mem_ctx, const char *hexdump, size_t hexdump_len)
+{
+       DATA_BLOB ret_blob = {'\0'};
+       size_t i = 0;
+       size_t char_count = 0;
+       /* hexdump line length is 77 chars long. We then use the ASCII representation of the bytes
+        * at the end of the final line to calculate how many are in that line, minus the extra space
+        * and newline. */
+       size_t hexdump_byte_count = (16 * (hexdump_len / 77));
+       if (hexdump_len % 77) {
+               hexdump_byte_count += ((hexdump_len % 77) - 59 - 2);
+       }
+       
+       ret_blob = data_blob_talloc(mem_ctx, NULL, hexdump_byte_count+1);
+       for (; i+1 < hexdump_len && hexdump[i] != 0 && hexdump[i+1] != 0; i++) {
+               if ((i%77) == 0) 
+                       i += 7; /* Skip the offset at the start of the line */
+               if ((i%77) < 56) { /* position 56 is after both hex chunks */
+                       if (hexdump[i] != ' ') {
+                               char_count += strhex_to_str((char *)&ret_blob.data[char_count],
+                                                           hexdump_byte_count - char_count,
+                                                           &hexdump[i], 2);
+                               i += 2;
+                       } else {
+                               i++;
+                       }
+               } else {
+                       i++;
+               }
+       }
+       ret_blob.length = char_count;
+       
+       return ret_blob;
+}
+
 /**
  * Print a buf in hex. Assumes dst is at least (srclen*2)+1 large.
  */
index d534e3c1dbaa8ff203826760984071776f68cd04..b1e96b8a84232131d1e1f109fa1e427cae25b848 100644 (file)
@@ -213,8 +213,9 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...)
        bool dumpdata = false;
        bool assume_ndr64 = false;
        bool quiet = false;
+       bool hex_input = false;
        int opt;
-       enum {OPT_CONTEXT_FILE=1000, OPT_VALIDATE, OPT_DUMP_DATA, OPT_LOAD_DSO, OPT_NDR64, OPT_QUIET};
+       enum {OPT_CONTEXT_FILE=1000, OPT_VALIDATE, OPT_DUMP_DATA, OPT_LOAD_DSO, OPT_NDR64, OPT_QUIET, OPT_HEX_INPUT};
        struct poptOption long_options[] = {
                POPT_AUTOHELP
                {"context-file", 'c', POPT_ARG_STRING, NULL, OPT_CONTEXT_FILE, "In-filename to parse first", "CTX-FILE" },
@@ -223,6 +224,7 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...)
                {"load-dso", 'l', POPT_ARG_STRING, NULL, OPT_LOAD_DSO, "load from shared object file", NULL },
                {"ndr64", 0, POPT_ARG_NONE, NULL, OPT_NDR64, "Assume NDR64 data", NULL },
                {"quiet", 0, POPT_ARG_NONE, NULL, OPT_QUIET, "Don't actually dump anything", NULL },
+               {"hex-input", 0, POPT_ARG_NONE, NULL, OPT_HEX_INPUT, "Read the input file in as a hex dump", NULL },
                POPT_COMMON_SAMBA
                POPT_COMMON_VERSION
                { NULL }
@@ -231,7 +233,7 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...)
        const struct ndr_interface_call_pipes *out_pipes = NULL;
        uint32_t highest_ofs;
        struct dcerpc_sec_verification_trailer *sec_vt = NULL;
-
+       
        ndr_table_init();
 
        /* Initialise samba stuff */
@@ -266,6 +268,9 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...)
                case OPT_QUIET:
                        quiet = true;
                        break;
+               case OPT_HEX_INPUT:
+                       hex_input = true;
+                       break;
                }
        }
 
@@ -381,7 +386,7 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...)
                        exit(1);
                }
                memcpy(v_st, st, f->struct_size);
-       } 
+       }
 
        if (filename)
                data = (uint8_t *)file_load(filename, &size, 0, mem_ctx);
@@ -395,9 +400,13 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...)
                        perror("stdin");
                exit(1);
        }
-
-       blob.data = data;
-       blob.length = size;
+       
+       if (hex_input) {
+               blob = hexdump_to_data_blob(mem_ctx, (char *)data, size);
+       } else {
+               blob.data = data;
+               blob.length = size;
+       }
 
        ndr_pull = ndr_pull_init_blob(&blob, mem_ctx);
        if (ndr_pull == NULL) {
@@ -584,7 +593,6 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...)
        }
 
        printf("dump OK\n");
-
        talloc_free(mem_ctx);
 
        poptFreeContext(pc);