commit 681c3b11f91887fc2a0b2910eb82f8e25d2bf143
parent d339643a30bbd58a5863ae285216b05f31a78d9d
Author: ukai <ukai>
Date: Fri, 16 Apr 2004 18:47:18 +0000
[w3m-dev 04064] authentication
closes: Bug#:244029: w3m: HTTP basic authentication annoyance
* fm.h (auth_cookie): deleted
* proto.h (find_auth_cookie): deleted
(add_auth_cookie): deleted
(add_auth_user_passwd): added
(invalidate_auth_user_passwd): added
* etc.c (auth_pass): add bad flag
delete file
(dir_under): deleted
(add_auth_pass_entry): add override flag
no need to check file
(find_auth_pass_entry): delete file
check bad flag
check uname
(find_auth_user_passwd): find by pu->user
(add_auth_user_passwd): added
(invalidate_auth_user_passwd): added
(parsePasswd): add no override
ignore file
(find_auth): deleted
(find_auth_cookie): deleted
(dump_auth_cookie): deleted
(add_auth_cookie): deleted
* file.c (getAuthCookie): add *uname, *pwd
rewrite
(loadGeneralFile): delete ss, add uname, pwd
use add_auth_user_passwd instead of add_auth_cookie
* url.c (HTTPrequest): don't authorization here
it should be done in getAuthCookie in loadGeneralFile
through extra_header
* ftp.c (openFTPStream): add uname
use find_auth_user_passwd instead of find_auth_cookie
use add_auth_user_passwd instead of add_auth_cookie
Diffstat:
M | ChangeLog | | | 37 | +++++++++++++++++++++++++++++++++++++ |
M | etc.c | | | 163 | +++++++++++++++++++++++++++++++------------------------------------------------ |
M | file.c | | | 148 | ++++++++++++++++++++++++++++++++++++++++++------------------------------------- |
M | fm.h | | | 9 | --------- |
M | ftp.c | | | 7 | ++++--- |
M | proto.h | | | 7 | ++++--- |
M | url.c | | | 27 | --------------------------- |
7 files changed, 186 insertions(+), 212 deletions(-)
diff --git a/ChangeLog b/ChangeLog
@@ -1,3 +1,40 @@
+2004-04-17 Fumitoshi UKAI <ukai@debian.or.jp>
+
+ * [w3m-dev 04064] authentication
+ closes: Bug#:244029: w3m: HTTP basic authentication annoyance
+ * fm.h (auth_cookie): deleted
+ * proto.h (find_auth_cookie): deleted
+ (add_auth_cookie): deleted
+ (add_auth_user_passwd): added
+ (invalidate_auth_user_passwd): added
+ * etc.c (auth_pass): add bad flag
+ delete file
+ (dir_under): deleted
+ (add_auth_pass_entry): add override flag
+ no need to check file
+ (find_auth_pass_entry): delete file
+ check bad flag
+ check uname
+ (find_auth_user_passwd): find by pu->user
+ (add_auth_user_passwd): added
+ (invalidate_auth_user_passwd): added
+ (parsePasswd): add no override
+ ignore file
+ (find_auth): deleted
+ (find_auth_cookie): deleted
+ (dump_auth_cookie): deleted
+ (add_auth_cookie): deleted
+ * file.c (getAuthCookie): add *uname, *pwd
+ rewrite
+ (loadGeneralFile): delete ss, add uname, pwd
+ use add_auth_user_passwd instead of add_auth_cookie
+ * url.c (HTTPrequest): don't authorization here
+ it should be done in getAuthCookie in loadGeneralFile
+ through extra_header
+ * ftp.c (openFTPStream): add uname
+ use find_auth_user_passwd instead of find_auth_cookie
+ use add_auth_user_passwd instead of add_auth_cookie
+
2004-04-10 SAKAI Kiyotaka <ksakai@kso.netwk.ntt-at.co.jp>
* [w3m-dev 04063] about Makefile
diff --git a/etc.c b/etc.c
@@ -20,10 +20,11 @@
#endif /* __WATT32__ */
struct auth_pass {
+ int bad;
int is_proxy;
Str host;
int port;
- Str file;
+/* Str file; */
Str realm;
Str uname;
Str pwd;
@@ -918,48 +919,55 @@ correct_irrtag(int status)
return tmp;
}
-static int
-dir_under(const char *x, const char *y)
-{
- size_t len = strlen(x);
- if (strcmp(x, y) == 0)
- return 1;
- return x[len - 1] == '/'
- && strlen(y) >= len
- && y[len - 1] == '/' && strncasecmp(x, y, len) == 0;
-}
-
+/*
+ * RFC2617: 1.2 Access Authentication Framework
+ *
+ * The realm value (case-sensitive), in combination with the canonical root
+ * URL (the absoluteURI for the server whose abs_path is empty; see section
+ * 5.1.2 of RFC2616 ) of the server being accessed, defines the protection
+ * space. These realms allow the protected resources on a server to be
+ * partitioned into a set of protection spaces, each with its own
+ * authentication scheme and/or authorization database.
+ *
+ */
static void
-add_auth_pass_entry(const struct auth_pass *ent, int netrc)
+add_auth_pass_entry(const struct auth_pass *ent, int netrc, int override)
{
if ((ent->host || netrc) /* netrc accept default (host == NULL) */
- &&(ent->is_proxy || ent->file || ent->realm || netrc)
+ &&(ent->is_proxy || ent->realm || netrc)
&& ent->uname && ent->pwd) {
struct auth_pass *newent = New(struct auth_pass);
memcpy(newent, ent, sizeof(struct auth_pass));
- if (passwords == NULL)
+ if (override) {
+ newent->next = passwords;
passwords = newent;
- else if (passwords->next == NULL)
- passwords->next = newent;
+ }
else {
- struct auth_pass *ep = passwords;
- for (; ep->next; ep = ep->next) ;
- ep->next = newent;
+ if (passwords == NULL)
+ passwords = newent;
+ else if (passwords->next == NULL)
+ passwords->next = newent;
+ else {
+ struct auth_pass *ep = passwords;
+ for (; ep->next; ep = ep->next) ;
+ ep->next = newent;
+ }
}
}
/* ignore invalid entries */
}
static struct auth_pass *
-find_auth_pass_entry(char *host, int port, char *file, char *realm,
+find_auth_pass_entry(char *host, int port, char *realm, char *uname,
int is_proxy)
{
struct auth_pass *ent;
for (ent = passwords; ent != NULL; ent = ent->next) {
if (ent->is_proxy == is_proxy
+ && (ent->bad != TRUE)
&& (!ent->host || !Strcasecmp_charp(ent->host, host))
&& (!ent->port || ent->port == port)
- && (!ent->file || !file || dir_under(ent->file->ptr, file))
+ && (!ent->uname || !uname || !Strcmp_charp(ent->uname, uname))
&& (!ent->realm || !realm || !Strcmp_charp(ent->realm, realm))
)
return ent;
@@ -978,7 +986,7 @@ find_auth_user_passwd(ParsedURL *pu, char *realm,
*pwd = Strnew_charp(pu->pass);
return 1;
}
- ent = find_auth_pass_entry(pu->host, pu->port, pu->file, realm, is_proxy);
+ ent = find_auth_pass_entry(pu->host, pu->port, realm, pu->user, is_proxy);
if (ent) {
*uname = ent->uname;
*pwd = ent->pwd;
@@ -987,13 +995,41 @@ find_auth_user_passwd(ParsedURL *pu, char *realm,
return 0;
}
+void
+add_auth_user_passwd(ParsedURL *pu, char *realm, Str uname, Str pwd,
+ int is_proxy)
+{
+ struct auth_pass ent;
+ memset(&ent, 0, sizeof(ent));
+
+ ent.is_proxy = is_proxy;
+ ent.host = Strnew_charp(pu->host);
+ ent.port = pu->port;
+ ent.realm = Strnew_charp(realm);
+ ent.uname = uname;
+ ent.pwd = pwd;
+ add_auth_pass_entry(&ent, 0, 1);
+}
+
+void
+invalidate_auth_user_passwd(ParsedURL *pu, char *realm, Str uname, Str pwd,
+ int is_proxy)
+{
+ struct auth_pass *ent;
+ ent = find_auth_pass_entry(pu->host, pu->port, realm, NULL, is_proxy);
+ if (ent) {
+ ent->bad = TRUE;
+ }
+ return;
+}
+
/* passwd */
/*
* machine <host>
* host <host>
* port <port>
* proxy
- * path <file>
+ * path <file> ; not used
* realm <realm>
* login <login>
* passwd <passwd>
@@ -1045,7 +1081,7 @@ parsePasswd(FILE * fp, int netrc)
if (!strcmp(p, "machine") || !strcmp(p, "host")
|| (netrc && !strcmp(p, "default"))) {
- add_auth_pass_entry(&ent, netrc);
+ add_auth_pass_entry(&ent, netrc, 0);
bzero(&ent, sizeof(struct auth_pass));
if (netrc)
ent.port = 21; /* XXX: getservbyname("ftp"); ? */
@@ -1067,7 +1103,7 @@ parsePasswd(FILE * fp, int netrc)
}
else if (!netrc && !strcmp(p, "path")) {
line = next_token(arg);
- ent.file = arg;
+ /* ent.file = arg; */
}
else if (!netrc && !strcmp(p, "realm")) {
/* XXX: rest of line becomes arg for realm */
@@ -1098,7 +1134,7 @@ parsePasswd(FILE * fp, int netrc)
line = NULL;
}
}
- add_auth_pass_entry(&ent, netrc);
+ add_auth_pass_entry(&ent, netrc, 0);
}
/* FIXME: gettextize? */
@@ -1164,79 +1200,6 @@ loadPasswd(void)
return;
}
-/* authentication */
-struct auth_cookie *
-find_auth(char *host, int port, char *file, char *realm)
-{
- struct auth_cookie *p;
-
- for (p = Auth_cookie; p != NULL; p = p->next) {
- if (!Strcasecmp_charp(p->host, host) &&
- p->port == port &&
- ((realm && !Strcasecmp_charp(p->realm, realm)) ||
- (p->file && file && dir_under(p->file->ptr, file))))
- return p;
- }
- return NULL;
-}
-
-Str
-find_auth_cookie(char *host, int port, char *file, char *realm)
-{
- struct auth_cookie *p = find_auth(host, port, file, realm);
- if (p)
- return p->cookie;
- return NULL;
-}
-
-#ifdef AUTH_DEBUG
-static void
-dump_auth_cookie(void)
-{
- if (w3m_debug) {
- FILE *ff = fopen("zzzauth", "a");
- struct auth_cookie *p;
-
- for (p = Auth_cookie; p != NULL; p = p->next) {
- Str tmp = Sprintf("%s, %d, %s, %s\n", p->host->ptr, p->port,
- p->file ? (const char *)p->file->ptr : "NULL",
- p->realm ? (const char *)p->realm->ptr : "NULL");
- fwrite(tmp->ptr, sizeof(char), tmp->length, ff);
- }
- fputc('\n', ff);
- fclose(ff);
- }
-}
-#endif
-
-void
-add_auth_cookie(char *host, int port, char *file, char *realm, Str cookie)
-{
- struct auth_cookie *p;
-
- p = find_auth(host, port, file, realm);
- if (p && (!p->file || !Strcasecmp_charp(p->file, file))) {
- if (realm && p->realm == NULL)
- p->realm = Strnew_charp(realm);
- p->cookie = cookie;
-#ifdef AUTH_DEBUG
- dump_auth_cookie();
-#endif
- return;
- }
- p = New(struct auth_cookie);
- p->host = Strnew_charp(host);
- p->port = port;
- p->file = file ? Strnew_charp(file) : NULL;
- p->realm = Strnew_charp(realm);
- p->cookie = cookie;
- p->next = Auth_cookie;
- Auth_cookie = p;
-#ifdef AUTH_DEBUG
- dump_auth_cookie();
-#endif
-}
-
/* get last modified time */
char *
last_modified(Buffer *buf)
diff --git a/file.c b/file.c
@@ -1388,22 +1388,26 @@ findAuthentication(struct http_auth *hauth, Buffer *buf, char *auth_field)
return hauth->scheme ? hauth : NULL;
}
-static Str
+static void
getAuthCookie(struct http_auth *hauth, char *auth_header,
TextList *extra_header, ParsedURL *pu, HRequest *hr,
- FormList *request)
+ FormList *request,
+ volatile Str *uname, volatile Str *pwd)
{
Str ss = NULL;
- Str uname, pwd;
Str tmp;
TextListItem *i;
int a_found;
int auth_header_len = strlen(auth_header);
char *realm = NULL;
+ int proxy;
if (hauth)
realm = qstr_unquote(get_auth_param(hauth->param, "realm"))->ptr;
+ if (!realm)
+ return;
+
a_found = FALSE;
for (i = extra_header->first; i != NULL; i = i->next) {
if (!strncasecmp(i->ptr, auth_header, auth_header_len)) {
@@ -1411,9 +1415,9 @@ getAuthCookie(struct http_auth *hauth, char *auth_header,
break;
}
}
+ proxy = !strncasecmp("Proxy-Authorization:", auth_header,
+ auth_header_len);
if (a_found) {
- if (!realm)
- return NULL;
/* This means that *-Authenticate: header is received after
* Authorization: header is sent to the server.
*/
@@ -1424,79 +1428,81 @@ getAuthCookie(struct http_auth *hauth, char *auth_header,
else
fprintf(stderr, "Wrong username or password\n");
sleep(1);
- ss = NULL;
/* delete Authenticate: header from extra_header */
delText(extra_header, i);
-
+ invalidate_auth_user_passwd(pu, realm, *uname, *pwd, proxy);
}
- if (realm && ss == NULL) {
- int proxy = !strncasecmp("Proxy-Authorization:", auth_header,
- auth_header_len);
+ *uname = NULL;
+ *pwd = NULL;
- if (!a_found && find_auth_user_passwd(pu, realm, &uname, &pwd, proxy)) {
- /* found username & password in passwd file */ ;
+ if (!a_found && find_auth_user_passwd(pu, realm, (Str*)uname, (Str*)pwd,
+ proxy)) {
+ /* found username & password in passwd file */ ;
+ }
+ else {
+ if (QuietMessage)
+ return;
+ /* input username and password */
+ sleep(2);
+ if (fmInitialized) {
+ char *pp;
+ term_raw();
+ /* FIXME: gettextize? */
+ if ((pp = inputStr(Sprintf("Username for %s: ", realm)->ptr,
+ NULL)) == NULL)
+ return;
+ *uname = Str_conv_to_system(Strnew_charp(pp));
+ if ((pp = inputLine(Sprintf("Password for %s: ", realm)->ptr, NULL,
+ IN_PASSWORD)) == NULL) {
+ *uname = NULL;
+ return;
+ }
+ *pwd = Str_conv_to_system(Strnew_charp(pp));
+ term_cbreak();
}
else {
- if (QuietMessage)
- return ss;
- /* input username and password */
- sleep(2);
- if (fmInitialized) {
- char *pp;
- term_raw();
+ /*
+ * If post file is specified as '-', stdin is closed at this
+ * point.
+ * In this case, w3m cannot read username from stdin.
+ * So exit with error message.
+ * (This is same behavior as lwp-request.)
+ */
+ if (feof(stdin) || ferror(stdin)) {
/* FIXME: gettextize? */
- if ((pp =
- inputStr(Sprintf("Username for %s: ", realm)->ptr,
- NULL)) == NULL)
- return NULL;
- uname = Str_conv_to_system(Strnew_charp(pp));
- if ((pp =
- inputLine(Sprintf("Password for %s: ", realm)->ptr, NULL,
- IN_PASSWORD)) == NULL)
- return NULL;
- pwd = Str_conv_to_system(Strnew_charp(pp));
- term_cbreak();
+ fprintf(stderr, "w3m: Authorization required for %s\n",
+ realm);
+ exit(1);
}
- else {
- /*
- * If post file is specified as '-', stdin is closed at this
- * point.
- * In this case, w3m cannot read username from stdin.
- * So exit with error message.
- * (This is same behavior as lwp-request.)
- */
- if (feof(stdin) || ferror(stdin)) {
- /* FIXME: gettextize? */
- fprintf(stderr, "w3m: Authorization required for %s\n",
- realm);
- exit(1);
- }
-
- /* FIXME: gettextize? */
- printf(proxy ? "Proxy Username for %s: " : "Username for %s: ",
- realm);
- fflush(stdout);
- uname = Strfgets(stdin);
- Strchop(uname);
+
+ /* FIXME: gettextize? */
+ printf(proxy ? "Proxy Username for %s: " : "Username for %s: ",
+ realm);
+ fflush(stdout);
+ *uname = Strfgets(stdin);
+ Strchop(*uname);
#ifdef HAVE_GETPASSPHRASE
- pwd = Strnew_charp((char *)
- getpassphrase(proxy ? "Proxy Password: " :
- "Password: "));
+ *pwd = Strnew_charp((char *)
+ getpassphrase(proxy ? "Proxy Password: " :
+ "Password: "));
#else
- pwd = Strnew_charp((char *)
- getpass(proxy ? "Proxy Password: " :
- "Password: "));
+ *pwd = Strnew_charp((char *)
+ getpass(proxy ? "Proxy Password: " :
+ "Password: "));
#endif
- }
}
- ss = hauth->cred(hauth, uname, pwd, pu, hr, request);
}
+ ss = hauth->cred(hauth, *uname, *pwd, pu, hr, request);
if (ss) {
tmp = Strnew_charp(auth_header);
Strcat_m_charp(tmp, " ", ss->ptr, "\r\n", NULL);
pushText(extra_header, tmp->ptr);
}
- return ss;
+ else {
+ *uname = NULL;
+ *pwd = NULL;
+ }
+ return;
}
static int
@@ -1566,7 +1572,8 @@ loadGeneralFile(char *path, ParsedURL *volatile current, char *referer,
int volatile searchHeader_through = TRUE;
MySignalHandler(*volatile prevtrap) (SIGNAL_ARG) = NULL;
TextList *extra_header = newTextList();
- volatile Str ss = NULL;
+ volatile Str uname = NULL;
+ volatile Str pwd = NULL;
volatile Str realm = NULL;
int volatile add_auth_cookie_flag;
unsigned char status = HTST_NORMAL;
@@ -1735,10 +1742,10 @@ loadGeneralFile(char *path, ParsedURL *volatile current, char *referer,
}
if (t == NULL)
t = "text/plain";
- if (add_auth_cookie_flag && realm && ss) {
+ if (add_auth_cookie_flag && realm && uname && pwd) {
/* If authorization is required and passed */
- add_auth_cookie(auth_pu->host, auth_pu->port, auth_pu->file,
- qstr_unquote(realm)->ptr, ss);
+ add_auth_user_passwd(&pu, qstr_unquote(realm)->ptr, uname, pwd,
+ 0);
add_auth_cookie_flag = 0;
}
if ((p = checkHeader(t_buf, "WWW-Authenticate:")) != NULL &&
@@ -1748,9 +1755,9 @@ loadGeneralFile(char *path, ParsedURL *volatile current, char *referer,
if (findAuthentication(&hauth, t_buf, "WWW-Authenticate:") != NULL
&& (realm = get_auth_param(hauth.param, "realm")) != NULL) {
auth_pu = &pu;
- ss = getAuthCookie(&hauth, "Authorization:", extra_header,
- auth_pu, &hr, request);
- if (ss == NULL) {
+ getAuthCookie(&hauth, "Authorization:", extra_header,
+ auth_pu, &hr, request, &uname, &pwd);
+ if (uname == NULL) {
/* abort */
TRAP_OFF;
goto page_loaded;
@@ -1769,9 +1776,10 @@ loadGeneralFile(char *path, ParsedURL *volatile current, char *referer,
!= NULL
&& (realm = get_auth_param(hauth.param, "realm")) != NULL) {
auth_pu = schemeToProxy(pu.scheme);
- ss = getAuthCookie(&hauth, "Proxy-Authorization:",
- extra_header, auth_pu, &hr, request);
- if (ss == NULL) {
+ getAuthCookie(&hauth, "Proxy-Authorization:",
+ extra_header, auth_pu, &hr, request,
+ &uname, &pwd);
+ if (uname == NULL) {
/* abort */
TRAP_OFF;
goto page_loaded;
diff --git a/fm.h b/fm.h
@@ -669,15 +669,6 @@ struct html_feed_environ {
int blank_lines;
};
-struct auth_cookie {
- Str host;
- int port;
- Str file;
- Str realm;
- Str cookie;
- struct auth_cookie *next;
-};
-
#ifdef USE_COOKIE
struct portlist {
unsigned short port;
diff --git a/ftp.c b/ftp.c
@@ -320,6 +320,7 @@ openFTPStream(ParsedURL *pu, URLFile *uf)
int status;
char *user = NULL;
char *pass = NULL;
+ Str uname = NULL;
Str pwd = NULL;
int add_auth_cookie_flag = FALSE;
char *realpathname = NULL;
@@ -328,7 +329,6 @@ openFTPStream(ParsedURL *pu, URLFile *uf)
return NULL;
if (pu->user == NULL && pu->pass == NULL) {
- Str uname, pwd;
if (find_auth_user_passwd(pu, NULL, &uname, &pwd, 0)) {
if (uname)
user = uname->ptr;
@@ -361,7 +361,8 @@ openFTPStream(ParsedURL *pu, URLFile *uf)
else if (pu->pass)
pass = pu->pass;
else if (pu->user) {
- pwd = find_auth_cookie(pu->host, pu->port, pu->file, pu->user);
+ pwd = NULL;
+ find_auth_user_passwd(pu, NULL, &uname, &pwd, 0);
if (pwd == NULL) {
if (fmInitialized) {
term_raw();
@@ -394,7 +395,7 @@ openFTPStream(ParsedURL *pu, URLFile *uf)
return NULL;
}
if (add_auth_cookie_flag)
- add_auth_cookie(pu->host, pu->port, pu->file, pu->user, pwd);
+ add_auth_user_passwd(pu, NULL, uname, pwd, 0);
ftp_read:
ftp_command(¤t_ftp, "TYPE", "I", &status);
diff --git a/proto.h b/proto.h
@@ -617,9 +617,10 @@ extern void loadPasswd(void);
extern void loadPreForm(void);
extern int find_auth_user_passwd(ParsedURL *pu, char *realm,
Str *uname, Str *pwd, int is_proxy);
-extern Str find_auth_cookie(char *host, int port, char *file, char *realm);
-extern void add_auth_cookie(char *host, int port, char *file, char *realm,
- Str cookie);
+extern void add_auth_user_passwd(ParsedURL *pu, char *realm,
+ Str uname, Str pwd, int is_proxy);
+extern void invalidate_auth_user_passwd(ParsedURL *pu, char *realm,
+ Str uname, Str pwd, int is_proxy);
extern char *last_modified(Buffer *buf);
extern Str romanNumeral(int n);
extern Str romanAlphabet(int n);
diff --git a/url.c b/url.c
@@ -1400,33 +1400,6 @@ HTTPrequest(ParsedURL *pu, ParsedURL *current, HRequest *hr, TextList *extra)
Strcat_charp(tmp, i->ptr);
}
- if (!seen_www_auth
-#ifdef USE_SSL
- && hr->command != HR_COMMAND_CONNECT
-#endif
- ) {
- Str auth_cookie = find_auth_cookie(pu->host, pu->port, pu->file, NULL);
- if (auth_cookie)
- Strcat_m_charp(tmp, "Authorization: ", auth_cookie->ptr,
- "\r\n", NULL);
- }
-
- if (!seen_proxy_auth && (hr->flag & HR_FLAG_PROXY)
-#ifdef USE_SSL
- && (pu->scheme != SCM_HTTPS || hr->command == HR_COMMAND_CONNECT)
-#endif
- ) {
- ParsedURL *proxy_pu = schemeToProxy(pu->scheme);
- Str auth_cookie =
- find_auth_cookie(proxy_pu->host, proxy_pu->port, proxy_pu->file,
- NULL);
- if (!auth_cookie && proxy_auth_cookie)
- auth_cookie = proxy_auth_cookie;
- if (auth_cookie)
- Strcat_m_charp(tmp, "Proxy-Authorization: ", auth_cookie->ptr,
- "\r\n", NULL);
- }
-
#ifdef USE_COOKIE
if (hr->command != HR_COMMAND_CONNECT &&
use_cookie && (cookie = find_cookie(pu))) {