libcli:smb: Add unit test for smb_bytes_pull_str()
authorAndreas Schneider <asn@samba.org>
Thu, 8 Jun 2017 14:08:15 +0000 (16:08 +0200)
committerAndreas Schneider <asn@cryptomilk.org>
Fri, 9 Jun 2017 11:00:11 +0000 (13:00 +0200)
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12824

Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>
Signed-off-by: Andreas Schneider <asn@samba.org>
Signed-off-by: Stefan Metzmacher <metze@samba.org>
libcli/smb/test_smb1cli_session.c [new file with mode: 0644]
libcli/smb/wscript
selftest/tests.py

diff --git a/libcli/smb/test_smb1cli_session.c b/libcli/smb/test_smb1cli_session.c
new file mode 100644 (file)
index 0000000..e924b32
--- /dev/null
@@ -0,0 +1,214 @@
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+#include "replace.h"
+#include <talloc.h>
+#include "libcli/util/ntstatus.h"
+#include "smb_util.h"
+
+static const uint8_t smb1_session_setup_bytes[] = {
+       0xA1, 0x82, 0x01, 0x02, 0x30, 0x81, 0xFF, 0xA0,
+       0x03, 0x0A, 0x01, 0x01, 0xA1, 0x0C, 0x06, 0x0A,
+       0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x02,
+       0x02, 0x0A, 0xA2, 0x81, 0xE9, 0x04, 0x81, 0xE6,
+       0x4E, 0x54, 0x4C, 0x4D, 0x53, 0x53, 0x50, 0x00,
+       0x02, 0x00, 0x00, 0x00, 0x16, 0x00, 0x16, 0x00,
+       0x38, 0x00, 0x00, 0x00, 0x15, 0x82, 0x89, 0x62,
+       0xF6, 0x65, 0xAB, 0x23, 0x47, 0xBC, 0x4D, 0x21,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x98, 0x00, 0x98, 0x00, 0x4E, 0x00, 0x00, 0x00,
+       0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F,
+       0x53, 0x00, 0x41, 0x00, 0x4D, 0x00, 0x42, 0x00,
+       0x41, 0x00, 0x44, 0x00, 0x4F, 0x00, 0x4D, 0x00,
+       0x41, 0x00, 0x49, 0x00, 0x4E, 0x00, 0x02, 0x00,
+       0x16, 0x00, 0x53, 0x00, 0x41, 0x00, 0x4D, 0x00,
+       0x42, 0x00, 0x41, 0x00, 0x44, 0x00, 0x4F, 0x00,
+       0x4D, 0x00, 0x41, 0x00, 0x49, 0x00, 0x4E, 0x00,
+       0x01, 0x00, 0x0E, 0x00, 0x4C, 0x00, 0x4F, 0x00,
+       0x43, 0x00, 0x41, 0x00, 0x4C, 0x00, 0x44, 0x00,
+       0x43, 0x00, 0x04, 0x00, 0x22, 0x00, 0x73, 0x00,
+       0x61, 0x00, 0x6D, 0x00, 0x62, 0x00, 0x61, 0x00,
+       0x2E, 0x00, 0x65, 0x00, 0x78, 0x00, 0x61, 0x00,
+       0x6D, 0x00, 0x70, 0x00, 0x6C, 0x00, 0x65, 0x00,
+       0x2E, 0x00, 0x63, 0x00, 0x6F, 0x00, 0x6D, 0x00,
+       0x03, 0x00, 0x32, 0x00, 0x6C, 0x00, 0x6F, 0x00,
+       0x63, 0x00, 0x61, 0x00, 0x6C, 0x00, 0x64, 0x00,
+       0x63, 0x00, 0x2E, 0x00, 0x73, 0x00, 0x61, 0x00,
+       0x6D, 0x00, 0x62, 0x00, 0x61, 0x00, 0x2E, 0x00,
+       0x65, 0x00, 0x78, 0x00, 0x61, 0x00, 0x6D, 0x00,
+       0x70, 0x00, 0x6C, 0x00, 0x65, 0x00, 0x2E, 0x00,
+       0x63, 0x00, 0x6F, 0x00, 0x6D, 0x00, 0x07, 0x00,
+       0x08, 0x00, 0x0C, 0x40, 0xA3, 0xC3, 0x5B, 0xE0,
+       0xD2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55,
+       0x00, 0x6E, 0x00, 0x69, 0x00, 0x78, 0x00, 0x00,
+       0x00, 0x53, 0x00, 0x61, 0x00, 0x6D, 0x00, 0x62,
+       0x00, 0x61, 0x00, 0x20, 0x00, 0x34, 0x00, 0x2E,
+       0x00, 0x37, 0x00, 0x2E, 0x00, 0x30, 0x00, 0x70,
+       0x00, 0x72, 0x00, 0x65, 0x00, 0x31, 0x00, 0x2D,
+       0x00, 0x44, 0x00, 0x45, 0x00, 0x56, 0x00, 0x45,
+       0x00, 0x4C, 0x00, 0x4F, 0x00, 0x50, 0x00, 0x45,
+       0x00, 0x52, 0x00, 0x42, 0x00, 0x55, 0x00, 0x49,
+       0x00, 0x4C, 0x00, 0x44, 0x00, 0x00, 0x00, 0x53,
+       0x00, 0x41, 0x00, 0x4D, 0x00, 0x42, 0x00, 0x41,
+       0x00, 0x44, 0x00, 0x4F, 0x00, 0x4D, 0x00, 0x41,
+       0x00, 0x49, 0x00, 0x4E, 0x00, 0x00, 0x00
+};
+
+static void test_smb_bytes_pull_str(void **state)
+{
+       NTSTATUS status;
+       const uint8_t *bytes = smb1_session_setup_bytes;
+       const size_t num_bytes = sizeof(smb1_session_setup_bytes);
+       const uint8_t *p = NULL;
+       size_t ret = 0;
+       size_t out_security_blob_length = 262;
+       bool use_unicode = true;
+       char *str = NULL;
+
+       p = bytes;
+       p += out_security_blob_length;
+
+       status = smb_bytes_pull_str(NULL, &str, use_unicode,
+                                   bytes, num_bytes,
+                                   p, &ret);
+       assert_true(NT_STATUS_IS_OK(status));
+       assert_string_equal(str, "Unix");
+       assert_int_equal(ret, 0x0b);
+       TALLOC_FREE(str);
+
+       p += ret;
+       status = smb_bytes_pull_str(NULL, &str, use_unicode,
+                                   bytes, num_bytes,
+                                   p, &ret);
+       assert_true(NT_STATUS_IS_OK(status));
+       assert_string_equal(str, "Samba 4.7.0pre1-DEVELOPERBUILD");
+       assert_int_equal(ret, 0x3e);
+       TALLOC_FREE(str);
+
+       p += ret;
+       status = smb_bytes_pull_str(NULL, &str, use_unicode,
+                                   bytes, num_bytes,
+                                   p, &ret);
+       assert_true(NT_STATUS_IS_OK(status));
+       assert_string_equal(str, "SAMBADOMAIN");
+       assert_int_equal(ret, 0x18);
+       TALLOC_FREE(str);
+
+       p += ret;
+       status = smb_bytes_pull_str(NULL, &str, use_unicode,
+                                   bytes, num_bytes,
+                                   p, &ret);
+       assert_true(NT_STATUS_IS_OK(status));
+       assert_string_equal(str, "");
+       assert_int_equal(ret, 0x00);
+       TALLOC_FREE(str);
+}
+
+static void test_smb_bytes_pull_str_no_unicode(void **state)
+{
+       NTSTATUS status;
+       const uint8_t *bytes = smb1_session_setup_bytes;
+       const size_t num_bytes = sizeof(smb1_session_setup_bytes);
+       const uint8_t *p = NULL;
+       size_t ret = 0;
+       size_t out_security_blob_length = 262;
+       bool use_unicode = false;
+       char *str = NULL;
+
+       p = bytes;
+       p += out_security_blob_length;
+
+       status = smb_bytes_pull_str(NULL, &str, use_unicode,
+                                   bytes, num_bytes,
+                                   p, &ret);
+       assert_true(NT_STATUS_IS_OK(status));
+       assert_string_equal(str, "");
+       assert_int_equal(ret, 0x01);
+       TALLOC_FREE(str);
+}
+
+static void test_smb_bytes_pull_str_wrong_offset(void **state)
+{
+       NTSTATUS status;
+       const uint8_t *bytes = smb1_session_setup_bytes;
+       const size_t num_bytes = sizeof(smb1_session_setup_bytes);
+       const uint8_t *p = NULL;
+       size_t ret = 0;
+       size_t out_security_blob_length = 261;
+       bool use_unicode = true;
+       char *str = NULL;
+
+       bytes += 1;
+       p = bytes;
+       p += out_security_blob_length;
+
+       status = smb_bytes_pull_str(NULL, &str, use_unicode,
+                                   bytes, num_bytes,
+                                   p, &ret);
+       assert_true(NT_STATUS_IS_OK(status));
+
+       assert_string_equal(str, "\xE5\x94\x80\xE6\xB8\x80\xE6\xA4\x80\xE7\xA0\x80");
+       assert_int_equal(ret, 0x0a);
+       TALLOC_FREE(str);
+}
+
+static void test_smb_bytes_pull_str_invalid_offset(void **state)
+{
+       NTSTATUS status;
+       const uint8_t *bytes = smb1_session_setup_bytes;
+       const size_t num_bytes = sizeof(smb1_session_setup_bytes);
+       const uint8_t *p = NULL;
+       size_t ret = 0;
+       bool use_unicode = true;
+       char *str = NULL;
+       intptr_t bytes_address = (intptr_t)bytes;
+
+       /* Warning: array subscript is below array bounds */
+       p = (const uint8_t *)(bytes_address - 1);
+       status = smb_bytes_pull_str(NULL, &str, use_unicode,
+                                   bytes, num_bytes,
+                                   p, &ret);
+       assert_int_equal(NT_STATUS_V(status),
+                        NT_STATUS_V(NT_STATUS_INTERNAL_ERROR));
+
+       p = bytes + num_bytes;
+       status = smb_bytes_pull_str(NULL, &str, use_unicode,
+                                   bytes, num_bytes,
+                                   p, &ret);
+       assert_true(NT_STATUS_IS_OK(status));
+       assert_string_equal(str, "");
+       assert_int_equal(ret, 0x00);
+       TALLOC_FREE(str);
+
+       p = bytes + num_bytes - 1;
+       status = smb_bytes_pull_str(NULL, &str, use_unicode,
+                                   bytes, num_bytes,
+                                   p, &ret);
+       assert_true(NT_STATUS_IS_OK(status));
+       assert_string_equal(str, "");
+       assert_int_equal(ret, 0x01);
+       TALLOC_FREE(str);
+
+       /* Warning: array subscript is above array bounds */
+       p = (const uint8_t *)(bytes_address + num_bytes + 1);
+       status = smb_bytes_pull_str(NULL, &str, use_unicode,
+                                   bytes, num_bytes,
+                                   p, &ret);
+       assert_int_equal(NT_STATUS_V(status),
+                        NT_STATUS_V(NT_STATUS_BUFFER_TOO_SMALL));
+}
+
+int main(void)
+{
+       const struct CMUnitTest tests[] = {
+               cmocka_unit_test(test_smb_bytes_pull_str),
+               cmocka_unit_test(test_smb_bytes_pull_str_no_unicode),
+               cmocka_unit_test(test_smb_bytes_pull_str_wrong_offset),
+               cmocka_unit_test(test_smb_bytes_pull_str_invalid_offset),
+       };
+
+       cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
+       return cmocka_run_group_tests(tests, NULL, NULL);
+}
index dacf631810d2f57ece0dbe55251912545de389a0..e6628266ddcbae07eb5d18f7ca9b6868aa1175c7 100644 (file)
@@ -64,3 +64,8 @@ def build(bld):
                     tstream_smbXcli_np.h
     ''',
     )
+
+    bld.SAMBA_BINARY('test_smb1cli_session',
+                     source='test_smb1cli_session.c',
+                     deps='cmocka cli_smb_common',
+                     install=False)
index b9c470c557a765f4b357ee980b02c89795ea8a6b..5367fe35936a1de36aa61f4272d5ea3eea1d048f 100644 (file)
@@ -149,3 +149,6 @@ if with_cmocka:
                   [os.path.join(bindir(), "default/testsuite/unittests/test_sambafs_srv_pipe")])
     plantestsuite("samba.unittests.lib_util_modules", "none",
                   [os.path.join(bindir(), "default/testsuite/unittests/test_lib_util_modules")])
+
+    plantestsuite("samba.unittests.smb1cli_session", "none",
+                  [os.path.join(bindir(), "default/libcli/smb/test_smb1cli_session")])