aboutsummaryrefslogtreecommitdiffstats
path: root/etc.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--etc.c188
1 files changed, 185 insertions, 3 deletions
diff --git a/etc.c b/etc.c
index 7af9869..08affeb 100644
--- a/etc.c
+++ b/etc.c
@@ -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 */