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 2019 Nexenta by DDN, 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
msg_put_a0()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
msg_put_a1()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
msg_put_apad()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
msg_put_atrunc1()130 msg_put_atrunc1()
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_atrunc1 encode\n");
145 goto out;
146 }
147
148 if (memcmp(temp, wire, 4)) {
149 printf("Fail: msg_put_atrunc1 cmp:\n");
150 hexdump((uchar_t *)temp, 4);
151 return;
152 }
153
154 printf("Pass: msg_put_atrunc1\n");
155
156 out:
157 smb_msgbuf_term(&mb);
158 }
159
160 static void
msg_put_atrunc2()161 msg_put_atrunc2()
162 {
163 uint8_t wire[] = { 'o', 'n', 'e', 't', 0};
164 uint8_t temp[32];
165 smb_msgbuf_t mb;
166 int mbflags = 0;
167 int rc;
168
169 (void) memset(temp, 0, sizeof (temp));
170 smb_msgbuf_init(&mb, temp, 4, mbflags);
171
172 /* Encode with wire length < strlen */
173 rc = smb_msgbuf_encode(&mb, "s", "onetwo");
174 /* Trunc should return "overflow" */
175 if (rc != -1) {
176 printf("Fail: msg_put_atrunc2 encode rc=%d\n", rc);
177 goto out;
178 }
179
180 if (memcmp(temp, wire, 5)) {
181 printf("Fail: msg_put_atrunc2 cmp:\n");
182 hexdump((uchar_t *)temp, 5);
183 return;
184 }
185
186 printf("Pass: msg_put_atrunc2\n");
187
188 out:
189 smb_msgbuf_term(&mb);
190 }
191
192 /*
193 * Put unicode string with NULL
194 */
195 static void
msg_put_u0()196 msg_put_u0()
197 {
198 uint16_t wire[] = { 'o', 'n', 'e', 0, 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, "Uw", "one", 42);
207 if (rc != 10) {
208 printf("Fail: msg_put_u0 encode\n");
209 goto out;
210 }
211
212 if (memcmp(temp, wire, 10)) {
213 printf("Fail: msg_put_u0 cmp:\n");
214 hexdump((uchar_t *)temp, 10);
215 return;
216 }
217
218 printf("Pass: msg_put_u0\n");
219
220 out:
221 smb_msgbuf_term(&mb);
222 }
223
224 /*
225 * Put unicode string, no NULL
226 */
227 static void
msg_put_u1()228 msg_put_u1()
229 {
230 uint16_t wire[] = { 'o', 'n', 'e', '.', 42, 0 };
231 uint8_t temp[32];
232 smb_msgbuf_t mb;
233 int mbflags = 0;
234 int rc;
235
236 smb_msgbuf_init(&mb, temp, sizeof (temp), mbflags);
237
238 rc = smb_msgbuf_encode(&mb, "8Uw", "one.", 42);
239 if (rc != 10) {
240 printf("Fail: msg_put_u1 encode\n");
241 goto out;
242 }
243
244 if (memcmp(temp, wire, 10)) {
245 printf("Fail: msg_put_u1 cmp:\n");
246 hexdump((uchar_t *)temp, 10);
247 return;
248 }
249
250 printf("Pass: msg_put_u1\n");
251
252 out:
253 smb_msgbuf_term(&mb);
254 }
255
256 static void
msg_put_u3()257 msg_put_u3()
258 {
259 uint8_t temp[32];
260 smb_msgbuf_t mb;
261 int mbflags = 0;
262 int rc;
263
264 smb_msgbuf_init(&mb, temp, sizeof (temp), mbflags);
265
266 rc = smb_msgbuf_encode(&mb, "U", mbsa);
267 if (rc != 8) {
268 printf("Fail: msg_put_u3 encode\n");
269 goto out;
270 }
271
272 if (memcmp(temp, wcsa, 8)) {
273 printf("Fail: msg_put_u3 cmp:\n");
274 hexdump((uchar_t *)temp, 8);
275 return;
276 }
277
278 printf("Pass: msg_put_u3\n");
279
280 out:
281 smb_msgbuf_term(&mb);
282 }
283
284 static void
msg_put_u4()285 msg_put_u4()
286 {
287 uint8_t temp[32];
288 smb_msgbuf_t mb;
289 int mbflags = 0;
290 int rc;
291
292 smb_msgbuf_init(&mb, temp, sizeof (temp), mbflags);
293
294 rc = smb_msgbuf_encode(&mb, "U", mbsp);
295 if (rc != 10) {
296 printf("Fail: msg_put_u4 encode\n");
297 goto out;
298 }
299
300 if (memcmp(temp, wcsp, 10)) {
301 printf("Fail: msg_put_u4 cmp:\n");
302 hexdump((uchar_t *)temp, 10);
303 return;
304 }
305
306 printf("Pass: msg_put_u4\n");
307
308 out:
309 smb_msgbuf_term(&mb);
310 }
311
312 static void
msg_put_upad()313 msg_put_upad()
314 {
315 uint16_t wire[] = { 'o', 'n', 'e', 0, 0 };
316 uint8_t temp[32];
317 smb_msgbuf_t mb;
318 int mbflags = 0;
319 int rc;
320
321 smb_msgbuf_init(&mb, temp, sizeof (temp), mbflags);
322
323 /* Encode with wire length > strlen */
324 rc = smb_msgbuf_encode(&mb, "10U", "one");
325 if (rc != 10) {
326 printf("Fail: msg_put_upad encode\n");
327 goto out;
328 }
329
330 if (memcmp(temp, wire, 10)) {
331 printf("Fail: msg_put_upad cmp:\n");
332 hexdump((uchar_t *)temp, 10);
333 return;
334 }
335
336 printf("Pass: msg_put_upad\n");
337
338 out:
339 smb_msgbuf_term(&mb);
340 }
341
342 static void
msg_put_utrunc1()343 msg_put_utrunc1()
344 {
345 uint16_t wire[] = { 'o', 'n', 'e', 't' };
346 uint8_t temp[32];
347 smb_msgbuf_t mb;
348 int mbflags = 0;
349 int rc;
350
351 smb_msgbuf_init(&mb, temp, sizeof (temp), mbflags);
352
353 /* Encode with wire length < strlen */
354 rc = smb_msgbuf_encode(&mb, "8U", "onetwo");
355 /* Trunc should put exactly 8 */
356 if (rc != 8) {
357 printf("Fail: msg_put_utrunc1 encode\n");
358 goto out;
359 }
360
361 if (memcmp(temp, wire, 8)) {
362 printf("Fail: msg_put_utrunc1 cmp:\n");
363 hexdump((uchar_t *)temp, 8);
364 return;
365 }
366
367 printf("Pass: msg_put_utrunc1\n");
368
369 out:
370 smb_msgbuf_term(&mb);
371 }
372
373 static void
msg_put_utrunc2()374 msg_put_utrunc2()
375 {
376 uint16_t wire[] = { 'o', 'n', 'e', 't', 0 };
377 uint8_t temp[32];
378 smb_msgbuf_t mb;
379 int mbflags = 0;
380 int rc;
381
382 (void) memset(temp, 0, sizeof (temp));
383 smb_msgbuf_init(&mb, temp, 8, mbflags);
384
385 /* Encode with wire length < strlen */
386 rc = smb_msgbuf_encode(&mb, "U", "onetwo");
387 /* Trunc should return "overflow" */
388 if (rc != -1) {
389 printf("Fail: msg_put_utrunc2 encode rc=%d\n", rc);
390 goto out;
391 }
392
393 if (memcmp(temp, wire, 10)) {
394 printf("Fail: msg_put_utrunc2 cmp:\n");
395 hexdump((uchar_t *)temp, 10);
396 return;
397 }
398
399 printf("Pass: msg_put_utrunc2\n");
400
401 out:
402 smb_msgbuf_term(&mb);
403 }
404
405 /*
406 * Parse an ascii string.
407 */
408 static void
msg_get_a0()409 msg_get_a0()
410 {
411 uint8_t wire[] = { 'o', 'n', 'e', 0, 42, 0 };
412 smb_msgbuf_t mb;
413 int mbflags = 0;
414 char *s;
415 int rc;
416 uint16_t w;
417
418 smb_msgbuf_init(&mb, wire, sizeof (wire), mbflags);
419
420 rc = smb_msgbuf_decode(&mb, "sw", &s, &w);
421 if (rc != 6) {
422 printf("Fail: msg_get_a0 decode\n");
423 goto out;
424 }
425 /*
426 * Decode a word after the string to make sure we
427 * end up positioned correctly after the string.
428 */
429 if (w != 42) {
430 printf("Fail: msg_get_a0 w=%d\n", w);
431 return;
432 }
433 if (strcmp(s, "one") != 0) {
434 printf("Fail: msg_get_a0 cmp: <%s>\n", s);
435 return;
436 }
437
438 printf("Pass: msg_get_a0\n");
439
440 out:
441 smb_msgbuf_term(&mb);
442 }
443
444 /*
445 * Parse an ascii string, no NULL
446 */
447 static void
msg_get_a1()448 msg_get_a1()
449 {
450 uint8_t wire[] = { 'o', 'n', 'e', '.', 42, 0 };
451 smb_msgbuf_t mb;
452 int mbflags = 0;
453 char *s;
454 int rc;
455 uint16_t w;
456
457 smb_msgbuf_init(&mb, wire, sizeof (wire), mbflags);
458
459 rc = smb_msgbuf_decode(&mb, "3s.w", &s, &w);
460 if (rc != 6) {
461 printf("Fail: msg_get_a1 decode\n");
462 goto out;
463 }
464 /*
465 * Decode a word after the string to make sure we
466 * end up positioned correctly after the string.
467 */
468 if (w != 42) {
469 printf("Fail: msg_get_a1 w=%d\n", w);
470 return;
471 }
472 if (strcmp(s, "one") != 0) {
473 printf("Fail: msg_get_a1 cmp: <%s>\n", s);
474 return;
475 }
476
477 printf("Pass: msg_get_a1\n");
478
479 out:
480 smb_msgbuf_term(&mb);
481 }
482
483 /* parse exactly to end of data */
484 static void
msg_get_a2()485 msg_get_a2()
486 {
487 uint8_t wire[] = { 'o', 'n', 'e' };
488 smb_msgbuf_t mb;
489 int mbflags = 0;
490 char *s;
491 int rc;
492
493 smb_msgbuf_init(&mb, wire, sizeof (wire), mbflags);
494
495 rc = smb_msgbuf_decode(&mb, "3s", &s);
496 if (rc != 3) {
497 printf("Fail: msg_get_a2 decode\n");
498 goto out;
499 }
500 if (mb.scan != mb.end) {
501 printf("Fail: msg_get_a2 wrong pos\n");
502 return;
503 }
504 if (strcmp(s, "one") != 0) {
505 printf("Fail: msg_get_a2 cmp: <%s>\n", s);
506 return;
507 }
508
509 printf("Pass: msg_get_a2\n");
510
511 out:
512 smb_msgbuf_term(&mb);
513 }
514
515 /*
516 * Parse a unicode string.
517 */
518 static void
msg_get_u0()519 msg_get_u0()
520 {
521 uint16_t wire[] = { 'o', 'n', 'e', 0, 42, 0 };
522 smb_msgbuf_t mb;
523 int mbflags = 0;
524 char *s;
525 int rc;
526 uint16_t w;
527
528 smb_msgbuf_init(&mb, (uint8_t *)wire, sizeof (wire), mbflags);
529
530 rc = smb_msgbuf_decode(&mb, "Uw", &s, &w);
531 if (rc != 10) {
532 printf("Fail: msg_get_u0 decode\n");
533 goto out;
534 }
535 /*
536 * Decode a word after the string to make sure we
537 * end up positioned correctly after the string.
538 */
539 if (w != 42) {
540 printf("Fail: msg_get_u0 w=%d\n", w);
541 return;
542 }
543 if (strcmp(s, "one") != 0) {
544 printf("Fail: msg_get_u0 cmp: <%s>\n", s);
545 return;
546 }
547
548 printf("Pass: msg_get_u0\n");
549
550 out:
551 smb_msgbuf_term(&mb);
552 }
553
554 /*
555 * Parse a string that's NOT null terminated.
556 */
557 static void
msg_get_u1()558 msg_get_u1()
559 {
560 uint16_t wire[] = { 'o', 'n', 'e', '.', 42, 0 };
561 smb_msgbuf_t mb;
562 int mbflags = 0;
563 char *s;
564 int rc;
565 uint16_t w;
566
567 smb_msgbuf_init(&mb, (uint8_t *)wire, sizeof (wire), mbflags);
568
569 rc = smb_msgbuf_decode(&mb, "6U..w", &s, &w);
570 if (rc != 10) {
571 printf("Fail: msg_get_u1 decode\n");
572 goto out;
573 }
574 /*
575 * Decode a word after the string to make sure we
576 * end up positioned correctly after the string.
577 */
578 if (w != 42) {
579 printf("Fail: msg_get_u1 w=%d\n", w);
580 return;
581 }
582 if (strcmp(s, "one") != 0) {
583 printf("Fail: msg_get_u1 cmp: <%s>\n", s);
584 return;
585 }
586
587 printf("Pass: msg_get_u1\n");
588
589 out:
590 smb_msgbuf_term(&mb);
591 }
592
593 /* parse exactly to end of data */
594 static void
msg_get_u2()595 msg_get_u2()
596 {
597 uint16_t wire[] = { 'o', 'n', 'e' };
598 smb_msgbuf_t mb;
599 int mbflags = 0;
600 char *s;
601 int rc;
602
603 smb_msgbuf_init(&mb, (uint8_t *)wire, sizeof (wire), mbflags);
604
605 rc = smb_msgbuf_decode(&mb, "6U", &s);
606 if (rc != 6) {
607 printf("Fail: msg_get_u2 decode\n");
608 goto out;
609 }
610 if (mb.scan != mb.end) {
611 printf("Fail: msg_get_u2 wrong pos\n");
612 return;
613 }
614 if (strcmp(s, "one") != 0) {
615 printf("Fail: msg_get_u2 cmp: <%s>\n", s);
616 return;
617 }
618
619 printf("Pass: msg_get_u2\n");
620
621 out:
622 smb_msgbuf_term(&mb);
623 }
624
625 static void
msg_get_u3()626 msg_get_u3()
627 {
628 smb_msgbuf_t mb;
629 int mbflags = 0;
630 char *s;
631 int rc;
632
633 smb_msgbuf_init(&mb, (uint8_t *)wcsa, sizeof (wcsa), mbflags);
634
635 rc = smb_msgbuf_decode(&mb, "#U", sizeof (wcsa), &s);
636 if (rc != 8) {
637 printf("Fail: msg_get_u3 decode\n");
638 goto out;
639 }
640 if (strcmp(s, mbsa) != 0) {
641 printf("Fail: msg_get_u3 cmp: <%s>\n", s);
642 return;
643 }
644
645 printf("Pass: msg_get_u3\n");
646
647 out:
648 smb_msgbuf_term(&mb);
649 }
650
651 static void
msg_get_u4()652 msg_get_u4()
653 {
654 smb_msgbuf_t mb;
655 int mbflags = 0;
656 char *s;
657 int rc;
658
659 smb_msgbuf_init(&mb, (uint8_t *)wcsp, sizeof (wcsp), mbflags);
660
661 rc = smb_msgbuf_decode(&mb, "#U", sizeof (wcsp), &s);
662 if (rc != 10) {
663 printf("Fail: msg_get_u4 decode\n");
664 goto out;
665 }
666 if (strcmp(s, mbsp) != 0) {
667 printf("Fail: msg_get_u4 cmp: <%s>\n", s);
668 return;
669 }
670
671 printf("Pass: msg_get_u4\n");
672
673 out:
674 smb_msgbuf_term(&mb);
675 }
676
677 void
test_msgbuf()678 test_msgbuf()
679 {
680
681 msg_put_a0();
682 msg_put_a1();
683 msg_put_apad();
684 msg_put_atrunc1();
685 msg_put_atrunc2();
686
687 msg_put_u0();
688 msg_put_u1();
689 msg_put_u3();
690 msg_put_u4();
691 msg_put_upad();
692 msg_put_utrunc1();
693 msg_put_utrunc2();
694
695 msg_get_a0();
696 msg_get_a1();
697 msg_get_a2();
698 msg_get_u0();
699 msg_get_u1();
700 msg_get_u2();
701 msg_get_u3();
702 msg_get_u4();
703
704 }
705