diff --git a/ssb-gtk/sbot.c b/ssb-gtk/sbot.c index 84445f1..d551033 100644 --- a/ssb-gtk/sbot.c +++ b/ssb-gtk/sbot.c @@ -353,21 +353,15 @@ data_read(GObject *source, GAsyncResult *result, gpointer user_data) } g_debug("Read %ld bytes", bytes_read); - - // Re-add the idle handler - g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, - G_SOURCE_FUNC(check_incoming_data), - g_object_ref(singleton), - g_object_unref); } static gboolean -check_incoming_data(SsbScuttler *scuttler) +read_inbound(GSocket *socket, GIOCondition condition, SsbScuttler *scuttler) { DataReadType *data = g_slice_new(DataReadType); GInputStream *stream = g_io_stream_get_input_stream(G_IO_STREAM(scuttler->connection)); - g_debug("Checking for incoming data"); + g_debug("Data is flowing in!"); data->scuttler = scuttler; data->read_buffer = g_malloc(MAX_MESSAGE_SIZE); @@ -404,11 +398,6 @@ ssb_scuttler_ensure(const gchar *ssb_dir) initialise(singleton, ssb_dir); } - g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, - G_SOURCE_FUNC(check_incoming_data), - g_object_ref(singleton), - g_object_unref); - return TRUE; } @@ -475,13 +464,19 @@ ssb_scuttler_shs_connect(SsbScuttler *scuttler, GError **error) GError *err = NULL; if (crypto_box_keypair(kx_pk, kx_sk) < 0) { - g_set_error(error, SSB_SCUTTLER_ERROR, SSB_SCUTTLER_ERROR_KEYGEN, "Could not generate auth keypair"); + g_set_error(error, + SSB_SCUTTLER_ERROR, SSB_SCUTTLER_ERROR_KEYGEN, + "Could not generate auth keypair"); return FALSE; } + g_debug("SHS auth keypair generated"); + if (crypto_auth(local_app_mac, kx_pk, crypto_box_PUBLICKEYBYTES, scuttler->app_key) < 0) { - g_set_error(error, SSB_SCUTTLER_ERROR, SSB_SCUTTLER_ERROR_KEYAUTH, "Failed to generate app mac"); + g_set_error(error, + SSB_SCUTTLER_ERROR, SSB_SCUTTLER_ERROR_KEYAUTH, + "Failed to generate app mac"); return FALSE; } @@ -496,6 +491,8 @@ ssb_scuttler_shs_connect(SsbScuttler *scuttler, GError **error) return FALSE; } + g_debug("Challenge sent"); + // Receive challenge response if (!ssb_scuttler_read(scuttler, buf, sizeof(buf), &err)) { g_propagate_error(error, err); @@ -503,11 +500,15 @@ ssb_scuttler_shs_connect(SsbScuttler *scuttler, GError **error) return FALSE; } + g_debug("Challenge response read"); + memcpy(remote_app_mac, buf, crypto_box_PUBLICKEYBYTES); memcpy(remote_kx_pk, buf + crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES); if (crypto_auth_verify(buf, remote_kx_pk, crypto_box_PUBLICKEYBYTES, scuttler->app_key) < 0) { - g_set_error(error, SSB_SCUTTLER_ERROR, SSB_SCUTTLER_ERROR_KEYVERIFY, "Wrong protocol (version?)"); + g_set_error(error, + SSB_SCUTTLER_ERROR, SSB_SCUTTLER_ERROR_KEYVERIFY, + "Wrong protocol (version?)"); return FALSE; } @@ -676,8 +677,12 @@ connection_finished(GObject *source, GAsyncResult *result, gpointer user_data) SsbScuttler *scuttler = g_task_get_task_data(task); GError *err = NULL; GSocketConnection *connection = g_socket_client_connect_finish(socket_client, result, &err); + GSocket *socket; + GSource *socket_source; if (connection == NULL) { + g_warning("Unable to connect to SBOT/* "); + g_task_return_error(task, err); g_object_unref(task); @@ -687,6 +692,8 @@ connection_finished(GObject *source, GAsyncResult *result, gpointer user_data) g_clear_object(&(scuttler->connection)); scuttler->connection = connection; + g_debug("Connected to SBOT"); + // TODO: This is only required if noauth is not set if (!ssb_scuttler_shs_connect(scuttler, &err)) { g_task_return_error(task, err); @@ -695,6 +702,14 @@ connection_finished(GObject *source, GAsyncResult *result, gpointer user_data) return; } + socket = g_socket_connection_get_socket(connection); + g_socket_set_blocking(socket, FALSE); + socket_source = g_socket_create_source(socket, G_IO_IN | G_IO_PRI, NULL); + g_source_set_callback(socket_source, + (GSourceFunc)read_inbound, + g_object_ref(scuttler), g_object_unref); + g_source_attach(socket_source, g_main_context_get_thread_default()); + g_task_return_boolean(task, TRUE); emit_connected(scuttler, TRUE); g_object_unref(task); @@ -887,6 +902,8 @@ ssb_scuttler_muxrpc_call(SsbScuttler *scuttler, JsonNode *req_node = json_node_new(JSON_NODE_OBJECT); GError *err = NULL; + g_debug("Calling %s SBOT method", method); + json_object_set_string_member(req_object, "name", method); json_object_set_string_member(req_object, "args", argument); @@ -899,19 +916,26 @@ ssb_scuttler_muxrpc_call(SsbScuttler *scuttler, json_node_free(req_node); if ((request_len = strlen(request)) > MAX_MESSAGE_SIZE) { - g_set_error(error, SSB_SCUTTLER_ERROR, SSB_SCUTTLER_ERROR_REQUEST_TOO_LARGE, "Request too large"); + g_set_error(error, SSB_SCUTTLER_ERROR, + SSB_SCUTTLER_ERROR_REQUEST_TOO_LARGE, + "Request too large"); return; } req_id = g_atomic_int_add(&(scuttler->request_id), 1); - if (!ssb_scuttler_send_packet(scuttler, SSB_PACKET_TYPE_JSON, request, request_len, req_id, !is_request, FALSE, &err)) { + if (!ssb_scuttler_send_packet(scuttler, + SSB_PACKET_TYPE_JSON, request, request_len, + req_id, !is_request, FALSE, + &err)) { g_propagate_error(error, err); return; } + g_debug("%s request sent", method); + g_free(request); } @@ -1045,7 +1069,9 @@ ssb_scuttler_whoami_async(SsbScuttler *scuttler, task = g_task_new(scuttler, cancellable, callback, user_data); if (!scuttler->connection) { - g_task_return_new_error(task, SSB_SCUTTLER_ERROR, SSB_SCUTTLER_ERROR_NOTCONNECTED, "Scuttler is not connected"); + g_task_return_new_error(task, + SSB_SCUTTLER_ERROR, SSB_SCUTTLER_ERROR_NOTCONNECTED, + "Scuttler is not connected"); g_object_unref(task); return; diff --git a/ssb-gtk/sbot.h b/ssb-gtk/sbot.h index dd5870b..9f4c604 100644 --- a/ssb-gtk/sbot.h +++ b/ssb-gtk/sbot.h @@ -33,6 +33,10 @@ void ssb_scuttler_connect_async(SsbScuttler *scuttler, gboolean ssb_scuttler_connect_finish(SsbScuttler *scuttler, GAsyncResult *result, GError **error); +void ssb_scuttler_whoami_async(SsbScuttler *scuttler, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); G_END_DECLS diff --git a/ssb-gtk/ssb-app.c b/ssb-gtk/ssb-app.c index a13e746..c73c875 100644 --- a/ssb-gtk/ssb-app.c +++ b/ssb-gtk/ssb-app.c @@ -83,6 +83,11 @@ ssb_app_dispose(GObject *gobject) G_OBJECT_CLASS(ssb_app_parent_class)->dispose(gobject); } +static void +whoami_finished(GObject *source, GAsyncResult *res, gpointer user_data) +{ +} + void connect_finished(GObject *source, GAsyncResult *res, gpointer user_data) { @@ -90,6 +95,8 @@ connect_finished(GObject *source, GAsyncResult *res, gpointer user_data) SsbApp *app = user_data; GError *err = NULL; gboolean connect_successful = ssb_scuttler_connect_finish(scuttler, res, &err); + + ssb_scuttler_whoami_async(scuttler, NULL, whoami_finished, app); } static void