From 0da81238628cb2659297eadd42080e5e9166fc21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96man?= Date: Thu, 28 May 2009 21:12:44 +0000 Subject: [PATCH] Change access-control a bit - Support reading of a superuser account (to be setup by dist-config scripts) - Add command-line option -C : Create a default user if no users are available. Previosuly, this was always done. --- src/access.c | 47 +++++++++++++++++++++++++++++++++++++++++------ src/access.h | 2 +- src/main.c | 11 +++++++---- 3 files changed, 49 insertions(+), 11 deletions(-) diff --git a/src/access.c b/src/access.c index 8e560eb7..dc62d24d 100644 --- a/src/access.c +++ b/src/access.c @@ -32,12 +32,14 @@ #include "tvhead.h" #include "access.h" #include "dtable.h" +#include "settings.h" #include struct access_entry_queue access_entries; - +const char *superuser_username; +const char *superuser_password; /** @@ -52,8 +54,17 @@ access_verify(const char *username, const char *password, uint32_t b = ntohl(si->sin_addr.s_addr); access_entry_t *ae; + if(username != NULL && superuser_username != NULL && + password != NULL && superuser_password != NULL && + !strcmp(username, superuser_username) && + !strcmp(password, superuser_password)) + return 0; + TAILQ_FOREACH(ae, &access_entries, ae_link) { + if(!ae->ae_enabled) + continue; + if(ae->ae_username[0] != '*') { /* acl entry requires username to match */ if(username == NULL) @@ -90,8 +101,24 @@ access_get_hashed(const char *username, const uint8_t digest[20], uint32_t r = 0; int match = 0; + if(superuser_username != NULL && superuser_password != NULL) { + + av_sha1_init(shactx); + av_sha1_update(shactx, (const uint8_t *)superuser_password, + strlen(superuser_password)); + av_sha1_update(shactx, challenge, 32); + av_sha1_final(shactx, d); + + if(!strcmp(superuser_username, username) && !memcmp(d, digest, 20)) + return 0xffffffff; + } + + TAILQ_FOREACH(ae, &access_entries, ae_link) { + if(!ae->ae_enabled) + continue; + if((b & ae->ae_netmask) != ae->ae_network) continue; /* IP based access mismatches */ @@ -101,7 +128,7 @@ access_get_hashed(const char *username, const uint8_t digest[20], av_sha1_update(shactx, challenge, 32); av_sha1_final(shactx, d); - if(memcmp(d, digest, 20)) /* Nintendo would have use strncmp() here :) */ + if(strcmp(ae->ae_username, username) || memcmp(d, digest, 20)) continue; match = 1; r |= ae->ae_rights; @@ -388,17 +415,17 @@ static const dtable_class_t access_dtc = { * */ void -access_init(void) +access_init(int createdefault) { dtable_t *dt; - htsmsg_t *r; + htsmsg_t *r, *m; access_entry_t *ae; - + TAILQ_INIT(&access_entries); dt = dtable_create(&access_dtc, "accesscontrol", NULL); - if(dtable_load(dt) == 0) { + if(dtable_load(dt) == 0 && createdefault) { /* No records available */ ae = access_entry_find(NULL, 1); @@ -415,4 +442,12 @@ access_init(void) fprintf(stderr, "Notice: Created default access controle entry\n"); } + + /* Load superuser account */ + + if((m = hts_settings_load("superuser")) != NULL) { + superuser_username = htsmsg_get_str(m, "username"); + superuser_password = htsmsg_get_str(m, "password"); + // Keep 'm' in memory + } } diff --git a/src/access.h b/src/access.h index 6815efd5..834a372c 100644 --- a/src/access.h +++ b/src/access.h @@ -75,6 +75,6 @@ uint32_t access_get_by_addr(struct sockaddr *src); /** * */ -void access_init(void); +void access_init(int createdefault); #endif /* ACCESS_H_ */ diff --git a/src/main.c b/src/main.c index 051b99b4..96e74d4a 100644 --- a/src/main.c +++ b/src/main.c @@ -192,12 +192,11 @@ main(int argc, char **argv) const char *usernam = NULL; const char *groupnam = NULL; int logfacility = LOG_DAEMON; + int createdefault = 0; sigset_t set; const char *contentpath = TVHEADEND_CONTENT_PATH; - signal(SIGPIPE, handle_sigpipe); - - while((c = getopt(argc, argv, "fu:g:s:c:")) != -1) { + while((c = getopt(argc, argv, "fu:g:s:c:C")) != -1) { switch(c) { case 'f': forkaway = 1; @@ -211,9 +210,13 @@ main(int argc, char **argv) case 'c': contentpath = optarg; break; + case 'C': + createdefault = 1; + break; } } + signal(SIGPIPE, handle_sigpipe); grp = getgrnam(groupnam ?: "video"); pw = usernam ? getpwnam(usernam) : NULL; @@ -268,7 +271,7 @@ main(int argc, char **argv) channels_init(); - access_init(); + access_init(createdefault); tcp_server_init();