diff options
| author | Hauke Mehrtens | 2026-04-23 22:21:04 +0000 |
|---|---|---|
| committer | Hauke Mehrtens | 2026-06-07 11:24:11 +0000 |
| commit | ec47f4176b1ea3c8916ed668a8935cb8636f9317 (patch) | |
| tree | f7449e12c124bdb2c81b9dcc43f48015b669b3f2 | |
| parent | bf403fa0f8e5d9e657bf380816165b4b5bc81591 (diff) | |
| download | uclient-ec47f4176b1ea3c8916ed668a8935cb8636f9317.tar.gz | |
uclient-fetch: always allocate auth_str and free it on exit
Previously auth_str was heap-allocated via asprintf() when both a
username and password were supplied, but aliased to the stack-allocated
strdupa() buffer when only a username was supplied. The heap allocation
was never freed, and the inconsistent ownership made the buffer
impossible to free unambiguously.
Always asprintf() when a username is given (appending an empty password
if none was provided) and free the result at the end of main().
As a side effect this also corrects the username-only case: auth_str now
ends in "username:" instead of a bare "username". The value is
base64-encoded verbatim into the Basic Authorization header, where
RFC 7617 requires the "user-id:password" form, so the old colon-less
value was a malformed empty-password credential. Digest auth is
unaffected, as it already treats a value with no ':' as an empty
password.
Assisted-by: Claude:claude-opus-4-7
Link: https://github.com/openwrt/uclient/pull/16
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
| -rw-r--r-- | uclient-fetch.c | 15 |
1 files changed, 7 insertions, 8 deletions
diff --git a/uclient-fetch.c b/uclient-fetch.c index 48fafe8..efb9b88 100644 --- a/uclient-fetch.c +++ b/uclient-fetch.c @@ -889,14 +889,11 @@ int main(int argc, char **argv) uloop_init(); if (username) { - if (password) { - rc = asprintf(&auth_str, "%s:%s", username, password); - if (rc < 0) { - error_ret = 1; - goto out; - } - } else - auth_str = username; + rc = asprintf(&auth_str, "%s:%s", username, password ? password : ""); + if (rc < 0) { + error_ret = 1; + goto out; + } } if (!quiet) @@ -949,5 +946,7 @@ out: free(h); } + free(auth_str); + return error_ret; } |