1 /* -*-mode: C; indent-tabs-mode: t; -*- 2 * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * Redistribution of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 11 * Redistribution in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * Neither the name of Sun Microsystems, Inc. or the names of 16 * contributors may be used to endorse or promote products derived 17 * from this software without specific prior written permission. 18 * 19 * This software is provided "AS IS," without a warranty of any kind. 20 * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, 21 * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A 22 * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. 23 * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE 24 * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING 25 * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL 26 * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, 27 * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR 28 * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF 29 * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, 30 * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 31 */ 32 33 #include <stdlib.h> 34 #include <stdio.h> 35 #include <string.h> 36 #include <strings.h> 37 #include <sys/types.h> 38 #include <sys/socket.h> 39 #include <netinet/in.h> 40 #include <arpa/inet.h> 41 #include <errno.h> 42 #include <unistd.h> 43 #include <signal.h> 44 45 #include <ipmitool/ipmi.h> 46 #include <ipmitool/ipmi_intf.h> 47 #include <ipmitool/helper.h> 48 #include <ipmitool/log.h> 49 #include <ipmitool/ipmi_lanp.h> 50 #include <ipmitool/ipmi_channel.h> 51 #include <ipmitool/ipmi_strings.h> 52 #include <ipmitool/ipmi_constants.h> 53 54 extern int csv_output; 55 extern int verbose; 56 57 void printf_channel_usage (void); 58 59 /** 60 * ipmi_1_5_authtypes 61 * 62 * Create a string describing the supported authentication types as 63 * specificed by the parameter n 64 */ 65 static const char * 66 ipmi_1_5_authtypes(uint8_t n) 67 { 68 uint32_t i; 69 static char supportedTypes[128]; 70 71 memset(supportedTypes, 0, sizeof(supportedTypes)); 72 for (i = 0; ipmi_authtype_vals[i].val != 0; i++) { 73 if (n & ipmi_authtype_vals[i].val) { 74 strcat(supportedTypes, ipmi_authtype_vals[i].str); 75 strcat(supportedTypes, " "); 76 } 77 } 78 79 return supportedTypes; 80 } 81 82 83 84 /** 85 * ipmi_get_channel_auth_cap 86 * 87 * return 0 on success 88 * -1 on failure 89 */ 90 int 91 ipmi_get_channel_auth_cap(struct ipmi_intf *intf, uint8_t channel, uint8_t priv) 92 { 93 struct ipmi_rs *rsp; 94 struct ipmi_rq req; 95 struct get_channel_auth_cap_rsp auth_cap; 96 uint8_t msg_data[2]; 97 98 /* Ask for IPMI v2 data as well */ 99 msg_data[0] = channel | 0x80; 100 msg_data[1] = priv; 101 102 memset(&req, 0, sizeof(req)); 103 req.msg.netfn = IPMI_NETFN_APP; 104 req.msg.cmd = IPMI_GET_CHANNEL_AUTH_CAP; 105 req.msg.data = msg_data; 106 req.msg.data_len = 2; 107 108 rsp = intf->sendrecv(intf, &req); 109 110 if ((rsp == NULL) || (rsp->ccode > 0)) { 111 /* 112 * It's very possible that this failed because we asked for IPMI v2 data 113 * Ask again, without requesting IPMI v2 data 114 */ 115 msg_data[0] &= 0x7F; 116 117 rsp = intf->sendrecv(intf, &req); 118 if (rsp == NULL) { 119 lprintf(LOG_ERR, "Unable to Get Channel Authentication Capabilities"); 120 return (-1); 121 } 122 if (rsp->ccode > 0) { 123 lprintf(LOG_ERR, "Get Channel Authentication Capabilities failed: %s", 124 val2str(rsp->ccode, completion_code_vals)); 125 return (-1); 126 } 127 } 128 129 memcpy(&auth_cap, rsp->data, sizeof(struct get_channel_auth_cap_rsp)); 130 131 printf("Channel number : %d\n", 132 auth_cap.channel_number); 133 printf("IPMI v1.5 auth types : %s\n", 134 ipmi_1_5_authtypes(auth_cap.enabled_auth_types)); 135 136 if (auth_cap.v20_data_available) { 137 printf("KG status : %s\n", 138 (auth_cap.kg_status) ? "non-zero" : "default (all zeroes)"); 139 } 140 141 printf("Per message authentication : %sabled\n", 142 (auth_cap.per_message_auth) ? "dis" : "en"); 143 printf("User level authentication : %sabled\n", 144 (auth_cap.user_level_auth) ? "dis" : "en"); 145 146 printf("Non-null user names exist : %s\n", 147 (auth_cap.non_null_usernames) ? "yes" : "no"); 148 printf("Null user names exist : %s\n", 149 (auth_cap.null_usernames) ? "yes" : "no"); 150 printf("Anonymous login enabled : %s\n", 151 (auth_cap.anon_login_enabled) ? "yes" : "no"); 152 153 if (auth_cap.v20_data_available) { 154 printf("Channel supports IPMI v1.5 : %s\n", 155 (auth_cap.ipmiv15_support) ? "yes" : "no"); 156 printf("Channel supports IPMI v2.0 : %s\n", 157 (auth_cap.ipmiv20_support) ? "yes" : "no"); 158 } 159 160 /* 161 * If there is support for an OEM authentication type, there is some 162 * information. 163 */ 164 if (auth_cap.enabled_auth_types & IPMI_1_5_AUTH_TYPE_BIT_OEM) { 165 printf("IANA Number for OEM : %d\n", 166 auth_cap.oem_id[0] | 167 auth_cap.oem_id[1] << 8 | 168 auth_cap.oem_id[2] << 16); 169 printf("OEM Auxiliary Data : 0x%x\n", 170 auth_cap.oem_aux_data); 171 } 172 173 return 0; 174 } 175 176 177 178 /** 179 * ipmi_get_channel_info 180 * 181 * returns 0 on success 182 * -1 on failure 183 * 184 */ 185 int 186 ipmi_get_channel_info(struct ipmi_intf *intf, uint8_t channel) 187 { 188 struct ipmi_rs *rsp; 189 struct ipmi_rq req; 190 uint8_t rqdata[2]; 191 uint8_t medium; 192 struct get_channel_info_rsp channel_info; 193 struct get_channel_access_rsp channel_access; 194 195 memset(&req, 0, sizeof(req)); 196 req.msg.netfn = IPMI_NETFN_APP; 197 req.msg.cmd = IPMI_GET_CHANNEL_INFO; 198 req.msg.data = &channel; 199 req.msg.data_len = 1; 200 201 rsp = intf->sendrecv(intf, &req); 202 if (rsp == NULL) { 203 lprintf(LOG_ERR, "Unable to Get Channel Info"); 204 return -1; 205 } 206 if (rsp->ccode > 0) { 207 lprintf(LOG_ERR, "Get Channel Info failed: %s", 208 val2str(rsp->ccode, completion_code_vals)); 209 return -1; 210 } 211 212 memcpy(&channel_info, rsp->data, sizeof(struct get_channel_info_rsp)); 213 214 printf("Channel 0x%x info:\n", channel_info.channel_number); 215 216 printf(" Channel Medium Type : %s\n", 217 val2str(channel_info.channel_medium, ipmi_channel_medium_vals)); 218 219 printf(" Channel Protocol Type : %s\n", 220 val2str(channel_info.channel_protocol, ipmi_channel_protocol_vals)); 221 222 printf(" Session Support : "); 223 switch (channel_info.session_support) { 224 case 0x0: 225 printf("session-less\n"); 226 break; 227 case 0x1: 228 printf("single-session\n"); 229 break; 230 case 0x2: 231 printf("multi-session\n"); 232 break; 233 case 0x3: 234 default: 235 printf("session-based\n"); 236 break; 237 } 238 239 printf(" Active Session Count : %d\n", 240 channel_info.active_sessions); 241 242 printf(" Protocol Vendor ID : %d\n", 243 channel_info.vendor_id[0] | 244 channel_info.vendor_id[1] << 8 | 245 channel_info.vendor_id[2] << 16); 246 247 248 /* only proceed if this is LAN channel */ 249 medium = ipmi_get_channel_medium(intf, channel); 250 if (medium != IPMI_CHANNEL_MEDIUM_LAN && 251 medium != IPMI_CHANNEL_MEDIUM_LAN_OTHER) { 252 return 0; 253 } 254 255 memset(&req, 0, sizeof(req)); 256 rqdata[0] = channel & 0xf; 257 258 /* get volatile settings */ 259 rqdata[1] = 0x80; /* 0x80=active */ 260 req.msg.netfn = IPMI_NETFN_APP; 261 req.msg.cmd = IPMI_GET_CHANNEL_ACCESS; 262 req.msg.data = rqdata; 263 req.msg.data_len = 2; 264 265 rsp = intf->sendrecv(intf, &req); 266 if (rsp == NULL) { 267 lprintf(LOG_ERR, "Unable to Get Channel Access (volatile)"); 268 return -1; 269 } 270 if (rsp->ccode > 0) { 271 lprintf(LOG_ERR, "Get Channel Access (volatile) failed: %s", 272 val2str(rsp->ccode, completion_code_vals)); 273 return -1; 274 } 275 276 memcpy(&channel_access, rsp->data, sizeof(struct get_channel_access_rsp)); 277 278 279 printf(" Volatile(active) Settings\n"); 280 printf(" Alerting : %sabled\n", 281 (channel_access.alerting) ? "dis" : "en"); 282 printf(" Per-message Auth : %sabled\n", 283 (channel_access.per_message_auth) ? "dis" : "en"); 284 printf(" User Level Auth : %sabled\n", 285 (channel_access.user_level_auth) ? "dis" : "en"); 286 287 printf(" Access Mode : "); 288 switch (channel_access.access_mode) { 289 case 0: 290 printf("disabled\n"); 291 break; 292 case 1: 293 printf("pre-boot only\n"); 294 break; 295 case 2: 296 printf("always available\n"); 297 break; 298 case 3: 299 printf("shared\n"); 300 break; 301 default: 302 printf("unknown\n"); 303 break; 304 } 305 306 /* get non-volatile settings */ 307 308 rqdata[1] = 0x40; /* 0x40=non-volatile */ 309 rsp = intf->sendrecv(intf, &req); 310 if (rsp == NULL) { 311 lprintf(LOG_ERR, "Unable to Get Channel Access (non-volatile)"); 312 return -1; 313 } 314 if (rsp->ccode > 0) { 315 lprintf(LOG_ERR, "Get Channel Access (non-volatile) failed: %s", 316 val2str(rsp->ccode, completion_code_vals)); 317 return -1; 318 } 319 320 memcpy(&channel_access, rsp->data, sizeof(struct get_channel_access_rsp)); 321 322 printf(" Non-Volatile Settings\n"); 323 printf(" Alerting : %sabled\n", 324 (channel_access.alerting) ? "dis" : "en"); 325 printf(" Per-message Auth : %sabled\n", 326 (channel_access.per_message_auth) ? "dis" : "en"); 327 printf(" User Level Auth : %sabled\n", 328 (channel_access.user_level_auth) ? "dis" : "en"); 329 330 printf(" Access Mode : "); 331 switch (channel_access.access_mode) { 332 case 0: 333 printf("disabled\n"); 334 break; 335 case 1: 336 printf("pre-boot only\n"); 337 break; 338 case 2: 339 printf("always available\n"); 340 break; 341 case 3: 342 printf("shared\n"); 343 break; 344 default: 345 printf("unknown\n"); 346 break; 347 } 348 349 return 0; 350 } 351 352 static int 353 ipmi_get_user_access(struct ipmi_intf *intf, uint8_t channel, uint8_t userid) 354 { 355 struct ipmi_rs *rsp; 356 struct ipmi_rq req1, req2; 357 uint8_t rqdata[2]; 358 struct get_user_access_rsp user_access; 359 int curr_uid; 360 int max_uid = 0; 361 int init = 1; 362 363 curr_uid = userid ? : 1; 364 365 memset(&req1, 0, sizeof(req1)); 366 req1.msg.netfn = IPMI_NETFN_APP; 367 req1.msg.cmd = IPMI_GET_USER_ACCESS; 368 req1.msg.data = rqdata; 369 req1.msg.data_len = 2; 370 371 memset(&req2, 0, sizeof(req2)); 372 req2.msg.netfn = IPMI_NETFN_APP; 373 req2.msg.cmd = IPMI_GET_USER_NAME; 374 req2.msg.data = rqdata; 375 req2.msg.data_len = 1; 376 377 do { 378 rqdata[0] = channel & 0xf; 379 rqdata[1] = curr_uid & 0x3f; 380 381 rsp = intf->sendrecv(intf, &req1); 382 if (rsp == NULL) { 383 lprintf(LOG_ERR, "Unable to Get User Access (channel %d id %d)", 384 rqdata[0], rqdata[1]); 385 return -1; 386 } 387 if (rsp->ccode > 0) { 388 lprintf(LOG_ERR, "Get User Access (channel %d id %d) failed: %s", 389 rqdata[0], rqdata[1], 390 val2str(rsp->ccode, completion_code_vals)); 391 return -1; 392 } 393 394 memcpy(&user_access, rsp->data, sizeof(struct get_user_access_rsp)); 395 396 rqdata[0] = curr_uid & 0x3f; 397 398 rsp = intf->sendrecv(intf, &req2); 399 if (rsp == NULL) { 400 lprintf(LOG_ERR, "Unable to Get User Name (id %d)", rqdata[0]); 401 return -1; 402 } 403 if (rsp->ccode > 0) { 404 lprintf(LOG_ERR, "Get User Name (id %d) failed: %s", 405 rqdata[0], val2str(rsp->ccode, completion_code_vals)); 406 return -1; 407 } 408 409 if (init) { 410 printf("Maximum User IDs : %d\n", user_access.max_user_ids); 411 printf("Enabled User IDs : %d\n", user_access.enabled_user_ids); 412 max_uid = user_access.max_user_ids; 413 init = 0; 414 } 415 416 printf("\n"); 417 printf("User ID : %d\n", curr_uid); 418 printf("User Name : %s\n", rsp->data); 419 printf("Fixed Name : %s\n", 420 (curr_uid <= user_access.fixed_user_ids) ? "Yes" : "No"); 421 printf("Access Available : %s\n", 422 (user_access.callin_callback) ? "callback" : "call-in / callback"); 423 printf("Link Authentication : %sabled\n", 424 (user_access.link_auth) ? "en" : "dis"); 425 printf("IPMI Messaging : %sabled\n", 426 (user_access.ipmi_messaging) ? "en" : "dis"); 427 printf("Privilege Level : %s\n", 428 val2str(user_access.privilege_limit, ipmi_privlvl_vals)); 429 430 curr_uid ++; 431 432 } while (!userid && curr_uid <= max_uid); 433 434 return 0; 435 } 436 437 static int 438 ipmi_set_user_access(struct ipmi_intf * intf, int argc, char ** argv) 439 { 440 uint8_t channel; 441 uint8_t privilege_limit; 442 uint8_t userid; 443 struct ipmi_rs *rsp; 444 struct ipmi_rq req; 445 uint8_t rqdata[2]; 446 struct get_user_access_rsp user_access; 447 struct set_user_access_data set_access; 448 int i; 449 450 if ((argc < 3) || (strncmp(argv[0], "help", 4) == 0)) { 451 printf_channel_usage(); 452 return 0; 453 } 454 if (is_ipmi_channel_num(argv[0], &channel) != 0 455 || is_ipmi_user_id(argv[1], &userid) != 0) { 456 return (-1); 457 } 458 459 memset(&req, 0, sizeof(req)); 460 req.msg.netfn = IPMI_NETFN_APP; 461 req.msg.cmd = IPMI_GET_USER_ACCESS; 462 req.msg.data = rqdata; 463 req.msg.data_len = 2; 464 465 rqdata[0] = channel & 0xf; 466 rqdata[1] = userid & 0x3f; 467 468 rsp = intf->sendrecv(intf, &req); 469 if (rsp == NULL) { 470 lprintf(LOG_ERR, "Unable to Get User Access (channel %d id %d)", 471 rqdata[0], rqdata[1]); 472 return -1; 473 } 474 if (rsp->ccode > 0) { 475 lprintf(LOG_ERR, "Get User Access (channel %d id %d) failed: %s", 476 rqdata[0], rqdata[1], 477 val2str(rsp->ccode, completion_code_vals)); 478 return -1; 479 } 480 481 memcpy(&user_access, rsp->data, sizeof(struct get_user_access_rsp)); 482 483 memset(&set_access, 0, sizeof(set_access)); 484 set_access.change_bits = 1; 485 set_access.callin_callback = user_access.callin_callback; 486 set_access.link_auth = user_access.link_auth; 487 set_access.ipmi_messaging = user_access.ipmi_messaging; 488 set_access.channel = channel; 489 set_access.user_id = userid; 490 set_access.privilege_limit = user_access.privilege_limit; 491 set_access.session_limit = 0; 492 493 for (i = 2; i < argc; i ++) { 494 if (strncmp(argv[i], "callin=", 7) == 0) { 495 set_access.callin_callback = !(strncmp (argv[i]+7, "off", 3)); 496 } 497 else if (strncmp(argv[i], "link=", 5) == 0) { 498 set_access.link_auth = strncmp (argv[i]+5, "off", 3); 499 } 500 else if (strncmp(argv[i], "ipmi=", 5) == 0) { 501 set_access.ipmi_messaging = strncmp (argv[i]+5, "off", 3); 502 } 503 else if (strncmp(argv[i], "privilege=", 10) == 0) { 504 if (str2uchar(argv[i]+10, &privilege_limit) != 0) { 505 lprintf(LOG_ERR, "Numeric value expected, but '%s' given.", argv[i]+10); 506 return (-1); 507 } 508 set_access.privilege_limit = privilege_limit; 509 } 510 else { 511 printf ("Invalid option: %s\n", argv [i]); 512 return -1; 513 } 514 } 515 516 memset(&req, 0, sizeof(req)); 517 req.msg.netfn = IPMI_NETFN_APP; 518 req.msg.cmd = IPMI_SET_USER_ACCESS; 519 req.msg.data = (uint8_t *) &set_access; 520 req.msg.data_len = 4; 521 522 rsp = intf->sendrecv(intf, &req); 523 if (rsp == NULL) { 524 lprintf(LOG_ERR, "Unable to Set User Access (channel %d id %d)", 525 set_access.channel, set_access.user_id); 526 return -1; 527 } 528 if (rsp->ccode > 0) { 529 lprintf(LOG_ERR, "Set User Access (channel %d id %d) failed: %s", 530 set_access.channel, set_access.user_id, 531 val2str(rsp->ccode, completion_code_vals)); 532 return -1; 533 } 534 535 return 0; 536 } 537 538 539 static const char * 540 iana_string(uint32_t iana) 541 { 542 static char s[10]; 543 544 if (iana) { 545 sprintf(s, "%06x", iana); 546 return s; 547 } else { 548 return "N/A"; 549 } 550 } 551 552 553 static int 554 ipmi_get_channel_cipher_suites(struct ipmi_intf *intf, const char *payload_type, 555 uint8_t channel) 556 { 557 struct ipmi_rs *rsp; 558 struct ipmi_rq req; 559 560 uint8_t oem_record; 561 uint8_t rqdata[3]; 562 uint32_t iana; 563 uint8_t auth_alg, integrity_alg, crypt_alg; 564 uint8_t cipher_suite_id; 565 uint8_t list_index = 0; 566 /* 0x40 sets * 16 bytes per set */ 567 uint8_t cipher_suite_data[1024]; 568 uint16_t offset = 0; 569 /* how much was returned, total */ 570 uint16_t cipher_suite_data_length = 0; 571 572 memset(cipher_suite_data, 0, sizeof(cipher_suite_data)); 573 574 memset(&req, 0, sizeof(req)); 575 req.msg.netfn = IPMI_NETFN_APP; 576 req.msg.cmd = IPMI_GET_CHANNEL_CIPHER_SUITES; 577 req.msg.data = rqdata; 578 req.msg.data_len = 3; 579 580 rqdata[0] = channel; 581 rqdata[1] = ((strncmp(payload_type, "ipmi", 4) == 0)? 0: 1); 582 /* Always ask for cipher suite format */ 583 rqdata[2] = 0x80; 584 585 rsp = intf->sendrecv(intf, &req); 586 if (rsp == NULL) { 587 lprintf(LOG_ERR, "Unable to Get Channel Cipher Suites"); 588 return -1; 589 } 590 if (rsp->ccode > 0) { 591 lprintf(LOG_ERR, "Get Channel Cipher Suites failed: %s", 592 val2str(rsp->ccode, completion_code_vals)); 593 return -1; 594 } 595 596 597 /* 598 * Grab the returned channel number once. We assume it's the same 599 * in future calls. 600 */ 601 if (rsp->data_len >= 1) { 602 channel = rsp->data[0]; 603 } 604 605 while ((rsp->data_len > 1) && (rsp->data_len == 17) && (list_index < 0x3F)) { 606 /* 607 * We got back cipher suite data -- store it. 608 * printf("copying data to offset %d\n", offset); 609 * printbuf(rsp->data + 1, rsp->data_len - 1, "this is the data"); 610 */ 611 memcpy(cipher_suite_data + offset, rsp->data + 1, rsp->data_len - 1); 612 offset += rsp->data_len - 1; 613 614 /* 615 * Increment our list for the next call 616 */ 617 ++list_index; 618 rqdata[2] = (rqdata[2] & 0x80) + list_index; 619 620 rsp = intf->sendrecv(intf, &req); 621 if (rsp == NULL) { 622 lprintf(LOG_ERR, "Unable to Get Channel Cipher Suites"); 623 return -1; 624 } 625 if (rsp->ccode > 0) { 626 lprintf(LOG_ERR, "Get Channel Cipher Suites failed: %s", 627 val2str(rsp->ccode, completion_code_vals)); 628 return -1; 629 } 630 } 631 632 /* Copy last chunk */ 633 if(rsp->data_len > 1) { 634 /* 635 * We got back cipher suite data -- store it. 636 * printf("copying data to offset %d\n", offset); 637 * printbuf(rsp->data + 1, rsp->data_len - 1, "this is the data"); 638 */ 639 memcpy(cipher_suite_data + offset, rsp->data + 1, rsp->data_len - 1); 640 offset += rsp->data_len - 1; 641 } 642 643 /* We can chomp on all our data now. */ 644 cipher_suite_data_length = offset; 645 offset = 0; 646 647 if (! csv_output) { 648 printf("ID IANA Auth Alg Integrity Alg Confidentiality Alg\n"); 649 } 650 while (offset < cipher_suite_data_length) { 651 if (cipher_suite_data[offset++] == 0xC0) { 652 /* standard type */ 653 oem_record = 0; 654 iana = 0; 655 656 /* Verify that we have at least a full record left; id + 3 algs */ 657 if ((cipher_suite_data_length - offset) < 4) { 658 lprintf(LOG_ERR, "Incomplete data record in cipher suite data"); 659 return -1; 660 } 661 cipher_suite_id = cipher_suite_data[offset++]; 662 } else if (cipher_suite_data[offset++] == 0xC1) { 663 /* OEM record type */ 664 oem_record = 1; 665 666 /* Verify that we have at least a full record left 667 * id + iana + 3 algs 668 */ 669 if ((cipher_suite_data_length - offset) < 4) { 670 lprintf(LOG_ERR, "Incomplete data record in cipher suite data"); 671 return -1; 672 } 673 674 cipher_suite_id = cipher_suite_data[offset++]; 675 676 /* Grab the IANA */ 677 iana = 678 cipher_suite_data[offset] | 679 (cipher_suite_data[offset + 1] << 8) | 680 (cipher_suite_data[offset + 2] << 16); 681 offset += 3; 682 } else { 683 lprintf(LOG_ERR, "Bad start of record byte in cipher suite data"); 684 return -1; 685 } 686 687 /* 688 * Grab the algorithms for this cipher suite. I guess we can't be 689 * sure of what order they'll come in. Also, I suppose we default 690 * to the NONE algorithm if one were absent. This part of the spec is 691 * poorly written -- I have read the errata document. For now, I'm only 692 * allowing one algorithm per type (auth, integrity, crypt) because I 693 * don't I understand how it could be otherwise. 694 */ 695 auth_alg = IPMI_AUTH_RAKP_NONE; 696 integrity_alg = IPMI_INTEGRITY_NONE; 697 crypt_alg = IPMI_CRYPT_NONE; 698 699 while (((cipher_suite_data[offset] & 0xC0) != 0xC0) && 700 ((cipher_suite_data_length - offset) > 0)) 701 { 702 switch (cipher_suite_data[offset] & 0xC0) 703 { 704 case 0x00: 705 /* Authentication algorithm specifier */ 706 auth_alg = cipher_suite_data[offset++] & 0x3F; 707 break; 708 case 0x40: 709 /* Interity algorithm specifier */ 710 integrity_alg = cipher_suite_data[offset++] & 0x3F; 711 break; 712 case 0x80: 713 /* Confidentiality algorithm specifier */ 714 crypt_alg = cipher_suite_data[offset++] & 0x3F; 715 break; 716 } 717 } 718 /* We have everything we need to spit out a cipher suite record */ 719 printf((csv_output? "%d,%s,%s,%s,%s\n" : 720 "%-4d %-7s %-15s %-15s %-15s\n"), 721 cipher_suite_id, 722 iana_string(iana), 723 val2str(auth_alg, ipmi_auth_algorithms), 724 val2str(integrity_alg, ipmi_integrity_algorithms), 725 val2str(crypt_alg, ipmi_encryption_algorithms)); 726 } 727 return 0; 728 } 729 730 731 732 uint8_t 733 ipmi_get_channel_medium(struct ipmi_intf *intf, uint8_t channel) 734 { 735 struct ipmi_rs *rsp; 736 struct ipmi_rq req; 737 struct get_channel_info_rsp info; 738 739 memset(&req, 0, sizeof(req)); 740 req.msg.netfn = IPMI_NETFN_APP; 741 req.msg.cmd = IPMI_GET_CHANNEL_INFO; 742 req.msg.data = &channel; 743 req.msg.data_len = 1; 744 745 rsp = intf->sendrecv(intf, &req); 746 if (rsp == NULL) { 747 lprintf(LOG_ERR, "Get Channel Info command failed"); 748 return 0; 749 } 750 if (rsp->ccode > 0) { 751 if (rsp->ccode == 0xcc) { 752 return IPMI_CHANNEL_MEDIUM_RESERVED; 753 } 754 lprintf(LOG_INFO, "Get Channel Info command failed: %s", 755 val2str(rsp->ccode, completion_code_vals)); 756 return IPMI_CHANNEL_MEDIUM_RESERVED; 757 } 758 759 memcpy(&info, rsp->data, sizeof(struct get_channel_info_rsp)); 760 761 lprintf(LOG_DEBUG, "Channel type: %s", 762 val2str(info.channel_medium, ipmi_channel_medium_vals)); 763 764 return info.channel_medium; 765 } 766 767 uint8_t 768 ipmi_current_channel_medium(struct ipmi_intf *intf) 769 { 770 return ipmi_get_channel_medium(intf, 0xE); 771 } 772 773 void 774 printf_channel_usage() 775 { 776 lprintf(LOG_NOTICE, 777 "Channel Commands: authcap <channel number> <max privilege>"); 778 lprintf(LOG_NOTICE, 779 " getaccess <channel number> [user id]"); 780 lprintf(LOG_NOTICE, 781 " setaccess <channel number> " 782 "<user id> [callin=on|off] [ipmi=on|off] [link=on|off] [privilege=level]"); 783 lprintf(LOG_NOTICE, 784 " info [channel number]"); 785 lprintf(LOG_NOTICE, 786 " getciphers <ipmi | sol> [channel]"); 787 lprintf(LOG_NOTICE, 788 ""); 789 lprintf(LOG_NOTICE, 790 "Possible privilege levels are:"); 791 lprintf(LOG_NOTICE, 792 " 1 Callback level"); 793 lprintf(LOG_NOTICE, 794 " 2 User level"); 795 lprintf(LOG_NOTICE, 796 " 3 Operator level"); 797 lprintf(LOG_NOTICE, 798 " 4 Administrator level"); 799 lprintf(LOG_NOTICE, 800 " 5 OEM Proprietary level"); 801 lprintf(LOG_NOTICE, 802 " 15 No access"); 803 } 804 805 806 int 807 ipmi_channel_main(struct ipmi_intf *intf, int argc, char **argv) 808 { 809 int retval = 0; 810 uint8_t channel; 811 uint8_t priv = 0; 812 if (argc < 1) { 813 lprintf(LOG_ERR, "Not enough parameters given."); 814 printf_channel_usage(); 815 return (-1); 816 } else if (strncmp(argv[0], "help", 4) == 0) { 817 printf_channel_usage(); 818 return 0; 819 } else if (strncmp(argv[0], "authcap", 7) == 0) { 820 if (argc != 3) { 821 printf_channel_usage(); 822 return (-1); 823 } 824 if (is_ipmi_channel_num(argv[1], &channel) != 0 825 || is_ipmi_user_priv_limit(argv[2], &priv) != 0) { 826 return (-1); 827 } 828 retval = ipmi_get_channel_auth_cap(intf, channel, priv); 829 } else if (strncmp(argv[0], "getaccess", 10) == 0) { 830 uint8_t user_id = 0; 831 if ((argc < 2) || (argc > 3)) { 832 printf_channel_usage(); 833 return (-1); 834 } 835 if (is_ipmi_channel_num(argv[1], &channel) != 0) { 836 return (-1); 837 } 838 if (argc == 3) { 839 if (is_ipmi_user_id(argv[2], &user_id) != 0) { 840 return (-1); 841 } 842 } 843 retval = ipmi_get_user_access(intf, channel, user_id); 844 } else if (strncmp(argv[0], "setaccess", 9) == 0) { 845 retval = ipmi_set_user_access(intf, argc-1, &(argv[1])); 846 } else if (strncmp(argv[0], "info", 4) == 0) { 847 channel = 0xE; 848 if (argc > 2) { 849 printf_channel_usage(); 850 return (-1); 851 } 852 if (argc == 2) { 853 if (is_ipmi_channel_num(argv[1], &channel) != 0) { 854 return (-1); 855 } 856 } 857 retval = ipmi_get_channel_info(intf, channel); 858 } else if (strncmp(argv[0], "getciphers", 10) == 0) { 859 /* channel getciphers <ipmi|sol> [channel] */ 860 channel = 0xE; 861 if ((argc < 2) || (argc > 3) || 862 (strncmp(argv[1], "ipmi", 4) && strncmp(argv[1], "sol", 3))) { 863 printf_channel_usage(); 864 return (-1); 865 } 866 if (argc == 3) { 867 if (is_ipmi_channel_num(argv[1], &channel) != 0) { 868 return (-1); 869 } 870 } 871 retval = ipmi_get_channel_cipher_suites(intf, 872 argv[1], /* ipmi | sol */ 873 channel); 874 } else { 875 printf("Invalid CHANNEL command: %s\n", argv[0]); 876 printf_channel_usage(); 877 retval = -1; 878 } 879 return retval; 880 } 881