Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.bin/ftp PR/50438: NONAKA Kimihiro: ftp(1): CONNECT metho...
details: https://anonhg.NetBSD.org/src/rev/0bbe2fd307e5
branches: trunk
changeset: 342330:0bbe2fd307e5
user: christos <christos%NetBSD.org@localhost>
date: Wed Dec 16 21:11:47 2015 +0000
description:
PR/50438: NONAKA Kimihiro: ftp(1): CONNECT method support
Please test!
diffstat:
usr.bin/ftp/fetch.c | 302 ++++++++++++++++++++++++++++++++++++++++++---------
1 files changed, 248 insertions(+), 54 deletions(-)
diffs (truncated from 449 to 300 lines):
diff -r 8c643c0b681b -r 0bbe2fd307e5 usr.bin/ftp/fetch.c
--- a/usr.bin/ftp/fetch.c Wed Dec 16 19:46:55 2015 +0000
+++ b/usr.bin/ftp/fetch.c Wed Dec 16 21:11:47 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: fetch.c,v 1.214 2015/12/16 19:17:16 christos Exp $ */
+/* $NetBSD: fetch.c,v 1.215 2015/12/16 21:11:47 christos Exp $ */
/*-
* Copyright (c) 1997-2015 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: fetch.c,v 1.214 2015/12/16 19:17:16 christos Exp $");
+__RCSID("$NetBSD: fetch.c,v 1.215 2015/12/16 21:11:47 christos Exp $");
#endif /* not lint */
/*
@@ -184,6 +184,18 @@
ui->portnum = 0;
}
+#ifdef WITH_SSL
+static void
+copyurlinfo(struct urlinfo *dui, struct urlinfo *sui)
+{
+ dui->host = ftp_strdup(sui->host);
+ dui->port = ftp_strdup(sui->port);
+ dui->path = ftp_strdup(sui->path);
+ dui->utype = sui->utype;
+ dui->portnum = sui->portnum;
+}
+#endif
+
static void
freeurlinfo(struct urlinfo *ui)
{
@@ -721,10 +733,9 @@
}
static int
-print_get(FETCH *fin, int isproxy, const struct urlinfo *ui)
+print_get(FETCH *fin, int hasleading, int isproxy, const struct urlinfo *ui)
{
- int hasleading = 0;
- const char *leading = " (";
+ const char *leading = hasleading ? ", " : " (";
if (isproxy) {
if (verbose) {
@@ -807,66 +818,87 @@
#define C_OK 0
#define C_CLEANUP 1
#define C_IMPROPER 2
+#define C_PROXY 3
+#define C_NOPROXY 4
+static int
+getresponseline(FETCH *fin, char *buf, size_t buflen, int *len)
+{
+ const char *errormsg;
+
+ alarmtimer(quit_time ? quit_time : 60);
+ *len = fetch_getline(fin, buf, buflen, &errormsg);
+ alarmtimer(0);
+ if (*len < 0) {
+ if (*errormsg == '\n')
+ errormsg++;
+ warnx("Receiving HTTP reply: %s", errormsg);
+ return C_CLEANUP;
+ }
+ while (*len > 0 && (ISLWS(buf[*len-1])))
+ buf[--*len] = '\0';
+
+ if (*len)
+ DPRINTF("%s: received `%s'\n", __func__, buf);
+ return C_OK;
+}
+
+static int
+getresponse(FETCH *fin, char **cp, size_t buflen, int *hcode)
+{
+ int len, rv;
+ char *ep, *buf = *cp;
+
+ *hcode = 0;
+ if ((rv = getresponseline(fin, buf, buflen, &len)) != C_OK)
+ return rv;
+
+ /* Determine HTTP response code */
+ *cp = strchr(buf, ' ');
+ if (*cp == NULL)
+ return C_IMPROPER;
+
+ (*cp)++;
+
+ *hcode = strtol(*cp, &ep, 10);
+ if (*ep != '\0' && !isspace((unsigned char)*ep))
+ return C_IMPROPER;
+
+ return C_OK;
+}
static int
negotiate_connection(FETCH *fin, const char *url, const char *penv,
off_t *rangestart, off_t *rangeend, off_t *entitylen,
time_t *mtime, struct authinfo *wauth, struct authinfo *pauth,
- int *rval, int *ischunked)
+ int *rval, int *ischunked, char **auth)
{
int len, hcode, rv;
char buf[FTPBUFLEN], *ep;
- const char *errormsg, *cp, *token;
- char *location, *message, *auth;
+ const char *cp, *token;
+ char *location, *message;
- auth = message = location = NULL;
+ *auth = message = location = NULL;
/* Read the response */
- alarmtimer(quit_time ? quit_time : 60);
- len = fetch_getline(fin, buf, sizeof(buf), &errormsg);
- alarmtimer(0);
- if (len < 0) {
- if (*errormsg == '\n')
- errormsg++;
- warnx("Receiving HTTP reply: %s", errormsg);
+ ep = buf;
+ switch (getresponse(fin, &ep, sizeof(buf), &hcode)) {
+ case C_CLEANUP:
goto cleanup_fetch_url;
+ case C_IMPROPER:
+ goto improper;
+ case C_OK:
+ message = ftp_strdup(ep);
+ break;
}
- while (len > 0 && (ISLWS(buf[len-1])))
- buf[--len] = '\0';
-
- DPRINTF("%s: received `%s'\n", __func__, buf);
-
- /* Determine HTTP response code */
- cp = strchr(buf, ' ');
- if (cp == NULL)
- goto improper;
- else
- cp++;
-
- hcode = strtol(cp, &ep, 10);
- if (*ep != '\0' && !isspace((unsigned char)*ep))
- goto improper;
-
- message = ftp_strdup(cp);
/* Read the rest of the header. */
for (;;) {
- alarmtimer(quit_time ? quit_time : 60);
- len = fetch_getline(fin, buf, sizeof(buf), &errormsg);
- alarmtimer(0);
- if (len < 0) {
- if (*errormsg == '\n')
- errormsg++;
- warnx("Receiving HTTP reply: %s", errormsg);
+ if ((rv = getresponseline(fin, buf, sizeof(buf), &len)) != C_OK)
goto cleanup_fetch_url;
- }
- while (len > 0 && (ISLWS(buf[len-1])))
- buf[--len] = '\0';
if (len == 0)
break;
- DPRINTF("%s: received `%s'\n", __func__, buf);
/*
* Look for some headers
@@ -960,8 +992,8 @@
"scheme `%s'\n", __func__, token);
continue;
}
- FREEPTR(auth);
- auth = ftp_strdup(token);
+ FREEPTR(*auth);
+ *auth = ftp_strdup(token);
DPRINTF("%s: parsed auth as `%s'\n",
__func__, cp);
}
@@ -1021,7 +1053,7 @@
if (verbose || aauth.auth == NULL ||
aauth.user == NULL || aauth.pass == NULL)
fprintf(ttyout, "%s\n", message);
- if (EMPTYSTRING(auth)) {
+ if (EMPTYSTRING(*auth)) {
warnx(
"No authentication challenge provided by server");
goto cleanup_fetch_url;
@@ -1043,7 +1075,7 @@
}
authp = &aauth.auth;
- if (auth_url(auth, authp, &aauth) == 0) {
+ if (auth_url(*auth, authp, &aauth) == 0) {
*rval = fetch_url(url, penv,
pauth->auth, wauth->auth);
memset(*authp, 0, strlen(*authp));
@@ -1069,12 +1101,143 @@
rv = C_IMPROPER;
goto out;
out:
- FREEPTR(auth);
FREEPTR(message);
FREEPTR(location);
return rv;
} /* end of ftp:// or http:// specific setup */
+#ifdef WITH_SSL
+static int
+connectmethod(int s, FETCH *fin, struct urlinfo *oui, struct urlinfo *ui,
+ struct authinfo *wauth, struct authinfo *pauth,
+ char **auth, int *hasleading)
+{
+ void *ssl;
+ int hcode, rv;
+ const char *leading = *hasleading ? ", " : " (";
+ const char *cp;
+ char buf[FTPBUFLEN], *ep;
+ char *message = NULL;
+
+ if (strchr(oui->host, ':')) {
+ char *h, *p;
+
+ /*
+ * strip off IPv6 scope identifier,
+ * since it is local to the node
+ */
+ h = ftp_strdup(oui->host);
+ if (isipv6addr(h) && (p = strchr(h, '%')) != NULL) {
+ *p = '\0';
+ }
+ fetch_printf(fin, "CONNECT [%s]:%s HTTP/1.1\r\n",
+ h, oui->port);
+ fetch_printf(fin, "Host: [%s]:%s\r\n", h, oui->port);
+ free(h);
+ } else {
+ fetch_printf(fin, "CONNECT %s:%s HTTP/1.1\r\n",
+ oui->host, oui->port);
+ fetch_printf(fin, "Host: %s:%s\r\n",
+ oui->host, oui->port);
+ }
+
+ print_agent(fin);
+ *hasleading = print_proxy(fin, leading, wauth->auth, pauth->auth);
+
+ if (verbose) {
+ leading = ", ";
+ (*hasleading)++;
+ } else {
+ leading = " (";
+ *hasleading = 0;
+ }
+ if (pauth->auth) {
+ if (verbose) {
+ fprintf(ttyout, "%swith proxy authorization" , leading);
+ leading = ", ";
+ (*hasleading)++;
+ }
+ fetch_printf(fin, "Proxy-Authorization: %s\r\n", pauth->auth);
+ }
+
+ if (verbose && *hasleading)
+ fputs(")\n", ttyout);
+ leading = " (";
+ *hasleading = 0;
+
+ fetch_printf(fin, "\r\n");
+ if (fetch_flush(fin) == EOF) {
+ warn("Writing HTTP request");
+ alarmtimer(0);
+ goto cleanup_fetch_url;
+ }
+ alarmtimer(0);
+
+ /* Read the response */
+ ep = buf;
+ switch (getresponse(fin, &ep, sizeof(buf), &hcode)) {
+ case C_CLEANUP:
+ goto cleanup_fetch_url;
+ case C_IMPROPER:
+ goto improper;
+ case C_OK:
+ message = ftp_strdup(ep);
+ break;
+ }
+
+ for (;;) {
+ int len;
+ if (getresponseline(fin, buf, sizeof(buf), &len) != C_OK)
+ goto cleanup_fetch_url;
+ if (len == 0)
Home |
Main Index |
Thread Index |
Old Index