forked from cory/tildefriends
		
	A variety of potential protocol/rpc fixes.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4119 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
		
							
								
								
									
										106
									
								
								src/ssb.c
									
									
									
									
									
								
							
							
						
						
									
										106
									
								
								src/ssb.c
									
									
									
									
									
								
							@@ -61,7 +61,7 @@ typedef enum {
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
	k_connections_changed_callbacks_max = 8,
 | 
			
		||||
	k_tf_ssb_rpc_message_body_length_max = 65536,
 | 
			
		||||
	k_tf_ssb_rpc_message_body_length_max = 64 * 1024,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct _tf_ssb_broadcast_t tf_ssb_broadcast_t;
 | 
			
		||||
@@ -446,6 +446,13 @@ static void _tf_ssb_connection_box_stream_send(tf_ssb_connection_t* connection,
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (size > 65535)
 | 
			
		||||
	{
 | 
			
		||||
		_tf_ssb_connection_close(connection, "sending message that is too big");
 | 
			
		||||
		tf_free(message_enc);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	uint8_t header[18];
 | 
			
		||||
	*(uint16_t*)header = htons((uint16_t)size);
 | 
			
		||||
	memcpy(header + sizeof(uint16_t), message_enc + 34 - 16, 16);
 | 
			
		||||
@@ -630,7 +637,8 @@ void tf_ssb_connection_rpc_send_error_method_not_allowed(tf_ssb_connection_t* co
 | 
			
		||||
	const char* k_unsupported = "{\"message\": \"method: is not in list of allowed methods\", \"name\": \"Error\", \"stack\": \"none\"}";
 | 
			
		||||
	tf_ssb_connection_rpc_send(
 | 
			
		||||
		connection,
 | 
			
		||||
		k_ssb_rpc_flag_json | k_ssb_rpc_flag_end_error | (flags & k_ssb_rpc_flag_stream),
 | 
			
		||||
		k_ssb_rpc_flag_json |
 | 
			
		||||
			((flags & k_ssb_rpc_flag_stream) ? (k_ssb_rpc_flag_stream | k_ssb_rpc_flag_end_error) : 0),
 | 
			
		||||
		request_number,
 | 
			
		||||
		(const uint8_t*)k_unsupported,
 | 
			
		||||
		strlen(k_unsupported),
 | 
			
		||||
@@ -698,6 +706,12 @@ void tf_ssb_calculate_message_id(JSContext* context, JSValue message, char* out_
 | 
			
		||||
	JSValue idval = JS_JSONStringify(context, message, JS_NULL, JS_NewInt32(context, 2));
 | 
			
		||||
	size_t len = 0;
 | 
			
		||||
	const char* messagestr = JS_ToCStringLen(context, &len, idval);
 | 
			
		||||
	if (!messagestr)
 | 
			
		||||
	{
 | 
			
		||||
		memset(out_id, 0, out_id_size);
 | 
			
		||||
		JS_FreeValue(context, idval);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	char* latin1 = tf_strdup(messagestr);
 | 
			
		||||
	uint8_t* write_pos = (uint8_t*)latin1;
 | 
			
		||||
@@ -736,10 +750,23 @@ void tf_ssb_calculate_message_id(JSContext* context, JSValue message, char* out_
 | 
			
		||||
 | 
			
		||||
static bool _tf_ssb_verify_and_strip_signature_internal(JSContext* context, JSValue val, char* out_id, size_t out_id_size, char* out_signature, size_t out_signature_size)
 | 
			
		||||
{
 | 
			
		||||
	JSValue signature = JS_GetPropertyStr(context, val, "signature");
 | 
			
		||||
	if (JS_IsUndefined(signature))
 | 
			
		||||
	{
 | 
			
		||||
		memset(out_signature, 0, out_signature_size);
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const char* str = JS_ToCString(context, signature);
 | 
			
		||||
	if (!str)
 | 
			
		||||
	{
 | 
			
		||||
		JS_FreeValue(context, signature);
 | 
			
		||||
		memset(out_signature, 0, out_signature_size);
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bool verified = false;
 | 
			
		||||
	tf_ssb_calculate_message_id(context, val, out_id, out_id_size);
 | 
			
		||||
	JSValue signature = JS_GetPropertyStr(context, val, "signature");
 | 
			
		||||
	const char* str = JS_ToCString(context, signature);
 | 
			
		||||
	JSAtom sigatom = JS_NewAtom(context, "signature");
 | 
			
		||||
	JS_DeleteProperty(context, val, sigatom, 0);
 | 
			
		||||
	JS_FreeAtom(context, sigatom);
 | 
			
		||||
@@ -1359,40 +1386,47 @@ static void _tf_ssb_connection_rpc_recv(tf_ssb_connection_t* connection, uint8_t
 | 
			
		||||
 | 
			
		||||
static void _tf_ssb_connection_rpc_recv_push(tf_ssb_connection_t* connection, const uint8_t* data, size_t size)
 | 
			
		||||
{
 | 
			
		||||
	if (connection->rpc_recv_size + size > sizeof(connection->rpc_recv_buffer))
 | 
			
		||||
	size_t size_left = size;
 | 
			
		||||
	size_t size_processed = 0;
 | 
			
		||||
	while (size_left > 0)
 | 
			
		||||
	{
 | 
			
		||||
		_tf_ssb_connection_close(connection, "recv buffer overflow");
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	memcpy(connection->rpc_recv_buffer + connection->rpc_recv_size, data, size);
 | 
			
		||||
	connection->rpc_recv_size += size;
 | 
			
		||||
 | 
			
		||||
	while (connection->rpc_recv_size >= 9)
 | 
			
		||||
	{
 | 
			
		||||
		uint8_t flags = *connection->rpc_recv_buffer;
 | 
			
		||||
		uint32_t body_len;
 | 
			
		||||
		int32_t request_number;
 | 
			
		||||
		memcpy(&body_len, connection->rpc_recv_buffer + 1, sizeof(body_len));
 | 
			
		||||
		body_len = htonl(body_len);
 | 
			
		||||
		memcpy(&request_number, connection->rpc_recv_buffer + 1 + sizeof(body_len), sizeof(request_number));
 | 
			
		||||
		request_number = htonl(request_number);
 | 
			
		||||
 | 
			
		||||
		size_t rpc_size = 9 + body_len;
 | 
			
		||||
		if (connection->rpc_recv_size >= rpc_size)
 | 
			
		||||
		size_t copy_size = (connection->rpc_recv_size + size_left > sizeof(connection->rpc_recv_buffer)) ? sizeof(connection->rpc_recv_buffer) - connection->rpc_recv_size : size_left;
 | 
			
		||||
		if (copy_size == 0)
 | 
			
		||||
		{
 | 
			
		||||
			uint8_t* end = &connection->rpc_recv_buffer[9 + body_len];
 | 
			
		||||
			uint8_t tmp = *end;
 | 
			
		||||
			*end = '\0';
 | 
			
		||||
			_tf_ssb_connection_rpc_recv(connection, flags, request_number, connection->rpc_recv_buffer + 9, body_len);
 | 
			
		||||
			*end = tmp;
 | 
			
		||||
			memmove(connection->rpc_recv_buffer, connection->rpc_recv_buffer + rpc_size, connection->rpc_recv_size - rpc_size);
 | 
			
		||||
			connection->rpc_recv_size -= rpc_size;
 | 
			
		||||
			_tf_ssb_connection_close(connection, "recv buffer overflow");
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		memcpy(connection->rpc_recv_buffer + connection->rpc_recv_size, data + size_processed, copy_size);
 | 
			
		||||
		connection->rpc_recv_size += copy_size;
 | 
			
		||||
		size_processed += copy_size;
 | 
			
		||||
		size_left -= copy_size;
 | 
			
		||||
 | 
			
		||||
		while (connection->rpc_recv_size >= 9)
 | 
			
		||||
		{
 | 
			
		||||
			/* Wait for more body. */
 | 
			
		||||
			break;
 | 
			
		||||
			uint8_t flags = *connection->rpc_recv_buffer;
 | 
			
		||||
			uint32_t body_len;
 | 
			
		||||
			int32_t request_number;
 | 
			
		||||
			memcpy(&body_len, connection->rpc_recv_buffer + 1, sizeof(body_len));
 | 
			
		||||
			body_len = htonl(body_len);
 | 
			
		||||
			memcpy(&request_number, connection->rpc_recv_buffer + 1 + sizeof(body_len), sizeof(request_number));
 | 
			
		||||
			request_number = htonl(request_number);
 | 
			
		||||
 | 
			
		||||
			size_t rpc_size = 9 + body_len;
 | 
			
		||||
			if (connection->rpc_recv_size >= rpc_size)
 | 
			
		||||
			{
 | 
			
		||||
				uint8_t* end = &connection->rpc_recv_buffer[9 + body_len];
 | 
			
		||||
				uint8_t tmp = *end;
 | 
			
		||||
				*end = '\0';
 | 
			
		||||
				_tf_ssb_connection_rpc_recv(connection, flags, request_number, connection->rpc_recv_buffer + 9, body_len);
 | 
			
		||||
				*end = tmp;
 | 
			
		||||
				memmove(connection->rpc_recv_buffer, connection->rpc_recv_buffer + rpc_size, connection->rpc_recv_size - rpc_size);
 | 
			
		||||
				connection->rpc_recv_size -= rpc_size;
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				/* Wait for more body. */
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -3078,8 +3112,8 @@ tf_ssb_blob_wants_t* tf_ssb_connection_get_blob_wants_state(tf_ssb_connection_t*
 | 
			
		||||
bool tf_ssb_verify_strip_and_store_message(tf_ssb_t* ssb, JSValue value)
 | 
			
		||||
{
 | 
			
		||||
	JSContext* context = tf_ssb_get_context(ssb);
 | 
			
		||||
	char signature[crypto_sign_BYTES + 128];
 | 
			
		||||
	char id[crypto_hash_sha256_BYTES * 2 + 1];
 | 
			
		||||
	char signature[crypto_sign_BYTES + 128] = { 0 };
 | 
			
		||||
	char id[crypto_hash_sha256_BYTES * 2 + 1] = { 0 };
 | 
			
		||||
	bool sequence_before_author = false;
 | 
			
		||||
	if (tf_ssb_verify_and_strip_signature(context, value, id, sizeof(id), signature, sizeof(signature), &sequence_before_author))
 | 
			
		||||
	{
 | 
			
		||||
 
 | 
			
		||||
@@ -367,6 +367,11 @@ static void _tf_ssb_rpc_room_meta(tf_ssb_connection_t* connection, uint8_t flags
 | 
			
		||||
	JS_FreeValue(context, response);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _tf_ssb_rpc_room_attendants_callback(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, JSValue args, const uint8_t* message, size_t size, void* user_data)
 | 
			
		||||
{
 | 
			
		||||
	printf("room attendants callback??\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _tf_ssb_rpc_room_attendants(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, JSValue args, const uint8_t* message, size_t size, void* user_data)
 | 
			
		||||
{
 | 
			
		||||
	tf_ssb_t* ssb = tf_ssb_connection_get_ssb(connection);
 | 
			
		||||
@@ -416,6 +421,7 @@ static void _tf_ssb_rpc_room_attendants(tf_ssb_connection_t* connection, uint8_t
 | 
			
		||||
	JS_FreeValue(context, state);
 | 
			
		||||
 | 
			
		||||
	tf_ssb_connection_set_attendant(connection, true, request_number);
 | 
			
		||||
	tf_ssb_connection_add_request(connection, -request_number, _tf_ssb_rpc_room_attendants_callback, NULL, NULL, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
typedef struct _blobs_get_t
 | 
			
		||||
@@ -966,6 +972,10 @@ static void _tf_ssb_rpc_send_ebt_replicate(tf_ssb_connection_t* connection)
 | 
			
		||||
 | 
			
		||||
static void _tf_ssb_rpc_ebt_replicate_server(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, JSValue args, const uint8_t* message, size_t size, void* user_data)
 | 
			
		||||
{
 | 
			
		||||
	if (flags & k_ssb_rpc_flag_end_error)
 | 
			
		||||
	{
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	_tf_ssb_rpc_ebt_replicate(connection, flags, request_number, args, message, size, user_data);
 | 
			
		||||
	tf_ssb_connection_add_request(connection, -request_number, _tf_ssb_rpc_ebt_replicate, NULL, NULL, NULL);
 | 
			
		||||
}
 | 
			
		||||
@@ -1053,7 +1063,7 @@ void tf_ssb_rpc_register(tf_ssb_t* ssb)
 | 
			
		||||
	tf_ssb_add_rpc_callback(ssb, (const char*[]) { "blobs", "createWants", NULL }, _tf_ssb_rpc_blobs_createWants, NULL, NULL);
 | 
			
		||||
	tf_ssb_add_rpc_callback(ssb, (const char*[]) { "tunnel", "connect", NULL }, _tf_ssb_rpc_tunnel_connect, NULL, NULL);
 | 
			
		||||
	tf_ssb_add_rpc_callback(ssb, (const char*[]) { "tunnel", "isRoom", NULL }, _tf_ssb_rpc_room_meta, NULL, NULL);
 | 
			
		||||
	tf_ssb_add_rpc_callback(ssb, (const char*[]) { "room", "meta", NULL }, _tf_ssb_rpc_room_meta, NULL, NULL);
 | 
			
		||||
	tf_ssb_add_rpc_callback(ssb, (const char*[]) { "room", "metadata", NULL }, _tf_ssb_rpc_room_meta, NULL, NULL);
 | 
			
		||||
	tf_ssb_add_rpc_callback(ssb, (const char*[]) { "room", "attendants", NULL }, _tf_ssb_rpc_room_attendants, NULL, NULL);
 | 
			
		||||
	tf_ssb_add_rpc_callback(ssb, (const char*[]) { "createHistoryStream", NULL }, _tf_ssb_rpc_createHistoryStream, NULL, NULL);
 | 
			
		||||
	tf_ssb_add_rpc_callback(ssb, (const char*[]) { "ebt", "replicate", NULL }, _tf_ssb_rpc_ebt_replicate_server, NULL, NULL);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user