diff options
Diffstat (limited to 'src/analysis/db/client.c')
-rw-r--r-- | src/analysis/db/client.c | 1081 |
1 files changed, 56 insertions, 1025 deletions
diff --git a/src/analysis/db/client.c b/src/analysis/db/client.c index ba0fec8..1f47eea 100644 --- a/src/analysis/db/client.c +++ b/src/analysis/db/client.c @@ -37,6 +37,7 @@ #include <i18n.h> +#include "client-int.h" #include "auth.h" #include "protocol.h" #include "misc/rlestr.h" @@ -47,59 +48,6 @@ -/* Format générique des adresses de connexion */ -typedef union _gen_sockaddr_t -{ - struct sockaddr_in inet4_addr; /* Adresse d'écoute IPv4 */ - struct sockaddr_in6 inet6_addr; /* Adresse d'écoute IPv6 */ - struct sockaddr inet_4_6_addr; /* Adresse d'écoute IPv4/6 */ - -} gen_sockaddr_t; - - -/* Description de client à l'écoute (instance) */ -struct _GHubClient -{ - GObject parent; /* A laisser en premier */ - - rle_string hash; /* Empreinte du binaire lié */ - GList *collections; /* Collections d'un binaire */ - - char *working; /* Répertoire de travail */ - - SSL_CTX *tls_ctx; /* Contexte du chiffrement */ - - int fd; /* Canal de communication */ - SSL *tls_fd; /* Même canal, mais sécurisé */ - char *desc; /* Description du lien */ - - GMutex sending_lock; /* Concurrence des envois */ - bool can_get_updates; /* Réception de maj possibles ?*/ - GThread *update; /* Procédure de traitement */ - - 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 _GHubClientClass -{ - GObjectClass parent; /* A laisser en premier */ - - /* Signaux */ - - void (* snapshots_updated) (GHubClient *); - void (* snapshot_changed) (GHubClient *); - -}; - - /* Initialise la classe des descriptions de fichier binaire. */ static void g_hub_client_class_init(GHubClientClass *); @@ -112,23 +60,17 @@ static void g_hub_client_dispose(GHubClient *); /* Procède à la libération totale de la mémoire. */ static void g_hub_client_finalize(GHubClient *); -/* Démarre réellement la connexion à la base de données. */ -static bool g_hub_client_start_common(GHubClient *, char *); - -/* Assure l'accueil des nouvelles mises à jour. */ -static void *g_hub_client_update(GHubClient *); - -/* Met à jour la liste des instantanés courants. */ -static bool g_hub_client_update_snapshots(GHubClient *, packed_buffer *); - -/* Met à jour l'identifiant de l'instantané courant. */ -static bool g_hub_client_update_current_snapshot(GHubClient *, packed_buffer *); +/* Format générique des adresses de connexion */ +typedef union _gen_sockaddr_t +{ + struct sockaddr_in inet4_addr; /* Adresse d'écoute IPv4 */ + struct sockaddr_in6 inet6_addr; /* Adresse d'écoute IPv6 */ + struct sockaddr inet_4_6_addr; /* Adresse d'écoute IPv4/6 */ -/* Identifie le canal de communication pour envois au serveur. */ -static SSL *g_hub_client_get_ssl_fd(GHubClient *); +} gen_sockaddr_t; -/* Marque le canal de communication comme disponible. */ -static void g_hub_client_put_ssl_fd(GHubClient *, SSL *); +/* Démarre réellement la connexion à la base de données. */ +static bool g_hub_client_start_common(GHubClient *, char *); @@ -157,22 +99,6 @@ static void g_hub_client_class_init(GHubClientClass *klass) object->dispose = (GObjectFinalizeFunc/* ! */)g_hub_client_dispose; object->finalize = (GObjectFinalizeFunc)g_hub_client_finalize; - g_signal_new("snapshots-updated", - G_TYPE_HUB_CLIENT, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(GHubClientClass, snapshots_updated), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - g_signal_new("snapshot-changed", - G_TYPE_HUB_CLIENT, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(GHubClientClass, snapshot_changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - } @@ -190,9 +116,6 @@ static void g_hub_client_class_init(GHubClientClass *klass) static void g_hub_client_init(GHubClient *client) { - setup_empty_rle_string(&client->hash); - client->collections = NULL; - client->working = NULL; client->tls_ctx = NULL; @@ -202,17 +125,10 @@ static void g_hub_client_init(GHubClient *client) client->desc = NULL; g_mutex_init(&client->sending_lock); - client->can_get_updates = false; + client->stop_ctrl[0] = -1; + client->stop_ctrl[1] = -1; client->update = NULL; - client->snapshots = NULL; - client->snap_count = 0; - g_mutex_init(&client->snap_lock); - - setup_empty_snapshot_id(&client->current); - client->has_current = false; - g_mutex_init(&client->cur_lock); - } @@ -230,12 +146,6 @@ static void g_hub_client_init(GHubClient *client) static void g_hub_client_dispose(GHubClient *client) { - g_hub_client_stop(client); - - g_mutex_clear(&client->cur_lock); - - g_mutex_clear(&client->snap_lock); - g_mutex_clear(&client->sending_lock); G_OBJECT_CLASS(g_hub_client_parent_class)->dispose(G_OBJECT(client)); @@ -257,10 +167,6 @@ static void g_hub_client_dispose(GHubClient *client) static void g_hub_client_finalize(GHubClient *client) { - size_t i; /* Boucle de parcours */ - - unset_rle_string(&client->hash); - if (client->working != NULL) free(client->working); @@ -270,15 +176,6 @@ static void g_hub_client_finalize(GHubClient *client) if (client->desc != NULL) free(client->desc); - if (client->snapshots != NULL) - { - for (i = 0; i < client->snap_count; i++) - exit_snapshot_info(&client->snapshots[i]); - - free(client->snapshots); - - } - G_OBJECT_CLASS(g_hub_client_parent_class)->finalize(G_OBJECT(client)); } @@ -286,33 +183,6 @@ static void g_hub_client_finalize(GHubClient *client) /****************************************************************************** * * -* Paramètres : hash = empreinte d'un binaire en cours d'analyse. * -* collections = ensemble de collections existantes. * -* * -* Description : Prépare un client pour une connexion à une BD. * -* * -* Retour : Structure mise en place ou NULL en cas d'échec. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GHubClient *g_hub_client_new(const char *hash, GList *collections) -{ - GHubClient *result; /* Adresse à retourner */ - - result = g_object_new(G_TYPE_HUB_CLIENT, NULL); - - init_static_rle_string(&result->hash, hash); - result->collections = collections; - - return result; - -} - - -/****************************************************************************** -* * * Paramètres : client = client pour les accès distants à manipuler. * * * * Description : Démarre la connexion à la base de données interne. * @@ -522,6 +392,7 @@ static bool g_hub_client_start_common(GHubClient *client, char *desc) char *filename; /* Fichier PEM à manipuler */ int ret; /* Bilan d'un appel */ char *rootdir; /* Racine pour le client */ + GHubClientClass *class; /* Classe du client connecté */ packed_buffer out_pbuf; /* Tampon d'émission */ bool status; /* Bilan d'une opération */ packed_buffer in_pbuf; /* Tampon de réception */ @@ -608,11 +479,13 @@ static bool g_hub_client_start_common(GHubClient *client, char *desc) goto ssl_error; } + class = G_HUB_CLIENT_GET_CLASS(client); + /** * On réalise l'envoi initial ; le premier paquet doit contenir : - * - la commande 'DBC_HELO'. - * - le numéro de version du client. - * - l'empreinte du binaire analysé. + * - la commande 'DBC_HELO' ; + * - le numéro de version du client ; + * - le rôle attendu de la connexion. * * Tout ceci est à synchroniser avec la fonction g_db_server_listener(). */ @@ -625,15 +498,19 @@ static bool g_hub_client_start_common(GHubClient *client, char *desc) status = extend_packed_buffer(&out_pbuf, (uint32_t []) { CDB_PROTOCOL_VERSION }, sizeof(uint32_t), true); if (!status) goto setup_error; - status = pack_rle_string(&client->hash, &out_pbuf); + status = extend_packed_buffer(&out_pbuf, &class->role, sizeof(uint32_t), true); if (!status) goto setup_error; + + + + status = ssl_send_packed_buffer(&out_pbuf, client->tls_fd); if (!status) goto setup_error; /** * Le serveur doit répondre pour un message type : - * - la commande 'DBC_WELCOME'. + * - la commande 'DBC_WELCOME' ; * - un identifiant d'erreur ('DBE_NONE', 'DBE_BAD_EXCHANGE' * ou 'DBE_WRONG_VERSION' ... 'DBE_LOADING_ERROR'). */ @@ -689,14 +566,19 @@ static bool g_hub_client_start_common(GHubClient *client, char *desc) } - client->can_get_updates = false; + ret = pipe(client->stop_ctrl); + if (ret != 0) + { + LOG_ERROR_N("pipe"); + goto sys_error; + } - client->update = g_thread_try_new("cdb_client", (GThreadFunc)g_hub_client_update, client, NULL); + client->update = g_thread_try_new("cdb_client", class->recv_func, client, NULL); if (client->update == NULL) { log_variadic_message(LMT_ERROR, _("Failed to start a listening thread for the server '%s'!"), desc); - goto comm_error; + goto sys_error; } exit_packed_buffer(&out_pbuf); @@ -704,6 +586,7 @@ static bool g_hub_client_start_common(GHubClient *client, char *desc) return true; + sys_error: comm_error: exit_packed_buffer(&in_pbuf); @@ -733,344 +616,6 @@ static bool g_hub_client_start_common(GHubClient *client, char *desc) * * * Paramètres : client = client pour les accès distants à manipuler. * * * -* Description : Assure l'accueil des nouvelles mises à jour. * -* * -* Retour : NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void *g_hub_client_update(GHubClient *client) -{ - packed_buffer out_pbuf; /* Tampon d'émission */ - bool status; /* Bilan d'une opération */ - struct pollfd fds; /* Surveillance des flux */ - packed_buffer in_pbuf; /* Tampon de réception */ - int ret; /* Bilan d'un appel */ - uint32_t tmp32; /* Valeur sur 32 bits */ - uint32_t command; /* Commande de la requête */ - DBError error; /* Bilan d'une commande passée */ - GDbCollection *collec; /* Collection visée au final */ - uint8_t tmp8; /* Valeur sur 8 bits */ - char *msg; /* Message d'erreur à imprimer */ - - /** - * Avant toute chose, on demande un stage d'actualisation ! - */ - - init_packed_buffer(&out_pbuf); - - status = extend_packed_buffer(&out_pbuf, (uint32_t []) { DBC_GET_SNAPSHOTS }, sizeof(uint32_t), true); - if (!status) - { - exit_packed_buffer(&out_pbuf); - goto exit; - } - - status = extend_packed_buffer(&out_pbuf, (uint32_t []) { DBC_GET_CUR_SNAPSHOT }, sizeof(uint32_t), true); - if (!status) - { - exit_packed_buffer(&out_pbuf); - goto exit; - } - - status = extend_packed_buffer(&out_pbuf, (uint32_t []) { DBC_GET_ALL_ITEMS }, sizeof(uint32_t), true); - if (!status) - { - exit_packed_buffer(&out_pbuf); - goto exit; - } - - status = ssl_send_packed_buffer(&out_pbuf, client->tls_fd); - if (!status) - { - log_simple_message(LMT_INFO, _("Failed to get all updates")); - exit_packed_buffer(&out_pbuf); - goto exit; - } - - exit_packed_buffer(&out_pbuf); - - /** - * Phase d'écoute continue... - */ - - fds.fd = client->fd; - fds.events = POLLIN | POLLPRI; - - init_packed_buffer(&in_pbuf); - - while (client->fd != -1) - { - ret = poll(&fds, 1, -1); - if (ret != 1) continue; - - /* Le canal est fermé, une sortie doit être demandée... */ - if (fds.revents & POLLNVAL) - break; - - /** - * Même chose, cf. "TCP: When is EPOLLHUP generated?" - * https://stackoverflow.com/questions/52976152/tcp-when-is-epollhup-generated/52976327#52976327 - */ - - if (fds.revents & (POLLHUP | POLLRDHUP)) - break; - - if (fds.revents & (POLLIN | POLLPRI)) - { - reset_packed_buffer(&in_pbuf); - - status = ssl_recv_packed_buffer(&in_pbuf, client->tls_fd); - if (!status) goto gdcu_bad_exchange; - - next_command: - - status = extract_packed_buffer(&in_pbuf, &command, sizeof(uint32_t), true); - if (!status) goto gdcu_bad_exchange; - - switch (command) - { - case DBC_SAVE: - - status = extract_packed_buffer(&in_pbuf, &tmp32, sizeof(uint32_t), true); - if (!status) goto gdcu_bad_exchange; - - error = tmp32; - - if (error == DBE_NONE) - log_variadic_message(LMT_INFO, _("Archive saved for binary '%s'"), - get_rle_string(&client->hash)); - else - log_variadic_message(LMT_ERROR, _("Failed to save the archive for binary '%s'"), - get_rle_string(&client->hash)); - - break; - - case DBC_COLLECTION: - - status = extract_packed_buffer(&in_pbuf, &tmp32, sizeof(uint32_t), true); - if (!status) goto gdcu_bad_exchange; - - collec = find_collection_in_list(client->collections, tmp32); - if (collec == NULL) goto gdcu_bad_exchange; - - if (client->can_get_updates) - status = g_db_collection_unpack(collec, &in_pbuf, NULL); - else - status = _g_db_collection_unpack(collec, &in_pbuf, (DBAction []) { 0 }, NULL); - - if (!status) goto gdcu_bad_exchange; - - break; - - case DBC_GET_ALL_ITEMS: - log_variadic_message(LMT_INFO, - _("This command is not available on this side: 0x%08x"), command); - goto gdcu_bad_exchange; - break; - - case DBC_SET_ALL_ITEMS: - - status = extract_packed_buffer(&in_pbuf, &tmp8, sizeof(uint8_t), true); - if (!status) goto gdcu_bad_exchange; - - client->can_get_updates = (tmp8 == 0x1); - break; - - case DBC_GET_SNAPSHOTS: - log_variadic_message(LMT_INFO, - _("This command is not available on this side: 0x%08x"), command); - goto gdcu_bad_exchange; - break; - - case DBC_SNAPSHOTS_UPDATED: - - status = g_hub_client_update_snapshots(client, &in_pbuf); - if (!status) goto gdcu_bad_exchange; - - break; - - case DBC_GET_CUR_SNAPSHOT: - log_variadic_message(LMT_INFO, - _("This command is not available on this side: 0x%08x"), command); - goto gdcu_bad_exchange; - break; - - case DBC_CUR_SNAPSHOT_UPDATED: - - status = g_hub_client_update_current_snapshot(client, &in_pbuf); - if (!status) goto gdcu_bad_exchange; - - break; - - case DBC_SET_CUR_SNAPSHOT: - case DBC_SET_SNAPSHOT_NAME: - case DBC_SET_SNAPSHOT_DESC: - case DBC_CREATE_SNAPSHOT: - case DBC_REMOVE_SNAPSHOT: - log_variadic_message(LMT_INFO, - _("This command is not available on this side: 0x%08x"), command); - goto gdcu_bad_exchange; - break; - - } - - if (has_more_data_in_packed_buffer(&in_pbuf)) - goto next_command; - - client->can_get_updates = true; - continue; - - gdcu_bad_exchange: - - asprintf(&msg, _("Bad reception from %s"), client->desc); - - LOG_ERROR(LMT_ERROR, msg); - - free(msg); - - break; - - } - - } - - exit: - - g_hub_client_stop(client); - - exit_packed_buffer(&in_pbuf); - - return NULL; - -} - - -/****************************************************************************** -* * -* Paramètres : client = client pour les accès distants à manipuler. * -* pbuf = données présentes à traiter. * -* * -* Description : Met à jour la liste des instantanés courants. * -* * -* Retour : true si l'opération s'est déroulée sans encombre, ou false. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_hub_client_update_snapshots(GHubClient *client, packed_buffer *pbuf) -{ - bool result; /* Validité à retourner */ - size_t i; /* Boucle de parcours */ - char id[SNAP_ID_HEX_SZ]; /* Caractères hexadécimaux */ - snapshot_info_t info; /* Description d'instantané */ - snapshot_info_t *dest; /* Destination de description */ - - result = true; - - g_mutex_lock(&client->snap_lock); - - if (client->snapshots != NULL) - { - for (i = 0; i < client->snap_count; i++) - exit_snapshot_info(&client->snapshots[i]); - - free(client->snapshots); - - client->snapshots = NULL; - client->snap_count = 0; - - } - - do - { - result = peek_packed_buffer(pbuf, id, SNAP_ID_HEX_SZ, false); - if (!result) break; - - if (strncmp(id, SNAPSHOT_END_MARK, SNAP_ID_HEX_SZ) == 0) - { - advance_packed_buffer(pbuf, SNAP_ID_HEX_SZ); - break; - } - - else - { - setup_empty_snapshot_info(&info); - - result = unpack_snapshot_info(&info, pbuf); - if (!result) break; - - client->snapshots = realloc(client->snapshots, ++client->snap_count * sizeof(snapshot_info_t)); - - dest = &client->snapshots[client->snap_count - 1]; - - setup_empty_snapshot_info(dest); - copy_snapshot_info(dest, &info); - - exit_snapshot_info(&info); - - } - - } - while (true); - - g_mutex_unlock(&client->snap_lock); - - if (result) - g_signal_emit_by_name(client, "snapshots-updated"); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : client = client pour les accès distants à manipuler. * -* pbuf = données présentes à traiter. * -* * -* Description : Met à jour l'identifiant de l'instantané courant. * -* * -* Retour : true si l'opération s'est déroulée sans encombre, ou false. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_hub_client_update_current_snapshot(GHubClient *client, packed_buffer *pbuf) -{ - bool result; /* Validité à retourner */ - snapshot_id_t id; /* Identifiant d'instantané */ - - setup_empty_snapshot_id(&id); - - result = unpack_snapshot_id(&id, pbuf); - - if (result) - { - g_mutex_lock(&client->cur_lock); - - copy_snapshot_id(&client->current, &id); - client->has_current = true; - - g_mutex_unlock(&client->cur_lock); - - g_signal_emit_by_name(client, "snapshot-changed"); - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : client = client pour les accès distants à manipuler. * -* * * Description : Arrête la connexion à la base de données. * * * * Retour : - * @@ -1083,8 +628,9 @@ void g_hub_client_stop(GHubClient *client) { int fd; /* Canal à clôturer */ int ret; /* Bilan d'un appel */ + ssize_t sent; /* Quantité de données émises */ - /* Canal de communication */ + /* Gestion du double appel */ if (client->fd == -1) { @@ -1103,13 +649,18 @@ void g_hub_client_stop(GHubClient *client) client->fd = -1; - ret = close(fd); - if (ret == -1) LOG_ERROR_N("close"); + /* Ordre d'arrêt */ if (g_thread_self() != client->update) + { + sent = write(client->stop_ctrl[1], "\xf0", 1); + if (sent != 1) LOG_ERROR_N("write"); + g_thread_join(client->update); - /* Environnement TLS */ + } + + /* Fermeture des flux */ SSL_free(client->tls_fd); client->tls_fd = NULL; @@ -1117,6 +668,17 @@ void g_hub_client_stop(GHubClient *client) SSL_CTX_free(client->tls_ctx); client->tls_ctx = NULL; + ret = close(fd); + if (ret == -1) LOG_ERROR_N("close"); + + ret = close(client->stop_ctrl[0]); + if (ret == -1) LOG_ERROR_N("close"); + client->stop_ctrl[0] = -1; + + ret = close(client->stop_ctrl[1]); + if (ret == -1) LOG_ERROR_N("close"); + client->stop_ctrl[1] = -1; + } @@ -1132,7 +694,7 @@ void g_hub_client_stop(GHubClient *client) * * ******************************************************************************/ -static SSL *g_hub_client_get_ssl_fd(GHubClient *client) +SSL *g_hub_client_get_ssl_fd(GHubClient *client) { SSL *result; /* Canal à retourner */ #ifndef NDEBUG @@ -1174,541 +736,10 @@ static SSL *g_hub_client_get_ssl_fd(GHubClient *client) * * ******************************************************************************/ -static void g_hub_client_put_ssl_fd(GHubClient *client, SSL *tls_fd) +void g_hub_client_put_ssl_fd(GHubClient *client, SSL *tls_fd) { g_mutex_unlock(&client->sending_lock); SSL_free(tls_fd); } - - -/****************************************************************************** -* * -* Paramètres : client = client pour les accès distants à manipuler. * -* * -* Description : Effectue une demande de sauvegarde de l'état courant. * -* * -* Retour : true si la commande a bien été envoyée, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_hub_client_save(GHubClient *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(client); - - if (tls_fd == NULL) - result = false; - - else - { - result = extend_packed_buffer(&out_pbuf, (uint32_t []) { DBC_SAVE }, sizeof(uint32_t), true); - - if (result) - result = ssl_send_packed_buffer(&out_pbuf, tls_fd); - - g_hub_client_put_ssl_fd(client, tls_fd); - - } - - exit_packed_buffer(&out_pbuf); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : client = client pour les accès distants à manipuler. * -* item = élémnent à pousser vers un serveur de collection. * -* * -* Description : Ajoute un élément à la collection d'un serveur. * -* * -* Retour : true si la commande a bien été envoyée, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_hub_client_add_item(GHubClient *client, const GDbItem *item) -{ - bool result; /* Bilan partiel à remonter */ - packed_buffer out_pbuf; /* Tampon d'émission */ - SSL *tls_fd; /* Canal de communication SSL */ - DBFeatures feature; /* Domaine de fonctionnalité */ - GDbCollection *collec; /* Collection visée au final */ - - init_packed_buffer(&out_pbuf); - - tls_fd = g_hub_client_get_ssl_fd(client); - - if (tls_fd == NULL) - result = false; - - else - { - feature = g_db_item_get_feature(item); - - collec = find_collection_in_list(client->collections, feature); - if (collec == NULL) - { - result = false; - goto bad_item_feature; - } - - result = g_db_collection_pack(collec, &out_pbuf, DBA_ADD_ITEM, item); - - if (result) - result = ssl_send_packed_buffer(&out_pbuf, tls_fd); - - bad_item_feature: - - g_hub_client_put_ssl_fd(client, tls_fd); - - } - - exit_packed_buffer(&out_pbuf); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : client = client pour les accès distants à manipuler. * -* timestamp = date du dernier élément à garder comme actif. * -* * -* Description : Active les éléments en amont d'un horodatage donné. * -* * -* Retour : true si la commande a bien été envoyée, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_hub_client_set_last_active(GHubClient *client, timestamp_t timestamp) -{ - 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(client); - - if (tls_fd == NULL) - result = false; - - else - { - result = extend_packed_buffer(&out_pbuf, (uint32_t []) { DBC_SET_LAST_ACTIVE }, sizeof(uint32_t), true); - - if (result) - result = pack_timestamp(×tamp, &out_pbuf); - - if (result) - result = ssl_send_packed_buffer(&out_pbuf, tls_fd); - - g_hub_client_put_ssl_fd(client, tls_fd); - - } - - exit_packed_buffer(&out_pbuf); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : client = client pour les accès distants à manipuler. * -* info = description des instantanés présents. [OUT] * -* count = taille de la liste retournée. [OUT] * -* * -* Description : Fournit la liste des instantanés existants. * -* * -* Retour : true si la liste retournée est valide, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_hub_client_get_snapshots(GHubClient *client, snapshot_info_t **info, size_t *count) -{ - bool result; /* Validité à retourner */ - size_t i; /* Boucle de parcours */ - snapshot_info_t *dest; /* Destination de description */ - - g_mutex_lock(&client->snap_lock); - - result = (client->snap_count > 0); - - if (result) - { - *info = malloc(client->snap_count * sizeof(snapshot_info_t)); - *count = client->snap_count; - - for (i = 0; i < client->snap_count; i++) - { - dest = &(*info)[i]; - - setup_empty_snapshot_info(dest); - copy_snapshot_info(dest, &client->snapshots[i]); - - } - - } - - g_mutex_unlock(&client->snap_lock); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : client = client pour les accès distants à manipuler. * -* id = identifiant d'instantané à renseigner. [OUT] * -* * -* Description : Fournit l'identifiant de l'instantané courant. * -* * -* Retour : true si l'identifiant retourné est valide, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_hub_client_get_current_snapshot(GHubClient *client, snapshot_id_t *id) -{ - bool result; /* Validité à retourner */ - - g_mutex_lock(&client->cur_lock); - - result = client->has_current; - - if (result) - copy_snapshot_id(id, &client->current); - - g_mutex_unlock(&client->cur_lock); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : client = client pour les accès distants à manipuler. * -* id = identifiant d'instantané à activer. * -* * -* Description : Définit l'identifiant de l'instantané courant. * -* * -* Retour : true si la commande a bien été envoyée, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_hub_client_set_current_snapshot(GHubClient *client, const snapshot_id_t *id) -{ - 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(client); - - if (tls_fd == NULL) - result = false; - - else - { - result = extend_packed_buffer(&out_pbuf, (uint32_t []) { DBC_SET_CUR_SNAPSHOT }, sizeof(uint32_t), true); - - if (result) - result = pack_snapshot_id(id, &out_pbuf); - - if (result) - result = ssl_send_packed_buffer(&out_pbuf, tls_fd); - - g_hub_client_put_ssl_fd(client, tls_fd); - - } - - exit_packed_buffer(&out_pbuf); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : client = client pour les accès distants à manipuler. * -* id = identifiant d'instantané à traiter. * -* name = désignation humaine pour l'instantané. * -* * -* Description : Définit la désignation d'un instantané donné. * -* * -* Retour : true si la commande a bien été envoyée, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_hub_client_set_snapshot_name(GHubClient *client, const snapshot_id_t *id, const char *name) -{ - bool result; /* Bilan partiel à remonter */ - packed_buffer out_pbuf; /* Tampon d'émission */ - SSL *tls_fd; /* Canal de communication SSL */ - rle_string string; /* Chaîne à transmettre */ - - init_packed_buffer(&out_pbuf); - - tls_fd = g_hub_client_get_ssl_fd(client); - - if (tls_fd == NULL) - result = false; - - else - { - result = extend_packed_buffer(&out_pbuf, (uint32_t []) { DBC_SET_SNAPSHOT_NAME }, sizeof(uint32_t), true); - - if (result) - result = pack_snapshot_id(id, &out_pbuf); - - if (result) - { - init_static_rle_string(&string, name); - - result = pack_rle_string(&string, &out_pbuf); - - exit_rle_string(&string); - - } - - if (result) - result = ssl_send_packed_buffer(&out_pbuf, tls_fd); - - g_hub_client_put_ssl_fd(client, tls_fd); - - } - - exit_packed_buffer(&out_pbuf); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : client = client pour les accès distants à manipuler. * -* id = identifiant d'instantané à traiter. * -* desc = description humaine pour l'instantané. * -* * -* Description : Définit la description d'un instantané donné. * -* * -* Retour : true si la commande a bien été envoyée, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_hub_client_set_snapshot_desc(GHubClient *client, const snapshot_id_t *id, const char *desc) -{ - bool result; /* Bilan partiel à remonter */ - packed_buffer out_pbuf; /* Tampon d'émission */ - SSL *tls_fd; /* Canal de communication SSL */ - rle_string string; /* Chaîne à transmettre */ - - init_packed_buffer(&out_pbuf); - - tls_fd = g_hub_client_get_ssl_fd(client); - - if (tls_fd == NULL) - result = false; - - else - { - result = extend_packed_buffer(&out_pbuf, (uint32_t []) { DBC_SET_SNAPSHOT_DESC }, sizeof(uint32_t), true); - - if (result) - result = pack_snapshot_id(id, &out_pbuf); - - if (result) - { - init_static_rle_string(&string, desc); - - result = pack_rle_string(&string, &out_pbuf); - - exit_rle_string(&string); - - } - - if (result) - result = ssl_send_packed_buffer(&out_pbuf, tls_fd); - - g_hub_client_put_ssl_fd(client, tls_fd); - - } - - exit_packed_buffer(&out_pbuf); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : client = client pour les accès distants à manipuler. * -* id = identifiant d'instantané à traiter. * -* * -* Description : Restaure un ancien instantané. * -* * -* Retour : true si la commande a bien été envoyée, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_hub_client_restore_snapshot(GHubClient *client, const snapshot_id_t *id) -{ - 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(client); - - if (tls_fd == NULL) - result = false; - - else - { - result = extend_packed_buffer(&out_pbuf, (uint32_t []) { DBC_SET_CUR_SNAPSHOT }, sizeof(uint32_t), true); - - if (result) - result = pack_snapshot_id(id, &out_pbuf); - - if (result) - result = ssl_send_packed_buffer(&out_pbuf, tls_fd); - - g_hub_client_put_ssl_fd(client, tls_fd); - - } - - exit_packed_buffer(&out_pbuf); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : client = client pour les accès distants à manipuler. * -* * -* Description : Crée un nouvel instantané à partir d'un autre. * -* * -* Retour : true si la commande a bien été envoyée, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_hub_client_create_snapshot(GHubClient *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(client); - - if (tls_fd == NULL) - result = false; - - else - { - result = extend_packed_buffer(&out_pbuf, (uint32_t []) { DBC_CREATE_SNAPSHOT }, sizeof(uint32_t), true); - - if (result) - result = ssl_send_packed_buffer(&out_pbuf, tls_fd); - - g_hub_client_put_ssl_fd(client, tls_fd); - - } - - exit_packed_buffer(&out_pbuf); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : client = client pour les accès distants à manipuler. * -* id = identifiant d'instantané à traiter. * -* rec = programme une suppression récursive. * -* * -* Description : Supprime un ancien instantané. * -* * -* Retour : true si la commande a bien été envoyée, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_hub_client_remove_snapshot(GHubClient *client, const snapshot_id_t *id, bool rec) -{ - 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(client); - - if (tls_fd == NULL) - result = false; - - else - { - result = extend_packed_buffer(&out_pbuf, (uint32_t []) { DBC_REMOVE_SNAPSHOT }, sizeof(uint32_t), true); - - if (result) - result = pack_snapshot_id(id, &out_pbuf); - - if (result) - result = extend_packed_buffer(&out_pbuf, (uint8_t []) { rec ? 0x1 : 0x0 }, sizeof(uint8_t), false); - - if (result) - result = ssl_send_packed_buffer(&out_pbuf, tls_fd); - - g_hub_client_put_ssl_fd(client, tls_fd); - - } - - exit_packed_buffer(&out_pbuf); - - return result; - -} |