From 90f9cf977a8eb6553d6bb4963202b90e2b8ff063 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sat, 16 Apr 2016 08:59:30 +0200
Subject: Created a basic tool to manage server configurations.

---
 .gitignore                  |   1 +
 ChangeLog                   |  22 +++
 src/Makefile.am             |  14 +-
 src/common/bits.c           |   3 +-
 src/common/bits.h           |   4 +-
 src/common/xml.c            |  55 +++++++
 src/common/xml.h            |   6 +
 src/csrvmng.c               | 369 ++++++++++++++++++++++++++++++++++++++++++++
 src/glibext/configuration.c |   2 +
 9 files changed, 472 insertions(+), 4 deletions(-)
 create mode 100644 src/csrvmng.c

diff --git a/.gitignore b/.gitignore
index 8005598..8349fb1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -66,6 +66,7 @@ resources.[ch]
 
 # Binaries
 src/chrysalide
+src/csrvmng
 tools/d2c/d2c
 
 # Misc
diff --git a/ChangeLog b/ChangeLog
index 8f0fc98..f7235b5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+16-04-16  Cyrille Bagard <nocbos@gmail.com>
+
+	* .gitignore:
+	Hide the new csrvmng from Git.
+
+	* src/Makefile.am:
+	Define csrvmng and add it to bin_PROGRAMS.
+
+	* src/common/bits.c:
+	* src/common/bits.h:
+	Disable some useless code.
+
+	* src/common/xml.c:
+	* src/common/xml.h:
+	Provide a way to delete nodes.
+
+	* src/csrvmng.c:
+	New entry: create a basic tool to manage server configurations.
+
+	* src/glibext/configuration.c:
+	Close the XML configuration file after reading.
+
 16-04-11  Cyrille Bagard <nocbos@gmail.com>
 
 	* src/analysis/binary.c:
diff --git a/src/Makefile.am b/src/Makefile.am
index 159c71f..452f163 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,7 +1,7 @@
 
 lib_LTLIBRARIES = libchrysacore.la libchrysaglibext.la libchrysadisass.la libchrysagtkext.la libchrysagui.la libchrysaplugin.la
 
-bin_PROGRAMS = chrysalide
+bin_PROGRAMS = chrysalide csrvmng
 
 .NOTPARALLEL: $(lib_LTLIBRARIES) $(bin_PROGRAMS)
 
@@ -106,6 +106,18 @@ chrysalide_LDADD = $(LIBINTL)
 
 
 ############################################################
+# Gestionnaire de serveurs distants
+############################################################
+
+csrvmng_SOURCES =						\
+	csrvmng.c
+
+
+csrvmng_LDFLAGS = $(LIBXML_LIBS) -Lcommon/.libs -lcommon
+
+
+
+############################################################
 # Le reste du monde
 ############################################################
 
diff --git a/src/common/bits.c b/src/common/bits.c
index 925c1b7..42493f2 100644
--- a/src/common/bits.c
+++ b/src/common/bits.c
@@ -547,7 +547,7 @@ unsigned long gfw(const bitfield_t *field)
 
 }
 
-
+#if 0
 
 /* ---------------------------------------------------------------------------------- */
 /*                           CHAMPS LIES À UNE ZONE MEMOIRE                           */
@@ -708,3 +708,4 @@ bool test_in_mem_field(memfield_t *field, const vmpa2t *addr)
     return result;
 
 }
+#endif
diff --git a/src/common/bits.h b/src/common/bits.h
index f2e1399..eb3a5af 100644
--- a/src/common/bits.h
+++ b/src/common/bits.h
@@ -80,7 +80,7 @@ bool is_bit_field_equal_to(const bitfield_t *, const bitfield_t *);
 
 unsigned long gfw(const bitfield_t *);
 
-
+#if 0
 /* ------------------------- CHAMPS LIES À UNE ZONE MEMOIRE ------------------------- */
 
 
@@ -110,7 +110,7 @@ bool test_in_mem_field(memfield_t *, const vmpa2t *);
 
 #define set_atomic_in_mem_field(f, range) false
 
-
+#endif
 
 
 #endif  /* _COMMON_BITS_H */
