From e381a13db6cbacad54c28b555016375541d6cfab Mon Sep 17 00:00:00 2001 From: wessels <> Date: Tue, 16 Jul 1996 05:57:49 +0000 Subject: [PATCH] Here is my patch to squid-1.1.alpha4 that adds the functionality to use basic authentication for user&passwd information on non-anonymous ftp. If it receives a non-anonymus ftp request without a password, then Squid responds with 401 Unauthorized with WWW-Authenticate: Basic realm="ftp " Notes: 1. This is normal authentication, not proxy authentication. The authentication is for the end server and not the proxy (i.e it is a translation of the ftp login procedure to HTTP). 2. The realm is always local to the server (string), and therefore only the user information is nessecary to make it unique. I added "ftp " minimize the risk of collision with a identical realm for another protocol (i.e. HTTP) on the same server. 3. This implementation is not fully complete. It needs some further work on expiration of generated 401 messages, but this doesn't really matter (they are expired immediately anyway). Maybe they should be negatively cached, but most browsers cache this internally anyway (to avoid unnessesary 401 messages). /Henrik --- src/errorpage.cc | 39 ++++++++++++++++++++++++++++++++++++++- src/ftp.cc | 44 ++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 80 insertions(+), 3 deletions(-) diff --git a/src/errorpage.cc b/src/errorpage.cc index a06cba7c69..49b36dc1d3 100644 --- a/src/errorpage.cc +++ b/src/errorpage.cc @@ -1,5 +1,5 @@ /* - * $Id: errorpage.cc,v 1.23 1996/07/15 23:12:36 wessels Exp $ + * $Id: errorpage.cc,v 1.24 1996/07/15 23:57:49 wessels Exp $ * * DEBUG: section 4 Error Generation * AUTHOR: Duane Wessels @@ -127,6 +127,8 @@ void errorInitialize() meta_data.misc += MAX_URL * 4; tbuf = xmalloc(MAX_URL * 3); meta_data.misc += MAX_URL * 3; + auth_msg = xmalloc(MAX_URL * 3); + meta_data.misc += MAX_URL * 3; } void squid_error_entry(entry, type, msg) @@ -256,3 +258,38 @@ Generated by %s/%s@%s\n\ getMyHostname()); return tmp_error_buf; } + +char *authorization_needed_msg(request, realm) + request_t *request; + char *realm; +{ + sprintf(auth_msg, "Authorization needed\n\ +Sorry, you have to authorize yourself to request\n\ +
    ftp://%s@%s%s
\n\ +from this cache. Please check with the cache administrator if you\n\ +believe this is incorrect.\n\ +
\n\ +
\n\ +Generated by %s/%s@%s\n\ +
\n\ +\n", + request->login, + request->host, + request->urlpath, + appname, + version_string, + getMyHostname()); + + mk_mime_hdr(tbuf, + (time_t) getNegativeTTL(), + strlen(auth_msg), + 0, + "text/html"); + sprintf(tmp_error_buf, "HTTP/1.0 401 Unauthorized\r\n\ +%s\ +WWW-Authenticate: Basic realm=\"%s\"\r\n\ +\r\n\ +%s", + tbuf, realm, auth_msg); + return tmp_error_buf; +} diff --git a/src/ftp.cc b/src/ftp.cc index fe6739cec9..1afa78343e 100644 --- a/src/ftp.cc +++ b/src/ftp.cc @@ -1,5 +1,5 @@ /* - * $Id: ftp.cc,v 1.41 1996/07/15 23:13:31 wessels Exp $ + * $Id: ftp.cc,v 1.42 1996/07/15 23:57:51 wessels Exp $ * * DEBUG: section 9 File Transfer Protocol (FTP) * AUTHOR: Harvest Derived @@ -127,6 +127,7 @@ typedef struct _Ftpdata { * expires */ int got_marker; /* denotes end of successful request */ int reply_hdr_state; + int authenticated; /* This ftp request is authenticated */ } FtpData; /* Local functions */ @@ -143,6 +144,9 @@ void ftpSendRequest _PARAMS((int fd, FtpData * data)); void ftpConnInProgress _PARAMS((int fd, FtpData * data)); void ftpServerClose _PARAMS((void)); +/* External functions */ +extern char *base64_decode _PARAMS((char *coded)); + static int ftpStateFree(fd, ftpState) int fd; FtpData *ftpState; @@ -526,6 +530,9 @@ void ftpSendRequest(fd, data) sprintf(tbuf, "-H %s ", s); strcat(buf, tbuf); } + if (data->authenticated) { + strcat(buf, "-a "); + } strcat(buf, "-h "); /* httpify */ strcat(buf, "- "); /* stdout */ strcat(buf, data->request->host); @@ -585,7 +592,13 @@ int ftpStart(unusedfd, url, request, entry) request_t *request; StoreEntry *entry; { + static char realm[8192]; FtpData *data = NULL; + char *req_hdr = entry->mem_obj->mime_hdr; + char *auth_hdr; + char *response; + char *auth; + int status; debug(9, 3, "FtpStart: FD %d \n", unusedfd, url); @@ -594,8 +607,35 @@ int ftpStart(unusedfd, url, request, entry) storeLockObject(data->entry = entry, NULL, NULL); data->request = requestLink(request); + auth_hdr = mime_get_header(req_hdr, "Authorization"); + auth = NULL; + if (auth_hdr) { + if (strcasecmp(strtok(auth_hdr, " \t"), "Basic") == 0) { + auth = base64_decode(strtok(NULL, " \t")); + } + } /* Parse login info. */ - ftp_login_parser(request->login, data); + if (auth) { + ftp_login_parser(auth, data); + data->authenticated = 1; + } else { + ftp_login_parser(request->login, data); + if (*data->user && !*data->password) { + /* This request is not fully authenticated */ + if (request->port == 21) { + sprintf(realm, "ftp %s", data->user); + } else { + sprintf(realm, "ftp %s port %d", + data->user, request->port); + } + response = authorization_needed_msg(request, realm); + storeAppend(entry, response, strlen(response)); + httpParseHeaders(response, entry->mem_obj->reply); + storeComplete(entry); + ftpStateFree(-1, data); + return COMM_OK; + } + } debug(9, 5, "FtpStart: FD %d, host=%s, path=%s, user=%s, passwd=%s\n", unusedfd, data->request->host, data->request->urlpath, -- 2.47.3