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