commit 650116cc62d86a9019dd83668b65659bdbe4c90a
parent 6ab5c441f6b1a7c939214c2bb75183f277a8248b
Author: ukai <ukai>
Date:   Tue, 10 Sep 2002 17:27:39 +0000
[w3m-dev 03307] add password_file support
* file.c (find_auth_user_passwd): added
* fm.h (passwd_file): added
* rc.c (CMT_PASSWDFILE): added
	(passwdfile): added
From: Fumitoshi UKAI  <ukai@debian.or.jp>
Diffstat:
| M | ChangeLog |  |  | 8 | ++++++++ | 
| M | NEWS |  |  | 1 | + | 
| M | file.c |  |  | 171 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------- | 
| M | fm.h |  |  | 1 | + | 
| M | rc.c |  |  | 4 | ++++ | 
5 files changed, 145 insertions(+), 40 deletions(-)
diff --git a/ChangeLog b/ChangeLog
@@ -1,3 +1,11 @@
+2002-09-11  Fumitoshi UKAI  <ukai@debian.or.jp>
+
+	* [w3m-dev 03307] add password_file support
+	* file.c (find_auth_user_passwd): added
+	* fm.h (passwd_file): added
+	* rc.c (CMT_PASSWDFILE): added
+		(passwdfile): added
+
 2002-09-09  Hiroyuki Ito <hito@crl.go.jp>
 
 	* [w3m-dev 03300] framebuffer: 8bit color support
diff --git a/NEWS b/NEWS
@@ -1,5 +1,6 @@
 w3m 0.4?
 
+* rc: passwd_file: passwd file for HTTP auth
 * func: MARK_WORD
 * rc: imgsize: obsoleted
 * w3m-img for framebuffer merged
diff --git a/file.c b/file.c
@@ -1342,6 +1342,89 @@ findAuthentication(struct http_auth *hauth, Buffer *buf, char *auth_field)
     return hauth->scheme ? hauth : NULL;
 }
 
