[w3m-dev 04064] authentication

Fumitoshi UKAI <[email protected]>
Newsgroups gmane.comp.web.w3m.devel
Organization Debian JP Project
Message-ID <[email protected]>
Bug#224029 http://bugs.debian.org/244029 

| AFAIK basic authentication is directory-based, not page-based, isn't it?


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.

 pathhost, port, realm 


 Digest2bug(auth_cookie
 challenge cookieDigest)


?

-- 


Index: etc.c
===================================================================
RCS file: /cvsroot/w3m/w3m/etc.c,v
retrieving revision 1.77
diff -p -u -r1.77 etc.c
--- etc.c	4 Apr 2004 16:47:20 -0000	1.77
+++ etc.c	16 Apr 2004 18:38:17 -0000
@@ -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, cha
 	*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, cha
     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)
Index: file.c
===================================================================
RCS file: /cvsroot/w3m/w3m/file.c,v
retrieving revision 1.234
diff -p -u -r1.234 file.c
--- file.c	8 Dec 2003 16:08:01 -0000	1.234
+++ file.c	16 Apr 2004 18:38:18 -0000
@@ -1388,22 +1388,26 @@ findAuthentication(struct http_auth *hau
     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, c
 	    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, c
 	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 *v
     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 *v
 	}
 	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 *v
 	    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 *v
 		!= 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;
Index: fm.h
===================================================================
RCS file: /cvsroot/w3m/w3m/fm.h,v
retrieving revision 1.124
diff -p -u -r1.124 fm.h
--- fm.h	5 Oct 2003 18:52:51 -0000	1.124
+++ fm.h	16 Apr 2004 18:38:18 -0000
@@ -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;
Index: ftp.c
===================================================================
RCS file: /cvsroot/w3m/w3m/ftp.c,v
retrieving revision 1.34
diff -p -u -r1.34 ftp.c
--- ftp.c	22 Oct 2003 18:44:31 -0000	1.34
+++ ftp.c	16 Apr 2004 18:38:18 -0000
@@ -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);
Index: proto.h
===================================================================
RCS file: /cvsroot/w3m/w3m/proto.h,v
retrieving revision 1.98
diff -p -u -r1.98 proto.h
--- proto.h	23 Mar 2004 16:44:02 -0000	1.98
+++ proto.h	16 Apr 2004 18:38:18 -0000
@@ -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);
Index: url.c
===================================================================
RCS file: /cvsroot/w3m/w3m/url.c,v
retrieving revision 1.88
diff -p -u -r1.88 url.c
--- url.c	30 Mar 2004 18:06:43 -0000	1.88
+++ url.c	16 Apr 2004 18:38:19 -0000
@@ -1400,33 +1400,6 @@ HTTPrequest(ParsedURL *pu, ParsedURL *cu
 	    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))) {
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.