Skip to content

Commit

Permalink
Fix #367: custom providers with printf(3) format specifiers broken
Browse files Browse the repository at this point in the history
A custom provider definition with printf() style format specifiers *and*
multiple hostname was broken, as reported in issue #367.

    custom namecheap {
        username    = YOURDOMAIN.TLD
        password    = mypass
        ddns-server = dynamicdns.park-your-domain.com
        ddns-path   = "/update?domain=%u&password=%p&host=%h"
        hostname    = { "host1", "host2", "host3" }
    }

The resulting HTTP requests were garbled, like this:

    GET /update?domain=YOURDOMAIN.TLD&password=mypass&host=host1 HTTP/1.0
    GET /update?domain=YOURDOMAIN.TLD&password=mypass&host=host1host2 HTTP/1.0
    GET /update?domain=YOURDOMAIN.TLD&password=mypass&host=host1host3 HTTP/1.0

The root cause was a legacy limitation causing the ddns-path to be
overwritten on first entry with the first host.  This patch fixes the
limitation by always composing the HTTP request in a temporary buffer,
using the custom ddns-path only as a template.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
  • Loading branch information
troglobit committed Dec 9, 2021
1 parent ce3b08f commit 1f6ae75
Showing 1 changed file with 15 additions and 11 deletions.
26 changes: 15 additions & 11 deletions plugins/generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,11 @@ static void skip_fmt(char *fmt, size_t len)
* %h - hostname
* %i - IP address
*/
static int custom_server_url(ddns_info_t *info, ddns_alias_t *alias)
static int custom_server_url(char *buf, ddns_info_t *info, ddns_alias_t *alias)
{
char *ptr;

while ((ptr = strchr(info->server_url, '%'))) {
while ((ptr = strchr(buf, '%'))) {
if (!strncmp(ptr, "%u", 2)) {
if (strnlen(info->creds.username, USERNAME_LEN) <= 0) {
logit(LOG_ERR, "Format specifier in ddns-path used: '%%u',"
Expand Down Expand Up @@ -135,7 +135,7 @@ static int custom_server_url(ddns_info_t *info, ddns_alias_t *alias)
return -1;
}

return strlen(info->server_url);
return strlen(buf);
}

static char tohex(char code)
Expand Down Expand Up @@ -204,17 +204,21 @@ static char *url_encode(char *str)
*/
static int request(ddns_t *ctx, ddns_info_t *info, ddns_alias_t *alias)
{
int ret;
char *url;
char buf[2 * sizeof(info->server_url)];
char *arg = "";
char *url;
int ret;

/* Operate of copy of URL, may contain %-modifiers */
strlcpy(buf, info->server_url, sizeof(buf));

/*
* if the user has specified modifiers, then he is probably
* aware of how to append his hostname or IP, otherwise just
* append the hostname or ip (depending on the append_myip option)
* if the user has specified modifiers, then they probably know
* how to append his hostname or IP, otherwise just append the
* hostname or ip (depending on the append_myip option)
*/
if (strchr(info->server_url, '%')) {
if (custom_server_url(info, alias) <= 0)
if (strchr(buf, '%')) {
if (custom_server_url(buf, info, alias) <= 0)
logit(LOG_ERR, "Invalid server URL: %s", info->server_url);
} else {
/* Backwards compat, default to append hostname */
Expand All @@ -224,7 +228,7 @@ static int request(ddns_t *ctx, ddns_info_t *info, ddns_alias_t *alias)
arg = alias->address;
}

url = url_encode(info->server_url);
url = url_encode(buf);
if (!url)
return 0;

Expand Down

0 comments on commit 1f6ae75

Please sign in to comment.