int32_t Fiid_obj_get_data(fiid_obj_t obj, char *field, uint8_t *data, uint32_t data_len) { int32_t rv; assert(fiid_obj_valid(obj) && field && data && data_len); if ((rv = fiid_obj_get_data(obj, field, data, data_len)) < 0) ierr_exit("Fiid_obj_get_data: field=%s: %s", field, fiid_strerror(fiid_obj_errnum(obj))); return rv; }
int ipmi_oem_get_system_info_string (ipmi_oem_state_data_t *state_data, uint8_t parameter_selector, uint8_t set_selector, uint8_t block_selector, char *string, unsigned int string_len, unsigned int *string_len_ret) { fiid_obj_t obj_cmd_rs = NULL; uint8_t configuration_parameter_data[IPMI_OEM_MAX_BYTES]; int len; int rv = -1; assert (state_data); assert (string); assert (string_len); if (!(obj_cmd_rs = fiid_obj_create (tmpl_cmd_get_system_info_parameters_rs))) { pstdout_fprintf (state_data->pstate, stderr, "fiid_obj_create: %s\n", strerror (errno)); goto cleanup; } if (ipmi_cmd_get_system_info_parameters (state_data->ipmi_ctx, IPMI_GET_SYSTEM_INFO_PARAMETER, parameter_selector, set_selector, block_selector, obj_cmd_rs) < 0) { if ((ipmi_ctx_errnum (state_data->ipmi_ctx) == IPMI_ERR_BAD_COMPLETION_CODE && ipmi_check_completion_code (obj_cmd_rs, IPMI_COMP_CODE_GET_SYSTEM_INFO_PARAMETERS_PARAMETER_NOT_SUPPORTED) == 1) || (ipmi_ctx_errnum (state_data->ipmi_ctx) == IPMI_ERR_COMMAND_INVALID_OR_UNSUPPORTED && ipmi_check_completion_code (obj_cmd_rs, IPMI_COMP_CODE_INVALID_DATA_FIELD_IN_REQUEST) == 1)) { pstdout_fprintf (state_data->pstate, stderr, "%s:%s '%s' option not supported on this system\n", state_data->prog_data->args->oem_id, state_data->prog_data->args->oem_command, state_data->prog_data->args->oem_options[0]); goto cleanup; } pstdout_fprintf (state_data->pstate, stderr, "ipmi_cmd_get_system_info_parameters: %s\n", ipmi_ctx_errormsg (state_data->ipmi_ctx)); goto cleanup; } if ((len = fiid_obj_get_data (obj_cmd_rs, "configuration_parameter_data", configuration_parameter_data, IPMI_OEM_MAX_BYTES)) < 0) { pstdout_fprintf (state_data->pstate, stderr, "fiid_obj_get_data: 'configuration_parameter_data': %s\n", fiid_obj_errormsg (obj_cmd_rs)); goto cleanup; } if (len > string_len) { pstdout_fprintf (state_data->pstate, stderr, "buffer overflow\n"); goto cleanup; } memcpy (string, &(configuration_parameter_data[0]), len); if (string_len_ret) (*string_len_ret) = len; rv = 0; cleanup: fiid_obj_destroy (obj_cmd_rs); return (rv); }
static config_err_t community_string_checkout (const char *section_name, struct config_keyvalue *kv, void *arg) { ipmi_pef_config_state_data_t *state_data; char community_string[IPMI_MAX_COMMUNITY_STRING_LENGTH+1] = { 0, }; fiid_obj_t obj_cmd_rs = NULL; config_err_t rv = CONFIG_ERR_FATAL_ERROR; config_err_t ret; uint8_t channel_number; assert (section_name); assert (kv); assert (arg); state_data = (ipmi_pef_config_state_data_t *)arg; if (!(obj_cmd_rs = fiid_obj_create (tmpl_cmd_get_lan_configuration_parameters_community_string_rs))) { pstdout_fprintf (state_data->pstate, stderr, "fiid_obj_create: %s\n", strerror (errno)); goto cleanup; } if ((ret = get_lan_channel_number (state_data, section_name, &channel_number)) != CONFIG_ERR_SUCCESS) { rv = ret; goto cleanup; } if (ipmi_cmd_get_lan_configuration_parameters_community_string (state_data->ipmi_ctx, channel_number, IPMI_GET_LAN_PARAMETER, IPMI_PEF_CONFIGURATION_PARAMETERS_NO_SET_SELECTOR, IPMI_PEF_CONFIGURATION_PARAMETERS_NO_BLOCK_SELECTOR, obj_cmd_rs) < 0) { if (state_data->prog_data->args->config_args.common_args.debug) pstdout_fprintf (state_data->pstate, stderr, "ipmi_cmd_get_lan_configuration_parameters_community_string: %s\n", ipmi_ctx_errormsg (state_data->ipmi_ctx)); if (config_is_config_param_non_fatal_error (state_data->ipmi_ctx, obj_cmd_rs, &ret)) rv = ret; goto cleanup; } memset (community_string,'\0', IPMI_MAX_COMMUNITY_STRING_LENGTH+1); if (fiid_obj_get_data (obj_cmd_rs, "community_string", community_string, IPMI_MAX_COMMUNITY_STRING_LENGTH+1) < 0) { pstdout_fprintf (state_data->pstate, stderr, "fiid_obj_get_data: 'obj_cmd_rs': %s\n", fiid_obj_errormsg (obj_cmd_rs)); goto cleanup; } if (config_section_update_keyvalue_output (state_data->pstate, kv, community_string) < 0) return (CONFIG_ERR_FATAL_ERROR); rv = CONFIG_ERR_SUCCESS; cleanup: fiid_obj_destroy (obj_cmd_rs); return (rv); }
int ipmiconsole_check_rakp_4_integrity_check_value (ipmiconsole_ctx_t c, ipmiconsole_packet_type_t p) { uint8_t managed_system_guid[IPMI_MANAGED_SYSTEM_GUID_LENGTH]; int managed_system_guid_len; uint32_t managed_system_session_id; uint8_t authentication_algorithm = 0; uint64_t val; int rv; assert (c); assert (c->magic == IPMICONSOLE_CTX_MAGIC); assert (p == IPMICONSOLE_PACKET_TYPE_RAKP_MESSAGE_4); /* IPMI Workaround * * Intel IPMI 2.0 implementations respond with the integrity check * value based on the integrity algorithm rather than the * authentication algorithm. */ if (c->config.workaround_flags & IPMICONSOLE_WORKAROUND_INTEL_2_0_SESSION) { if (c->config.integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_NONE) authentication_algorithm = IPMI_AUTHENTICATION_ALGORITHM_RAKP_NONE; else if (c->config.integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_HMAC_SHA1_96) authentication_algorithm = IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA1; else if (c->config.integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_HMAC_MD5_128) authentication_algorithm = IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5; else if (c->config.integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_MD5_128) { /* achu: I have thus far been unable to reverse engineer this * corner case. Since we cannot provide a reasonable two * part authentication, we're going to error out. */ IPMICONSOLE_CTX_DEBUG (c, ("Intel Non-Compliance: Cannot Reverse Engineer")); ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_BMC_ERROR); return (0); } } else authentication_algorithm = c->config.authentication_algorithm; if (FIID_OBJ_GET (c->connection.obj_open_session_response, "managed_system_session_id", &val) < 0) { IPMICONSOLE_CTX_DEBUG (c, ("FIID_OBJ_GET: 'managed_system_session_id': %s", fiid_obj_errormsg (c->connection.obj_open_session_response))); ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR); return (-1); } managed_system_session_id = val; if ((managed_system_guid_len = fiid_obj_get_data (c->connection.obj_rakp_message_2, "managed_system_guid", managed_system_guid, IPMI_MANAGED_SYSTEM_RANDOM_NUMBER_LENGTH)) < 0) { IPMICONSOLE_CTX_DEBUG (c, ("fiid_obj_get_data: 'managed_system_guid': %s", fiid_obj_errormsg (c->connection.obj_rakp_message_2))); ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR); return (-1); } if (managed_system_guid_len != IPMI_MANAGED_SYSTEM_GUID_LENGTH) { IPMICONSOLE_CTX_DEBUG (c, ("fiid_obj_get_data: invalid managed system guid length: %d", managed_system_guid_len)); ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR); return (-1); } /* IPMI Workaround (achu) * * Discovered on Supermicro X8DTG, Supermicro X8DTU, Intel * S5500WBV/Penguin Relion 700 * * For whatever reason, with cipher suite 0, the RAKP 4 response * returns with an Integrity Check Value when it should be empty. */ if (c->config.workaround_flags & IPMICONSOLE_WORKAROUND_NON_EMPTY_INTEGRITY_CHECK_VALUE && !c->config.cipher_suite_id) { if (fiid_obj_clear_field (c->connection.obj_rakp_message_4, "integrity_check_value") < 0) { IPMICONSOLE_CTX_DEBUG (c, ("fiid_obj_clear_field: 'integrity_check_value': %s", fiid_obj_errormsg (c->connection.obj_rakp_message_4))); ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR); return (-1); } } if ((rv = ipmi_rmcpplus_check_rakp_4_integrity_check_value (authentication_algorithm, c->session.sik_key_ptr, c->session.sik_key_len, c->session.remote_console_random_number, IPMI_REMOTE_CONSOLE_RANDOM_NUMBER_LENGTH, managed_system_session_id, managed_system_guid, managed_system_guid_len, c->connection.obj_rakp_message_4)) < 0) { IPMICONSOLE_CTX_DEBUG (c, ("ipmi_rmcpplus_check_rakp_4_integrity_check_value: p = %d; %s", p, strerror (errno))); ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR); return (-1); } if (!rv) IPMICONSOLE_CTX_DEBUG (c, ("rakp 4 integrity check value check failed; p = %d", p)); return (rv); }
int assemble_ipmi_lan_pkt (fiid_obj_t obj_rmcp_hdr, fiid_obj_t obj_lan_session_hdr, fiid_obj_t obj_lan_msg_hdr, fiid_obj_t obj_cmd, const void *authentication_code_data, unsigned int authentication_code_data_len, void *pkt, unsigned int pkt_len, unsigned int flags) { uint8_t authentication_type; uint64_t val; unsigned int indx = 0; int required_len; void *authentication_code_field_ptr = NULL; void *checksum_data_ptr = NULL; void *msg_data_ptr = NULL; void *ipmi_msg_len_ptr = NULL; unsigned int msg_data_count = 0; unsigned int checksum_data_count = 0; uint8_t ipmi_msg_len; fiid_obj_t obj_lan_msg_trlr = NULL; uint8_t pwbuf[IPMI_1_5_MAX_PASSWORD_LENGTH]; uint8_t checksum; int len, rv = -1; unsigned int flags_mask = 0; if (!fiid_obj_valid (obj_rmcp_hdr) || !fiid_obj_valid (obj_lan_session_hdr) || !fiid_obj_valid (obj_lan_msg_hdr) || !fiid_obj_valid (obj_cmd) || (authentication_code_data && authentication_code_data_len > IPMI_1_5_MAX_PASSWORD_LENGTH) || !pkt || (flags & ~flags_mask)) { SET_ERRNO (EINVAL); return (-1); } if (FIID_OBJ_TEMPLATE_COMPARE (obj_rmcp_hdr, tmpl_rmcp_hdr) < 0) { ERRNO_TRACE (errno); return (-1); } if (FIID_OBJ_TEMPLATE_COMPARE (obj_lan_session_hdr, tmpl_lan_session_hdr) < 0) { ERRNO_TRACE (errno); return (-1); } if (FIID_OBJ_TEMPLATE_COMPARE (obj_lan_msg_hdr, tmpl_lan_msg_hdr_rq) < 0) { ERRNO_TRACE (errno); return (-1); } if (FIID_OBJ_PACKET_VALID (obj_rmcp_hdr) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcp_hdr); return (-1); } /* * ipmi_msg_len is calculated in this function, so we can't use * fiid_obj_packet_valid() on obj_lan_session_hdr b/c ipmi_msg_len * is probably not set yet. */ if (FIID_OBJ_PACKET_VALID (obj_lan_msg_hdr) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_msg_hdr); return (-1); } if (FIID_OBJ_PACKET_VALID (obj_cmd) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd); return (-1); } if (FIID_OBJ_GET (obj_lan_session_hdr, "authentication_type", &val) < 0) { ERRNO_TRACE (errno); return (-1); } authentication_type = val; if (authentication_type != IPMI_AUTHENTICATION_TYPE_NONE && authentication_type != IPMI_AUTHENTICATION_TYPE_MD2 && authentication_type != IPMI_AUTHENTICATION_TYPE_MD5 && authentication_type != IPMI_AUTHENTICATION_TYPE_STRAIGHT_PASSWORD_KEY) { SET_ERRNO (EINVAL); return (-1); } /* no need for overflow checks, handled w/ _ipmi_lan_pkt_rq_min_size check */ required_len = _ipmi_lan_pkt_rq_min_size (authentication_type, obj_cmd); if (pkt_len < required_len) { SET_ERRNO (EMSGSIZE); return (-1); } memset (pkt, 0, pkt_len); if ((len = fiid_obj_get_all (obj_rmcp_hdr, pkt + indx, pkt_len - indx)) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcp_hdr); goto cleanup; } indx += len; if ((len = fiid_obj_get_block (obj_lan_session_hdr, "authentication_type", "session_id", pkt + indx, pkt_len - indx)) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_session_hdr); goto cleanup; } indx += len; /* authentication_code generated last. Save pointers for later calculation */ if (authentication_type != IPMI_AUTHENTICATION_TYPE_NONE) { authentication_code_field_ptr = (pkt + indx); indx += IPMI_1_5_MAX_PASSWORD_LENGTH; } ipmi_msg_len_ptr = (pkt + indx); if ((len = fiid_template_field_len_bytes (tmpl_lan_session_hdr, "ipmi_msg_len")) < 0) { ERRNO_TRACE (errno); goto cleanup; } if (len != 1) { SET_ERRNO (EINVAL); goto cleanup; } indx += len; msg_data_ptr = (pkt + indx); if ((len = fiid_obj_get_block (obj_lan_msg_hdr, "rs_addr", "checksum1", pkt + indx, pkt_len - indx)) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_msg_hdr); goto cleanup; } indx += len; msg_data_count += len; checksum_data_ptr = (pkt + indx); if ((len = fiid_obj_get_block (obj_lan_msg_hdr, "rq_addr", "rq_seq", pkt + indx, pkt_len - indx)) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_msg_hdr); goto cleanup; } indx += len; msg_data_count += len; checksum_data_count += len; if ((len = fiid_obj_get_all (obj_cmd, pkt + indx, pkt_len - indx)) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd); goto cleanup; } indx += len; msg_data_count += len; checksum_data_count += len; if (!(obj_lan_msg_trlr = fiid_obj_create (tmpl_lan_msg_trlr))) { ERRNO_TRACE (errno); goto cleanup; } checksum = ipmi_checksum (checksum_data_ptr, checksum_data_count); if (fiid_obj_set_all (obj_lan_msg_trlr, &checksum, sizeof (checksum)) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_msg_trlr); goto cleanup; } if ((len = fiid_obj_get_all (obj_lan_msg_trlr, pkt + indx, pkt_len - indx)) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_msg_trlr); goto cleanup; } indx += len; msg_data_count += len; /* ipmi_msg_len done after message length is computed */ ipmi_msg_len = msg_data_count; memcpy (ipmi_msg_len_ptr, &ipmi_msg_len, sizeof (ipmi_msg_len)); /* Auth code must be done last, some authentication like md2 and md5 * require all fields, including checksums, to be calculated * beforehand */ if (authentication_type != IPMI_AUTHENTICATION_TYPE_NONE) { int authentication_len; memset (pwbuf, '\0', IPMI_1_5_MAX_PASSWORD_LENGTH); if ((authentication_len = fiid_obj_field_len_bytes (obj_lan_session_hdr, "authentication_code")) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_session_hdr); goto cleanup; } if (authentication_len) { if (fiid_obj_get_data (obj_lan_session_hdr, "authentication_code", pwbuf, IPMI_1_5_MAX_PASSWORD_LENGTH) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_session_hdr); goto cleanup; } memcpy (authentication_code_field_ptr, pwbuf, IPMI_1_5_MAX_PASSWORD_LENGTH); } else { if (authentication_code_data) memcpy (pwbuf, authentication_code_data, authentication_code_data_len); if (authentication_type == IPMI_AUTHENTICATION_TYPE_STRAIGHT_PASSWORD_KEY) { memcpy (authentication_code_field_ptr, pwbuf, IPMI_1_5_MAX_PASSWORD_LENGTH); } else /* IPMI_AUTHENTICATION_TYPE_MD2 || IPMI_AUTHENTICATION_TYPE_MD5 */ { uint8_t session_id_buf[1024]; uint8_t session_sequence_number_buf[1024]; int session_id_len, session_sequence_number_len; if ((session_id_len = fiid_obj_get_data (obj_lan_session_hdr, "session_id", session_id_buf, 1024)) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_session_hdr); goto cleanup; } if ((session_sequence_number_len = fiid_obj_get_data (obj_lan_session_hdr, "session_sequence_number", session_sequence_number_buf, 1024)) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_session_hdr); goto cleanup; } if (authentication_type == IPMI_AUTHENTICATION_TYPE_MD2) { md2_t ctx; uint8_t digest[MD2_DIGEST_LENGTH]; assert (IPMI_1_5_MAX_PASSWORD_LENGTH == MD2_DIGEST_LENGTH); md2_init (&ctx); md2_update_data (&ctx, pwbuf, IPMI_1_5_MAX_PASSWORD_LENGTH); md2_update_data (&ctx, session_id_buf, session_id_len); md2_update_data (&ctx, msg_data_ptr, msg_data_count); md2_update_data (&ctx, session_sequence_number_buf, session_sequence_number_len); md2_update_data (&ctx, pwbuf, IPMI_1_5_MAX_PASSWORD_LENGTH); md2_finish (&ctx, digest, MD2_DIGEST_LENGTH); md2_init (&ctx); memcpy (authentication_code_field_ptr, digest, IPMI_1_5_MAX_PASSWORD_LENGTH); secure_memset (digest, '\0', MD2_DIGEST_LENGTH); } else if (authentication_type == IPMI_AUTHENTICATION_TYPE_MD5) { md5_t ctx; uint8_t digest[MD5_DIGEST_LENGTH]; assert (IPMI_1_5_MAX_PASSWORD_LENGTH == MD5_DIGEST_LENGTH); md5_init (&ctx); md5_update_data (&ctx, pwbuf, IPMI_1_5_MAX_PASSWORD_LENGTH); md5_update_data (&ctx, session_id_buf, session_id_len); md5_update_data (&ctx, msg_data_ptr, msg_data_count); md5_update_data (&ctx, session_sequence_number_buf, session_sequence_number_len); md5_update_data (&ctx, pwbuf, IPMI_1_5_MAX_PASSWORD_LENGTH); md5_finish (&ctx, digest, MD5_DIGEST_LENGTH); md5_init (&ctx); memcpy (authentication_code_field_ptr, digest, IPMI_1_5_MAX_PASSWORD_LENGTH); secure_memset (digest, '\0', MD5_DIGEST_LENGTH); } } } } if (indx > INT_MAX) { SET_ERRNO (EMSGSIZE); goto cleanup; } rv = indx; cleanup: if (rv < 0) secure_memset (pkt, '\0', pkt_len); fiid_obj_destroy (obj_lan_msg_trlr); secure_memset (pwbuf, '\0', IPMI_1_5_MAX_PASSWORD_LENGTH); return (rv); }
int ipmiconsole_check_rakp_2_key_exchange_authentication_code (ipmiconsole_ctx_t c, ipmiconsole_packet_type_t p) { uint8_t managed_system_random_number[IPMI_MANAGED_SYSTEM_RANDOM_NUMBER_LENGTH]; int managed_system_random_number_len; uint8_t managed_system_guid[IPMI_MANAGED_SYSTEM_GUID_LENGTH]; int managed_system_guid_len; char username_buf[IPMI_MAX_USER_NAME_LENGTH+1]; char *username; unsigned int username_len; char *password; unsigned int password_len; uint32_t managed_system_session_id; uint64_t val; int rv; assert (c); assert (c->magic == IPMICONSOLE_CTX_MAGIC); assert (p == IPMICONSOLE_PACKET_TYPE_RAKP_MESSAGE_2); /* IPMI Workaround * * Intel IPMI 2.0 implementations pad their usernames. */ if (c->config.workaround_flags & IPMICONSOLE_WORKAROUND_INTEL_2_0_SESSION) { memset (username_buf, '\0', IPMI_MAX_USER_NAME_LENGTH+1); if (strlen (c->config.username)) strcpy (username_buf, c->config.username); username = username_buf; username_len = IPMI_MAX_USER_NAME_LENGTH; } else { if (strlen (c->config.username)) username = c->config.username; else username = NULL; username_len = (username) ? strlen (username) : 0; } /* IPMI Workaround * * Supermicro IPMI 2.0 implementations may have invalid payload lengths * on the RAKP response packet. */ if (c->config.workaround_flags & IPMICONSOLE_WORKAROUND_SUPERMICRO_2_0_SESSION) { uint8_t keybuf[IPMICONSOLE_PACKET_BUFLEN]; int keybuf_len; if ((keybuf_len = fiid_obj_get_data (c->connection.obj_rakp_message_2, "key_exchange_authentication_code", keybuf, IPMICONSOLE_PACKET_BUFLEN)) < 0) { IPMICONSOLE_CTX_DEBUG (c, ("fiid_obj_get_data: 'key_exchange_authentication_code': %s", fiid_obj_errormsg (c->connection.obj_rakp_message_2))); ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR); return (-1); } if (c->config.authentication_algorithm == IPMI_AUTHENTICATION_ALGORITHM_RAKP_NONE && keybuf_len == 1) { if (fiid_obj_clear_field (c->connection.obj_rakp_message_2, "key_exchange_authentication_code") < 0) { IPMICONSOLE_CTX_DEBUG (c, ("fiid_obj_clear_field: 'key_exchange_authentication_code': %s", fiid_obj_errormsg (c->connection.obj_rakp_message_2))); ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR); return (-1); } } else if (c->config.authentication_algorithm == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA1 && keybuf_len == (IPMI_HMAC_SHA1_DIGEST_LENGTH + 1)) { if (fiid_obj_set_data (c->connection.obj_rakp_message_2, "key_exchange_authentication_code", keybuf, IPMI_HMAC_SHA1_DIGEST_LENGTH) < 0) { IPMICONSOLE_CTX_DEBUG (c, ("fiid_obj_set_data: 'key_exchange_authentication_code': %s", fiid_obj_errormsg (c->connection.obj_rakp_message_2))); ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR); return (-1); } } else if (c->config.authentication_algorithm == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5 && keybuf_len == (IPMI_HMAC_MD5_DIGEST_LENGTH + 1)) { if (fiid_obj_set_data (c->connection.obj_rakp_message_2, "key_exchange_authentication_code", keybuf, IPMI_HMAC_MD5_DIGEST_LENGTH) < 0) { IPMICONSOLE_CTX_DEBUG (c, ("fiid_obj_set_data: 'key_exchange_authentication_code': %s", fiid_obj_errormsg (c->connection.obj_rakp_message_2))); ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR); return (-1); } } } if (strlen (c->config.password)) password = c->config.password; else password = NULL; password_len = (password) ? strlen (password) : 0; /* IPMI Workaround * * Intel IPMI 2.0 implementations improperly calculate HMAC-MD5-128 hashes * when the passwords are > 16 bytes long. The BMCs probably assume * all keys are <= 16 bytes in length. So we have to adjust. */ if (c->config.workaround_flags & IPMICONSOLE_WORKAROUND_INTEL_2_0_SESSION && c->config.authentication_algorithm == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5 && password_len > IPMI_1_5_MAX_PASSWORD_LENGTH) password_len = IPMI_1_5_MAX_PASSWORD_LENGTH; /* IPMI Workaround * * Discovered on Sun Fire 4100. * * The key exchange authentication code is the wrong length. We * need to shorten it. */ if (c->config.workaround_flags & IPMICONSOLE_WORKAROUND_SUN_2_0_SESSION && c->config.authentication_algorithm == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA1) { uint8_t buf[IPMI_MAX_KEY_EXCHANGE_AUTHENTICATION_CODE_LENGTH]; int buf_len; /* trace, but do not return potential error */ if ((buf_len = fiid_obj_get_data (c->connection.obj_rakp_message_2, "key_exchange_authentication_code", buf, IPMI_MAX_KEY_EXCHANGE_AUTHENTICATION_CODE_LENGTH)) < 0) IPMICONSOLE_CTX_DEBUG (c, ("fiid_obj_get_data: 'key_exchange_authentication_code': %s", fiid_obj_errormsg (c->connection.obj_rakp_message_2))); if (buf_len == (IPMI_HMAC_SHA1_DIGEST_LENGTH + 1)) { /* trace, but do not return potential error */ if (fiid_obj_clear_field (c->connection.obj_rakp_message_2, "key_exchange_authentication_code") < 0) IPMICONSOLE_CTX_DEBUG (c, ("fiid_obj_clear_field: 'key_exchange_authentication_code': %s", fiid_obj_errormsg (c->connection.obj_rakp_message_2))); if (fiid_obj_set_data (c->connection.obj_rakp_message_2, "key_exchange_authentication_code", buf, IPMI_HMAC_SHA1_DIGEST_LENGTH) < 0) IPMICONSOLE_CTX_DEBUG (c, ("fiid_obj_set_data: 'key_exchange_authentication_code': %s", fiid_obj_errormsg (c->connection.obj_rakp_message_2))); } } if (FIID_OBJ_GET (c->connection.obj_open_session_response, "managed_system_session_id", &val) < 0) { IPMICONSOLE_CTX_DEBUG (c, ("FIID_OBJ_GET: 'managed_system_session_id': %s", fiid_obj_errormsg (c->connection.obj_open_session_response))); ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR); return (-1); } managed_system_session_id = val; if ((managed_system_random_number_len = fiid_obj_get_data (c->connection.obj_rakp_message_2, "managed_system_random_number", managed_system_random_number, IPMI_MANAGED_SYSTEM_RANDOM_NUMBER_LENGTH)) < 0) { IPMICONSOLE_CTX_DEBUG (c, ("fiid_obj_get_data: 'managed_system_random_number': %s", fiid_obj_errormsg (c->connection.obj_rakp_message_2))); ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR); return (-1); } if (managed_system_random_number_len != IPMI_MANAGED_SYSTEM_RANDOM_NUMBER_LENGTH) { IPMICONSOLE_CTX_DEBUG (c, ("fiid_obj_get_data: invalid managed system random number length: %d", managed_system_random_number_len)); ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR); return (-1); } if ((managed_system_guid_len = fiid_obj_get_data (c->connection.obj_rakp_message_2, "managed_system_guid", managed_system_guid, IPMI_MANAGED_SYSTEM_GUID_LENGTH)) < 0) { IPMICONSOLE_CTX_DEBUG (c, ("fiid_obj_get_data: 'managed_system_guid': %s", fiid_obj_errormsg (c->connection.obj_rakp_message_2))); ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR); return (-1); } if (managed_system_guid_len != IPMI_MANAGED_SYSTEM_GUID_LENGTH) { IPMICONSOLE_CTX_DEBUG (c, ("fiid_obj_get_data: invalid managed system guid length: %d", managed_system_guid_len)); ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR); return (-1); } if ((rv = ipmi_rmcpplus_check_rakp_2_key_exchange_authentication_code (c->config.authentication_algorithm, password, password_len, c->session.remote_console_session_id, managed_system_session_id, c->session.remote_console_random_number, IPMI_REMOTE_CONSOLE_RANDOM_NUMBER_LENGTH, managed_system_random_number, managed_system_random_number_len, managed_system_guid, managed_system_guid_len, c->session.name_only_lookup, c->config.privilege_level, username, username_len, c->connection.obj_rakp_message_2)) < 0) { IPMICONSOLE_CTX_DEBUG (c, ("ipmi_rmcpplus_check_rakp_2_key_exchange_authentication_code: p = %d; %s", p, strerror (errno))); ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR); return (-1); } if (!rv) IPMICONSOLE_CTX_DEBUG (c, ("rakp 2 key exchanged authentication code check failed; p = %d", p)); return (rv); }
static int _sdr_cache_get_record (ipmi_sdr_ctx_t ctx, ipmi_ctx_t ipmi_ctx, uint16_t record_id, void *record_buf, unsigned int record_buf_len, uint16_t *reservation_id, uint16_t *next_record_id) { fiid_obj_t obj_cmd_rs = NULL; fiid_obj_t obj_sdr_record_header = NULL; int sdr_record_header_length = 0; int sdr_record_len = 0; unsigned int record_length = 0; int rv = -1; unsigned int bytes_to_read = IPMI_SDR_CACHE_BYTES_TO_READ_START; unsigned int offset_into_record = 0; unsigned int reservation_id_retry_count = 0; uint8_t temp_record_buf[IPMI_SDR_MAX_RECORD_LENGTH]; uint64_t val; assert (ctx); assert (ctx->magic == IPMI_SDR_CTX_MAGIC); assert (ipmi_ctx); assert (record_buf); assert (record_buf_len); assert (reservation_id); assert (next_record_id); if (!(obj_cmd_rs = fiid_obj_create (tmpl_cmd_get_sdr_rs))) { SDR_ERRNO_TO_SDR_ERRNUM (ctx, errno); goto cleanup; } if (!(obj_sdr_record_header = fiid_obj_create (tmpl_sdr_record_header))) { SDR_ERRNO_TO_SDR_ERRNUM (ctx, errno); goto cleanup; } if ((sdr_record_header_length = fiid_template_len_bytes (tmpl_sdr_record_header)) < 0) { SDR_ERRNO_TO_SDR_ERRNUM (ctx, errno); goto cleanup; } /* achu: * * Many motherboards now allow you to read the full SDR record, try * that first. If it fails for any reason, bail and try to read via * partial reads. */ reservation_id_retry_count = 0; while (!offset_into_record) { if (ipmi_cmd_get_sdr (ipmi_ctx, *reservation_id, record_id, 0, IPMI_SDR_READ_ENTIRE_RECORD_BYTES_TO_READ, obj_cmd_rs) < 0) { if (ipmi_ctx_errnum (ipmi_ctx) == IPMI_ERR_BAD_COMPLETION_CODE) { uint8_t comp_code; if (FIID_OBJ_GET (obj_cmd_rs, "comp_code", &val) < 0) { SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_cmd_rs); goto cleanup; } comp_code = val; if (comp_code == IPMI_COMP_CODE_RESERVATION_CANCELLED && (reservation_id_retry_count < IPMI_SDR_CACHE_MAX_RESERVATION_ID_RETRY)) { if (_sdr_cache_reservation_id (ctx, ipmi_ctx, reservation_id) < 0) goto cleanup; reservation_id_retry_count++; continue; } } goto partial_read; } if ((sdr_record_len = fiid_obj_get_data (obj_cmd_rs, "record_data", temp_record_buf, IPMI_SDR_MAX_RECORD_LENGTH)) < 0) { SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_cmd_rs); goto cleanup; } /* Assume this is an "IPMI Error", fall through to partial reads */ if (sdr_record_len < sdr_record_header_length) goto partial_read; /* * IPMI Workaround (achu) * * Discovered on Xyratex HB-F8-SRAY * * For some reason reading the entire SDR record (with * IPMI_SDR_READ_ENTIRE_RECORD_BYTES_TO_READ) the response * returns fewer bytes than the actual length of the record. * However, when reading with partial reads things ultimately * succeed. If we notice the length is off, we fall out and do * a partial read. */ if ((((uint8_t)temp_record_buf[IPMI_SDR_RECORD_LENGTH_INDEX]) + IPMI_SDR_RECORD_HEADER_LENGTH) > sdr_record_len) goto partial_read; if (sdr_record_len > record_buf_len) { SDR_SET_ERRNUM (ctx, IPMI_SDR_ERR_INTERNAL_ERROR); goto cleanup; } if (FIID_OBJ_GET (obj_cmd_rs, "next_record_id", &val) < 0) { SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_cmd_rs); goto cleanup; } *next_record_id = val; memcpy (record_buf, temp_record_buf, sdr_record_len); offset_into_record += sdr_record_len; goto out; } partial_read: reservation_id_retry_count = 0; while (!record_length) { uint8_t record_header_buf[IPMI_SDR_MAX_RECORD_LENGTH]; int sdr_record_header_len; if (ipmi_cmd_get_sdr (ipmi_ctx, *reservation_id, record_id, 0, sdr_record_header_length, obj_cmd_rs) < 0) { if (ipmi_ctx_errnum (ipmi_ctx) != IPMI_ERR_BAD_COMPLETION_CODE) { SDR_SET_ERRNUM (ctx, IPMI_SDR_ERR_IPMI_ERROR); goto cleanup; } else { uint8_t comp_code; if (FIID_OBJ_GET (obj_cmd_rs, "comp_code", &val) < 0) { SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_cmd_rs); goto cleanup; } comp_code = val; if (comp_code == IPMI_COMP_CODE_RESERVATION_CANCELLED && (reservation_id_retry_count < IPMI_SDR_CACHE_MAX_RESERVATION_ID_RETRY)) { if (_sdr_cache_reservation_id (ctx, ipmi_ctx, reservation_id) < 0) goto cleanup; reservation_id_retry_count++; continue; } SDR_SET_ERRNUM (ctx, IPMI_SDR_ERR_IPMI_ERROR); goto cleanup; } } if ((sdr_record_header_len = fiid_obj_get_data (obj_cmd_rs, "record_data", record_header_buf, IPMI_SDR_MAX_RECORD_LENGTH)) < 0) { SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_cmd_rs); goto cleanup; } if (sdr_record_header_len < sdr_record_header_length) { SDR_SET_ERRNUM (ctx, IPMI_SDR_ERR_IPMI_ERROR); goto cleanup; } if (fiid_obj_set_all (obj_sdr_record_header, record_header_buf, sdr_record_header_len) < 0) { SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_header); goto cleanup; } if (FIID_OBJ_GET (obj_sdr_record_header, "record_length", &val) < 0) { SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_header); goto cleanup; } if (sdr_record_header_len > record_buf_len) { SDR_SET_ERRNUM (ctx, IPMI_SDR_ERR_INTERNAL_ERROR); goto cleanup; } /* copy header into buf */ memcpy (record_buf, record_header_buf, sdr_record_header_len); offset_into_record += sdr_record_header_len; record_length = val + sdr_record_header_length; } if (record_length > record_buf_len) { SDR_SET_ERRNUM (ctx, IPMI_SDR_ERR_INTERNAL_ERROR); goto cleanup; } if (FIID_OBJ_GET (obj_cmd_rs, "next_record_id", &val) < 0) { SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_cmd_rs); goto cleanup; } *next_record_id = val; reservation_id_retry_count = 0; while (offset_into_record < record_length) { int record_data_len; if ((record_length - offset_into_record) < bytes_to_read) bytes_to_read = record_length - offset_into_record; if (ipmi_cmd_get_sdr (ipmi_ctx, *reservation_id, record_id, offset_into_record, bytes_to_read, obj_cmd_rs) < 0) { if (ipmi_ctx_errnum (ipmi_ctx) != IPMI_ERR_BAD_COMPLETION_CODE) { SDR_SET_ERRNUM (ctx, IPMI_SDR_ERR_IPMI_ERROR); goto cleanup; } else { uint8_t comp_code; if (FIID_OBJ_GET (obj_cmd_rs, "comp_code", &val) < 0) { SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_cmd_rs); goto cleanup; } comp_code = val; if (comp_code == IPMI_COMP_CODE_RESERVATION_CANCELLED && (reservation_id_retry_count < IPMI_SDR_CACHE_MAX_RESERVATION_ID_RETRY)) { if (_sdr_cache_reservation_id (ctx, ipmi_ctx, reservation_id) < 0) goto cleanup; reservation_id_retry_count++; continue; } else if ((comp_code == IPMI_COMP_CODE_CANNOT_RETURN_REQUESTED_NUMBER_OF_BYTES || comp_code == IPMI_COMP_CODE_UNSPECIFIED_ERROR) && bytes_to_read > sdr_record_header_length) { bytes_to_read -= IPMI_SDR_CACHE_BYTES_TO_READ_DECREMENT; if (bytes_to_read < sdr_record_header_length) bytes_to_read = sdr_record_header_length; continue; } SDR_SET_ERRNUM (ctx, IPMI_SDR_ERR_IPMI_ERROR); goto cleanup; } } if ((record_data_len = fiid_obj_get_data (obj_cmd_rs, "record_data", record_buf + offset_into_record, record_buf_len - offset_into_record)) < 0) { SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_cmd_rs); goto cleanup; } offset_into_record += record_data_len; } out: rv = offset_into_record; cleanup: fiid_obj_destroy (obj_cmd_rs); fiid_obj_destroy (obj_sdr_record_header); return (rv); }
static int _api_ssif_ipmb_recv (ipmi_ctx_t ctx, fiid_obj_t obj_ipmb_msg_hdr_rs, fiid_obj_t obj_ipmb_msg_trlr, fiid_obj_t obj_cmd_rs) { struct ipmi_ctx_target target_save; uint8_t buf[IPMI_MAX_PKT_LEN]; fiid_obj_t obj_ipmb_msg_rs = NULL; fiid_obj_t obj_get_cmd_rs = NULL; int len, ret, rv = -1; unsigned int intf_flags = IPMI_INTERFACE_FLAGS_DEFAULT; assert (ctx && ctx->magic == IPMI_CTX_MAGIC && ctx->type == IPMI_DEVICE_SSIF && fiid_obj_valid (obj_ipmb_msg_hdr_rs) && fiid_obj_valid (obj_ipmb_msg_trlr) && fiid_obj_valid (obj_cmd_rs)); if (ctx->flags & IPMI_FLAGS_NO_LEGAL_CHECK) intf_flags |= IPMI_INTERFACE_FLAGS_NO_LEGAL_CHECK; if (!(obj_ipmb_msg_rs = fiid_obj_create (tmpl_ipmb_msg))) { API_ERRNO_TO_API_ERRNUM (ctx, errno); goto cleanup; } if (!(obj_get_cmd_rs = fiid_obj_create (tmpl_cmd_get_message_rs))) { API_ERRNO_TO_API_ERRNUM (ctx, errno); goto cleanup; } /* get_message will send to the BMC, so clear out target information */ memcpy (&target_save, &ctx->target, sizeof (target_save)); ctx->target.channel_number_is_set = 0; ctx->target.rs_addr_is_set = 0; ret = ipmi_cmd_get_message (ctx, obj_get_cmd_rs); /* restore target info */ memcpy (&ctx->target, &target_save, sizeof (target_save)); if (ret < 0) { if (ipmi_check_completion_code (obj_get_cmd_rs, IPMI_COMP_CODE_GET_MESSAGE_DATA_NOT_AVAILABLE) == 1) API_SET_ERRNUM (ctx, IPMI_ERR_MESSAGE_TIMEOUT); else API_BAD_RESPONSE_TO_API_ERRNUM (ctx, obj_get_cmd_rs); goto cleanup; } if ((len = fiid_obj_get_data (obj_get_cmd_rs, "message_data", buf, IPMI_MAX_PKT_LEN)) < 0) { API_FIID_OBJECT_ERROR_TO_API_ERRNUM (ctx, obj_get_cmd_rs); goto cleanup; } if (fiid_obj_set_all (obj_ipmb_msg_rs, buf, len) < 0) { API_FIID_OBJECT_ERROR_TO_API_ERRNUM (ctx, obj_ipmb_msg_rs); goto cleanup; } if (unassemble_ipmi_ipmb_msg (obj_ipmb_msg_rs, obj_ipmb_msg_hdr_rs, obj_cmd_rs, obj_ipmb_msg_trlr, intf_flags) < 0) { API_ERRNO_TO_API_ERRNUM (ctx, errno); goto cleanup; } rv = 0; cleanup: fiid_obj_destroy (obj_ipmb_msg_rs); fiid_obj_destroy (obj_get_cmd_rs); return (rv); }
static ipmi_config_err_t _get_key (ipmi_config_state_data_t *state_data, const char *section_name, uint8_t key_type, void *key, unsigned int key_len) { fiid_obj_t obj_cmd_rs = NULL; uint8_t buf[IPMI_CONFIG_PARSE_BUFLEN]; int buf_len; ipmi_config_err_t rv = IPMI_CONFIG_ERR_FATAL_ERROR; ipmi_config_err_t ret; uint8_t channel_number; assert (state_data); assert (section_name); assert (key_type == IPMI_CHANNEL_SECURITY_KEYS_KEY_ID_K_R || key_type == IPMI_CHANNEL_SECURITY_KEYS_KEY_ID_K_G); assert (key); assert (key_len); if (!(obj_cmd_rs = fiid_obj_create (tmpl_cmd_set_channel_security_keys_rs))) { pstdout_fprintf (state_data->pstate, stderr, "fiid_obj_create: %s\n", strerror (errno)); goto cleanup; } if ((ret = get_lan_channel_number (state_data, section_name, &channel_number)) != IPMI_CONFIG_ERR_SUCCESS) { rv = ret; goto cleanup; } if (ipmi_cmd_set_channel_security_keys (state_data->ipmi_ctx, channel_number, IPMI_CHANNEL_SECURITY_KEYS_OPERATION_READ_KEY, key_type, NULL, 0, obj_cmd_rs) < 0) { if (!IPMI_CTX_ERRNUM_IS_FATAL_ERROR (state_data->ipmi_ctx)) rv = IPMI_CONFIG_ERR_NON_FATAL_ERROR; if (rv == IPMI_CONFIG_ERR_FATAL_ERROR || state_data->prog_data->args->common_args.debug) pstdout_fprintf (state_data->pstate, stderr, "ipmi_cmd_set_channel_security_keys: %s\n", ipmi_ctx_errormsg (state_data->ipmi_ctx)); goto cleanup; } if ((buf_len = fiid_obj_get_data (obj_cmd_rs, "key_value", buf, IPMI_CONFIG_PARSE_BUFLEN)) < 0) { pstdout_fprintf (state_data->pstate, stderr, "fiid_obj_get_data: 'key_value': %s\n", fiid_obj_errormsg (obj_cmd_rs)); goto cleanup; } if (key_len < buf_len) { pstdout_fprintf (state_data->pstate, stderr, "ipmi_cmd_set_channel_security_keys: short buffer\n"); goto cleanup; } memcpy (key, buf, buf_len); rv = IPMI_CONFIG_ERR_SUCCESS; cleanup: fiid_obj_destroy (obj_cmd_rs); return (rv); }
static ipmi_config_err_t asset_tag_checkout (ipmi_config_state_data_t *state_data, const char *section_name, struct ipmi_config_keyvalue *kv) { fiid_obj_t obj_cmd_rs = NULL; char asset_tag_data[IPMI_DCMI_MAX_ASSET_TAG_LENGTH + 1]; int data_len; unsigned int offset = 0; uint8_t total_asset_tag_length = 0; uint8_t bytes_to_read = IPMI_DCMI_ASSET_TAG_NUMBER_OF_BYTES_TO_READ_MAX; ipmi_config_err_t rv = IPMI_CONFIG_ERR_FATAL_ERROR; ipmi_config_err_t ret; assert (state_data); assert (section_name); assert (kv); if (!(obj_cmd_rs = fiid_obj_create (tmpl_cmd_dcmi_get_asset_tag_rs))) { pstdout_fprintf (state_data->pstate, stderr, "fiid_obj_create: %s\n", strerror (errno)); goto cleanup; } memset (asset_tag_data, '\0', IPMI_DCMI_MAX_ASSET_TAG_LENGTH + 1); while (1) { uint64_t val; if (!offset || ((total_asset_tag_length - offset) >= IPMI_DCMI_ASSET_TAG_NUMBER_OF_BYTES_TO_READ_MAX)) bytes_to_read = IPMI_DCMI_ASSET_TAG_NUMBER_OF_BYTES_TO_READ_MAX; else bytes_to_read = total_asset_tag_length - offset; if (ipmi_cmd_dcmi_get_asset_tag (state_data->ipmi_ctx, offset, bytes_to_read, obj_cmd_rs) < 0) { if (ipmi_config_param_errnum_is_non_fatal (state_data, obj_cmd_rs, &ret)) rv = ret; if (rv == IPMI_CONFIG_ERR_FATAL_ERROR || state_data->prog_data->args->common_args.debug) pstdout_fprintf (state_data->pstate, stderr, "ipmi_cmd_dcmi_get_asset_tag: %s\n", ipmi_ctx_errormsg (state_data->ipmi_ctx)); goto cleanup; } if (FIID_OBJ_GET (obj_cmd_rs, "total_asset_tag_length", &val) < 0) { pstdout_fprintf (state_data->pstate, stderr, "fiid_obj_get: 'total_asset_tag_length': %s\n", fiid_obj_errormsg (obj_cmd_rs)); goto cleanup; } total_asset_tag_length = val; if (!total_asset_tag_length) break; if ((data_len = fiid_obj_get_data (obj_cmd_rs, "data", asset_tag_data + offset, IPMI_DCMI_MAX_ASSET_TAG_LENGTH - offset)) < 0) { pstdout_fprintf (state_data->pstate, stderr, "fiid_obj_get_data: 'data': %s\n", fiid_obj_errormsg (obj_cmd_rs)); goto cleanup; } offset += data_len; if (offset >= total_asset_tag_length) break; } /* Handle special case UTF-8 encoding w/ BOM prefix */ if (asset_tag_data[0] == IPMI_DCMI_ASSET_TAG_UTF8_BOM_BYTE0 && asset_tag_data[1] == IPMI_DCMI_ASSET_TAG_UTF8_BOM_BYTE1 && asset_tag_data[2] == IPMI_DCMI_ASSET_TAG_UTF8_BOM_BYTE2) { /* achu: I think this is right for UTF-8 in libc and is * portable, but I would bet some systems won't like this. */ if (ipmi_config_section_update_keyvalue_output (state_data, kv, &asset_tag_data[3]) < 0) return (IPMI_CONFIG_ERR_FATAL_ERROR); } else { if (ipmi_config_section_update_keyvalue_output (state_data, kv, asset_tag_data) < 0) return (IPMI_CONFIG_ERR_FATAL_ERROR); } rv = IPMI_CONFIG_ERR_SUCCESS; cleanup: fiid_obj_destroy (obj_cmd_rs); return (rv); }
static ipmi_config_err_t management_controller_identifier_string_checkout (ipmi_config_state_data_t *state_data, const char *section_name, struct ipmi_config_keyvalue *kv) { fiid_obj_t obj_cmd_rs = NULL; char management_controller_identifier_string_data[IPMI_DCMI_MAX_MANAGEMENT_CONTROLLER_IDENTIFIER_STRING_LENGTH + 1]; int data_len; unsigned int offset = 0; uint8_t total_length = 0; uint8_t bytes_to_read = IPMI_DCMI_MANAGEMENT_CONTROLLER_IDENTIFIER_STRING_NUMBER_OF_BYTES_TO_READ_MAX; ipmi_config_err_t rv = IPMI_CONFIG_ERR_FATAL_ERROR; ipmi_config_err_t ret; assert (state_data); assert (section_name); assert (kv); if (!(obj_cmd_rs = fiid_obj_create (tmpl_cmd_dcmi_get_management_controller_identifier_string_rs))) { pstdout_fprintf (state_data->pstate, stderr, "fiid_obj_create: %s\n", strerror (errno)); goto cleanup; } memset (management_controller_identifier_string_data, '\0', IPMI_DCMI_MAX_MANAGEMENT_CONTROLLER_IDENTIFIER_STRING_LENGTH + 1); while (1) { uint64_t val; if (!offset || ((total_length - offset) >= IPMI_DCMI_MANAGEMENT_CONTROLLER_IDENTIFIER_STRING_NUMBER_OF_BYTES_TO_READ_MAX)) bytes_to_read = IPMI_DCMI_MANAGEMENT_CONTROLLER_IDENTIFIER_STRING_NUMBER_OF_BYTES_TO_READ_MAX; else bytes_to_read = total_length - offset; if (ipmi_cmd_dcmi_get_management_controller_identifier_string (state_data->ipmi_ctx, offset, bytes_to_read, obj_cmd_rs) < 0) { if (ipmi_config_param_errnum_is_non_fatal (state_data, obj_cmd_rs, &ret)) rv = ret; if (rv == IPMI_CONFIG_ERR_FATAL_ERROR || state_data->prog_data->args->common_args.debug) pstdout_fprintf (state_data->pstate, stderr, "ipmi_cmd_dcmi_get_management_controller_identifier_string: %s\n", ipmi_ctx_errormsg (state_data->ipmi_ctx)); goto cleanup; } if (FIID_OBJ_GET (obj_cmd_rs, "total_length", &val) < 0) { pstdout_fprintf (state_data->pstate, stderr, "fiid_obj_get: 'total_length': %s\n", fiid_obj_errormsg (obj_cmd_rs)); goto cleanup; } total_length = val; if (!total_length) break; if ((data_len = fiid_obj_get_data (obj_cmd_rs, "data", management_controller_identifier_string_data + offset, IPMI_DCMI_MAX_MANAGEMENT_CONTROLLER_IDENTIFIER_STRING_LENGTH - offset)) < 0) { pstdout_fprintf (state_data->pstate, stderr, "fiid_obj_get_data: 'data': %s\n", fiid_obj_errormsg (obj_cmd_rs)); goto cleanup; } offset += data_len; if (offset >= total_length) break; } if (ipmi_config_section_update_keyvalue_output (state_data, kv, management_controller_identifier_string_data) < 0) return (IPMI_CONFIG_ERR_FATAL_ERROR); rv = IPMI_CONFIG_ERR_SUCCESS; cleanup: fiid_obj_destroy (obj_cmd_rs); return (rv); }