From edd4ffa870e51cdc5f3d0b42f19473bd934f3189 Mon Sep 17 00:00:00 2001 From: Benny Prijono Date: Wed, 23 May 2007 07:05:59 +0000 Subject: [PATCH] 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 --- pjnath/include/pjnath/stun_auth.h | 13 ++++++++++ pjnath/src/pjnath/stun_auth.c | 43 +++++++++++++++++++++++++++++++ pjnath/src/pjnath/stun_session.c | 6 ++--- 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/pjnath/include/pjnath/stun_auth.h b/pjnath/include/pjnath/stun_auth.h index 2bf190d88..07712be3a 100644 --- a/pjnath/include/pjnath/stun_auth.h +++ b/pjnath/include/pjnath/stun_auth.h @@ -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 diff --git a/pjnath/src/pjnath/stun_auth.c b/pjnath/src/pjnath/stun_auth.c index c670bfcd9..4e2701f6d 100644 --- a/pjnath/src/pjnath/stun_auth.c +++ b/pjnath/src/pjnath/stun_auth.c @@ -21,8 +21,10 @@ #include #include #include +#include #include +#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, diff --git a/pjnath/src/pjnath/stun_session.c b/pjnath/src/pjnath/stun_session.c index dbc71ca99..d3bca5209 100644 --- a/pjnath/src/pjnath/stun_session.c +++ b/pjnath/src/pjnath/stun_session.c @@ -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);