diff options
Diffstat (limited to '')
-rw-r--r-- | ChangeLog | 30 | ||||
-rw-r--r-- | conv.c | 4 | ||||
-rw-r--r-- | etc.c | 188 | ||||
-rw-r--r-- | file.c | 135 | ||||
-rw-r--r-- | proto.h | 9 | ||||
-rw-r--r-- | rc.c | 3 | ||||
-rw-r--r-- | textlist.c | 16 | ||||
-rw-r--r-- | textlist.h | 4 | ||||
-rw-r--r-- | url.c | 55 |
9 files changed, 309 insertions, 135 deletions
@@ -1,3 +1,31 @@ +2002-09-25 AIDA Shinra <aida-s@jcom.home.ne.jp> + + * [w3m-dev 03318] Re: Passwords + * etc.c (struct auth_path): added + (passwords): added + (dir_under): added + (add_auth_pass_entry): added + (find_auth_pass_entry): added + (find_auth_user_passwd): added + (loadPasswd): added + (find_auth): dir_under() + (add_auth_cookie): check file + * file.c (find_auth_user_passwd): removed + (getAuthCookie): use delText() + check proxy + (get_auth_cookie): removed + (loadGeneralFile): auth_pu + * proto.h (schemeToProxy): added + (get_auth_cookie): removed + (loadPasswd): added + (find_auth_user_passwd): added + * rc.c (sync_with_option): loadPasswd() + * textlist.c (delValue): added + * textlist.h (delValue): added + (delText): added + * url.c (HTTPrequest): seen_www_auth + (schemeToProxy): added + 2002-09-11 Fumitoshi UKAI <ukai@debian.or.jp> * [w3m-dev 03312] Re: Passwords @@ -3787,4 +3815,4 @@ * release-0-2-1 * import w3m-0.2.1 -$Id: ChangeLog,v 1.427 2002/09/11 15:08:49 ukai Exp $ +$Id: ChangeLog,v 1.428 2002/09/24 16:35:02 ukai Exp $ @@ -1,4 +1,4 @@ -/* $Id: conv.c,v 1.6 2001/11/29 09:34:14 ukai Exp $ */ +/* $Id: conv.c,v 1.7 2002/09/24 16:35:02 ukai Exp $ */ #include <stdio.h> #include <string.h> #include "fm.h" @@ -237,7 +237,7 @@ cConvSE(Str is) state = SJIS_SHIFT_L; } else if (0xe0 <= *p && *p <= 0xef) { /* JIS X 0208 */ -/* } else if (0xe0 <= *p && *p <= 0xfc) { *//* JIS X 0213 */ + /* } else if (0xe0 <= *p && *p <= 0xfc) { *//* JIS X 0213 */ ub = (*p & 0x7f) - 0x40; state = SJIS_SHIFT_H; } @@ -1,4 +1,4 @@ -/* $Id: etc.c,v 1.22 2002/06/07 15:46:44 ukai Exp $ */ +/* $Id: etc.c,v 1.23 2002/09/24 16:35:02 ukai Exp $ */ #include "fm.h" #include <pwd.h> #include "myctype.h" @@ -24,6 +24,18 @@ #define close(x) close_s(x) #endif /* __WATT32__ */ +struct auth_pass { + int is_proxy; + Str host; + int port; + Str file; + Str realm; + Str uname; + Str pwd; + struct auth_pass *next; +}; + +struct auth_pass *passwords = NULL; int columnSkip(Buffer *buf, int offset) @@ -838,6 +850,150 @@ correct_irrtag(int status) return tmp; } +static int +dir_under(const char *x, const char *y) +{ + size_t len = strlen(x); + return x[len - 1] == '/' + && strlen(y) >= len + && y[len - 1] == '/' && strncasecmp(x, y, len) == 0; +} + +static void +add_auth_pass_entry(const struct auth_pass *ent) +{ + if (ent->host && (ent->is_proxy || ent->file || ent->realm) + && ent->uname && ent->pwd) { + struct auth_pass *newent = New(struct auth_pass); + memcpy(newent, ent, sizeof(struct auth_pass)); + newent->next = passwords; + passwords = newent; + } + /* ignore invalid entries */ +} + +static struct auth_pass * +find_auth_pass_entry(char *host, int port, char *file, char *realm, + int is_proxy) +{ + struct auth_pass *ent; + for (ent = passwords; ent != NULL; ent = ent->next) { + if (ent->is_proxy == is_proxy && !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)) + ) + return ent; + } + return NULL; +} + +int +find_auth_user_passwd(char *host, int port, char *file, char *realm, + Str *uname, Str *pwd, int is_proxy) +{ + struct auth_pass *ent; + ent = find_auth_pass_entry(host, port, file, realm, is_proxy); + if (ent) { + *uname = ent->uname; + *pwd = ent->pwd; + return 1; + } + return 0; +} + +/* passwd */ +/* + * machine <name> + * port <port> + * proxy + * path <file> + * realm <realm> + * login <login> + * passwd <passwd> + */ + +#define PASS_IS_READABLE_MSG "SECURITY NOTE: password file must not be accessible by others" +void +loadPasswd(void) +{ + 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; + } + + fp = fopen(expandName(passwd_file), "r"); + if (fp == NULL) + return; /* never? */ + + bzero(&ent, sizeof(struct auth_pass)); + while (1) { + Str line; + Str arg = NULL; + char *p, *q; + + line = Strfgets(fp); + if (line->length == 0) + break; + p = line->ptr; + p[line->length - 1] = '\0'; /* remove CR */ + SKIP_BLANKS(p); + + if (*p == '#' || *p == '\0') + 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); + } + + if (!strcmp(p, "machine")) { + add_auth_pass_entry(&ent); + bzero(&ent, sizeof(struct auth_pass)); + ent.host = arg; + } + else if (!strcmp(p, "port") && arg) + ent.port = atoi(arg->ptr); + else if (!strcmp(p, "proxy") && !arg) + ent.is_proxy = 1; + else if (!strcmp(p, "path")) + ent.file = arg; + else if (!strcmp(p, "realm")) + ent.realm = arg; + else if (!strcmp(p, "login")) + ent.uname = arg; + else if (!strcmp(p, "password")) + ent.pwd = arg; + /* ignore */ + } + add_auth_pass_entry(&ent); + fclose(fp); + return; +} + /* authentication */ struct auth_cookie * find_auth(char *host, int port, char *file, char *realm) @@ -848,7 +1004,7 @@ find_auth(char *host, int port, char *file, char *realm) if (!Strcasecmp_charp(p->host, host) && p->port == port && ((realm && !Strcasecmp_charp(p->realm, realm)) || - (p->file && file && !Strcasecmp_charp(p->file, file)))) + (p->file && file && dir_under(p->file->ptr, file)))) return p; } return NULL; @@ -863,16 +1019,39 @@ find_auth_cookie(char *host, int port, char *file, char *realm) 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) { + 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); @@ -883,6 +1062,9 @@ add_auth_cookie(char *host, int port, char *file, char *realm, Str cookie) p->cookie = cookie; p->next = Auth_cookie; Auth_cookie = p; +#ifdef AUTH_DEBUG + dump_auth_cookie(); +#endif } /* get last modified time */ @@ -1,4 +1,4 @@ -/* $Id: file.c,v 1.100 2002/09/11 15:08:54 ukai Exp $ */ +/* $Id: file.c,v 1.101 2002/09/24 16:35:02 ukai Exp $ */ #include "fm.h" #include <sys/types.h> #include "myctype.h" @@ -1342,92 +1342,6 @@ 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 (passwd_file == NULL) - return 0; - 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) - break; - *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? */ ; - } - } - fclose(fp); - 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, @@ -1436,7 +1350,7 @@ getAuthCookie(struct http_auth *hauth, char *auth_header, Str ss; Str uname, pwd; Str tmp; - TextListItem *i, **i0; + TextListItem *i; int a_found; int auth_header_len = strlen(auth_header); char *realm = NULL; @@ -1445,8 +1359,7 @@ getAuthCookie(struct http_auth *hauth, char *auth_header, realm = qstr_unquote(get_auth_param(hauth->param, "realm"))->ptr; a_found = FALSE; - for (i0 = &(extra_header->first), i = *i0; i != NULL; - i0 = &(i->next), i = *i0) { + for (i = extra_header->first; i != NULL; i = i->next) { if (!strncasecmp(i->ptr, auth_header, auth_header_len)) { a_found = TRUE; break; @@ -1466,15 +1379,19 @@ getAuthCookie(struct http_auth *hauth, char *auth_header, fprintf(stderr, "Wrong username or password\n"); sleep(1); ss = NULL; - *i0 = i->next; /* delete Authenticate: header from * - * extra_header */ + /* delete Authenticate: header from extra_header */ + delText(extra_header, i); + } else ss = find_auth_cookie(pu->host, pu->port, pu->file, realm); if (realm && ss == NULL) { + int proxy = !strncasecmp("Proxy-Authorization:", auth_header, + auth_header_len); + if (!a_found && find_auth_user_passwd(pu->host, pu->port, pu->file, realm, - &uname, &pwd)) { + &uname, &pwd, proxy)) { /* found username & password in passwd file */ ; } else { @@ -1497,9 +1414,6 @@ getAuthCookie(struct http_auth *hauth, char *auth_header, 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. @@ -1539,16 +1453,6 @@ getAuthCookie(struct http_auth *hauth, char *auth_header, return ss; } -void -get_auth_cookie(char *auth_header, - TextList *extra_header, ParsedURL *pu, HRequest *hr, - FormList *request) -{ - getAuthCookie(NULL, auth_header, extra_header, pu, hr, request); -} - - - static int same_url_p(ParsedURL *pu1, ParsedURL *pu2) { @@ -1584,6 +1488,7 @@ loadGeneralFile(char *path, ParsedURL *volatile current, char *referer, URLOption url_option; Str tmp; HRequest hr; + ParsedURL *volatile auth_pu; tpath = path; prevtrap = NULL; @@ -1774,7 +1679,7 @@ loadGeneralFile(char *path, ParsedURL *volatile current, char *referer, } if (add_auth_cookie_flag && realm && ss) { /* If authorization is required and passed */ - add_auth_cookie(pu.host, pu.port, pu.file, + add_auth_cookie(auth_pu->host, auth_pu->port, auth_pu->file, qstr_unquote(realm)->ptr, ss); add_auth_cookie_flag = 0; } @@ -1784,8 +1689,9 @@ loadGeneralFile(char *path, ParsedURL *volatile current, char *referer, struct http_auth hauth; if (findAuthentication(&hauth, t_buf, "WWW-Authenticate:") != NULL && (realm = get_auth_param(hauth.param, "realm")) != NULL) { - ss = getAuthCookie(&hauth, "Authorization:", extra_header, &pu, - &hr, request); + auth_pu = &pu; + ss = getAuthCookie(&hauth, "Authorization:", extra_header, + auth_pu, &hr, request); if (ss == NULL) { /* abort */ UFclose(&f); @@ -1805,10 +1711,9 @@ loadGeneralFile(char *path, ParsedURL *volatile current, char *referer, if (findAuthentication(&hauth, t_buf, "Proxy-Authenticate:") != NULL && (realm = get_auth_param(hauth.param, "realm")) != NULL) { + auth_pu = schemeToProxy(pu.scheme); ss = getAuthCookie(&hauth, "Proxy-Authorization:", - extra_header, &HTTP_proxy_parsed, &hr, - request); - proxy_auth_cookie = ss; + extra_header, auth_pu, &hr, request); if (ss == NULL) { /* abort */ UFclose(&f); @@ -1816,15 +1721,13 @@ loadGeneralFile(char *path, ParsedURL *volatile current, char *referer, return NULL; } UFclose(&f); + add_auth_cookie_flag = 1; status = HTST_NORMAL; goto load_doc; } } /* XXX: RFC2617 3.2.3 Authentication-Info: ? */ - if (add_auth_cookie_flag) - /* If authorization is required and passed */ - add_auth_cookie(pu.host, pu.port, pu.file, - qstr_unquote(realm)->ptr, ss); + if (status == HTST_CONNECT) { of = &f; goto load_doc; @@ -1,4 +1,4 @@ -/* $Id: proto.h,v 1.46 2002/09/05 15:43:22 ukai Exp $ */ +/* $Id: proto.h,v 1.47 2002/09/24 16:35:02 ukai Exp $ */ /* * This file was automatically generated by version 1.7 of cextract. * Manual editing not recommended. @@ -127,14 +127,12 @@ extern void initURIMethods(); extern Str searchURIMethods(ParsedURL *pu); extern void chkExternalURIBuffer(Buffer *buf); #endif +extern ParsedURL *schemeToProxy(int scheme); extern void examineFile(char *path, URLFile *uf); extern char *acceptableEncoding(); extern int dir_exist(char *path); extern Str convertLine(URLFile *uf, Str line, char *code, int mode); extern Buffer *loadFile(char *path); -extern void get_auth_cookie(char *auth_header, - TextList *extra_header, ParsedURL *pu, - HRequest *hr, FormList *request); extern Buffer *loadGeneralFile(char *path, ParsedURL *current, char *referer, int flag, FormList *request); extern int is_boundary(int, int); @@ -522,6 +520,9 @@ extern Buffer *dirBuffer(char *dirname); extern void set_environ(char *var, char *value); extern FILE *localcgi_post(char *, char *, FormList *, char *); extern FILE *localcgi_get(char *, char *, char *); +extern void loadPasswd(void); +extern int find_auth_user_passwd(char *host, int port, char *file, 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); @@ -1,4 +1,4 @@ -/* $Id: rc.c,v 1.48 2002/09/10 17:27:50 ukai Exp $ */ +/* $Id: rc.c,v 1.49 2002/09/24 16:35:02 ukai Exp $ */ /* * Initialization file etc. */ @@ -1234,6 +1234,7 @@ sync_with_option(void) if (fmInitialized && displayImage) initImage(); #endif + loadPasswd(); if (AcceptLang == NULL || *AcceptLang == '\0') { #if LANG == JA @@ -1,4 +1,4 @@ -/* $Id: textlist.c,v 1.4 2001/11/24 02:01:26 ukai Exp $ */ +/* $Id: textlist.c,v 1.5 2002/09/24 16:35:02 ukai Exp $ */ #include "textlist.h" #include "indep.h" #include "Str.h" @@ -79,6 +79,20 @@ rpopValue(GeneralList *tl) return f->ptr; } +void +delValue(GeneralList *tl, ListItem *it) +{ + if (it->prev) + it->prev->next = it->next; + else + tl->first = it->next; + if (it->next) + it->next->prev = it->prev; + else + tl->last = it->prev; + tl->nitem--; +} + GeneralList * appendGeneralList(GeneralList *tl, GeneralList *tl2) { @@ -1,4 +1,4 @@ -/* $Id: textlist.h,v 1.4 2001/12/02 16:26:08 ukai Exp $ */ +/* $Id: textlist.h,v 1.5 2002/09/24 16:35:02 ukai Exp $ */ #ifndef TEXTLIST_H #define TEXTLIST_H #include "Str.h" @@ -22,6 +22,7 @@ extern GeneralList *newGeneralList(void); extern void pushValue(GeneralList *tl, void *s); extern void *popValue(GeneralList *tl); extern void *rpopValue(GeneralList *tl); +extern void delValue(GeneralList *tl, ListItem *it); extern GeneralList *appendGeneralList(GeneralList *, GeneralList *); /* Text list */ @@ -42,6 +43,7 @@ typedef struct _textlist { #define pushText(tl, s) pushValue((GeneralList *)(tl), (void *)allocStr((s)?(s):"",-1)) #define popText(tl) ((char *)popValue((GeneralList *)(tl))) #define rpopText(tl) ((char *)rpopValue((GeneralList *)(tl))) +#define delText(tl, i) delValue((GeneralList *)(tl), (void *)(i)) #define appendTextList(tl, tl2) ((TextList *)appendGeneralList((GeneralList *)(tl), (GeneralList *)(tl2))) /* Line text list */ @@ -1,4 +1,4 @@ -/* $Id: url.c,v 1.48 2002/03/08 15:59:25 ukai Exp $ */ +/* $Id: url.c,v 1.49 2002/09/24 16:35:02 ukai Exp $ */ #include "fm.h" #include <sys/types.h> #include <sys/socket.h> @@ -1282,6 +1282,7 @@ HTTPrequest(ParsedURL *pu, ParsedURL *current, HRequest *hr, TextList *extra) { Str tmp; TextListItem *i; + int seen_www_auth = 0; int seen_proxy_auth = 0; #ifdef USE_COOKIE Str cookie; @@ -1296,16 +1297,32 @@ HTTPrequest(ParsedURL *pu, ParsedURL *current, HRequest *hr, TextList *extra) Strcat_charp(tmp, otherinfo(pu, current, hr->referer)); if (extra != NULL) for (i = extra->first; i != NULL; i = i->next) { + if (strncasecmp(i->ptr, "Authorization:", + sizeof("Authorization:") - 1) == 0) + seen_www_auth = 1; if (strncasecmp(i->ptr, "Proxy-Authorization:", sizeof("Proxy-Authorization:") - 1) == 0) seen_proxy_auth = 1; Strcat_charp(tmp, i->ptr); } - if (!seen_proxy_auth && (hr->flag & HR_FLAG_PROXY) - && proxy_auth_cookie != NULL) - Strcat_m_charp(tmp, "Proxy-Authorization: ", proxy_auth_cookie->ptr, - "\r\n", NULL); + if (!seen_www_auth) { + Str auth_cookie = find_auth_cookie(pu->host, pu->port, pu->file, NULL); + if (!auth_cookie && proxy_auth_cookie) + auth_cookie = proxy_auth_cookie; + if (auth_cookie) + Strcat_m_charp(tmp, "Authorization: ", auth_cookie->ptr, + "\r\n", NULL); + } + + if (!seen_proxy_auth && (hr->flag & HR_FLAG_PROXY)) { + 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) + Strcat_m_charp(tmp, "Proxy-Authorization: ", auth_cookie->ptr, + "\r\n", NULL); + } #ifdef USE_COOKIE if (hr->command != HR_COMMAND_CONNECT && @@ -1545,7 +1562,6 @@ openURL(char *url, ParsedURL *pu, ParsedURL *current, #ifdef USE_SSL case SCM_HTTPS: #endif /* USE_SSL */ - get_auth_cookie("Authorization:", extra_header, pu, hr, request); if (pu->file == NULL) pu->file = allocStr("/", -1); if (request && request->method == FORM_METHOD_POST && request->body) @@ -2138,3 +2154,30 @@ chkExternalURIBuffer(Buffer *buf) } } #endif + +ParsedURL * +schemeToProxy(int scheme) +{ + ParsedURL *pu = NULL; /* for gcc */ + switch (scheme) { + case SCM_HTTP: +#ifdef USE_SSL + case SCM_HTTPS: +#endif + pu = &HTTP_proxy_parsed; + break; + case SCM_FTP: + pu = &FTP_proxy_parsed; + break; +#ifdef USE_GOPHER + case SCM_GOPHER: + pu = &GOPHER_proxy_parsed; + break; +#endif +#ifdef DEBUG + default: + abort(); +#endif + } + return pu; +} |