Line data Source code
1 : #include <stdarg.h>
2 : #include <stddef.h>
3 : #include <stdint.h>
4 : #include <setjmp.h>
5 : #include <cmocka.h>
6 :
7 : #include "replace.h"
8 : #include <talloc.h>
9 : #include "libcli/util/ntstatus.h"
10 : #include "smb_constants.h"
11 : #include "smb_util.h"
12 :
13 : static const uint8_t smb1_session_setup_bytes[] = {
14 : 0xA1, 0x82, 0x01, 0x02, 0x30, 0x81, 0xFF, 0xA0,
15 : 0x03, 0x0A, 0x01, 0x01, 0xA1, 0x0C, 0x06, 0x0A,
16 : 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x02,
17 : 0x02, 0x0A, 0xA2, 0x81, 0xE9, 0x04, 0x81, 0xE6,
18 : 0x4E, 0x54, 0x4C, 0x4D, 0x53, 0x53, 0x50, 0x00,
19 : 0x02, 0x00, 0x00, 0x00, 0x16, 0x00, 0x16, 0x00,
20 : 0x38, 0x00, 0x00, 0x00, 0x15, 0x82, 0x89, 0x62,
21 : 0xF6, 0x65, 0xAB, 0x23, 0x47, 0xBC, 0x4D, 0x21,
22 : 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
23 : 0x98, 0x00, 0x98, 0x00, 0x4E, 0x00, 0x00, 0x00,
24 : 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F,
25 : 0x53, 0x00, 0x41, 0x00, 0x4D, 0x00, 0x42, 0x00,
26 : 0x41, 0x00, 0x44, 0x00, 0x4F, 0x00, 0x4D, 0x00,
27 : 0x41, 0x00, 0x49, 0x00, 0x4E, 0x00, 0x02, 0x00,
28 : 0x16, 0x00, 0x53, 0x00, 0x41, 0x00, 0x4D, 0x00,
29 : 0x42, 0x00, 0x41, 0x00, 0x44, 0x00, 0x4F, 0x00,
30 : 0x4D, 0x00, 0x41, 0x00, 0x49, 0x00, 0x4E, 0x00,
31 : 0x01, 0x00, 0x0E, 0x00, 0x4C, 0x00, 0x4F, 0x00,
32 : 0x43, 0x00, 0x41, 0x00, 0x4C, 0x00, 0x44, 0x00,
33 : 0x43, 0x00, 0x04, 0x00, 0x22, 0x00, 0x73, 0x00,
34 : 0x61, 0x00, 0x6D, 0x00, 0x62, 0x00, 0x61, 0x00,
35 : 0x2E, 0x00, 0x65, 0x00, 0x78, 0x00, 0x61, 0x00,
36 : 0x6D, 0x00, 0x70, 0x00, 0x6C, 0x00, 0x65, 0x00,
37 : 0x2E, 0x00, 0x63, 0x00, 0x6F, 0x00, 0x6D, 0x00,
38 : 0x03, 0x00, 0x32, 0x00, 0x6C, 0x00, 0x6F, 0x00,
39 : 0x63, 0x00, 0x61, 0x00, 0x6C, 0x00, 0x64, 0x00,
40 : 0x63, 0x00, 0x2E, 0x00, 0x73, 0x00, 0x61, 0x00,
41 : 0x6D, 0x00, 0x62, 0x00, 0x61, 0x00, 0x2E, 0x00,
42 : 0x65, 0x00, 0x78, 0x00, 0x61, 0x00, 0x6D, 0x00,
43 : 0x70, 0x00, 0x6C, 0x00, 0x65, 0x00, 0x2E, 0x00,
44 : 0x63, 0x00, 0x6F, 0x00, 0x6D, 0x00, 0x07, 0x00,
45 : 0x08, 0x00, 0x0C, 0x40, 0xA3, 0xC3, 0x5B, 0xE0,
46 : 0xD2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55,
47 : 0x00, 0x6E, 0x00, 0x69, 0x00, 0x78, 0x00, 0x00,
48 : 0x00, 0x53, 0x00, 0x61, 0x00, 0x6D, 0x00, 0x62,
49 : 0x00, 0x61, 0x00, 0x20, 0x00, 0x34, 0x00, 0x2E,
50 : 0x00, 0x37, 0x00, 0x2E, 0x00, 0x30, 0x00, 0x70,
51 : 0x00, 0x72, 0x00, 0x65, 0x00, 0x31, 0x00, 0x2D,
52 : 0x00, 0x44, 0x00, 0x45, 0x00, 0x56, 0x00, 0x45,
53 : 0x00, 0x4C, 0x00, 0x4F, 0x00, 0x50, 0x00, 0x45,
54 : 0x00, 0x52, 0x00, 0x42, 0x00, 0x55, 0x00, 0x49,
55 : 0x00, 0x4C, 0x00, 0x44, 0x00, 0x00, 0x00, 0x53,
56 : 0x00, 0x41, 0x00, 0x4D, 0x00, 0x42, 0x00, 0x41,
57 : 0x00, 0x44, 0x00, 0x4F, 0x00, 0x4D, 0x00, 0x41,
58 : 0x00, 0x49, 0x00, 0x4E, 0x00, 0x00, 0x00
59 : };
60 :
61 1 : static void test_smb_bytes_pull_str(void **state)
62 : {
63 1 : NTSTATUS status;
64 1 : const uint8_t *bytes = smb1_session_setup_bytes;
65 1 : const size_t num_bytes = sizeof(smb1_session_setup_bytes);
66 1 : const uint8_t *p = NULL;
67 1 : size_t ret = 0;
68 1 : size_t out_security_blob_length = 262;
69 1 : bool use_unicode = true;
70 1 : char *str = NULL;
71 :
72 1 : p = bytes;
73 1 : p += out_security_blob_length;
74 :
75 1 : status = smb_bytes_pull_str(NULL, &str, use_unicode,
76 : bytes, num_bytes,
77 : p, &ret);
78 1 : assert_true(NT_STATUS_IS_OK(status));
79 1 : assert_string_equal(str, "Unix");
80 1 : assert_int_equal(ret, 0x0b);
81 1 : TALLOC_FREE(str);
82 :
83 1 : p += ret;
84 1 : status = smb_bytes_pull_str(NULL, &str, use_unicode,
85 : bytes, num_bytes,
86 : p, &ret);
87 1 : assert_true(NT_STATUS_IS_OK(status));
88 1 : assert_string_equal(str, "Samba 4.7.0pre1-DEVELOPERBUILD");
89 1 : assert_int_equal(ret, 0x3e);
90 1 : TALLOC_FREE(str);
91 :
92 1 : p += ret;
93 1 : status = smb_bytes_pull_str(NULL, &str, use_unicode,
94 : bytes, num_bytes,
95 : p, &ret);
96 1 : assert_true(NT_STATUS_IS_OK(status));
97 1 : assert_string_equal(str, "SAMBADOMAIN");
98 1 : assert_int_equal(ret, 0x18);
99 1 : TALLOC_FREE(str);
100 :
101 1 : p += ret;
102 1 : status = smb_bytes_pull_str(NULL, &str, use_unicode,
103 : bytes, num_bytes,
104 : p, &ret);
105 1 : assert_true(NT_STATUS_IS_OK(status));
106 1 : assert_string_equal(str, "");
107 1 : assert_int_equal(ret, 0x00);
108 1 : TALLOC_FREE(str);
109 1 : }
110 :
111 1 : static void test_smb_bytes_pull_str_no_unicode(void **state)
112 : {
113 1 : NTSTATUS status;
114 1 : const uint8_t *bytes = smb1_session_setup_bytes;
115 1 : const size_t num_bytes = sizeof(smb1_session_setup_bytes);
116 1 : const uint8_t *p = NULL;
117 1 : size_t ret = 0;
118 1 : size_t out_security_blob_length = 262;
119 1 : bool use_unicode = false;
120 1 : char *str = NULL;
121 :
122 1 : p = bytes;
123 1 : p += out_security_blob_length;
124 :
125 1 : status = smb_bytes_pull_str(NULL, &str, use_unicode,
126 : bytes, num_bytes,
127 : p, &ret);
128 1 : assert_true(NT_STATUS_IS_OK(status));
129 1 : assert_string_equal(str, "");
130 1 : assert_int_equal(ret, 0x01);
131 1 : TALLOC_FREE(str);
132 1 : }
133 :
134 1 : static void test_smb_bytes_pull_str_wrong_offset(void **state)
135 : {
136 1 : NTSTATUS status;
137 1 : const uint8_t *bytes = smb1_session_setup_bytes;
138 1 : const size_t num_bytes = sizeof(smb1_session_setup_bytes);
139 1 : const uint8_t *p = NULL;
140 1 : size_t ret = 0;
141 1 : size_t out_security_blob_length = 261;
142 1 : bool use_unicode = true;
143 1 : char *str = NULL;
144 :
145 1 : bytes += 1;
146 1 : p = bytes;
147 1 : p += out_security_blob_length;
148 :
149 1 : status = smb_bytes_pull_str(NULL, &str, use_unicode,
150 : bytes, num_bytes,
151 : p, &ret);
152 1 : assert_true(NT_STATUS_IS_OK(status));
153 :
154 1 : assert_string_equal(str, "\xE5\x94\x80\xE6\xB8\x80\xE6\xA4\x80\xE7\xA0\x80");
155 1 : assert_int_equal(ret, 0x0a);
156 1 : TALLOC_FREE(str);
157 1 : }
158 :
159 1 : static void test_smb_bytes_pull_str_invalid_offset(void **state)
160 : {
161 1 : NTSTATUS status;
162 1 : const uint8_t *bytes = smb1_session_setup_bytes;
163 1 : const size_t num_bytes = sizeof(smb1_session_setup_bytes);
164 1 : const uint8_t *p = NULL;
165 1 : size_t ret = 0;
166 1 : bool use_unicode = true;
167 1 : char *str = NULL;
168 1 : intptr_t bytes_address = (intptr_t)bytes;
169 :
170 : /* Warning: array subscript is below array bounds */
171 1 : p = (const uint8_t *)(bytes_address - 1);
172 1 : status = smb_bytes_pull_str(NULL, &str, use_unicode,
173 : bytes, num_bytes,
174 : p, &ret);
175 1 : assert_int_equal(NT_STATUS_V(status),
176 : NT_STATUS_V(NT_STATUS_INTERNAL_ERROR));
177 :
178 1 : p = bytes + num_bytes;
179 1 : status = smb_bytes_pull_str(NULL, &str, use_unicode,
180 : bytes, num_bytes,
181 : p, &ret);
182 1 : assert_true(NT_STATUS_IS_OK(status));
183 1 : assert_string_equal(str, "");
184 1 : assert_int_equal(ret, 0x00);
185 1 : TALLOC_FREE(str);
186 :
187 1 : p = bytes + num_bytes - 1;
188 1 : status = smb_bytes_pull_str(NULL, &str, use_unicode,
189 : bytes, num_bytes,
190 : p, &ret);
191 1 : assert_true(NT_STATUS_IS_OK(status));
192 1 : assert_string_equal(str, "");
193 1 : assert_int_equal(ret, 0x01);
194 1 : TALLOC_FREE(str);
195 :
196 : /* Warning: array subscript is above array bounds */
197 1 : p = (const uint8_t *)(bytes_address + num_bytes + 1);
198 1 : status = smb_bytes_pull_str(NULL, &str, use_unicode,
199 : bytes, num_bytes,
200 : p, &ret);
201 1 : assert_int_equal(NT_STATUS_V(status),
202 : NT_STATUS_V(NT_STATUS_BUFFER_TOO_SMALL));
203 1 : }
204 :
205 1 : int main(void)
206 : {
207 1 : const struct CMUnitTest tests[] = {
208 : cmocka_unit_test(test_smb_bytes_pull_str),
209 : cmocka_unit_test(test_smb_bytes_pull_str_no_unicode),
210 : cmocka_unit_test(test_smb_bytes_pull_str_wrong_offset),
211 : cmocka_unit_test(test_smb_bytes_pull_str_invalid_offset),
212 : };
213 :
214 1 : cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
215 1 : return cmocka_run_group_tests(tests, NULL, NULL);
216 : }
|