#include #include #include #include #include #include #include #include #include #include #include /* 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 [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; }