diff options
Diffstat (limited to 'src/analysis/db/cdb.c')
-rw-r--r-- | src/analysis/db/cdb.c | 218 |
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; + +} |