+/* passwd */
+/*
+ * machine <name>
+ * port <port>
+ * path <file>
+ * realm <realm>
+ * login <login>
+ * passwd <passwd>
+ */
+static int
+find_auth_user_passwd(char *host, int port, char *file, char *realm,
+		      Str *uname, Str *pwd)
+{
+    struct stat st;
+    FILE *fp;
+    Str line;
+    char *d, *tok;
+    int matched = 0;
+
+    *uname = NULL;
+    *pwd = NULL;
+    if (stat(expandName(passwd_file), &st) < 0)
+	return 0;
+
+    /* check permissions, if group or others readable or writable,
+     * refuse it, because it's insecure.
+     */
+    if ((st.st_mode & (S_IRWXG | S_IRWXO)) != 0)
+	return 0;
+
+    fp = fopen(expandName(passwd_file), "r");
+    if (fp == NULL)
+	return 0;		/* never? */
+
+    while ((line = Strfgets(fp))->length > 0) {
+	d = line->ptr;
+	if (d[0] == '#')
+	    continue;
+	tok = strtok(d, " \t\n\r");
+	if (tok == NULL)
+	    continue;
+	d = strtok(NULL, "\n\r");
+	if (d == NULL)
+	    continue;
+	if (strcmp(tok, "machine") == 0) {
+	    if (matched && *uname && *pwd)
+		return 1;
+	    *uname = NULL;
+	    *pwd = NULL;
+	    if (strcmp(d, host) == 0)
+		matched = 1;
+	    continue;
+	}
+	else if (strcmp(tok, "port") == 0) {
+	    if (matched && (atoi(d) != port))
+		matched = 0;
+	}
+	else if (strcmp(tok, "path") == 0) {
+	    if (matched && file && (strcmp(d, file) != 0))
+		matched = 0;
+	}
+	else if (strcmp(tok, "realm") == 0) {
+	    if (matched && realm && (strcmp(d, realm) != 0))
+		matched = 0;
+	}
+	else if (strcmp(tok, "login") == 0) {
+	    if (matched)
+		*uname = Strnew_charp(d);
+	}
+	else if (strcmp(tok, "password") == 0 || strcmp(tok, "passwd") == 0) {
+	    if (matched)
+		*pwd = Strnew_charp(d);
+	}
+	else {
+	    /* ignore? */ ;
+	}
+    }
+    if (matched && *uname && *pwd)
+	return 1;
+
+    return 0;
+}
+
 static Str
 getAuthCookie(struct http_auth *hauth, char *auth_header,
 	      TextList *extra_header, ParsedURL *pu, HRequest *hr,
@@ -1386,53 +1469,61 @@ getAuthCookie(struct http_auth *hauth, char *auth_header,
     else
 	ss = find_auth_cookie(pu->host, pu->port, pu->file, realm);
     if (realm && ss == NULL) {
-	if (QuietMessage)
-	    return ss;
-	/* input username and password */
-	sleep(2);
-	if (fmInitialized) {
-	    char *pp;
-	    term_raw();
-	    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));
+	if (find_auth_user_passwd(pu->host, pu->port, pu->file, realm,
+				  &uname, &pwd)) {
+	    /* found username & password in passwd file */ ;
 	}
 	else {
-	    int proxy = !strncasecmp("Proxy-Authorization:", auth_header,
-				     auth_header_len);
-
-	    /*
-	     * 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)) {
-		fprintf(stderr, "w3m: Authorization required for %s\n", realm);
-		exit(1);
+	    if (QuietMessage)
+		return ss;
+	    /* input username and password */
+	    sleep(2);
+	    if (fmInitialized) {
+		char *pp;
+		term_raw();
+		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));
 	    }
+	    else {
+		int proxy = !strncasecmp("Proxy-Authorization:", auth_header,
+					 auth_header_len);
+
+		/*
+		 * 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)) {
+		    fprintf(stderr, "w3m: Authorization required for %s\n",
+			    realm);
+		    exit(1);
+		}
 
-	    printf(proxy ? "Proxy Username for %s: " : "Username for %s: ",
-		   realm);
-	    fflush(stdout);
-	    uname = Strfgets(stdin);
-	    Strchop(uname);
+		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);
     }
diff --git a/fm.h b/fm.h
@@ -838,6 +838,7 @@ global char *ExtBrowser init(DEF_EXT_BROWSER);
 global char *ExtBrowser2 init(NULL);
 global char *ExtBrowser3 init(NULL);
 global int BackgroundExtViewer init(TRUE);
+global char *passwd_file init(NULL);
 global char *ftppasswd init(NULL);
 #ifdef FTPPASS_HOSTNAMEGEN
 global int ftppass_hostnamegen init(TRUE);
diff --git a/rc.c b/rc.c
@@ -127,6 +127,7 @@ static char *config_file = NULL;
 #define CMT_EXTBRZ       "外部ブラウザ"
 #define CMT_EXTBRZ2      "外部ブラウザその2"
 #define CMT_EXTBRZ3      "外部ブラウザその3"
+#define CMT_PASSWDFILE	 "パスワードファイル"
 #define CMT_FTPPASS      "FTPのパスワード(普通は自分のmail addressを使う)"
 #ifdef FTPPASS_HOSTNAMEGEN
 #define CMT_FTPPASS_HOSTNAMEGEN	"FTPのパスワードのドメイン名を自動生成する"
@@ -268,6 +269,7 @@ static char *config_file = NULL;
 #define CMT_EXTBRZ       "External Browser"
 #define CMT_EXTBRZ2      "Second External Browser"
 #define CMT_EXTBRZ3      "Third External Browser"
+#define CMT_PASSWDFILE	 "Password file"
 #define CMT_FTPPASS      "Password for anonymous FTP (your mail address)"
 #ifdef FTPPASS_HOSTNAMEGEN
 #define CMT_FTPPASS_HOSTNAMEGEN "Generate domain part of password for FTP"
@@ -665,6 +667,8 @@ struct param_ptr params8[] = {
 };
 #endif
 struct param_ptr params9[] = {
+    {"passwd_file", P_STRING, PI_TEXT, (void *)&passwd_file, CMT_PASSWDFILE,
+     NULL},
     {"ftppasswd", P_STRING, PI_TEXT, (void *)&ftppasswd, CMT_FTPPASS, NULL},
 #ifdef FTPPASS_HOSTNAMEGEN
     {"ftppass_hostnamegen", P_INT, PI_ONOFF, (void *)&ftppass_hostnamegen,