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 } 639