[gPXE] patch: uri struct with decoded user info. Prevoiusly it had only the encoded user info.

gL2n30Y06arv2 gL2n30Y06arv2 gl2n30y06arv2 at hotmail.com
Thu Dec 17 19:53:43 EST 2009


1. This patch replaces the encoded user info (user:password), that was kept in struct uri, with
   its decoded counterpart.  The decoded version should 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.
2. I couldn't get along with git.  Maybe now, that the patch is kept in the archive of this list,
   I will give git a second chance.  I do hope that this patch truly represents the diff between 
   my branch and the one in the archive. 
3. There are 5 files concerned: include/gpxe/uri.h, core/uri.c, tests/uri_test.c, net/tcp/ftp.c,
   net/tcp/http.c.  I do hope this is an exhaustive list.
4. I used tests/uri_test.c for testing.  I have also tested the ftp method.  I did not test
   the http method in any way, other then get it compiled cleanly.
5. I think the only other file that is concerned is usr/imgmgmt.c.  As far as I can tell, it 
   should not be modified because of my work.

Please apply.

--- old/include/gpxe/uri.h    2009-12-18 02:00:17.000000000 +0100
+++ new/include/gpxe/uri.h    2009-12-18 01:51:17.000000000 +0100
@@ -47,9 +47,9 @@
     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;

--- old/core/uri.c    2009-12-18 02:00:17.000000000 +0100
+++ new/core/uri.c    2009-12-18 02:04:05.000000000 +0100
@@ -45,9 +45,9 @@
     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 @@
         uri->path = path;
     }
 
-    /* Split authority into user[:password] and host[:port] portions */
+    /* Split authority into user[:password] and host[:port]
+       portions.  Decode 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 @@
     /* [user[:password]@]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 @@
 }
 
 /**
- * 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 @@
     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 @@
         } else {
             c = *(encoded_string++);
         }
-        ssnprintf ( buf++, remaining--, "%c", c );
+        *(remaining--, buf++) = c;
     }
+
+    if ( remaining )
+        *buf = '\0';
+
     return ( len - remaining );
 }

--- old/tests/uri_test.c    2009-12-18 02:00:17.000000000 +0100
+++ new/tests/uri_test.c    2009-12-18 01:51:17.000000000 +0100
@@ -14,12 +14,13 @@
 };
 
 static struct uri_test uri_tests[] = {
-    { "http://www.fensystems.co.uk", "",
-      "http://www.fensystems.co.uk/" },
-    { "http://etherboot.org/wiki/page1", "page2",
-      "http://etherboot.org/wiki/page2" },
-    { "http://etherboot.org/wiki/page1", "../page3",
-      "http://etherboot.org/page3" },
+    { "ftp://:user%40isp.fr@www.fensystems.co.uk", "",
+      "ftp://:user%40isp.fr@www.fensystems.co.uk/" },
+    { "https://user:pass%40word@etherboot.org/wiki/page1", "page2",
+      "https://user:pass%40word@etherboot.org/wiki/page2" },
+    { "http://user:gpxe%40etherboot.org@etherboot.org/wiki/page1",
+      "../page3",
+      "http://user:gpxe%40etherboot.org@etherboot.org/page3" },
     { "tftp://192.168.0.1/", "/tftpboot/vmlinuz",
       "tftp://192.168.0.1/tftpboot/vmlinuz" },
 #if 0
@@ -120,6 +121,7 @@
     int rc;
     int overall_rc = 0;
 
+    printf ( "Start uri_test () \n" );
     for ( i = 0 ; i < ( sizeof ( uri_tests ) /
                 sizeof ( uri_tests[0] ) ) ; i++ ) {
         uri_test = &uri_tests[i];
@@ -141,5 +143,6 @@
 
     if ( overall_rc )
         printf ( "URI tests failed: %s\n", strerror ( overall_rc ) );
+    printf ( "End uri_test () \n" );
     return overall_rc;
 }

--- old/net/tcp/ftp.c    2009-12-18 02:00:17.000000000 +0100
+++ new/net/tcp/ftp.c    2009-12-18 01:51:17.000000000 +0100
@@ -122,42 +122,44 @@
 };
 
 /**
- * Retrieve FTP user
+ * Retrieve FTP pathname
  *
- * @v ftp              FTP request
- * @ret user           FTP user
+ * @v ftp        FTP request
+ * @ret path        FTP pathname
  */
-static const char * ftp_uri_user ( struct ftp_request *ftp ) {
-    static char *ftp_default_user = "anonymous";
-    return ftp->uri->user ? ftp->uri->user : ftp_default_user;
+static const char * ftp_uri_path ( struct ftp_request *ftp ) {
+    return ftp->uri->path;
 }
 
 /**
- * Retrieve FTP password
+ * Retrieve FTP user
  *
- * @v ftp              FTP request
- * @ret password       FTP password
+ * @v ftp        FTP request
+ * @ret user        FTP user
  */
-static const char * ftp_uri_password ( struct ftp_request *ftp ) {
-    static char *ftp_default_password = "etherboot at etherboot.org";
-    return ftp->uri->password ? ftp->uri->password : ftp_default_password;
+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 pathname
+ * Retrieve FTP password
  *
  * @v ftp        FTP request
- * @ret path        FTP pathname
+ * @ret password    FTP password
  */
-static const char * ftp_uri_path ( struct ftp_request *ftp ) {
-    return ftp->uri->path;
+static const char * ftp_password ( struct ftp_request *ftp ) {
+    static char *ftp_default_password = 
+                    "etherboot at etherboot.org";
+    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 ", ftp_uri_user },
-    [FTP_PASS]    = { "PASS ", ftp_uri_password },
+    [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 },

--- old/net/tcp/http.c    2009-12-18 02:00:17.000000000 +0100
+++ new/net/tcp/http.c    2009-12-18 01:51:17.000000000 +0100
@@ -437,21 +437,8 @@
 
         /* 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 );
         }
 


 		 	   		  
_________________________________________________________________
Windows Live Hotmail: Your friends can get your Facebook updates, right from Hotmail®.
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_4:092009


More information about the gPXE mailing list