Squid-2.2.STABLE4: FTP password URLs
Changes Squid to preserve any password which was entered in the URL
when BASE HREF is used to "correct" directory URLs without a trailing /.
This patch also fixes a minor issue with URL encoding of filenames.
Squid only encoded those characters classified as "unsafe", not those
classified as "reserved". What this means is for example if a directory
contains a file with a name including "/", ";" or other reserved characters
then Squid (or actually the browser, but Squid gets the blaim) would be
confused.
Index: squid/include/util.h
diff -u squid/include/util.h:1.1.1.13 squid/include/util.h:1.1.1.13.22.1
--- squid/include/util.h:1.1.1.13 Sun Feb 14 23:29:40 1999
+++ squid/include/util.h Tue Jul 13 00:46:42 1999
@@ -80,6 +80,7 @@
/* rfc1738.c */
extern char *rfc1738_escape(const char *);
+extern char *rfc1738_escape_part(const char *);
extern void rfc1738_unescape(char *);
#if XMALLOC_STATISTICS
Index: squid/lib/rfc1738.c
diff -u squid/lib/rfc1738.c:1.1.1.9 squid/lib/rfc1738.c:1.1.1.9.2.1
--- squid/lib/rfc1738.c:1.1.1.9 Tue Jul 13 00:09:15 1999
+++ squid/lib/rfc1738.c Tue Jul 13 00:46:49 1999
@@ -68,12 +68,23 @@
(char) 0x20 /* space */
};
+static char rfc1738_reserved_chars[] =
+{
+ (char) 0x3b, /* ; */
+ (char) 0x2f, /* / */
+ (char) 0x3f, /* ? */
+ (char) 0x3a, /* : */
+ (char) 0x40, /* @ */
+ (char) 0x3d, /* = */
+ (char) 0x26 /* & */
+};
+
/*
* rfc1738_escape - Returns a static buffer contains the RFC 1738
* compliant, escaped version of the given url.
*/
-char *
-rfc1738_escape(const char *url)
+static char *
+rfc1738_do_escape(const char *url, int encode_reserved)
{
static char *buf;
static size_t bufsize = 0;
@@ -96,6 +107,13 @@
break;
}
}
+ /* RFC 1738 defines these chars as reserved */
+ for (i = 0; i < sizeof(rfc1738_reserved_chars) && encode_reserved ; i++) {
+ if (*p == rfc1738_reserved_chars[i]) {
+ do_escape = 1;
+ break;
+ }
+ }
/* RFC 1738 says any control chars (0x00-0x1F) are encoded */
if ((unsigned char) *p <= (unsigned char) 0x1F) {
do_escape = 1;
@@ -122,6 +140,26 @@
}
*q = '\0';
return (buf);
+}
+
+/*
+ * rfc1738_escape - Returns a static buffer contains the RFC 1738
+ * compliant, escaped version of the given url.
+ */
+char *
+rfc1738_escape(const char *url)
+{
+ return rfc1738_do_escape(url, 0);
+}
+
+/*
+ * rfc1738_escape_part - Returns a static buffer contains the RFC 1738
+ * compliant, escaped version of the given url segment.
+ */
+char *
+rfc1738_escape_part(const char *url)
+{
+ return rfc1738_do_escape(url, 1);
}
/*
Index: squid/src/ftp.c
diff -u squid/src/ftp.c:1.1.1.35.2.3 squid/src/ftp.c:1.1.1.35.2.5
--- squid/src/ftp.c:1.1.1.35.2.3 Tue Jul 13 00:24:51 1999
+++ squid/src/ftp.c Tue Jul 13 00:47:52 1999
@@ -89,6 +89,7 @@
char *reply_hdr;
int reply_hdr_state;
char *title_url;
+ char *base_href;
int conn_att;
int login_att;
ftp_state_t state;
@@ -297,6 +298,7 @@
safe_free(ftpState->old_reply);
safe_free(ftpState->old_filepath);
safe_free(ftpState->title_url);
+ safe_free(ftpState->base_href);
safe_free(ftpState->filepath);
safe_free(ftpState->data.host);
if (ftpState->data.fd > -1) {
@@ -356,7 +358,7 @@
storeAppendPrintf(e, "\n");
if (ftpState->flags.use_base)
storeAppendPrintf(e, "
\n");
@@ -692,7 +694,7 @@
}
}
/* {icon} {text} . . . {date}{size}{chdir}{view}{download}{link}\n */
- xstrncpy(href, rfc1738_escape(parts->name), 2048);
+ xstrncpy(href, rfc1738_escape_part(parts->name), 2048);
xstrncpy(text, parts->showname, 2048);
switch (parts->type) {
case 'd':
@@ -991,6 +993,21 @@
if (request->port != urlDefaultPort(PROTO_FTP))
snprintf(&t[strlen(t)], len - strlen(t), ":%d", request->port);
strcat(t, strBuf(request->urlpath));
+ t = ftpState->base_href = xcalloc(len, 1);
+ strcat(t, "ftp://");
+ if (strcmp(ftpState->user, "anonymous")) {
+ strcat(t, rfc1738_escape_part(ftpState->user));
+ if (ftpState->password_url) {
+ strcat(t, ":");
+ strcat(t, rfc1738_escape_part(ftpState->password));
+ }
+ strcat(t, "@");
+ }
+ strcat(t, request->host);
+ if (request->port != urlDefaultPort(PROTO_FTP))
+ snprintf(&t[strlen(t)], len - strlen(t), ":%d", request->port);
+ strcat(t, strBuf(request->urlpath));
+ strcat(t, "/");
}
void
Index: squid/src/gopher.c
diff -u squid/src/gopher.c:1.1.1.20 squid/src/gopher.c:1.1.1.20.22.1
--- squid/src/gopher.c:1.1.1.20 Sun Feb 14 23:30:00 1999
+++ squid/src/gopher.c Tue Jul 13 00:46:49 1999
@@ -430,7 +430,7 @@
port[0] = 0; /* 0 means none */
}
/* escape a selector here */
- escaped_selector = xstrdup(rfc1738_escape(selector));
+ escaped_selector = xstrdup(rfc1738_escape_part(selector));
switch (gtype) {
case GOPHER_DIRECTORY: