|
@@ -27,6 +27,7 @@
|
|
* History
|
|
* History
|
|
* --------
|
|
* --------
|
|
* 2006-10-13 created (vlada)
|
|
* 2006-10-13 created (vlada)
|
|
|
|
+ * 2006-12-14 fixed calculation of body length (vlada)
|
|
*/
|
|
*/
|
|
|
|
|
|
#ifdef USE_STUN
|
|
#ifdef USE_STUN
|
|
@@ -233,30 +234,16 @@ int stun_parse_body(
|
|
fp_present = 0;
|
|
fp_present = 0;
|
|
|
|
|
|
/*
|
|
/*
|
|
- * the message length is different for rfc and rfc bis
|
|
|
|
- * the bis version contains fingerprint that is not included in
|
|
|
|
- * length of body which is listed in header of message
|
|
|
|
|
|
+ * Mark the body lenght as unparsed.
|
|
*/
|
|
*/
|
|
not_parsed = req->msg.buf.len - sizeof(struct stun_hdr);
|
|
not_parsed = req->msg.buf.len - sizeof(struct stun_hdr);
|
|
|
|
|
|
- if (req->old) {
|
|
|
|
- if (not_parsed != req->hdr.len) {
|
|
|
|
|
|
+ if (not_parsed != req->hdr.len) {
|
|
#ifdef EXTRA_DEBUG
|
|
#ifdef EXTRA_DEBUG
|
|
- LOG(L_DBG, "DEBUG: stun_parse_body: body too short to be valid\n");
|
|
|
|
|
|
+ LOG(L_DBG, "DEBUG: stun_parse_body: body too short to be valid\n");
|
|
#endif
|
|
#endif
|
|
- *error_code = BAD_REQUEST_ERR;
|
|
|
|
- return 0;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- else {
|
|
|
|
- if (not_parsed !=
|
|
|
|
- req->hdr.len + SHA_DIGEST_LENGTH + sizeof(struct stun_attr)) {
|
|
|
|
-#ifdef EXTRA_DEBUG
|
|
|
|
- LOG(L_DBG, "DEBUG: stun_parse_body: body too short to be valid\n");
|
|
|
|
-#endif
|
|
|
|
- *error_code = BAD_REQUEST_ERR;
|
|
|
|
- return 0;
|
|
|
|
- }
|
|
|
|
|
|
+ *error_code = BAD_REQUEST_ERR;
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
|
|
|
|
tmp_unknown = *unknown;
|
|
tmp_unknown = *unknown;
|
|
@@ -425,6 +412,7 @@ int stun_create_response(
|
|
struct stun_unknown_att* unknown,
|
|
struct stun_unknown_att* unknown,
|
|
UINT_T error_code)
|
|
UINT_T error_code)
|
|
{
|
|
{
|
|
|
|
+ UINT_T msg_len;
|
|
/*
|
|
/*
|
|
* Alloc some space for response.
|
|
* Alloc some space for response.
|
|
* Optimalization? - maybe it would be better to use biggish static array.
|
|
* Optimalization? - maybe it would be better to use biggish static array.
|
|
@@ -523,31 +511,41 @@ int stun_create_response(
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- /* count length of body except header and fingerprint
|
|
|
|
- * and copy message length at the beginning of buffer
|
|
|
|
- */
|
|
|
|
- res->hdr.len = htons(res->msg.buf.len - sizeof(struct stun_hdr));
|
|
|
|
- memcpy(&res->msg.buf.s[sizeof(USHORT_T)], (void *) &res->hdr.len,
|
|
|
|
- sizeof(USHORT_T));
|
|
|
|
-
|
|
|
|
if (req->old == 0) {
|
|
if (req->old == 0) {
|
|
- /* add optional information about server */
|
|
|
|
|
|
+ /*
|
|
|
|
+ * add optional information about server; attribute SERVER is not a part of
|
|
|
|
+ * rfc3489.txt
|
|
|
|
+ * */
|
|
if (stun_add_common_text_attr(res, SERVER_ATTR, SERVER_HDR, PAD4)!=0) {
|
|
if (stun_add_common_text_attr(res, SERVER_ATTR, SERVER_HDR, PAD4)!=0) {
|
|
#ifdef EXTRA_DEBUG
|
|
#ifdef EXTRA_DEBUG
|
|
LOG(L_DBG, "DEBUG: stun_create_response: failed to add common text attribute\n");
|
|
LOG(L_DBG, "DEBUG: stun_create_response: failed to add common text attribute\n");
|
|
#endif
|
|
#endif
|
|
return FATAL_ERROR;
|
|
return FATAL_ERROR;
|
|
}
|
|
}
|
|
-
|
|
|
|
- if (stun_allow_fp) {
|
|
|
|
- if (add_fingerprint(&res->msg) != 0) {
|
|
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (req->old == 0 && stun_allow_fp) {
|
|
|
|
+ /* count length of body except header and fingerprint
|
|
|
|
+ * and copy message length at the beginning of buffer
|
|
|
|
+ */
|
|
|
|
+ msg_len = res->msg.buf.len - sizeof(struct stun_hdr);
|
|
|
|
+ msg_len += SHA_DIGEST_LENGTH + sizeof(struct stun_attr);
|
|
|
|
+ res->hdr.len = htons(msg_len);
|
|
|
|
+ memcpy(&res->msg.buf.s[sizeof(USHORT_T)], (void *) &res->hdr.len,
|
|
|
|
+ sizeof(USHORT_T));
|
|
|
|
+
|
|
|
|
+ if (add_fingerprint(&res->msg) != 0) {
|
|
#ifdef EXTRA_DEBUG
|
|
#ifdef EXTRA_DEBUG
|
|
- LOG(L_DBG, "DEBUG: stun_create_response: failed to add fingerprint\n");
|
|
|
|
|
|
+ LOG(L_DBG, "DEBUG: stun_create_response: failed to add fingerprint\n");
|
|
#endif
|
|
#endif
|
|
- return FATAL_ERROR;
|
|
|
|
- }
|
|
|
|
|
|
+ return FATAL_ERROR;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ else {
|
|
|
|
+ res->hdr.len = htons(res->msg.buf.len - sizeof(struct stun_hdr));
|
|
|
|
+ memcpy(&res->msg.buf.s[sizeof(USHORT_T)], (void *) &res->hdr.len,
|
|
|
|
+ sizeof(USHORT_T));
|
|
|
|
+ }
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -957,7 +955,8 @@ int validate_fingerprint(struct stun_msg* req, USHORT_T* error_code)
|
|
UCHAR_T msg_digest[SHA_DIGEST_LENGTH];
|
|
UCHAR_T msg_digest[SHA_DIGEST_LENGTH];
|
|
UINT_T buf_len;
|
|
UINT_T buf_len;
|
|
|
|
|
|
- buf_len = req->hdr.len+sizeof(struct stun_hdr);
|
|
|
|
|
|
+ buf_len = req->hdr.len + sizeof(struct stun_hdr);
|
|
|
|
+ buf_len -= SHA_DIGEST_LENGTH + sizeof(struct stun_attr);
|
|
|
|
|
|
if (SHA1((UCHAR_T *) req->msg.buf.s, buf_len, msg_digest) == 0) {
|
|
if (SHA1((UCHAR_T *) req->msg.buf.s, buf_len, msg_digest) == 0) {
|
|
LOG(L_ERR, "ERROR: STUN: SHA-1 algorithm failed.\n");
|
|
LOG(L_ERR, "ERROR: STUN: SHA-1 algorithm failed.\n");
|