summaryrefslogtreecommitdiff
path: root/src/analysis/db
diff options
context:
space:
mode:
Diffstat (limited to 'src/analysis/db')
-rw-r--r--src/analysis/db/Makefile.am8
-rw-r--r--src/analysis/db/analyst-int.h76
-rw-r--r--src/analysis/db/analyst.c245
-rw-r--r--src/analysis/db/analyst.h20
-rw-r--r--src/analysis/db/cdb.c380
-rw-r--r--src/analysis/db/cdb.h6
-rw-r--r--src/analysis/db/items/Makefile.am11
-rw-r--r--src/analysis/db/items/comment.c2
-rw-r--r--src/analysis/db/items/move.c12
-rw-r--r--src/analysis/db/misc/Makefile.am11
-rw-r--r--src/analysis/db/protocol.h31
-rw-r--r--src/analysis/db/server.c36
12 files changed, 676 insertions, 162 deletions
diff --git a/src/analysis/db/Makefile.am b/src/analysis/db/Makefile.am
index 8f8242c..b9325e0 100644
--- a/src/analysis/db/Makefile.am
+++ b/src/analysis/db/Makefile.am
@@ -21,20 +21,16 @@ libanalysisdb_la_SOURCES = \
server.h server.c \
snapshot.h snapshot.c
+libanalysisdb_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) $(LIBARCHIVE_CFLAGS) $(LIBSQLITE_CFLAGS) $(LIBSSL_CFLAGS)
+
libanalysisdb_la_LIBADD = \
items/libanalysisdbitems.la \
misc/libanalysisdbmisc.la
-libanalysisdb_la_LDFLAGS = $(LIBSSL_LIBS)
-
devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%)
dev_HEADERS = $(libanalysisdb_la_SOURCES:%c=)
-AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBARCHIVE_CFLAGS) $(LIBSQLITE_CFLAGS) $(LIBSSL_CFLAGS)
-
-AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
-
SUBDIRS = items misc
diff --git a/src/analysis/db/analyst-int.h b/src/analysis/db/analyst-int.h
new file mode 100644
index 0000000..4f76eff
--- /dev/null
+++ b/src/analysis/db/analyst-int.h
@@ -0,0 +1,76 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * analyst-int.h - prototypes pour la définition interne des connexions en analyste à un serveur Chrysalide
+ *
+ * Copyright (C) 2022 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ANALYSIS_DB_ANALYST_INT_H
+#define _ANALYSIS_DB_ANALYST_INT_H
+
+
+#include "analyst.h"
+#include "client-int.h"
+
+
+
+/* Description de client à l'écoute (instance) */
+struct _GAnalystClient
+{
+ GHubClient parent; /* A laisser en premier */
+
+ char *cnt_hash; /* Empreinte du binaire lié */
+ char *cnt_class; /* Interprétation du contenu */
+
+ GLoadedContent *loaded; /* Contenu chargé */
+ 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 (* ready) (GAnalystClient *);
+ void (* server_status_changed) (GAnalystClient *, LoadingStatusHint);
+ void (* snapshots_updated) (GAnalystClient *);
+ void (* snapshot_changed) (GAnalystClient *);
+
+};
+
+
+/* Prépare un client pour une connexion à une BD. */
+bool g_analyst_client_setup(GAnalystClient *, const char *, const char *, GList *, GLoadedContent *);
+
+
+
+#endif /* _ANALYSIS_DB_ANALYST_INT_H */
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;
+
+}
diff --git a/src/analysis/db/analyst.h b/src/analysis/db/analyst.h
index 7b11f53..ff189ba 100644
--- a/src/analysis/db/analyst.h
+++ b/src/analysis/db/analyst.h
@@ -34,9 +34,25 @@
#include "collection.h"
#include "misc/snapshot.h"
#include "../content.h"
+#include "../loaded.h"
+
+/* ------------------------------- GLUES POUR LA GLIB ------------------------------- */
+
+
+#define G_TYPE_LOADING_STATUS_HINT g_loading_status_hint_type()
+
+
+/* Définit un type GLib pour l'énumération "LoadingStatusHint". */
+GType g_loading_status_hint_type(void);
+
+
+
+/* ----------------------- DEFINITION D'ANALYSTE COMME CLIENT ----------------------- */
+
+
#define G_TYPE_ANALYST_CLIENT g_analyst_client_get_type()
#define G_ANALYST_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_ANALYST_CLIENT, GAnalystClient))
#define G_IS_ANALYST_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_ANALYST_CLIENT))
@@ -55,8 +71,8 @@ typedef struct _GAnalystClientClass GAnalystClientClass;
/* Indique le type défini pour une description de client à l'écoute. */
GType g_analyst_client_get_type(void);
-/* Prépare un client pour une connexion à une BD. */
-GAnalystClient *g_analyst_client_new(const char *, GList *);
+/* Met en place un client pour une connexion à une BD. */
+GAnalystClient *g_analyst_client_new(const char *, const char *, GList *, GLoadedContent *);
/* Envoie un contenu binaire pour conservation côté serveur. */
bool g_analyst_client_send_content(GAnalystClient *, GBinContent *);
diff --git a/src/analysis/db/cdb.c b/src/analysis/db/cdb.c
index 62de6a7..6d4b84d 100644
--- a/src/analysis/db/cdb.c
+++ b/src/analysis/db/cdb.c
@@ -38,8 +38,8 @@
#include <sys/stat.h>
-#include <i18n.h>
#include <config.h>
+#include <i18n.h>
#include "backend-int.h"
@@ -59,7 +59,7 @@
-/* ------------------------- COEUR DE LA GESTION D'ARCHIVES ------------------------- */
+/* -------------------------- LIEN VERS UN CLIENT CONNECTE -------------------------- */
/* Informations relatives à un client */
@@ -69,29 +69,51 @@ typedef struct _cdb_client
char *peer_name; /* Désignation du correspondant*/
char *user; /* Utilisateur à l'autre bout */
- uint64_t last_time; /* Date de dernier envoi */
+ gint ref_count; /* Décompte d'utilisation */
} cdb_client;
+/* Met en place le suivi d'une connexion de client. */
+static cdb_client *create_cdb_client(SSL *, const char *, const char *);
+
+/* Supprime le suivi d'une connexion de client. */
+static void delete_cdb_client(cdb_client *);
+
+/* Augmente le décompte d'utilisation d'un suivi de connexion. */
+static void ref_cdb_client(cdb_client *);
+
+/* Diminue le décompte d'utilisation d'un suivi de connexion. */
+static void unref_cdb_client(cdb_client *);
+
+
+
+/* ------------------------- COEUR DE LA GESTION D'ARCHIVES ------------------------- */
+
+
/* Description d'une archive d'éléments utilisateur (instance) */
struct _GCdbArchive
{
GServerBackend parent; /* A laisser en premier */
rle_string hash; /* Empreinte cryptographique */
+ rle_string class; /* Nature du contenu analysé */
char *filename; /* Chemin d'accès à l'archive */
char *tmpdir; /* Répertoire de travail */
- char *cnt_file; /* Fichier de contenu binaire */
char *xml_desc; /* Fichier de description */
+ char *cnt_file; /* Fichier de contenu binaire */
+
+ GMutex loading_access; /* Verrou pour l'accès */
+
+
GList *collections; /* Ensemble de modifications */
GDbSnapshot *snapshot; /* Instantanés de bases SQL */
sqlite3 *db; /* Base de données à manipuler */
- cdb_client *clients; /* Connexions en place */
+ cdb_client **clients; /* Connexions en place */
size_t count; /* Quantité de clients */
GMutex clients_access; /* Verrou pour l'accès */
@@ -171,14 +193,115 @@ static bool g_cdb_archive_send_snapshot_change(GCdbArchive *, packed_buffer_t *)
/* ------------------------- PRISES EN COMPTE DES COMMANDES ------------------------- */
-/* Prépare la réponse à envoyer à un client connecté. */
-static bool setup_server_answer(DBCommand, DBError, packed_buffer_t *);
+/* Prépare une courte réponse à envoyer à un client connecté. */
+static bool craft_server_short_answer(DBCommand, uleb128_t, packed_buffer_t *);
/* Enregistre le contenu binaire lié à une analyse. */
static bool g_cdb_archive_set_content(GCdbArchive *, packed_buffer_t *, packed_buffer_t *);
+/* -------------------------- LIEN VERS UN CLIENT CONNECTE -------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : fd = canal de communication réseau ouvert. *
+* peer_name = désignation de la connexion. *
+* user = désignation de l'utilisateur de la connexion. *
+* *
+* Description : Met en place le suivi d'une connexion de client. *
+* *
+* Retour : Structure dédiée construite. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static cdb_client *create_cdb_client(SSL *fd, const char *peer_name, const char *user)
+{
+ cdb_client *result; /* Fiche d'entité à retourner */
+
+ result = malloc(sizeof(cdb_client));
+
+ result->tls_fd = fd;
+
+ result->peer_name = strdup(peer_name);
+ result->user = strdup(user);
+
+ g_atomic_int_set(&result->ref_count, 1);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : client = informations de suivi à libérer de la mémoire. *
+* *
+* Description : Supprime le suivi d'une connexion de client. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void delete_cdb_client(cdb_client *client)
+{
+ assert(g_atomic_int_get(&client->ref_count) == 0);
+
+ SSL_free(client->tls_fd);
+
+ free(client->peer_name);
+ free(client->user);
+
+ free(client);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : client = informations de suivi à libérer de la mémoire. *
+* *
+* Description : Augmente le décompte d'utilisation d'un suivi de connexion. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void ref_cdb_client(cdb_client *client)
+{
+ g_atomic_int_inc(&client->ref_count);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : client = informations de suivi à libérer de la mémoire. *
+* *
+* Description : Diminue le décompte d'utilisation d'un suivi de connexion. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void unref_cdb_client(cdb_client *client)
+{
+ if (g_atomic_int_dec_and_test(&client->ref_count))
+ delete_cdb_client(client);
+
+}
+
+
+
/* ---------------------------------------------------------------------------------- */
/* COEUR DE LA GESTION D'ARCHIVES */
/* ---------------------------------------------------------------------------------- */
@@ -235,15 +358,19 @@ static void g_cdb_archive_class_init(GCdbArchiveClass *klass)
static void g_cdb_archive_init(GCdbArchive *archive)
{
setup_empty_rle_string(&archive->hash);
+ setup_empty_rle_string(&archive->class);
archive->filename = NULL;
archive->tmpdir = NULL;
- archive->cnt_file = NULL;
archive->xml_desc = NULL;
+ archive->cnt_file = NULL;
+ g_mutex_init(&archive->loading_access);
+
archive->collections = create_collections_list();
archive->snapshot = NULL;
+ archive->db = NULL;
g_mutex_init(&archive->clients_access);
@@ -266,9 +393,11 @@ static void g_cdb_archive_dispose(GCdbArchive *archive)
{
g_server_backend_stop(G_SERVER_BACKEND(archive));
+ g_mutex_clear(&archive->clients_access);
+
g_clear_object(&archive->snapshot);
- g_mutex_clear(&archive->clients_access);
+ g_mutex_clear(&archive->loading_access);
G_OBJECT_CLASS(g_cdb_archive_parent_class)->dispose(G_OBJECT(archive));
@@ -315,6 +444,7 @@ static void g_cdb_archive_finalize(GCdbArchive *archive)
if (archive->filename != NULL)
free(archive->filename);
+ exit_rle_string(&archive->class);
exit_rle_string(&archive->hash);
G_OBJECT_CLASS(g_cdb_archive_parent_class)->finalize(G_OBJECT(archive));
@@ -327,6 +457,7 @@ static void g_cdb_archive_finalize(GCdbArchive *archive)
* Paramètres : basedir = répertoire de stockage des enregistrements. *
* tmpdir = répertoire de travail temporaire. *
* hash = empreinte du binaire à représenter. *
+* class = nature du contenu analysé associé. *
* error = indication éventuelle en cas d'échec. [OUT] *
* *
* Description : Définit ou ouvre une archive d'éléments utilisateur. *
@@ -338,7 +469,7 @@ static void g_cdb_archive_finalize(GCdbArchive *archive)
* *
******************************************************************************/
-GCdbArchive *g_cdb_archive_new(const char *basedir, const char *tmpdir, const rle_string *hash, DBError *error)
+GCdbArchive *g_cdb_archive_new(const char *basedir, const char *tmpdir, const rle_string *hash, const rle_string *class, DBError *error)
{
GCdbArchive *result; /* Adresse à retourner */
int ret; /* Retour d'un appel */
@@ -347,13 +478,16 @@ GCdbArchive *g_cdb_archive_new(const char *basedir, const char *tmpdir, const rl
result = g_object_new(G_TYPE_CDB_ARCHIVE, NULL);
dup_into_rle_string(&result->hash, get_rle_string(hash));
+ dup_into_rle_string(&result->class, get_rle_string(class));
*error = DBE_SYS_ERROR;
/* Chemin de l'archive */
result->filename = strdup(basedir);
- result->filename = stradd(result->filename, hash->data);
+ result->filename = stradd(result->filename, get_rle_string(hash));
+ result->filename = stradd(result->filename, "-");
+ result->filename = stradd(result->filename, get_rle_string(class));
result->filename = stradd(result->filename, ".cdb.tar.xz");
if (!mkpath(result->filename))
@@ -679,18 +813,26 @@ DBError g_cdb_archive_write(const GCdbArchive *archive)
* *
* Paramètres : archive = informations quant à l'archive à consulter. *
* hash = empreinte extérieure à comparer. *
+* class = nature du contenu analysé. *
* *
-* Description : Détermine si une empreinte correspond à celle d'une archive. *
+* Description : Détermine l'archive correspond à une cible recherchée. *
* *
-* Retour : Résultat de la comparaison : -1, 0 ou 1. *
+* Retour : Bilan de l'opération. *
* *
* Remarques : - *
* *
******************************************************************************/
-int g_cdb_archive_compare_hash(const GCdbArchive *archive, const rle_string *hash)
+bool g_cdb_archive_compare_is_suitable_for(const GCdbArchive *archive, const rle_string *hash, const rle_string *class)
{
- return cmp_rle_string(&archive->hash, hash);
+ bool result; /* Bilan à retourner */
+
+ result = (cmp_rle_string(&archive->hash, hash) == 0);
+
+ if (result)
+ result = (cmp_rle_string(&archive->class, class) == 0);
+
+ return result;
}
@@ -867,7 +1009,7 @@ static void on_collection_extended(GDbCollection *collec, GDbItem *item, GCdbArc
for (i = 0; i < archive->count && status; i++)
{
- status = ssl_send_packed_buffer(&pbuf, archive->clients[i].tls_fd);
+ status = ssl_send_packed_buffer(&pbuf, archive->clients[i]->tls_fd);
if (!status)
LOG_ERROR(LMT_ERROR, _("Failed to send some DB update"));
@@ -896,6 +1038,8 @@ static void on_collection_extended(GDbCollection *collec, GDbItem *item, GCdbArc
static void *g_cdb_archive_process(GCdbArchive *archive)
{
GServerBackend *base; /* Base de l'instance */
+ cdb_client **clients; /* Clients surveillés */
+ size_t last_count; /* Quantité de ces clients */
struct pollfd *fds; /* Surveillance des flux */
nfds_t nfds; /* Quantité de ces flux */
nfds_t i; /* Boucle de parcours */
@@ -912,20 +1056,38 @@ static void *g_cdb_archive_process(GCdbArchive *archive)
base = G_SERVER_BACKEND(archive);
+ clients = NULL;
+ last_count = 0;
+
fds = NULL;
while (1)
{
+ /* Réinitialisation ? */
+
+ for (i = 0; i < last_count; i++)
+ unref_cdb_client(clients[i]);
+
/* Reconstitution d'une liste à jour */
g_mutex_lock(&archive->clients_access);
- nfds = archive->count + 2;
+ last_count = archive->count;
+
+ clients = realloc(clients, last_count * sizeof(cdb_client));
+
+ for (i = 0; i < last_count; i++)
+ {
+ clients[i] = archive->clients[i];
+ ref_cdb_client(clients[i]);
+ }
+
+ nfds = last_count + 2;
fds = realloc(fds, nfds * sizeof(struct pollfd));
for (i = 0; i < (nfds - 2); i++)
{
- fds[i].fd = SSL_get_fd(archive->clients[i].tls_fd);
+ fds[i].fd = SSL_get_fd(clients[i]->tls_fd);
fds[i].events = POLLIN | POLLPRI;
}
@@ -978,7 +1140,7 @@ static void *g_cdb_archive_process(GCdbArchive *archive)
{
init_packed_buffer(&in_pbuf);
- status = ssl_recv_packed_buffer(&in_pbuf, archive->clients[i].tls_fd);
+ status = ssl_recv_packed_buffer(&in_pbuf, clients[i]->tls_fd);
if (!status) goto gcap_bad_exchange;
next_command:
@@ -988,17 +1150,12 @@ static void *g_cdb_archive_process(GCdbArchive *archive)
command = tmp32;
+ init_packed_buffer(&out_pbuf);
+
switch (command)
{
case DBC_SET_CONTENT:
-
status = g_cdb_archive_set_content(archive, &in_pbuf, &out_pbuf);
- if (!status) goto gcap_bad_reply;
-
- status = ssl_send_packed_buffer(&out_pbuf, archive->clients[i].tls_fd);
- if (!status) goto gcap_bad_reply;
-
- exit_packed_buffer(&out_pbuf);
break;
@@ -1007,7 +1164,7 @@ static void *g_cdb_archive_process(GCdbArchive *archive)
error = g_cdb_archive_write(archive);
- init_packed_buffer(&out_pbuf);
+ //init_packed_buffer(&out_pbuf);
status = extend_packed_buffer(&out_pbuf, (uint32_t []) { DBC_SAVE },
sizeof(uint32_t), true);
@@ -1016,7 +1173,7 @@ static void *g_cdb_archive_process(GCdbArchive *archive)
status = extend_packed_buffer(&out_pbuf, (uint32_t []) { error }, sizeof(uint32_t), true);
if (!status) goto gcap_bad_reply;
- status = ssl_send_packed_buffer(&out_pbuf, archive->clients[i].tls_fd);
+ status = ssl_send_packed_buffer(&out_pbuf, clients[i]->tls_fd);
if (!status) goto gcap_bad_reply;
exit_packed_buffer(&out_pbuf);
@@ -1057,10 +1214,10 @@ static void *g_cdb_archive_process(GCdbArchive *archive)
status = extend_packed_buffer(&out_pbuf, (uint8_t []) { 0x0 }, sizeof(uint8_t), true);
if (!status) goto gcap_bad_reply;
- status = ssl_send_packed_buffer(&out_pbuf, archive->clients[i].tls_fd);
- if (!status) goto gcap_bad_reply;
+ //status = ssl_send_packed_buffer(&out_pbuf, clients[i]->tls_fd);
+ //if (!status) goto gcap_bad_reply;
- exit_packed_buffer(&out_pbuf);
+ //exit_packed_buffer(&out_pbuf);
break;
@@ -1079,7 +1236,7 @@ static void *g_cdb_archive_process(GCdbArchive *archive)
&in_pbuf, &out_pbuf, archive->db);
if (!status) goto gcap_bad_reply;
- status = ssl_send_packed_buffer(&out_pbuf, archive->clients[i].tls_fd);
+ status = ssl_send_packed_buffer(&out_pbuf, clients[i]->tls_fd);
if (!status) goto gcap_bad_reply;
exit_packed_buffer(&out_pbuf);
@@ -1091,10 +1248,12 @@ static void *g_cdb_archive_process(GCdbArchive *archive)
if (!g_cdb_archive_send_snapshot_update(archive, &out_pbuf))
goto critical_error;
- status = ssl_send_packed_buffer(&out_pbuf, archive->clients[i].tls_fd);
- if (!status) goto gcap_bad_reply;
+ status = true;
- exit_packed_buffer(&out_pbuf);
+ //status = ssl_send_packed_buffer(&out_pbuf, clients[i]->tls_fd);
+ //if (!status) goto gcap_bad_reply;
+
+ //exit_packed_buffer(&out_pbuf);
break;
@@ -1103,10 +1262,10 @@ static void *g_cdb_archive_process(GCdbArchive *archive)
if (!g_cdb_archive_send_snapshot_change(archive, &out_pbuf))
goto critical_error;
- status = ssl_send_packed_buffer(&out_pbuf, archive->clients[i].tls_fd);
- if (!status) goto gcap_bad_reply;
+ //status = ssl_send_packed_buffer(&out_pbuf, clients[i]->tls_fd);
+ //if (!status) goto gcap_bad_reply;
- exit_packed_buffer(&out_pbuf);
+ //exit_packed_buffer(&out_pbuf);
break;
@@ -1225,6 +1384,17 @@ static void *g_cdb_archive_process(GCdbArchive *archive)
}
+ if (!status)
+ goto gcap_bad_reply;
+
+ if (get_packed_buffer_payload_length(&out_pbuf) > 0)
+ {
+ status = ssl_send_packed_buffer(&out_pbuf, clients[i]->tls_fd);
+ if (!status) goto gcap_bad_reply;
+ }
+
+ exit_packed_buffer(&out_pbuf);
+
if (has_more_data_in_packed_buffer(&in_pbuf))
goto next_command;
@@ -1268,6 +1438,12 @@ static void *g_cdb_archive_process(GCdbArchive *archive)
g_server_backend_stop(G_SERVER_BACKEND(archive));
+ for (i = 0; i < last_count; i++)
+ unref_cdb_client(clients[i]);
+
+ if (clients != NULL)
+ free(clients);
+
if (fds != NULL)
free(fds);
@@ -1291,40 +1467,100 @@ static void *g_cdb_archive_process(GCdbArchive *archive)
* *
******************************************************************************/
+static LoadingStatusHint g_cdb_archive_compute_loading_hint(GCdbArchive *archive)
+{
+ LoadingStatusHint result; /* Statut à retourner */
+
+
+ // Try
+ // g_mutex_lock(&archive->loading_access);
+
+
+
+ // cnt_file
+
+ if (archive->cnt_file == NULL)
+ result = LSH_NEED_CONTENT;
+
+ else
+ result = LSH_NEED_FORMAT;
+
+
+
+
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : archive = support pour le suivi d'une connexion. *
+* fd = canal de communication réseau ouvert. *
+* peer_name = désignation de la connexion. *
+* user = désignation de l'utilisateur de la connexion. *
+* *
+* Description : Prend en compte une connexion nouvelle d'un utilisateur. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
static void g_cdb_archive_add_client(GCdbArchive *archive, SSL *fd, const char *peer_name, const char *user)
{
cdb_client *client; /* Nouvelle fiche d'entité */
+ packed_buffer_t out_pbuf; /* Tampon d'émission */
+ LoadingStatusHint hint; /* Statut de chargement */
+ bool status; /* Bilan de lecture initiale */
+
+ client = create_cdb_client(fd, peer_name, user);
/**
- * La situation est un peu compliquée lors de l'accueil d'un nouveau client :
- *
- * - soit on envoie tous les éléments à prendre en compte, mais on doit
- * bloquer la base de données jusqu'à l'intégration pleine et entière
- * du client, afin que ce dernier ne loupe pas l'envoi d'un nouvel
- * élément entre temps.
+ * Le verrou encadrant les évolutions des contenus initiaux doit englober
+ * l'extension de la liste des clients.
*
- * - soit on intègre le client et celui ci demande des mises à jour
- * collection par collection ; c'est également à lui que revient le rejet
- * des éléments envoyés en solitaires avant la réception de la base
- * complète.
+ * En effet, une évolution partielle peut intervenir dans la fonction
+ * g_cdb_archive_process(), à un moment au seul le verrou dans les
+ * évolutions sera posé (g_cdb_archive_set_content() par exemple).
*
- * On fait le choix du second scenario ici, du fait de la difficulté
- * de maîtriser facilement la reconstitution d'une liste de clients dans
- * g_cdb_archive_process() depuis un autre flot d'exécution.
+ * Or g_cdb_archive_compute_loading_hint() doit fournir ici un état qui ne
+ * varie pas entre le calcul et l'envoi. Donc verrous sur les clients et
+ * l'état de l'archive doivent englover l'ensemble des traitements ci-après.
*/
+ g_mutex_lock(&archive->loading_access);
+
g_mutex_lock(&archive->clients_access);
- archive->clients = realloc(archive->clients, ++archive->count * sizeof(cdb_client));
+ hint = g_cdb_archive_compute_loading_hint(archive);
+
+ if (hint != LSH_READY)
+ hint = (archive->count == 0 ? hint : LSH_ON_WAIT_LIST);
+
+ init_packed_buffer(&out_pbuf);
+
+ status = craft_server_short_answer(DBC_LOADING_STATUS, hint, &out_pbuf);
+
+ if (status)
+ status = ssl_send_packed_buffer(&out_pbuf, fd);
+
+ exit_packed_buffer(&out_pbuf);
+
+ if (status)
+ {
+ archive->clients = realloc(archive->clients, ++archive->count * sizeof(cdb_client *));
- client = &archive->clients[archive->count - 1];
+ archive->clients[archive->count - 1] = client;
- client->tls_fd = fd;
- client->peer_name = strdup(peer_name);
- client->user = strdup(user);
+ }
g_mutex_unlock(&archive->clients_access);
+ g_mutex_unlock(&archive->loading_access);
+
}
@@ -1343,20 +1579,15 @@ static void g_cdb_archive_add_client(GCdbArchive *archive, SSL *fd, const char *
static void _g_cdb_archive_remove_client(GCdbArchive *archive, size_t index)
{
- cdb_client *client; /* Client à traiter */
-
assert(!g_mutex_trylock(&archive->clients_access));
- client = &archive->clients[index];
-
- SSL_free(client->tls_fd);
- free(client->user);
+ unref_cdb_client(archive->clients[index]);
if ((index + 1) < archive->count)
memmove(&archive->clients[index], &archive->clients[index + 1],
- (archive->count - index - 1) * sizeof(cdb_client));
+ (archive->count - index - 1) * sizeof(cdb_client *));
- archive->clients = realloc(archive->clients, --archive->count * sizeof(cdb_client));
+ archive->clients = realloc(archive->clients, --archive->count * sizeof(cdb_client *));
}
@@ -1407,7 +1638,7 @@ static void g_cdb_archive_send_reply_to_all_clients(GCdbArchive *archive, packed
for (i = 0; i < archive->count; i++)
{
- status = ssl_send_packed_buffer(pbuf, archive->clients[i].tls_fd);
+ status = ssl_send_packed_buffer(pbuf, archive->clients[i]->tls_fd);
if (!status)
{
log_variadic_message(LMT_ERROR, _("Error while replying to client %zu"), i);
@@ -1533,10 +1764,10 @@ static bool g_cdb_archive_send_snapshot_change(GCdbArchive *archive, packed_buff
/******************************************************************************
* *
* Paramètres : cmd = commande à l'origine d'un traitement. *
-* error = bilan de traitement à communiquer. *
+* value = valeur à communiquer. *
* out_pbuf = paquet à consituer pour un retour au client. [OUT]*
* *
-* Description : Prépare la réponse à envoyer à un client connecté. *
+* Description : Prépare une courte réponse à envoyer à un client connecté. *
* *
* Retour : Indication pour le maintien de la communication. *
* *
@@ -1544,7 +1775,7 @@ static bool g_cdb_archive_send_snapshot_change(GCdbArchive *archive, packed_buff
* *
******************************************************************************/
-static bool setup_server_answer(DBCommand cmd, DBError error, packed_buffer_t *out_pbuf)
+static bool craft_server_short_answer(DBCommand cmd, uleb128_t value, packed_buffer_t *out_pbuf)
{
bool result; /* Bilan à retourner */
@@ -1553,7 +1784,7 @@ static bool setup_server_answer(DBCommand cmd, DBError error, packed_buffer_t *o
result = extend_packed_buffer(out_pbuf, (uint32_t []) { cmd }, sizeof(uint32_t), true);
if (result)
- result = extend_packed_buffer(out_pbuf, (uint32_t []) { error }, sizeof(uint32_t), true);
+ result = pack_uleb128((uleb128_t []){ value }, out_pbuf);
return result;
@@ -1587,6 +1818,7 @@ static bool g_cdb_archive_set_content(GCdbArchive *archive, packed_buffer_t *in_
const gchar *hash; /* Empreinte de ce contenu */
int fd; /* Flux ouvert en écriture */
bool status; /* Bilan d'une écriture */
+ LoadingStatusHint hint; /* Statut de chargement */
result = true;
error = DBE_NONE;
@@ -1687,7 +1919,15 @@ static bool g_cdb_archive_set_content(GCdbArchive *archive, packed_buffer_t *in_
/* Formulation de la réponse */
- result = setup_server_answer(DBC_SET_CONTENT, error, out_pbuf);
+ result = craft_server_short_answer(DBC_SET_CONTENT, error, out_pbuf);
+
+ if (result && error == DBE_NONE)
+ {
+ hint = g_cdb_archive_compute_loading_hint(archive);
+
+ result = craft_server_short_answer(DBC_LOADING_STATUS, hint, out_pbuf);
+
+ }
free_and_exit:
diff --git a/src/analysis/db/cdb.h b/src/analysis/db/cdb.h
index b2c3fc3..7a557f2 100644
--- a/src/analysis/db/cdb.h
+++ b/src/analysis/db/cdb.h
@@ -54,7 +54,7 @@ typedef struct _GCdbArchiveClass GCdbArchiveClass;
GType g_cdb_archive_get_type(void);
/* Prépare un client pour une connexion à une BD. */
-GCdbArchive *g_cdb_archive_new(const char *, const char *, const rle_string *, DBError *);
+GCdbArchive *g_cdb_archive_new(const char *, const char *, const rle_string *, const rle_string *, DBError *);
/* Construit un chemin pour un fichier propre à l'archive. */
char *g_cdb_archive_get_tmp_filename(const GCdbArchive *, const char *);
@@ -62,8 +62,8 @@ char *g_cdb_archive_get_tmp_filename(const GCdbArchive *, const char *);
/* Enregistre une archive avec tous les éléments à conserver. */
DBError g_cdb_archive_write(const GCdbArchive *);
-/* Détermine si une empreinte correspond à celle d'une archive. */
-int g_cdb_archive_compare_hash(const GCdbArchive *, const rle_string *);
+/* Détermine l'archive correspond à une cible recherchée. */
+bool g_cdb_archive_compare_is_suitable_for(const GCdbArchive *, const rle_string *, const rle_string *);
diff --git a/src/analysis/db/items/Makefile.am b/src/analysis/db/items/Makefile.am
index b9ce117..f8f70d5 100644
--- a/src/analysis/db/items/Makefile.am
+++ b/src/analysis/db/items/Makefile.am
@@ -7,18 +7,9 @@ libanalysisdbitems_la_SOURCES = \
move.h move.c \
switcher.h switcher.c
-libanalysisdbitems_la_LIBADD =
-
-libanalysisdbitems_la_LDFLAGS =
+libanalysisdbitems_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) $(LIBSQLITE_CFLAGS)
devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%)
dev_HEADERS = $(libanalysisdbitems_la_SOURCES:%c=)
-
-
-AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBARCHIVE_CFLAGS) $(LIBSQLITE_CFLAGS)
-
-AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
-
-SUBDIRS =
diff --git a/src/analysis/db/items/comment.c b/src/analysis/db/items/comment.c
index da7a4c0..fb27f60 100644
--- a/src/analysis/db/items/comment.c
+++ b/src/analysis/db/items/comment.c
@@ -39,9 +39,9 @@
#include "../../human/asm/lang.h"
#include "../../../common/array.h"
#include "../../../common/extstr.h"
+#include "../../../core/columns.h"
#include "../../../glibext/gbinarycursor.h"
#include "../../../glibext/linegen-int.h"
-#include "../../../gtkext/gtkblockdisplay.h"
diff --git a/src/analysis/db/items/move.c b/src/analysis/db/items/move.c
index af1c8c1..e4f503b 100644
--- a/src/analysis/db/items/move.c
+++ b/src/analysis/db/items/move.c
@@ -35,9 +35,13 @@
#include "../collection-int.h"
#include "../item-int.h"
-#include "../../../gui/core/global.h"
+#ifdef INCLUDE_GTK_SUPPORT
+# include "../../../gui/core/global.h"
+#endif
#include "../../../glibext/gbinarycursor.h"
-#include "../../../glibext/gloadedpanel.h"
+#ifdef INCLUDE_GTK_SUPPORT
+# include "../../../glibext/gloadedpanel.h"
+#endif
@@ -410,6 +414,8 @@ static char *g_db_move_build_label(GDbMove *move)
static bool g_db_move_run(const GDbMove *move, GLineCursor *cursor)
{
+#ifdef INCLUDE_GTK_SUPPORT
+
GLoadedPanel *panel; /* Afficheur effectif de code */
typedef struct _move_params
@@ -465,6 +471,8 @@ static bool g_db_move_run(const GDbMove *move, GLineCursor *cursor)
if (panel != NULL)
g_object_unref(G_OBJECT(panel));
+#endif
+
return true;
}
diff --git a/src/analysis/db/misc/Makefile.am b/src/analysis/db/misc/Makefile.am
index 6d4af6c..fc3cab2 100644
--- a/src/analysis/db/misc/Makefile.am
+++ b/src/analysis/db/misc/Makefile.am
@@ -6,18 +6,7 @@ libanalysisdbmisc_la_SOURCES = \
snapshot.h snapshot.c \
timestamp.h timestamp.c
-libanalysisdbmisc_la_LIBADD =
-
-libanalysisdbmisc_la_LDFLAGS =
-
devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%)
dev_HEADERS = $(libanalysisdbmisc_la_SOURCES:%c=)
-
-
-AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBARCHIVE_CFLAGS) $(LIBSQLITE_CFLAGS)
-
-AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
-
-SUBDIRS =
diff --git a/src/analysis/db/protocol.h b/src/analysis/db/protocol.h
index 17263c8..7707058 100644
--- a/src/analysis/db/protocol.h
+++ b/src/analysis/db/protocol.h
@@ -76,14 +76,21 @@ typedef enum _ServerPrivLevels
+/**
+ * Précisions pour la commande DBC_LOADING_STATUS.
+ */
+
+
/* Eléments de base nécessaires */
-typedef enum _RequiredBasics
+typedef enum _LoadingStatusHint
{
- RBS_NONE = 0x0, /* (Plus) rien n'est requis */
- RBS_CONTENT = 0x1, /* Contenu binaire à analyser */
- RBS_LOADED = 0x2, /* Contenu binaire analysé */
+ LSH_READY = 0, /* (Plus) rien n'est requis */
+ LSH_ON_WAIT_LIST = 1, /* Concurrence des connexions */
+ LSH_NEED_CONTENT = 2, /* Suppléments nécessaires */
+ LSH_NEED_FORMAT = 3, /* Suppléments nécessaires */
+ LSH_NEED_ARCH = 4, /* Suppléments nécessaires */
-} RequiredBasics;
+} LoadingStatusHint;
@@ -135,6 +142,8 @@ typedef enum _DBAction
*/
typedef enum _DBCommand
{
+ /* ------------------------- Commandes à portée générale ------------------------- */
+
/**
* Le client envoie un tout premier paquet de la forme suivante :
*
@@ -176,6 +185,18 @@ typedef enum _DBCommand
/* ------------------------ Commandes pour analyste ------------------------ */
/**
+ * Gestion de la commande 'DBC_LOADING_STATUS'.
+ *
+ * Le serveur envoie un statut de prise en charge au début d'une connexion :
+ *
+ * [ Indication du serveur : DBC_LOADING_STATUS]
+ * [ Statut courant ; cf. LoadingStatusHint ]
+ *
+ */
+
+ DBC_LOADING_STATUS, /* Indications initiales */
+
+ /**
* Gestion de la commande 'DBC_SET_CONTENT'.
*
* Le client connecté envoie un paquet de la forme suivante :
diff --git a/src/analysis/db/server.c b/src/analysis/db/server.c
index b08962c..79d5df1 100644
--- a/src/analysis/db/server.c
+++ b/src/analysis/db/server.c
@@ -1028,7 +1028,7 @@ static GServerBackend *g_hub_server_handle_admin(GHubServer *server, packed_buff
if (has_more_data_in_packed_buffer(in_pbuf))
{
- log_variadic_message(LMT_ERROR, _("The client from '%s' provided to much data!"), peer_name);
+ log_variadic_message(LMT_ERROR, _("The client from '%s' provided too much data!"), peer_name);
result = NULL;
@@ -1074,6 +1074,7 @@ static GServerBackend *g_hub_server_handle_analyst(GHubServer *server, packed_bu
{
GCdbArchive *result; /* Support de suivi à retourner*/
rle_string hash; /* Empreinte du binaire visé */
+ rle_string class; /* Nature du contenu visé */
bool status; /* Bilan d'une opération */
GList *iter; /* Boucle de parcours */
GCdbArchive *archive; /* Destinataire final du client*/
@@ -1087,6 +1088,8 @@ static GServerBackend *g_hub_server_handle_analyst(GHubServer *server, packed_bu
/* Fin de réception des données envoyées */
+ setup_empty_rle_string(&hash);
+
status = unpack_rle_string(&hash, in_pbuf);
if (!status)
{
@@ -1097,13 +1100,28 @@ static GServerBackend *g_hub_server_handle_analyst(GHubServer *server, packed_bu
if (is_rle_string_empty(&hash))
{
log_variadic_message(LMT_ERROR, _("The submitted binary hash from '%s' is empty!"), peer_name);
- goto wrong_receiving;
+ goto wrong_receiving_0;
+ }
+
+ setup_empty_rle_string(&class);
+
+ status = unpack_rle_string(&class, in_pbuf);
+ if (!status)
+ {
+ log_variadic_message(LMT_ERROR, _("Error while getting the content class from '%s'..."), peer_name);
+ goto wrong_receiving_0;
+ }
+
+ if (is_rle_string_empty(&class))
+ {
+ log_variadic_message(LMT_ERROR, _("The submitted content class from '%s' is empty!"), peer_name);
+ goto wrong_receiving_1;
}
if (has_more_data_in_packed_buffer(in_pbuf))
{
- log_variadic_message(LMT_ERROR, _("The client from '%s' provided to much data!"), peer_name);
- goto wrong_receiving;
+ log_variadic_message(LMT_ERROR, _("The client from '%s' provided too much data!"), peer_name);
+ goto wrong_receiving_1;
}
/* Recherche d'un support existant adapté */
@@ -1114,7 +1132,7 @@ static GServerBackend *g_hub_server_handle_analyst(GHubServer *server, packed_bu
{
archive = G_CDB_ARCHIVE(iter->data);
- if (g_cdb_archive_compare_hash(archive, &hash) == 0)
+ if (g_cdb_archive_compare_is_suitable_for(archive, &hash, &class))
break;
}
@@ -1137,7 +1155,7 @@ static GServerBackend *g_hub_server_handle_analyst(GHubServer *server, packed_bu
tmpdir = strdup(server->working);
tmpdir = stradd(tmpdir, "tmp" G_DIR_SEPARATOR_S);
- result = g_cdb_archive_new(basedir, tmpdir, &hash, error);
+ result = g_cdb_archive_new(basedir, tmpdir, &hash, &class, error);
free(tmpdir);
free(basedir);
@@ -1146,7 +1164,11 @@ static GServerBackend *g_hub_server_handle_analyst(GHubServer *server, packed_bu
}
- wrong_receiving:
+ wrong_receiving_1:
+
+ exit_rle_string(&class);
+
+ wrong_receiving_0:
exit_rle_string(&hash);