/*
 * add_fingerprint()
 * 			- msg: response buffer
 * 
 * The function add_fingerprint ensures adding fingerprint attribute into
 * response buffer.
 * 
 * Return value:	0	if there is no environment error
 * 					-1	if there is some enviroment error such as insufficiency
 * 						of memory
 */
int add_fingerprint(struct stun_buffer* msg)
{
	struct stun_attr attr;
	USHORT_T attr_type_size;
	
	attr_type_size = sizeof(struct stun_attr);
	attr.type = htons(FINGERPRINT_ATTR);
	attr.len = htons(SHA_DIGEST_LENGTH);
	
	if (msg->empty < (SHA_DIGEST_LENGTH + attr_type_size)) {
		if (reallock_buffer(msg, SHA_DIGEST_LENGTH + attr_type_size) != 0) {
			return FATAL_ERROR;
		}
	}
	
	memcpy(&msg->buf.s[msg->buf.len], (void *) &attr, attr_type_size);	
	msg->buf.len += attr_type_size;
	msg->empty -= attr_type_size;
	
	if (SHA1((UCHAR_T *)msg->buf.s, msg->buf.len-attr_type_size, 
			 (UCHAR_T *) &msg->buf.s[msg->buf.len]) == 0) {
		LOG(L_ERR, "ERROR: STUN: SHA-1 algorithm failed.\n");
		return FATAL_ERROR;
	}
	
	msg->buf.len += SHA_DIGEST_LENGTH;
	msg->empty -= SHA_DIGEST_LENGTH;
	
	return 0;
}
Esempio n. 2
0
/*
 * buf_copy()
 * 			- msg: buffer where the data will be copy to
 * 			- source: source data buffer
 * 			- len: number of bytes that should be copied
 * 
 * The function buf_copy copies "len" bytes from source into msg buffer
 * 
 * Return value:	0	if there is no environment error
 * 					-1	if there is some enviroment error such as insufficiency
 * 						of memory
 */
static int buf_copy(struct stun_buffer* msg, void* source, UINT_T len)
{
	if (msg->empty < len) {
		if (reallock_buffer(msg, len) != 0) {
			return FATAL_ERROR;
		}
	}
	
	memcpy(&msg->buf.s[msg->buf.len], source, len);
	msg->buf.len += len;
	msg->empty -= len;
	
	return 0;
}
Esempio n. 3
0
/*
 * add_error_code()
 * 			- res: response representation
 * 			- error_code: value of error type
 * 
 * The function add_error_code ensures copy of link list of unknown 
 * attributes into response buffer.
 * 
 * Return value:	0	if there is no environment error
 * 					-1	if there is some enviroment error such as insufficiency
 * 						of memory
 */
static int add_error_code(struct stun_msg* res, USHORT_T error_code)
{
	struct stun_attr attr;
	USHORT_T	orig_len;
	USHORT_T	two_bytes;
	int			text_pad;
	char		err[2];
	
	orig_len = res->msg.buf.len;
	text_pad = 0;
	
	/* the type and length will be copy as last one because of unknown length*/
	if (res->msg.buf.len < sizeof(struct stun_attr)) {
		if (reallock_buffer(&res->msg, sizeof(struct stun_attr)) != 0) {
#ifdef EXTRA_DEBUG
			LOG(L_DBG, "DEBUG: add_error_code: failed to reallocate buffer\n");
#endif
			return FATAL_ERROR;
		}
	}
	res->msg.buf.len += sizeof(struct stun_attr);
	res->msg.empty -= sizeof(struct stun_attr);
	
	/* first two bytes are empty */
	two_bytes = 0x0000;
	
	if (buf_copy(&res->msg, (void *) &two_bytes, sizeof(USHORT_T)) != 0) {
#ifdef EXTRA_DEBUG
		LOG(L_DBG, "DEBUG: add_error_code: failed to copy buffer\n");
#endif
		return FATAL_ERROR;
	}
	
	err[0] = error_code / 100;
	err[1] = error_code % 100;
	if (buf_copy(&res->msg, (void *) err, sizeof(UCHAR_T)*2) != 0) {
		return FATAL_ERROR;
	}
	
	switch (error_code) {
		case TRY_ALTERNATE_ERR:
			text_pad = copy_str_to_buffer(res, TRY_ALTERNATE_TXT, PAD4); 
			break;
		case BAD_REQUEST_ERR:
			text_pad = copy_str_to_buffer(res, BAD_REQUEST_TXT, PAD4); 
			break;
		case UNAUTHORIZED_ERR:
			text_pad = copy_str_to_buffer(res, UNAUTHORIZED_TXT, PAD4); 
			break;
		case UNKNOWN_ATTRIBUTE_ERR:
			text_pad = copy_str_to_buffer(res, UNKNOWN_ATTRIBUTE_TXT, PAD4);
			break;
		case STALE_CREDENTIALS_ERR:
			text_pad = copy_str_to_buffer(res, STALE_CREDENTIALS_TXT, PAD4); 
			break;
		case INTEGRITY_CHECK_ERR:
			text_pad = copy_str_to_buffer(res, INTEGRITY_CHECK_TXT, PAD4); 
			break;
		case MISSING_USERNAME_ERR:
			text_pad = copy_str_to_buffer(res, MISSING_USERNAME_TXT, PAD4); 
			break;
		case USE_TLS_ERR:
			text_pad = copy_str_to_buffer(res, USE_TLS_TXT, PAD4); 
			break;
		case MISSING_REALM_ERR:
			text_pad = copy_str_to_buffer(res, MISSING_REALM_TXT, PAD4); 
			break;
		case MISSING_NONCE_ERR:
			text_pad = copy_str_to_buffer(res, MISSING_NONCE_TXT, PAD4); 
			break;
		case UNKNOWN_USERNAME_ERR:
			text_pad = copy_str_to_buffer(res, UNKNOWN_USERNAME_TXT, PAD4); 
			break;
		case STALE_NONCE_ERR:
			text_pad = copy_str_to_buffer(res, STALE_NONCE_TXT, PAD4);
			break;
		case SERVER_ERROR_ERR:
			text_pad = copy_str_to_buffer(res, SERVER_ERROR_TXT, PAD4); 
			break;
		case GLOBAL_FAILURE_ERR:
			text_pad = copy_str_to_buffer(res, GLOBAL_FAILURE_TXT, PAD4); 
			break;
		default:
			LOG(L_ERR, "ERROR: STUN: Unknown error code.\n");
			break;
	}
	if (text_pad < 0) {
#ifdef EXTRA_DEBUG
		LOG(L_DBG, "DEBUG: add_error_code: text_pad is negative\n");
#endif
		goto error;
	}
	attr.type = htons(ERROR_CODE_ATTR);
	/* count length of "value" field -> without type and lehgth field */
	attr.len = htons(res->msg.buf.len - orig_len - 
					 text_pad - sizeof(struct stun_attr));
	memcpy(&res->msg.buf.s[orig_len], (void *)&attr, sizeof(struct stun_attr));
	
	return 0;

error:
	return FATAL_ERROR;
}