summaryrefslogtreecommitdiff
path: root/src/analysis/db/client.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2014-08-18 21:55:24 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2014-08-18 21:55:24 (GMT)
commita0a7b6c1e05c78ae433f353d15e3366107b67d03 (patch)
treebca0b187778cf016c6131bfc982b08c67a38442b /src/analysis/db/client.c
parent161c0f8ab227af5033b1b6456607b9b9c3bc60df (diff)
Inserted storages and collections into loaded binaries (first steps).
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@389 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/analysis/db/client.c')
-rw-r--r--src/analysis/db/client.c272
1 files changed, 221 insertions, 51 deletions
diff --git a/src/analysis/db/client.c b/src/analysis/db/client.c
index 946f202..4b807ae 100644
--- a/src/analysis/db/client.c
+++ b/src/analysis/db/client.c
@@ -33,6 +33,9 @@
#include "protocol.h"
+#include "misc/rlestr.h"
+#include "../../common/io.h"
+#include "../../gui/panels/log.h"
@@ -41,9 +44,12 @@ struct _GDbClient
{
GObject parent; /* A laisser en premier */
- int fd;
- struct sockaddr_in addr; /* Adresse d'écoute */
+ rle_string hash; /* Empreinte du binaire lié */
+ GList *collections; /* Collections d'un binaire */
+ int fd; /* Canal de communication */
+
+ GMutex sending_lock; /* Concurrence des envois */
GThread *update; /* Procédure de traitement */
};
@@ -118,7 +124,7 @@ static void g_db_client_init(GDbClient *client)
/******************************************************************************
* *
-* Paramètres : binary = instance d'objet GLib à traiter. *
+* Paramètres : client = instance d'objet GLib à traiter. *
* *
* Description : Procède à la libération totale de la mémoire. *
* *
@@ -128,19 +134,19 @@ static void g_db_client_init(GDbClient *client)
* *
******************************************************************************/
-static void g_db_client_finalize(GDbClient *binary)
+static void g_db_client_finalize(GDbClient *client)
{
- //free(binary->filename);
+ unset_rle_string(&client->hash);
- G_OBJECT_CLASS(g_db_client_parent_class)->finalize(G_OBJECT(binary));
+ G_OBJECT_CLASS(g_db_client_parent_class)->finalize(G_OBJECT(client));
}
/******************************************************************************
* *
-* Paramètres : host = hôte à représenter pour le service. *
-* port = port de connexion pour les clients. *
+* 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. *
* *
@@ -150,28 +156,155 @@ static void g_db_client_finalize(GDbClient *binary)
* *
******************************************************************************/
-GDbClient *g_db_client_new(const char *host, short port)
+GDbClient *g_db_client_new(const char *hash, GDbCollection *collections)
{
GDbClient *result; /* Adresse à retourner */
- struct hostent *hp; /* Informations sur l'hôte */
result = g_object_new(G_TYPE_DB_CLIENT, NULL);
+ set_rle_string(&result->hash, hash);
+ result->collections = collections;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : client = client pour les accès distants à manipuler. *
+* host = hôte à représenter pour le service. *
+* port = port de connexion pour les clients. *
+* username = utilisateur effectuant les évolutions. *
+* *
+* Description : Démarre la connexion à la base de données. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_db_client_start(GDbClient *client, const char *host, unsigned short port, const char *username)
+{
+ struct hostent *hp; /* Informations sur l'hôte */
+ struct sockaddr_in addr; /* Adresse de transmission */
+ int ret; /* Bilan d'un appel */
+ rle_string user; /* Nom d'utilisateur associé */
+ uint32_t data; /* Mot de données lues */
+ DBError error; /* Validation de la connexion */
+
+ /* Identification du serveur à contacter */
+
hp = gethostbyname(host);
- if (hp == NULL) goto gdsn_error;
+ if (hp == NULL) return false;
- result->addr.sin_family = hp->h_addrtype;
- memcpy(&result->addr.sin_addr, hp->h_addr_list[0], sizeof(struct in_addr));
+ addr.sin_family = hp->h_addrtype;
+ memcpy(&addr.sin_addr, hp->h_addr_list[0], sizeof(struct in_addr));
- result->addr.sin_port = htons(port);
+ addr.sin_port = htons(port);
- return result;
+ /* Création d'un canal de communication */
+
+ client->fd = socket(AF_INET, SOCK_STREAM, 0);
+ if (client->fd == -1)
+ {
+ perror("socket");
+ return false;
+ }
+
+ ret = connect(client->fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
+ if (ret == -1)
+ {
+ perror("connect");
+ goto gdcs_no_listening;
+ }
- gdsn_error:
+ /* Préparation du nom d'utilisateur à diffuser */
- g_object_unref(G_OBJECT(result));
+ init_rle_string(&user, username);
- return NULL;
+ /**
+ * 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é.
+ * - l'identifiant de l'utilisateur effectuant des modifications.
+ *
+ * Tout ceci est à synchroniser avec la fonction g_db_server_listener().
+ */
+
+ if (!safe_send(client->fd, (uint32_t []) { htobe32(DBC_HELO) }, sizeof(uint32_t), MSG_MORE))
+ goto gdcs_error;
+
+ if (!safe_send(client->fd, (uint32_t []) { htobe32(CDB_PROTOCOL_VERSION) }, sizeof(uint32_t), MSG_MORE))
+ goto gdcs_error;
+
+ if (!send_rle_string(&client->hash, client->fd, MSG_MORE))
+ goto gdcs_error;
+
+ if (!send_rle_string(&user, client->fd, 0))
+ goto gdcs_error;
+
+ /**
+ * Le serveur doit répondre pour un message type :
+ * - la commande 'DBC_WELCOME'.
+ * - un identifiant d'erreur ('DBE_NONE' ou 'DBE_WRONG_VERSION').
+ */
+
+ if (!safe_recv(client->fd, &data, sizeof(uint32_t), 0))
+ goto gdcs_error;
+
+ if (be32toh(data) != DBC_WELCOME)
+ {
+ log_variadic_message(LMT_ERROR, _("The server '%s:%hu' did not welcome us!"), host, port);
+ goto gdcs_error;
+ }
+
+ if (!safe_recv(client->fd, &data, sizeof(uint32_t), 0))
+ goto gdcs_error;
+
+ error = be32toh(data);
+
+ switch (error)
+ {
+ case DBE_NONE:
+ log_variadic_message(LMT_INFO, _("Connected to the server '%s:%hu'!"), host, port);
+ break;
+
+ case DBE_WRONG_VERSION:
+ log_variadic_message(LMT_ERROR, _("The server '%s:%hu' does not use our protocol version (0x%08x)..."),
+ host, port, CDB_PROTOCOL_VERSION);
+ goto gdcs_error;
+ break;
+
+ default:
+ log_variadic_message(LMT_ERROR, _("The server '%s:%hu' uses an unknown protocol..."), host, port);
+ goto gdcs_error;
+ break;
+
+ }
+
+ client->update = g_thread_try_new("cdb_client", (GThreadFunc)g_db_client_update, client, NULL);
+ if (client->update == NULL)
+ {
+ log_variadic_message(LMT_ERROR, _("Failed to start a listening thread for the server '%s:%hu'!"),
+ host, port);
+ goto gdcs_error;
+ }
+
+ return true;
+
+ gdcs_error:
+
+ unset_rle_string(&user);
+
+ gdcs_no_listening:
+
+ close(client->fd);
+ client->fd = -1;
+
+ return false;
}
@@ -192,6 +325,10 @@ static void *g_db_client_update(GDbClient *client)
{
struct pollfd fds; /* Surveillance des flux */
int ret; /* Bilan d'un appel */
+ uint32_t val32; /* Valeur sur 32 bits */
+ bool status; /* Bilan d'une opération */
+ uint32_t command; /* Commande de la requête */
+ GDbCollection *collec; /* Collection visée au final */
fds.fd = client->fd;
fds.events = POLLIN | POLLPRI;
@@ -209,16 +346,50 @@ static void *g_db_client_update(GDbClient *client)
if (fds.revents & (POLLIN | POLLPRI))
{
+ status = safe_recv(fds.fd, &val32, sizeof(uint32_t), 0);
+ if (!status) goto gdcu_bad_exchange;
+
+ command = be32toh(val32);
+
+ switch (command)
+ {
+ case DBC_COLLECTION:
+
+ status = safe_recv(fds.fd, &val32, sizeof(uint32_t), 0);
+ if (!status) goto gdcu_bad_exchange;
+
+ collec = find_collection_in_list(client->collections, be32toh(val32));
+ if (collec == NULL) goto gdcu_bad_exchange;
+
+ status = g_db_collection_recv(collec, fds.fd);
+ if (!status) goto gdcu_bad_exchange;
+
+
+
+
+ printf("## CLIENT ## Got Something to read...\n");
+
+ break;
+
+ }
+
+ continue;
+
+ gdcu_bad_exchange:
+
+ printf("Bad reception...\n");
+
+ /* TODO : close conn */
+
+ ;
- /* TODO */
- pause();
}
}
- g_db_client_stop(client);
+ //g_db_client_stop(client);
return NULL;
@@ -229,39 +400,44 @@ static void *g_db_client_update(GDbClient *client)
* *
* Paramètres : client = client pour les accès distants à manipuler. *
* *
-* Description : Démarre la connexion à la base de données. *
+* Description : Arrête la connexion à la base de données. *
* *
-* Retour : Bilan de l'opération. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-bool g_db_client_start(GDbClient *client)
+void g_db_client_stop(GDbClient *client)
{
- int ret; /* Bilan d'un appel */
+ if (client->fd != -1)
+ return;
- client->fd = socket(AF_INET, SOCK_STREAM, 0);
- if (client->fd == -1)
- {
- perror("socket");
- return false;
- }
+ close(client->fd);
+ client->fd = -1;
- ret = connect(client->fd, (struct sockaddr *)&client->addr, sizeof(struct sockaddr_in));
- if (ret == -1)
- {
- perror("connect");
- close(client->fd);
- client->fd = -1;
- return false;
- }
+ g_thread_join(client->update);
- //client->update = g_thread_new("cdb_listener", (GThreadFunc)g_db_client_update, client);
+}
- send(client->fd, "A", 1, 0);
- return true;
+/******************************************************************************
+* *
+* Paramètres : client = client pour les accès distants à manipuler. *
+* *
+* Description : Identifie le canal de communication pour envois au serveur. *
+* *
+* Retour : Descripteur de flux normalement ouvert. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+int g_db_client_get_fd(GDbClient *client)
+{
+ g_mutex_lock(&client->sending_lock);
+
+ return client->fd;
}
@@ -270,7 +446,7 @@ bool g_db_client_start(GDbClient *client)
* *
* Paramètres : client = client pour les accès distants à manipuler. *
* *
-* Description : Arrête la connexion à la base de données. *
+* Description : Marque le canal de communication comme disponible. *
* *
* Retour : - *
* *
@@ -278,14 +454,8 @@ bool g_db_client_start(GDbClient *client)
* *
******************************************************************************/
-void g_db_client_stop(GDbClient *client)
+void g_db_client_put_fd(GDbClient *client)
{
- if (client->fd != -1)
- return;
-
- close(client->fd);
- client->fd = -1;
-
- g_thread_join(client->update);
+ g_mutex_unlock(&client->sending_lock);
}