Exemplo n.º 1
0
int32_t 
Fiid_obj_set_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_set_data(obj, field, data, data_len)) < 0)
    ierr_exit("Fiid_obj_set_data: field=%s: %s", field, fiid_strerror(fiid_obj_errnum(obj)));
  
  return rv;
}
Exemplo n.º 2
0
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);
}
Exemplo n.º 3
0
int
unassemble_ipmi_lan_pkt (const void *pkt,
                         unsigned int pkt_len,
                         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,
                         fiid_obj_t obj_lan_msg_trlr,
			 unsigned int flags)
{
  uint8_t authentication_type;
  unsigned int indx = 0;
  unsigned int obj_cmd_len;
  int obj_lan_msg_trlr_len, len;
  uint64_t val;
  unsigned int flags_mask = (IPMI_INTERFACE_FLAGS_NO_LEGAL_CHECK);

  if (!pkt
      || !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)
      || !fiid_obj_valid (obj_lan_msg_trlr)
      || (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_rs) < 0)
    {
      ERRNO_TRACE (errno);
      return (-1);
    }
  if (FIID_OBJ_TEMPLATE_COMPARE (obj_lan_msg_trlr, tmpl_lan_msg_trlr) < 0)
    {
      ERRNO_TRACE (errno);
      return (-1);
    }

  indx = 0;
  if (fiid_obj_clear (obj_rmcp_hdr) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcp_hdr);
      return (-1);
    }

  if (fiid_obj_clear (obj_lan_session_hdr) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_session_hdr);
      return (-1);
    }

  if (fiid_obj_clear (obj_lan_msg_hdr) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_msg_hdr);
      return (-1);
    }
  
  if (fiid_obj_clear (obj_cmd) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd);
      return (-1);
    }

  if (fiid_obj_clear (obj_lan_msg_trlr) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_msg_trlr);
      return (-1);
    }

  if ((len = fiid_obj_set_all (obj_rmcp_hdr, pkt + indx, pkt_len - indx)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcp_hdr);
      return (-1);
    }
  indx += len;

  if (pkt_len <= indx)
    {
      /* cannot parse packet */
      ERR_TRACE ("malformed packet", EINVAL);
      return (0);
    }

  if ((len = fiid_obj_set_block (obj_lan_session_hdr,
                                 "authentication_type",
                                 "session_id",
                                 pkt + indx,
                                 pkt_len - indx)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_session_hdr);
      return (-1);
    }
  indx += len;

  if (FIID_OBJ_GET (obj_lan_session_hdr,
                    "authentication_type",
                    &val) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_session_hdr);
      return (-1);
    }
  authentication_type = val;

  if (!IPMI_1_5_AUTHENTICATION_TYPE_VALID (authentication_type))
    {
      /* cannot parse packet */
      ERR_TRACE ("malformed packet", EINVAL);
      return (0);
    }

  if (authentication_type != IPMI_AUTHENTICATION_TYPE_NONE)
    {
      if ((len = fiid_obj_set_data (obj_lan_session_hdr,
                                    "authentication_code",
                                    pkt + indx,
                                    pkt_len - indx)) < 0)
        {
          FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_session_hdr);
          return (-1);
        }
      indx += len;

      if (pkt_len <= indx)
        {
          /* cannot parse packet */
          ERR_TRACE ("malformed packet", EINVAL);
          return (0);
        }
    }

  if ((len = fiid_obj_set_data (obj_lan_session_hdr,
                                "ipmi_msg_len",
                                pkt + indx,
                                pkt_len - indx)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_session_hdr);
      return (-1);
    }
  indx += len;

  if (pkt_len <= indx)
    {
      /* cannot parse packet */
      ERR_TRACE ("malformed packet", EINVAL);
      return (0);
    }

  if ((len = fiid_obj_set_all (obj_lan_msg_hdr, pkt + indx, pkt_len - indx)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_msg_hdr);
      return (-1);
    }
  indx += len;

  if (pkt_len <= indx)
    {
      /* cannot parse packet */
      ERR_TRACE ("malformed packet", EINVAL);
      return (0);
    }

  if ((obj_lan_msg_trlr_len = fiid_template_len_bytes (tmpl_lan_msg_trlr)) < 0)
    {
      ERRNO_TRACE (errno);
      return (-1);
    }

  if ((pkt_len - indx) <= obj_lan_msg_trlr_len)
    {
      /* cannot parse packet */
      ERR_TRACE ("malformed packet", EINVAL);
      return (0);
    }

  obj_cmd_len = (pkt_len - indx) - obj_lan_msg_trlr_len;

  if ((len = fiid_obj_set_all (obj_cmd, pkt + indx, obj_cmd_len)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd);
      return (-1);
    }
  indx += len;

  if (pkt_len <= indx)
    {
      /* cannot parse packet */
      ERR_TRACE ("malformed packet", EINVAL);
      return (0);
    }

  if ((len = fiid_obj_set_all (obj_lan_msg_trlr, pkt + indx, pkt_len - indx)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_msg_trlr);
      return (-1);
    }
  indx += len;
  
  if (FIID_OBJ_PACKET_VALID (obj_rmcp_hdr) == 1
      && FIID_OBJ_PACKET_VALID (obj_lan_session_hdr) == 1
      && FIID_OBJ_PACKET_VALID (obj_lan_msg_hdr) == 1
      && ((flags & IPMI_INTERFACE_FLAGS_NO_LEGAL_CHECK) || FIID_OBJ_PACKET_SUFFICIENT (obj_cmd) == 1)
      && FIID_OBJ_PACKET_VALID (obj_lan_msg_trlr) == 1)
    return (1);

  return (0);
}