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.
This commit is contained in:
parent
e8aa1ecb38
commit
0da8123862
3 changed files with 49 additions and 11 deletions
47
src/access.c
47
src/access.c
|
@ -32,12 +32,14 @@
|
|||
#include "tvhead.h"
|
||||
#include "access.h"
|
||||
#include "dtable.h"
|
||||
#include "settings.h"
|
||||
|
||||
#include <libavutil/sha1.h>
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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_ */
|
||||
|
|
11
src/main.c
11
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();
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue