wip, doesnt compile: start implementing read functions
This commit is contained in:
parent
505573ee03
commit
495c2a37c2
209
ssb-gtk/sbot.c
209
ssb-gtk/sbot.c
@ -4,6 +4,9 @@
|
||||
|
||||
#include "sbot.h"
|
||||
|
||||
#define MAX_MESSAGE_SIZE 32768
|
||||
#define BOXS_MAXLEN 4096
|
||||
|
||||
struct _SsbScuttler {
|
||||
GObject parent_instance;
|
||||
|
||||
@ -20,6 +23,7 @@ struct _SsbScuttler {
|
||||
guchar nonce1[24];
|
||||
guchar nonce2[24];
|
||||
guchar rx_nonce[24];
|
||||
guchar rx_buf[BOXS_MAXLEN];
|
||||
gsize rx_buf_pos;
|
||||
gsize rx_buf_len;
|
||||
gboolean noauth;
|
||||
@ -56,9 +60,6 @@ typedef enum {
|
||||
SSB_STREAM_STATE_ENDED_ERROR,
|
||||
} SsbStreamState;
|
||||
|
||||
#define MAX_MESSAGE_SIZE 32768
|
||||
#define BOXS_MAXLEN 4096
|
||||
|
||||
G_DEFINE_QUARK(ssb_scttler_error_quark, ssb_scuttler_error);
|
||||
G_DEFINE_TYPE(SsbScuttler, ssb_scuttler, G_TYPE_INITIALLY_UNOWNED);
|
||||
|
||||
@ -367,7 +368,7 @@ read_inbound(GSocket *socket, GIOCondition condition, SsbScuttler *scuttler)
|
||||
data->read_buffer = g_malloc(MAX_MESSAGE_SIZE);
|
||||
|
||||
g_input_stream_read_async(stream,
|
||||
data->read_buffer, MAX_MESSAGE_SIZE,
|
||||
data->read_buffer, 2,
|
||||
G_PRIORITY_DEFAULT,
|
||||
NULL,
|
||||
data_read, data);
|
||||
@ -870,6 +871,206 @@ ssb_scuttler_send_packet(SsbScuttler *scuttler,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
bs_read_packet(SsbScuttler *scuttler, gpointer buf, gsize *lenp, GError **error)
|
||||
{
|
||||
guchar boxed_header[34];
|
||||
gsize len;
|
||||
GError *err = NULL;
|
||||
|
||||
if (!ssb_scuttler_read(scuttler, boxed_header, 34, &err)) {
|
||||
if (err->code == G_IO_ERROR_BROKEN_PIPE) {
|
||||
g_propagate_error(error, err);
|
||||
} else {
|
||||
g_set_error(error,
|
||||
SSB_SCUTTLER_ERROR, SSB_SCUTTLER_ERROR_READ,
|
||||
"Failed to read boxed packet header");
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BoxsHeader header;
|
||||
|
||||
if (crypto_secretbox_open_easy((guchar *
|
||||
)&header, boxed_header, 34, scuttler->rx_nonce, scuttler->decrypt_key) < 0) {
|
||||
g_set_error(error,
|
||||
SSB_SCUTTLER_ERROR, SSB_SCUTTLER_ERROR_DECRYPT,
|
||||
"Failed to unbox packet header");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
increment_nonce(scuttler->rx_nonce);
|
||||
|
||||
if ((header.len == 0) && !memcmp(header.mac, zeros, 16)) {
|
||||
g_set_error(error,
|
||||
G_IO_ERROR, G_IO_ERROR_BROKEN_PIPE,
|
||||
"Broken pipe");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
len = g_ntohs(header.len);
|
||||
|
||||
if (len > BOXS_MAXLEN) {
|
||||
g_set_error(error,
|
||||
SSB_SCUTTLER_ERROR, SSB_SCUTTLER_ERROR_RESPONSE_TOO_LARGE,
|
||||
"Received boxed packet too large");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
guchar boxed_data[len + 16];
|
||||
|
||||
if (!ssb_scuttler_read(scuttler, boxed_data + 16, len, &err)) {
|
||||
g_propagate_error(error, err);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
memcpy(boxed_data, header.mac, 16);
|
||||
|
||||
if (crypto_secretbox_open_easy(buf, boxed_data, len + 16, scuttler->rx_nonce, scuttler->decrypt_key) < 0) {
|
||||
g_set_error(error,
|
||||
SSB_SCUTTLER_ERROR, SSB_SCUTTLER_ERROR_CRYPT,
|
||||
"Failed to unbx packet data");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
increment_nonce(scuttler->rx_nonce);
|
||||
|
||||
if (lenp) {
|
||||
*lenp = len;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
bs_read(SsbScuttler *scuttler, gpointer buf, gsize len)
|
||||
{
|
||||
size_t remaining;
|
||||
GError *err = NULL;
|
||||
|
||||
while (len > 0) {
|
||||
remaining = (scuttler->rx_buf_len > len) ? len : scuttler->rx_buf_len;
|
||||
|
||||
if (buf) {
|
||||
memcpy(buf, scuttler->rx_buf + scuttler->rx_buf_pos, remaining);
|
||||
}
|
||||
|
||||
scuttler->rx_buf_len -= remaining;
|
||||
scuttler->rx_buf_pos += remaining;
|
||||
len -= remaining;
|
||||
buf += remaining;
|
||||
|
||||
if (len == 0) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (bs_read_packet(scuttler, scuttler->rx_buf, &(scuttler->rx_buf_len), &err) < 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
scuttler->rx_buf_pos = 0;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ps_read_header(SsbScuttler *scuttler, gsize *len, guint32 *req_id, SsbPacketFlags *flags)
|
||||
{
|
||||
char buf[9];
|
||||
PacketHeader header;
|
||||
|
||||
if (!bs_read(scuttler, buf, sizeof(buf))) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
memcpy(&header, buf + 1, 8);
|
||||
|
||||
if (len) {
|
||||
*len = g_ntohl(header.len);
|
||||
}
|
||||
|
||||
if (req_id) {
|
||||
*req_id = g_ntohl(header.request_id);
|
||||
}
|
||||
|
||||
if (flags) {
|
||||
*flags = buf[0];
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ps_reject(SsbScuttler *scuttler, gsize len, guint32 req, SsbPacketFlags flags, GError **error)
|
||||
{
|
||||
g_debug("Ignoring packet");
|
||||
|
||||
if (bs_read_out(scuttler, len) < 0) {
|
||||
g_set_error(error,
|
||||
SSB_SCUTTLER_ERROR, SSB_SCUTTLER_ERROR_READ,
|
||||
"bs_read_out");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ssb_scuttler_read_async(SsbScuttler *scuttler, guint32 req_id, GError **error)
|
||||
{
|
||||
guint32 req;
|
||||
gsize len;
|
||||
SsbPacketFlags flags;
|
||||
|
||||
while (TRUE) {
|
||||
if (!ps_read_header(scuttler, &len, &req, &flags)) {
|
||||
g_set_error(error, SSB_SCUTTLER_ERROR, SSB_SCUTTLER_ERROR_READ, "ps_read_header");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (req == -req_id) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ((req == 0) && (len == 0)) {
|
||||
g_set_error(error, SSB_SCUTTLER_ERROR, SSB_SCUTTLER_ERROR_STREAM_END, "Unexpected end of parent stream");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ps_reject(scuttler, len, req, flags);
|
||||
}
|
||||
|
||||
if (flags & SSB_PACKET_FLAGS_END) {
|
||||
gint rc;
|
||||
|
||||
if ((rc = ps_read_error(scuttler, flags, len)) < 0) {
|
||||
g_set_error(error, SSB_SCUTTLER_ERROR, SSB_SCUTTLER_ERROR_READ, "bs_read_error");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (rc == 1) {
|
||||
return 2; // TODO: What is this for?
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (bs_read_out(bs, buffer, len) < 0) {
|
||||
g_set_error(error, SSB_SCUTTLER_ERROR, SSB_SCUTTLER_ERROR_READ, "bs_read_out");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// was: muxrpc_call
|
||||
/**
|
||||
* ssb_scuttler_muxrpc_call:
|
||||
|
@ -15,6 +15,11 @@ typedef enum {
|
||||
SSB_SCUTTLER_ERROR_REQUEST_TOO_LARGE,
|
||||
SSB_SCUTTLER_ERROR_SEND,
|
||||
SSB_SCUTTLER_ERROR_NOTCONNECTED,
|
||||
SSB_SCUTTLER_ERROR_READ,
|
||||
SSB_SCUTTLER_ERROR_CRYPT,
|
||||
SSB_SCUTTLER_ERROR_DECRYPT,
|
||||
SSB_SCUTTLER_ERROR_RESPONSE_TOO_LARGE,
|
||||
SSB_SCUTTLER_ERROR_STREAM_END,
|
||||
} SsbScuttlerError;
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
Loading…
Reference in New Issue
Block a user