Exemplo n.º 1
0
size_t
stun_usage_ice_conncheck_create (StunAgent *agent, StunMessage *msg,
                                 uint8_t *buffer, size_t buffer_len,
                                 const uint8_t *username, const size_t username_len,
                                 const uint8_t *password, const size_t password_len,
                                 bool cand_use, bool controlling, uint32_t priority,
                                 uint64_t tie, StunUsageIceCompatibility compatibility)
{
    StunMessageReturn val;
    
    stun_agent_init_request (agent, msg, buffer, buffer_len, STUN_BINDING);
    
    if (compatibility == STUN_USAGE_ICE_COMPATIBILITY_RFC5245) {
        if (cand_use)
        {
            val = stun_message_append_flag (msg, STUN_ATTRIBUTE_USE_CANDIDATE);
            if (val != STUN_MESSAGE_RETURN_SUCCESS)
                return 0;
        }
        
        val = stun_message_append32 (msg, STUN_ATTRIBUTE_PRIORITY, priority);
        if (val != STUN_MESSAGE_RETURN_SUCCESS)
            return 0;
        
        if (controlling)
            val = stun_message_append64 (msg, STUN_ATTRIBUTE_ICE_CONTROLLING, tie);
        else
            val = stun_message_append64 (msg, STUN_ATTRIBUTE_ICE_CONTROLLED, tie);
        if (val != STUN_MESSAGE_RETURN_SUCCESS)
            return 0;
    }
    
    if (username && username_len > 0) {
        val = stun_message_append_bytes (msg, STUN_ATTRIBUTE_USERNAME,
                                         username, username_len);
        if (val != STUN_MESSAGE_RETURN_SUCCESS)
            return 0;
    }
    
    return stun_agent_finish_message (agent, msg, password, password_len);
    
}
Exemplo n.º 2
0
int main (void)
{
  uint8_t buf[100];
  size_t len;
  union {
    struct sockaddr_storage storage;
    struct sockaddr addr;
  } addr;

  StunAgent agent;
  StunMessage msg;
  uint16_t known_attributes[] = {STUN_ATTRIBUTE_USERNAME,
                                 STUN_ATTRIBUTE_MESSAGE_INTEGRITY,
                                 STUN_ATTRIBUTE_ERROR_CODE,
                                 0};

  stun_agent_init (&agent, known_attributes,
      STUN_COMPATIBILITY_RFC5389, STUN_AGENT_USAGE_USE_FINGERPRINT);

  /* Request formatting test */
  stun_agent_init_request (&agent, &msg, buf, sizeof(buf), STUN_BINDING);
  finish_check (&agent, &msg);
  if (memcmp (buf, "\x00\x01", 2))
    fatal ("Request formatting test failed");

  /* Response formatting test */
  stun_agent_init_response (&agent, &msg, buf, sizeof (buf), &msg);
  finish_check (&agent, &msg);
  if (memcmp (buf, "\x01\x01", 2))
    fatal ("Response formatting test failed");

  /* Error formatting test */
  stun_agent_init_request (&agent, &msg, buf, sizeof(buf), STUN_BINDING);
  finish_check (&agent, &msg);
  if (!stun_agent_init_error (&agent, &msg, buf, sizeof (buf), &msg, 400))
    fatal ("Error initialization test failed");
  finish_check (&agent, &msg);
  if (memcmp (buf, "\x01\x11", 2))
    fatal ("Error formatting test failed");
  /* Unknown error formatting test */
  stun_agent_init_request (&agent, &msg, buf, sizeof(buf), STUN_BINDING);
  finish_check (&agent, &msg);
  if (!stun_agent_init_error (&agent, &msg, buf, sizeof (buf), &msg, 666))
    fatal ("Unknown error initialization test failed");
  finish_check (&agent, &msg);
  if (memcmp (buf, "\x01\x11", 2))
    fatal ("Unknown error formatting test failed");

  /* Overflow tests */
  stun_agent_init_request (&agent, &msg, buf, sizeof(buf), STUN_BINDING);

  for (len = 0;
       stun_message_append_flag (&msg, 0xffff) !=
           STUN_MESSAGE_RETURN_NOT_ENOUGH_SPACE;
       len += 4)
  {
    if (len > 0xffff)
      fatal ("Overflow protection test failed");
  }

  if (stun_message_append32 (&msg, 0xffff, 0x12345678) !=
      STUN_MESSAGE_RETURN_NOT_ENOUGH_SPACE)
    fatal ("Double-word overflow test failed");
  if (stun_message_append64 (&msg, 0xffff,
          0x123456789abcdef0) != STUN_MESSAGE_RETURN_NOT_ENOUGH_SPACE)
    fatal ("Quad-word overflow test failed");
  if (stun_message_append_string (&msg, 0xffff, "foobar") !=
      STUN_MESSAGE_RETURN_NOT_ENOUGH_SPACE)
    fatal ("String overflow test failed");

  memset (&addr, 0, sizeof (addr));
  addr.addr.sa_family = AF_INET;
#ifdef HAVE_SS_LEN
  addr.addr.ss_len = sizeof (addr);
#endif
  if (stun_message_append_xor_addr (&msg, 0xffff, &addr.storage,
          sizeof (addr)) != STUN_MESSAGE_RETURN_NOT_ENOUGH_SPACE)
    fatal ("Address overflow test failed");
  len = sizeof (msg);
  if (stun_agent_finish_message (&agent, &msg, NULL, 0) != 0)
    fatal ("Fingerprint overflow test failed");
  if (stun_agent_finish_message (&agent, &msg, pwd, strlen ((char *) pwd)) != 0)
    fatal ("Message integrity overflow test failed");

  /* Address attributes tests */
  check_af ("IPv4", AF_INET, sizeof (struct sockaddr_in));
#ifdef AF_INET6
  check_af ("IPv6", AF_INET6, sizeof (struct sockaddr_in6));
#endif

  return 0;
}
Exemplo n.º 3
0
int main (void)
{
  union {
    struct sockaddr sa;
    struct sockaddr_storage storage;
    struct sockaddr_in ip4;
  } addr;
  uint8_t req_buf[STUN_MAX_MESSAGE_SIZE];
  uint8_t resp_buf[STUN_MAX_MESSAGE_SIZE];
  const const uint64_t tie = 0x8000000000000000LL;
  StunMessageReturn val;
  StunUsageIceReturn val2;
  size_t len;
  size_t rlen;
  static char username[] = "L:R";
  static uint8_t ufrag[] = "L", pass[] = "secret";
  size_t ufrag_len = strlen ((char*) ufrag);
  size_t pass_len = strlen ((char*) pass);
  int code;
  bool control = false;
  StunAgent agent;
  StunMessage req;
  StunMessage resp;
  StunDefaultValidaterData validater_data[] = {
    {ufrag, ufrag_len, pass, pass_len},
    {(uint8_t *) username, strlen (username), pass, pass_len},
    {NULL, 0, NULL, 0}};
  StunValidationStatus valid;

  stun_agent_init (&agent, STUN_ALL_KNOWN_ATTRIBUTES,
      STUN_COMPATIBILITY_RFC5389,
      STUN_AGENT_USAGE_USE_FINGERPRINT |
      STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS);

  memset (&addr, 0, sizeof (addr));
  addr.ip4.sin_family = AF_INET;
#ifdef HAVE_SA_LEN
  addr.ip4.sin_len = sizeof (addr);
#endif
  addr.ip4.sin_port = htons (12345);
  addr.ip4.sin_addr.s_addr = htonl (0x7f000001);

  /* Incorrect message class */
  assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), STUN_BINDING));
  assert (stun_agent_init_response (&agent, &req, req_buf, sizeof (req_buf), &req));

  rlen = stun_agent_finish_message (&agent, &req, NULL, 0);
  assert (rlen > 0);

  len = sizeof (resp_buf);
  val2 = stun_usage_ice_conncheck_create_reply (&agent, &req,
      &resp, resp_buf, &len, &addr.storage,
      sizeof (addr.ip4), &control, tie, STUN_USAGE_ICE_COMPATIBILITY_RFC5245);
  assert (val2 == STUN_USAGE_ICE_RETURN_INVALID_REQUEST);
  assert (len == 0);

  /* Incorrect message method */
  assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), 0x666));
  val = stun_message_append_string (&req, STUN_ATTRIBUTE_USERNAME, username);
  assert (val == STUN_MESSAGE_RETURN_SUCCESS);
  rlen = stun_agent_finish_message (&agent, &req, pass, pass_len);
  assert (rlen > 0);

  len = sizeof (resp_buf);
  val2 = stun_usage_ice_conncheck_create_reply (&agent, &req,
      &resp, resp_buf, &len, &addr.storage,
      sizeof (addr.ip4), &control, tie, STUN_USAGE_ICE_COMPATIBILITY_RFC5245);
  assert (val2 == STUN_USAGE_ICE_RETURN_INVALID_METHOD);
  assert (len > 0);

  /* Unknown attribute */
  assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), STUN_BINDING));
  val = stun_message_append_string (&req, 0x666, "The evil unknown attribute!");
  assert (val == STUN_MESSAGE_RETURN_SUCCESS);
  val = stun_message_append_string (&req, STUN_ATTRIBUTE_USERNAME, username);
  assert (val == STUN_MESSAGE_RETURN_SUCCESS);
  rlen = stun_agent_finish_message (&agent, &req, pass, pass_len);
  assert (rlen > 0);

  valid = stun_agent_validate (&agent, &req, req_buf, rlen,
      stun_agent_default_validater, validater_data);

  assert (valid == STUN_VALIDATION_UNKNOWN_REQUEST_ATTRIBUTE);

  /* Unauthenticated message */
  assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), STUN_BINDING));
  rlen = stun_agent_finish_message (&agent, &req, NULL, 0);
  assert (rlen > 0);

  valid = stun_agent_validate (&agent, &req, req_buf, rlen,
      stun_agent_default_validater, validater_data);

  assert (valid == STUN_VALIDATION_UNAUTHORIZED_BAD_REQUEST);

  /* No username */
  assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), STUN_BINDING));
  rlen = stun_agent_finish_message (&agent, &req, pass, pass_len);
  assert (rlen > 0);

  valid = stun_agent_validate (&agent, &req, req_buf, rlen,
      stun_agent_default_validater, validater_data);

  assert (valid == STUN_VALIDATION_UNAUTHORIZED_BAD_REQUEST);
  assert (stun_usage_ice_conncheck_priority (&req) == 0);
  assert (stun_usage_ice_conncheck_use_candidate (&req) == false);

  /* Good message */
  assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), STUN_BINDING));
  val = stun_message_append32 (&req, STUN_ATTRIBUTE_PRIORITY, 0x12345678);
  assert (val == STUN_MESSAGE_RETURN_SUCCESS);
  val = stun_message_append_flag (&req, STUN_ATTRIBUTE_USE_CANDIDATE);
  assert (val == STUN_MESSAGE_RETURN_SUCCESS);
  val = stun_message_append_string (&req, STUN_ATTRIBUTE_USERNAME,
      (char*) ufrag);
  assert (val == STUN_MESSAGE_RETURN_SUCCESS);
  rlen = stun_agent_finish_message (&agent, &req, pass, pass_len);
  assert (rlen > 0);

  len = sizeof (resp_buf);
  val2 = stun_usage_ice_conncheck_create_reply (&agent, &req,
      &resp, resp_buf, &len, &addr.storage,
      sizeof (addr.ip4), &control, tie, STUN_USAGE_ICE_COMPATIBILITY_RFC5245);
  assert (val2 == STUN_USAGE_ICE_RETURN_SUCCESS);
  assert (len > 0);
  assert (stun_agent_validate (&agent, &resp, resp_buf, len,
          stun_agent_default_validater, validater_data) == STUN_VALIDATION_SUCCESS);
  assert (stun_message_get_class (&resp) == STUN_RESPONSE);
  assert (stun_usage_ice_conncheck_priority (&req) == 0x12345678);
  assert (stun_usage_ice_conncheck_use_candidate (&req) == true);

  /* Invalid socket address */
  assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), STUN_BINDING));
  val = stun_message_append_string (&req, STUN_ATTRIBUTE_USERNAME,
      (char *) ufrag);
  assert (val == STUN_MESSAGE_RETURN_SUCCESS);
  rlen = stun_agent_finish_message (&agent, &req, pass, pass_len);
  assert (rlen > 0);

  addr.ip4.sin_family = AF_UNSPEC;
  len = sizeof (resp_buf);
  val2 = stun_usage_ice_conncheck_create_reply (&agent, &req,
      &resp, resp_buf, &len, &addr.storage,
      sizeof (addr.ip4), &control, tie, STUN_USAGE_ICE_COMPATIBILITY_RFC5245);
  assert (val2 == STUN_USAGE_ICE_RETURN_INVALID_ADDRESS);
  assert (len == 0);

  addr.ip4.sin_family = AF_INET;

  /* Lost role conflict */
  assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), STUN_BINDING));
  val = stun_message_append64 (&req, STUN_ATTRIBUTE_ICE_CONTROLLING, tie + 1);
  assert (val == STUN_MESSAGE_RETURN_SUCCESS);
  val = stun_message_append_string (&req, STUN_ATTRIBUTE_USERNAME,
     (char *) ufrag);
  assert (val == STUN_MESSAGE_RETURN_SUCCESS);
  rlen = stun_agent_finish_message (&agent, &req, pass, pass_len);
  assert (rlen > 0);


  len = sizeof (resp_buf);
  control = true;
  val2 = stun_usage_ice_conncheck_create_reply (&agent, &req,
      &resp, resp_buf, &len, &addr.storage,
      sizeof (addr.ip4), &control, tie, STUN_USAGE_ICE_COMPATIBILITY_RFC5245);
  assert (val2 == STUN_USAGE_ICE_RETURN_ROLE_CONFLICT);
  assert (len > 0);
  assert (control == false);
  assert (stun_agent_validate (&agent, &resp, resp_buf, len,
          stun_agent_default_validater, validater_data) == STUN_VALIDATION_SUCCESS);
  assert (stun_message_get_class (&resp) == STUN_RESPONSE);

  /* Won role conflict */
  assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), STUN_BINDING));
  val = stun_message_append64 (&req, STUN_ATTRIBUTE_ICE_CONTROLLED, tie - 1);
  assert (val == STUN_MESSAGE_RETURN_SUCCESS);
  val = stun_message_append_string (&req, STUN_ATTRIBUTE_USERNAME,
      (char *) ufrag);
  assert (val == STUN_MESSAGE_RETURN_SUCCESS);
  rlen = stun_agent_finish_message (&agent, &req, pass, pass_len);
  assert (rlen > 0);

  len = sizeof (resp_buf);
  control = false;
  val2 = stun_usage_ice_conncheck_create_reply (&agent, &req,
      &resp, resp_buf, &len, &addr.storage,
      sizeof (addr.ip4), &control, tie, STUN_USAGE_ICE_COMPATIBILITY_RFC5245);
  assert (val2 == STUN_USAGE_ICE_RETURN_SUCCESS);
  assert (len > 0);
  assert (control == false);
  assert (stun_agent_validate (&agent, &resp, resp_buf, len,
          stun_agent_default_validater, validater_data) == STUN_VALIDATION_SUCCESS);
  assert (stun_message_get_class (&resp) == STUN_ERROR);
  stun_message_find_error (&resp, &code);
  assert (code == STUN_ERROR_ROLE_CONFLICT);


  return 0;
}
Exemplo n.º 4
0
size_t
stun_usage_ice_conncheck_create (StunAgent *agent, StunMessage *msg,
    uint8_t *buffer, size_t buffer_len,
    const uint8_t *username, const size_t username_len,
    const uint8_t *password, const size_t password_len,
    bool cand_use, bool controlling, uint32_t priority,
    uint64_t tie, const char *candidate_identifier,
    StunUsageIceCompatibility compatibility)
{
  StunMessageReturn val;

  stun_agent_init_request (agent, msg, buffer, buffer_len, STUN_BINDING);

  if (compatibility == STUN_USAGE_ICE_COMPATIBILITY_RFC5245 ||
      compatibility == STUN_USAGE_ICE_COMPATIBILITY_MSICE2) {
    if (cand_use)
    {
      val = stun_message_append_flag (msg, STUN_ATTRIBUTE_USE_CANDIDATE);
      if (val != STUN_MESSAGE_RETURN_SUCCESS)
        return 0;
    }

    val = stun_message_append32 (msg, STUN_ATTRIBUTE_PRIORITY, priority);
    if (val != STUN_MESSAGE_RETURN_SUCCESS)
      return 0;

    if (controlling)
      val = stun_message_append64 (msg, STUN_ATTRIBUTE_ICE_CONTROLLING, tie);
    else
      val = stun_message_append64 (msg, STUN_ATTRIBUTE_ICE_CONTROLLED, tie);
    if (val != STUN_MESSAGE_RETURN_SUCCESS)
      return 0;
  }

  if (username && username_len > 0) {
    val = stun_message_append_bytes (msg, STUN_ATTRIBUTE_USERNAME,
        username, username_len);
    if (val != STUN_MESSAGE_RETURN_SUCCESS)
      return 0;
  }

  if (compatibility == STUN_USAGE_ICE_COMPATIBILITY_MSICE2 &&
      candidate_identifier) {
    size_t identifier_len = strlen(candidate_identifier);
    size_t attribute_len = identifier_len;
    int modulo4 = identifier_len % 4;
    uint8_t* buf;

    if (modulo4)
        attribute_len += 4 - modulo4;

    // Avoid a coverify false positive
    assert (attribute_len >= identifier_len);
    buf = malloc(attribute_len);
    memset(buf, 0, attribute_len);
    memcpy(buf, candidate_identifier, identifier_len);

    val = stun_message_append_bytes (msg, STUN_ATTRIBUTE_CANDIDATE_IDENTIFIER,
            buf, attribute_len);

    free(buf);

    if (val != STUN_MESSAGE_RETURN_SUCCESS)
		return 0;

    val = stun_message_append32 (msg,
        STUN_ATTRIBUTE_MS_IMPLEMENTATION_VERSION, 2);

    if (val != STUN_MESSAGE_RETURN_SUCCESS)
      return 0;
  }

  return stun_agent_finish_message (agent, msg, password, password_len);

}