Skip to content

Commit

Permalink
Don't forward client messages until authenticated
Browse files Browse the repository at this point in the history
Until the authentication is completed, hold off all client messages
received after BEGIN. We only send to the server the authentication
commands up (and including) the BEGIN command, but everything past the
line terminators is queued into the `extra_input_data` buffer and we
stop reading from the client socket.

Once the authentication is completed, the (partial) message we saved
into `extra_input_data` is queued for the D-Bus server into the first
outgoing buffer, and reading from the client socket resumes.

Note that in order to cleanly process the partial sendind of data,
another offset is introduced into the Buffer structure, which holds the
bytes of buffers which have already been sent over the socket.

Signed-off-by: Alberto Mardegan <[email protected]>
  • Loading branch information
mardy committed May 16, 2024
1 parent 0e63504 commit 02db72e
Showing 1 changed file with 48 additions and 18 deletions.
66 changes: 48 additions & 18 deletions flatpak-proxy.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,13 @@ typedef enum {

typedef struct
{
/* Total size (capacity) of the buffer */
gsize size;
/* Offset to the first writable position (the buffer is full when pos ==
* size) */
gsize pos;
/* Offset to the first byte that hasn't been sent yet */
gsize sent;
int refcount;
gboolean send_credentials;
GList *control_messages;
Expand Down Expand Up @@ -780,6 +785,7 @@ buffer_new (gsize size, Buffer *old)
if (old)
{
buffer->pos = old->pos;
buffer->sent = old->sent;
/* Takes ownership of any old control messages */
buffer->control_messages = old->control_messages;
old->control_messages = NULL;
Expand Down Expand Up @@ -844,13 +850,18 @@ buffer_read (ProxySide *side,
Buffer *buffer,
GSocket *socket)
{
gsize received;
FlatpakProxyClient *client = side->client;
gsize received = 0;
GInputVector v;
GError *error = NULL;
GSocketControlMessage **messages;
int num_messages, i;

if (side->extra_input_data)
if (client->auth_state == AUTH_WAITING_FOR_BACKLOG &&
side == &client->client_side)
return FALSE;

if (side->extra_input_data && client->auth_state == AUTH_COMPLETE)
{
gsize extra_size;
const guchar *extra_bytes = g_bytes_get_data (side->extra_input_data, &extra_size);
Expand All @@ -872,7 +883,7 @@ buffer_read (ProxySide *side,
g_clear_pointer (&side->extra_input_data, g_bytes_unref);
}
}
else
else if (!side->extra_input_data)
{
gssize res;
int flags = 0;
Expand Down Expand Up @@ -948,7 +959,7 @@ buffer_write (ProxySide *side,
return FALSE;
}

buffer->pos = 1;
buffer->sent = 1;
return TRUE;
}

Expand All @@ -957,8 +968,8 @@ buffer_write (ProxySide *side,
for (l = buffer->control_messages, i = 0; l != NULL; l = l->next, i++)
messages[i] = l->data;

v.buffer = &buffer->data[buffer->pos];
v.size = buffer->size - buffer->pos;
v.buffer = &buffer->data[buffer->sent];
v.size = buffer->pos - buffer->sent;

res = g_socket_send_message (socket, NULL, &v, 1,
messages, n_messages,
Expand All @@ -985,16 +996,15 @@ buffer_write (ProxySide *side,
g_list_free_full (buffer->control_messages, g_object_unref);
buffer->control_messages = NULL;

buffer->pos += res;
buffer->sent += res;
return TRUE;
}

static gboolean
side_out_cb (GSocket *socket, GIOCondition condition, gpointer user_data)
send_outgoing_buffers (GSocket *socket, ProxySide *side)
{
ProxySide *side = user_data;
FlatpakProxyClient *client = side->client;
gboolean retval = G_SOURCE_CONTINUE;
gboolean all_done = FALSE;

g_object_ref (client);

Expand All @@ -1004,7 +1014,7 @@ side_out_cb (GSocket *socket, GIOCondition condition, gpointer user_data)

if (buffer_write (side, buffer, socket))
{
if (buffer->pos == buffer->size)
if (buffer->sent == buffer->pos)
{
side->buffers = g_list_delete_link (side->buffers, side->buffers);
buffer_unref (buffer);
Expand All @@ -1020,16 +1030,32 @@ side_out_cb (GSocket *socket, GIOCondition condition, gpointer user_data)
{
ProxySide *other_side = get_other_side (side);

side->out_source = NULL;
retval = G_SOURCE_REMOVE;
all_done = TRUE;

if (other_side->closed)
side_closed (side);
}

g_object_unref (client);

return retval;
return all_done;
}

static gboolean
side_out_cb (GSocket *socket, GIOCondition condition, gpointer user_data)
{
ProxySide *side = user_data;

gboolean all_done = send_outgoing_buffers (socket, side);
if (all_done)
{
side->out_source = NULL;
return G_SOURCE_REMOVE;
}
else
{
return G_SOURCE_CONTINUE;
}
}

static void
Expand Down Expand Up @@ -1068,7 +1094,6 @@ queue_outgoing_buffer (ProxySide *side, Buffer *buffer)
g_source_unref (side->out_source);
}

buffer->pos = 0;
side->buffers = g_list_append (side->buffers, buffer);
}

Expand Down Expand Up @@ -1850,6 +1875,7 @@ message_to_buffer (GDBusMessage *message)
blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, NULL);
buffer = buffer_new (blob_size, NULL);
memcpy (buffer->data, blob, blob_size);
buffer->pos = blob_size;
g_free (blob);

return buffer;
Expand Down Expand Up @@ -2963,7 +2989,6 @@ side_in_cb (GSocket *socket, GIOCondition condition, gpointer user_data)
gboolean found_auth_end = FALSE;
gsize extra_data;

buffer->size = buffer->pos;
if (!side->got_first_byte)
{
buffer->send_credentials = TRUE;
Expand All @@ -2977,8 +3002,8 @@ side_in_cb (GSocket *socket, GIOCondition condition, gpointer user_data)
if (auth_end >= 0)
{
found_auth_end = TRUE;
buffer->size = auth_end;
extra_data = buffer->pos - buffer->size;
extra_data = buffer->pos - auth_end;
buffer->size = buffer->pos = auth_end;

/* We may have gotten some extra data which is not part of
the auth handshake, keep it for the next iteration. */
Expand All @@ -2999,6 +3024,11 @@ side_in_cb (GSocket *socket, GIOCondition condition, gpointer user_data)

if (found_auth_end)
{
/* Immediately send the outgoing buffer */
GSocketConnection *connection = client->bus_side.connection;
GSocket *socket = g_socket_connection_get_socket (connection);
send_outgoing_buffers (socket, &client->bus_side);

client->auth_state = AUTH_WAITING_FOR_BACKLOG;
check_pending_auth_lines (client);
}
Expand Down

0 comments on commit 02db72e

Please sign in to comment.