diff --git a/src/common/xml.c b/src/common/xml.c
index a9c65b5..952aaf7 100644
--- a/src/common/xml.c
+++ b/src/common/xml.c
@@ -843,6 +843,61 @@ xmlNodePtr add_node_to_node(xmlDocPtr xdoc, xmlNodePtr parent, const char *name)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : xdoc = structure XML chargée.                                *
+*                node = noeud à retirer de la structure.                      *
+*                                                                             *
+*  Description : Retire un noeud d'un document XML.                           *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void _remove_node_from_doc(xmlDocPtr xdoc, xmlNodePtr node)
+{
+    xmlUnlinkNode(node);
+    xmlFreeNode(node);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : xdoc    = structure XML chargée.                             *
+*                context = contexte à utiliser pour les recherches.           *
+*                path    = chemin d'accès au noeud visé.                      *
+*                                                                             *
+*  Description : Retire un noeud d'un document XML.                           *
+*                                                                             *
+*  Retour      : true si le noeud XML a bien été trouvé, false sinon.         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool remove_node_from_doc(xmlDocPtr xdoc, xmlXPathContextPtr context, const char *path)
+{
+    bool result;                            /* Bilan à retourner           */
+    xmlNodePtr node;                        /* Noeud à considérer          */
+
+    node = get_node_from_xpath(context, path);
+
+    if (node != NULL)
+    {
+        _remove_node_from_doc(xdoc, node);
+        result = true;
+    }
+    else
+        result = false;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : xdoc    = structure XML chargée.                             *
 *                context = contexte à utiliser pour les recherches.           *
 *                path    = chemin d'accès au noeud visé.                      *
diff --git a/src/common/xml.h b/src/common/xml.h
index 674bfd4..f16f31e 100644
--- a/src/common/xml.h
+++ b/src/common/xml.h
@@ -122,6 +122,12 @@ xmlNodePtr add_node_to_xpath(xmlDocPtr, xmlXPathContextPtr, const char *, const
 /* Ajoute un noeud à un autre noeud. */
 xmlNodePtr add_node_to_node(xmlDocPtr, xmlNodePtr, const char *);
 
+/* Retire un noeud d'un document XML. */
+void _remove_node_from_doc(xmlDocPtr, xmlNodePtr);
+
+/* Retire un noeud d'un document XML. */
+bool remove_node_from_doc(xmlDocPtr, xmlXPathContextPtr, const char *);
+
 /* S'assure qu'un noeud donné est bien présent dans le document. */
 xmlNodePtr ensure_node_exist(xmlDocPtr, xmlXPathContextPtr, const char *);
 
diff --git a/src/csrvmng.c b/src/csrvmng.c
new file mode 100644
index 0000000..e0b01e1
--- /dev/null
+++ b/src/csrvmng.c
@@ -0,0 +1,369 @@
+
+#include <fcntl.h>
+#include <getopt.h>
+#include <malloc.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+
+#include <common/xml.h>
+
+
+
+/* Affiche des indications sur l'utilisation du programme. */
+static void show_usage(const char *);
+
+/* Inscrit les paramètres d'accès au serveur configuré. */
+static bool init_server_config(xmlDoc *, xmlXPathContextPtr, const char *, short int);
+
+/* Lie un nouvel utilisateur à un serveur configuré. */
+static bool add_new_user_into_server_config(xmlDoc *, xmlXPathContextPtr, const char *, const char *);
+
+/* Retire un utilisateur des connaissances d'un serveur. */
+static bool remove_user_from_server_config(xmlDoc *, xmlXPathContextPtr, const char *);
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : binary = désignation du programme binaire courant.           *
+*                                                                             *
+*  Description : Affiche des indications sur l'utilisation du programme.      *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void show_usage(const char *binary)
+{
+    printf("\n");
+
+    printf("%s --help | --file <conf> [options...]\n", binary);
+
+    printf("\n");
+
+    printf("\n");
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : argc = nombre d'arguments dans la ligne de commande.         *
+*                argv = arguments de la ligne de commande.                    *
+*                                                                             *
+*  Description : Point d'entrée du programme.                                 *
+*                                                                             *
+*  Retour      : EXIT_SUCCESS si le prgm s'est déroulé sans encombres.        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int main(int argc, char **argv)
+{
+    int result;                             /* Bilan de l'exécution        */
+    bool need_help;                         /* Affichage de l'usage ?      */
+    char *filename;                         /* Fichier de configuration    */
+    char *address;                          /* Adresse d'un serveur        */
+    short int port;                         /* Port d'écoute associé       */
+    char *username;                         /* Utilisateur à manipuler     */
+    char *pubkey;                           /* Fichier de clef publique    */
+    bool need_removal;                      /* Suppression d'utilisateur   */
+    int opt_index;                          /* Indice de parcours          */
+    int ret;                                /* Bilan d'un appel            */
+    bool pair_ok;                           /* Associations correctes ?    */
+    xmlDoc *xdoc;                           /* Document XML à traiter      */
+    xmlXPathContextPtr ctx;                 /* Contexte XPath associé      */
+    bool has_conf;                          /* Fichier XML ouvert ?        */
+    bool status;                            /* Bilan d'un appel            */
+
+    static struct option long_options[] = {
+
+        { "help",   no_argument,        NULL,   'h' },
+
+        { "file",   required_argument,  NULL,   'f' },
+        { "addr",   required_argument,  NULL,   'a' },
+        { "port",   required_argument,  NULL,   'p' },
+        { "user",   required_argument,  NULL,   'u' },
+        { "key",    required_argument,  NULL,   'k' },
+        { "remove", no_argument,        NULL,   'r' },
+
+        { NULL,     0,                  NULL,   0   }
+
+    };
+
+    result = EXIT_FAILURE;
+
+    need_help = false;
+    filename = NULL;
+    address = NULL;
+    port = 0;
+    username = NULL;
+    pubkey = NULL;
+    need_removal = false;
+
+    for (opt_index = 0; ;)
+    {
+        ret = getopt_long(argc, argv, "hf:a:p:u:k:r", long_options, &opt_index);
+        if (ret == -1) break;
+
+        switch (ret)
+        {
+            case 'h':
+                need_help = true;
+                break;
+
+            case 'f':
+                filename = optarg;
+                break;
+
+            case 'a':
+                address = optarg;
+                break;
+
+            case 'p':
+                port = atoi(optarg);
+                break;
+
+            case 'u':
+                username = optarg;
+                break;
+
+            case 'k':
+                pubkey = optarg;
+                break;
+
+            case 'r':
+                need_removal = true;
+                break;
+
+            default:
+                need_help = true;
+                result = EXIT_FAILURE;
+                break;
+
+        }
+
+    }
+
+    /* Vérification des entrées */
+
+    pair_ok = true;
+
+    if (address != NULL)
+        pair_ok &= (port > 0);
+
+    if (port > 0)
+        pair_ok &= (address != NULL);
+
+    if (need_removal)
+        pair_ok &= (username != NULL);
+
+    else
+    {
+        if (username != NULL)
+            pair_ok &= (pubkey != NULL);
+
+        if (pubkey != NULL)
+            pair_ok &= (username != NULL);
+
+    }
+
+    if (need_help || filename == NULL || !pair_ok)
+    {
+        show_usage(argv[0]);
+
+        if (need_help)
+            result = EXIT_SUCCESS;
+
+        goto exit;
+
+    }
+
+    /* Traitement demandés */
+
+    has_conf = open_xml_file(filename, &xdoc, &ctx);
+
+    if (!has_conf)
+        has_conf = create_new_xml_file(&xdoc, &ctx);
+
+    if (address != NULL && port > 0)
+    {
+        status = init_server_config(xdoc, ctx, address, port);
+
+        result = (status ? EXIT_SUCCESS : EXIT_FAILURE);
+
+    }
+
+    if (username != NULL && pubkey != NULL)
+    {
+        status = add_new_user_into_server_config(xdoc, ctx, username, pubkey);
+
+        result = (status ? EXIT_SUCCESS : EXIT_FAILURE);
+
+    }
+
+    if (username != NULL && need_removal)
+    {
+        status = remove_user_from_server_config(xdoc, ctx, username);
+
+        if (status)
+            result = EXIT_SUCCESS;
+
+    }
+
+    save_xml_file(xdoc, filename);
+
+    close_xml_file(xdoc, ctx);
+
+ exit:
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : xdoc    = document XML à compléter.                          *
+*                ctx     = contete XPath à utiliser pour les parcours.        *
+*                address = adresse IP ou nom de domaine à contacter.          *
+*                port    = port désigné pour les communications.              *
+*                                                                             *
+*  Description : Inscrit les paramètres d'accès au serveur configuré.         *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool init_server_config(xmlDoc *xdoc, xmlXPathContextPtr ctx, const char *address, short int port)
+{
+    bool result;                            /* Bilan à faire remonter      */
+    const char *path;                       /* Chemin d'accès XML          */
+
+    path = "/ChrysalideServerConfig/Server";
+
+    result = add_content_to_node(xdoc, ctx, path, "");
+
+    result &= add_string_attribute_to_node(xdoc, ctx, path, "address", address);
+
+    result &= add_long_attribute_to_node(xdoc, ctx, path, "port", port);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : xdoc     = document XML à compléter.                         *
+*                ctx      = contete XPath à utiliser pour les parcours.       *
+*                username = nom de l'utilisateur à ajouter.                   *
+*                pubkey   = fichier contenant une clef publique.              *
+*                                                                             *
+*  Description : Lie un nouvel utilisateur à un serveur configuré.            *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool add_new_user_into_server_config(xmlDoc *xdoc, xmlXPathContextPtr ctx, const char *username, const char *pubkey)
+{
+    bool result;                            /* Bilan à faire remonter      */
+    int fd;                                 /* Descripteur du fichier      */
+    struct stat info;                       /* Informations sur le fichier */
+    int ret;                                /* Bilan d'un appel            */
+    void *content;                          /* Contenu brut du fichier     */
+    char *data;                             /* Données brutes à placer     */
+    const char *path;                       /* Chemin d'accès XML          */
+
+    result = false;
+
+    /* Récupération des données */
+
+    fd = open(pubkey, O_RDONLY);
+    if (fd == -1)
+    {
+        perror("open");
+        goto anuisc_exit;
+    }
+
+    ret = fstat(fd, &info);
+    if (ret == -1)
+    {
+        close(fd);
+        perror("fstat");
+        goto anuisc_exit;
+    }
+
+    content = mmap(NULL, info.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+    if (content == MAP_FAILED)
+    {
+        close(fd);
+        perror("mmap");
+        goto anuisc_exit;
+    }
+
+    data = (char *)calloc(info.st_size, sizeof(char));
+    memcpy(data, content, info.st_size);
+
+    munmap(content, info.st_size);
+    close(fd);
+
+    /* Création de l'entrée XML */
+
+    path = "/ChrysalideServerConfig/Access/User";
+
+    result = add_content_to_node(xdoc, ctx, path, data);
+
+    result &= add_string_attribute_to_node(xdoc, ctx, path, "name", username);
+
+    free(data);
+
+ anuisc_exit:
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : xdoc     = document XML à compléter.                         *
+*                ctx      = contete XPath à utiliser pour les parcours.       *
+*                username = nom de l'utilisateur à ajouter.                   *
+*                                                                             *
+*  Description : Retire un utilisateur des connaissances d'un serveur.        *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool remove_user_from_server_config(xmlDoc *xdoc, xmlXPathContextPtr ctx, const char *username)
+{
+    bool result;                            /* Bilan à faire remonter      */
+    char *path;                             /* Chemin d'accès XML          */
+
+    asprintf(&path, "/ChrysalideServerConfig/Access/User[@name=\"%s\"]", username);
+
+    result = remove_node_from_doc(xdoc, ctx, path);
+
+    free(path);
+
+    return result;
+
+}
diff --git a/src/glibext/configuration.c b/src/glibext/configuration.c
index d8547a6..a8f8af3 100644
--- a/src/glibext/configuration.c
+++ b/src/glibext/configuration.c
@@ -1267,6 +1267,8 @@ bool g_generic_config_read(GGenConfig *config)
 
     g_generic_config_runlock(config);
 
+    close_xml_file(xdoc, context);
+
     return true;
 
 }
-- 
cgit v0.11.2-87-g4458