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 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_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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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