Explorar o código

Fixed wrong calculation of body length. If the message is in bis format, the length of body must include length of fingerprint.

Vladimir Marek %!s(int64=19) %!d(string=hai) anos
pai
achega
0f315be63f
Modificáronse 1 ficheiros con 33 adicións e 34 borrados
  1. 33 34
      ser_stun.c

+ 33 - 34
ser_stun.c

@@ -27,6 +27,7 @@
  * History
  * --------
  *  2006-10-13  created (vlada)
+ *  2006-12-14  fixed calculation of body length (vlada) 
  */
 
 #ifdef USE_STUN 
@@ -233,30 +234,16 @@ int stun_parse_body(
 	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);
 	
-	if (req->old) {
-		if (not_parsed != req->hdr.len) {
+	if (not_parsed != req->hdr.len) {
 #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
-			*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;
@@ -425,6 +412,7 @@ int stun_create_response(
 						struct stun_unknown_att* unknown, 
 						UINT_T error_code)
 {
+	UINT_T msg_len;
 	/*
 	 * Alloc some space for response.
 	 * 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) {
-		/* 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) {
 #ifdef EXTRA_DEBUG
 			LOG(L_DBG, "DEBUG: stun_create_response: failed to add common text attribute\n");
 #endif
 			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
-				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
-				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;
 }
@@ -957,7 +955,8 @@ int validate_fingerprint(struct stun_msg* req, USHORT_T* error_code)
 	UCHAR_T	msg_digest[SHA_DIGEST_LENGTH];
 	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) {
 		LOG(L_ERR, "ERROR: STUN: SHA-1 algorithm failed.\n");