summaryrefslogtreecommitdiff
path: root/src/analysis/db/cdb.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/analysis/db/cdb.c')
-rw-r--r--src/analysis/db/cdb.c218
1 files changed, 215 insertions, 3 deletions
diff --git a/src/analysis/db/cdb.c b/src/analysis/db/cdb.c
index 4da55fd..e4179d3 100644
--- a/src/analysis/db/cdb.c
+++ b/src/analysis/db/cdb.c
@@ -26,6 +26,7 @@
#include <assert.h>
#include <errno.h>
+#include <fcntl.h>
#include <malloc.h>
#include <poll.h>
#include <pthread.h>
@@ -45,9 +46,12 @@
#include "collection.h"
#include "protocol.h"
#include "snapshot.h"
+#include "../content.h"
+#include "../storage/storage.h"
#include "../../common/compression.h"
#include "../../common/cpp.h"
#include "../../common/extstr.h"
+#include "../../common/io.h"
#include "../../common/pathname.h"
#include "../../common/xml.h"
#include "../../core/collections.h"
@@ -79,6 +83,7 @@ struct _GCdbArchive
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 */
GList *collections; /* Ensemble de modifications */
@@ -163,6 +168,17 @@ 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 *);
+
+/* Enregistre le contenu binaire lié à une analyse. */
+static bool g_cdb_archive_set_content(GCdbArchive *, packed_buffer_t *, packed_buffer_t *);
+
+
+
/* ---------------------------------------------------------------------------------- */
/* COEUR DE LA GESTION D'ARCHIVES */
/* ---------------------------------------------------------------------------------- */
@@ -222,6 +238,8 @@ static void g_cdb_archive_init(GCdbArchive *archive)
archive->filename = NULL;
archive->tmpdir = NULL;
+ archive->cnt_file = NULL;
+ archive->xml_desc = NULL;
archive->collections = create_collections_list();
@@ -285,15 +303,18 @@ static void g_cdb_archive_finalize(GCdbArchive *archive)
#endif
}
+ if (archive->cnt_file != NULL)
+ free(archive->cnt_file);
+
if (archive->xml_desc != NULL)
free(archive->xml_desc);
- if (archive->filename != NULL)
- free(archive->filename);
-
if (archive->tmpdir != NULL)
free(archive->tmpdir);
+ if (archive->filename != NULL)
+ free(archive->filename);
+
exit_rle_string(&archive->hash);
G_OBJECT_CLASS(g_cdb_archive_parent_class)->finalize(G_OBJECT(archive));
@@ -932,6 +953,19 @@ static void *g_cdb_archive_process(GCdbArchive *archive)
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;
+
+
+
case DBC_SAVE:
error = g_cdb_archive_write(archive);
@@ -1451,3 +1485,181 @@ static bool g_cdb_archive_send_snapshot_change(GCdbArchive *archive, packed_buff
return result;
}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* PRISES EN COMPTE DES COMMANDES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : cmd = commande à l'origine d'un traitement. *
+* error = bilan de traitement à communiquer. *
+* out_pbuf = paquet à consituer pour un retour au client. [OUT]*
+* *
+* Description : Prépare la réponse à envoyer à un client connecté. *
+* *
+* Retour : Indication pour le maintien de la communication. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool setup_server_answer(DBCommand cmd, DBError error, packed_buffer_t *out_pbuf)
+{
+ bool result; /* Bilan à retourner */
+
+ init_packed_buffer(out_pbuf);
+
+ 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);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : archive = archive à connecter avec un utilisateur. *
+* in_pbuf = paquet à consulter. *
+* out_pbuf = paquet à consituer pour un retour au client. [OUT]*
+* *
+* Description : Enregistre le contenu binaire lié à une analyse. *
+* *
+* Retour : Indication pour le maintien de la communication. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_cdb_archive_set_content(GCdbArchive *archive, packed_buffer_t *in_pbuf, packed_buffer_t *out_pbuf)
+{
+ bool result; /* Bilan à retourner */
+ DBError error; /* Bilan d'une opération */
+ uleb128_t data_length; /* Taille du contenu stocké */
+ void *data; /* Données du stockage */
+ packed_buffer_t test_pbuf; /* Copie des données pour test */
+ uleb128_t pos; /* Position du contenu */
+ GObjectStorage *storage; /* Gestionnaire de stockage */
+ GSerializableObject *content; /* Contenu restitué */
+ const gchar *hash; /* Empreinte de ce contenu */
+ int ret; /* Retour d'un appel */
+ int fd; /* Flux ouvert en écriture */
+ bool status; /* Bilan d'une écriture */
+
+ result = true;
+ error = DBE_NONE;
+
+ /* Récupération de la charge utile */
+
+ result = unpack_uleb128(&data_length, in_pbuf);
+ if (!result) goto exit;
+
+ data = malloc(data_length);
+
+ result = extract_packed_buffer(in_pbuf, data, data_length, false);
+ if (!result) goto free_and_exit;
+
+ /* Validation de l'empreinte du contenu */
+
+ init_packed_buffer(&test_pbuf);
+
+ result = extend_packed_buffer(&test_pbuf, data, data_length, false);
+ if (!result) goto check_failure;
+
+ rewind_packed_buffer(&test_pbuf);
+
+ result = unpack_uleb128(&pos, &test_pbuf);
+ if (!result) goto check_failure;
+
+ storage = g_object_storage_load(&test_pbuf);
+ if (storage == NULL)
+ {
+ result = false;
+ goto check_failure;
+ }
+
+ content = g_object_storage_load_object(storage, "contents", pos);
+ if (!G_IS_BIN_CONTENT(content))
+ {
+ result = false;
+ goto storage_check_failure;
+ }
+
+ hash = g_binary_content_get_checksum(G_BIN_CONTENT(content));
+
+ if (strcmp(hash, get_rle_string(&archive->hash)) != 0)
+ error = DBE_WRONG_HASH;
+
+ g_object_unref(G_OBJECT(content));
+
+ storage_check_failure:
+
+ g_object_unref(G_OBJECT(storage));
+
+ check_failure:
+
+ exit_packed_buffer(&test_pbuf);
+
+ if (!result) goto free_and_exit;
+
+ /* Enregistrement sur disque */
+
+ if (error == DBE_NONE)
+ {
+ if (archive->cnt_file != NULL)
+ free(archive->cnt_file);
+
+ ret = asprintf(&archive->cnt_file, "%s" G_DIR_SEPARATOR_S "%s_storedcontent.bin",
+ archive->tmpdir, get_rle_string(&archive->hash));
+ if (ret == -1)
+ {
+ error = DBE_SYS_ERROR;
+ goto save_error;
+ }
+
+ fd = open(archive->cnt_file, O_WRONLY | O_CREAT, 0600);
+ if (fd == -1)
+ {
+ error = DBE_SYS_ERROR;
+ goto save_error;
+ }
+
+ status = safe_write(fd, data, data_length);
+
+ if (!status)
+ {
+ unlink(archive->cnt_file);
+ free(archive->cnt_file);
+ archive->cnt_file = NULL;
+
+ error = DBE_SYS_ERROR;
+
+ }
+
+ close(fd);
+
+ save_error:
+
+ ;
+
+ }
+
+ /* Formulation de la réponse */
+
+ result = setup_server_answer(DBC_SET_CONTENT, error, out_pbuf);
+
+ free_and_exit:
+
+ free(data);
+
+ exit:
+
+ return result;
+
+}