w3m

Unnamed repository; edit this file to name it for gitweb.
git clone https://logand.com/git/w3m.git/
Log | Files | Refs | README

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:
MChangeLog | 37+++++++++++++++++++++++++++++++++++++
Metc.c | 163+++++++++++++++++++++++++++++++------------------------------------------------
Mfile.c | 148++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Mfm.h | 9---------
Mftp.c | 7++++---
Mproto.h | 7++++---
Murl.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(&current_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))) {