On 08/13/12 17:37, Christiano F. Haesbaert wrote:
On Mon, Aug 13, 2012 at 04:33:40PM +0200, Christiano F. Haesbaert wrote:
I think I've hunt this down

http://tools.ietf.org/html/rfc3986#section-3.3

If you follow the BNF for path, you have.

path -> path->absolute -> segment-nz -> 1*pchar -> \
        unreserved / pct-encoded / sub-delims / ':' / '@'.

So it seems "everything" is allowed on path, I'll fix the diff.


So this addresses halex points, I tested on urls with @ and :, works
fine. I still calloc and I use an extra byte since the auth string can
be displayed on debug.

Again, why calloc? IIRC b64_ntop() adds a trailing null.


Index: fetch.c
===================================================================
RCS file: /cvs/src/usr.bin/ftp/fetch.c,v
retrieving revision 1.105
diff -d -u -p -r1.105 fetch.c
--- fetch.c     30 Apr 2012 13:41:26 -0000      1.105
+++ fetch.c     13 Aug 2012 15:33:29 -0000
@@ -177,7 +177,7 @@ url_get(const char *origline, const char
  {
        char pbuf[NI_MAXSERV], hbuf[NI_MAXHOST], *cp, *portnum, *path, ststr[4];
        char *hosttail, *cause = "unknown", *newline, *host, *port, *buf = NULL;
-       char *epath, *redirurl, *loctail;
+       char *epath, *redirurl, *loctail, *h, *p;
        int error, i, isftpurl = 0, isfileurl = 0, isredirect = 0, rval = -1;
        struct addrinfo hints, *res0, *res, *ares = NULL;
        const char * volatile savefile;
@@ -191,7 +191,7 @@ url_get(const char *origline, const char
        size_t len, wlen;
  #ifndef SMALL
        char *sslpath = NULL, *sslhost = NULL;
-       char *locbase, *full_host = NULL;
+       char *locbase, *full_host = NULL, *auth = NULL;
        const char *scheme;
        int ishttpsurl = 0;
        SSL_CTX *ssl_ctx = NULL;
@@ -250,6 +250,28 @@ url_get(const char *origline, const char
                        warnx("No filename after host (use -o): %s", origline);
                        goto cleanup_url_get;
                }
+#ifndef SMALL
+               /*
+                * Look for auth header in host, since now host does not
+                * contain the path. Basic auth from RFC 2617, valid
+                * characters for path are in RFC 3986 section 3.3.
+                */
+               if (proxyenv == NULL &&
+                   (!strcmp(scheme, HTTP_URL) || !strcmp(scheme, HTTPS_URL))) {
+                       if ((p = strchr(host, '@')) != NULL) {
+                               size_t authlen = (strlen(host) + 2) * 4 / 3 + 1;
+
+                               *p = 0; /* Kill @ */
+                               if ((auth = calloc(1, authlen)) == NULL)
+                                       err(1, "Can't allocate memory for "
+                                           "authorization");
+                               if (b64_ntop(host, strlen(host),
+                                   auth, authlen) == -1)
+                                       errx(1, "error in base64 encoding");
+                               host = p + 1;
+                       }
+               }
+#endif /* SMALL */
        }

  noslash:
@@ -460,8 +482,9 @@ noslash:
                if ((full_host = strdup(host)) == NULL)
                        errx(1, "Cannot allocate memory for hostname");
        if (debug)
-               fprintf(ttyout, "host %s, port %s, path %s, save as %s.\n",
-                   host, portnum, path, savefile);
+               fprintf(ttyout, "host %s, port %s, path %s, "
+                   "save as %s, auth %s.\n",
+                   host, portnum, path, savefile, auth);
  #endif /* !SMALL */

        memset(&hints, 0, sizeof(hints));
@@ -638,15 +661,18 @@ again:
                        else
                                restart_point = 0;
                }
-#endif /* !SMALL */
+               if (auth) {
+                       ftp_printf(fin, ssl,
+                           "GET /%s %s\r\nAuthorization: Basic %s\r\nHost: ",
+                           epath, restart_point ?
+                           "HTTP/1.1\r\nConnection: close" : "HTTP/1.0",
+                           auth);
+                       free(auth);
+               } else
+#endif /* SMALL */
                ftp_printf(fin, ssl, "GET /%s %s\r\nHost: ", epath,
-#ifndef SMALL
-                       restart_point ? "HTTP/1.1\r\nConnection: close" :
-#endif /* !SMALL */
-                       "HTTP/1.0");
+                   "HTTP/1.0");
                if (strchr(host, ':')) {
-                       char *h, *p;
-
                        /*
                         * strip off scoped address portion, since it's
                         * local to node
Index: ftp.1
===================================================================
RCS file: /cvs/src/usr.bin/ftp/ftp.1,v
retrieving revision 1.82
diff -d -u -p -r1.82 ftp.1
--- ftp.1       30 Apr 2012 13:41:26 -0000      1.82
+++ ftp.1       11 Aug 2012 20:08:00 -0000
@@ -61,7 +61,8 @@
  .Op Fl o Ar output
  .Op Fl s Ar srcaddr
  .Sm off
-.No http:// Ar host Oo : Ar port
+.No http:// Oo Ar user : password No @
+.Oc Ar host Oo : Ar port
  .Oc No / Ar file
  .Sm on
  .Ar ...
@@ -71,7 +72,8 @@
  .Op Fl o Ar output
  .Op Fl s Ar srcaddr
  .Sm off
-.No https:// Ar host Oo : Ar port
+.No https:// Oo Ar user : password No @
+.Oc Ar host Oo : Ar port
  .Oc No / Ar file
  .Sm on
  .Ar ...
@@ -1278,12 +1280,12 @@ isn't defined, log in as
  .Ar user
  with a password of
  .Ar password .
-.It http://host[:port]/file
+.It http://[user:password@]host[:port]/file
  An HTTP URL, retrieved using the HTTP protocol.
  If
  .Ev http_proxy
  is defined, it is used as a URL to an HTTP proxy server.
-.It https://host[:port]/file
+.It https://[user:password@]host[:port]/file
  An HTTPS URL, retrieved using the HTTPS protocol.
  If
  .Ev http_proxy
Index: main.c
===================================================================
RCS file: /cvs/src/usr.bin/ftp/main.c,v
retrieving revision 1.83
diff -d -u -p -r1.83 main.c
--- main.c      19 May 2012 02:04:22 -0000      1.83
+++ main.c      11 Aug 2012 20:08:00 -0000
@@ -775,12 +775,14 @@ usage(void)
  #endif /* !SMALL */
            "[-o output] "
  #ifndef SMALL
-           "[-s srcaddr] "
+           "[-s srcaddr]\n"
+           "           "
  #endif /* !SMALL */
-           "http://host[:port]/file ...\n"
+           "http://[user:password@]host[:port]/file ...\n"
  #ifndef SMALL
-           "       %s [-C] [-c cookie] [-o output] [-s srcaddr] "
-           "https://host[:port]/file\n";
+           "       %s [-C] [-c cookie] [-o output] [-s srcaddr]\n"
+           "           "
+           "https://[user:password@]host[:port]/file\n";
            "           ...\n"
  #endif /* !SMALL */
            "       %s "

Reply via email to