OpenVAS Scanner 23.40.3
nasl_http2.c File Reference
#include "nasl_http2.h"
#include "../misc/plugutils.h"
#include "../misc/user_agent.h"
#include "exec.h"
#include "nasl_debug.h"
#include "nasl_func.h"
#include "nasl_global_ctxt.h"
#include "nasl_lex_ctxt.h"
#include "nasl_socket.h"
#include "nasl_tree.h"
#include "nasl_var.h"
#include <ctype.h>
#include <curl/curl.h>
#include <gnutls/gnutls.h>
#include <gvm/base/prefs.h>
#include <gvm/util/kb.h>
#include <string.h>
Include dependency graph for nasl_http2.c:

Go to the source code of this file.

Data Structures

struct  handle_table_s
 Struct to store handles. More...
struct  string
 Define a string struct for storing the response. More...

Macros

#define G_LOG_DOMAIN   "lib nasl"
 GLib log domain.
#define MAX_HANDLES   10

Typedefs

typedef enum KEYWORD_E KEYWORD
 Allowed methods.

Enumerations

enum  KEYWORD_E {
  POST , GET , PUT , DELETE ,
  HEAD
}
 Allowed methods. More...

Functions

static int next_handle_id (void)
 Get the new available handle identifier.
tree_cellnasl_http2_handle (lex_ctxt *lexic)
 Creates a handle for http requests.
tree_cellnasl_http2_close_handle (lex_ctxt *lexic)
 Close a handle for http requests previously initialized.
static void init_string (struct string *s)
 Initialize the string struct to hold the response or header.
static size_t response_callback_fn (void *ptr, size_t size, size_t nmemb, void *struct_string)
 Call back function to stored the response.
static size_t header_callback_fn (char *buffer, size_t size, size_t nmemb, void *struct_string)
 Call back function to stored the header.
static tree_cell_http2_req (lex_ctxt *lexic, KEYWORD keyword)
 Perform an HTTP request. Forcing HTTP2 if possible.
tree_cellnasl_http2_get_response_code (lex_ctxt *lexic)
 Get the http response code after performing a HTTP request.
tree_cellnasl_http2_set_custom_header (lex_ctxt *lexic)
 Set a custom header element in the header.
tree_cellnasl_http2_get (lex_ctxt *lexic)
 Wrapper function for GET request. See _http2_req.
tree_cellnasl_http2_head (lex_ctxt *lexic)
 Wrapper function for HEAD request. See _http2_req.
tree_cellnasl_http2_post (lex_ctxt *lexic)
 Wrapper function for POST request. See _http2_req.
tree_cellnasl_http2_delete (lex_ctxt *lexic)
 Wrapper function for DELETE request. See _http2_req.
tree_cellnasl_http2_put (lex_ctxt *lexic)
 Wrapper function for PUT request. See _http2_req.

Variables

static struct handle_table_shandle_table [MAX_HANDLES]
 Handle Table.

Macro Definition Documentation

◆ G_LOG_DOMAIN

#define G_LOG_DOMAIN   "lib nasl"

GLib log domain.

Definition at line 31 of file nasl_http2.c.

◆ MAX_HANDLES

#define MAX_HANDLES   10

Typedef Documentation

◆ KEYWORD

typedef enum KEYWORD_E KEYWORD

Allowed methods.

Enumeration Type Documentation

◆ KEYWORD_E

enum KEYWORD_E

Allowed methods.

Enumerator
POST 
GET 
PUT 
DELETE 
HEAD 

Definition at line 37 of file nasl_http2.c.

38{
39 POST,
40 GET,
41 PUT,
42 DELETE,
43 HEAD,
44} KEYWORD;
enum KEYWORD_E KEYWORD
Allowed methods.
@ HEAD
Definition nasl_http2.c:43
@ GET
Definition nasl_http2.c:40
@ POST
Definition nasl_http2.c:39
@ DELETE
Definition nasl_http2.c:42
@ PUT
Definition nasl_http2.c:41

Function Documentation

◆ _http2_req()

tree_cell * _http2_req ( lex_ctxt * lexic,
KEYWORD keyword )
static

