OpenVAS Scanner 22.7.9
nasl_http.c
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Greenbone AG
2 * SPDX-FileCopyrightText: 2002-2004 Tenable Network Security
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 */
6
7#include "nasl_http.h"
8
9#include "../misc/plugutils.h" /* plug_get_host_fqdn */
10#include "../misc/user_agent.h" /* for user_agent_get */
11#include "exec.h"
12#include "nasl_debug.h"
13#include "nasl_func.h"
14#include "nasl_global_ctxt.h"
15#include "nasl_lex_ctxt.h"
16#include "nasl_socket.h"
17#include "nasl_tree.h"
18#include "nasl_var.h"
19
20#include <ctype.h> /* for isspace */
21#include <glib.h>
22#include <gvm/base/prefs.h> /* for prefs_get */
23#include <gvm/util/kb.h> /* for kb_item_get_str */
24#include <string.h> /* for strlen */
25
26#undef G_LOG_DOMAIN
30#define G_LOG_DOMAIN "lib nasl"
31
32/*-----------------[ http_* functions ]-------------------------------*/
33
36{
37 return nasl_open_sock_tcp_bufsz (lexic, 65536);
38}
39
42{
43 return nasl_close_socket (lexic);
44}
45
46static char *
47build_encode_URL (char *method, char *path, char *name, char *httpver)
48{
49 char *ret, *ret2;
50
51 if (path == NULL)
52 ret = g_strdup (name);
53 else
54 ret = g_strdup_printf ("%s/%s", path, name);
55
56 g_debug ("Request => %s", ret);
57 ret2 = g_strdup_printf ("%s %s %s", method, ret, httpver);
58 g_free (ret);
59 return ret2;
60}
61
62static tree_cell *
63_http_req (lex_ctxt *lexic, char *keyword)
64{
65 tree_cell *retc;
66 char *request, *auth, tmp[32];
67 char *item = get_str_var_by_name (lexic, "item");
68 char *data = get_str_var_by_name (lexic, "data");
69 int port = get_int_var_by_name (lexic, "port", -1);
70 struct script_infos *script_infos = lexic->script_infos;
71 int ver;
72 kb_t kb;
73
74 if (item == NULL || port < 0)
75 {
76 nasl_perror (lexic,
77 "Error : http_* functions have the following syntax :\n");
78 nasl_perror (lexic, "http_*(port:<port>, item:<item> [, data:<data>]\n");
79 return NULL;
80 }
81
82 if (port <= 0 || port > 65535)
83 {
84 nasl_perror (lexic, "http_req: invalid value %d for port parameter\n",
85 port);
86 return NULL;
87 }
88
90
91 g_snprintf (tmp, sizeof (tmp), "http/%d", port);
92 ver = kb_item_get_int (kb, tmp);
93
94 if ((ver <= 0) || (ver == 11))
95 {
96 char *hostname, *ua, *hostheader, *url;
97
99 if (hostname == NULL)
100 return NULL;
101
102 ua = g_strdup (user_agent_get (lexic->script_infos->ipc_context));
103 /* Servers should not have a problem with port 80 or 443 appended.
104 * RFC2616 allows to omit the port in which case the default port for
105 * that service is assumed.
106 * However, some servers like IIS/OWA wrongly respond with a "404"
107 * instead of a "200" in case the port is appended. Because of this,
108 * ports 80 and 443 are not appended.
109 */
110 if (port == 80 || port == 443)
111 hostheader = g_strdup (hostname);
112 else
113 hostheader = g_strdup_printf ("%s:%d", hostname, port);
114
115 url = build_encode_URL (keyword, NULL, item, "HTTP/1.1");
116 request = g_strdup_printf ("%s\r\n\
117Connection: Close\r\n\
118Host: %s\r\n\
119Pragma: no-cache\r\n\
120Cache-Control: no-cache\r\n\
121User-Agent: %s\r\n\
122Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*\r\n\
123Accept-Language: en\r\n\
124Accept-Charset: iso-8859-1,*,utf-8\r\n",
125 url, hostheader, ua);
126 g_free (hostname);
127 g_free (hostheader);
128 g_free (ua);
129 g_free (url);
130 }
131 else
132 request = build_encode_URL (keyword, NULL, item, "HTTP/1.0\r\n");
133
134 g_snprintf (tmp, sizeof (tmp), "/tmp/http/auth/%d", port);
135 auth = kb_item_get_str (kb, tmp);
136 if (!auth)
137 auth = kb_item_get_str (kb, "http/auth");
138
139 if (auth)
140 {
141 char *authntmp = g_strconcat (request, auth, "\r\n", NULL);
142 g_free (request);
143 g_free (auth);
144 request = authntmp;
145 }
146 if (data)
147 {
148 char content_length[128], *data_tmp;
149
150 g_snprintf (content_length, sizeof (content_length),
151 "Content-Length: %zu\r\n\r\n", strlen (data));
152 data_tmp = g_strconcat (request, content_length, data, NULL);
153 g_free (request);
154 request = data_tmp;
155 }
156 else
157 {
158 char *no_data_tmp = g_strconcat (request, "\r\n", NULL);
159 g_free (request);
160 request = no_data_tmp;
161 }
162
164 retc->size = strlen (request);
165 retc->x.str_val = request;
166 return retc;
167}
168
169/*
170 * Syntax :
171 *
172 * http_get(port:<port>, item:<item>);
173 *
174 */
175tree_cell *
177{
178 return _http_req (lexic, "GET");
179}
180
181/*
182 * Syntax :
183 *
184 * http_head(port:<port>, item:<item>);
185 *
186 */
187tree_cell *
189{
190 return _http_req (lexic, "HEAD");
191}
192
193/*
194 * Syntax :
195 * http_post(port:<port>, item:<item>)
196 */
197tree_cell *
199{
200 return _http_req (lexic, "POST");
201}
202
203/*
204 * http_delete(port:<port>, item:<item>)
205 */
206tree_cell *
208{
209 return _http_req (lexic, "DELETE");
210}
211
212/*
213 * http_put(port:<port>, item:<item>, data:<data>)
214 */
215tree_cell *
217{
218 return _http_req (lexic, "PUT");
219}
220
221/*-------------------[ cgibin() ]--------------------------------*/
222
223tree_cell *
225{
226 const char *path = prefs_get ("cgi_path");
227 tree_cell *retc;
228
229 (void) lexic;
230 if (path == NULL)
231 path = "/cgi-bin:/scripts";
233 retc->x.str_val = g_strdup (path);
234 retc->size = strlen (path);
235
236 return retc;
237}
void nasl_perror(lex_ctxt *lexic, char *msg,...)
Definition: nasl_debug.c:111
tree_cell * http_close_socket(lex_ctxt *lexic)
Definition: nasl_http.c:41
tree_cell * http_head(lex_ctxt *lexic)
Definition: nasl_http.c:188
static tree_cell * _http_req(lex_ctxt *lexic, char *keyword)
Definition: nasl_http.c:63
tree_cell * http_put(lex_ctxt *lexic)
Definition: nasl_http.c:216
tree_cell * http_open_socket(lex_ctxt *lexic)
Definition: nasl_http.c:35
tree_cell * cgibin(lex_ctxt *lexic)
Definition: nasl_http.c:224
tree_cell * http_get(lex_ctxt *lexic)
Definition: nasl_http.c:176
tree_cell * http_delete(lex_ctxt *lexic)
Definition: nasl_http.c:207
static char * build_encode_URL(char *method, char *path, char *name, char *httpver)
Definition: nasl_http.c:47
tree_cell * http_post(lex_ctxt *lexic)
Definition: nasl_http.c:198
const char * name
Definition: nasl_init.c:411
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:1104
tree_cell * nasl_open_sock_tcp_bufsz(lex_ctxt *lexic, int bufsz)
Definition: nasl_socket.c:409
tree_cell * nasl_close_socket(lex_ctxt *lexic)
Definition: nasl_socket.c:1012
tree_cell * alloc_typed_cell(int typ)
Definition: nasl_tree.c:28
@ CONST_DATA
Definition: nasl_tree.h:82
const char * hostname
Definition: pluginlaunch.c:68
char * plug_get_host_fqdn(struct script_infos *args)
Definition: plugutils.c:242
kb_t plug_get_kb(struct script_infos *args)
Definition: plugutils.c:1055
Definition: nasl_tree.h:94
union TC::@5 x
int size
Definition: nasl_tree.h:99
char * str_val
Definition: nasl_tree.h:103
struct ipc_context * ipc_context
Definition: scanneraux.h:31
struct script_infos * script_infos
Definition: nasl_lex_ctxt.h:30
const gchar * user_agent_get(struct ipc_context *ipc_context)
Get user-agent.
Definition: user_agent.c:106