/* Decode and authenticate message with unknown non-mandatory attribute */ static int handle_unknown_non_mandatory(void) { pj_pool_t *pool = pj_pool_create(mem, NULL, 1000, 1000, NULL); pj_stun_msg *msg0, *msg1, *msg2; pj_uint8_t data[] = { 1, 2, 3, 4, 5, 6}; pj_uint8_t packet[500]; pj_stun_auth_cred cred; pj_size_t len; pj_status_t rc; PJ_LOG(3,(THIS_FILE, " handling unknown non-mandatory attr")); PJ_LOG(3,(THIS_FILE, " encoding")); rc = pj_stun_msg_create(pool, PJ_STUN_BINDING_REQUEST, PJ_STUN_MAGIC, NULL, &msg0); rc += pj_stun_msg_add_string_attr(pool, msg0, PJ_STUN_ATTR_USERNAME, &USERNAME); rc += pj_stun_msg_add_binary_attr(pool, msg0, 0x80ff, data, sizeof(data)); rc += pj_stun_msg_add_msgint_attr(pool, msg0); rc += pj_stun_msg_encode(msg0, packet, sizeof(packet), 0, &PASSWORD, &len); #if 0 if (1) { unsigned i; puts(""); printf("{ "); for (i=0; i<len; ++i) printf("0x%02x, ", packet[i]); puts(" }"); } #endif PJ_LOG(3,(THIS_FILE, " decoding")); rc += pj_stun_msg_decode(pool, packet, len, PJ_STUN_IS_DATAGRAM | PJ_STUN_CHECK_PACKET, &msg1, NULL, NULL); rc += cmp_msg(msg0, msg1); pj_bzero(&cred, sizeof(cred)); cred.type = PJ_STUN_AUTH_CRED_STATIC; cred.data.static_cred.username = USERNAME; cred.data.static_cred.data_type = PJ_STUN_PASSWD_PLAIN; cred.data.static_cred.data = PASSWORD; PJ_LOG(3,(THIS_FILE, " authenticating")); rc += pj_stun_authenticate_request(packet, (unsigned)len, msg1, &cred, pool, NULL, NULL); PJ_LOG(3,(THIS_FILE, " clone")); msg2 = pj_stun_msg_clone(pool, msg1); rc += cmp_msg(msg0, msg2); pj_pool_release(pool); return rc==0 ? 0 : -4410; }
static pj_stun_msg* create_msgint3(pj_pool_t *pool, test_vector *v) { pj_stun_msg *msg; pj_sockaddr mapped_addr; pj_str_t s1; pj_status_t status; status = pj_stun_msg_create(pool, v->msg_type, PJ_STUN_MAGIC, (pj_uint8_t*)v->tsx_id, &msg); if (status != PJ_SUCCESS) goto on_error; status = pj_stun_msg_add_string_attr(pool, msg, PJ_STUN_ATTR_SOFTWARE, pj_cstr(&s1, "test vector")); if (status != PJ_SUCCESS) goto on_error; status = pj_sockaddr_init(pj_AF_INET6(), &mapped_addr, pj_cstr(&s1, "2001:db8:1234:5678:11:2233:4455:6677"), 32853); if (status != PJ_SUCCESS) goto on_error; status = pj_stun_msg_add_sockaddr_attr(pool, msg, PJ_STUN_ATTR_XOR_MAPPED_ADDR, PJ_TRUE, &mapped_addr, sizeof(pj_sockaddr)); if (status != PJ_SUCCESS) goto on_error; status = pj_stun_msg_add_msgint_attr(pool, msg); if (status != PJ_SUCCESS) goto on_error; status = pj_stun_msg_add_uint_attr(pool, msg, PJ_STUN_ATTR_FINGERPRINT, 0); if (status != PJ_SUCCESS) goto on_error; return msg; on_error: app_perror(" error: create_msgint3()", status); return NULL; }
static pj_stun_msg* create_msgint1(pj_pool_t *pool, test_vector *v) { pj_stun_msg *msg; pj_timestamp u64; pj_str_t s1; pj_status_t status; status = pj_stun_msg_create(pool, v->msg_type, PJ_STUN_MAGIC, (pj_uint8_t*)v->tsx_id, &msg); if (status != PJ_SUCCESS) goto on_error; status = pj_stun_msg_add_uint_attr(pool, msg, PJ_STUN_ATTR_PRIORITY, 0x6e0001ff); if (status != PJ_SUCCESS) goto on_error; u64.u32.hi = 0x932ff9b1; u64.u32.lo = 0x51263b36; status = pj_stun_msg_add_uint64_attr(pool, msg, PJ_STUN_ATTR_ICE_CONTROLLED, &u64); if (status != PJ_SUCCESS) goto on_error; status = pj_stun_msg_add_string_attr(pool, msg, PJ_STUN_ATTR_USERNAME, pj_cstr(&s1, v->username)); if (status != PJ_SUCCESS) goto on_error; status = pj_stun_msg_add_msgint_attr(pool, msg); if (status != PJ_SUCCESS) goto on_error; status = pj_stun_msg_add_uint_attr(pool, msg, PJ_STUN_ATTR_FINGERPRINT, 0); if (status != PJ_SUCCESS) goto on_error; return msg; on_error: app_perror(" error: create_msgint1()", status); return NULL; }
static pj_stun_msg* create_msgint2(pj_pool_t *pool, test_vector *v) { pj_stun_msg *msg; pj_sockaddr_in mapped_addr; pj_str_t s1; pj_stun_msg_create(pool, v->msg_type, PJ_STUN_MAGIC, (pj_uint8_t*)v->tsx_id, &msg); pj_stun_msg_add_string_attr(pool, msg, PJ_STUN_ATTR_SOFTWARE, pj_cstr(&s1, "test vector")); pj_sockaddr_in_init(&mapped_addr, pj_cstr(&s1, "127.0.0.1"), 32853); pj_stun_msg_add_sockaddr_attr(pool, msg, PJ_STUN_ATTR_XOR_MAPPED_ADDR, PJ_TRUE, &mapped_addr, sizeof(pj_sockaddr_in)); pj_stun_msg_add_msgint_attr(pool, msg); pj_stun_msg_add_uint_attr(pool, msg, PJ_STUN_ATTR_FINGERPRINT, 0); return msg; }
static pj_stun_msg* create_success_response(test_server *test_srv, turn_allocation *alloc, pj_stun_msg *req, pj_pool_t *pool, unsigned lifetime, pj_str_t *auth_key) { pj_stun_msg *resp; pj_str_t tmp; pj_status_t status; /* Create response */ status = pj_stun_msg_create_response(pool, req, 0, NULL, &resp); if (status != PJ_SUCCESS) { return NULL; } /* Add TURN_NONCE */ pj_stun_msg_add_string_attr(pool, resp, PJ_STUN_ATTR_NONCE, pj_cstr(&tmp, TURN_NONCE)); /* Add LIFETIME */ pj_stun_msg_add_uint_attr(pool, resp, PJ_STUN_ATTR_LIFETIME, lifetime); if (lifetime != 0) { /* Add XOR-RELAYED-ADDRESS */ pj_stun_msg_add_sockaddr_attr(pool, resp, PJ_STUN_ATTR_XOR_RELAYED_ADDR, PJ_TRUE, &alloc->alloc_addr, pj_sockaddr_get_len(&alloc->alloc_addr)); /* Add XOR-MAPPED-ADDRESS */ pj_stun_msg_add_sockaddr_attr(pool, resp, PJ_STUN_ATTR_XOR_MAPPED_ADDR, PJ_TRUE, &alloc->client_addr, pj_sockaddr_get_len(&alloc->client_addr)); } /* Add blank MESSAGE-INTEGRITY */ pj_stun_msg_add_msgint_attr(pool, resp); /* Set auth key */ pj_stun_create_key(pool, auth_key, &test_srv->domain, &test_srv->username, PJ_STUN_PASSWD_PLAIN, &test_srv->passwd); return resp; }
static pj_stun_msg* create_msgint1(pj_pool_t *pool, test_vector *v) { pj_stun_msg *msg; pj_timestamp u64; pj_str_t s1; pj_stun_msg_create(pool, v->msg_type, PJ_STUN_MAGIC, (pj_uint8_t*)v->tsx_id, &msg); pj_stun_msg_add_uint_attr(pool, msg, PJ_STUN_ATTR_PRIORITY, 0x6e0001ff); u64.u32.hi = 0x932ff9b1; u64.u32.lo = 0x51263b36; pj_stun_msg_add_uint64_attr(pool, msg, PJ_STUN_ATTR_ICE_CONTROLLED, &u64); pj_stun_msg_add_string_attr(pool, msg, PJ_STUN_ATTR_USERNAME, pj_cstr(&s1, v->username)); pj_stun_msg_add_msgint_attr(pool, msg); pj_stun_msg_add_uint_attr(pool, msg, PJ_STUN_ATTR_FINGERPRINT, 0); return msg; }
static pj_status_t apply_msg_options(pj_stun_session *sess, pj_pool_t *pool, const pj_stun_req_cred_info *auth_info, pj_stun_msg *msg) { pj_status_t status = 0; pj_str_t realm, username, nonce, auth_key; /* If the agent is sending a request, it SHOULD add a SOFTWARE attribute * to the request. The server SHOULD include a SOFTWARE attribute in all * responses. * * If magic value is not PJ_STUN_MAGIC, only apply the attribute for * responses. */ if (sess->srv_name.slen && pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_SOFTWARE, 0)==NULL && (PJ_STUN_IS_RESPONSE(msg->hdr.type) || (PJ_STUN_IS_REQUEST(msg->hdr.type) && msg->hdr.magic==PJ_STUN_MAGIC))) { pj_stun_msg_add_string_attr(pool, msg, PJ_STUN_ATTR_SOFTWARE, &sess->srv_name); } if (pj_stun_auth_valid_for_msg(msg) && auth_info) { realm = auth_info->realm; username = auth_info->username; nonce = auth_info->nonce; auth_key = auth_info->auth_key; } else { realm.slen = username.slen = nonce.slen = auth_key.slen = 0; } /* Create and add USERNAME attribute if needed */ if (username.slen && PJ_STUN_IS_REQUEST(msg->hdr.type)) { status = pj_stun_msg_add_string_attr(pool, msg, PJ_STUN_ATTR_USERNAME, &username); PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); } /* Add REALM only when long term credential is used */ if (realm.slen && PJ_STUN_IS_REQUEST(msg->hdr.type)) { status = pj_stun_msg_add_string_attr(pool, msg, PJ_STUN_ATTR_REALM, &realm); PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); } /* Add NONCE when desired */ if (nonce.slen && (PJ_STUN_IS_REQUEST(msg->hdr.type) || PJ_STUN_IS_ERROR_RESPONSE(msg->hdr.type))) { status = pj_stun_msg_add_string_attr(pool, msg, PJ_STUN_ATTR_NONCE, &nonce); } /* Add MESSAGE-INTEGRITY attribute */ if (username.slen && auth_key.slen) { status = pj_stun_msg_add_msgint_attr(pool, msg); PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); } /* Add FINGERPRINT attribute if necessary */ if (sess->use_fingerprint) { status = pj_stun_msg_add_uint_attr(pool, msg, PJ_STUN_ATTR_FINGERPRINT, 0); PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); } return PJ_SUCCESS; }