Perform an HTTP request. Forcing HTTP2 if possible.

NASL Named Parameters:\n
  • handle The handle identifier
  • port The port to use for the connection
  • item The path
  • schema Optional URL schema to be used. http or https. Default to https.
  • data Optional data to be sent with POST or PUT
NASL Returns:\n http header followed by the response from the server. Null on error.
Parameters
[in]lexicLexical context of NASL interpreter.
Returns
On success the function returns a tree-cell with the http header followed by the response from the server. Null on error.

Definition at line 252 of file nasl_http2.c.

253{
254 tree_cell *retc;
255 char *item = get_str_var_by_name (lexic, "item");
256 char *data = get_str_var_by_name (lexic, "data");
257 int port = get_int_var_by_name (lexic, "port", -1);
258 char *schema = get_str_var_by_name (lexic, "schema");
259 struct script_infos *script_infos = lexic->script_infos;
260 char *hostname;
261 GString *url = NULL;
262 CURL *handle = NULL;
263 int handle_id = get_int_var_by_name (lexic, "handle", -1);
264 struct string response, header_data;
265
266 if (item == NULL || port < 0 || handle_id < 0)
267 {
268 nasl_perror (lexic,
269 "Error : http2_* functions have the following syntax :\n");
270 nasl_perror (lexic, "http_*(handle: <handle>, port:<port>, item:<item> "
271 "[,schema:<schema>][, data:<data>]\n");
272 return NULL;
273 }
274
275 unsigned int table_slot;
276 for (table_slot = 0; table_slot < MAX_HANDLES; table_slot++)
277 {
278 if (handle_table[table_slot]->handle_id == handle_id)
279 break;
280 else
281 {
282 g_message ("%s: Unknown handle identifier %d", __func__, handle_id);
283 return NULL;
284 }
285 }
286
287 handle = handle_table[table_slot]->handle;
288
289 if (port <= 0 || port > 65535)
290 {
291 nasl_perror (lexic, "http2_req: invalid value %d for port parameter\n",
292 port);
293 return NULL;
294 }
295
296 // Fork here for every vhost
298 if (hostname == NULL)
299 return NULL;
300
301 curl_easy_reset (handle);
302
303 // force http2
304 curl_easy_setopt (handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
305
306 // Build URL
307 url = schema ? g_string_new (schema) : g_string_new ("https");
308 g_string_append (url, "://");
309 g_string_append (url, hostname);
310
311 /* Servers should not have a problem with port 80 or 443 appended.
312 * RFC2616 allows to omit the port in which case the default port for
313 * that service is assumed.
314 * However, some servers like IIS/OWA wrongly respond with a "404"
315 * instead of a "200" in case the port is appended. Because of this,
316 * ports 80 and 443 are not appended.
317 */
318 if (port != 80 && port != 443)
319 {
320 char buf[12];
321 snprintf (buf, sizeof (buf), ":%d", port);
322 g_string_append (url, buf);
323 }
324 g_string_append (url, item);
325
326 g_message ("%s: URL: %s", __func__, url->str);
327 // Set URL
328 if (curl_easy_setopt (handle, CURLOPT_URL, url->str) != CURLE_OK)
329 {
330 g_warning ("Not possible to set the URL");
331 curl_easy_cleanup (handle);
332 return NULL;
333 }
334 g_string_free (url, TRUE);
335
336 // Accept an insecure connection. Don't verify the server certificate
337 curl_easy_setopt (handle, CURLOPT_SSL_VERIFYPEER, 0L);
338 curl_easy_setopt (handle, CURLOPT_SSL_VERIFYHOST, 0L);
339
340 // Set User Agent
341 char *ua = NULL;
342 if ((user_agent_get (lexic->script_infos->ipc_context, &ua) == -2)
344 {
345 g_message ("Not possible to send the User Agent to the host process. "
346 "Invalid IPC context");
347 }
348 if (ua)
349 {
350 curl_easy_setopt (handle, CURLOPT_USERAGENT, g_strdup (url->str));
351 g_free (ua);
352 }
353
354 // Init the struct where the response is stored and set the callback function
355 init_string (&response);
356 curl_easy_setopt (handle, CURLOPT_WRITEFUNCTION, response_callback_fn);
357 curl_easy_setopt (handle, CURLOPT_WRITEDATA, &response);
358
359 init_string (&header_data);
360 curl_easy_setopt (handle, CURLOPT_HEADERFUNCTION, header_callback_fn);
361 curl_easy_setopt (handle, CURLOPT_HEADERDATA, &header_data);
362
363 switch (keyword)
364 {
365 case DELETE:
366 curl_easy_setopt (handle, CURLOPT_CUSTOMREQUEST, "DELETE");
367 break;
368 case HEAD:
369 curl_easy_setopt (handle, CURLOPT_NOBODY, 1L);
370 break;
371 case PUT:
372 curl_easy_setopt (handle, CURLOPT_CUSTOMREQUEST, "PUT");
373 if (data)
374 {
375 curl_easy_setopt (handle, CURLOPT_POSTFIELDS, data);
376 curl_easy_setopt (handle, CURLOPT_POSTFIELDSIZE, strlen (data));
377 }
378 break;
379 case GET:
380 curl_easy_setopt (handle, CURLOPT_HTTPGET, 1L);
381 break;
382 case POST:
383 // Set body. POST is set automatically with this options
384 if (data)
385 {
386 curl_easy_setopt (handle, CURLOPT_POSTFIELDS, data);
387 curl_easy_setopt (handle, CURLOPT_POSTFIELDSIZE, strlen (data));
388 }
389 break;
390 default:
391 g_message ("%s: Invalid http method.", __func__);
392 break;
393 }
394
395 int ret = CURLE_OK;
396 if ((ret = curl_easy_perform (handle)) != CURLE_OK)
397 {
398 g_warning ("%s: Error sending request: %d", __func__, ret);
399 curl_easy_cleanup (handle);
400 g_free (response.ptr);
401 return NULL;
402 }
403
404 GString *complete_resp = g_string_new (header_data.ptr);
405 g_string_append (complete_resp, "\n");
406 g_string_append (complete_resp, response.ptr);
407 g_free (response.ptr);
408 g_free (header_data.ptr);
409
410 long http_code = -1;
411 curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &http_code);
412 handle_table[table_slot]->http_code = http_code;
413
415 retc->size = complete_resp->len;
416 retc->x.str_val = g_strdup (complete_resp->str);
417
418 g_string_free (complete_resp, TRUE);
419 return retc;
420}
void nasl_perror(lex_ctxt *lexic, char *msg,...)
Definition nasl_debug.c:105
#define MAX_HANDLES
Definition nasl_http2.c:55
static struct handle_table_s * handle_table[MAX_HANDLES]
Handle Table.
Definition nasl_http2.c:59
static size_t header_callback_fn(char *buffer, size_t size, size_t nmemb, void *struct_string)
Call back function to stored the header.
Definition nasl_http2.c:211
static void init_string(struct string *s)
Initialize the string struct to hold the response or header.
Definition nasl_http2.c:169
char * get_str_var_by_name(lex_ctxt *, const char *)
Definition nasl_var.c:1118
long int get_int_var_by_name(lex_ctxt *, const char *, int)
Definition nasl_var.c:1101
tree_cell * alloc_typed_cell(int typ)
Definition nasl_tree.c:25
@ CONST_DATA
Definition nasl_tree.h:82
struct TC tree_cell
const char * hostname
char * plug_get_host_fqdn(struct script_infos *args)
Definition plugutils.c:291
long int size
Definition nasl_tree.h:99
union TC::@332262321161220155002104006201360276211317150140 x
char * str_val
Definition nasl_tree.h:103
struct ipc_context * ipc_context
Definition scanneraux.h:31
Define a string struct for storing the response.
struct script_infos * script_infos
static size_t response_callback_fn(void *ptr, size_t size, size_t nmemb, void *struct_string)
Call back function to stored the response.
int user_agent_get(struct ipc_context *ipc_context, char **useragent)
Get user-agent.
Definition user_agent.c:114

References alloc_typed_cell(), CONST_DATA, DELETE, GET, get_int_var_by_name(), get_str_var_by_name(), handle_table, HEAD, header_callback_fn(), hostname, init_string(), script_infos::ipc_context, MAX_HANDLES, nasl_perror(), plug_get_host_fqdn(), POST, string::ptr, PUT, response_callback_fn(), struct_lex_ctxt::script_infos, TC::size, script_infos::standalone, TC::str_val, user_agent_get(), and TC::x.

Referenced by nasl_http2_delete(), nasl_http2_get(), nasl_http2_head(), nasl_http2_post(), and nasl_http2_put().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ header_callback_fn()

size_t header_callback_fn ( char * buffer,
size_t size,
size_t nmemb,
void * struct_string )
static

Call back function to stored the header.

@description The function signature is the necessary to work with libcurl. It stores the header in s. It reallocate memory if necessary.

Definition at line 211 of file nasl_http2.c.

213{
214 struct string *s = struct_string;
215 size_t new_len = s->len + size * nmemb;
216 char *ptr_aux = g_realloc (s->ptr, new_len + 1);
217 s->ptr = ptr_aux;
218 if (s->ptr == NULL)
219 {
220 g_warning ("%s: Error allocating memory for response", __func__);
221 return 0; // no memory left
222 }
223 memcpy (s->ptr + s->len, buffer, size * nmemb);
224 s->ptr[new_len] = '\0';
225 s->len = new_len;
226
227 return size * nmemb;
228}

References string::len, and string::ptr.

Referenced by _http2_req().

Here is the caller graph for this function:

◆ init_string()

void init_string ( struct string * s)
static

Initialize the string struct to hold the response or header.

Parameters
s[in/out]The string struct to be initialized

Definition at line 169 of file nasl_http2.c.

170{
171 s->len = 0;
172 s->ptr = g_malloc0 (s->len + 1);
173 if (s->ptr == NULL)
174 {
175 g_warning ("%s: Error allocating memory for response", __func__);
176 return;
177 }
178 s->ptr[0] = '\0';
179}

References string::len, and string::ptr.

Referenced by _http2_req().

Here is the caller graph for this function:

◆ nasl_http2_close_handle()

tree_cell * nasl_http2_close_handle ( lex_ctxt * lexic)

Close a handle for http requests previously initialized.

NASL Function: http2_handle\n
NASL Named Parameters:\n
  • handle The handle identifier for the handle to be closed
NASL Returns:\n O on success, -1 on error
Parameters
[in]lexicLexical context of NASL interpreter.
Returns
The function returns a tree-cell with a integer. O on success, -1 on error.

Definition at line 129 of file nasl_http2.c.

130{
131 tree_cell *retc = NULL;
132 int handle_id = get_int_var_by_num (lexic, 0, -1);
133 unsigned int table_slot;
134 int ret = 0;
135
136 for (table_slot = 0; table_slot < MAX_HANDLES; table_slot++)
137 {
138 if (handle_table[table_slot]->handle_id == handle_id)
139 {
140 curl_easy_cleanup (handle_table[table_slot]->handle);
141 handle_table[table_slot]->handle = NULL;
142 handle_table[table_slot]->handle_id = 0;
143 handle_table[table_slot] = NULL;
144 }
145 else
146 {
147 g_message ("%s: Unknown handle identifier %d", __func__, handle_id);
148 ret = -1;
149 }
150 }
152 retc->x.i_val = ret;
153 return retc;
154}
long int get_int_var_by_num(lex_ctxt *, int, int)
Definition nasl_var.c:1094
@ CONST_INT
Definition nasl_tree.h:79
long int i_val
Definition nasl_tree.h:104

References alloc_typed_cell(), CONST_INT, get_int_var_by_num(), handle_table_s::handle, handle_table_s::handle_id, handle_table, TC::i_val, MAX_HANDLES, and TC::x.

Here is the call graph for this function:

◆ nasl_http2_delete()

tree_cell * nasl_http2_delete ( lex_ctxt * lexic)

Wrapper function for DELETE request. See _http2_req.

Definition at line 549 of file nasl_http2.c.

550{
551 return _http2_req (lexic, DELETE);
552}
static tree_cell * _http2_req(lex_ctxt *lexic, KEYWORD keyword)
Perform an HTTP request. Forcing HTTP2 if possible.
Definition nasl_http2.c:252

References _http2_req(), and DELETE.

Here is the call graph for this function:

◆ nasl_http2_get()

tree_cell * nasl_http2_get ( lex_ctxt * lexic)

Wrapper function for GET request. See _http2_req.

Definition at line 525 of file nasl_http2.c.

526{
527 return _http2_req (lexic, GET);
528}

References _http2_req(), and GET.

Here is the call graph for this function:

◆ nasl_http2_get_response_code()

tree_cell * nasl_http2_get_response_code ( lex_ctxt * lexic)

Get the http response code after performing a HTTP request.

NASL Named Parameters:\n
  • handle The handle identifier
NASL Returns:\n http code or 0 if not set. NULL on error
Parameters
[in]lexicLexical context of NASL interpreter.
Returns
On success the function returns a tree-cell with and integer representing the http code response. Null on error.

Definition at line 436 of file nasl_http2.c.

437{
438 tree_cell *retc = NULL;
439 unsigned int table_slot;
440 int handle_id = get_int_var_by_name (lexic, "handle", -1);
441
442 if (handle_id < 0)
443 {
444 nasl_perror (lexic,
445 "Error : http2_* functions have the following syntax :\n");
446 nasl_perror (lexic, "http_*(handle: <handle>\n");
447 return NULL;
448 }
449
450 for (table_slot = 0; table_slot < MAX_HANDLES; table_slot++)
451 {
452 if (handle_table[table_slot]->handle_id == handle_id)
453 break;
454 else
455 {
456 g_message ("%s: Unknown handle identifier %d", __func__, handle_id);
457 return NULL;
458 }
459 }
460
462 retc->x.i_val = handle_table[table_slot]->http_code;
463 return retc;
464}

References alloc_typed_cell(), CONST_INT, get_int_var_by_name(), handle_table, TC::i_val, MAX_HANDLES, nasl_perror(), and TC::x.

Here is the call graph for this function:

◆ nasl_http2_handle()

tree_cell * nasl_http2_handle ( lex_ctxt * lexic)

Creates a handle for http requests.

NASL Function: http2_handle\n
NASL Returns:\n Handle identifier. Null on error.
Parameters
[in]lexicLexical context of NASL interpreter.
Returns
On success the function returns a tree-cell with the handle identifier. Null on error.

Definition at line 84 of file nasl_http2.c.

85{
86 (void) lexic;
87 tree_cell *retc = NULL;
88 CURL *handle = curl_easy_init ();
89 unsigned int table_slot;
90
91 if (!handle)
92 return NULL;
93
94 for (table_slot = 0; table_slot < MAX_HANDLES; table_slot++)
95 if (!handle_table[table_slot] || !handle_table[table_slot]->handle_id)
96 break;
97
98 if (!(table_slot < MAX_HANDLES))
99 {
100 g_message ("%s: No space left in HTTP2 handle table", __func__);
101 curl_easy_cleanup (handle);
102 return NULL;
103 }
104
105 handle_table[table_slot] = g_malloc0 (sizeof (struct handle_table_s));
106 handle_table[table_slot]->handle = handle;
107 handle_table[table_slot]->handle_id = next_handle_id ();
108
110 retc->x.i_val = handle_table[table_slot]->handle_id;
111 return retc;
112}
static int next_handle_id(void)
Get the new available handle identifier.
Definition nasl_http2.c:64
Struct to store handles.
Definition nasl_http2.c:49

References alloc_typed_cell(), CONST_INT, handle_table_s::handle, handle_table_s::handle_id, handle_table, TC::i_val, MAX_HANDLES, next_handle_id(), and TC::x.

Here is the call graph for this function:

◆ nasl_http2_head()

tree_cell * nasl_http2_head ( lex_ctxt * lexic)

Wrapper function for HEAD request. See _http2_req.

Definition at line 533 of file nasl_http2.c.

534{
535 return _http2_req (lexic, HEAD);
536}

References _http2_req(), and HEAD.

Here is the call graph for this function:

◆ nasl_http2_post()

tree_cell * nasl_http2_post ( lex_ctxt * lexic)

Wrapper function for POST request. See _http2_req.

Definition at line 541 of file nasl_http2.c.

542{
543 return _http2_req (lexic, POST);
544}

References _http2_req(), and POST.

Here is the call graph for this function:

◆ nasl_http2_put()

tree_cell * nasl_http2_put ( lex_ctxt * lexic)

Wrapper function for PUT request. See _http2_req.

Definition at line 557 of file nasl_http2.c.

558{
559 return _http2_req (lexic, PUT);
560}

References _http2_req(), and PUT.

Here is the call graph for this function:

◆ nasl_http2_set_custom_header()

tree_cell * nasl_http2_set_custom_header ( lex_ctxt * lexic)

Set a custom header element in the header.

NASL Named Parameters:\n
  • handle The handle identifier
  • header_item A string to add to the header
NASL Returns:\n 0 on success. NULL on error
Parameters
[in]lexicLexical context of NASL interpreter.
Returns
On success the function returns a tree-cell integer 0 on success. Null on error.

Definition at line 482 of file nasl_http2.c.

483{
484 tree_cell *retc = NULL;
485 struct curl_slist *customheader = NULL;
486 unsigned int table_slot;
487 CURL *handle;
488 int handle_id = get_int_var_by_name (lexic, "handle", -1);
489 char *headeritem = get_str_var_by_name (lexic, "header_item");
490
491 if (handle_id < 0 || headeritem == NULL)
492 {
493 nasl_perror (lexic,
494 "Error : http2_* functions have the following syntax :\n");
495 nasl_perror (lexic,
496 "http_*(handle: <handle>, header_item:<header_item>\n");
497 return NULL;
498 }
499
500 for (table_slot = 0; table_slot < MAX_HANDLES; table_slot++)
501 {
502 if (handle_table[table_slot]->handle_id == handle_id)
503 break;
504 else
505 {
506 g_message ("%s: Unknown handle identifier %d", __func__, handle_id);
507 return NULL;
508 }
509 }
510 handle = handle_table[table_slot]->handle;
511
512 // SET Content type
513 customheader = curl_slist_append (customheader, headeritem);
514 curl_easy_setopt (handle, CURLOPT_HTTPHEADER, customheader);
515
517 retc->x.i_val = 0;
518
519 return retc;
520}

References alloc_typed_cell(), CONST_INT, get_int_var_by_name(), get_str_var_by_name(), handle_table, TC::i_val, MAX_HANDLES, nasl_perror(), and TC::x.

Here is the call graph for this function:

◆ next_handle_id()

int next_handle_id ( void )
static

Get the new available handle identifier.

Definition at line 64 of file nasl_http2.c.

65{
66 static int last = 9000;
67 last++;
68
69 return last;
70}

Referenced by nasl_http2_handle().

Here is the caller graph for this function:

◆ response_callback_fn()

size_t response_callback_fn ( void * ptr,
size_t size,
size_t nmemb,
void * struct_string )
static

Call back function to stored the response.

@description The function signature is the necessary to work with libcurl. It stores the response in s. It reallocate memory if necessary.

Definition at line 187 of file nasl_http2.c.

188{
189 struct string *s = struct_string;
190 size_t new_len = s->len + size * nmemb;
191 char *ptr_aux = g_realloc (s->ptr, new_len + 1);
192 s->ptr = ptr_aux;
193 if (s->ptr == NULL)
194 {
195 g_warning ("%s: Error allocating memory for response", __func__);
196 return 0; // no memory left
197 }
198 memcpy (s->ptr + s->len, ptr, size * nmemb);
199 s->ptr[new_len] = '\0';
200 s->len = new_len;
201
202 return size * nmemb;
203}

References string::len, and string::ptr.

Variable Documentation

◆ handle_table

struct handle_table_s* handle_table[MAX_HANDLES]
static