summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2007-05-23 07:05:59 +0000
committerBenny Prijono <bennylp@teluu.com>2007-05-23 07:05:59 +0000
commitff0ad1551351f97da64fcbc68e096d830995262c (patch)
treebf91dd46e4418d23998e21324860274b8b4a821d
parent9d72f1aa58317d2667feef40e54eef4d9fb5df29 (diff)
Ticket #287: selectively disable authentication for several STUN error responses
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@1290 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjnath/include/pjnath/stun_auth.h13
-rw-r--r--pjnath/src/pjnath/stun_auth.c43
-rw-r--r--pjnath/src/pjnath/stun_session.c6
3 files changed, 59 insertions, 3 deletions
diff --git a/pjnath/include/pjnath/stun_auth.h b/pjnath/include/pjnath/stun_auth.h
index 2bf190d8..07712be3 100644
--- a/pjnath/include/pjnath/stun_auth.h
+++ b/pjnath/include/pjnath/stun_auth.h
@@ -295,6 +295,19 @@ PJ_DECL(pj_status_t) pj_stun_authenticate_request(const pj_uint8_t *pkt,
/**
+ * 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
* PJ_STUN_ATTR_MESSAGE_INTEGRITY attribute by calling pj_stun_msg_find_attr()
diff --git a/pjnath/src/pjnath/stun_auth.c b/pjnath/src/pjnath/stun_auth.c
index c670bfcd..4e2701f6 100644
--- a/pjnath/src/pjnath/stun_auth.c
+++ b/pjnath/src/pjnath/stun_auth.c
@@ -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,
diff --git a/pjnath/src/pjnath/stun_session.c b/pjnath/src/pjnath/stun_session.c
index dbc71ca9..d3bca520 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);