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:
parent
6ed057089b
commit
f6ae15c4dc
106
src/ssb.c
106
src/ssb.c
@ -61,7 +61,7 @@ typedef enum {
|
|||||||
|
|
||||||
enum {
|
enum {
|
||||||
k_connections_changed_callbacks_max = 8,
|
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;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (size > 65535)
|
||||||
|
{
|
||||||
|
_tf_ssb_connection_close(connection, "sending message that is too big");
|
||||||
|
tf_free(message_enc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t header[18];
|
uint8_t header[18];
|
||||||
*(uint16_t*)header = htons((uint16_t)size);
|
*(uint16_t*)header = htons((uint16_t)size);
|
||||||
memcpy(header + sizeof(uint16_t), message_enc + 34 - 16, 16);
|
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\"}";
|
const char* k_unsupported = "{\"message\": \"method: is not in list of allowed methods\", \"name\": \"Error\", \"stack\": \"none\"}";
|
||||||
tf_ssb_connection_rpc_send(
|
tf_ssb_connection_rpc_send(
|
||||||
connection,
|
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,
|
request_number,
|
||||||
(const uint8_t*)k_unsupported,
|
(const uint8_t*)k_unsupported,
|
||||||
strlen(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));
|
JSValue idval = JS_JSONStringify(context, message, JS_NULL, JS_NewInt32(context, 2));
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
const char* messagestr = JS_ToCStringLen(context, &len, idval);
|
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);
|
char* latin1 = tf_strdup(messagestr);
|
||||||
uint8_t* write_pos = (uint8_t*)latin1;
|
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)
|
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;
|
bool verified = false;
|
||||||
tf_ssb_calculate_message_id(context, val, out_id, out_id_size);
|
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");
|
JSAtom sigatom = JS_NewAtom(context, "signature");
|
||||||
JS_DeleteProperty(context, val, sigatom, 0);
|
JS_DeleteProperty(context, val, sigatom, 0);
|
||||||
JS_FreeAtom(context, sigatom);
|
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)
|
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");
|
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;
|
||||||
return;
|
if (copy_size == 0)
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
uint8_t* end = &connection->rpc_recv_buffer[9 + body_len];
|
_tf_ssb_connection_close(connection, "recv buffer overflow");
|
||||||
uint8_t tmp = *end;
|
return;
|
||||||
*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
|
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. */
|
uint8_t flags = *connection->rpc_recv_buffer;
|
||||||
break;
|
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)
|
bool tf_ssb_verify_strip_and_store_message(tf_ssb_t* ssb, JSValue value)
|
||||||
{
|
{
|
||||||
JSContext* context = tf_ssb_get_context(ssb);
|
JSContext* context = tf_ssb_get_context(ssb);
|
||||||
char signature[crypto_sign_BYTES + 128];
|
char signature[crypto_sign_BYTES + 128] = { 0 };
|
||||||
char id[crypto_hash_sha256_BYTES * 2 + 1];
|
char id[crypto_hash_sha256_BYTES * 2 + 1] = { 0 };
|
||||||
bool sequence_before_author = false;
|
bool sequence_before_author = false;
|
||||||
if (tf_ssb_verify_and_strip_signature(context, value, id, sizeof(id), signature, sizeof(signature), &sequence_before_author))
|
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);
|
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)
|
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);
|
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);
|
JS_FreeValue(context, state);
|
||||||
|
|
||||||
tf_ssb_connection_set_attendant(connection, true, request_number);
|
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
|
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)
|
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_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);
|
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*[]) { "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", "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*[]) { "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*[]) { "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*[]) { "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);
|
tf_ssb_add_rpc_callback(ssb, (const char*[]) { "ebt", "replicate", NULL }, _tf_ssb_rpc_ebt_replicate_server, NULL, NULL);
|
||||||
|
Loading…
Reference in New Issue
Block a user