summaryrefslogtreecommitdiff
path: root/src/analysis/db/analyst.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/analysis/db/analyst.c')
-rw-r--r--src/analysis/db/analyst.c245
1 files changed, 200 insertions, 45 deletions
diff --git a/src/analysis/db/analyst.c b/src/analysis/db/analyst.c
index 49585c2..43fb840 100644
--- a/src/analysis/db/analyst.c
+++ b/src/analysis/db/analyst.c
@@ -29,43 +29,13 @@
#include <string.h>
-#include "client-int.h"
+#include "analyst-int.h"
#include "../storage/storage.h"
#include "../../core/logs.h"
-/* Description de client à l'écoute (instance) */
-struct _GAnalystClient
-{
- GHubClient parent; /* A laisser en premier */
-
- char *hash; /* Empreinte du binaire lié */
- GList *collections; /* Collections d'un binaire */
-
- bool can_get_updates; /* Réception de maj possibles ?*/
-
- snapshot_info_t *snapshots; /* Liste des instantanés */
- size_t snap_count; /* Taille de cette liste */
- GMutex snap_lock; /* Concurrence des accès */
-
- snapshot_id_t current; /* Instantané courant */
- bool has_current; /* Validité de l'identifiant */
- GMutex cur_lock; /* Concurrence des accès */
-
-};
-
-/* Description de client à l'écoute (classe) */
-struct _GAnalystClientClass
-{
- GHubClientClass parent; /* A laisser en premier */
-
- /* Signaux */
-
- void (* snapshots_updated) (GAnalystClient *);
- void (* snapshot_changed) (GAnalystClient *);
-
-};
+/* ----------------------- DEFINITION D'ANALYSTE COMME CLIENT ----------------------- */
/* Initialise la classe des descriptions de fichier binaire. */
@@ -94,6 +64,58 @@ static bool g_analyst_client_update_current_snapshot(GAnalystClient *, packed_bu
+/* ------------------------- PRISES EN COMPTE DES COMMANDES ------------------------- */
+
+
+/* Prend en compte une évolution du statut côté serveur. */
+static bool g_analyst_client_handle_loading_hints(GAnalystClient *, packed_buffer_t *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* GLUES POUR LA GLIB */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Définit un type GLib pour l'énumération "LoadingStatusHint". *
+* *
+* Retour : Type GLib enregistré. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GType g_loading_status_hint_type(void)
+{
+ static GType result = 0;
+
+ static const GEnumValue values[] = {
+ { LSH_READY, "LSH_READY", "ready" },
+ { LSH_ON_WAIT_LIST, "LSH_ON_WAIT_LIST", "on_wait_list" },
+ { LSH_NEED_CONTENT, "LSH_NEED_CONTENT", "need_content" },
+ { LSH_NEED_FORMAT, "LSH_NEED_FORMAT", "need_format" },
+ { LSH_NEED_ARCH, "LSH_NEED_ARCH", "need_arch" },
+ { 0, NULL, NULL }
+ };
+
+ if (result == 0)
+ result = g_enum_register_static(g_intern_static_string("LoadingStatusHint"), values);
+
+ return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* DEFINITION D'ANALYSTE COMME CLIENT */
+/* ---------------------------------------------------------------------------------- */
+
+
/* Indique le type défini pour une description de client à l'écoute. */
G_DEFINE_TYPE(GAnalystClient, g_analyst_client, G_TYPE_HUB_CLIENT);
@@ -126,6 +148,22 @@ static void g_analyst_client_class_init(GAnalystClientClass *klass)
client->complete_hello = (complete_client_hello_fc)g_analyst_client_complete_hello;
client->recv_func = (GThreadFunc)g_analyst_client_update;
+ g_signal_new("ready",
+ G_TYPE_ANALYST_CLIENT,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(GAnalystClientClass, ready),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ g_signal_new("server-status-changed",
+ G_TYPE_ANALYST_CLIENT,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(GAnalystClientClass, server_status_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__ENUM,
+ G_TYPE_NONE, 1, G_TYPE_LOADING_STATUS_HINT);
+
g_signal_new("snapshots-updated",
G_TYPE_ANALYST_CLIENT,
G_SIGNAL_RUN_LAST,
@@ -159,7 +197,10 @@ static void g_analyst_client_class_init(GAnalystClientClass *klass)
static void g_analyst_client_init(GAnalystClient *client)
{
- client->hash = NULL;
+ client->cnt_hash = NULL;
+ client->cnt_class = NULL;
+
+ client->loaded = NULL;
client->collections = NULL;
client->can_get_updates = false;
@@ -195,6 +236,8 @@ static void g_analyst_client_dispose(GAnalystClient *client)
g_mutex_clear(&client->snap_lock);
+ g_clear_object(&client->loaded);
+
G_OBJECT_CLASS(g_analyst_client_parent_class)->dispose(G_OBJECT(client));
}
@@ -216,8 +259,11 @@ static void g_analyst_client_finalize(GAnalystClient *client)
{
size_t i; /* Boucle de parcours */
- if (client->hash != NULL)
- free(client->hash);
+ if (client->cnt_hash != NULL)
+ free(client->cnt_hash);
+
+ if (client->cnt_class != NULL)
+ free(client->cnt_class);
if (client->snapshots != NULL)
{
@@ -236,9 +282,11 @@ static void g_analyst_client_finalize(GAnalystClient *client)
/******************************************************************************
* *
* Paramètres : hash = empreinte d'un binaire en cours d'analyse. *
+* class = nature de l'interprétation de ce contenu. *
* collections = ensemble de collections existantes. *
+* loaded = éventuel élément local préchargé. *
* *
-* Description : Prépare un client pour une connexion à une BD. *
+* Description : Met en place un client pour une connexion à une BD. *
* *
* Retour : Structure mise en place ou NULL en cas d'échec. *
* *
@@ -246,14 +294,54 @@ static void g_analyst_client_finalize(GAnalystClient *client)
* *
******************************************************************************/
-GAnalystClient *g_analyst_client_new(const char *hash, GList *collections)
+GAnalystClient *g_analyst_client_new(const char *hash, const char *class, GList *collections, GLoadedContent *loaded)
{
GAnalystClient *result; /* Adresse à retourner */
+ bool status; /* Bilan de l'initialisation */
result = g_object_new(G_TYPE_ANALYST_CLIENT, NULL);
- result->hash = strdup(hash);
- result->collections = collections;
+ status = g_analyst_client_setup(result, hash, class, collections, loaded);
+
+ assert(status);
+
+ if (!status)
+ g_clear_object(&result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : client = client pour les accès distants à initialiser. *
+* hash = empreinte d'un binaire en cours d'analyse. *
+* class = nature de l'interprétation de ce contenu. *
+* collections = ensemble de collections existantes. *
+* loaded = éventuel élément local préchargé. *
+* *
+* Description : Prépare un client pour une connexion à une BD. *
+* *
+* Retour : Structure mise en place ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_analyst_client_setup(GAnalystClient *client, const char *hash, const char *class, GList *collections, GLoadedContent *loaded)
+{
+ bool result; /* Bilan à retourner */
+
+ result = true;
+
+ client->cnt_hash = strdup(hash);
+ client->cnt_class = strdup(class);
+
+ client->loaded = loaded;
+ if (loaded != NULL) g_object_ref(G_OBJECT(loaded));
+
+ client->collections = collections;
return result;
@@ -278,7 +366,13 @@ static bool g_analyst_client_complete_hello(GAnalystClient *client, packed_buffe
bool result; /* Bilan à retourner */
rle_string str; /* Chaîne à communiquer */
- init_static_rle_string(&str, client->hash);
+ init_static_rle_string(&str, client->cnt_hash);
+
+ result = pack_rle_string(&str, pbuf);
+
+ exit_rle_string(&str);
+
+ init_static_rle_string(&str, client->cnt_class);
result = pack_rle_string(&str, pbuf);
@@ -406,6 +500,11 @@ static void *g_analyst_client_update(GAnalystClient *client)
switch (command)
{
+ case DBC_LOADING_STATUS:
+ status = g_analyst_client_handle_loading_hints(client, &in_pbuf);
+ if (!status) goto gdcu_bad_exchange;
+ break;
+
case DBC_SAVE:
status = extract_packed_buffer(&in_pbuf, &tmp32, sizeof(uint32_t), true);
@@ -414,10 +513,10 @@ static void *g_analyst_client_update(GAnalystClient *client)
error = tmp32;
if (error == DBE_NONE)
- log_variadic_message(LMT_INFO, _("Archive saved for binary '%s'"), client->hash);
+ log_variadic_message(LMT_INFO, _("Archive saved for binary '%s'"), client->cnt_hash);
else
log_variadic_message(LMT_ERROR, _("Failed to save the archive for binary '%s'"),
- client->hash);
+ client->cnt_hash);
break;
@@ -669,10 +768,10 @@ bool g_analyst_client_send_content(GAnalystClient *client, GBinContent *content)
hash = g_binary_content_get_checksum(content);
- if (strcmp(hash, client->hash) != 0)
+ if (strcmp(hash, client->cnt_hash) != 0)
{
log_variadic_message(LMT_ERROR, _("Provided ontent does not match client content (hash: '%s')"),
- client->hash);
+ client->cnt_hash);
goto exit;
}
@@ -680,7 +779,7 @@ bool g_analyst_client_send_content(GAnalystClient *client, GBinContent *content)
init_packed_buffer(&cnt_pbuf);
- storage = g_object_storage_new(client->hash);
+ storage = g_object_storage_new(client->cnt_hash);
result = g_object_storage_store_object(storage, "contents", G_SERIALIZABLE_OBJECT(content), &pos);
if (!result) goto exit_with_failure;
@@ -1261,3 +1360,59 @@ bool g_analyst_client_remove_snapshot(GAnalystClient *client, const snapshot_id_
return result;
}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* PRISES EN COMPTE DES COMMANDES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : archive = archive à connecter avec un utilisateur. *
+* in_pbuf = paquet à consulter. *
+* *
+* Description : Prend en compte une évolution du statut côté serveur. *
+* *
+* Retour : Indication pour le maintien de la communication. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_analyst_client_handle_loading_hints(GAnalystClient *client, packed_buffer_t *in_pbuf)
+{
+ bool result; /* Bilan à retourner */
+ uleb128_t hint; /* Indication du serveur */
+
+ result = unpack_uleb128(&hint, in_pbuf);
+
+ switch (hint)
+ {
+ case LSH_READY:
+ g_signal_emit_by_name(client, "ready");
+ break;
+
+ case LSH_ON_WAIT_LIST:
+ log_simple_message(LMT_INFO, _("Waiting for content from server..."));
+ break;
+
+ case LSH_NEED_CONTENT:
+ case LSH_NEED_FORMAT:
+ case LSH_NEED_ARCH:
+ g_signal_emit_by_name(client, "server-status-changed", hint);
+ break;
+
+ default:
+ log_variadic_message(LMT_ERROR,
+ _("Unknown loaded hint received (%x); unsupported newer protocol?"),
+ hint);
+ result = false;
+ break;
+
+ }
+
+ return result;
+
+}