xref: /illumos-gate/usr/src/cmd/smbsrv/test-msgbuf/test_mbmarshal.c (revision 66582b606a8194f7f3ba5b3a3a6dca5b0d346361)
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 smb_session_t test_ssn;
36 smb_request_t test_sr;
37 
38 /*
39  * Put ASCII string with NULL
40  */
41 static void
42 mbm_put_a0()
43 {
44 	uint8_t wire[] = { 'o', 'n', 'e', 0, 42, 0 };
45 	mbuf_chain_t *mbc;
46 	int rc;
47 
48 	mbc = smb_mbc_alloc(100);
49 
50 	rc = smb_mbc_encodef(mbc, "sw", "one", 42);
51 	if (rc != 0) {
52 		printf("Fail: mbm_put_a0 encode\n");
53 		goto out;
54 	}
55 	if (mbc->chain->m_len != 6) {
56 		printf("Fail: mbm_put_a0 len=%d\n",
57 		    mbc->chain->m_len);
58 		return;
59 	}
60 
61 	if (memcmp(mbc->chain->m_data, wire, 6)) {
62 		printf("Fail: mbm_put_a0 cmp:\n");
63 		hexdump((uchar_t *)mbc->chain->m_data, 6);
64 		return;
65 	}
66 
67 	printf("Pass: mbm_put_a0\n");
68 
69 out:
70 	smb_mbc_free(mbc);
71 }
72 
73 /*
74  * Put ASCII string, no NULL
75  */
76 static void
77 mbm_put_a1()
78 {
79 	uint8_t wire[] = { 'o', 'n', 'e', '.', 42, 0 };
80 	mbuf_chain_t *mbc;
81 	int rc;
82 
83 	mbc = smb_mbc_alloc(100);
84 
85 	rc = smb_mbc_encodef(mbc, "4sw", "one.", 42);
86 	if (rc != 0) {
87 		printf("Fail: mbm_put_a1 encode\n");
88 		goto out;
89 	}
90 	if (mbc->chain->m_len != 6) {
91 		printf("Fail: mbm_put_a1 len=%d\n",
92 		    mbc->chain->m_len);
93 		return;
94 	}
95 
96 	if (memcmp(mbc->chain->m_data, wire, 6)) {
97 		printf("Fail: mbm_put_a1 cmp:\n");
98 		hexdump((uchar_t *)mbc->chain->m_data, 6);
99 		return;
100 	}
101 
102 	printf("Pass: mbm_put_a1\n");
103 
104 out:
105 	smb_mbc_free(mbc);
106 }
107 
108 static void
109 mbm_put_apad()
110 {
111 	uint8_t wire[] = { 'o', 'n', 'e', 0, 0 };
112 	mbuf_chain_t *mbc;
113 	int rc;
114 
115 	mbc = smb_mbc_alloc(100);
116 
117 	/* Encode with wire length > strlen */
118 	rc = smb_mbc_encodef(mbc, "5s", "one");
119 	if (rc != 0) {
120 		printf("Fail: mbm_put_apad encode\n");
121 		goto out;
122 	}
123 	if (mbc->chain->m_len != 5) {
124 		printf("Fail: mbm_put_apad len=%d\n",
125 		    mbc->chain->m_len);
126 		return;
127 	}
128 
129 	if (memcmp(mbc->chain->m_data, wire, 5)) {
130 		printf("Fail: mbm_put_apad cmp:\n");
131 		hexdump((uchar_t *)mbc->chain->m_data, 5);
132 		return;
133 	}
134 
135 	printf("Pass: mbm_put_apad\n");
136 
137 out:
138 	smb_mbc_free(mbc);
139 }
140 
141 static void
142 mbm_put_atrunc()
143 {
144 	uint8_t wire[] = { 'o', 'n', 'e', 't', };
145 	mbuf_chain_t *mbc;
146 	int rc;
147 
148 	mbc = smb_mbc_alloc(100);
149 
150 	/* Encode with wire length < strlen */
151 	rc = smb_mbc_encodef(mbc, "4s", "onetwo");
152 	if (rc != 0) {
153 		printf("Fail: mbm_put_atrunc encode\n");
154 		goto out;
155 	}
156 	/* Trunc should put exactly 4 */
157 	if (mbc->chain->m_len != 4) {
158 		printf("Fail: mbm_put_atrunc len=%d\n",
159 		    mbc->chain->m_len);
160 		return;
161 	}
162 
163 	if (memcmp(mbc->chain->m_data, wire, 4)) {
164 		printf("Fail: mbm_put_atrunc cmp:\n");
165 		hexdump((uchar_t *)mbc->chain->m_data, 4);
166 		return;
167 	}
168 
169 	printf("Pass: mbm_put_atrunc\n");
170 
171 out:
172 	smb_mbc_free(mbc);
173 }
174 
175 /*
176  * Put unicode string with NULL
177  */
178 static void
179 mbm_put_u0()
180 {
181 	uint16_t wire[] = { 'o', 'n', 'e', 0, 42, 0 };
182 	mbuf_chain_t *mbc;
183 	int rc;
184 
185 	mbc = smb_mbc_alloc(100);
186 
187 	rc = smb_mbc_encodef(mbc, "Uw", "one", 42);
188 	if (rc != 0) {
189 		printf("Fail: mbm_put_u0 encode\n");
190 		goto out;
191 	}
192 	if (mbc->chain->m_len != 10) {
193 		printf("Fail: mbm_put_u0 len=%d\n",
194 		    mbc->chain->m_len);
195 		return;
196 	}
197 
198 	if (memcmp(mbc->chain->m_data, wire, 10)) {
199 		printf("Fail: mbm_put_u0 cmp:\n");
200 		hexdump((uchar_t *)mbc->chain->m_data, 10);
201 		return;
202 	}
203 
204 	printf("Pass: mbm_put_u0\n");
205 
206 out:
207 	smb_mbc_free(mbc);
208 }
209 
210 /*
211  * Put unicode string, no NULL
212  */
213 static void
214 mbm_put_u1()
215 {
216 	uint16_t wire[] = { 'o', 'n', 'e', '.', 42, 0 };
217 	mbuf_chain_t *mbc;
218 	int rc;
219 
220 	mbc = smb_mbc_alloc(100);
221 
222 	rc = smb_mbc_encodef(mbc, "8Uw", "one.", 42);
223 	if (rc != 0) {
224 		printf("Fail: mbm_put_u1 encode\n");
225 		goto out;
226 	}
227 	if (mbc->chain->m_len != 10) {
228 		printf("Fail: mbm_put_u1 len=%d\n",
229 		    mbc->chain->m_len);
230 		return;
231 	}
232 
233 	if (memcmp(mbc->chain->m_data, wire, 10)) {
234 		printf("Fail: mbm_put_u1 cmp:\n");
235 		hexdump((uchar_t *)mbc->chain->m_data, 10);
236 		return;
237 	}
238 
239 	printf("Pass: mbm_put_u1\n");
240 
241 out:
242 	smb_mbc_free(mbc);
243 }
244 
245 static void
246 mbm_put_u3()
247 {
248 	mbuf_chain_t *mbc;
249 	int rc;
250 
251 	mbc = smb_mbc_alloc(100);
252 
253 	rc = smb_mbc_encodef(mbc, "U", mbsa);
254 	if (rc != 0) {
255 		printf("Fail: mbm_put_u3 encode\n");
256 		goto out;
257 	}
258 	if (mbc->chain->m_len != 8) {
259 		printf("Fail: mbm_put_u3 len=%d\n",
260 		    mbc->chain->m_len);
261 		return;
262 	}
263 
264 	if (memcmp(mbc->chain->m_data, wcsa, 8)) {
265 		printf("Fail: mbm_put_u3 cmp:\n");
266 		hexdump((uchar_t *)mbc->chain->m_data, 8);
267 		return;
268 	}
269 
270 	printf("Pass: mbm_put_u3\n");
271 
272 out:
273 	smb_mbc_free(mbc);
274 }
275 
276 static void
277 mbm_put_u4()
278 {
279 	mbuf_chain_t *mbc;
280 	int rc;
281 
282 	mbc = smb_mbc_alloc(100);
283 
284 	rc = smb_mbc_encodef(mbc, "U", mbsp);
285 	if (rc != 0) {
286 		printf("Fail: mbm_put_u4 encode\n");
287 		goto out;
288 	}
289 	if (mbc->chain->m_len != 10) {
290 		printf("Fail: mbm_put_u4 len=%d\n",
291 		    mbc->chain->m_len);
292 		return;
293 	}
294 
295 	if (memcmp(mbc->chain->m_data, wcsp, 10)) {
296 		printf("Fail: mbm_put_u4 cmp:\n");
297 		hexdump((uchar_t *)mbc->chain->m_data, 10);
298 		return;
299 	}
300 
301 	printf("Pass: mbm_put_u4\n");
302 
303 out:
304 	smb_mbc_free(mbc);
305 }
306 
307 static void
308 mbm_put_upad()
309 {
310 	uint16_t wire[] = { 'o', 'n', 'e', 0, 0 };
311 	mbuf_chain_t *mbc;
312 	int rc;
313 
314 	mbc = smb_mbc_alloc(100);
315 
316 	/* Encode with wire length > strlen */
317 	rc = smb_mbc_encodef(mbc, "10U", "one");
318 	if (rc != 0) {
319 		printf("Fail: mbm_put_upad encode\n");
320 		goto out;
321 	}
322 	if (mbc->chain->m_len != 10) {
323 		printf("Fail: mbm_put_upad len=%d\n",
324 		    mbc->chain->m_len);
325 		return;
326 	}
327 
328 	if (memcmp(mbc->chain->m_data, wire, 10)) {
329 		printf("Fail: mbm_put_upad cmp:\n");
330 		hexdump((uchar_t *)mbc->chain->m_data, 10);
331 		return;
332 	}
333 
334 	printf("Pass: mbm_put_upad\n");
335 
336 out:
337 	smb_mbc_free(mbc);
338 }
339 
340 static void
341 mbm_put_utrunc()
342 {
343 	uint16_t wire[] = { 'o', 'n', 'e', 't' };
344 	mbuf_chain_t *mbc;
345 	int rc;
346 
347 	mbc = smb_mbc_alloc(100);
348 
349 	/* Encode with wire length < strlen */
350 	rc = smb_mbc_encodef(mbc, "8U", "onetwo");
351 	if (rc != 0) {
352 		printf("Fail: mbm_put_utrunc encode\n");
353 		goto out;
354 	}
355 	/* Trunc should put exactly 8 */
356 	if (mbc->chain->m_len != 8) {
357 		printf("Fail: mbm_put_utrunc len=%d\n",
358 		    mbc->chain->m_len);
359 		return;
360 	}
361 
362 	if (memcmp(mbc->chain->m_data, wire, 8)) {
363 		printf("Fail: mbm_put_utrunc cmp:\n");
364 		hexdump((uchar_t *)mbc->chain->m_data, 8);
365 		return;
366 	}
367 
368 	printf("Pass: mbm_put_utrunc\n");
369 
370 out:
371 	smb_mbc_free(mbc);
372 }
373 
374 /*
375  * Parse an ascii string.
376  */
377 static void
378 mbm_get_a0()
379 {
380 	uint8_t wire[] = { 'o', 'n', 'e', 0, 42, 0 };
381 	mbuf_chain_t mbc;
382 	char *s;
383 	int rc;
384 	uint16_t w;
385 
386 	bzero(&mbc, sizeof (mbc));
387 	MBC_ATTACH_BUF(&mbc, (uchar_t *)wire, sizeof (wire));
388 
389 	rc = smb_mbc_decodef(&mbc, "%sw", &test_sr, &s, &w);
390 	if (rc != 0) {
391 		printf("Fail: mbm_get_a0 decode\n");
392 		goto out;
393 	}
394 	/*
395 	 * Decode a word after the string to make sure we
396 	 * end up positioned correctly after the string.
397 	 */
398 	if (w != 42) {
399 		printf("Fail: mbm_get_a0 w=%d\n", w);
400 		return;
401 	}
402 	if (strcmp(s, "one") != 0) {
403 		printf("Fail: mbm_get_a0 cmp: <%s>\n", s);
404 		return;
405 	}
406 
407 	printf("Pass: mbm_get_a0\n");
408 
409 out:
410 	MBC_FLUSH(&mbc);
411 }
412 
413 /*
414  * Parse an ascii string, no NULL
415  */
416 static void
417 mbm_get_a1()
418 {
419 	uint8_t wire[] = { 'o', 'n', 'e', '.', 42, 0 };
420 	mbuf_chain_t mbc;
421 	char *s;
422 	int rc;
423 	uint16_t w;
424 
425 	bzero(&mbc, sizeof (mbc));
426 	MBC_ATTACH_BUF(&mbc, (uchar_t *)wire, sizeof (wire));
427 
428 	rc = smb_mbc_decodef(&mbc, "%3s.w", &test_sr, &s, &w);
429 	if (rc != 0) {
430 		printf("Fail: mbm_get_a1 decode\n");
431 		goto out;
432 	}
433 	/*
434 	 * Decode a word after the string to make sure we
435 	 * end up positioned correctly after the string.
436 	 */
437 	if (w != 42) {
438 		printf("Fail: mbm_get_a1 w=%d\n", w);
439 		return;
440 	}
441 	if (strcmp(s, "one") != 0) {
442 		printf("Fail: mbm_get_a1 cmp: <%s>\n", s);
443 		return;
444 	}
445 
446 	printf("Pass: mbm_get_a1\n");
447 
448 out:
449 	MBC_FLUSH(&mbc);
450 }
451 
452 /* parse exactly to end of data */
453 static void
454 mbm_get_a2()
455 {
456 	uint8_t wire[] = { 'o', 'n', 'e' };
457 	mbuf_chain_t mbc;
458 	char *s;
459 	int rc;
460 
461 	bzero(&mbc, sizeof (mbc));
462 	MBC_ATTACH_BUF(&mbc, (uchar_t *)wire, sizeof (wire));
463 
464 	rc = smb_mbc_decodef(&mbc, "%3s", &test_sr, &s);
465 	if (rc != 0) {
466 		printf("Fail: mbm_get_a2 decode\n");
467 		goto out;
468 	}
469 	if (mbc.chain_offset != 3) {
470 		printf("Fail: mbm_get_a2 wrong pos\n");
471 		return;
472 	}
473 	if (strcmp(s, "one") != 0) {
474 		printf("Fail: mbm_get_a2 cmp: <%s>\n", s);
475 		return;
476 	}
477 
478 	printf("Pass: mbm_get_a2\n");
479 
480 out:
481 	MBC_FLUSH(&mbc);
482 }
483 
484 /*
485  * Parse a unicode string.
486  */
487 static void
488 mbm_get_u0()
489 {
490 	uint16_t wire[] = { 'o', 'n', 'e', 0, 42, 0 };
491 	mbuf_chain_t mbc;
492 	char *s;
493 	int rc;
494 	uint16_t w;
495 
496 	bzero(&mbc, sizeof (mbc));
497 	MBC_ATTACH_BUF(&mbc, (uchar_t *)wire, sizeof (wire));
498 
499 	rc = smb_mbc_decodef(&mbc, "%Uw", &test_sr, &s, &w);
500 	if (rc != 0) {
501 		printf("Fail: mbm_get_u0 decode\n");
502 		goto out;
503 	}
504 	/*
505 	 * Decode a word after the string to make sure we
506 	 * end up positioned correctly after the string.
507 	 */
508 	if (w != 42) {
509 		printf("Fail: mbm_get_u0 w=%d\n", w);
510 		return;
511 	}
512 	if (strcmp(s, "one") != 0) {
513 		printf("Fail: mbm_get_u0 cmp: <%s>\n", s);
514 		return;
515 	}
516 
517 	printf("Pass: mbm_get_u0\n");
518 
519 out:
520 	MBC_FLUSH(&mbc);
521 }
522 
523 /*
524  * Parse a string that's NOT null terminated.
525  */
526 static void
527 mbm_get_u1()
528 {
529 	uint16_t wire[] = { 'o', 'n', 'e', '.', 42, 0 };
530 	mbuf_chain_t mbc;
531 	char *s;
532 	int rc;
533 	uint16_t w;
534 
535 	bzero(&mbc, sizeof (mbc));
536 	MBC_ATTACH_BUF(&mbc, (uchar_t *)wire, sizeof (wire));
537 
538 	rc = smb_mbc_decodef(&mbc, "%6U..w", &test_sr, &s, &w);
539 	if (rc != 0) {
540 		printf("Fail: mbm_get_u1 decode\n");
541 		goto out;
542 	}
543 	/*
544 	 * Decode a word after the string to make sure we
545 	 * end up positioned correctly after the string.
546 	 */
547 	if (w != 42) {
548 		printf("Fail: mbm_get_u1 w=%d\n", w);
549 		return;
550 	}
551 	if (strcmp(s, "one") != 0) {
552 		printf("Fail: mbm_get_u1 cmp: <%s>\n", s);
553 		return;
554 	}
555 
556 	printf("Pass: mbm_get_u1\n");
557 
558 out:
559 	MBC_FLUSH(&mbc);
560 }
561 
562 /* parse exactly to end of data */
563 static void
564 mbm_get_u2()
565 {
566 	uint16_t wire[] = { 't', 'w', 'o' };
567 	mbuf_chain_t mbc;
568 	char *s;
569 	int rc;
570 
571 	bzero(&mbc, sizeof (mbc));
572 	MBC_ATTACH_BUF(&mbc, (uchar_t *)wire, sizeof (wire));
573 
574 	rc = smb_mbc_decodef(&mbc, "%6U", &test_sr, &s);
575 	if (rc != 0) {
576 		printf("Fail: mbm_get_u2 decode\n");
577 		goto out;
578 	}
579 	if (mbc.chain_offset != 6) {
580 		printf("Fail: mbm_get_u2 wrong pos\n");
581 		return;
582 	}
583 	if (strcmp(s, "two") != 0) {
584 		printf("Fail: mbm_get_u2 cmp: <%s>\n", s);
585 		return;
586 	}
587 
588 	printf("Pass: mbm_get_a2\n");
589 
590 out:
591 	MBC_FLUSH(&mbc);
592 }
593 
594 static void
595 mbm_get_u3()
596 {
597 	mbuf_chain_t mbc;
598 	char *s;
599 	int rc;
600 
601 	bzero(&mbc, sizeof (mbc));
602 	MBC_ATTACH_BUF(&mbc, (uchar_t *)wcsa, sizeof (wcsa));
603 
604 	rc = smb_mbc_decodef(&mbc, "%#U", &test_sr, sizeof (wcsa), &s);
605 	if (rc != 0) {
606 		printf("Fail: mbm_get_u3 decode\n");
607 		goto out;
608 	}
609 	if (strcmp(s, mbsa) != 0) {
610 		printf("Fail: mbm_get_u3 cmp: <%s>\n", s);
611 		return;
612 	}
613 
614 	printf("Pass: mbm_get_u3\n");
615 
616 out:
617 	MBC_FLUSH(&mbc);
618 }
619 
620 static void
621 mbm_get_u4()
622 {
623 	mbuf_chain_t mbc;
624 	char *s;
625 	int rc;
626 
627 	bzero(&mbc, sizeof (mbc));
628 	MBC_ATTACH_BUF(&mbc, (uchar_t *)wcsp, sizeof (wcsp));
629 
630 	rc = smb_mbc_decodef(&mbc, "%#U", &test_sr, sizeof (wcsp), &s);
631 	if (rc != 0) {
632 		printf("Fail: mbm_get_u4 decode\n");
633 		goto out;
634 	}
635 	if (strcmp(s, mbsp) != 0) {
636 		printf("Fail: mbm_get_u4 cmp: <%s>\n", s);
637 		return;
638 	}
639 
640 	printf("Pass: mbm_get_u4\n");
641 
642 out:
643 	MBC_FLUSH(&mbc);
644 }
645 
646 void
647 test_mbmarshal()
648 {
649 
650 	smb_mbc_init();
651 
652 	test_ssn.dialect = 0x210;	// SMB 2.1
653 	test_sr.session = &test_ssn;
654 	test_sr.sr_magic = SMB_REQ_MAGIC;
655 	smb_srm_init(&test_sr);
656 
657 	mbm_put_a0();
658 	mbm_put_a1();
659 	mbm_put_apad();
660 	mbm_put_atrunc();
661 
662 	mbm_put_u0();
663 	mbm_put_u1();
664 	mbm_put_u3();
665 	mbm_put_u4();
666 	mbm_put_upad();
667 	mbm_put_utrunc();
668 
669 	mbm_get_a0();
670 	mbm_get_a1();
671 	mbm_get_a2();
672 	mbm_get_u0();
673 	mbm_get_u1();
674 	mbm_get_u2();
675 	mbm_get_u3();
676 	mbm_get_u4();
677 
678 	smb_srm_fini(&test_sr);
679 	smb_mbc_fini();
680 }
681