From 98076c3b06700b1cf24f3fdca1844c0dcf6faeb2 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Tue, 22 Feb 2022 20:11:49 +0100 Subject: Include cURL support for network operations. --- configure.ac | 15 ++++ src/Makefile.am | 3 +- src/common/Makefile.am | 5 +- src/common/curl.c | 231 +++++++++++++++++++++++++++++++++++++++++++++++++ src/common/curl.h | 54 ++++++++++++ 5 files changed, 305 insertions(+), 3 deletions(-) create mode 100644 src/common/curl.c create mode 100644 src/common/curl.h diff --git a/configure.ac b/configure.ac index 5c383a7..fbda04a 100644 --- a/configure.ac +++ b/configure.ac @@ -395,6 +395,20 @@ AC_SUBST(LIBSSL_CFLAGS) AC_SUBST(LIBSSL_LIBS) +#--- Checks for libcurl + +PKG_CHECK_MODULES(LIBCURL,libcurl >= 7.64,[libcurl_found=yes],[libcurl_found=no]) + +if test "$libcurl_found" = "yes"; then + libcurl_version=`pkg-config libcurl --modversion` +else + libcurl_version='-' +fi + +AC_SUBST(LIBCURL_CFLAGS) +AC_SUBST(LIBCURL_LIBS) + + #--- Checks for Python if test "x$enable_debug" = "xyes"; then @@ -628,6 +642,7 @@ echo The XML C parser and toolkit of Gnome........ : $libxml_version echo The flexible interface for archives I/O...... : $libarchive_version echo The small, fast and reliable database engine. : $libsqlite_version echo The cryptography and SSL/TLS toolkit......... : $libssl_version +echo The client URL library....................... : $libcurl_version echo echo Available Python programming language........ : $python3_version diff --git a/src/Makefile.am b/src/Makefile.am index f90d3bc..321b472 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -24,7 +24,8 @@ libchrysacore_la_SOURCES = \ libchrysacore_la_LDFLAGS = \ -avoid-version -ldl \ $(LIBGTK_LIBS) $(LIBXML_LIBS) \ - $(LIBSQLITE_LIBS) $(LIBARCHIVE_LIBS) + $(LIBSQLITE_LIBS) $(LIBARCHIVE_LIBS) \ + $(LIBCURL_LIBS) libchrysacore_la_LIBADD = \ analysis/libanalysis.la \ diff --git a/src/common/Makefile.am b/src/common/Makefile.am index 3379eed..28e5459 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -9,6 +9,7 @@ libcommon_la_SOURCES = \ bits.h bits.c \ compression.h compression.c \ cpp.h \ + curl.h curl.c \ dllist.h dllist.c \ endianness.h endianness.c \ environment.h environment.c \ @@ -30,7 +31,7 @@ libcommon_la_SOURCES = \ xdg.h xdg.c \ xml.h xml.c -libcommon_la_LDFLAGS = $(LIBGTK_LIBS) $(LIBXML_LIBS) +libcommon_la_LDFLAGS = $(LIBGTK_LIBS) $(LIBXML_LIBS) $(LIBCURL_LIBS) devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%) @@ -38,7 +39,7 @@ devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%) dev_HEADERS = $(libcommon_la_SOURCES:%c=) -AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) +AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBCURL_CFLAGS) AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) diff --git a/src/common/curl.c b/src/common/curl.c new file mode 100644 index 0000000..573180f --- /dev/null +++ b/src/common/curl.c @@ -0,0 +1,231 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * curl.c - encapsulation des fonctionnalités de cURL + * + * Copyright (C) 2022 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Chrysalide. If not, see . + */ + + +#include "curl.h" + + +#include +#include + + + +/* Mémorise les données reçues en réponse à une requête. */ +static size_t receive_data_from_internet(void *, size_t, size_t, curl_net_data_t *); + + + +/****************************************************************************** +* * +* Paramètres : contents = contenu nouveau en arrivance d'Internet. * +* size = taille d'un élément reçu. * +* nmemb = quantité de ces éléments. * +* data = zone de collecte à compléter. [OUT] * +* * +* Description : Mémorise les données reçues en réponse à une requête. * +* * +* Retour : Taille de données effectivement reçue. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static size_t receive_data_from_internet(void *contents, size_t size, size_t nmemb, curl_net_data_t *data) +{ + size_t realsize; /* Taille brute en octets */ + + realsize = size * nmemb; + + data->memory = realloc(data->memory, data->size + realsize + 1); + + memcpy(&(data->memory[data->size]), contents, realsize); + + data->size += realsize; + + data->memory[data->size] = 0; + + return realsize; + +} + + +/****************************************************************************** +* * +* Paramètres : url = resource distant à cibler. * +* headers = entêtes enventuels à joindre à la requête. * +* hcount = quantité de ces entêtes. * +* cookies = éventuels biscuits formatés ou NULL. * +* ecb = éventuelle fonction d'intervention à appeler. * +* resp = réponse obtenue du serveur distant. [OUT] * +* * +* Description : Mémorise les données reçues en réponse à une requête. * +* * +* Retour : Taille de données effectivement reçue. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool send_http_get_request(const char *url, char * const headers[], size_t hcount, const char *cookies, setup_extra_curl_cb ecb, curl_net_data_t *resp) +{ + bool result; /* Bilan d'opération à renvoyer*/ + CURL *req; /* Requête HTTP */ + struct curl_slist *hlist; /* Entêtes éventuelles */ + size_t i; /* Boucle de parcours */ + CURLcode ret; /* Code de retour d'opération */ + + result = false; + + resp->memory = NULL; + resp->size = 0; + + req = curl_easy_init(); + if (req == NULL) goto exit; + + curl_easy_setopt(req, CURLOPT_URL, url); + + /* Entêtes à transmettre */ + + hlist = NULL; + + for (i = 0; i < hcount; i++) + hlist = curl_slist_append(hlist, headers[i]); + + curl_easy_setopt(req, CURLOPT_HTTPHEADER, hlist); + + if (cookies != NULL) + curl_easy_setopt(req, CURLOPT_COOKIE, cookies); + + /* Réception des données */ + + curl_easy_setopt(req, CURLOPT_WRITEDATA, (void *)resp); + + curl_easy_setopt(req, CURLOPT_WRITEFUNCTION, receive_data_from_internet); + + /* Définition de la charge utile */ + + curl_easy_setopt(req, CURLOPT_HTTPGET, 1); + + /* Emission de la requête */ + + if (ecb != NULL) + ecb(req); + + ret = curl_easy_perform(req); + + result = (ret == CURLE_OK); + + if (!result) + fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(ret)); + + curl_slist_free_all(hlist); + + curl_easy_cleanup(req); + + exit: + + return result; + +} + +/****************************************************************************** +* * +* Paramètres : url = resource distant à cibler. * +* headers = entêtes enventuels à joindre à la requête. * +* hcount = quantité de ces entêtes. * +* cookies = éventuels biscuits formatés ou NULL. * +* payload = charge utile à transmettre au serveur distant. * +* ecb = éventuelle fonction d'intervention à appeler. * +* resp = réponse obtenue du serveur distant. [OUT] * +* * +* Description : Mémorise les données reçues en réponse à une requête. * +* * +* Retour : Taille de données effectivement reçue. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool send_http_post_request(const char *url, char * const headers[], size_t hcount, const char *cookies, const curl_net_data_t *payload, setup_extra_curl_cb ecb, curl_net_data_t *resp) +{ + bool result; /* Bilan d'opération à renvoyer*/ + CURL *req; /* Requête HTTP */ + struct curl_slist *hlist; /* Entêtes éventuelles */ + size_t i; /* Boucle de parcours */ + CURLcode ret; /* Code de retour d'opération */ + + result = false; + + resp->memory = NULL; + resp->size = 0; + + req = curl_easy_init(); + if (req == NULL) goto exit; + + curl_easy_setopt(req, CURLOPT_URL, url); + + /* Entêtes à transmettre */ + + hlist = NULL; + + for (i = 0; i < hcount; i++) + hlist = curl_slist_append(hlist, headers[i]); + + curl_easy_setopt(req, CURLOPT_HTTPHEADER, hlist); + + if (cookies != NULL) + curl_easy_setopt(req, CURLOPT_COOKIE, cookies); + + /* Réception des données */ + + curl_easy_setopt(req, CURLOPT_WRITEDATA, (void *)resp); + + curl_easy_setopt(req, CURLOPT_WRITEFUNCTION, receive_data_from_internet); + + /* Définition de la charge utile */ + + curl_easy_setopt(req, CURLOPT_POST, 1); + + curl_easy_setopt(req, CURLOPT_POSTFIELDS, payload->memory); + curl_easy_setopt(req, CURLOPT_POSTFIELDSIZE, payload->size); + + /* Emission de la requête */ + + if (ecb != NULL) + ecb(req); + + ret = curl_easy_perform(req); + + result = (ret == CURLE_OK); + + if (!result) + fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(ret)); + + curl_slist_free_all(hlist); + + curl_easy_cleanup(req); + + exit: + + return result; + +} diff --git a/src/common/curl.h b/src/common/curl.h new file mode 100644 index 0000000..02d9e91 --- /dev/null +++ b/src/common/curl.h @@ -0,0 +1,54 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * curl.h - prototypes pour l'encapsulation des fonctionnalités de cURL + * + * Copyright (C) 2022 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Chrysalide. If not, see . + */ + + +#ifndef _COMMON_CURL_H +#define _COMMON_CURL_H + + +#include +#include + + + +/* Données échangées avec Internet */ +typedef struct _curl_net_data_t +{ + char *memory; /* Zone de mémoire allouée */ + size_t size; /* Quantité de données */ + +} curl_net_data_t; + + +/* Prototype pour une intervention complémentaire dans la préparation des requêtes */ +typedef CURLcode (* setup_extra_curl_cb) (CURL *); + + +/* Mémorise les données reçues en réponse à une requête. */ +bool send_http_get_request(const char *, char * const [], size_t, const char *, setup_extra_curl_cb, curl_net_data_t *); + +/* Mémorise les données reçues en réponse à une requête. */ +bool send_http_post_request(const char *, char * const [], size_t, const char *, const curl_net_data_t *, setup_extra_curl_cb, curl_net_data_t *); + + + +#endif /* _COMMON_CURL_H */ -- cgit v0.11.2-87-g4458