diff --git a/CHANGELOG.md b/CHANGELOG.md index e5197c148..548dd0ba4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Add support for test_alive_hosts_only feature of openvas. [#320](https://github.com/greenbone/gvm-libs/pull/320) - Add function to set and get the NVT QoD. [#321](https://github.com/greenbone/gvm-libs/pull/321) - Add unit tests for networking.c port list functions. [#325](https://github.com/greenbone/gvm-libs/pull/325) +- Add gmp_start_task_ext_c. [#327](https://github.com/greenbone/gvm-libs/pull/327) ### Fixed - Fix is_cidr_block(). [#322](https://github.com/greenbone/gvm-libs/pull/322) diff --git a/gmp/gmp.c b/gmp/gmp.c index 471e46c31..0efc2cf6d 100644 --- a/gmp/gmp.c +++ b/gmp/gmp.c @@ -115,6 +115,78 @@ gmp_check_response (gnutls_session_t *session, entity_t *entity) return ret; } +/** + * @brief Read response and convert status of response to a return value. + * + * @param[in] connection Connection. + * @param[in] convert_99 If true, return will be 99 if response was 400 with + * status_text "Permission Denied". + * + * @return 0 on success, 99 if convert_99 and permission denied, -1 or GMP + * response code on error. + */ +static int +check_response_c (gvm_connection_t *connection, int convert_99) +{ + int ret; + const char *status; + entity_t entity; + + /* Read the response. */ + + entity = NULL; + if (read_entity_c (connection, &entity)) + return -1; + + /* Check the response. */ + + status = entity_attribute (entity, "status"); + if (status == NULL) + { + free_entity (entity); + return -1; + } + if (strlen (status) == 0) + { + free_entity (entity); + return -1; + } + if (status[0] == '2') + { + free_entity (entity); + return 0; + } + ret = (int) strtol (status, NULL, 10); + if (errno == ERANGE) + { + free_entity (entity); + return -1; + } + + if (convert_99 + && entity_attribute (entity, "status_text") + && strcasecmp (entity_attribute (entity, "status_text"), + "Permission denied") + == 0) + ret = 99; + + free_entity (entity); + return ret; +} + +/** + * @brief Read response and convert status of response to a return value. + * + * @param[in] connection Connection. + * + * @return 0 on success, -1 or GMP response code on error. + */ +int +gmp_check_response_c (gvm_connection_t *connection) +{ + return check_response_c (connection, 0); +} + /** * @brief "Ping" the manager. * @@ -791,48 +863,33 @@ gmp_start_task_report_c (gvm_connection_t *connection, const char *task_id, } /** - * @brief Read response and convert status of response to a return value. + * @brief Start a task and read the manager response. * * @param[in] connection Connection. + * @param[in] opts Options to apply. * - * @return 0 on success, -1 or GMP response code on error. + * @return 0 on success, 99 permission denied, -1 or GMP response code on error. */ int -gmp_check_response_c (gvm_connection_t *connection) +gmp_start_task_ext_c (gvm_connection_t *connection, gmp_start_task_opts_t opts) { int ret; - const char *status; - entity_t entity; - /* Read the response. */ + /* Check args. */ - entity = NULL; - if (read_entity_c (connection, &entity)) + if (opts.task_id == NULL) return -1; - /* Check the response. */ + /* Send request. */ - status = entity_attribute (entity, "status"); - if (status == NULL) - { - free_entity (entity); - return -1; - } - if (strlen (status) == 0) - { - free_entity (entity); - return -1; - } - if (status[0] == '2') - { - free_entity (entity); - return 0; - } - ret = (int) strtol (status, NULL, 10); - free_entity (entity); - if (errno == ERANGE) + ret = gvm_connection_sendf (connection, "", + opts.task_id); + if (ret) return -1; - return ret; + + /* Read response. */ + + return check_response_c (connection, 1); } /** diff --git a/gmp/gmp.h b/gmp/gmp.h index b3b1cb2b0..1f1fa8394 100644 --- a/gmp/gmp.h +++ b/gmp/gmp.h @@ -324,6 +324,19 @@ gmp_start_task_report (gnutls_session_t *, const char *, char **); int gmp_start_task_report_c (gvm_connection_t *, const char *, char **); +/** + * @brief Struct holding options for gmp start_task command. + */ +typedef struct +{ + const char *task_id; ///< ID of task. +} gmp_start_task_opts_t; + +static const gmp_start_task_opts_t gmp_start_task_opts_defaults = { NULL }; + +int +gmp_start_task_ext_c (gvm_connection_t *, gmp_start_task_opts_t); + int gmp_stop_task (gnutls_session_t *, const char *);