From ed6b8090138cac09217722e7d95ca295f819d4fc Mon Sep 17 00:00:00 2001 From: DL6ER Date: Mon, 16 Jan 2023 19:57:24 +0100 Subject: [PATCH] Modify removing and adding local DNS entries via path instead of payload Signed-off-by: DL6ER --- .github/workflows/openapi-validator.yml | 2 +- src/api/api.c | 2 +- src/api/config.c | 3 + src/api/dns.c | 98 +++++--------- src/api/docs/content/specs/dns.yaml | 169 +++++++++++++----------- src/api/docs/content/specs/main.yaml | 5 +- src/api/ftl.c | 1 - 7 files changed, 132 insertions(+), 148 deletions(-) diff --git a/.github/workflows/openapi-validator.yml b/.github/workflows/openapi-validator.yml index 1f52a5cb..c4d8f34f 100644 --- a/.github/workflows/openapi-validator.yml +++ b/.github/workflows/openapi-validator.yml @@ -7,7 +7,7 @@ env: jobs: openapi-validator: - name: Node ${{ matrix.node }} + name: Node runs-on: ubuntu-latest steps: diff --git a/src/api/api.c b/src/api/api.c index 875bf560..efad6093 100644 --- a/src/api/api.c +++ b/src/api/api.c @@ -35,7 +35,7 @@ static struct { { "/api/dns/blocking", "", api_dns_blocking, { false, false } }, { "/api/dns/cache", "", api_dns_cache, { false, false } }, { "/api/dns/port", "", api_dns_port, { false, false } }, - { "/api/dns/entries", "", api_dns_entries, { false, false } }, + { "/api/dns/entries", "/{ip}/{host}", api_dns_entries, { false, false } }, { "/api/clients", "/{client}", api_list, { false, false } }, { "/api/domains", "/{type}/{kind}/{domain}", api_list, { false, false } }, { "/api/groups", "/{name}", api_list, { false, false } }, diff --git a/src/api/config.c b/src/api/config.c index 248d9a64..b7cb025c 100644 --- a/src/api/config.c +++ b/src/api/config.c @@ -474,6 +474,9 @@ static int api_config_patch(struct ftl_conn *api) dnsmasq_changed = true; } + // Reload debug levels + set_debug_flags(); + // Store changed configuration to disk writeFTLtoml(true); diff --git a/src/api/dns.c b/src/api/dns.c index 0b13320c..90d6d89c 100644 --- a/src/api/dns.c +++ b/src/api/dns.c @@ -311,43 +311,20 @@ static int write_custom_list(struct ftl_conn *api, cJSON *entries) static int add_to_custom_list(struct ftl_conn *api, cJSON *entries) { - // Check if valid JSON payload is available - if (api->payload.json == NULL) - { - cJSON_Delete(entries); - return send_json_error(api, 400, - "bad_request", - "Invalid request body data (no valid JSON)", - NULL); - } - + // Split URI into IP and host char *ip = NULL; - cJSON *json_ip = cJSON_GetObjectItem(api->payload.json, "ip"); - if(cJSON_IsString(json_ip) && strlen(json_ip->valuestring) > 0) - { - ip = json_ip->valuestring; - } - else - { - cJSON_Delete(entries); - return send_json_error(api, 400, - "bad_request", - "Invalid request: No item \"ip\" in payload", - NULL); - } char *host = NULL; - cJSON *json_host = cJSON_GetObjectItem(api->payload.json, "host"); - if(cJSON_IsString(json_host) && strlen(json_host->valuestring) > 0) - { - host = json_host->valuestring; - } - else + if(sscanf(api->item, "%m[^/]/%m[^/]", &ip, &host) != 2) { cJSON_Delete(entries); + if(ip != NULL) + free(ip); + if(host != NULL) + free(host); return send_json_error(api, 400, - "bad_request", - "Invalid request: No item \"host\" in payload", - NULL); + "validation_error", + "Invalid URI", + "URI must be in the format /api/dns/entries/{ip}/{host}"); } // Convert domain to lowercase @@ -358,6 +335,8 @@ static int add_to_custom_list(struct ftl_conn *api, cJSON *entries) if(error != NULL) { cJSON_Delete(entries); + free(ip); + free(host); return send_json_error(api, 400, "validation_error", "Specified host is not valid", @@ -369,6 +348,8 @@ static int add_to_custom_list(struct ftl_conn *api, cJSON *entries) if(!isValidIPv4(ip) && !isValidIPv6(ip)) { cJSON_Delete(entries); + free(ip); + free(host); return send_json_error(api, 400, "validation_error", "Specified IP address is neither a valid IPv4 nor IPv6 address", @@ -395,6 +376,8 @@ static int add_to_custom_list(struct ftl_conn *api, cJSON *entries) strcmp(host, list_host->valuestring) == 0) { // Entry already present in list, no need to add it + free(ip); + free(host); return 200; } } @@ -406,48 +389,27 @@ static int add_to_custom_list(struct ftl_conn *api, cJSON *entries) JSON_ADD_ITEM_TO_ARRAY(entries, entry); // Write the file + free(ip); + free(host); return write_custom_list(api, entries); } static int remove_from_custom_list(struct ftl_conn *api, cJSON *entries) { - // Check if valid JSON payload is available - if (api->payload.json == NULL) - { - cJSON_Delete(entries); - return send_json_error(api, 400, - "bad_request", - "Invalid request body data (no valid JSON)", - NULL); - } - + // Split URI into IP and host char *ip = NULL; - cJSON *json_ip = cJSON_GetObjectItem(api->payload.json, "ip"); - if(cJSON_IsString(json_ip) && strlen(json_ip->valuestring) > 0) - { - ip = json_ip->valuestring; - } - else - { - cJSON_Delete(entries); - return send_json_error(api, 400, - "bad_request", - "Invalid request: No item \"ip\" in payload", - NULL); - } char *host = NULL; - cJSON *json_host = cJSON_GetObjectItem(api->payload.json, "host"); - if(cJSON_IsString(json_host) && strlen(json_host->valuestring) > 0) - { - host = json_host->valuestring; - } - else + if(sscanf(api->item, "%m[^/]/%m[^/]", &ip, &host) != 2) { cJSON_Delete(entries); + if(ip != NULL) + free(ip); + if(host != NULL) + free(host); return send_json_error(api, 400, - "bad_request", - "Invalid request: No item \"host\" in payload", - NULL); + "validation_error", + "Invalid URI", + "URI must be in the format /api/dns/entries/{ip}/{host}"); } // Convert domain to lowercase @@ -456,7 +418,11 @@ static int remove_from_custom_list(struct ftl_conn *api, cJSON *entries) // Read list from disk int ret = read_custom_list(api, entries); if(ret != 200) + { + free(ip); + free(host); return ret; + } // Check if this entry exists in the list for(int i = 0; i < cJSON_GetArraySize(entries); i++) @@ -477,6 +443,8 @@ static int remove_from_custom_list(struct ftl_conn *api, cJSON *entries) } // Write the file + free(ip); + free(host); return write_custom_list(api, entries); } @@ -501,7 +469,7 @@ int api_dns_entries(struct ftl_conn *api) JSON_SEND_OBJECT(json); } } - else if(api->method == HTTP_POST) + else if(api->method == HTTP_PUT) { // Add item to list identified by payload cJSON *entries = JSON_NEW_ARRAY(); diff --git a/src/api/docs/content/specs/dns.yaml b/src/api/docs/content/specs/dns.yaml index 217eae45..357533a3 100644 --- a/src/api/docs/content/specs/dns.yaml +++ b/src/api/docs/content/specs/dns.yaml @@ -105,86 +105,80 @@ components: schema: $ref: 'dns.yaml#/components/schemas/dns_port' entries: - summary: Modify list of additional DNS records get: - summary: Get current list of additional DNS records - tags: - - DNS control - operationId: "get_dns_entries" - description: Returns a list of currently configured additional DNS records (if any) - responses: - '200': - description: OK - content: - application/json: - schema: - $ref: 'dns.yaml#/components/schemas/host_records' - post: - summary: Add entry to list of additional DNS records - tags: - - DNS control - operationId: "add_dns_entries" - description: | - Adds an additional DNS records to the list of known DNS records - requestBody: - description: Callback payload - content: - 'application/json': - schema: - $ref: 'dns.yaml#/components/schemas/host_record' - responses: - '200': - description: OK - content: - application/json: - schema: - $ref: 'dns.yaml#/components/schemas/host_records' - '400': - description: Bad request - content: - application/json: - schema: - oneOf: - - $ref: 'dns.yaml#/components/schemas/errors/no_payload' - '401': - description: Unauthorized - content: - application/json: - schema: - $ref: 'common.yaml#/components/errors/unauthorized' - delete: - summary: Remove entry to list of additional DNS records - tags: - - DNS control - operationId: "remove_dns_entries" - description: | - Removes an additional DNS records from the list of known DNS records - requestBody: - description: Callback payload - content: - 'application/json': - schema: - $ref: 'dns.yaml#/components/schemas/host_record' - responses: - '200': - description: OK - content: - application/json: - schema: - $ref: 'dns.yaml#/components/schemas/host_records' - '400': - description: Bad request - content: - application/json: - schema: - oneOf: - - $ref: 'dns.yaml#/components/schemas/errors/no_payload' - '401': - description: Unauthorized - content: - application/json: - schema: - $ref: 'common.yaml#/components/errors/unauthorized' + summary: Read list of additional DNS records + get: + summary: Get current list of additional DNS records + tags: + - DNS control + operationId: "get_dns_entries" + description: Returns a list of currently configured additional DNS records (if any) + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: 'dns.yaml#/components/schemas/host_records' + put_delete: + summary: Modify list of additional DNS records + parameters: + - $ref: 'dns.yaml#/components/parameters/ip' + - $ref: 'dns.yaml#/components/parameters/host' + put: + summary: Add entry to list of additional DNS records + tags: + - DNS control + operationId: "add_dns_entries" + description: | + Adds an additional DNS records to the list of known DNS records + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: 'dns.yaml#/components/schemas/host_records' + '400': + description: Bad request + content: + application/json: + schema: + oneOf: + - $ref: 'dns.yaml#/components/schemas/errors/no_payload' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: 'common.yaml#/components/errors/unauthorized' + delete: + summary: Remove entry to list of additional DNS records + tags: + - DNS control + operationId: "remove_dns_entries" + description: | + Removes an additional DNS records from the list of known DNS records + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: 'dns.yaml#/components/schemas/host_records' + '400': + description: Bad request + content: + application/json: + schema: + oneOf: + - $ref: 'dns.yaml#/components/schemas/errors/no_payload' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: 'common.yaml#/components/errors/unauthorized' schemas: blocking: type: object @@ -330,3 +324,20 @@ components: ds: 60 dnskey: 35 other: 14 + parameters: + ip: + in: path + name: ip + description: IP address (Pv4 or IPv6) + schema: + type: string + required: true + example: "192.168.2.10" + host: + in: path + name: host + description: Hostname + schema: + type: string + required: true + example: "mymusicbox" diff --git a/src/api/docs/content/specs/main.yaml b/src/api/docs/content/specs/main.yaml index 620a6804..9dd15c2f 100644 --- a/src/api/docs/content/specs/main.yaml +++ b/src/api/docs/content/specs/main.yaml @@ -112,7 +112,10 @@ paths: $ref: 'dns.yaml#/components/paths/port' /dns/entries: - $ref: 'dns.yaml#/components/paths/entries' + $ref: 'dns.yaml#/components/paths/entries/get' + + /dns/entries/{ip}/{host}: + $ref: 'dns.yaml#/components/paths/entries/put_delete' /domains/{type}/{kind}/{domain}: $ref: 'domains.yaml#/components/paths/type_kind_domain' diff --git a/src/api/ftl.c b/src/api/ftl.c index 7a99966d..9825c6db 100644 --- a/src/api/ftl.c +++ b/src/api/ftl.c @@ -16,7 +16,6 @@ #include "../fifo.h" // sysinfo() #include -#include // get_blockingstatus() #include "../setupVars.h" // counters