summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristiano F. Haesbaert <haesbaert@cvs.openbsd.org>2012-08-14 20:47:09 +0000
committerChristiano F. Haesbaert <haesbaert@cvs.openbsd.org>2012-08-14 20:47:09 +0000
commit4362286174683064864362c728c7ecfb192d7467 (patch)
treeba20b246ea72266ca2bb2600fef1406a1c5d5362
parent1cdc3c87d0dfff4803f012b69f2234d62226eb7e (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.c53
-rw-r--r--usr.bin/ftp/ftp.114
-rw-r--r--usr.bin/ftp/main.c12
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 "