ipmi_channel.c 26 KB

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