Ejemplo n.º 1
0
Archivo: otp.c Proyecto: Foda/pluto-fw
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);
   }
}
Ejemplo n.º 3
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;
   }
}
Ejemplo n.º 4
0
Archivo: otp.c Proyecto: Foda/pluto-fw
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);
   }
}
Ejemplo n.º 6
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) */
    }
}
Ejemplo n.º 7
0
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));
}
Ejemplo n.º 9
0
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);
}
Ejemplo n.º 10
0
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);
}
Ejemplo n.º 11
0
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);
}