Ticket #287: selectively disable authentication for several STUN error responses

git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@1290 74dad513-b988-da41-8d7b-12977e46ad98
This commit is contained in:
Benny Prijono 2007-05-23 07:05:59 +00:00
parent eb92128714
commit edd4ffa870
3 changed files with 59 additions and 3 deletions

View File

@ -294,6 +294,19 @@ PJ_DECL(pj_status_t) pj_stun_authenticate_request(const pj_uint8_t *pkt,
pj_stun_msg **p_response);
/**
* Determine if STUN message can be authenticated. Some STUN error
* responses cannot be authenticated since they cannot contain STUN
* MESSAGE-INTEGRITY attribute. STUN Indication messages also cannot
* be authenticated.
*
* @param msg The STUN message.
*
* @return Non-zero if the STUN message can be authenticated.
*/
PJ_DECL(pj_bool_t) pj_stun_auth_valid_for_msg(const pj_stun_msg *msg);
/**
* Verify credential in the STUN response. Note that before calling this
* function, application must have checked that the message contains

View File

@ -21,8 +21,10 @@
#include <pjlib-util/hmac_sha1.h>
#include <pjlib-util/sha1.h>
#include <pj/assert.h>
#include <pj/log.h>
#include <pj/string.h>
#define THIS_FILE "stun_auth.c"
/* Duplicate credential */
PJ_DEF(void) pj_stun_auth_cred_dup( pj_pool_t *pool,
@ -348,6 +350,47 @@ PJ_DEF(pj_status_t) pj_stun_authenticate_request(const pj_uint8_t *pkt,
}
/* Determine if STUN message can be authenticated */
PJ_DEF(pj_bool_t) pj_stun_auth_valid_for_msg(const pj_stun_msg *msg)
{
unsigned msg_type = msg->hdr.type;
const pj_stun_errcode_attr *err_attr;
/* STUN requests and success response can be authenticated */
if (!PJ_STUN_IS_ERROR_RESPONSE(msg_type) &&
!PJ_STUN_IS_INDICATION(msg_type))
{
return PJ_TRUE;
}
/* STUN Indication cannot be authenticated */
if (PJ_STUN_IS_INDICATION(msg_type))
return PJ_FALSE;
/* Authentication for STUN error responses depend on the error
* code.
*/
err_attr = (const pj_stun_errcode_attr*)
pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_ERROR_CODE, 0);
if (err_attr == NULL) {
PJ_LOG(4,(THIS_FILE, "STUN error code attribute not present in "
"error response"));
return PJ_TRUE;
}
switch (err_attr->err_code) {
case PJ_STUN_SC_UNAUTHORIZED:
case PJ_STUN_SC_MISSING_USERNAME:
case PJ_STUN_SC_MISSING_REALM:
case PJ_STUN_SC_UNKNOWN_USERNAME:
case PJ_STUN_SC_INTEGRITY_CHECK_FAILURE:
return PJ_FALSE;
default:
return PJ_TRUE;
}
}
/* Authenticate MESSAGE-INTEGRITY in the response */
PJ_DEF(pj_status_t) pj_stun_authenticate_response(const pj_uint8_t *pkt,
unsigned pkt_len,

View File

@ -267,8 +267,7 @@ static pj_status_t apply_msg_options(pj_stun_session *sess,
&sess->srv_name);
}
need_auth = PJ_STUN_IS_REQUEST(msg->hdr.type) ||
PJ_STUN_IS_SUCCESS_RESPONSE(msg->hdr.type);
need_auth = pj_stun_auth_valid_for_msg(msg);
if (sess->cred && sess->cred->type == PJ_STUN_AUTH_CRED_STATIC &&
need_auth)
@ -843,7 +842,8 @@ static pj_status_t on_incoming_response(pj_stun_session *sess,
/* Authenticate the message, unless PJ_STUN_NO_AUTHENTICATE
* is specified in the option.
*/
if ((options & PJ_STUN_NO_AUTHENTICATE) == 0 && tdata->auth_key.slen != 0)
if ((options & PJ_STUN_NO_AUTHENTICATE) == 0 && tdata->auth_key.slen != 0
&& pj_stun_auth_valid_for_msg(msg))
{
status = pj_stun_authenticate_response(pkt, pkt_len, msg,
&tdata->auth_key);