> Date: Thu, 24 Dec 2009 17:01:21 +0000 > From: [email protected] > > Please resend as an attachment. The whitespace has been mangled and > the patch doesn't apply. > > Thanks for adding test cases. Please leave the tests without a > username:password and append the new test cases on the end. That way > URIs without username:password remain tested. >
Trying both an inline, and an attachment, of the same thing. >From a89c5fa96e32d56b00673ab2b0cddd39eca2c89b Mon Sep 17 00:00:00 2001 From: gL2n30Y06arv2 <[email protected]> Date: Sat, 26 Dec 2009 01:28:37 +0200 Subject: [PATCH] Decodes struct uri.{user,password} members. Replaces the encoded user info (user:password), that was kept in struct uri, with its decoded counterpart. The decoded version is expected to be much more useful. It also attempts to amend the other parts of the project appropriately. The reference is section 3.2 of RFC 3986. Signed-off-by: gL2n30Y06arv2 <[email protected]> --- src/core/uri.c | 45 ++++++++++++++++++++++++++++----------------- src/include/gpxe/uri.h | 4 ++-- src/net/tcp/ftp.c | 28 ++++++++++++++++++++++++++-- src/net/tcp/http.c | 17 ++--------------- src/tests/uri_test.c | 7 +++++++ 5 files changed, 65 insertions(+), 36 deletions(-) diff --git a/src/core/uri.c b/src/core/uri.c index 50a96d3..63166e5 100644 --- a/src/core/uri.c +++ b/src/core/uri.c @@ -45,9 +45,9 @@ static void dump_uri ( struct uri *uri ) { if ( uri->opaque ) DBG ( " opaque \"%s\"", uri->opaque ); if ( uri->user ) - DBG ( " user \"%s\"", uri->user ); + DBG ( " decoded user \"%s\"", uri->user ); if ( uri->password ) - DBG ( " password \"%s\"", uri->password ); + DBG ( " decoded password \"%s\"", uri->password ); if ( uri->host ) DBG ( " host \"%s\"", uri->host ); if ( uri->port ) @@ -149,19 +149,25 @@ struct uri * parse_uri ( const char *uri_string ) { uri->path = path; } - /* Split authority into user[:password] and host[:port] portions */ + /* Split authority into user[:password] and host[:port] + portions. Decodes authority. */ if ( ( tmp = strchr ( authority, '@' ) ) ) { /* Has user[:password] */ *(tmp++) = '\0'; uri->host = tmp; + uri_decode ( authority, authority /* in place */, + strlen ( authority ) + 1 /* NULL */ ); + /* assert ( uri->host>= ( authority + + strlen ( authority ) + 1 ) ); */ uri->user = authority; - if ( ( tmp = strchr ( authority, ':' ) ) ) { + if ( ( tmp = strchr ( uri->user, ':' ) ) ) { /* Has password */ *(tmp++) = '\0'; uri->password = tmp; } + } else { - /* No user:password */ + /* No user[:password] */ uri->host = authority; } @@ -229,13 +235,14 @@ int unparse_uri ( char *buf, size_t size, struct uri *uri ) { /* [user[:passwo...@]host[:port] */ if ( uri->host ) { if ( uri->user ) { + used += uri_encode ( uri->user, ( buf + used ), + ( size - used ) ); used += ssnprintf ( ( buf + used ), ( size - used ), - "%s", uri->user ); - if ( uri->password ) { - used += ssnprintf ( ( buf + used ), - ( size - used ), - ":%s", uri->password ); - } + ":" ); + if ( uri->password ) + used += uri_encode ( uri->password, + ( buf + used ), + ( size - used ) ); used += ssnprintf ( ( buf + used ), ( size - used ), "@" ); } @@ -435,12 +442,14 @@ size_t uri_encode ( const char *raw_string, char *buf, size_t len ) { } /** - * Decode URI-encoded string + * Decode URI-encoded string. * * @v encoded_string URI-encoded string * @v buf Buffer to contain decoded string * @v len Length of buffer * @ret len Length of decoded string (excluding NUL) + * + * Can be used when encoded_string and buf overlap and in place. */ size_t uri_decode ( const char *encoded_string, char *buf, size_t len ) { ssize_t remaining = len; @@ -448,10 +457,8 @@ size_t uri_decode ( const char *encoded_string, char *buf, size_t len ) { char *hexbuf_end; unsigned char c; - if ( len ) - buf[0] = '\0'; - - while ( *encoded_string ) { + while ( *encoded_string && + remaining> 1 /* a NULL is essential */ ) { if ( *encoded_string == '%' ) { encoded_string++; snprintf ( hexbuf, sizeof ( hexbuf ), "%s", @@ -461,7 +468,11 @@ size_t uri_decode ( const char *encoded_string, char *buf, size_t len ) { } else { c = *(encoded_string++); } - ssnprintf ( buf++, remaining--, "%c", c ); + *(remaining--, buf++) = c; } + + if ( remaining ) + *buf = '\0'; + return ( len - remaining ); } diff --git a/src/include/gpxe/uri.h b/src/include/gpxe/uri.h index 03c88d2..de8d5a9 100644 --- a/src/include/gpxe/uri.h +++ b/src/include/gpxe/uri.h @@ -47,9 +47,9 @@ struct uri { const char *scheme; /** Opaque part */ const char *opaque; - /** User name */ + /** Decoded user name */ const char *user; - /** Password */ + /** Decoded password */ const char *password; /** Host name */ const char *host; diff --git a/src/net/tcp/ftp.c b/src/net/tcp/ftp.c index 0719bf7..26103f6 100644 --- a/src/net/tcp/ftp.c +++ b/src/net/tcp/ftp.c @@ -131,11 +131,35 @@ static const char * ftp_uri_path ( struct ftp_request *ftp ) { return ftp->uri->path; } +/** + * Retrieve FTP user + * + * @v ftp FTP request + * @ret user FTP user + */ +static const char * ftp_user ( struct ftp_request *ftp ) { + static char *ftp_default_user = "anonymous"; + return ftp->uri->user ? ftp->uri->user : ftp_default_user; +} + +/** + * Retrieve FTP password + * + * @v ftp FTP request + * @ret password FTP password + */ +static const char * ftp_password ( struct ftp_request *ftp ) { + static char *ftp_default_password = + "[email protected]"; + return ftp->uri->password ? + ftp->uri->password : ftp_default_password; +} + /** FTP control channel strings */ static struct ftp_control_string ftp_strings[] = { [FTP_CONNECT] = { NULL, NULL }, - [FTP_USER] = { "USER anonymous", NULL }, - [FTP_PASS] = { "PASS [email protected]", NULL }, + [FTP_USER] = { "USER ", ftp_user }, + [FTP_PASS] = { "PASS ", ftp_password }, [FTP_TYPE] = { "TYPE I", NULL }, [FTP_PASV] = { "PASV", NULL }, [FTP_RETR] = { "RETR ", ftp_uri_path }, diff --git a/src/net/tcp/http.c b/src/net/tcp/http.c index a02408a..eda9f8b 100644 --- a/src/net/tcp/http.c +++ b/src/net/tcp/http.c @@ -437,21 +437,8 @@ static void http_step ( struct process *process ) { /* Construct authorisation, if applicable */ if ( user ) { - char *buf = user_pw; - ssize_t remaining = sizeof ( user_pw ); - size_t len; - - /* URI-decode the username and password */ - len = uri_decode ( user, buf, remaining ); - buf += len; - remaining -= len; - *(remaining--, buf++) = ':'; - len = uri_decode ( password, buf, remaining ); - buf += len; - remaining -= len; - assert ( remaining>= 0 ); - - /* Base64-encode the "user:password" string */ + snprintf ( user_pw, user_pw_len + 1 /* NUL */, + "%s:%s", user, password ); base64_encode ( user_pw, user_pw_base64 ); } diff --git a/src/tests/uri_test.c b/src/tests/uri_test.c index 2548760..aa84ace 100644 --- a/src/tests/uri_test.c +++ b/src/tests/uri_test.c @@ -23,6 +23,13 @@ static struct uri_test uri_tests[] = { { "tftp://192.168.0.1/", "/tftpboot/vmlinuz", "tftp://192.168.0.1/tftpboot/vmlinuz" }, #if 0 + { "ftp://:user%[email protected]", "", + "ftp://:user%[email protected]/" }, + { "https://user%40isp.fr:@etherboot.org/wiki/page1", "page2", + "https://user%40isp.fr:@etherboot.org/wiki/page2" }, + { "http://user:gpxe%[email protected]/wiki/page1", + "../page3", + "http://user:gpxe%[email protected]/page3" }, "http://www.etherboot.org/wiki", "mailto:[email protected]", "ftp://joe:[email protected]:8081/hidden/path/to?what=is#this", -- 1.6.5 _________________________________________________________________ Windows Live: Keep your friends up to date with what you do online. http://www.microsoft.com/middleeast/windows/windowslive/see-it-in-action/social-network-basics.aspx?ocid=PID23461::T:WLMTAGL:ON:WL:en-xm:SI_SB_1:092010
uriWithDecodedUserInfo.patch
Description: Binary data
_______________________________________________ gPXE mailing list [email protected] http://etherboot.org/mailman/listinfo/gpxe
