uint8_t svc_otp_unlock(uint16_t pin) { timeout = g_timeout; uint8_t hash[20]; hal_sha1((uint8_t*)&pin, 2, hash); hal_aes_init(); hal_aes_set_key(hash); secure_memset(hash, 0, sizeof(hash)); locked = 0; }
void rce_nfy_term_rex(rce_nfy_p nfy_p) { if (RCE_NULL != nfy_p) { secure_memset((void*)(&nfy_p->sigex), 0, sizeof(struct rce_nfy_sigex_s)); } else { ERR_FATAL("null handle use", 0, 0, 0); } }
/** API, Initialization of service prior to use @return None. */ void pd_mon_host_init(void) { int i; secure_memset(&pd_mon_internal, 0, sizeof(pd_mon_internal)); // Initialize Local Storage qurt_pimutex_init(&pd_mon_internal.mutex); // Initalize Mutex qurt_anysignal_init(&pd_mon_internal.signal); // Initalize Signal for (i = 0; i < sizeof(pd_mon_internal.status)/sizeof(PD_MON_STATUS_T); i++) { pd_mon_internal.status[i].cid = PD_MON_STATUS_NO_CID; } }
int32_t svc_otp_get_token(uint8_t index) { timeout = g_timeout; otp_item_t *it = &(otp_store[index]); uint8_t secret[32]; hal_aes_decrypt(secret, it->secret); hal_aes_decrypt(secret+16, it->secret+16); int32_t out = -1; oath_totp_generate (secret, it->secret_len, time_counter, //now 30, 0, 6, &out); secure_memset(secret, 0, sizeof(secret)); return out; }
void rce_nfy_init_rex(rce_nfy_p nfy_p, RCEVT_SIGEX sigex) { if (RCE_NULL != nfy_p) { RCEVT_SIGEX_SIGREX* sigex_p = (RCEVT_SIGEX_SIGREX*)(&(nfy_p->sigex)); if (sizeof(struct rce_nfy_sigex_s) < sizeof(RCEVT_SIGEX_SIGREX)) { ERR_FATAL("payload size configuration", 0, 0, 0); } secure_memset((void*)(&nfy_p->sigex), 0, sizeof(struct rce_nfy_sigex_s)); sigex_p->mask = ((RCEVT_SIGEX_SIGREX*)sigex)->mask; sigex_p->signal = ((RCEVT_SIGEX_SIGREX*)sigex)->signal; } else { ERR_FATAL("null handle use", 0, 0, 0); } }
void secure_free (void *ptr, size_t len) { assert (len); if (ptr) { secure_memset (ptr, '\0', len); #if defined(MAP_ANONYMOUS) && defined(MAP_LOCK) && HAVE_MMAP /* ignore potential error, void return func */ munmap (ptr, len); #elif defined(MAP_ANONYMOUS) && !defined(MAP_LOCK) /* ignore potential error, void return func */ /* munlock is not necessary, munmap is sufficient */ munmap (ptr, len); #else /* !defined(MAP_ANONYMOUS) */ free (ptr); #endif /* !defined(MAP_ANONYMOUS) */ } }
void * secure_malloc (size_t len) { void *ptr; assert (len); #if defined(MAP_ANONYMOUS) && defined(MAP_LOCK) && HAVE_MMAP if ((ptr = mmap (NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS | MAP_LOCKED, -1, 0)) == MAP_FAILED) return (NULL); #elif defined(MAP_ANONYMOUS) && !defined(MAP_LOCK) if ((ptr = mmap (NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0)) == MAP_FAILED) return (NULL); if (mlock (ptr, len) < 0) { munmap (ptr, len); return (NULL); } #else /* !defined(MAP_ANONYMOUS) */ if (!(ptr = malloc (len))) return (NULL); #endif /* !defined(MAP_ANONYMOUS) */ #if 0 /* The following case could be implemented, however, we don't compile * it because it can cause fd leaks. */ if ((fd = open ("/dev/zero", O_RDWR)) < 0) return (NULL); if ((ptr = mmap (NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, -1, 0)) == MAP_FAILED) { /* ignore potential error, this is error path */ close (fd); return (NULL); } if (mlock (ptr, len) < 0) { /* ignore potential error, this is error path */ munmap (ptr, len); /* ignore potential error, this is error path */ close (fd); return (NULL); } #endif /* 0 */ secure_memset (ptr, '\0', len); return (ptr); }
void image_uuid(void) { secure_memset((void*)version_internal_uuid, NULL, sizeof(version_internal_uuid)); strlcpy(version_internal_uuid, OEM_IMAGE_UUID_STRING_AUTO_UPDATED, sizeof(version_internal_uuid)); }
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 main (int argc, char **argv) { struct ipmiconsole_arguments cmd_args; struct ipmiconsole_ipmi_config ipmi_config; struct ipmiconsole_protocol_config protocol_config; struct ipmiconsole_engine_config engine_config; ipmiconsole_ctx_t c = NULL; int debug_flags = 0; int fd = -1; ipmiconsole_argp_parse (argc, argv, &cmd_args); if (cmd_args.common_args.debug) { #ifndef NDEBUG if (cmd_args.debugfile) debug_flags |= IPMICONSOLE_DEBUG_FILE; else debug_flags |= IPMICONSOLE_DEBUG_STDERR; #else debug_flags |= IPMICONSOLE_DEBUG_STDERR; #endif /* NDEBUG */ debug_flags |= IPMICONSOLE_DEBUG_IPMI_PACKETS; } if (signal (SIGPIPE, SIG_IGN) == SIG_ERR) { /* Argh, it doesn't return an errno, oh well */ perror ("signal"); exit (EXIT_FAILURE); } if (ipmiconsole_engine_init (1, debug_flags) < 0) { perror ("ipmiconsole_setup"); exit (EXIT_FAILURE); } /* convert config information to ipmiconsole configuration */ memset (&ipmi_config, '\0', sizeof (struct ipmiconsole_ipmi_config)); ipmi_config.username = cmd_args.common_args.username; ipmi_config.password = cmd_args.common_args.password; ipmi_config.k_g = cmd_args.common_args.k_g; ipmi_config.k_g_len = cmd_args.common_args.k_g_len; if (cmd_args.common_args.privilege_level == IPMI_PRIVILEGE_LEVEL_USER) ipmi_config.privilege_level = IPMICONSOLE_PRIVILEGE_USER; else if (cmd_args.common_args.privilege_level == IPMI_PRIVILEGE_LEVEL_OPERATOR) ipmi_config.privilege_level = IPMICONSOLE_PRIVILEGE_OPERATOR; else if (cmd_args.common_args.privilege_level == IPMI_PRIVILEGE_LEVEL_ADMIN) ipmi_config.privilege_level = IPMICONSOLE_PRIVILEGE_ADMIN; else { fprintf (stderr, "Config Error: Invalid privilege level"); exit (EXIT_FAILURE); } ipmi_config.cipher_suite_id = cmd_args.common_args.cipher_suite_id; if (cmd_args.common_args.workaround_flags_outofband_2_0 & IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_AUTHENTICATION_CAPABILITIES) ipmi_config.workaround_flags |= IPMICONSOLE_WORKAROUND_AUTHENTICATION_CAPABILITIES; if (cmd_args.common_args.workaround_flags_outofband_2_0 & IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_INTEL_2_0_SESSION) ipmi_config.workaround_flags |= IPMICONSOLE_WORKAROUND_INTEL_2_0_SESSION; if (cmd_args.common_args.workaround_flags_outofband_2_0 & IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_SUPERMICRO_2_0_SESSION) ipmi_config.workaround_flags |= IPMICONSOLE_WORKAROUND_SUPERMICRO_2_0_SESSION; if (cmd_args.common_args.workaround_flags_outofband_2_0 & IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_SUN_2_0_SESSION) ipmi_config.workaround_flags |= IPMICONSOLE_WORKAROUND_SUN_2_0_SESSION; if (cmd_args.common_args.workaround_flags_outofband_2_0 & IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_OPEN_SESSION_PRIVILEGE) ipmi_config.workaround_flags |= IPMICONSOLE_WORKAROUND_OPEN_SESSION_PRIVILEGE; if (cmd_args.common_args.workaround_flags_outofband_2_0 & IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_NON_EMPTY_INTEGRITY_CHECK_VALUE) ipmi_config.workaround_flags |= IPMICONSOLE_WORKAROUND_NON_EMPTY_INTEGRITY_CHECK_VALUE; if (cmd_args.common_args.workaround_flags_outofband_2_0 & IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_NO_CHECKSUM_CHECK) ipmi_config.workaround_flags |= IPMICONSOLE_WORKAROUND_NO_CHECKSUM_CHECK; if (cmd_args.common_args.section_specific_workaround_flags & IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_IGNORE_SOL_PAYLOAD_SIZE) ipmi_config.workaround_flags |= IPMICONSOLE_WORKAROUND_IGNORE_SOL_PAYLOAD_SIZE; if (cmd_args.common_args.section_specific_workaround_flags & IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_IGNORE_SOL_PORT) ipmi_config.workaround_flags |= IPMICONSOLE_WORKAROUND_IGNORE_SOL_PORT; if (cmd_args.common_args.section_specific_workaround_flags & IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_SKIP_SOL_ACTIVATION_STATUS) ipmi_config.workaround_flags |= IPMICONSOLE_WORKAROUND_SKIP_SOL_ACTIVATION_STATUS; memset (&protocol_config, '\0', sizeof (struct ipmiconsole_protocol_config)); protocol_config.session_timeout_len = cmd_args.common_args.session_timeout; protocol_config.retransmission_timeout_len = cmd_args.common_args.retransmission_timeout; protocol_config.retransmission_backoff_count = -1; protocol_config.keepalive_timeout_len = -1; protocol_config.retransmission_keepalive_timeout_len = -1; protocol_config.acceptable_packet_errors_count = -1; protocol_config.maximum_retransmission_count = -1; memset (&engine_config, '\0', sizeof (struct ipmiconsole_engine_config)); engine_config.engine_flags = 0; if (cmd_args.serial_keepalive) engine_config.engine_flags |= IPMICONSOLE_ENGINE_SERIAL_KEEPALIVE; if (cmd_args.serial_keepalive_empty) engine_config.engine_flags |= IPMICONSOLE_ENGINE_SERIAL_KEEPALIVE_EMPTY; if (cmd_args.lock_memory) engine_config.engine_flags |= IPMICONSOLE_ENGINE_LOCK_MEMORY; engine_config.behavior_flags = 0; if (cmd_args.dont_steal) engine_config.behavior_flags |= IPMICONSOLE_BEHAVIOR_ERROR_ON_SOL_INUSE; if (cmd_args.deactivate) engine_config.behavior_flags |= IPMICONSOLE_BEHAVIOR_DEACTIVATE_ONLY; if (cmd_args.deactivate_all_instances) engine_config.behavior_flags |= IPMICONSOLE_BEHAVIOR_DEACTIVATE_ALL_INSTANCES; engine_config.debug_flags = debug_flags; if (!(c = ipmiconsole_ctx_create (cmd_args.common_args.hostname, &ipmi_config, &protocol_config, &engine_config))) { perror ("ipmiconsole_ctx_create"); goto cleanup; } if (cmd_args.sol_payload_instance) { if (ipmiconsole_ctx_set_config (c, IPMICONSOLE_CTX_CONFIG_OPTION_SOL_PAYLOAD_INSTANCE, &(cmd_args.sol_payload_instance)) < 0) { fprintf (stderr, "ipmiconsole_submit_block: %s\r\n", ipmiconsole_ctx_errormsg (c)); goto cleanup; } } if (ipmiconsole_engine_submit_block (c) < 0) { if (ipmiconsole_ctx_errnum (c) == IPMICONSOLE_ERR_IPMI_2_0_UNAVAILABLE || ipmiconsole_ctx_errnum (c) == IPMICONSOLE_ERR_CIPHER_SUITE_ID_UNAVAILABLE || ipmiconsole_ctx_errnum (c) == IPMICONSOLE_ERR_HOSTNAME_INVALID || ipmiconsole_ctx_errnum (c) == IPMICONSOLE_ERR_USERNAME_INVALID || ipmiconsole_ctx_errnum (c) == IPMICONSOLE_ERR_PASSWORD_INVALID || ipmiconsole_ctx_errnum (c) == IPMICONSOLE_ERR_K_G_INVALID || ipmiconsole_ctx_errnum (c) == IPMICONSOLE_ERR_PRIVILEGE_LEVEL_INSUFFICIENT || ipmiconsole_ctx_errnum (c) == IPMICONSOLE_ERR_PRIVILEGE_LEVEL_CANNOT_BE_OBTAINED || ipmiconsole_ctx_errnum (c) == IPMICONSOLE_ERR_SOL_UNAVAILABLE || ipmiconsole_ctx_errnum (c) == IPMICONSOLE_ERR_SOL_INUSE || ipmiconsole_ctx_errnum (c) == IPMICONSOLE_ERR_SOL_REQUIRES_ENCRYPTION || ipmiconsole_ctx_errnum (c) == IPMICONSOLE_ERR_SOL_REQUIRES_NO_ENCRYPTION || ipmiconsole_ctx_errnum (c) == IPMICONSOLE_ERR_BMC_BUSY || ipmiconsole_ctx_errnum (c) == IPMICONSOLE_ERR_BMC_ERROR || ipmiconsole_ctx_errnum (c) == IPMICONSOLE_ERR_BMC_IMPLEMENTATION || ipmiconsole_ctx_errnum (c) == IPMICONSOLE_ERR_CONNECTION_TIMEOUT || ipmiconsole_ctx_errnum (c) == IPMICONSOLE_ERR_SESSION_TIMEOUT || ipmiconsole_ctx_errnum (c) == IPMICONSOLE_ERR_EXCESS_RETRANSMISSIONS_SENT || ipmiconsole_ctx_errnum (c) == IPMICONSOLE_ERR_EXCESS_ERRORS_RECEIVED) printf ("[error received]: %s\n", ipmiconsole_ctx_errormsg (c)); else fprintf (stderr, "ipmiconsole_submit_block: %s\r\n", ipmiconsole_ctx_errormsg (c)); goto cleanup; } if (cmd_args.deactivate) goto cleanup; if ((fd = ipmiconsole_ctx_fd (c)) < 0) { fprintf (stderr, "ipmiconsole_ctx_fd: %s\r\n", ipmiconsole_ctx_errormsg (c)); goto cleanup; } #ifndef NDEBUG if (!cmd_args.noraw) { if (_set_mode_raw () < 0) goto cleanup; } #else /* !NDEBUG */ if (_set_mode_raw () < 0) goto cleanup; #endif /* !NDEBUG */ printf ("[SOL established]\r\n"); while (1) { char buf[IPMICONSOLE_BUFLEN]; struct timeval tv; ssize_t n; fd_set rds; FD_ZERO (&rds); FD_SET (fd, &rds); FD_SET (STDIN_FILENO, &rds); tv.tv_sec = 0; tv.tv_usec = 250000; if (select (fd + 1, &rds, NULL, NULL, &tv) < 0) { perror ("select"); goto cleanup; } if (FD_ISSET (STDIN_FILENO, &rds)) { if ((n = read (STDIN_FILENO, buf, IPMICONSOLE_BUFLEN)) < 0) { perror ("read"); goto cleanup; } if (!n) goto cleanup; if (_stdin (c, cmd_args.escape_char, fd, buf, n) < 0) goto cleanup; } if (FD_ISSET (fd, &rds)) { if ((n = read (fd, buf, IPMICONSOLE_BUFLEN)) < 0) { perror ("read"); goto cleanup; } if (n) { if (write (STDOUT_FILENO, buf, n) != n) { perror ("write"); goto cleanup; } } else { /* b/c we're exitting */ /* achu: it is possible that errnum can equal success. * Most likely scenario is user sets a flag in the * libipmiconsole.conf file that alters the behavior of * what this tool expects to happen. For example, if * user specifies deactivate on the command line, we * know to quit early. However, if the user does so in * libipmiconsole.conf, we as a tool won't know to * expect it. */ if (ipmiconsole_ctx_errnum (c) == IPMICONSOLE_ERR_SOL_STOLEN) printf ("\r\n[%s]\r\n", ipmiconsole_ctx_errormsg (c)); else if (ipmiconsole_ctx_errnum (c) != IPMICONSOLE_ERR_SUCCESS) printf ("\r\n[error received]: %s\r\n", ipmiconsole_ctx_errormsg (c)); goto cleanup; } } /* Clear out data */ secure_memset (buf, '\0', IPMICONSOLE_BUFLEN); } cleanup: if (fd >= 0) { printf ("\r\n[closing the connection]\r\n"); /* ignore potential error, cleanup path */ close (fd); } ipmiconsole_ctx_destroy (c); ipmiconsole_engine_teardown (1); #ifndef NDEBUG if (!cmd_args.noraw) _reset_mode (); #else /* !NDEBUG */ _reset_mode (); #endif /* !NDEBUG */ return (EXIT_SUCCESS); }
static int _stdin (ipmiconsole_ctx_t c, char escape_char, int fd, char *buf, unsigned int buflen) { static int last_char_escape = 0; char tbuf[IPMICONSOLE_BUFLEN]; unsigned int tbuflen = 0; ssize_t n; unsigned int i; assert (c); assert (fd); assert (buf); assert (buflen); for (i = 0; i < buflen; i++) { if (last_char_escape) { last_char_escape = 0; if (buf[i] == '?') { printf ("%c? - this menu\r\n", escape_char); printf ("%c. - exit\r\n", escape_char); printf ("%cB - generate break\r\n", escape_char); printf ("%cD - send DEL character\r\n", escape_char); printf ("%c& - & character\r\n", escape_char); } else if (buf[i] == '.') { if (tbuflen) { n = write (fd, tbuf, tbuflen); /* Clear out data */ secure_memset (tbuf, '\0', IPMICONSOLE_BUFLEN); if (n < 0) { perror ("write"); return (-1); } if (n != tbuflen) { perror ("write"); return (-1); } } /* b/c we're exitting */ return (-1); } else if (buf[i] == 'B') { if (tbuflen) { n = write (fd, tbuf, tbuflen); /* Clear out data */ secure_memset (tbuf, '\0', IPMICONSOLE_BUFLEN); if (n < 0) { perror ("write"); return (-1); } if (n != tbuflen) { perror ("write"); return (-1); } } tbuflen = 0; printf ("[generate break]\r\n"); if (ipmiconsole_ctx_generate_break (c) < 0) { fprintf (stderr, "ipmiconsole_ctx_generate_break: %s\r\n", ipmiconsole_ctx_errormsg (c)); return (-1); } } else if (buf[i] == 'D') { /* achu: Some keywords don't send DEL when you press delete, they send some other funky crap. */ tbuf[tbuflen++] = 0x7F; } else if (buf[i] == escape_char) tbuf[tbuflen++] = escape_char; else { tbuf[tbuflen++] = escape_char; tbuf[tbuflen++] = buf[i]; } } else if (buf[i] == escape_char) last_char_escape = 1; else tbuf[tbuflen++] = buf[i]; } if (tbuflen) { n = write (fd, tbuf, tbuflen); /* Clear out data */ secure_memset (tbuf, '\0', IPMICONSOLE_BUFLEN); if (n < 0) { if (errno != EPIPE) perror ("write"); else { if (ipmiconsole_ctx_errnum (c) == IPMICONSOLE_ERR_SOL_STOLEN) printf ("\r\n[%s]\r\n", ipmiconsole_ctx_errormsg (c)); else printf ("\r\n[error received]: %s\r\n", ipmiconsole_ctx_errormsg (c)); } return (-1); } if (n != tbuflen) { perror ("write"); return (-1); } } return (0); }