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:
M | ChangeLog | | | 17 | +++++++++++++++++ |
M | NEWS | | | 1 | + |
M | etc.c | | | 198 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------ |
M | ftp.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);