summaryrefslogtreecommitdiffstats
path: root/branches/1.0/tinyNET/src/stun/tnet_stun_message.c
diff options
context:
space:
mode:
Diffstat (limited to 'branches/1.0/tinyNET/src/stun/tnet_stun_message.c')
-rw-r--r--branches/1.0/tinyNET/src/stun/tnet_stun_message.c440
1 files changed, 0 insertions, 440 deletions
diff --git a/branches/1.0/tinyNET/src/stun/tnet_stun_message.c b/branches/1.0/tinyNET/src/stun/tnet_stun_message.c
deleted file mode 100644
index 9769092..0000000
--- a/branches/1.0/tinyNET/src/stun/tnet_stun_message.c
+++ /dev/null
@@ -1,440 +0,0 @@
-/*
-* Copyright (C) 2009-2010 Mamadou Diop.
-*
-* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
-*
-* This file is part of Open Source Doubango Framework.
-*
-* DOUBANGO is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, either version 3 of the License, or
-* (at your option) any later version.
-*
-* DOUBANGO is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with DOUBANGO.
-*
-*/
-
-/**@file tnet_stun_message.c
- * @brief STUN2 (RFC 5389) message parser.
- *
- * @author Mamadou Diop <diopmamadou(at)doubango.org>
- *
- * @date Created: Sat Nov 8 16:54:58 2009 mdiop
- */
-#include "tnet_stun_message.h"
-
-#include "tnet_stun.h"
-
-#include "../tnet_types.h"
-#include "../tnet_endianness.h"
-#include "../turn/tnet_turn_attribute.h"
-
-#include "tsk_memory.h"
-#include "tsk_hmac.h"
-#include "tsk_string.h"
-#include "tsk_ppfcs32.h"
-
-#include <string.h>
-
-
-/**@ingroup tnet_stun_group
-* Creates new STUN message.
-* @retval @ref tnet_stun_message_t object.
-* @sa tnet_stun_message_create_null.
-*/
-
-tnet_stun_message_t* tnet_stun_message_create(const char* username, const char* password)
-{
- return tsk_object_new(tnet_stun_message_def_t, username, password);
-}
-
-/**@ingroup tnet_stun_group
-* Creates new STUN message.
-* @retval @ref tnet_stun_message_t object.
-* @sa tnet_stun_message_create.
-*/
-tnet_stun_message_t* tnet_stun_message_create_null()
-{
- return tnet_stun_message_create(tsk_null, tsk_null);
-}
-
-#define SERIALIZE_N_ADD_ATTRIBUTE(att_name, payload, payload_size) \
- attribute = (tnet_stun_attribute_t *)tnet_stun_attribute_##att_name##_create(payload, payload_size); \
- tnet_stun_attribute_serialize(attribute, output); \
- tnet_stun_attribute_pad(attribute, output); \
- TSK_OBJECT_SAFE_FREE(attribute);
-
-/**@ingroup tnet_stun_group
- * Serializes a STUN message as binary data.
- * @param [in,out] self The STUN message to serialize.
- * @retval A buffer holding the binary data (result) if serialization succeed and zero otherwise.
-**/
-tsk_buffer_t* tnet_stun_message_serialize(const tnet_stun_message_t *self)
-{
- tsk_buffer_t *output = 0;
- tnet_stun_attribute_t *attribute;
- unsigned compute_integrity = self->integrity;
-
- if(!self){
- goto bail;
- }
-
- output = tsk_buffer_create_null();
-
- /* RFC 5389 - 6. STUN Message Structure
- 0 1 2 3
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- |0 0| STUN Message Type | Message Length |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Magic Cookie |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | |
- | Transaction ID (96 bits) |
- | |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-
- /* STUN Message Type
- */
- {
- uint16_t type = tnet_htons(self->type);
- tsk_buffer_append(output, &(type), 2);
- }
-
- /* Message Length ==> Will be updated after attributes have been added. */
- {
- uint16_t length = 0;
- tsk_buffer_append(output, &(length), 2);
- }
-
- /* Magic Cookie
- */
- {
- uint32_t cookie = tnet_htonl(self->cookie);
- tsk_buffer_append(output, &(cookie), 4);
- }
-
-
- /* Transaction ID (96 bits==>16bytes)
- */
- tsk_buffer_append(output, self->transaction_id, TNET_STUN_TRANSACID_SIZE);
-
- /* DONT-FRAGMENT
- */
- if(self->dontfrag){
- attribute = (tnet_stun_attribute_t *)tnet_turn_attribute_dontfrag_create();
- tnet_stun_attribute_serialize(attribute, output);
- TSK_OBJECT_SAFE_FREE(attribute);
- }
-
- /*=== Attributes ===
- */
- {
- tsk_list_item_t *item;
- tsk_list_foreach(item, self->attributes)
- {
- attribute = item->data;
- tnet_stun_attribute_serialize(attribute, output);
- tnet_stun_attribute_pad(attribute, output);
- }
- }
-
- /* AUTHENTICATION */
- if(self->realm && self->nonce){
- SERIALIZE_N_ADD_ATTRIBUTE(username, self->username, tsk_strlen(self->username));
- SERIALIZE_N_ADD_ATTRIBUTE(realm, self->realm, tsk_strlen(self->realm));
- SERIALIZE_N_ADD_ATTRIBUTE(nonce, self->nonce, tsk_strlen(self->nonce));
-
- compute_integrity = 1;
- }
-
- /* Message Length: The message length MUST contain the size, in bytes, of the message
- not including the 20-byte STUN header.
- */
- {
- uint16_t length = (output->size) - TNET_STUN_HEADER_SIZE;
- if(self->fingerprint)
- length += (2/* Type */ + 2 /* Length */+ 4 /* FINGERPRINT VALUE*/);
-
- if(compute_integrity)
- length += (2/* Type */ + 2 /* Length */+ TSK_SHA1_DIGEST_SIZE /* INTEGRITY VALUE*/);
-
- *(((uint16_t*)output->data)+1) = tnet_htons(length);
- }
-
- /* MESSAGE-INTEGRITY */
- if(compute_integrity){
- /* RFC 5389 - 15.4. MESSAGE-INTEGRITY
- The MESSAGE-INTEGRITY attribute contains an HMAC-SHA1 [RFC2104] of the STUN message.
-
- For long-term credentials ==> key = MD5(username ":" realm ":" SASLprep(password))
- For short-term credentials ==> key = SASLprep(password)
- FIXME: what about short term credentials?
- FIXME: what about SASLprep
- */
- char* keystr = 0;
- tsk_sha1digest_t hmac;
- tsk_md5digest_t md5;
-
- tsk_sprintf(&keystr, "%s:%s:%s", self->username, self->realm, self->password);
- TSK_MD5_DIGEST_CALC(keystr, tsk_strlen(keystr), md5);
- hmac_sha1digest_compute(output->data, output->size, (const char*)md5, TSK_MD5_DIGEST_SIZE, hmac);
-
- SERIALIZE_N_ADD_ATTRIBUTE(integrity, hmac, TSK_SHA1_DIGEST_SIZE);
-
- TSK_FREE(keystr);
- }
-
- /* FINGERPRINT */
- if(self->fingerprint){
- /* RFC 5389 - 15.5. FINGERPRINT
- The FINGERPRINT attribute MAY be present in all STUN messages. The
- value of the attribute is computed as the CRC-32 of the STUN message
- up to (but excluding) the FINGERPRINT attribute itself, XOR'ed with
- the 32-bit value 0x5354554e
- */
- uint32_t fingerprint = tsk_pppfcs32(TSK_PPPINITFCS32, output->data, output->size);
- fingerprint ^= 0x5354554e;
- fingerprint = tnet_htonl(fingerprint);
-
- attribute = (tnet_stun_attribute_t *)tnet_stun_attribute_fingerprint_create(fingerprint);
- tnet_stun_attribute_serialize(attribute, output);
- TSK_OBJECT_SAFE_FREE(attribute);
- }
-
-bail:
- return output;
-}
-
-
-/**@ingroup tnet_stun_group
- *
- * Deserializes a STUN message from binary data.
- *
- * @param [in,out] data A pointer to the binary data.
- * @param size The size of the binary data.
- *
- * @retval A STUN message if deserialization succeed or NULL otherwise.
-**/
-tnet_stun_message_t* tnet_stun_message_deserialize(const uint8_t *data, tsk_size_t size)
-{
- tnet_stun_message_t *message = 0;
- uint8_t* dataPtr, *dataEnd;
-
-
- if(!data || (size < TNET_STUN_HEADER_SIZE) || !TNET_IS_STUN2(data))
- {
- goto bail;
- }
-
- dataPtr = (uint8_t*)data;
- dataEnd = (dataPtr + size);
-
- message = tnet_stun_message_create_null();
-
- /* Message Type
- */
- message->type = (tnet_stun_message_type_t)tnet_ntohs_2(dataPtr);
- dataPtr += 2;
-
- /* Message Length
- */
- message->length = tnet_ntohs_2(dataPtr);
- dataPtr += 2;
-
- /* Check message validity
- */
- if((message->length + TNET_STUN_HEADER_SIZE) != size)
- {
- TSK_OBJECT_SAFE_FREE(message);
- goto bail;
- }
-
- /* Magic Cookie
- ==> already set by the constructor and checked by @ref TNET_IS_STUN2
- */
- dataPtr += 4;
-
- /* Transaction ID
- */
- memcpy(message->transaction_id, dataPtr, TNET_STUN_TRANSACID_SIZE);
- dataPtr += TNET_STUN_TRANSACID_SIZE;
-
- /* == Parse attributes
- */
- while(dataPtr < dataEnd){
- tnet_stun_attribute_t *attribute = tnet_stun_attribute_deserialize(dataPtr, (dataEnd - dataPtr));
- if(attribute){
- tsk_size_t att_size = (attribute->length + 2 /* Type*/ + 2/* Length */);
- att_size += (att_size%4) ? 4-(att_size%4) : 0; // Skip zero bytes used to pad the attribute.
-
- dataPtr += att_size;
- tsk_list_push_back_data(message->attributes, (void**)&attribute);
-
- continue;
- }
- else{
- continue;
- }
-
-
-
-
- }
-
-
-bail:
- return message;
-}
-
-/**@ingroup tnet_stun_group
-* Adds an attribute to a STUN message.
-* @param self The STUN message into which to add the attribute.
-* @param attribute The attribute to add.
-* @retval Zero if succeed and non-zero error code otherwise.
-*/
-int tnet_stun_message_add_attribute(tnet_stun_message_t *self, tnet_stun_attribute_t** attribute)
-{
- //if(self && attribute)
- {
- tsk_list_push_back_data(self->attributes, (void**)attribute);
- return 0;
- }
- return -1;
-}
-
-/**@ingroup tnet_stun_group
-* Gets a STUN attribute from a message.
-* @param self The message from which to get the attribute.
-* @param type The type of the attribute to retrieve.
-* @retval @ref tnet_stun_attribute_t object if found and NULL otherwise.
-*/
-const tnet_stun_attribute_t* tnet_stun_message_get_attribute(const tnet_stun_message_t *self, tnet_stun_attribute_type_t type)
-{
- tnet_stun_attribute_t* attribute;
-
- if(self && !TSK_LIST_IS_EMPTY(self->attributes)){
- tsk_list_item_t *item;
- tsk_list_foreach(item, self->attributes){
- if((attribute = item->data) && attribute->type == type){
- return attribute;
- }
- }
- }
- return 0;
-}
-
-/**@ingroup tnet_stun_group
-* Gets the STUN error-code attribute value from the message.
-* @param self The STUN message from which to get the error code.
-* @retval The error code if the message contain such attribute or -1 otherwise.
-*/
-short tnet_stun_message_get_errorcode(const tnet_stun_message_t *self)
-{
- const tnet_stun_attribute_errorcode_t* error = (const tnet_stun_attribute_errorcode_t*)tnet_stun_message_get_attribute(self, stun_error_code);
- if(error){
- return ((error->_class*100) + error->number);
- }
- return -1;
-}
-
-/**@ingroup tnet_stun_group
-* Gets the STUN @b realm attribute value from the message.
-* @param self The STUN message from which to get the @b realm.
-* @retval The @b realm as a string pointer code if the message contain such attribute or NULL otherwise.
-*/
-const char* tnet_stun_message_get_realm(const tnet_stun_message_t *self)
-{
- const tnet_stun_attribute_realm_t* realm = (const tnet_stun_attribute_realm_t*)tnet_stun_message_get_attribute(self, stun_realm);
- if(realm){
- return realm->value;
- }
- return 0;
-}
-
-/**@ingroup tnet_stun_group
-* Gets the STUN @b nonce attribute value from the message.
-* @param self The STUN message from which to get the @b nonce.
-* @retval The @b nonce as a string pointer code if the message contain such attribute or NULL otherwise.
-*/
-const char* tnet_stun_message_get_nonce(const tnet_stun_message_t *self)
-{
- const tnet_stun_attribute_nonce_t* nonce = (const tnet_stun_attribute_nonce_t*)tnet_stun_message_get_attribute(self, stun_nonce);
- if(nonce){
- return nonce->value;
- }
- return 0;
-}
-
-/**@ingroup tnet_stun_group
-* Gets the STUN @b lifetime attribute value from the message.
-* @param self The STUN message from which to get the @b lifetime.
-* @retval The @b lifetime (any positive value) if the message contain such attribute or -1 otherwise.
-*/
-int32_t tnet_stun_message_get_lifetime(const tnet_stun_message_t *self)
-{
- const tnet_turn_attribute_lifetime_t* lifetime = (const tnet_turn_attribute_lifetime_t*)tnet_stun_message_get_attribute(self, stun_lifetime);
- if(lifetime){
- return lifetime->value;
- }
- return -1;
-}
-
-
-
-
-
-
-
-
-
-//=================================================================================================
-// STUN2 MESSAGE object definition
-//
-static tsk_object_t* tnet_stun_message_ctor(tsk_object_t * self, va_list * app)
-{
- tnet_stun_message_t *message = self;
- if(message){
- message->username = tsk_strdup(va_arg(*app, const char*));
- message->password = tsk_strdup(va_arg(*app, const char*));
-
- message->cookie = TNET_STUN_MAGIC_COOKIE;
- message->attributes = tsk_list_create();
-
- message->fingerprint = 1;
- message->integrity = 0;
- }
- return self;
-}
-
-static tsk_object_t* tnet_stun_message_dtor(tsk_object_t * self)
-{
- tnet_stun_message_t *message = self;
- if(message){
- TSK_FREE(message->username);
- TSK_FREE(message->password);
- TSK_FREE(message->realm);
- TSK_FREE(message->nonce);
-
- TSK_OBJECT_SAFE_FREE(message->attributes);
- }
-
- return self;
-}
-
-static const tsk_object_def_t tnet_stun_message_def_s =
-{
- sizeof(tnet_stun_message_t),
- tnet_stun_message_ctor,
- tnet_stun_message_dtor,
- tsk_null,
-};
-const tsk_object_def_t *tnet_stun_message_def_t = &tnet_stun_message_def_s;
-
OpenPOWER on IntegriCloud