diff options
author | Christiano F. Haesbaert <haesbaert@cvs.openbsd.org> | 2012-08-14 20:47:09 +0000 |
---|---|---|
committer | Christiano F. Haesbaert <haesbaert@cvs.openbsd.org> | 2012-08-14 20:47:09 +0000 |
commit | 4362286174683064864362c728c7ecfb192d7467 (patch) | |
tree | ba20b246ea72266ca2bb2600fef1406a1c5d5362 | |
parent | 1cdc3c87d0dfff4803f012b69f2234d62226eb7e (diff) |
Add support for basic HTTP authentication as described on RFC 2617 and
RFC 3986. This allows the following idiom in ftp:
ftp http[s]://user:pass@host/file
With some pointers from halex a lot of testing and feedback from lteo,
thanks a lot.
ok lteo@
-rw-r--r-- | usr.bin/ftp/fetch.c | 53 | ||||
-rw-r--r-- | usr.bin/ftp/ftp.1 | 14 | ||||
-rw-r--r-- | usr.bin/ftp/main.c | 12 |
3 files changed, 56 insertions, 23 deletions
diff --git a/usr.bin/ftp/fetch.c b/usr.bin/ftp/fetch.c index a9cb49db78c..81cf02f8d76 100644 --- a/usr.bin/ftp/fetch.c +++ b/usr.bin/ftp/fetch.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fetch.c,v 1.105 2012/04/30 13:41:26 haesbaert Exp $ */ +/* $OpenBSD: fetch.c,v 1.106 2012/08/14 20:47:08 haesbaert Exp $ */ /* $NetBSD: fetch.c,v 1.14 1997/08/18 10:20:20 lukem Exp $ */ /*- @@ -177,7 +177,7 @@ url_get(const char *origline, const char *proxyenv, const char *outfile) { 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 *proxyenv, const char *outfile) 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; @@ -253,6 +253,29 @@ url_get(const char *origline, const char *proxyenv, const char *outfile) } noslash: + +#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) + 5) * 4 / 3; + *p = 0; /* Kill @ */ + if ((auth = malloc(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 */ + if (outfile) savefile = outfile; else { @@ -460,8 +483,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 +662,19 @@ 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); + auth = NULL; + } 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 @@ -953,6 +981,7 @@ cleanup_url_get: SSL_free(ssl); } free(full_host); + free(auth); #endif /* !SMALL */ if (fin != NULL) fclose(fin); diff --git a/usr.bin/ftp/ftp.1 b/usr.bin/ftp/ftp.1 index 1c2e56e2a94..16b9c302bd5 100644 --- a/usr.bin/ftp/ftp.1 +++ b/usr.bin/ftp/ftp.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ftp.1,v 1.82 2012/04/30 13:41:26 haesbaert Exp $ +.\" $OpenBSD: ftp.1,v 1.83 2012/08/14 20:47:08 haesbaert Exp $ .\" $NetBSD: ftp.1,v 1.22 1997/08/18 10:20:22 lukem Exp $ .\" .\" Copyright (c) 1985, 1989, 1990, 1993 @@ -30,7 +30,7 @@ .\" .\" @(#)ftp.1 8.3 (Berkeley) 10/9/94 .\" -.Dd $Mdocdate: April 30 2012 $ +.Dd $Mdocdate: August 14 2012 $ .Dt FTP 1 .Os .Sh NAME @@ -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 diff --git a/usr.bin/ftp/main.c b/usr.bin/ftp/main.c index 4674fa55e95..01e4e3343de 100644 --- a/usr.bin/ftp/main.c +++ b/usr.bin/ftp/main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: main.c,v 1.83 2012/05/19 02:04:22 lteo Exp $ */ +/* $OpenBSD: main.c,v 1.84 2012/08/14 20:47:08 haesbaert Exp $ */ /* $NetBSD: main.c,v 1.24 1997/08/18 10:20:26 lukem Exp $ */ /* @@ -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 " |