diff options
author | Thomas "Cakeisalie5" Touhey <thomas@touhey.fr> | 2018-03-20 15:59:30 +0100 |
---|---|---|
committer | Thomas "Cakeisalie5" Touhey <thomas@touhey.fr> | 2018-03-20 15:59:30 +0100 |
commit | 7621e2010121af73a0c5e6956487d459e6129324 (patch) | |
tree | 11ab1d6a3b4fc374678b113c029d37334e7955b8 | |
parent | 94f683d97f19bbbc8e29842a48b28061ab1e89c8 (diff) |
Ajouté multi-usage du même handle curl, corrigé quelques lectures dangereuses.
-rw-r--r-- | daemon/cfg.c | 42 | ||||
-rw-r--r-- | daemon/cgi.c | 77 | ||||
-rw-r--r-- | daemon/error.c | 3 | ||||
-rw-r--r-- | daemon/internals.h | 13 | ||||
-rw-r--r-- | daemon/main.c | 7 | ||||
-rw-r--r-- | daemon/wes.c | 89 |
6 files changed, 149 insertions, 82 deletions
diff --git a/daemon/cfg.c b/daemon/cfg.c index 5ae5702..2bbf965 100644 --- a/daemon/cfg.c +++ b/daemon/cfg.c @@ -41,23 +41,14 @@ * Utilitaires. * --- */ -/* `prepare_request()`: Préparation d'une requête, avec URL et identifiants. */ +/* `get_request()`: Préparation d'une requête, avec URL et identifiants. */ -static int prepare_request(CURL *curl, wes_t *wes, const char *section) +static int get_request(wes_t *wes, CURL **handlep, const char *section) { - char url[40 + SECSIZE]; - const unsigned char *ip; + char path[10 + SECSIZE]; - ip = wes->addr.data.inet.ipv4; - sprintf(url, "ftp://%d.%d.%d.%d/CFG/%s.CFG", ip[0], ip[1], ip[2], ip[3], - section); - - curl_easy_setopt(curl, CURLOPT_URL, url); - curl_easy_setopt(curl, CURLOPT_USERNAME, wes->ftp_name); - curl_easy_setopt(curl, CURLOPT_PASSWORD, wes->ftp_pass); - curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L); - - return (WROK); + sprintf(path, "/CFG/%s.CFG", section); + return (open_http_handle(wes, handlep, path)); } /* `normalize_section()`: Normalisation du nom de section. */ @@ -137,11 +128,10 @@ static int normalize_value(char *buf, const char *src) static int emptysection(wescfgsec_t *sec) { - wescfg_t *cfg, **cfgp; + wescfg_t *cfg; - cfgp = &sec->child; - while ((cfg = *cfgp)) { - cfgp = &cfg->next; + while ((cfg = sec->child)) { + sec->child = cfg->next; free(cfg); } @@ -286,6 +276,7 @@ static int gathersection(wes_t *wes, wescfgsec_t *sec) struct getcookie cookie; CURL *curl; CURLcode cres; const char *section; + int err; section = sec->data; @@ -295,9 +286,8 @@ static int gathersection(wes_t *wes, wescfgsec_t *sec) /* On initialise la requête. */ - curl = curl_easy_init(); - if (!curl) - return (WRUNKNOWN); + if ((err = get_request(wes, &curl, section))) + return (err); cookie.sec = sec; cookie.step = SG_KEY; @@ -305,12 +295,10 @@ static int gathersection(wes_t *wes, wescfgsec_t *sec) cookie.hadval = 0; cookie.err = WROK; - prepare_request(curl, wes, section); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, getsection_callback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &cookie); cres = curl_easy_perform(curl); - curl_easy_cleanup(curl); if (cres != CURLE_OK) { emptysection(sec); @@ -446,6 +434,7 @@ static int sendsection(wes_t *wes, wescfgsec_t *sec) struct sendcookie cookie; curl_off_t fsize; wescfg_t *cfg; + int err; /* On calcule le nombre total de bytes que cela va prendre. */ @@ -459,14 +448,15 @@ static int sendsection(wes_t *wes, wescfgsec_t *sec) if (!curl) return (WRUNKNOWN); - prepare_request(curl, wes, &sec->data[sec->keysz]); - curl_easy_setopt(curl, CURLOPT_UPLOAD, 1); + if ((err = get_request(wes, &curl, &sec->data[sec->keysz]))) + return (err); + + curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); curl_easy_setopt(curl, CURLOPT_READDATA, &cookie); curl_easy_setopt(curl, CURLOPT_READFUNCTION, sendsection_callback); curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)fsize); cres = curl_easy_perform(curl); - curl_easy_cleanup(curl); switch (cres) { case CURLE_OK: diff --git a/daemon/cgi.c b/daemon/cgi.c index 02c157b..4e953e2 100644 --- a/daemon/cgi.c +++ b/daemon/cgi.c @@ -213,17 +213,16 @@ static curl_off_t estimatescriptsize(int num, const wescgi_t *blocks) static int sendscript(wes_t *wes, int num, const wescgi_t *blocks) { - CURL *curl; - CURLcode cres; - char url[50]; - const unsigned char *ip; + CURL *curl; CURLcode cres; + char path[50]; struct ucookie cookie; + int err; /* Initialisation du handle de la libcurl. */ - curl = curl_easy_init(); - if (!curl) - return (WRUNKNOWN); + sprintf(path, "/WH%d.CGI", wes->id); + if ((err = open_ftp_handle(wes, &curl, path))) + return (err); /* Initialisation du cookie. */ @@ -240,13 +239,6 @@ static int sendscript(wes_t *wes, int num, const wescgi_t *blocks) /* Définition des méta-informations. */ - ip = wes->addr.data.inet.ipv4; - sprintf(url, "ftp://%d.%d.%d.%d/WH%d.CGI", ip[0], ip[1], ip[2], ip[3], - wes->id); - - curl_easy_setopt(curl, CURLOPT_URL, url); - curl_easy_setopt(curl, CURLOPT_USERNAME, wes->ftp_name); - curl_easy_setopt(curl, CURLOPT_PASSWORD, wes->ftp_pass); curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L); curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); @@ -260,7 +252,6 @@ static int sendscript(wes_t *wes, int num, const wescgi_t *blocks) /* Exécution de la requête. */ cres = curl_easy_perform(curl); - curl_easy_cleanup(curl); switch (cres) { case CURLE_OK: @@ -314,30 +305,22 @@ static size_t delscript_write(char *buffer, size_t blksize, size_t nmemb, static int delscript(wes_t *wes) { - char url[50], hdr[20]; - const unsigned char *ip; + char hdr[20]; CURL *curl; CURLcode cres; struct curl_slist *headerlist = NULL; + int err; /* Initialisation du handle de la libcurl. */ - curl = curl_easy_init(); - if (!curl) - return (WRUNKNOWN); + if ((err = open_ftp_handle(wes, &curl, "/"))) + return (err); /* Préparation des méta-informations. */ - ip = wes->addr.data.inet.ipv4; - sprintf(url, "ftp://%d.%d.%d.%d/", ip[0], ip[1], ip[2], ip[3]); sprintf(hdr, "DELE WH%d.CGI", wes->id); headerlist = curl_slist_append(headerlist, hdr); - curl_easy_setopt(curl, CURLOPT_URL, url); - curl_easy_setopt(curl, CURLOPT_USERNAME, wes->ftp_name); - curl_easy_setopt(curl, CURLOPT_PASSWORD, wes->ftp_pass); - curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L); - curl_easy_setopt(curl, CURLOPT_QUOTE, headerlist); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, delscript_write); @@ -345,8 +328,6 @@ static int delscript(wes_t *wes) /* Exécution de la requête. */ cres = curl_easy_perform(curl); - curl_easy_cleanup(curl); - curl_slist_free_all(headerlist); switch (cres) { @@ -581,17 +562,16 @@ static size_t execscript_write(char *buffer, size_t blksize, size_t nmemb, static int execscript(wes_t *wes, int num, wescgi_t *blocks) { - CURL *curl; - CURLcode cres; - char url[50], sepbuf[sizeof(REQSEP) + 1]; - const unsigned char *ip; + CURL *curl; CURLcode cres; + char path[20], sepbuf[sizeof(REQSEP) + 1]; struct ecookie cookie; + int err; /* Initialisation du handle de la libcurl. */ - curl = curl_easy_init(); - if (!curl) - return (WRUNKNOWN); + sprintf(path, "/WH%d.CGI", wes->id); + if ((err = open_http_handle(wes, &curl, path))) + return (err); /* Initialisation du cookie. */ @@ -614,17 +594,6 @@ static int execscript(wes_t *wes, int num, wescgi_t *blocks) blocks[0].full = 1; /* NUL character */ } - /* Définition des méta-informations. */ - - ip = wes->addr.data.inet.ipv4; - sprintf(url, "http://%d.%d.%d.%d/WH%d.CGI", ip[0], ip[1], ip[2], ip[3], - wes->id); - - curl_easy_setopt(curl, CURLOPT_URL, url); - curl_easy_setopt(curl, CURLOPT_USERNAME, wes->http_name); - curl_easy_setopt(curl, CURLOPT_PASSWORD, wes->http_pass); - curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L); - /* Définition du fichier à envoyer. */ curl_easy_setopt(curl, CURLOPT_WRITEDATA, &cookie); @@ -633,7 +602,6 @@ static int execscript(wes_t *wes, int num, wescgi_t *blocks) /* Exécution de la requête. */ cres = curl_easy_perform(curl); - curl_easy_cleanup(curl); switch (cres) { case CURLE_OK: @@ -689,14 +657,21 @@ int get_cgi(wes_t *wes, int num, wescgi_t *blocks) /* `get_cgi_var()`: Récupération de valeurs par CGI. */ int get_cgi_var(wes_t *wes, const char *var, const char *format, - char *buffer, size_t len) + char *buffer, size_t *len) { wescgi_t cgi; + int err; cgi.var = var; cgi.format = format; cgi.buffer = buffer; - cgi.len = len; + cgi.len = *len; - return (get_cgi(wes, 1, &cgi)); + if ((err = get_cgi(wes, 1, &cgi))) + return (err); + + *len = cgi.full; + if (cgi.full > cgi.len) + return (WRSPACE); + return (WROK); } diff --git a/daemon/error.c b/daemon/error.c index 5581069..07eefbb 100644 --- a/daemon/error.c +++ b/daemon/error.c @@ -34,7 +34,8 @@ static const char *error_strings[] = { "une erreur inconnue s'est produite", "cette opération est interdite", "une allocation mémoire a échoué", - NULL, NULL, NULL, NULL, NULL, NULL, + "espace insuffisant pour stocker la réponse", + NULL, NULL, NULL, NULL, NULL, "le serveur n'a pas pu être atteint", "un élément n'a pas été trouvé", diff --git a/daemon/internals.h b/daemon/internals.h index 96d4652..1e1ab4f 100644 --- a/daemon/internals.h +++ b/daemon/internals.h @@ -45,6 +45,7 @@ # define WRUNKNOWN 1 /* Une erreur inconnue s'est produite. */ # define WROP 2 /* Cette opération est interdite. */ # define WRALLOC 3 /* Une allocation mémoire a échoué. */ +# define WRSPACE 4 /* Pas assez d'espace pour stocker quelque chose */ # define WRNOHOST 10 /* Le serveur n'a pas pu être atteint. */ # define WRNOTFOUND 11 /* Un élément n'a pas été trouvé. */ @@ -232,6 +233,11 @@ typedef struct wes { char *ftp_pass; char *ftp_data; + /* Canaux (handles de la libcurl) pour le HTTP et FTP. */ + + CURL *http_handle; + CURL *ftp_handle; + /* Éléments pour la gestion de la configuration. * Il s'agit d'une liste chaînée de sections. */ @@ -321,6 +327,11 @@ extern int set_ipv4(wes_t *wes, const unsigned char ip[4]); extern int set_http_ids(wes_t *wes, const char *name, const char *pass); extern int set_ftp_ids(wes_t *wes, const char *name, const char *pass); +/* Ouvrir les canaux HTTP et FTP sur lesquels on fait les requêtes. */ + +extern int open_http_handle(wes_t *wes, CURL **handlep, const char *path); +extern int open_ftp_handle(wes_t *wes, CURL **handlep, const char *path); + /* Récupérer et définir la valeur d'une option de configuration sur le * serveur WES. La « section » correspond au fichier dans le dossier `CFG/` * accessible sur le serveur FTP du serveur WES. */ @@ -348,7 +359,7 @@ extern int clear_data(wes_t *wes); extern int get_cgi(wes_t *wes, int num, wescgi_t *blocks); extern int get_cgi_var(wes_t *wes, const char *var, const char *format, - char *buffer, size_t len); + char *buffer, size_t *len); /* --- * Gestion de la liste. diff --git a/daemon/main.c b/daemon/main.c index 7023180..ced4f51 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -50,13 +50,13 @@ static int runtests(weslist_t *list) printf("Nom du WES: %s\n", wes->name); /* On récupète une variable via CGI. */ - +#if 1 { char value[200], value2[200], value3[3000]; wescgi_t blocks[] = { WESCGI("v v", "[%s]", value, 11), WESCGI("v K", "aa", value2, 200), - WESCGI("r o", NULL, value3, 200) + WESCGI("r o", NULL, value3, 2500) }; int i, count = sizeof(blocks) / sizeof(wescgi_t); @@ -68,9 +68,10 @@ static int runtests(weslist_t *list) i + 1, blocks[i].lines, blocks[i].full - 1, blocks[i].len - 1, blocks[i].buffer); } +#endif /* On récupère `RESEAU/ADIP` pour l'afficher. */ -#if 0 +#if 1 { char value[21]; diff --git a/daemon/wes.c b/daemon/wes.c index 0819804..4d59773 100644 --- a/daemon/wes.c +++ b/daemon/wes.c @@ -69,6 +69,8 @@ int init_wes(wes_t *wes) wes->name = ""; wes->http_data = NULL; wes->ftp_data = NULL; + wes->http_handle = NULL; + wes->ftp_handle = NULL; err = set_http_ids(wes, DEFAULT_HTTP_NAME, DEFAULT_HTTP_PASS); if (err) @@ -91,6 +93,11 @@ int deinit_wes(wes_t *wes) if (*wes->name) free(wes->name); + if (wes->http_handle) + curl_easy_cleanup(wes->http_handle); + if (wes->ftp_handle) + curl_easy_cleanup(wes->ftp_handle); + clear_config(wes); /* FIXME: clear_data(wes); */ free(wes->http_data); @@ -190,3 +197,85 @@ int set_ftp_ids(wes_t *wes, const char *name, const char *pass) return (0); } + +/* `open_http_handle()`: Ouverture d'un canal HTTP pour un chemin HTTP. + * Ce canal n'a point besoin d'être fermé. */ + +int open_http_handle(wes_t *wes, CURL **handlep, const char *path) +{ + CURL *handle; + const unsigned char *ip; + char url[50 + 200 + 1]; + + /* TODO: Faudrait gérer l'IPv6 aussi. */ + ip = wes->addr.data.inet.ipv4; + sprintf(url, "http://%d.%d.%d.%d%.200s", ip[0], ip[1], ip[2], ip[3], + path); + + if (wes->http_handle) + handle = wes->http_handle; + else { + handle = curl_easy_init(); + if (!handle) + return (WRUNKNOWN); + + wes->http_handle = handle; + } + + /* TODO: put in the path and else as components? */ + curl_easy_setopt(handle, CURLOPT_URL, url); + + curl_easy_setopt(handle, CURLOPT_USERNAME, wes->http_name); + curl_easy_setopt(handle, CURLOPT_PASSWORD, wes->http_pass); + curl_easy_setopt(handle, CURLOPT_UPLOAD, 0L); + curl_easy_setopt(handle, CURLOPT_VERBOSE, 0L); + curl_easy_setopt(handle, CURLOPT_QUOTE, NULL); + curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, NULL); + curl_easy_setopt(handle, CURLOPT_WRITEDATA, stdout); + curl_easy_setopt(handle, CURLOPT_READFUNCTION, NULL); + curl_easy_setopt(handle, CURLOPT_READDATA, stdin); + + *handlep = handle; + return (WROK); +} + +/* `open_ftp_handle()`: Ouverture d'un canal FTP pour un chemin FTP. + * Ce canal n'a point besoin d'être fermé. */ + +int open_ftp_handle(wes_t *wes, CURL **handlep, const char *path) +{ + CURL *handle; + const unsigned char *ip; + char url[50 + 200 + 1]; + + /* TODO: Faudrait gérer l'IPv6 aussi. */ + ip = wes->addr.data.inet.ipv4; + sprintf(url, "ftp://%d.%d.%d.%d%.200s", ip[0], ip[1], ip[2], ip[3], + path); + + if (wes->ftp_handle) + handle = wes->ftp_handle; + else { + handle = curl_easy_init(); + if (!handle) + return (WRUNKNOWN); + + wes->ftp_handle = handle; + } + + /* TODO: put in the path and else as components? */ + curl_easy_setopt(handle, CURLOPT_URL, url); + + curl_easy_setopt(handle, CURLOPT_USERNAME, wes->ftp_name); + curl_easy_setopt(handle, CURLOPT_PASSWORD, wes->ftp_pass); + curl_easy_setopt(handle, CURLOPT_UPLOAD, 0L); + curl_easy_setopt(handle, CURLOPT_VERBOSE, 0L); + curl_easy_setopt(handle, CURLOPT_QUOTE, NULL); + curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, stdout); + curl_easy_setopt(handle, CURLOPT_WRITEDATA, NULL); + curl_easy_setopt(handle, CURLOPT_READFUNCTION, stdin); + curl_easy_setopt(handle, CURLOPT_READDATA, NULL); + + *handlep = handle; + return (WROK); +} |