From 6f0d30fd5cc921dedbc0f0741e3959b4ebc4027d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 20 Nov 2019 10:00:52 +1300 Subject: [PATCH] ndrdump: Allow for base64-encoded input in a file and on the command line It has become customary to provide reproduction steps for fuzzing failures in terms of an ndrdump command line. This allows the input to be provided as a argument or in a file rather than via base64 -d. This makes reproducing the issue easier as everything can be put in a plaintext bug report. Signed-off-by: Andrew Bartlett Reviewed-by: Douglas Bagnall --- librpc/tools/ndrdump.c | 42 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/librpc/tools/ndrdump.c b/librpc/tools/ndrdump.c index 31f82c27d99..4938111c729 100644 --- a/librpc/tools/ndrdump.c +++ b/librpc/tools/ndrdump.c @@ -26,6 +26,7 @@ #include "librpc/gen_ndr/ndr_dcerpc.h" #include "lib/cmdline/popt_common.h" #include "param/param.h" +#include "lib/util/base64.h" static const struct ndr_interface_call *find_function( const struct ndr_interface_table *p, @@ -265,6 +266,7 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) * name of a public structure */ const char *format = NULL; + const char *cmdline_input = NULL; const uint8_t *data; size_t size; DATA_BLOB blob; @@ -284,6 +286,7 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) bool assume_ndr64 = false; bool quiet = false; bool hex_input = false; + bool base64_input = false; bool stop_on_parse_failure = false; int opt; enum { @@ -293,7 +296,9 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) OPT_LOAD_DSO, OPT_NDR64, OPT_QUIET, + OPT_BASE64_INPUT, OPT_HEX_INPUT, + OPT_CMDLINE_INPUT, OPT_STOP_ON_PARSE_FAILURE, }; struct poptOption long_options[] = { @@ -304,7 +309,9 @@ 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 }, + {"base64-input", 0, POPT_ARG_NONE, NULL, OPT_BASE64_INPUT, "Read the input file in as a base64 string", NULL }, {"hex-input", 0, POPT_ARG_NONE, NULL, OPT_HEX_INPUT, "Read the input file in as a hex dump", NULL }, + {"input", 0, POPT_ARG_STRING, NULL, OPT_CMDLINE_INPUT, "Provide the input on the command line (use with --base64-input)", "INPUT" }, {"stop-on-parse-failure", 0, POPT_ARG_NONE, NULL, OPT_STOP_ON_PARSE_FAILURE, "Do not try to print structures that fail to parse.", NULL }, POPT_COMMON_SAMBA @@ -348,9 +355,15 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) case OPT_QUIET: quiet = true; break; + case OPT_BASE64_INPUT: + base64_input = true; + break; case OPT_HEX_INPUT: hex_input = true; break; + case OPT_CMDLINE_INPUT: + cmdline_input = poptGetOptArg(pc); + break; case OPT_STOP_ON_PARSE_FAILURE: stop_on_parse_failure = true; break; @@ -484,10 +497,18 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) memcpy(v_st, st, f->struct_size); } - if (filename) + if (filename && cmdline_input) { + printf("cannot combine --input with a filename\n"); + TALLOC_FREE(mem_ctx); + exit(1); + } else if (cmdline_input) { + data = (const uint8_t *)cmdline_input; + size = strlen(cmdline_input); + } else if (filename) { data = (uint8_t *)file_load(filename, &size, 0, mem_ctx); - else + } else { data = (uint8_t *)stdin_load(mem_ctx, &size); + } if (!data) { if (filename) @@ -497,10 +518,19 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...) exit(1); } - if (hex_input) { - blob = hexdump_to_data_blob(mem_ctx, - (const char *)data, - size); + if (hex_input && base64_input) { + printf("cannot combine --hex-input with --base64-input\n"); + TALLOC_FREE(mem_ctx); + exit(1); + + } else if (hex_input) { + blob = hexdump_to_data_blob(mem_ctx, (const char *)data, size); + } else if (base64_input) { + /* Use talloc_strndup() to ensure null termination */ + blob = base64_decode_data_blob(talloc_strndup(mem_ctx, + (const char *)data, size)); + /* base64_decode_data_blob() allocates on NULL */ + talloc_steal(mem_ctx, blob.data); } else { blob = data_blob_const(data, size); } -- 2.47.3