mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
503226406b
Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org>
216 lines
6.6 KiB
C
216 lines
6.6 KiB
C
#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_constants.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);
|
|
}
|