1 /* Copyright (C) 2018-2021 Greenbone Networks GmbH 2 * 3 * SPDX-License-Identifier: AGPL-3.0-or-later 4 * 5 * This program is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU Affero General Public License as 7 * published by the Free Software Foundation, either version 3 of the 8 * License, or (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU Affero General Public License for more details. 14 * 15 * You should have received a copy of the GNU Affero General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 #ifndef _GVMD_GMP_BASE_H 20 #define _GVMD_GMP_BASE_H 21 22 #include <glib.h> 23 24 /** 25 * @brief A handle on a GMP parser. 26 */ 27 typedef struct 28 { 29 int (*client_writer) (const char *, void *); ///< Writes to the client. 30 void *client_writer_data; ///< Argument to client_writer. 31 int importing; ///< Whether the current op is importing. 32 int read_over; ///< Read over any child elements. 33 int parent_state; ///< Parent state when reading over. 34 gchar **disabled_commands; ///< Disabled commands. 35 } gmp_parser_t; 36 37 int 38 find_attribute (const gchar **, const gchar **, const char *, const gchar **); 39 40 int 41 append_attribute (const gchar **, const gchar **, const char *, gchar **); 42 43 void 44 buffer_xml_append_printf (GString *, const char *, ...); 45 46 gboolean 47 send_to_client (const char *, int (*) (const char *, void *), void *); 48 49 gboolean 50 send_find_error_to_client (const char *, const char *, const char *, 51 gmp_parser_t *); 52 53 void 54 error_send_to_client (GError **); 55 56 void 57 internal_error_send_to_client (GError **); 58 59 /** 60 * @brief Send response message to client and return a given value on error. 61 * 62 * Queue a message in \ref to_client with \ref send_to_client. On failure 63 * call \ref error_send_to_client on a GError* called "error" and do a return. 64 * 65 * @param[in] err_ret Return value on send error. 66 * @param[in] format Format string for message. 67 * @param[in] args Arguments for format string. 68 */ 69 #define SENDF_TO_CLIENT_OR_FAIL_WITH_RETURN(err_ret, format, args...) \ 70 do \ 71 { \ 72 gchar *msg = g_markup_printf_escaped (format, ##args); \ 73 if (send_to_client (msg, gmp_parser->client_writer, \ 74 gmp_parser->client_writer_data)) \ 75 { \ 76 g_free (msg); \ 77 error_send_to_client (error); \ 78 return err_ret; \ 79 } \ 80 g_free (msg); \ 81 } \ 82 while (0) 83 84 /** 85 * @brief Send response message to client, returning on fail. 86 * 87 * Queue a message in \ref to_client with \ref send_to_client. On failure 88 * call \ref error_send_to_client on a GError* called "error" and do a return. 89 * 90 * @param[in] format Format string for message. 91 * @param[in] args Arguments for format string. 92 */ 93 #define SENDF_TO_CLIENT_OR_FAIL(format, args...) \ 94 do \ 95 { \ 96 gchar *msg = g_markup_printf_escaped (format, ##args); \ 97 if (send_to_client (msg, gmp_parser->client_writer, \ 98 gmp_parser->client_writer_data)) \ 99 { \ 100 g_free (msg); \ 101 error_send_to_client (error); \ 102 return; \ 103 } \ 104 g_free (msg); \ 105 } \ 106 while (0) 107 108 /** 109 * @brief Send response message to client, returning on fail. 110 * 111 * Queue a message in \ref to_client with \ref send_to_client. On failure 112 * call \ref error_send_to_client on a GError* called "error" and do a return. 113 * 114 * @param[in] msg The message, a string. 115 */ 116 #define SEND_TO_CLIENT_OR_FAIL(msg) \ 117 do \ 118 { \ 119 if (send_to_client (msg, gmp_parser->client_writer, \ 120 gmp_parser->client_writer_data)) \ 121 { \ 122 error_send_to_client (error); \ 123 return; \ 124 } \ 125 } \ 126 while (0) 127 128 void 129 log_event (const char *, const char *, const char *, const char *) 130 __attribute__ ((weak)); 131 132 void 133 log_event_fail (const char *, const char *, const char *, const char *); 134 135 /* Status codes. */ 136 137 /* HTTP status codes used: 138 * 139 * 200 OK 140 * 201 Created 141 * 202 Accepted 142 * 400 Bad request 143 * 401 Must auth 144 * 404 Missing 145 */ 146 147 /** 148 * @brief Response code for a syntax error. 149 */ 150 #define STATUS_ERROR_SYNTAX "400" 151 152 /** 153 * @brief Response code when authorisation is required. 154 */ 155 #define STATUS_ERROR_MUST_AUTH "401" 156 157 /** 158 * @brief Response code when authorisation is required. 159 */ 160 #define STATUS_ERROR_MUST_AUTH_TEXT "Authenticate first" 161 162 /** 163 * @brief Response code for forbidden access. 164 */ 165 #define STATUS_ERROR_ACCESS "403" 166 167 /** 168 * @brief Response code text for forbidden access. 169 */ 170 #define STATUS_ERROR_ACCESS_TEXT "Access to resource forbidden" 171 172 /** 173 * @brief Response code for a missing resource. 174 */ 175 #define STATUS_ERROR_MISSING "404" 176 177 /** 178 * @brief Response code text for a missing resource. 179 */ 180 #define STATUS_ERROR_MISSING_TEXT "Resource missing" 181 182 /** 183 * @brief Response code for a busy resource. 184 */ 185 #define STATUS_ERROR_BUSY "409" 186 187 /** 188 * @brief Response code text for a busy resource. 189 */ 190 #define STATUS_ERROR_BUSY_TEXT "Resource busy" 191 192 /** 193 * @brief Response code when authorisation failed. 194 */ 195 #define STATUS_ERROR_AUTH_FAILED "400" 196 197 /** 198 * @brief Response code text when authorisation failed. 199 */ 200 #define STATUS_ERROR_AUTH_FAILED_TEXT "Authentication failed" 201 202 /** 203 * @brief Response code on success. 204 */ 205 #define STATUS_OK "200" 206 207 /** 208 * @brief Response code text on success. 209 */ 210 #define STATUS_OK_TEXT "OK" 211 212 /** 213 * @brief Response code on success, when a resource is created. 214 */ 215 #define STATUS_OK_CREATED "201" 216 217 /** 218 * @brief Response code on success, when a resource is created. 219 */ 220 #define STATUS_OK_CREATED_TEXT "OK, resource created" 221 222 /** 223 * @brief Response code on success, when the operation will finish later. 224 */ 225 #define STATUS_OK_REQUESTED "202" 226 227 /** 228 * @brief Response code text on success, when the operation will finish later. 229 */ 230 #define STATUS_OK_REQUESTED_TEXT "OK, request submitted" 231 232 /** 233 * @brief Response code for an internal error. 234 */ 235 #define STATUS_INTERNAL_ERROR "500" 236 237 /** 238 * @brief Response code text for an internal error. 239 */ 240 #define STATUS_INTERNAL_ERROR_TEXT "Internal error" 241 242 /** 243 * @brief Response code when a service is unavailable. 244 */ 245 #define STATUS_SERVICE_UNAVAILABLE "503" 246 247 /** 248 * @brief Response code when a service is down. 249 */ 250 #define STATUS_SERVICE_DOWN "503" 251 252 /** 253 * @brief Response code text when a service is down. 254 */ 255 #define STATUS_SERVICE_DOWN_TEXT "Service temporarily down" 256 257 /** 258 * @brief Expand to XML for a STATUS_ERROR_SYNTAX response. 259 * 260 * @param tag Name of the command generating the response. 261 * @param text Text for the status_text attribute of the response. 262 */ 263 #define XML_ERROR_SYNTAX(tag, text) \ 264 "<" tag "_response" \ 265 " status=\"" STATUS_ERROR_SYNTAX "\"" \ 266 " status_text=\"" text "\"/>" 267 268 /** 269 * @brief Expand to XML for a STATUS_ERROR_ACCESS response. 270 * 271 * @param tag Name of the command generating the response. 272 */ 273 #define XML_ERROR_ACCESS(tag) \ 274 "<" tag "_response" \ 275 " status=\"" STATUS_ERROR_ACCESS "\"" \ 276 " status_text=\"" STATUS_ERROR_ACCESS_TEXT "\"/>" 277 278 /** 279 * @brief Expand to XML for a STATUS_SERVICE_UNAVAILABLE response. 280 * 281 * @param tag Name of the command generating the response. 282 * @param text Status text. 283 */ 284 #define XML_ERROR_UNAVAILABLE(tag, text) \ 285 "<" tag "_response" \ 286 " status=\"" STATUS_SERVICE_UNAVAILABLE "\"" \ 287 " status_text=\"" text "\"/>" 288 289 /** 290 * @brief Expand to XML for a STATUS_ERROR_MISSING response. 291 * 292 * @param tag Name of the command generating the response. 293 */ 294 #define XML_ERROR_MISSING(tag) \ 295 "<" tag "_response" \ 296 " status=\"" STATUS_ERROR_MISSING "\"" \ 297 " status_text=\"" STATUS_ERROR_MISSING_TEXT "\"/>" 298 299 /** 300 * @brief Expand to XML for a STATUS_ERROR_AUTH_FAILED response. 301 * 302 * @param tag Name of the command generating the response. 303 */ 304 #define XML_ERROR_AUTH_FAILED(tag) \ 305 "<" tag "_response" \ 306 " status=\"" STATUS_ERROR_AUTH_FAILED "\"" \ 307 " status_text=\"" STATUS_ERROR_AUTH_FAILED_TEXT "\"/>" 308 309 /** 310 * @brief Expand to XML for a STATUS_ERROR_BUSY response. 311 * 312 * @param tag Name of the command generating the response. 313 */ 314 #define XML_ERROR_BUSY(tag) \ 315 "<" tag "_response" \ 316 " status=\"" STATUS_ERROR_BUSY "\"" \ 317 " status_text=\"" STATUS_ERROR_BUSY_TEXT "\"/>" 318 319 /** 320 * @brief Expand to XML for a STATUS_OK response. 321 * 322 * @param tag Name of the command generating the response. 323 */ 324 #define XML_OK(tag) \ 325 "<" tag "_response" \ 326 " status=\"" STATUS_OK "\"" \ 327 " status_text=\"" STATUS_OK_TEXT "\"/>" 328 329 /** 330 * @brief Expand to XML for a STATUS_OK_CREATED response. 331 * 332 * @param tag Name of the command generating the response. 333 */ 334 #define XML_OK_CREATED(tag) \ 335 "<" tag "_response" \ 336 " status=\"" STATUS_OK_CREATED "\"" \ 337 " status_text=\"" STATUS_OK_CREATED_TEXT "\"/>" 338 339 /** 340 * @brief Expand to XML for a STATUS_OK_CREATED response with %s for ID. 341 * 342 * @param tag Name of the command generating the response. 343 */ 344 #define XML_OK_CREATED_ID(tag) \ 345 "<" tag "_response" \ 346 " status=\"" STATUS_OK_CREATED "\"" \ 347 " status_text=\"" STATUS_OK_CREATED_TEXT "\"" \ 348 " id=\"%s\"/>" 349 350 /** 351 * @brief Expand to XML for a STATUS_OK_REQUESTED response. 352 * 353 * @param tag Name of the command generating the response. 354 */ 355 #define XML_OK_REQUESTED(tag) \ 356 "<" tag "_response" \ 357 " status=\"" STATUS_OK_REQUESTED "\"" \ 358 " status_text=\"" STATUS_OK_REQUESTED_TEXT "\"/>" 359 360 /** 361 * @brief Expand to XML for a STATUS_INTERNAL_ERROR response. 362 * 363 * @param tag Name of the command generating the response. 364 */ 365 #define XML_INTERNAL_ERROR(tag) \ 366 "<" tag "_response" \ 367 " status=\"" STATUS_INTERNAL_ERROR "\"" \ 368 " status_text=\"" STATUS_INTERNAL_ERROR_TEXT "\"/>" 369 370 /** 371 * @brief Sends XML for a STATUS_SERVICE_DOWN response. 372 * 373 * @param tag Name of the command generating the response. 374 */ 375 #define SEND_XML_SERVICE_DOWN(tag) \ 376 do \ 377 { \ 378 char *str; \ 379 str = \ 380 g_strdup_printf ("<%s_response status='%s' status_text='%s'/>", tag, \ 381 STATUS_SERVICE_DOWN, STATUS_SERVICE_DOWN_TEXT); \ 382 SEND_TO_CLIENT_OR_FAIL (str); \ 383 g_free (str); \ 384 } \ 385 while (0); 386 387 #endif /* not _GVMD_GMP_BASE_H */ 388