w3m

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

commit ac9c41fdf46935d1406f5c973bc60d0413eab616
parent 44e064ed5ce638cef2fa51c26822e4556b61282c
Author: ukai <ukai>
Date:   Wed, 30 Oct 2002 17:21:35 +0000

[w3m-dev 03365] ~/.netrc support
* etc.c (add_auth_pass_entry): add netrc arg
		add new entry to tail
	(find_auth_pass_entry): ent->host == NULL is "default"
	(loadPasswd): rewrite with next_token, parsePasswd,
			openPasswdFile
			load ~/.netrc
	(next_token): added
	(parsePasswd): added
	(openPasswdFile): added
* ftp.c (openFTP): use find_auth_user_passwd
* NEWS: ~/.netrc
From: Fumitoshi UKAI  <ukai@debian.or.jp>

Diffstat:
MChangeLog | 17+++++++++++++++++
MNEWS | 1+
Metc.c | 198+++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------
Mftp.c | 21+++++++++++++++++----
4 files changed, 173 insertions(+), 64 deletions(-)

diff --git a/ChangeLog b/ChangeLog @@ -1,3 +1,18 @@ +2002-10-31 Fumitoshi UKAI <ukai@debian.or.jp> + + * [w3m-dev 03365] ~/.netrc support + * etc.c (add_auth_pass_entry): add netrc arg + add new entry to tail + (find_auth_pass_entry): ent->host == NULL is "default" + (loadPasswd): rewrite with next_token, parsePasswd, + openPasswdFile + load ~/.netrc + (next_token): added + (parsePasswd): added + (openPasswdFile): added + * ftp.c (openFTP): use find_auth_user_passwd + * NEWS: ~/.netrc + 2002-10-31 Hironori SAKAMOTO <hsaka@mth.biglobe.ne.jp> * [w3m-dev 03363] refresh download @@ -21,6 +36,8 @@ use user and passwd if these are defined in ParsedURL * file.c (getAuthCookie): change find_auth_user_passwd() * proto.h (find_auth_user_passwd): change prototype + * NOTE: http://user:pass@www.url.com is NOT RECOMMENDED + for security reasons. 2002-10-30 Hironori SAKAMOTO <hsaka@mth.biglobe.ne.jp> diff --git a/NEWS b/NEWS @@ -1,5 +1,6 @@ w3m 0.3.2 (release candidate) +* ~/.netrc: password for ftp * rc: display_lineinfo: display current line number * rc: passwd_file: passwd file for HTTP auth * func: MARK_WORD diff --git a/etc.c b/etc.c @@ -862,14 +862,22 @@ dir_under(const char *x, const char *y) } static void -add_auth_pass_entry(const struct auth_pass *ent) +add_auth_pass_entry(const struct auth_pass *ent, int netrc) { - if (ent->host && (ent->is_proxy || ent->file || ent->realm) + if ((ent->host || netrc) /* netrc accept default (host == NULL) */ + &&(ent->is_proxy || ent->file || ent->realm || netrc) && ent->uname && ent->pwd) { struct auth_pass *newent = New(struct auth_pass); memcpy(newent, ent, sizeof(struct auth_pass)); - newent->next = passwords; - passwords = 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 */ } @@ -880,7 +888,8 @@ find_auth_pass_entry(char *host, int port, char *file, char *realm, { struct auth_pass *ent; for (ent = passwords; ent != NULL; ent = ent->next) { - if (ent->is_proxy == is_proxy && !Strcmp_charp(ent->host, host) + if (ent->is_proxy == is_proxy + && (!ent->host || !Strcmp_charp(ent->host, host)) && (!ent->port || ent->port == port) && (!ent->file || !file || dir_under(ent->file->ptr, file)) && (!ent->realm || !realm || !Strcmp_charp(ent->realm, realm)) @@ -923,84 +932,153 @@ find_auth_user_passwd(ParsedURL *pu, char *realm, * password <passwd> */ -#define PASS_IS_READABLE_MSG "SECURITY NOTE: password file must not be accessible by others" -void -loadPasswd(void) +static Str +next_token(Str arg) { - struct stat st; - FILE *fp; - struct auth_pass ent; - - if (passwd_file == NULL) - return; - if (stat(expandName(passwd_file), &st) < 0) - return; - - /* check permissions, if group or others readable or writable, - * refuse it, because it's insecure. - */ - if ((st.st_mode & (S_IRWXG | S_IRWXO)) != 0) { - if (fmInitialized) { - message(PASS_IS_READABLE_MSG, 0, 0); - refresh(); - } - else { - fputs(PASS_IS_READABLE_MSG, stderr); - fputc('\n', stderr); - } - sleep(2); - return; + Str narg = NULL; + char *p, *q; + if (arg == NULL || arg->length == 0) + return NULL; + p = arg->ptr; + q = p; + SKIP_NON_BLANKS(q); + if (*q != '\0') { + *q++ = '\0'; + SKIP_BLANKS(q); + if (*q != '\0') + narg = Strnew_charp(q); } + return narg; +} - fp = fopen(expandName(passwd_file), "r"); - if (fp == NULL) - return; /* never? */ +static void +parsePasswd(FILE * fp, int netrc) +{ + struct auth_pass ent; + Str line = NULL; bzero(&ent, sizeof(struct auth_pass)); while (1) { - Str line; Str arg = NULL; - char *p, *q; + char *p; - line = Strfgets(fp); + if (line == NULL || line->length == 0) + line = Strfgets(fp); if (line->length == 0) break; + Strchop(line); + Strremovefirstspaces(line); p = line->ptr; - p[line->length - 1] = '\0'; /* remove CR */ - SKIP_BLANKS(p); - - if (*p == '#' || *p == '\0') + if (*p == '#' || *p == '\0') { + line = NULL; continue; /* comment or empty line */ - q = p; - SKIP_NON_BLANKS(q); - if (*q != '\0') { - *q++ = '\0'; - SKIP_BLANKS(q); - if (*q != '\0') - arg = Strnew_charp(q); } + arg = next_token(line); - if (!strcmp(p, "machine") || !strcmp(p, "host")) { - add_auth_pass_entry(&ent); + if (!strcmp(p, "machine") || !strcmp(p, "host") + || (netrc && !strcmp(p, "default"))) { + add_auth_pass_entry(&ent, netrc); bzero(&ent, sizeof(struct auth_pass)); - ent.host = arg; + if (netrc) + ent.port = 21; /* XXX: getservbyname("ftp"); ? */ + if (strcmp(p, "default") != 0) { + line = next_token(arg); + ent.host = arg; + } + else { + line = arg; + } } - else if (!strcmp(p, "port") && arg) + else if (!netrc && !strcmp(p, "port") && arg) { + line = next_token(arg); ent.port = atoi(arg->ptr); - else if (!strcmp(p, "proxy") && !arg) + } + else if (!netrc && !strcmp(p, "proxy")) { ent.is_proxy = 1; - else if (!strcmp(p, "path")) + line = arg; + } + else if (!netrc && !strcmp(p, "path")) { + line = next_token(arg); ent.file = arg; - else if (!strcmp(p, "realm")) + } + else if (!netrc && !strcmp(p, "realm")) { + /* XXX: rest of line becomes arg for realm */ + line = NULL; ent.realm = arg; - else if (!strcmp(p, "login")) + } + else if (!strcmp(p, "login")) { + line = next_token(arg); ent.uname = arg; - else if (!strcmp(p, "password") || !strcmp(p, "passwd")) + } + else if (!strcmp(p, "password") || !strcmp(p, "passwd")) { + line = next_token(arg); ent.pwd = arg; - /* ignore */ + } + else if (netrc && !strcmp(p, "machdef")) { + while ((line = Strfgets(fp))->length != 0) { + if (*line->ptr == '\n') + break; + } + line = NULL; + } + else if (netrc && !strcmp(p, "account")) { + /* ignore */ + line = next_token(arg); + } + else { + /* ignore rest of line */ + line = NULL; + } + } + add_auth_pass_entry(&ent, netrc); +} + +#define PASS_IS_READABLE_MSG "SECURITY NOTE: passwd file must not be accessible by others" + +static FILE * +openPasswdFile(char *fname) +{ + struct stat st; + if (fname == NULL) + return NULL; + if (stat(expandName(fname), &st) < 0) + return NULL; + + /* check permissions, if group or others readable or writable, + * refuse it, because it's insecure. + */ + if ((st.st_mode & (S_IRWXG | S_IRWXO)) != 0) { + if (fmInitialized) { + message(PASS_IS_READABLE_MSG, 0, 0); + refresh(); + } + else { + fputs(PASS_IS_READABLE_MSG, stderr); + fputc('\n', stderr); + } + sleep(2); + return NULL; + } + + return fopen(expandName(fname), "r"); +} + +void +loadPasswd(void) +{ + FILE *fp; + fp = openPasswdFile(passwd_file); + if (fp != NULL) { + parsePasswd(fp, 0); + fclose(fp); + } + + /* for FTP */ + fp = openPasswdFile("~/.netrc"); + if (fp != NULL) { + parsePasswd(fp, 1); + fclose(fp); } - add_auth_pass_entry(&ent); - fclose(fp); return; } diff --git a/ftp.c b/ftp.c @@ -391,8 +391,8 @@ openFTP(ParsedURL *pu) Str tmp2 = Strnew(); Str tmp3 = Strnew(); STATUS s; - char *user; - char *pass; + char *user = NULL; + char *pass = NULL; Str pwd = NULL; int add_auth_cookie_flag; char *realpathname = NULL; @@ -402,13 +402,26 @@ openFTP(ParsedURL *pu) #endif add_auth_cookie_flag = 0; - if (pu->user) + 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; + if (pwd) + pass = pwd->ptr; + } + } + if (user) + /* do nothing */ ; + else if (pu->user) user = pu->user; else { Strcat_charp(tmp3, "anonymous"); user = tmp3->ptr; } - if (pu->pass) + if (pass) + /* do nothing */ ; + else if (pu->pass) pass = pu->pass; else if (pu->user) { pwd = find_auth_cookie(pu->host, pu->port, pu->file, pu->user);