/* 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 int fingerprint_test_vector() { pj_pool_t *pool; pj_status_t status; unsigned i; int rc = 0; /* To avoid function not referenced warnings */ (void)create_msgint2; (void)create_msgint3; PJ_LOG(3,(THIS_FILE, " draft-denis-behave-rfc3489bis-test-vectors-02")); pool = pj_pool_create(mem, "fingerprint", 1024, 1024, NULL); for (i=0; i<PJ_ARRAY_SIZE(test_vectors); ++i) { struct test_vector *v; pj_stun_msg *ref_msg, *msg; pj_size_t parsed_len; pj_size_t len; unsigned pos; pj_uint8_t buf[1500]; char print[1500]; pj_str_t key; PJ_LOG(3,(THIS_FILE, " Running test %d/%d", i, PJ_ARRAY_SIZE(test_vectors))); v = &test_vectors[i]; /* Print reference message */ PJ_LOG(4,(THIS_FILE, "Reference message PDU:\n%s", print_binary((pj_uint8_t*)v->pdu, v->pdu_len))); /* Try to parse the reference message first */ status = pj_stun_msg_decode(pool, (pj_uint8_t*)v->pdu, v->pdu_len, PJ_STUN_IS_DATAGRAM | PJ_STUN_CHECK_PACKET, &ref_msg, &parsed_len, NULL); if (status != PJ_SUCCESS) { PJ_LOG(1,(THIS_FILE, " Error decoding reference message")); rc = -1010; goto on_return; } if (parsed_len != v->pdu_len) { PJ_LOG(1,(THIS_FILE, " Parsed len error")); rc = -1020; goto on_return; } /* Print the reference message */ pj_stun_msg_dump(ref_msg, print, sizeof(print), NULL); PJ_LOG(4,(THIS_FILE, "Reference message:\n%s", print)); /* Create our message */ msg = v->create(pool, v); if (msg == NULL) { PJ_LOG(1,(THIS_FILE, " Error creating stun message")); rc = -1030; goto on_return; } /* Encode message */ if (v->options & USE_MESSAGE_INTEGRITY) { pj_str_t s1, s2, r; pj_stun_create_key(pool, &key, pj_cstr(&r, v->realm), pj_cstr(&s1, v->username), PJ_STUN_PASSWD_PLAIN, pj_cstr(&s2, v->password)); pj_stun_msg_encode(msg, buf, sizeof(buf), 0, &key, &len); } else { pj_stun_msg_encode(msg, buf, sizeof(buf), 0, NULL, &len); } /* Print our raw message */ PJ_LOG(4,(THIS_FILE, "Message PDU:\n%s", print_binary((pj_uint8_t*)buf, len))); /* Print our message */ pj_stun_msg_dump(msg, print, sizeof(print), NULL); PJ_LOG(4,(THIS_FILE, "Message is:\n%s", print)); /* Compare message length */ if (len != v->pdu_len) { PJ_LOG(1,(THIS_FILE, " Message length mismatch")); rc = -1050; goto on_return; } pos = cmp_buf(buf, (const pj_uint8_t*)v->pdu, len); if (pos != (unsigned)-1) { PJ_LOG(1,(THIS_FILE, " Message mismatch at byte %d", pos)); rc = -1060; goto on_return; } /* Authenticate the request/response */ if (v->options & USE_MESSAGE_INTEGRITY) { if (PJ_STUN_IS_REQUEST(msg->hdr.type)) { pj_stun_auth_cred cred; pj_status_t status; pj_bzero(&cred, sizeof(cred)); cred.type = PJ_STUN_AUTH_CRED_STATIC; cred.data.static_cred.realm = pj_str(v->realm); cred.data.static_cred.username = pj_str(v->username); cred.data.static_cred.data = pj_str(v->password); cred.data.static_cred.nonce = pj_str(v->nonce); status = pj_stun_authenticate_request(buf, len, msg, &cred, pool, NULL, NULL); if (status != PJ_SUCCESS) { char errmsg[PJ_ERR_MSG_SIZE]; pj_strerror(status, errmsg, sizeof(errmsg)); PJ_LOG(1,(THIS_FILE, " Request authentication failed: %s", errmsg)); rc = -1070; goto on_return; } } else if (PJ_STUN_IS_RESPONSE(msg->hdr.type)) { pj_status_t status; status = pj_stun_authenticate_response(buf, len, msg, &key); if (status != PJ_SUCCESS) { char errmsg[PJ_ERR_MSG_SIZE]; pj_strerror(status, errmsg, sizeof(errmsg)); PJ_LOG(1,(THIS_FILE, " Response authentication failed: %s", errmsg)); rc = -1080; goto on_return; } } } } on_return: pj_pool_release(pool); return rc; }