mirror of
git://projects.qi-hardware.com/openwrt-xburst.git
synced 2024-11-17 19:59:25 +02:00
package/busybox: wget: URL-decode user:password before base64-encoding it into auth hdr (upstream fix)
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@29299 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
parent
c247f5a905
commit
bfd5f1061a
@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
|
|||||||
|
|
||||||
PKG_NAME:=busybox
|
PKG_NAME:=busybox
|
||||||
PKG_VERSION:=1.19.3
|
PKG_VERSION:=1.19.3
|
||||||
PKG_RELEASE:=8
|
PKG_RELEASE:=9
|
||||||
PKG_FLAGS:=essential
|
PKG_FLAGS:=essential
|
||||||
|
|
||||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
|
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
|
||||||
|
@ -0,0 +1,237 @@
|
|||||||
|
http://git.busybox.net/busybox/commit/?id=dd1061b6a79b0161597799e825bfefc27993ace5
|
||||||
|
|
||||||
|
From dd1061b6a79b0161597799e825bfefc27993ace5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Denys Vlasenko <vda.linux@googlemail.com>
|
||||||
|
Date: Sun, 11 Sep 2011 21:04:02 +0200
|
||||||
|
Subject: [PATCH] wget: URL-decode user:password before base64-encoding it into auth hdr. Closes 3625.
|
||||||
|
|
||||||
|
function old new delta
|
||||||
|
percent_decode_in_place - 152 +152
|
||||||
|
parse_url 304 317 +13
|
||||||
|
handle_incoming_and_exit 2795 2798 +3
|
||||||
|
httpd_main 763 760 -3
|
||||||
|
decodeString 152 - -152
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
(add/remove: 2/1 grow/shrink: 2/1 up/down: 168/-155) Total: 13 bytes
|
||||||
|
|
||||||
|
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
|
||||||
|
|
||||||
|
--- a/include/libbb.h
|
||||||
|
+++ b/include/libbb.h
|
||||||
|
@@ -1570,6 +1570,15 @@ int starts_with_cpu(const char *str) FAS
|
||||||
|
unsigned get_cpu_count(void) FAST_FUNC;
|
||||||
|
|
||||||
|
|
||||||
|
+/* Use strict=1 if you process input from untrusted source:
|
||||||
|
+ * it will return NULL on invalid %xx (bad hex chars)
|
||||||
|
+ * and str + 1 if decoded char is / or NUL.
|
||||||
|
+ * In non-strict mode, it always succeeds (returns str),
|
||||||
|
+ * and also it additionally decoded '+' to space.
|
||||||
|
+ */
|
||||||
|
+char *percent_decode_in_place(char *str, int strict) FAST_FUNC;
|
||||||
|
+
|
||||||
|
+
|
||||||
|
extern const char bb_uuenc_tbl_base64[];
|
||||||
|
extern const char bb_uuenc_tbl_std[];
|
||||||
|
void bb_uuencode(char *store, const void *s, int length, const char *tbl) FAST_FUNC;
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/libbb/percent_decode.c
|
||||||
|
@@ -0,0 +1,69 @@
|
||||||
|
+/* vi: set sw=4 ts=4: */
|
||||||
|
+/*
|
||||||
|
+ * Licensed under GPLv2 or later, see file LICENSE in this source tree.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+//kbuild:lib-y += percent_decode.o
|
||||||
|
+
|
||||||
|
+#include "libbb.h"
|
||||||
|
+
|
||||||
|
+static unsigned hex_to_bin(unsigned char c)
|
||||||
|
+{
|
||||||
|
+ unsigned v;
|
||||||
|
+
|
||||||
|
+ v = c - '0';
|
||||||
|
+ if (v <= 9)
|
||||||
|
+ return v;
|
||||||
|
+ /* c | 0x20: letters to lower case, non-letters
|
||||||
|
+ * to (potentially different) non-letters */
|
||||||
|
+ v = (unsigned)(c | 0x20) - 'a';
|
||||||
|
+ if (v <= 5)
|
||||||
|
+ return v + 10;
|
||||||
|
+ return ~0;
|
||||||
|
+/* For testing:
|
||||||
|
+void t(char c) { printf("'%c'(%u) %u\n", c, c, hex_to_bin(c)); }
|
||||||
|
+int main() { t(0x10); t(0x20); t('0'); t('9'); t('A'); t('F'); t('a'); t('f');
|
||||||
|
+t('0'-1); t('9'+1); t('A'-1); t('F'+1); t('a'-1); t('f'+1); return 0; }
|
||||||
|
+*/
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+char* FAST_FUNC percent_decode_in_place(char *str, int strict)
|
||||||
|
+{
|
||||||
|
+ /* note that decoded string is always shorter than original */
|
||||||
|
+ char *src = str;
|
||||||
|
+ char *dst = str;
|
||||||
|
+ char c;
|
||||||
|
+
|
||||||
|
+ while ((c = *src++) != '\0') {
|
||||||
|
+ unsigned v;
|
||||||
|
+
|
||||||
|
+ if (!strict && c == '+') {
|
||||||
|
+ *dst++ = ' ';
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+ if (c != '%') {
|
||||||
|
+ *dst++ = c;
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+ v = hex_to_bin(src[0]);
|
||||||
|
+ if (v > 15) {
|
||||||
|
+ bad_hex:
|
||||||
|
+ if (strict)
|
||||||
|
+ return NULL;
|
||||||
|
+ *dst++ = '%';
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+ v = (v * 16) | hex_to_bin(src[1]);
|
||||||
|
+ if (v > 255)
|
||||||
|
+ goto bad_hex;
|
||||||
|
+ if (strict && (v == '/' || v == '\0')) {
|
||||||
|
+ /* caller takes it as indication of invalid
|
||||||
|
+ * (dangerous wrt exploits) chars */
|
||||||
|
+ return str + 1;
|
||||||
|
+ }
|
||||||
|
+ *dst++ = v;
|
||||||
|
+ src += 2;
|
||||||
|
+ }
|
||||||
|
+ *dst = '\0';
|
||||||
|
+ return str;
|
||||||
|
+}
|
||||||
|
--- a/networking/httpd.c
|
||||||
|
+++ b/networking/httpd.c
|
||||||
|
@@ -820,78 +820,6 @@ static char *encodeString(const char *st
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
-/*
|
||||||
|
- * Given a URL encoded string, convert it to plain ascii.
|
||||||
|
- * Since decoding always makes strings smaller, the decode is done in-place.
|
||||||
|
- * Thus, callers should xstrdup() the argument if they do not want the
|
||||||
|
- * argument modified. The return is the original pointer, allowing this
|
||||||
|
- * function to be easily used as arguments to other functions.
|
||||||
|
- *
|
||||||
|
- * string The first string to decode.
|
||||||
|
- * option_d 1 if called for httpd -d
|
||||||
|
- *
|
||||||
|
- * Returns a pointer to the decoded string (same as input).
|
||||||
|
- */
|
||||||
|
-static unsigned hex_to_bin(unsigned char c)
|
||||||
|
-{
|
||||||
|
- unsigned v;
|
||||||
|
-
|
||||||
|
- v = c - '0';
|
||||||
|
- if (v <= 9)
|
||||||
|
- return v;
|
||||||
|
- /* c | 0x20: letters to lower case, non-letters
|
||||||
|
- * to (potentially different) non-letters */
|
||||||
|
- v = (unsigned)(c | 0x20) - 'a';
|
||||||
|
- if (v <= 5)
|
||||||
|
- return v + 10;
|
||||||
|
- return ~0;
|
||||||
|
-/* For testing:
|
||||||
|
-void t(char c) { printf("'%c'(%u) %u\n", c, c, hex_to_bin(c)); }
|
||||||
|
-int main() { t(0x10); t(0x20); t('0'); t('9'); t('A'); t('F'); t('a'); t('f');
|
||||||
|
-t('0'-1); t('9'+1); t('A'-1); t('F'+1); t('a'-1); t('f'+1); return 0; }
|
||||||
|
-*/
|
||||||
|
-}
|
||||||
|
-static char *decodeString(char *orig, int option_d)
|
||||||
|
-{
|
||||||
|
- /* note that decoded string is always shorter than original */
|
||||||
|
- char *string = orig;
|
||||||
|
- char *ptr = string;
|
||||||
|
- char c;
|
||||||
|
-
|
||||||
|
- while ((c = *ptr++) != '\0') {
|
||||||
|
- unsigned v;
|
||||||
|
-
|
||||||
|
- if (option_d && c == '+') {
|
||||||
|
- *string++ = ' ';
|
||||||
|
- continue;
|
||||||
|
- }
|
||||||
|
- if (c != '%') {
|
||||||
|
- *string++ = c;
|
||||||
|
- continue;
|
||||||
|
- }
|
||||||
|
- v = hex_to_bin(ptr[0]);
|
||||||
|
- if (v > 15) {
|
||||||
|
- bad_hex:
|
||||||
|
- if (!option_d)
|
||||||
|
- return NULL;
|
||||||
|
- *string++ = '%';
|
||||||
|
- continue;
|
||||||
|
- }
|
||||||
|
- v = (v * 16) | hex_to_bin(ptr[1]);
|
||||||
|
- if (v > 255)
|
||||||
|
- goto bad_hex;
|
||||||
|
- if (!option_d && (v == '/' || v == '\0')) {
|
||||||
|
- /* caller takes it as indication of invalid
|
||||||
|
- * (dangerous wrt exploits) chars */
|
||||||
|
- return orig + 1;
|
||||||
|
- }
|
||||||
|
- *string++ = v;
|
||||||
|
- ptr += 2;
|
||||||
|
- }
|
||||||
|
- *string = '\0';
|
||||||
|
- return orig;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
#if ENABLE_FEATURE_HTTPD_BASIC_AUTH
|
||||||
|
/*
|
||||||
|
* Decode a base64 data stream as per rfc1521.
|
||||||
|
@@ -1949,7 +1877,7 @@ static void handle_incoming_and_exit(con
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Decode URL escape sequences */
|
||||||
|
- tptr = decodeString(urlcopy, 0);
|
||||||
|
+ tptr = percent_decode_in_place(urlcopy, /*strict:*/ 1);
|
||||||
|
if (tptr == NULL)
|
||||||
|
send_headers_and_exit(HTTP_BAD_REQUEST);
|
||||||
|
if (tptr == urlcopy + 1) {
|
||||||
|
@@ -2408,7 +2336,7 @@ int httpd_main(int argc UNUSED_PARAM, ch
|
||||||
|
, &verbose
|
||||||
|
);
|
||||||
|
if (opt & OPT_DECODE_URL) {
|
||||||
|
- fputs(decodeString(url_for_decode, 1), stdout);
|
||||||
|
+ fputs(percent_decode_in_place(url_for_decode, /*strict:*/ 0), stdout);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#if ENABLE_FEATURE_HTTPD_ENCODE_URL_STR
|
||||||
|
--- a/networking/wget.c
|
||||||
|
+++ b/networking/wget.c
|
||||||
|
@@ -298,8 +298,13 @@ static void parse_url(const char *src_ur
|
||||||
|
|
||||||
|
sp = strrchr(h->host, '@');
|
||||||
|
if (sp != NULL) {
|
||||||
|
- h->user = h->host;
|
||||||
|
+ // URL-decode "user:password" string before base64-encoding:
|
||||||
|
+ // wget http://test:my%20pass@example.com should send
|
||||||
|
+ // Authorization: Basic dGVzdDpteSBwYXNz
|
||||||
|
+ // which decodes to "test:my pass".
|
||||||
|
+ // Standard wget and curl do this too.
|
||||||
|
*sp = '\0';
|
||||||
|
+ h->user = percent_decode_in_place(h->host, /*strict:*/ 0);
|
||||||
|
h->host = sp + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -660,12 +665,6 @@ static void download_one_url(const char
|
||||||
|
|
||||||
|
#if ENABLE_FEATURE_WGET_AUTHENTICATION
|
||||||
|
if (target.user) {
|
||||||
|
-//TODO: URL-decode "user:password" string before base64-encoding:
|
||||||
|
-//wget http://test:my%20pass@example.com should send
|
||||||
|
-// Authorization: Basic dGVzdDpteSBwYXNz
|
||||||
|
-//which decodes to "test:my pass", instead of what we send now:
|
||||||
|
-// Authorization: Basic dGVzdDpteSUyMHBhc3M=
|
||||||
|
-//Can reuse decodeString() from httpd.c
|
||||||
|
fprintf(sfp, "Proxy-Authorization: Basic %s\r\n"+6,
|
||||||
|
base64enc(target.user));
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
--- a/networking/wget.c
|
--- a/networking/wget.c
|
||||||
+++ b/networking/wget.c
|
+++ b/networking/wget.c
|
||||||
@@ -872,7 +872,7 @@ int wget_main(int argc UNUSED_PARAM, cha
|
@@ -871,7 +871,7 @@ int wget_main(int argc UNUSED_PARAM, cha
|
||||||
/* Ignored: */
|
/* Ignored: */
|
||||||
// "tries\0" Required_argument "t"
|
// "tries\0" Required_argument "t"
|
||||||
/* Ignored (we always use PASV): */
|
/* Ignored (we always use PASV): */
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
--- a/networking/httpd.c
|
--- a/networking/httpd.c
|
||||||
+++ b/networking/httpd.c
|
+++ b/networking/httpd.c
|
||||||
@@ -1772,21 +1772,32 @@ static int check_user_passwd(const char
|
@@ -1700,21 +1700,32 @@ static int check_user_passwd(const char
|
||||||
|
|
||||||
if (ENABLE_FEATURE_HTTPD_AUTH_MD5) {
|
if (ENABLE_FEATURE_HTTPD_AUTH_MD5) {
|
||||||
char *md5_passwd;
|
char *md5_passwd;
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
#define last_mod (G.last_mod )
|
#define last_mod (G.last_mod )
|
||||||
#define ip_a_d (G.ip_a_d )
|
#define ip_a_d (G.ip_a_d )
|
||||||
#define g_realm (G.g_realm )
|
#define g_realm (G.g_realm )
|
||||||
@@ -1028,8 +1035,11 @@ static void send_headers(int responseNum
|
@@ -956,8 +963,11 @@ static void send_headers(int responseNum
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (responseNum == HTTP_MOVED_TEMPORARILY) {
|
if (responseNum == HTTP_MOVED_TEMPORARILY) {
|
||||||
@ -48,7 +48,7 @@
|
|||||||
(g_query ? "?" : ""),
|
(g_query ? "?" : ""),
|
||||||
(g_query ? g_query : ""));
|
(g_query ? g_query : ""));
|
||||||
}
|
}
|
||||||
@@ -1997,8 +2007,12 @@ static void handle_incoming_and_exit(con
|
@@ -1925,8 +1935,12 @@ static void handle_incoming_and_exit(con
|
||||||
} while (*++tptr);
|
} while (*++tptr);
|
||||||
*++urlp = '\0'; /* terminate after last character */
|
*++urlp = '\0'; /* terminate after last character */
|
||||||
|
|
||||||
@ -62,7 +62,7 @@
|
|||||||
if (is_directory(urlcopy + 1, 1, NULL)) {
|
if (is_directory(urlcopy + 1, 1, NULL)) {
|
||||||
found_moved_temporarily = urlcopy;
|
found_moved_temporarily = urlcopy;
|
||||||
}
|
}
|
||||||
@@ -2355,7 +2369,9 @@ static void sighup_handler(int sig UNUSE
|
@@ -2283,7 +2297,9 @@ static void sighup_handler(int sig UNUSE
|
||||||
}
|
}
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@ -73,7 +73,7 @@
|
|||||||
d_opt_decode_url,
|
d_opt_decode_url,
|
||||||
h_opt_home_httpd,
|
h_opt_home_httpd,
|
||||||
IF_FEATURE_HTTPD_ENCODE_URL_STR(e_opt_encode_url,)
|
IF_FEATURE_HTTPD_ENCODE_URL_STR(e_opt_encode_url,)
|
||||||
@@ -2404,12 +2420,13 @@ int httpd_main(int argc UNUSED_PARAM, ch
|
@@ -2332,12 +2348,13 @@ int httpd_main(int argc UNUSED_PARAM, ch
|
||||||
/* We do not "absolutize" path given by -h (home) opt.
|
/* We do not "absolutize" path given by -h (home) opt.
|
||||||
* If user gives relative path in -h,
|
* If user gives relative path in -h,
|
||||||
* $SCRIPT_FILENAME will not be set. */
|
* $SCRIPT_FILENAME will not be set. */
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
--- a/networking/httpd.c
|
--- a/networking/httpd.c
|
||||||
+++ b/networking/httpd.c
|
+++ b/networking/httpd.c
|
||||||
@@ -1294,10 +1294,10 @@ static NOINLINE void cgi_io_loop_and_exi
|
@@ -1222,10 +1222,10 @@ static NOINLINE void cgi_io_loop_and_exi
|
||||||
if (full_write(STDOUT_FILENO, HTTP_200, sizeof(HTTP_200)-1) != sizeof(HTTP_200)-1)
|
if (full_write(STDOUT_FILENO, HTTP_200, sizeof(HTTP_200)-1) != sizeof(HTTP_200)-1)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
--- a/networking/httpd.c
|
--- a/networking/httpd.c
|
||||||
+++ b/networking/httpd.c
|
+++ b/networking/httpd.c
|
||||||
@@ -1886,6 +1886,7 @@ static void handle_incoming_and_exit(con
|
@@ -1814,6 +1814,7 @@ static void handle_incoming_and_exit(con
|
||||||
char *header_ptr = header_ptr;
|
char *header_ptr = header_ptr;
|
||||||
Htaccess_Proxy *proxy_entry;
|
Htaccess_Proxy *proxy_entry;
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user