1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
14 */
15
16 /*
17 * Test putting/getting unicode strings in mbchains.
18 */
19
20 #include <sys/types.h>
21 #include <sys/debug.h>
22 #include <sys/varargs.h>
23 #include <smbsrv/smb_kproto.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <strings.h>
27
28 #include "test_defs.h"
29
30 static char mbsa[] = "A\xef\xbc\xa1."; // A fwA . (5)
31 static char mbsp[] = "P\xf0\x9f\x92\xa9."; // P poop . (6)
32 static smb_wchar_t wcsa[] = { 'A', 0xff21, '.', 0 }; // (3)
33 static smb_wchar_t wcsp[] = { 'P', 0xd83d, 0xdca9, '.', 0 }; // (4)
34
35 /*
36 * Put ASCII string with NULL
37 */
38 static void
39 msg_put_a0()
40 {
41 uint8_t wire[] = { 'o', 'n', 'e', 0, 42, 0 };
42 uint8_t temp[32];
43 smb_msgbuf_t mb;
44 int mbflags = 0;
45 int rc;
46
47 smb_msgbuf_init(&mb, temp, sizeof (temp), mbflags);
48
49 rc = smb_msgbuf_encode(&mb, "sw", "one", 42);
50 if (rc != 6) {
51 printf("Fail: msg_put_a0 encode\n");
52 goto out;
53 }
54
55 if (memcmp(temp, wire, 6)) {
56 printf("Fail: msg_put_a0 cmp:\n");
57 hexdump((uchar_t *)temp, 6);
58 return;
59 }
60
61 printf("Pass: msg_put_a0\n");
62
63 out:
64 smb_msgbuf_term(&mb);
65 }
66
67 /*
68 * Put ASCII string, no NULL
69 */
70 static void
71 msg_put_a1()
72 {
73 uint8_t wire[] = { 'o', 'n', 'e', '.', 42, 0 };
74 uint8_t temp[32];
75 smb_msgbuf_t mb;
76 int mbflags = 0;
77 int rc;
78
79 smb_msgbuf_init(&mb, temp, sizeof (temp), mbflags);
80
81 rc = smb_msgbuf_encode(&mb, "4sw", "one.", 42);
82 if (rc != 6) {
83 printf("Fail: msg_put_a1 encode\n");
84 goto out;
85 }
86
87 if (memcmp(temp, wire, 6)) {
88 printf("Fail: msg_put_a1 cmp:\n");
89 hexdump((uchar_t *)temp, 6);
90 return;
91 }
92
93 printf("Pass: msg_put_a1\n");
94
95 out:
96 smb_msgbuf_term(&mb);
97 }
98
99 static void
100 msg_put_apad()
101 {
102 uint8_t wire[] = { 'o', 'n', 'e', 0, 0 };
103 uint8_t temp[32];
104 smb_msgbuf_t mb;
105 int mbflags = 0;
106 int rc;
107
108 smb_msgbuf_init(&mb, temp, sizeof (temp), mbflags);
109
110 /* Encode with wire length > strlen */
111 rc = smb_msgbuf_encode(&mb, "5s", "one");
112 if (rc != 5) {
113 printf("Fail: msg_put_apad encode\n");
114 goto out;
115 }
116
117 if (memcmp(temp, wire, 5)) {
118 printf("Fail: msg_put_apad cmp:\n");
119 hexdump((uchar_t *)temp, 5);
120 return;
121 }
122
123 printf("Pass: msg_put_apad\n");
124
125 out:
126 smb_msgbuf_term(&mb);
127 }
128
129 static void
130 msg_put_atrunc()
131 {
132 uint8_t wire[] = { 'o', 'n', 'e', 't', };
133 uint8_t temp[32];
134 smb_msgbuf_t mb;
135 int mbflags = 0;
136 int rc;
137
138 smb_msgbuf_init(&mb, temp, sizeof (temp), mbflags);
139
140 /* Encode with wire length < strlen */
141 rc = smb_msgbuf_encode(&mb, "4s", "onetwo");
142 /* Trunc should put exactly 4 */
143 if (rc != 4) {
144 printf("Fail: msg_put_atrunc encode\n");
145 goto out;
146 }
147
148 if (memcmp(temp, wire, 4)) {
149 printf("Fail: msg_put_atrunc cmp:\n");
150 hexdump((uchar_t *)temp, 4);
151 return;
152 }
153
154 printf("Pass: msg_put_atrunc\n");
155
156 out:
157 smb_msgbuf_term(&mb);
158 }
159
160 /*
161 * Put unicode string with NULL
162 */
163 static void
164 msg_put_u0()
165 {
166 uint16_t wire[] = { 'o', 'n', 'e', 0, 42, 0 };
167 uint8_t temp[32];
168 smb_msgbuf_t mb;
169 int mbflags = 0;
170 int rc;
171
172 smb_msgbuf_init(&mb, temp, sizeof (temp), mbflags);
173
174 rc = smb_msgbuf_encode(&mb, "Uw", "one", 42);
175 if (rc != 10) {
176 printf("Fail: msg_put_u0 encode\n");
177 goto out;
178 }
179
180 if (memcmp(temp, wire, 10)) {
181 printf("Fail: msg_put_u0 cmp:\n");
182 hexdump((uchar_t *)temp, 10);
183 return;
184 }
185
186 printf("Pass: msg_put_u0\n");
187
188 out:
189 smb_msgbuf_term(&mb);
190 }
191
192 /*
193 * Put unicode string, no NULL
194 */
195 static void
196 msg_put_u1()
197 {
198 uint16_t wire[] = { 'o', 'n', 'e', '.', 42, 0 };
199 uint8_t temp[32];
200 smb_msgbuf_t mb;
201 int mbflags = 0;
202 int rc;
203
204 smb_msgbuf_init(&mb, temp, sizeof (temp), mbflags);
205
206 rc = smb_msgbuf_encode(&mb, "8Uw", "one.", 42);
207 if (rc != 10) {
208 printf("Fail: msg_put_u1 encode\n");
209 goto out;
210 }
211
212 if (memcmp(temp, wire, 10)) {
213 printf("Fail: msg_put_u1 cmp:\n");
214 hexdump((uchar_t *)temp, 10);
215 return;
216 }
217
218 printf("Pass: msg_put_u1\n");
219
220 out:
221 smb_msgbuf_term(&mb);
222 }
223
224 static void
225 msg_put_u3()
226 {
227 uint8_t temp[32];
228 smb_msgbuf_t mb;
229 int mbflags = 0;
230 int rc;
231
232 smb_msgbuf_init(&mb, temp, sizeof (temp), mbflags);
233
234 rc = smb_msgbuf_encode(&mb, "U", mbsa);
235 if (rc != 8) {
236 printf("Fail: msg_put_u3 encode\n");
237 goto out;
238 }
239
240 if (memcmp(temp, wcsa, 8)) {
241 printf("Fail: msg_put_u3 cmp:\n");
242 hexdump((uchar_t *)temp, 8);
243 return;
244 }
245
246 printf("Pass: msg_put_u3\n");
247
248 out:
249 smb_msgbuf_term(&mb);
250 }
251
252 static void
253 msg_put_u4()
254 {
255 uint8_t temp[32];
256 smb_msgbuf_t mb;
257 int mbflags = 0;
258 int rc;
259
260 smb_msgbuf_init(&mb, temp, sizeof (temp), mbflags);
261
262 rc = smb_msgbuf_encode(&mb, "U", mbsp);
263 if (rc != 10) {
264 printf("Fail: msg_put_u4 encode\n");
265 goto out;
266 }
267
268 if (memcmp(temp, wcsp, 10)) {
269 printf("Fail: msg_put_u4 cmp:\n");
270 hexdump((uchar_t *)temp, 10);
271 return;
272 }
273
274 printf("Pass: msg_put_u4\n");
275
276 out:
277 smb_msgbuf_term(&mb);
278 }
279
280 static void
281 msg_put_upad()
282 {
283 uint16_t wire[] = { 'o', 'n', 'e', 0, 0 };
284 uint8_t temp[32];
285 smb_msgbuf_t mb;
286 int mbflags = 0;
287 int rc;
288
289 smb_msgbuf_init(&mb, temp, sizeof (temp), mbflags);
290
291 /* Encode with wire length > strlen */
292 rc = smb_msgbuf_encode(&mb, "10U", "one");
293 if (rc != 10) {
294 printf("Fail: msg_put_upad encode\n");
295 goto out;
296 }
297
298 if (memcmp(temp, wire, 10)) {
299 printf("Fail: msg_put_upad cmp:\n");
300 hexdump((uchar_t *)temp, 10);
301 return;
302 }
303
304 printf("Pass: msg_put_upad\n");
305
306 out:
307 smb_msgbuf_term(&mb);
308 }
309
310 static void
311 msg_put_utrunc()
312 {
313 uint16_t wire[] = { 'o', 'n', 'e', 't' };
314 uint8_t temp[32];
315 smb_msgbuf_t mb;
316 int mbflags = 0;
317 int rc;
318
319 smb_msgbuf_init(&mb, temp, sizeof (temp), mbflags);
320
321 /* Encode with wire length < strlen */
322 rc = smb_msgbuf_encode(&mb, "8U", "onetwo");
323 /* Trunc should put exactly 8 */
324 if (rc != 8) {
325 printf("Fail: msg_put_utrunc encode\n");
326 goto out;
327 }
328
329 if (memcmp(temp, wire, 8)) {
330 printf("Fail: msg_put_utrunc cmp:\n");
331 hexdump((uchar_t *)temp, 8);
332 return;
333 }
334
335 printf("Pass: msg_put_utrunc\n");
336
337 out:
338 smb_msgbuf_term(&mb);
339 }
340
341 /*
342 * Parse an ascii string.
343 */
344 static void
345 msg_get_a0()
346 {
347 uint8_t wire[] = { 'o', 'n', 'e', 0, 42, 0 };
348 smb_msgbuf_t mb;
349 int mbflags = 0;
350 char *s;
351 int rc;
352 uint16_t w;
353
354 smb_msgbuf_init(&mb, wire, sizeof (wire), mbflags);
355
356 rc = smb_msgbuf_decode(&mb, "sw", &s, &w);
357 if (rc != 6) {
358 printf("Fail: msg_get_a0 decode\n");
359 goto out;
360 }
361 /*
362 * Decode a word after the string to make sure we
363 * end up positioned correctly after the string.
364 */
365 if (w != 42) {
366 printf("Fail: msg_get_a0 w=%d\n", w);
367 return;
368 }
369 if (strcmp(s, "one") != 0) {
370 printf("Fail: msg_get_a0 cmp: <%s>\n", s);
371 return;
372 }
373
374 printf("Pass: msg_get_a0\n");
375
376 out:
377 smb_msgbuf_term(&mb);
378 }
379
380 /*
381 * Parse an ascii string, no NULL
382 */
383 static void
384 msg_get_a1()
385 {
386 uint8_t wire[] = { 'o', 'n', 'e', '.', 42, 0 };
387 smb_msgbuf_t mb;
388 int mbflags = 0;
389 char *s;
390 int rc;
391 uint16_t w;
392
393 smb_msgbuf_init(&mb, wire, sizeof (wire), mbflags);
394
395 rc = smb_msgbuf_decode(&mb, "3s.w", &s, &w);
396 if (rc != 6) {
397 printf("Fail: msg_get_a1 decode\n");
398 goto out;
399 }
400 /*
401 * Decode a word after the string to make sure we
402 * end up positioned correctly after the string.
403 */
404 if (w != 42) {
405 printf("Fail: msg_get_a1 w=%d\n", w);
406 return;
407 }
408 if (strcmp(s, "one") != 0) {
409 printf("Fail: msg_get_a1 cmp: <%s>\n", s);
410 return;
411 }
412
413 printf("Pass: msg_get_a1\n");
414
415 out:
416 smb_msgbuf_term(&mb);
417 }
418
419 /* parse exactly to end of data */
420 static void
421 msg_get_a2()
422 {
423 uint8_t wire[] = { 'o', 'n', 'e' };
424 smb_msgbuf_t mb;
425 int mbflags = 0;
426 char *s;
427 int rc;
428
429 smb_msgbuf_init(&mb, wire, sizeof (wire), mbflags);
430
431 rc = smb_msgbuf_decode(&mb, "3s", &s);
432 if (rc != 3) {
433 printf("Fail: msg_get_a2 decode\n");
434 goto out;
435 }
436 if (mb.scan != mb.end) {
437 printf("Fail: msg_get_a2 wrong pos\n");
438 return;
439 }
440 if (strcmp(s, "one") != 0) {
441 printf("Fail: msg_get_a2 cmp: <%s>\n", s);
442 return;
443 }
444
445 printf("Pass: msg_get_a2\n");
446
447 out:
448 smb_msgbuf_term(&mb);
449 }
450
451 /*
452 * Parse a unicode string.
453 */
454 static void
455 msg_get_u0()
456 {
457 uint16_t wire[] = { 'o', 'n', 'e', 0, 42, 0 };
458 smb_msgbuf_t mb;
459 int mbflags = 0;
460 char *s;
461 int rc;
462 uint16_t w;
463
464 smb_msgbuf_init(&mb, (uint8_t *)wire, sizeof (wire), mbflags);
465
466 rc = smb_msgbuf_decode(&mb, "Uw", &s, &w);
467 if (rc != 10) {
468 printf("Fail: msg_get_u0 decode\n");
469 goto out;
470 }
471 /*
472 * Decode a word after the string to make sure we
473 * end up positioned correctly after the string.
474 */
475 if (w != 42) {
476 printf("Fail: msg_get_u0 w=%d\n", w);
477 return;
478 }
479 if (strcmp(s, "one") != 0) {
480 printf("Fail: msg_get_u0 cmp: <%s>\n", s);
481 return;
482 }
483
484 printf("Pass: msg_get_u0\n");
485
486 out:
487 smb_msgbuf_term(&mb);
488 }
489
490 /*
491 * Parse a string that's NOT null terminated.
492 */
493 static void
494 msg_get_u1()
495 {
496 uint16_t wire[] = { 'o', 'n', 'e', '.', 42, 0 };
497 smb_msgbuf_t mb;
498 int mbflags = 0;
499 char *s;
500 int rc;
501 uint16_t w;
502
503 smb_msgbuf_init(&mb, (uint8_t *)wire, sizeof (wire), mbflags);
504
505 rc = smb_msgbuf_decode(&mb, "6U..w", &s, &w);
506 if (rc != 10) {
507 printf("Fail: msg_get_u1 decode\n");
508 goto out;
509 }
510 /*
511 * Decode a word after the string to make sure we
512 * end up positioned correctly after the string.
513 */
514 if (w != 42) {
515 printf("Fail: msg_get_u1 w=%d\n", w);
516 return;
517 }
518 if (strcmp(s, "one") != 0) {
519 printf("Fail: msg_get_u1 cmp: <%s>\n", s);
520 return;
521 }
522
523 printf("Pass: msg_get_u1\n");
524
525 out:
526 smb_msgbuf_term(&mb);
527 }
528
529 /* parse exactly to end of data */
530 static void
531 msg_get_u2()
532 {
533 uint16_t wire[] = { 'o', 'n', 'e' };
534 smb_msgbuf_t mb;
535 int mbflags = 0;
536 char *s;
537 int rc;
538
539 smb_msgbuf_init(&mb, (uint8_t *)wire, sizeof (wire), mbflags);
540
541 rc = smb_msgbuf_decode(&mb, "6U", &s);
542 if (rc != 6) {
543 printf("Fail: msg_get_u2 decode\n");
544 goto out;
545 }
546 if (mb.scan != mb.end) {
547 printf("Fail: msg_get_u2 wrong pos\n");
548 return;
549 }
550 if (strcmp(s, "one") != 0) {
551 printf("Fail: msg_get_u2 cmp: <%s>\n", s);
552 return;
553 }
554
555 printf("Pass: msg_get_u2\n");
556
557 out:
558 smb_msgbuf_term(&mb);
559 }
560
561 static void
562 msg_get_u3()
563 {
564 smb_msgbuf_t mb;
565 int mbflags = 0;
566 char *s;
567 int rc;
568
569 smb_msgbuf_init(&mb, (uint8_t *)wcsa, sizeof (wcsa), mbflags);
570
571 rc = smb_msgbuf_decode(&mb, "#U", sizeof (wcsa), &s);
572 if (rc != 8) {
573 printf("Fail: msg_get_u3 decode\n");
574 goto out;
575 }
576 if (strcmp(s, mbsa) != 0) {
577 printf("Fail: msg_get_u3 cmp: <%s>\n", s);
578 return;
579 }
580
581 printf("Pass: msg_get_u3\n");
582
583 out:
584 smb_msgbuf_term(&mb);
585 }
586
587 static void
588 msg_get_u4()
589 {
590 smb_msgbuf_t mb;
591 int mbflags = 0;
592 char *s;
593 int rc;
594
595 smb_msgbuf_init(&mb, (uint8_t *)wcsp, sizeof (wcsp), mbflags);
596
597 rc = smb_msgbuf_decode(&mb, "#U", sizeof (wcsp), &s);
598 if (rc != 10) {
599 printf("Fail: msg_get_u4 decode\n");
600 goto out;
601 }
602 if (strcmp(s, mbsp) != 0) {
603 printf("Fail: msg_get_u4 cmp: <%s>\n", s);
604 return;
605 }
606
607 printf("Pass: msg_get_u4\n");
608
609 out:
610 smb_msgbuf_term(&mb);
611 }
612
613 void
614 test_msgbuf()
615 {
616
617 msg_put_a0();
618 msg_put_a1();
619 msg_put_apad();
620 msg_put_atrunc();
621
622 msg_put_u0();
623 msg_put_u1();
624 msg_put_u3();
625 msg_put_u4();
626 msg_put_upad();
627 msg_put_utrunc();
628
629 msg_get_a0();
630 msg_get_a1();
631 msg_get_a2();
632 msg_get_u0();
633 msg_get_u1();
634 msg_get_u2();
635 msg_get_u3();
636 msg_get_u4();
637
638 }