1 /* 2 * Copyright (C) 2003-2015 FreeIPMI Core Team 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 * 17 */ 18 19 #ifdef HAVE_CONFIG_H 20 #include <config.h> 21 #endif /* HAVE_CONFIG_H */ 22 23 #include <stdio.h> 24 #include <stdlib.h> 25 #ifdef STDC_HEADERS 26 #include <string.h> 27 #endif /* STDC_HEADERS */ 28 #include <assert.h> 29 #include <errno.h> 30 31 #include "freeipmi/debug/ipmi-debug.h" 32 #include "freeipmi/cmds/ipmi-messaging-support-cmds.h" 33 #include "freeipmi/cmds/ipmi-sol-cmds.h" 34 #include "freeipmi/fiid/fiid.h" 35 #include "freeipmi/interface/ipmi-ipmb-interface.h" 36 #include "freeipmi/interface/ipmi-lan-interface.h" 37 #include "freeipmi/interface/ipmi-rmcpplus-interface.h" 38 #include "freeipmi/interface/rmcp-interface.h" 39 #include "freeipmi/payload/ipmi-sol-payload.h" 40 #include "freeipmi/util/ipmi-rmcpplus-util.h" 41 42 #include "ipmi-debug-common.h" 43 44 #include "libcommon/ipmi-crypt.h" 45 #include "libcommon/ipmi-fiid-util.h" 46 #include "libcommon/ipmi-fill-util.h" 47 #include "libcommon/ipmi-trace.h" 48 49 #include "freeipmi-portability.h" 50 51 /* return data parsed on success, 0 if can't parse anymore, -1 on error */ 52 static int 53 _dump_rmcpplus_session_hdr (int fd, 54 const char *prefix, 55 const char *session_hdr, 56 const void *pkt, 57 unsigned int pkt_len, 58 uint8_t *payload_type, 59 uint8_t *payload_authenticated, 60 uint8_t *payload_encrypted, 61 uint32_t *session_id, 62 uint16_t *ipmi_payload_len) 63 { 64 fiid_obj_t obj_rmcpplus_session_hdr = NULL; 65 unsigned int indx = 0; 66 int obj_len, rv = -1; 67 uint64_t val; 68 69 assert (pkt 70 && pkt_len 71 && payload_type 72 && payload_authenticated 73 && payload_encrypted 74 && session_id 75 && ipmi_payload_len); 76 77 /* 78 * Extract auth_type and payload information 79 */ 80 if (!(obj_rmcpplus_session_hdr = fiid_obj_create (tmpl_rmcpplus_session_hdr))) 81 { 82 ERRNO_TRACE (errno); 83 goto cleanup; 84 } 85 86 if ((obj_len = fiid_obj_set_block (obj_rmcpplus_session_hdr, 87 "authentication_type", 88 "payload_type.encrypted", 89 pkt + indx, 90 pkt_len - indx)) < 0) 91 { 92 FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcpplus_session_hdr); 93 goto cleanup; 94 } 95 indx += obj_len; 96 97 if (pkt_len <= indx) 98 goto output; 99 100 if (FIID_OBJ_GET (obj_rmcpplus_session_hdr, 101 "payload_type", 102 &val) < 0) 103 { 104 FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcpplus_session_hdr); 105 goto cleanup; 106 } 107 (*payload_type) = val; 108 109 /* 110 * Extract OEM IANA and OEM Payload ID 111 */ 112 if (*payload_type == IPMI_PAYLOAD_TYPE_OEM_EXPLICIT) 113 { 114 if ((obj_len = fiid_obj_set_block (obj_rmcpplus_session_hdr, 115 "oem_iana", 116 "oem_payload_id", 117 pkt + indx, 118 pkt_len - indx)) < 0) 119 { 120 FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcpplus_session_hdr); 121 goto cleanup; 122 } 123 indx += obj_len; 124 125 if (pkt_len <= indx) 126 goto output; 127 } 128 129 /* 130 * Extract Session ID, Session Sequence Number, and Payload Length 131 */ 132 if ((obj_len = fiid_obj_set_block (obj_rmcpplus_session_hdr, 133 "session_id", 134 "ipmi_payload_len", 135 pkt + indx, 136 pkt_len - indx)) < 0) 137 { 138 FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcpplus_session_hdr); 139 goto cleanup; 140 } 141 indx += obj_len; 142 143 if (pkt_len <= indx) 144 goto output; 145 146 if (FIID_OBJ_GET (obj_rmcpplus_session_hdr, 147 "payload_type.authenticated", 148 &val) < 0) 149 { 150 FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcpplus_session_hdr); 151 goto cleanup; 152 } 153 (*payload_authenticated) = val; 154 155 if (FIID_OBJ_GET (obj_rmcpplus_session_hdr, 156 "payload_type.encrypted", 157 &val) < 0) 158 { 159 FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcpplus_session_hdr); 160 goto cleanup; 161 } 162 (*payload_encrypted) = val; 163 164 if (FIID_OBJ_GET (obj_rmcpplus_session_hdr, 165 "session_id", 166 &val) < 0) 167 { 168 FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcpplus_session_hdr); 169 goto cleanup; 170 } 171 (*session_id) = val; 172 173 if (FIID_OBJ_GET (obj_rmcpplus_session_hdr, 174 "ipmi_payload_len", 175 &val) < 0) 176 { 177 FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcpplus_session_hdr); 178 goto cleanup; 179 } 180 (*ipmi_payload_len) = val; 181 182 output: 183 if (ipmi_obj_dump (fd, 184 prefix, 185 session_hdr, 186 NULL, 187 obj_rmcpplus_session_hdr) < 0) 188 { 189 ERRNO_TRACE (errno); 190 goto cleanup; 191 } 192 193 rv = indx; 194 cleanup: 195 fiid_obj_destroy (obj_rmcpplus_session_hdr); 196 return (rv); 197 } 198 199 /* return 1 on parse success, 0 if can't parse anymore, -1 on error */ 200 static int 201 _dump_rmcpplus_payload_data (int fd, 202 const char *prefix, 203 const char *msg_hdr, 204 const char *cmd_hdr, 205 const char *ipmb_msg_hdr, 206 const char *ipmb_cmd_hdr, 207 const char *ipmb_msg_trlr_hdr, 208 const char *trailer_hdr, 209 uint8_t payload_type, 210 fiid_template_t tmpl_lan_msg_hdr, 211 fiid_template_t tmpl_cmd, 212 fiid_template_t tmpl_ipmb_msg_hdr, 213 fiid_template_t tmpl_ipmb_cmd, 214 const void *pkt, 215 uint16_t ipmi_payload_len) 216 { 217 char *payload_unexpected_hdr = 218 "Payload Unexpected Data:\n" 219 "------------------------"; 220 fiid_obj_t obj_lan_msg_hdr = NULL; 221 fiid_obj_t obj_cmd = NULL; 222 fiid_obj_t obj_lan_msg_trlr = NULL; 223 fiid_obj_t obj_payload_unexpected_data = NULL; 224 int obj_lan_msg_trlr_len, len, rv = -1; 225 unsigned int obj_cmd_len; 226 unsigned int indx = 0; 227 228 assert ((payload_type == IPMI_PAYLOAD_TYPE_IPMI 229 || payload_type == IPMI_PAYLOAD_TYPE_SOL) 230 && !(payload_type == IPMI_PAYLOAD_TYPE_IPMI 231 && !(tmpl_lan_msg_hdr 232 && (fiid_template_compare (tmpl_lan_msg_hdr, 233 tmpl_lan_msg_hdr_rq) == 1 234 || fiid_template_compare (tmpl_lan_msg_hdr, 235 tmpl_lan_msg_hdr_rs) == 1))) 236 && tmpl_cmd 237 && !(payload_type == IPMI_PAYLOAD_TYPE_SOL 238 && !(fiid_template_compare (tmpl_cmd, 239 tmpl_sol_payload_data) == 1 240 || fiid_template_compare (tmpl_cmd, 241 tmpl_sol_payload_data_remote_console_to_bmc) == 1 242 || fiid_template_compare (tmpl_cmd, 243 tmpl_sol_payload_data_bmc_to_remote_console) == 1)) 244 && pkt 245 && ipmi_payload_len); 246 247 /* Dump message header */ 248 249 if (payload_type == IPMI_PAYLOAD_TYPE_IPMI) 250 { 251 uint8_t ipmb_buf[IPMI_DEBUG_MAX_PKT_LEN]; 252 int ipmb_buf_len = 0; 253 254 if (!(obj_lan_msg_hdr = fiid_obj_create (tmpl_lan_msg_hdr))) 255 { 256 ERRNO_TRACE (errno); 257 goto cleanup; 258 } 259 260 if ((len = fiid_obj_set_all (obj_lan_msg_hdr, 261 pkt + indx, 262 ipmi_payload_len - indx)) < 0) 263 { 264 FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_msg_hdr); 265 goto cleanup; 266 } 267 indx += len; 268 269 if (ipmi_obj_dump (fd, 270 prefix, 271 msg_hdr, 272 NULL, 273 obj_lan_msg_hdr) < 0) 274 { 275 ERRNO_TRACE (errno); 276 goto cleanup; 277 } 278 279 if (ipmi_payload_len <= indx) 280 { 281 rv = 0; 282 goto cleanup; 283 } 284 285 if ((obj_lan_msg_trlr_len = fiid_template_len_bytes (tmpl_lan_msg_trlr)) < 0) 286 { 287 ERRNO_TRACE (errno); 288 goto cleanup; 289 } 290 291 if ((ipmi_payload_len - indx) <= obj_lan_msg_trlr_len) 292 goto dump_payload_extra; 293 294 obj_cmd_len = (ipmi_payload_len - indx) - obj_lan_msg_trlr_len; 295 296 if (!(obj_cmd = fiid_obj_create (tmpl_cmd))) 297 { 298 ERRNO_TRACE (errno); 299 goto cleanup; 300 } 301 302 if ((len = fiid_obj_set_all (obj_cmd, 303 pkt + indx, 304 obj_cmd_len)) < 0) 305 { 306 FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd); 307 goto cleanup; 308 } 309 indx += len; 310 311 if (tmpl_ipmb_msg_hdr && tmpl_ipmb_cmd) 312 { 313 if ((ipmb_buf_len = fiid_obj_get_data (obj_cmd, 314 "message_data", 315 ipmb_buf, 316 IPMI_DEBUG_MAX_PKT_LEN)) < 0) 317 { 318 FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd); 319 goto cleanup; 320 } 321 322 if (fiid_obj_clear_field (obj_cmd, "message_data") < 0) 323 { 324 FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd); 325 goto cleanup; 326 } 327 } 328 329 if (ipmi_obj_dump (fd, 330 prefix, 331 cmd_hdr, 332 NULL, 333 obj_cmd) < 0) 334 { 335 ERRNO_TRACE (errno); 336 goto cleanup; 337 } 338 339 if (tmpl_ipmb_msg_hdr && tmpl_ipmb_cmd && ipmb_buf_len) 340 { 341 if (debug_dump_ipmb (fd, 342 prefix, 343 ipmb_buf, 344 ipmb_buf_len, 345 tmpl_ipmb_msg_hdr, 346 tmpl_ipmb_cmd) < 0) 347 goto cleanup; 348 } 349 350 if (ipmi_payload_len <= indx) 351 { 352 rv = 0; 353 goto cleanup; 354 } 355 356 /* Dump trailer */ 357 358 if (!(obj_lan_msg_trlr = fiid_obj_create (tmpl_lan_msg_trlr))) 359 { 360 ERRNO_TRACE (errno); 361 goto cleanup; 362 } 363 364 if ((len = fiid_obj_set_all (obj_lan_msg_trlr, 365 pkt + indx, 366 ipmi_payload_len - indx)) < 0) 367 { 368 FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_msg_trlr); 369 goto cleanup; 370 } 371 indx += len; 372 373 if (ipmi_obj_dump (fd, 374 prefix, 375 trailer_hdr, 376 NULL, 377 obj_lan_msg_trlr) < 0) 378 { 379 ERRNO_TRACE (errno); 380 goto cleanup; 381 } 382 } 383 else /* payload_type == IPMI_PAYLOAD_TYPE_SOL */ 384 { 385 obj_cmd_len = ipmi_payload_len; 386 387 if (!(obj_cmd = fiid_obj_create (tmpl_cmd))) 388 { 389 ERRNO_TRACE (errno); 390 goto cleanup; 391 } 392 393 if ((len = fiid_obj_set_all (obj_cmd, 394 pkt + indx, 395 obj_cmd_len)) < 0) 396 { 397 FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd); 398 goto cleanup; 399 } 400 indx += len; 401 402 if (ipmi_obj_dump (fd, 403 prefix, 404 cmd_hdr, 405 NULL, 406 obj_cmd) < 0) 407 { 408 ERRNO_TRACE (errno); 409 goto cleanup; 410 } 411 } 412 413 /* Dump payload unexpected stuff */ 414 415 dump_payload_extra: 416 417 if ((ipmi_payload_len - indx) > 0) 418 { 419 if (!(obj_payload_unexpected_data = fiid_obj_create (tmpl_unexpected_data))) 420 { 421 ERRNO_TRACE (errno); 422 goto cleanup; 423 } 424 425 if ((len = fiid_obj_set_all (obj_payload_unexpected_data, 426 pkt + indx, 427 ipmi_payload_len - indx)) < 0) 428 { 429 FIID_OBJECT_ERROR_TO_ERRNO (obj_payload_unexpected_data); 430 goto cleanup; 431 } 432 indx += len; 433 434 if (ipmi_obj_dump (fd, 435 prefix, 436 payload_unexpected_hdr, 437 NULL, 438 obj_payload_unexpected_data) < 0) 439 { 440 ERRNO_TRACE (errno); 441 goto cleanup; 442 } 443 } 444 445 rv = 1; 446 cleanup: 447 fiid_obj_destroy (obj_lan_msg_hdr); 448 fiid_obj_destroy (obj_cmd); 449 fiid_obj_destroy (obj_lan_msg_trlr); 450 fiid_obj_destroy (obj_payload_unexpected_data); 451 return (rv); 452 } 453 454 /* return 1 on parse success, 0 if can't parse anymore, -1 on error */ 455 static int 456 _dump_rmcpplus_payload_confidentiality_none (int fd, 457 const char *prefix, 458 const char *payload_hdr, 459 const char *msg_hdr, 460 const char *cmd_hdr, 461 const char *ipmb_msg_hdr, 462 const char *ipmb_cmd_hdr, 463 const char *ipmb_msg_trlr_hdr, 464 const char *trailer_hdr, 465 uint8_t payload_type, 466 fiid_template_t tmpl_lan_msg_hdr, 467 fiid_template_t tmpl_cmd, 468 fiid_template_t tmpl_ipmb_msg_hdr, 469 fiid_template_t tmpl_ipmb_cmd, 470 const void *pkt, 471 uint16_t ipmi_payload_len) 472 { 473 fiid_obj_t obj_rmcpplus_payload = NULL; 474 int ret, rv = -1; 475 476 assert ((payload_type == IPMI_PAYLOAD_TYPE_IPMI 477 || payload_type == IPMI_PAYLOAD_TYPE_SOL) 478 && !(payload_type == IPMI_PAYLOAD_TYPE_IPMI 479 && !(tmpl_lan_msg_hdr 480 && (fiid_template_compare (tmpl_lan_msg_hdr, 481 tmpl_lan_msg_hdr_rq) == 1 482 || fiid_template_compare (tmpl_lan_msg_hdr, 483 tmpl_lan_msg_hdr_rs) == 1))) 484 && tmpl_cmd 485 && !(payload_type == IPMI_PAYLOAD_TYPE_SOL 486 && !(fiid_template_compare (tmpl_cmd, 487 tmpl_sol_payload_data) == 1 488 || fiid_template_compare (tmpl_cmd, 489 tmpl_sol_payload_data_remote_console_to_bmc) == 1 490 || fiid_template_compare (tmpl_cmd, 491 tmpl_sol_payload_data_bmc_to_remote_console) == 1)) 492 493 && pkt 494 && ipmi_payload_len); 495 496 if (!(obj_rmcpplus_payload = fiid_obj_create (tmpl_rmcpplus_payload))) 497 { 498 ERRNO_TRACE (errno); 499 goto cleanup; 500 } 501 502 if (fiid_obj_set_data (obj_rmcpplus_payload, 503 "payload_data", 504 pkt, 505 ipmi_payload_len) < 0) 506 { 507 FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcpplus_payload); 508 goto cleanup; 509 } 510 511 if (ipmi_obj_dump (fd, 512 prefix, 513 payload_hdr, 514 NULL, 515 obj_rmcpplus_payload) < 0) 516 { 517 ERRNO_TRACE (errno); 518 goto cleanup; 519 } 520 521 if ((ret = _dump_rmcpplus_payload_data (fd, 522 prefix, 523 msg_hdr, 524 cmd_hdr, 525 ipmb_msg_hdr, 526 ipmb_cmd_hdr, 527 ipmb_msg_trlr_hdr, 528 trailer_hdr, 529 payload_type, 530 tmpl_lan_msg_hdr, 531 tmpl_cmd, 532 tmpl_ipmb_msg_hdr, 533 tmpl_ipmb_cmd, 534 pkt, 535 ipmi_payload_len)) < 0) 536 { 537 ERRNO_TRACE (errno); 538 goto cleanup; 539 } 540 541 rv = ret; 542 cleanup: 543 fiid_obj_destroy (obj_rmcpplus_payload); 544 return (rv); 545 } 546 547 /* return 1 on parse success, 0 if can't parse anymore, -1 on error */ 548 static int 549 _dump_rmcpplus_payload_confidentiality_aes_cbc_128 (int fd, 550 const char *prefix, 551 const char *payload_hdr, 552 const char *msg_hdr, 553 const char *cmd_hdr, 554 const char *ipmb_msg_hdr, 555 const char *ipmb_cmd_hdr, 556 const char *ipmb_msg_trlr_hdr, 557 const char *trailer_hdr, 558 uint8_t payload_type, 559 fiid_template_t tmpl_lan_msg_hdr, 560 fiid_template_t tmpl_cmd, 561 fiid_template_t tmpl_ipmb_msg_hdr, 562 fiid_template_t tmpl_ipmb_cmd, 563 const void *confidentiality_key, 564 unsigned int confidentiality_key_len, 565 const void *pkt, 566 uint16_t ipmi_payload_len) 567 { 568 uint8_t iv[IPMI_CRYPT_AES_CBC_128_IV_LENGTH]; 569 uint8_t payload_buf[IPMI_MAX_PAYLOAD_LENGTH]; 570 uint8_t pad_len; 571 int cipher_keylen, cipher_blocklen, decrypt_len, ret, rv = -1; 572 unsigned int payload_data_len, cmd_data_len; 573 fiid_obj_t obj_rmcpplus_payload = NULL; 574 unsigned int indx = 0; 575 576 /* Note: Confidentiality Key for AES_CBS_128 is K2 */ 577 578 assert ((payload_type == IPMI_PAYLOAD_TYPE_IPMI 579 || payload_type == IPMI_PAYLOAD_TYPE_SOL) 580 && !(payload_type == IPMI_PAYLOAD_TYPE_IPMI 581 && !(tmpl_lan_msg_hdr 582 && (fiid_template_compare (tmpl_lan_msg_hdr, 583 tmpl_lan_msg_hdr_rq) == 1 584 || fiid_template_compare (tmpl_lan_msg_hdr, 585 tmpl_lan_msg_hdr_rs) == 1))) 586 && tmpl_cmd 587 && !(payload_type == IPMI_PAYLOAD_TYPE_SOL 588 && !(fiid_template_compare (tmpl_cmd, 589 tmpl_sol_payload_data) == 1 590 || fiid_template_compare (tmpl_cmd, 591 tmpl_sol_payload_data_remote_console_to_bmc) == 1 592 || fiid_template_compare (tmpl_cmd, 593 tmpl_sol_payload_data_bmc_to_remote_console) == 1)) 594 && confidentiality_key 595 && confidentiality_key_len 596 && pkt 597 && ipmi_payload_len); 598 599 if ((cipher_keylen = crypt_cipher_key_len (IPMI_CRYPT_CIPHER_AES)) < 0) 600 { 601 ERRNO_TRACE (errno); 602 goto cleanup; 603 } 604 assert (!(cipher_keylen < IPMI_CRYPT_AES_CBC_128_KEY_LENGTH)); 605 606 if (confidentiality_key_len < IPMI_CRYPT_AES_CBC_128_KEY_LENGTH) 607 { 608 SET_ERRNO (EINVAL); 609 goto cleanup; 610 } 611 confidentiality_key_len = IPMI_CRYPT_AES_CBC_128_KEY_LENGTH; 612 613 if ((cipher_blocklen = crypt_cipher_block_len (IPMI_CRYPT_CIPHER_AES)) < 0) 614 { 615 ERRNO_TRACE (errno); 616 goto cleanup; 617 } 618 assert (cipher_blocklen == IPMI_CRYPT_AES_CBC_128_BLOCK_LENGTH); 619 620 if (ipmi_payload_len < IPMI_CRYPT_AES_CBC_128_BLOCK_LENGTH) 621 { 622 rv = 0; 623 goto cleanup; 624 } 625 626 payload_data_len = ipmi_payload_len - IPMI_CRYPT_AES_CBC_128_BLOCK_LENGTH; 627 628 if (!payload_data_len) 629 { 630 rv = 0; 631 goto cleanup; 632 } 633 634 memcpy (iv, pkt, IPMI_CRYPT_AES_CBC_128_BLOCK_LENGTH); 635 indx += IPMI_CRYPT_AES_CBC_128_BLOCK_LENGTH; 636 memcpy (payload_buf, pkt + indx, payload_data_len); 637 638 if (!(obj_rmcpplus_payload = fiid_obj_create (tmpl_rmcpplus_payload))) 639 { 640 ERRNO_TRACE (errno); 641 goto cleanup; 642 } 643 644 if (fiid_obj_set_data (obj_rmcpplus_payload, 645 "confidentiality_header", 646 iv, 647 IPMI_CRYPT_AES_CBC_128_BLOCK_LENGTH) < 0) 648 { 649 FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcpplus_payload); 650 goto cleanup; 651 } 652 653 if ((decrypt_len = crypt_cipher_decrypt (IPMI_CRYPT_CIPHER_AES, 654 IPMI_CRYPT_CIPHER_MODE_CBC, 655 confidentiality_key, 656 confidentiality_key_len, 657 iv, 658 IPMI_CRYPT_AES_CBC_128_BLOCK_LENGTH, 659 payload_buf, 660 payload_data_len)) < 0) 661 { 662 ERRNO_TRACE (errno); 663 goto cleanup; 664 } 665 666 if (decrypt_len != payload_data_len) 667 { 668 SET_ERRNO (EINVAL); 669 goto cleanup; 670 } 671 672 pad_len = payload_buf[payload_data_len - 1]; 673 if (pad_len > IPMI_CRYPT_AES_CBC_128_BLOCK_LENGTH) 674 { 675 rv = 0; 676 goto cleanup; 677 } 678 679 if ((pad_len + 1) > payload_data_len) 680 { 681 rv = 0; 682 goto cleanup; 683 } 684 685 cmd_data_len = payload_data_len - pad_len - 1; 686 687 if (cmd_data_len <= 0) 688 { 689 rv = 0; 690 goto cleanup; 691 } 692 693 if (fiid_obj_set_data (obj_rmcpplus_payload, 694 "payload_data", 695 payload_buf, 696 cmd_data_len) < 0) 697 { 698 FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcpplus_payload); 699 goto cleanup; 700 } 701 702 if (fiid_obj_set_data (obj_rmcpplus_payload, 703 "confidentiality_trailer", 704 payload_buf + cmd_data_len, 705 pad_len + 1) < 0) 706 { 707 FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcpplus_payload); 708 goto cleanup; 709 } 710 711 if (ipmi_obj_dump (fd, 712 prefix, 713 payload_hdr, 714 NULL, 715 obj_rmcpplus_payload) < 0) 716 { 717 ERRNO_TRACE (errno); 718 goto cleanup; 719 } 720 721 if ((ret = _dump_rmcpplus_payload_data (fd, 722 prefix, 723 msg_hdr, 724 cmd_hdr, 725 ipmb_msg_hdr, 726 ipmb_cmd_hdr, 727 ipmb_msg_trlr_hdr, 728 trailer_hdr, 729 payload_type, 730 tmpl_lan_msg_hdr, 731 tmpl_cmd, 732 tmpl_ipmb_msg_hdr, 733 tmpl_ipmb_cmd, 734 payload_buf, 735 cmd_data_len)) < 0) 736 { 737 ERRNO_TRACE (errno); 738 goto cleanup; 739 } 740 741 rv = ret; 742 cleanup: 743 fiid_obj_destroy (obj_rmcpplus_payload); 744 return (rv); 745 } 746 747 /* return 1 on parse success, 0 if can't parse anymore, -1 on error */ 748 static int 749 _dump_rmcpplus_payload_rakp (int fd, 750 const char *prefix, 751 const char *payload_hdr, 752 const char *cmd_hdr, 753 uint8_t payload_type, 754 fiid_template_t tmpl_cmd, 755 const void *pkt, 756 uint16_t ipmi_payload_len) 757 { 758 fiid_obj_t obj_rmcpplus_payload = NULL; 759 fiid_obj_t obj_cmd = NULL; 760 int rv = -1; 761 762 assert ((payload_type == IPMI_PAYLOAD_TYPE_RMCPPLUS_OPEN_SESSION_REQUEST 763 || payload_type == IPMI_PAYLOAD_TYPE_RMCPPLUS_OPEN_SESSION_RESPONSE 764 || payload_type == IPMI_PAYLOAD_TYPE_RAKP_MESSAGE_1 765 || payload_type == IPMI_PAYLOAD_TYPE_RAKP_MESSAGE_2 766 || payload_type == IPMI_PAYLOAD_TYPE_RAKP_MESSAGE_3 767 || payload_type == IPMI_PAYLOAD_TYPE_RAKP_MESSAGE_4) 768 && tmpl_cmd 769 && !(payload_type == IPMI_PAYLOAD_TYPE_RMCPPLUS_OPEN_SESSION_REQUEST 770 && (fiid_template_compare (tmpl_cmd, 771 tmpl_rmcpplus_open_session_request) != 1)) 772 && !(payload_type == IPMI_PAYLOAD_TYPE_RMCPPLUS_OPEN_SESSION_RESPONSE 773 && (fiid_template_compare (tmpl_cmd, 774 tmpl_rmcpplus_open_session_response) != 1)) 775 && !(payload_type == IPMI_PAYLOAD_TYPE_RAKP_MESSAGE_1 776 && (fiid_template_compare (tmpl_cmd, 777 tmpl_rmcpplus_rakp_message_1) != 1)) 778 && !(payload_type == IPMI_PAYLOAD_TYPE_RAKP_MESSAGE_2 779 && (fiid_template_compare (tmpl_cmd, 780 tmpl_rmcpplus_rakp_message_2) != 1)) 781 && !(payload_type == IPMI_PAYLOAD_TYPE_RAKP_MESSAGE_3 782 && (fiid_template_compare (tmpl_cmd, 783 tmpl_rmcpplus_rakp_message_3) != 1)) 784 && !(payload_type == IPMI_PAYLOAD_TYPE_RAKP_MESSAGE_4 785 && (fiid_template_compare (tmpl_cmd, 786 tmpl_rmcpplus_rakp_message_4) != 1)) 787 && pkt 788 && ipmi_payload_len); 789 790 if (!(obj_rmcpplus_payload = fiid_obj_create (tmpl_rmcpplus_payload))) 791 { 792 ERRNO_TRACE (errno); 793 goto cleanup; 794 } 795 796 if (fiid_obj_set_data (obj_rmcpplus_payload, 797 "payload_data", 798 pkt, 799 ipmi_payload_len) < 0) 800 { 801 FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcpplus_payload); 802 goto cleanup; 803 } 804 805 if (ipmi_obj_dump (fd, 806 prefix, 807 payload_hdr, 808 NULL, 809 obj_rmcpplus_payload) < 0) 810 { 811 ERRNO_TRACE (errno); 812 goto cleanup; 813 } 814 815 if (payload_type == IPMI_PAYLOAD_TYPE_RMCPPLUS_OPEN_SESSION_REQUEST) 816 { 817 if (!(obj_cmd = fiid_obj_create (tmpl_rmcpplus_open_session_request))) 818 { 819 ERRNO_TRACE (errno); 820 goto cleanup; 821 } 822 } 823 else if (payload_type == IPMI_PAYLOAD_TYPE_RMCPPLUS_OPEN_SESSION_RESPONSE) 824 { 825 if (!(obj_cmd = fiid_obj_create (tmpl_rmcpplus_open_session_response))) 826 { 827 ERRNO_TRACE (errno); 828 goto cleanup; 829 } 830 } 831 else if (payload_type == IPMI_PAYLOAD_TYPE_RAKP_MESSAGE_1) 832 { 833 if (!(obj_cmd = fiid_obj_create (tmpl_rmcpplus_rakp_message_1))) 834 { 835 ERRNO_TRACE (errno); 836 goto cleanup; 837 } 838 } 839 else if (payload_type == IPMI_PAYLOAD_TYPE_RAKP_MESSAGE_2) 840 { 841 if (!(obj_cmd = fiid_obj_create (tmpl_rmcpplus_rakp_message_2))) 842 { 843 ERRNO_TRACE (errno); 844 goto cleanup; 845 } 846 } 847 else if (payload_type == IPMI_PAYLOAD_TYPE_RAKP_MESSAGE_3) 848 { 849 if (!(obj_cmd = fiid_obj_create (tmpl_rmcpplus_rakp_message_3))) 850 { 851 ERRNO_TRACE (errno); 852 goto cleanup; 853 } 854 } 855 else /* IPMI_PAYLOAD_TYPE_RAKP_MESSAGE_4 */ 856 { 857 if (!(obj_cmd = fiid_obj_create (tmpl_rmcpplus_rakp_message_4))) 858 { 859 ERRNO_TRACE (errno); 860 goto cleanup; 861 } 862 } 863 864 if (fiid_obj_set_all (obj_cmd, 865 pkt, 866 ipmi_payload_len) < 0) 867 { 868 FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd); 869 goto cleanup; 870 } 871 872 if (ipmi_obj_dump (fd, 873 prefix, 874 cmd_hdr, 875 NULL, 876 obj_cmd) < 0) 877 { 878 ERRNO_TRACE (errno); 879 goto cleanup; 880 } 881 882 rv = 1; 883 cleanup: 884 fiid_obj_destroy (obj_rmcpplus_payload); 885 fiid_obj_destroy (obj_cmd); 886 return (rv); 887 } 888 889 /* return 1 on parse success, 0 if can't parse anymore, -1 on error */ 890 static int 891 _dump_rmcpplus_payload (int fd, 892 const char *prefix, 893 const char *payload_hdr, 894 const char *msg_hdr, 895 const char *cmd_hdr, 896 const char *ipmb_msg_hdr, 897 const char *ipmb_cmd_hdr, 898 const char *ipmb_msg_trlr_hdr, 899 const char *trailer_hdr, 900 uint8_t payload_type, 901 uint8_t authentication_algorithm, 902 uint8_t confidentiality_algorithm, 903 fiid_template_t tmpl_lan_msg_hdr, 904 fiid_template_t tmpl_cmd, 905 fiid_template_t tmpl_ipmb_msg_hdr, 906 fiid_template_t tmpl_ipmb_cmd, 907 const void *confidentiality_key, 908 unsigned int confidentiality_key_len, 909 const void *pkt, 910 uint16_t ipmi_payload_len) 911 { 912 assert ((payload_type == IPMI_PAYLOAD_TYPE_IPMI 913 || payload_type == IPMI_PAYLOAD_TYPE_SOL 914 || payload_type == IPMI_PAYLOAD_TYPE_RMCPPLUS_OPEN_SESSION_REQUEST 915 || payload_type == IPMI_PAYLOAD_TYPE_RMCPPLUS_OPEN_SESSION_RESPONSE 916 || payload_type == IPMI_PAYLOAD_TYPE_RAKP_MESSAGE_1 917 || payload_type == IPMI_PAYLOAD_TYPE_RAKP_MESSAGE_2 918 || payload_type == IPMI_PAYLOAD_TYPE_RAKP_MESSAGE_3 919 || payload_type == IPMI_PAYLOAD_TYPE_RAKP_MESSAGE_4) 920 && IPMI_AUTHENTICATION_ALGORITHM_SUPPORTED (authentication_algorithm) 921 && IPMI_CONFIDENTIALITY_ALGORITHM_SUPPORTED (confidentiality_algorithm) 922 && !(confidentiality_algorithm == IPMI_CONFIDENTIALITY_ALGORITHM_AES_CBC_128 923 && !(confidentiality_key 924 && confidentiality_key_len)) 925 && ipmi_payload_len 926 && !(payload_type == IPMI_PAYLOAD_TYPE_IPMI 927 && !(tmpl_lan_msg_hdr 928 && (fiid_template_compare (tmpl_lan_msg_hdr, 929 tmpl_lan_msg_hdr_rq) == 1 930 || fiid_template_compare (tmpl_lan_msg_hdr, 931 tmpl_lan_msg_hdr_rs) == 1))) 932 && tmpl_cmd 933 && !(payload_type == IPMI_PAYLOAD_TYPE_SOL 934 && !(fiid_template_compare (tmpl_cmd, 935 tmpl_sol_payload_data) == 1 936 || fiid_template_compare (tmpl_cmd, 937 tmpl_sol_payload_data_remote_console_to_bmc) == 1 938 || fiid_template_compare (tmpl_cmd, 939 tmpl_sol_payload_data_bmc_to_remote_console) == 1)) 940 && pkt 941 && ipmi_payload_len); 942 943 if (payload_type == IPMI_PAYLOAD_TYPE_IPMI 944 || payload_type == IPMI_PAYLOAD_TYPE_SOL) 945 { 946 if (confidentiality_algorithm == IPMI_CONFIDENTIALITY_ALGORITHM_NONE) 947 return (_dump_rmcpplus_payload_confidentiality_none (fd, 948 prefix, 949 payload_hdr, 950 msg_hdr, 951 cmd_hdr, 952 ipmb_msg_hdr, 953 ipmb_cmd_hdr, 954 ipmb_msg_trlr_hdr, 955 trailer_hdr, 956 payload_type, 957 tmpl_lan_msg_hdr, 958 tmpl_cmd, 959 tmpl_ipmb_msg_hdr, 960 tmpl_ipmb_cmd, 961 pkt, 962 ipmi_payload_len)); 963 else /* IPMI_CONFIDENTIALITY_ALGORITHM_AES_CBC_128 */ 964 return (_dump_rmcpplus_payload_confidentiality_aes_cbc_128 (fd, 965 prefix, 966 payload_hdr, 967 msg_hdr, 968 cmd_hdr, 969 ipmb_msg_hdr, 970 ipmb_cmd_hdr, 971 ipmb_msg_trlr_hdr, 972 trailer_hdr, 973 payload_type, 974 tmpl_lan_msg_hdr, 975 tmpl_cmd, 976 tmpl_ipmb_msg_hdr, 977 tmpl_ipmb_cmd, 978 confidentiality_key, 979 confidentiality_key_len, 980 pkt, 981 ipmi_payload_len)); 982 } 983 else 984 return (_dump_rmcpplus_payload_rakp (fd, 985 prefix, 986 payload_hdr, 987 cmd_hdr, 988 payload_type, 989 tmpl_cmd, 990 pkt, 991 ipmi_payload_len)); 992 } 993 994 /* return data parsed on success, 0 if can't parse anymore, -1 on error */ 995 static int 996 _dump_rmcpplus_session_trlr (int fd, 997 const char *prefix, 998 const char *session_trailer_hdr, 999 uint32_t session_id, 1000 uint8_t payload_authenticated, 1001 uint8_t integrity_algorithm, 1002 const void *pkt, 1003 unsigned int pkt_len) 1004 { 1005 int pad_length_field_len, next_header_field_len, rv = -1; 1006 unsigned int pad_length, authentication_code_len = 0; 1007 fiid_obj_t obj_rmcpplus_session_trlr = NULL; 1008 unsigned int indx = 0; 1009 1010 assert (IPMI_INTEGRITY_ALGORITHM_SUPPORTED (integrity_algorithm)); 1011 1012 if (!session_id || payload_authenticated == IPMI_PAYLOAD_FLAG_UNAUTHENTICATED) 1013 return (1); 1014 1015 /* payload should be authenticated */ 1016 if (integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_NONE) 1017 authentication_code_len = 0; 1018 else if (integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_HMAC_SHA1_96) 1019 authentication_code_len = IPMI_HMAC_SHA1_96_AUTHENTICATION_CODE_LENGTH; 1020 else if (integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_HMAC_MD5_128) 1021 authentication_code_len = IPMI_HMAC_MD5_128_AUTHENTICATION_CODE_LENGTH; 1022 else if (integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_MD5_128) 1023 authentication_code_len = IPMI_MD5_128_AUTHENTICATION_CODE_LENGTH; 1024 else if (integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_HMAC_SHA256_128) 1025 authentication_code_len = IPMI_HMAC_SHA256_128_AUTHENTICATION_CODE_LENGTH; 1026 else 1027 authentication_code_len = 0; /* just in case IPMI implementation is bogus */ 1028 1029 if (!(obj_rmcpplus_session_trlr = fiid_obj_create (tmpl_rmcpplus_session_trlr))) 1030 { 1031 ERRNO_TRACE (errno); 1032 goto cleanup; 1033 } 1034 1035 if ((pad_length_field_len = fiid_template_field_len_bytes (tmpl_rmcpplus_session_trlr, 1036 "pad_length")) < 0) 1037 { 1038 ERRNO_TRACE (errno); 1039 goto cleanup; 1040 } 1041 1042 if ((next_header_field_len = fiid_template_field_len_bytes (tmpl_rmcpplus_session_trlr, 1043 "next_header")) < 0) 1044 { 1045 ERRNO_TRACE (errno); 1046 goto cleanup; 1047 } 1048 1049 if (pkt_len < (pad_length_field_len)) 1050 { 1051 next_header_field_len = 0; 1052 authentication_code_len = 0; 1053 } 1054 else if (pkt_len < (pad_length_field_len + next_header_field_len)) 1055 authentication_code_len = 0; 1056 else if (authentication_code_len 1057 && pkt_len < (authentication_code_len + pad_length_field_len + next_header_field_len)) 1058 authentication_code_len = pkt_len - pad_length_field_len - next_header_field_len; 1059 1060 pad_length = pkt_len - pad_length_field_len - next_header_field_len - authentication_code_len; 1061 1062 if (pad_length) 1063 { 1064 if (fiid_obj_set_data (obj_rmcpplus_session_trlr, 1065 "integrity_pad", 1066 pkt + indx, 1067 pad_length) < 0) 1068 { 1069 FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcpplus_session_trlr); 1070 goto cleanup; 1071 } 1072 indx += pad_length; 1073 } 1074 1075 if (pad_length_field_len) 1076 { 1077 if (fiid_obj_set_data (obj_rmcpplus_session_trlr, 1078 "pad_length", 1079 pkt + indx, 1080 pad_length_field_len) < 0) 1081 { 1082 FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcpplus_session_trlr); 1083 goto cleanup; 1084 } 1085 indx += pad_length_field_len; 1086 } 1087 1088 if (next_header_field_len) 1089 { 1090 if (fiid_obj_set_data (obj_rmcpplus_session_trlr, 1091 "next_header", 1092 pkt + indx, 1093 next_header_field_len) < 0) 1094 { 1095 FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcpplus_session_trlr); 1096 goto cleanup; 1097 } 1098 indx += next_header_field_len; 1099 } 1100 1101 if (authentication_code_len) 1102 { 1103 if (fiid_obj_set_data (obj_rmcpplus_session_trlr, 1104 "authentication_code", 1105 pkt + indx, 1106 authentication_code_len) < 0) 1107 { 1108 FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcpplus_session_trlr); 1109 goto cleanup; 1110 } 1111 indx += authentication_code_len; 1112 } 1113 1114 1115 if (ipmi_obj_dump (fd, 1116 prefix, 1117 session_trailer_hdr, 1118 NULL, 1119 obj_rmcpplus_session_trlr) < 0) 1120 { 1121 ERRNO_TRACE (errno); 1122 goto cleanup; 1123 } 1124 1125 rv = indx; 1126 cleanup: 1127 fiid_obj_destroy (obj_rmcpplus_session_trlr); 1128 return (rv); 1129 } 1130 1131 static int 1132 _ipmi_dump_rmcpplus_packet (int fd, 1133 const char *prefix, 1134 const char *hdr, 1135 const char *trlr, 1136 uint8_t authentication_algorithm, 1137 uint8_t integrity_algorithm, 1138 uint8_t confidentiality_algorithm, 1139 const void *integrity_key, 1140 unsigned int integrity_key_len, 1141 const void *confidentiality_key, 1142 unsigned int confidentiality_key_len, 1143 const void *pkt, 1144 unsigned int pkt_len, 1145 fiid_template_t tmpl_lan_msg_hdr, 1146 fiid_template_t tmpl_cmd, 1147 fiid_template_t tmpl_ipmb_msg_hdr, 1148 fiid_template_t tmpl_ipmb_cmd) 1149 { 1150 int obj_rmcp_hdr_len, obj_len, ret, rv = -1; 1151 uint8_t payload_type = 0, payload_authenticated = 0, payload_encrypted = 0; 1152 uint32_t session_id = 0; 1153 uint16_t ipmi_payload_len = 0; 1154 char prefix_buf[IPMI_DEBUG_MAX_PREFIX_LEN]; 1155 fiid_obj_t obj_rmcp_hdr = NULL; 1156 fiid_obj_t obj_unexpected_data = NULL; 1157 char *rmcp_hdr = 1158 "RMCP Header:\n" 1159 "------------"; 1160 char *session_hdr = 1161 "IPMI RMCPPLUS Session Header:\n" 1162 "-----------------------------"; 1163 char *payload_hdr = 1164 "IPMI RMCPPLUS Payload:\n" 1165 "----------------------"; 1166 char *msg_hdr = 1167 "IPMI Message Header:\n" 1168 "--------------------"; 1169 char *cmd_hdr = 1170 "IPMI Command Data:\n" 1171 "------------------"; 1172 char *ipmb_msg_hdr = 1173 "IPMB Message Header:\n" 1174 "--------------------"; 1175 char *ipmb_cmd_hdr = 1176 "IPMB Message Data:\n" 1177 "------------------"; 1178 char *ipmb_msg_trlr_hdr = 1179 "IPMB Message Trailer:\n" 1180 "---------------------"; 1181 char *trailer_hdr = 1182 "IPMI Trailer:\n" 1183 "-------------"; 1184 char *session_trailer_hdr = 1185 "IPMI RMCPPLUS Session Trailer:\n" 1186 "------------------------------"; 1187 char *extra_hdr = 1188 "Unexpected Data:\n" 1189 "----------------"; 1190 unsigned int indx = 0; 1191 1192 assert (pkt); 1193 assert (IPMI_AUTHENTICATION_ALGORITHM_SUPPORTED (authentication_algorithm)); 1194 assert (IPMI_INTEGRITY_ALGORITHM_SUPPORTED (integrity_algorithm)); 1195 assert (IPMI_CONFIDENTIALITY_ALGORITHM_SUPPORTED (confidentiality_algorithm)); 1196 assert (!(confidentiality_algorithm == IPMI_CONFIDENTIALITY_ALGORITHM_AES_CBC_128 1197 && !(confidentiality_key 1198 && confidentiality_key_len))); 1199 assert (tmpl_cmd); 1200 1201 if (debug_set_prefix (prefix_buf, IPMI_DEBUG_MAX_PREFIX_LEN, prefix) < 0) 1202 { 1203 ERRNO_TRACE (errno); 1204 goto cleanup; 1205 } 1206 1207 if (debug_output_str (fd, prefix_buf, hdr) < 0) 1208 { 1209 ERRNO_TRACE (errno); 1210 goto cleanup; 1211 } 1212 1213 /* Dump rmcp header */ 1214 1215 if (!(obj_rmcp_hdr = fiid_obj_create (tmpl_rmcp_hdr))) 1216 { 1217 ERRNO_TRACE (errno); 1218 goto cleanup; 1219 } 1220 1221 if ((obj_rmcp_hdr_len = fiid_obj_set_all (obj_rmcp_hdr, 1222 pkt + indx, 1223 pkt_len - indx)) < 0) 1224 { 1225 FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcp_hdr); 1226 goto cleanup; 1227 } 1228 indx += obj_rmcp_hdr_len; 1229 1230 if (ipmi_obj_dump (fd, 1231 prefix, 1232 rmcp_hdr, 1233 NULL, 1234 obj_rmcp_hdr) < 0) 1235 { 1236 ERRNO_TRACE (errno); 1237 goto cleanup; 1238 } 1239 1240 if (pkt_len <= indx) 1241 goto out; 1242 1243 /* Dump rmcpplus session header */ 1244 1245 if ((obj_len = _dump_rmcpplus_session_hdr (fd, 1246 prefix, 1247 session_hdr, 1248 pkt + indx, 1249 pkt_len - indx, 1250 &payload_type, 1251 &payload_authenticated, 1252 &payload_encrypted, 1253 &session_id, 1254 &ipmi_payload_len)) < 0) 1255 { 1256 ERRNO_TRACE (errno); 1257 goto cleanup; 1258 } 1259 1260 /* don't know how to parse, dump as just big blob of hex */ 1261 if (!obj_len) 1262 goto dump_extra; 1263 1264 indx += obj_len; 1265 1266 if (pkt_len <= indx) 1267 goto out; 1268 1269 /* achu: If the packet is really messed up, dump the packet in raw form */ 1270 if ((payload_type != IPMI_PAYLOAD_TYPE_IPMI 1271 && payload_type != IPMI_PAYLOAD_TYPE_SOL 1272 && payload_type != IPMI_PAYLOAD_TYPE_RMCPPLUS_OPEN_SESSION_REQUEST 1273 && payload_type != IPMI_PAYLOAD_TYPE_RMCPPLUS_OPEN_SESSION_RESPONSE 1274 && payload_type != IPMI_PAYLOAD_TYPE_RAKP_MESSAGE_1 1275 && payload_type != IPMI_PAYLOAD_TYPE_RAKP_MESSAGE_2 1276 && payload_type != IPMI_PAYLOAD_TYPE_RAKP_MESSAGE_3 1277 && payload_type != IPMI_PAYLOAD_TYPE_RAKP_MESSAGE_4) 1278 || !IPMI_AUTHENTICATION_ALGORITHM_SUPPORTED (authentication_algorithm) 1279 || !IPMI_INTEGRITY_ALGORITHM_SUPPORTED (integrity_algorithm) 1280 || !IPMI_CONFIDENTIALITY_ALGORITHM_SUPPORTED (confidentiality_algorithm) 1281 || !ipmi_payload_len) 1282 goto dump_extra; 1283 1284 if (payload_type == IPMI_PAYLOAD_TYPE_IPMI) 1285 { 1286 if (!tmpl_lan_msg_hdr 1287 || (fiid_template_compare (tmpl_lan_msg_hdr, 1288 tmpl_lan_msg_hdr_rq) != 1 1289 && fiid_template_compare (tmpl_lan_msg_hdr, 1290 tmpl_lan_msg_hdr_rs) != 1)) 1291 { 1292 SET_ERRNO (EINVAL); 1293 goto cleanup; 1294 } 1295 } 1296 else if (payload_type == IPMI_PAYLOAD_TYPE_SOL) 1297 { 1298 if (fiid_template_compare (tmpl_cmd, 1299 tmpl_sol_payload_data) != 1 1300 && fiid_template_compare (tmpl_cmd, 1301 tmpl_sol_payload_data_remote_console_to_bmc) != 1 1302 && fiid_template_compare (tmpl_cmd, 1303 tmpl_sol_payload_data_bmc_to_remote_console) != 1) 1304 { 1305 SET_ERRNO (EINVAL); 1306 goto cleanup; 1307 } 1308 } 1309 else if (payload_type == IPMI_PAYLOAD_TYPE_RMCPPLUS_OPEN_SESSION_REQUEST) 1310 { 1311 if (fiid_template_compare (tmpl_cmd, tmpl_rmcpplus_open_session_request) != 1) 1312 { 1313 SET_ERRNO (EINVAL); 1314 goto cleanup; 1315 } 1316 } 1317 else if (payload_type == IPMI_PAYLOAD_TYPE_RMCPPLUS_OPEN_SESSION_RESPONSE) 1318 { 1319 if (fiid_template_compare (tmpl_cmd, tmpl_rmcpplus_open_session_response) != 1) 1320 { 1321 SET_ERRNO (EINVAL); 1322 goto cleanup; 1323 } 1324 } 1325 else if (payload_type == IPMI_PAYLOAD_TYPE_RAKP_MESSAGE_1) 1326 { 1327 if (fiid_template_compare (tmpl_cmd, tmpl_rmcpplus_rakp_message_1) != 1) 1328 { 1329 SET_ERRNO (EINVAL); 1330 goto cleanup; 1331 } 1332 } 1333 else if (payload_type == IPMI_PAYLOAD_TYPE_RAKP_MESSAGE_2) 1334 { 1335 if (fiid_template_compare (tmpl_cmd, tmpl_rmcpplus_rakp_message_2) != 1) 1336 { 1337 SET_ERRNO (EINVAL); 1338 goto cleanup; 1339 } 1340 } 1341 else if (payload_type == IPMI_PAYLOAD_TYPE_RAKP_MESSAGE_3) 1342 { 1343 if (fiid_template_compare (tmpl_cmd, tmpl_rmcpplus_rakp_message_3) != 1) 1344 { 1345 SET_ERRNO (EINVAL); 1346 goto cleanup; 1347 } 1348 } 1349 else if (payload_type == IPMI_PAYLOAD_TYPE_RAKP_MESSAGE_4) 1350 { 1351 if (fiid_template_compare (tmpl_cmd, tmpl_rmcpplus_rakp_message_4) != 1) 1352 { 1353 SET_ERRNO (EINVAL); 1354 goto cleanup; 1355 } 1356 } 1357 1358 /* Dump Payload */ 1359 1360 if ((ret = _dump_rmcpplus_payload (fd, 1361 prefix, 1362 payload_hdr, 1363 msg_hdr, 1364 cmd_hdr, 1365 ipmb_msg_hdr, 1366 ipmb_cmd_hdr, 1367 ipmb_msg_trlr_hdr, 1368 trailer_hdr, 1369 payload_type, 1370 authentication_algorithm, 1371 confidentiality_algorithm, 1372 tmpl_lan_msg_hdr, 1373 tmpl_cmd, 1374 tmpl_ipmb_msg_hdr, 1375 tmpl_ipmb_cmd, 1376 confidentiality_key, 1377 confidentiality_key_len, 1378 pkt + indx, 1379 ipmi_payload_len)) < 0) 1380 { 1381 ERRNO_TRACE (errno); 1382 goto cleanup; 1383 } 1384 1385 /* don't know how to parse, dump as just big blob of hex */ 1386 if (!ret) 1387 goto dump_extra; 1388 1389 indx += ipmi_payload_len; 1390 1391 if (pkt_len <= indx) 1392 goto out; 1393 1394 /* Dump trailer */ 1395 1396 if ((obj_len = _dump_rmcpplus_session_trlr (fd, 1397 prefix, 1398 session_trailer_hdr, 1399 session_id, 1400 payload_authenticated, 1401 integrity_algorithm, 1402 pkt + indx, 1403 pkt_len - indx)) < 0) 1404 { 1405 ERRNO_TRACE (errno); 1406 goto cleanup; 1407 } 1408 1409 /* don't know how to parse, dump as just big blob of hex */ 1410 if (!obj_len) 1411 goto dump_extra; 1412 1413 indx += obj_len; 1414 1415 /* Dump extra stuff if packet is longer than expected */ 1416 dump_extra: 1417 if ((pkt_len - indx) > 0) 1418 { 1419 if (!(obj_unexpected_data = fiid_obj_create (tmpl_unexpected_data))) 1420 { 1421 ERRNO_TRACE (errno); 1422 goto cleanup; 1423 } 1424 1425 if ((obj_len = fiid_obj_set_all (obj_unexpected_data, 1426 pkt + indx, 1427 pkt_len - indx)) < 0) 1428 { 1429 FIID_OBJECT_ERROR_TO_ERRNO (obj_unexpected_data); 1430 goto cleanup; 1431 } 1432 indx += obj_len; 1433 1434 if (ipmi_obj_dump (fd, 1435 prefix, 1436 extra_hdr, 1437 NULL, 1438 obj_unexpected_data) < 0) 1439 { 1440 ERRNO_TRACE (errno); 1441 goto cleanup; 1442 } 1443 } 1444 1445 if (debug_output_str (fd, prefix_buf, trlr) < 0) 1446 { 1447 ERRNO_TRACE (errno); 1448 goto cleanup; 1449 } 1450 1451 out: 1452 #if WITH_RAWDUMPS 1453 /* For those vendors that get confused when they see the nice output 1454 * and want the hex output 1455 */ 1456 if (ipmi_dump_hex (fd, 1457 prefix, 1458 hdr, 1459 trlr, 1460 pkt, 1461 pkt_len) < 0) 1462 { 1463 ERRNO_TRACE (errno); 1464 goto cleanup; 1465 } 1466 #endif 1467 1468 rv = 0; 1469 cleanup: 1470 fiid_obj_destroy (obj_rmcp_hdr); 1471 fiid_obj_destroy (obj_unexpected_data); 1472 return (rv); 1473 } 1474 1475 int 1476 ipmi_dump_rmcpplus_packet (int fd, 1477 const char *prefix, 1478 const char *hdr, 1479 const char *trlr, 1480 uint8_t authentication_algorithm, 1481 uint8_t integrity_algorithm, 1482 uint8_t confidentiality_algorithm, 1483 const void *integrity_key, 1484 unsigned int integrity_key_len, 1485 const void *confidentiality_key, 1486 unsigned int confidentiality_key_len, 1487 const void *pkt, 1488 unsigned int pkt_len, 1489 fiid_template_t tmpl_lan_msg_hdr, 1490 fiid_template_t tmpl_cmd) 1491 { 1492 if (!pkt 1493 || !IPMI_AUTHENTICATION_ALGORITHM_SUPPORTED (authentication_algorithm) 1494 || !IPMI_INTEGRITY_ALGORITHM_SUPPORTED (integrity_algorithm) 1495 || !IPMI_CONFIDENTIALITY_ALGORITHM_SUPPORTED (confidentiality_algorithm) 1496 || (confidentiality_algorithm == IPMI_CONFIDENTIALITY_ALGORITHM_AES_CBC_128 1497 && (!confidentiality_key 1498 || !confidentiality_key_len)) 1499 || !tmpl_cmd) 1500 { 1501 SET_ERRNO (EINVAL); 1502 return (-1); 1503 } 1504 1505 return (_ipmi_dump_rmcpplus_packet (fd, 1506 prefix, 1507 hdr, 1508 trlr, 1509 authentication_algorithm, 1510 integrity_algorithm, 1511 confidentiality_algorithm, 1512 integrity_key, 1513 integrity_key_len, 1514 confidentiality_key, 1515 confidentiality_key_len, 1516 pkt, 1517 pkt_len, 1518 tmpl_lan_msg_hdr, 1519 tmpl_cmd, 1520 NULL, 1521 NULL)); 1522 } 1523 1524 int 1525 ipmi_dump_rmcpplus_packet_ipmb (int fd, 1526 const char *prefix, 1527 const char *hdr, 1528 const char *trlr, 1529 uint8_t authentication_algorithm, 1530 uint8_t integrity_algorithm, 1531 uint8_t confidentiality_algorithm, 1532 const void *integrity_key, 1533 unsigned int integrity_key_len, 1534 const void *confidentiality_key, 1535 unsigned int confidentiality_key_len, 1536 const void *pkt, 1537 unsigned int pkt_len, 1538 fiid_template_t tmpl_lan_msg_hdr, 1539 fiid_template_t tmpl_cmd, 1540 fiid_template_t tmpl_ipmb_msg_hdr, 1541 fiid_template_t tmpl_ipmb_cmd) 1542 { 1543 int ret1, ret2; 1544 1545 if (!pkt 1546 || !IPMI_AUTHENTICATION_ALGORITHM_SUPPORTED (authentication_algorithm) 1547 || !IPMI_INTEGRITY_ALGORITHM_SUPPORTED (integrity_algorithm) 1548 || !IPMI_CONFIDENTIALITY_ALGORITHM_SUPPORTED (confidentiality_algorithm) 1549 || (confidentiality_algorithm == IPMI_CONFIDENTIALITY_ALGORITHM_AES_CBC_128 1550 && (!confidentiality_key 1551 || !confidentiality_key_len)) 1552 || !tmpl_cmd 1553 || !tmpl_ipmb_msg_hdr 1554 || !tmpl_ipmb_cmd) 1555 { 1556 SET_ERRNO (EINVAL); 1557 return (-1); 1558 } 1559 1560 if ((ret1 = fiid_template_compare (tmpl_cmd, tmpl_cmd_send_message_rq)) < 0) 1561 return (-1); 1562 1563 if ((ret2 = fiid_template_compare (tmpl_cmd, tmpl_cmd_get_message_rs)) < 0) 1564 return (-1); 1565 1566 if (!ret1 && !ret2) 1567 { 1568 SET_ERRNO (EINVAL); 1569 return (-1); 1570 } 1571 1572 return (_ipmi_dump_rmcpplus_packet (fd, 1573 prefix, 1574 hdr, 1575 trlr, 1576 authentication_algorithm, 1577 integrity_algorithm, 1578 confidentiality_algorithm, 1579 integrity_key, 1580 integrity_key_len, 1581 confidentiality_key, 1582 confidentiality_key_len, 1583 pkt, 1584 pkt_len, 1585 tmpl_lan_msg_hdr, 1586 tmpl_cmd, 1587 tmpl_ipmb_msg_hdr, 1588 tmpl_ipmb_cmd)); 1589 } 1590