diff options
Diffstat (limited to 'src/analysis/db/admin.c')
-rw-r--r-- | src/analysis/db/admin.c | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/src/analysis/db/admin.c b/src/analysis/db/admin.c index 355f8c0..771a912 100644 --- a/src/analysis/db/admin.c +++ b/src/analysis/db/admin.c @@ -25,10 +25,13 @@ #include <assert.h> +#include <malloc.h> #include <poll.h> +#include <string.h> #include "client-int.h" +#include "../../common/leb128.h" #include "../../core/logs.h" @@ -38,6 +41,10 @@ struct _GAdminClient { GHubClient parent; /* A laisser en premier */ + char **binaries; /* Liste de binaires existants*/ + size_t binaries_count; /* Taille de cette liste */ + GMutex binaries_lock; /* Concurrence des accès */ + }; /* Description de client à l'écoute (classe) */ @@ -45,6 +52,10 @@ struct _GAdminClientClass { GHubClientClass parent; /* A laisser en premier */ + /* Signaux */ + + void (* existing_binaries_updated) (GAdminClient *); + }; @@ -63,6 +74,9 @@ static void g_admin_client_finalize(GAdminClient *); /* Assure l'accueil des nouvelles mises à jour. */ static void *g_admin_client_update(GAdminClient *); +/* Met à jour la liste des binaires existants. */ +static bool g_admin_client_update_existing_binaries(GAdminClient *, packed_buffer *); + /* Indique le type défini pour une description de client à l'écoute. */ @@ -96,6 +110,14 @@ static void g_admin_client_class_init(GAdminClientClass *klass) client->role = CRL_ADMIN; client->recv_func = (GThreadFunc)g_admin_client_update; + g_signal_new("existing-binaries-updated", + G_TYPE_ADMIN_CLIENT, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GAdminClientClass, existing_binaries_updated), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + } @@ -113,6 +135,9 @@ static void g_admin_client_class_init(GAdminClientClass *klass) static void g_admin_client_init(GAdminClient *client) { + client->binaries = NULL; + client->binaries_count = 0; + g_mutex_init(&client->binaries_lock); } @@ -152,6 +177,19 @@ static void g_admin_client_dispose(GAdminClient *client) static void g_admin_client_finalize(GAdminClient *client) { + size_t i; /* Boucle de parcours */ + + if (client->binaries != NULL) + { + for (i = 0; i < client->binaries_count; i++) + free(client->binaries[i]); + + free(client->binaries); + + } + + g_mutex_clear(&client->binaries_lock); + G_OBJECT_CLASS(g_admin_client_parent_class)->finalize(G_OBJECT(client)); } @@ -256,6 +294,11 @@ static void *g_admin_client_update(GAdminClient *client) switch (command) { + case DBC_EXISTING_BINARIES: + status = g_admin_client_update_existing_binaries(client, &in_pbuf); + if (!status) goto bad_exchange; + break; + default: log_variadic_message(LMT_INFO, _("This command is not available on this side: 0x%08x"), command); @@ -290,3 +333,169 @@ static void *g_admin_client_update(GAdminClient *client) return NULL; } + + +/****************************************************************************** +* * +* Paramètres : client = client pour les accès distants à manipuler. * +* * +* Description : Effectue une demande de liste de binaires existants. * +* * +* Retour : true si la commande a bien été envoyée, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_admin_client_request_existing_binaries(GAdminClient *client) +{ + bool result; /* Bilan partiel à remonter */ + packed_buffer out_pbuf; /* Tampon d'émission */ + SSL *tls_fd; /* Canal de communication SSL */ + + init_packed_buffer(&out_pbuf); + + tls_fd = g_hub_client_get_ssl_fd(G_HUB_CLIENT(client)); + + if (tls_fd == NULL) + result = false; + + else + { + result = extend_packed_buffer(&out_pbuf, (uint32_t []) { DBC_LIST_BINARIES }, sizeof(uint32_t), true); + + if (result) + result = ssl_send_packed_buffer(&out_pbuf, tls_fd); + + g_hub_client_put_ssl_fd(G_HUB_CLIENT(client), tls_fd); + + } + + exit_packed_buffer(&out_pbuf); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : client = client pour les accès distants à manipuler. * +* pbuf = données présentes à traiter. * +* * +* Description : Met à jour la liste des binaires existants. * +* * +* Retour : true si l'opération s'est déroulée sans encombre, ou false. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_admin_client_update_existing_binaries(GAdminClient *client, packed_buffer *pbuf) +{ + bool result; /* Validité à retourner */ + size_t i; /* Boucle de parcours */ + uleb128_t count; /* Nombre d'éléments détectés */ + rle_string name; /* Nom à exporter */ + + result = true; + + g_mutex_lock(&client->binaries_lock); + + if (client->binaries != NULL) + { + for (i = 0; i < client->binaries_count; i++) + free(client->binaries[i]); + + free(client->binaries); + + client->binaries = NULL; + client->binaries_count = 0; + + } + + result = unpack_uleb128(&count, pbuf); + if (!result) goto exit; + + client->binaries_count = count; + + if (count > 0) + { + client->binaries = calloc(client->binaries_count, sizeof(char *)); + + for (i = 0; i < client->binaries_count; i++) + { + result = unpack_rle_string(&name, pbuf); + if (!result) break; + + client->binaries[i] = strdup(name.data); + + exit_rle_string(&name); + + } + + if (i < client->binaries_count) + { + for (i = 0; i < client->binaries_count; i++) + if (client->binaries[i] != NULL) + free(client->binaries[i]); + + free(client->binaries); + + client->binaries = NULL; + client->binaries_count = 0; + + } + + } + + exit: + + g_mutex_unlock(&client->binaries_lock); + + if (result) + g_signal_emit_by_name(client, "existing-binaries-updated"); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : client = client pour les accès distants à manipuler. * +* count = taille de la liste retournée. [OUT] * +* * +* Description : Fournit la liste des instantanés existants. * +* * +* Retour : Liste de binaires en place ou NULL si aucun. * +* * +* Remarques : - * +* * +******************************************************************************/ + +char **g_admin_client_get_existing_binaries(GAdminClient *client, size_t *count) +{ + char **result; /* Liste à retourner */ + size_t i; /* Boucle de parcours */ + + result = NULL; + *count = 0; + + g_mutex_lock(&client->binaries_lock); + + if (client->binaries_count > 0) + { + result = malloc(client->binaries_count * sizeof(char *)); + *count = client->binaries_count; + + for (i = 0; i < client->binaries_count; i++) + result[i] = strdup(client->binaries[i]); + + } + + g_mutex_unlock(&client->binaries_lock); + + return result; + +} |