diff options
| -rw-r--r-- | configure.ac | 15 | ||||
| -rw-r--r-- | src/Makefile.am | 3 | ||||
| -rw-r--r-- | src/common/Makefile.am | 5 | ||||
| -rw-r--r-- | src/common/curl.c | 231 | ||||
| -rw-r--r-- | src/common/curl.h | 54 | 
5 files changed, 305 insertions, 3 deletions
| 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 <http://www.gnu.org/licenses/>. + */ + + +#include "curl.h" + + +#include <malloc.h> +#include <string.h> + + + +/* 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 <http://www.gnu.org/licenses/>. + */ + + +#ifndef _COMMON_CURL_H +#define _COMMON_CURL_H + + +#include <stdbool.h> +#include <curl/curl.h> + + + +/* 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 */ | 
