Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
ACL: add full rights copy for tickets to resolve connection counting,…
… fixes #2349
  • Loading branch information
perexg committed Oct 7, 2014
1 parent 5b3f648 commit a510248
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 39 deletions.
39 changes: 33 additions & 6 deletions src/access.c
Expand Up @@ -57,6 +57,7 @@ access_ticket_destroy(access_ticket_t *at)
free(at->at_id);
free(at->at_resource);
TAILQ_REMOVE(&access_tickets, at, at_link);
access_destroy(at->at_access);
free(at);
}

Expand Down Expand Up @@ -92,14 +93,16 @@ access_ticket_timout(void *aux)
* Create a new ticket for the requested resource and generate a id for it
*/
const char *
access_ticket_create(const char *resource)
access_ticket_create(const char *resource, access_t *a)
{
uint8_t buf[20];
char id[41];
unsigned int i;
access_ticket_t *at;
static const char hex_string[16] = "0123456789ABCDEF";

assert(a);

at = calloc(1, sizeof(access_ticket_t));

RAND_bytes(buf, 20);
Expand All @@ -114,6 +117,8 @@ access_ticket_create(const char *resource)
at->at_id = strdup(id);
at->at_resource = strdup(resource);

at->at_access = access_copy(a);

TAILQ_INSERT_TAIL(&access_tickets, at, at_link);
gtimer_arm(&at->at_timer, access_ticket_timout, at, 60*5);

Expand All @@ -140,18 +145,37 @@ access_ticket_delete(const char *id)
/**
*
*/
int
access_ticket_verify(const char *id, const char *resource)
access_t *
access_ticket_verify2(const char *id, const char *resource)
{
access_ticket_t *at;

if((at = access_ticket_find(id)) == NULL)
return -1;
return NULL;

if(strcmp(at->at_resource, resource))
return -1;
return NULL;

return 0;
return access_copy(at->at_access);
}

/**
*
*/
access_t *
access_copy(access_t *src)
{
access_t *dst = malloc(sizeof(*dst));
*dst = *src;
if (src->aa_username)
dst->aa_username = strdup(src->aa_username);
if (src->aa_representative)
dst->aa_representative = strdup(src->aa_representative);
if (src->aa_dvrcfgs)
dst->aa_dvrcfgs = htsmsg_copy(src->aa_dvrcfgs);
if (src->aa_chtags)
dst->aa_chtags = htsmsg_copy(src->aa_chtags);
return dst;
}

/**
Expand Down Expand Up @@ -1207,10 +1231,13 @@ void
access_done(void)
{
access_entry_t *ae;
access_ticket_t *at;

pthread_mutex_lock(&global_lock);
while ((ae = TAILQ_FIRST(&access_entries)) != NULL)
access_entry_destroy(ae);
while ((at = TAILQ_FIRST(&access_tickets)) != NULL)
access_ticket_destroy(at);
free((void *)superuser_username);
superuser_username = NULL;
free((void *)superuser_password);
Expand Down
34 changes: 20 additions & 14 deletions src/access.h
Expand Up @@ -79,6 +79,18 @@ typedef struct access_entry {

extern const idclass_t access_entry_class;

typedef struct access {
char *aa_username;
char *aa_representative;
uint32_t aa_rights;
htsmsg_t *aa_dvrcfgs;
uint32_t aa_chmin;
uint32_t aa_chmax;
htsmsg_t *aa_chtags;
int aa_match;
uint32_t aa_conn_limit;
} access_t;

TAILQ_HEAD(access_ticket_queue, access_ticket);

extern struct access_ticket_queue access_tickets;
Expand All @@ -90,20 +102,9 @@ typedef struct access_ticket {

gtimer_t at_timer;
char *at_resource;
access_t *at_access;
} access_ticket_t;

typedef struct access {
char *aa_username;
char *aa_representative;
uint32_t aa_rights;
htsmsg_t *aa_dvrcfgs;
uint32_t aa_chmin;
uint32_t aa_chmax;
htsmsg_t *aa_chtags;
int aa_match;
uint32_t aa_conn_limit;
} access_t;

#define ACCESS_ANONYMOUS 0
#define ACCESS_STREAMING (1<<0)
#define ACCESS_ADVANCED_STREAMING (1<<1)
Expand All @@ -118,12 +119,12 @@ typedef struct access {
/**
* Create a new ticket for the requested resource and generate a id for it
*/
const char* access_ticket_create(const char *resource);
const char* access_ticket_create(const char *resource, access_t *a);

/**
* Verifies that a given ticket id matches a resource
*/
int access_ticket_verify(const char *id, const char *resource);
access_t *access_ticket_verify2(const char *id, const char *resource);

int access_ticket_delete(const char *ticket_id);

Expand All @@ -132,6 +133,11 @@ int access_ticket_delete(const char *ticket_id);
*/
void access_destroy(access_t *a);

/**
* Copy the access structure
*/
access_t *access_copy(access_t *src);

/**
* Verifies that the given user in combination with the source ip
* complies with the requested mask
Expand Down
4 changes: 2 additions & 2 deletions src/htsp_server.c
Expand Up @@ -1653,15 +1653,15 @@ htsp_method_getTicket(htsp_connection_t *htsp, htsmsg_t *in)
return htsp_error("User does not have access");

snprintf(path, sizeof(path), "/stream/channelid/%d", id);
ticket = access_ticket_create(path);
ticket = access_ticket_create(path, htsp->htsp_granted_access);
} else if(!htsmsg_get_u32(in, "dvrId", &id)) {
if (!(de = dvr_entry_find_by_id(id)))
return htsp_error("DVR entry does not exist");
if (!htsp_user_access_channel(htsp, de->de_channel))
return htsp_error("User does not have access");

snprintf(path, sizeof(path), "/dvrfile/%d", id);
ticket = access_ticket_create(path);
ticket = access_ticket_create(path, htsp->htsp_granted_access);
} else {
return htsp_error("Missing argument 'channelId' or 'dvrId'");
}
Expand Down
23 changes: 12 additions & 11 deletions src/http.c
Expand Up @@ -410,19 +410,20 @@ http_redirect(http_connection_t *hc, const char *location,
*/
static int http_access_verify_ticket(http_connection_t *hc)
{
const char *ticket_id = http_arg_get(&hc->hc_req_args, "ticket");
const char *ticket_id;

if (hc->hc_ticket)
if (hc->hc_ticket || hc->hc_access)
return 0;
if(!access_ticket_verify(ticket_id, hc->hc_url)) {
char addrstr[50];
tcp_get_ip_str((struct sockaddr*)hc->hc_peer, addrstr, 50);
tvhlog(LOG_INFO, "HTTP", "%s: using ticket %s for %s",
addrstr, ticket_id, hc->hc_url);
hc->hc_ticket = 1;
return 0;
}
return -1;
ticket_id = http_arg_get(&hc->hc_req_args, "ticket");
hc->hc_access = access_ticket_verify2(ticket_id, hc->hc_url);
if (hc->hc_access == NULL)
return -1;
char addrstr[50];
tcp_get_ip_str((struct sockaddr*)hc->hc_peer, addrstr, 50);
tvhlog(LOG_INFO, "HTTP", "%s: using ticket %s for %s",
addrstr, ticket_id, hc->hc_url);
hc->hc_ticket = 1;
return 0;
}

/**
Expand Down
12 changes: 6 additions & 6 deletions src/webui/webui.c
Expand Up @@ -450,7 +450,7 @@ http_channel_playlist(http_connection_t *hc, channel_t *channel)
htsbuf_qprintf(hq, "#EXTM3U\n");
htsbuf_qprintf(hq, "#EXTINF:-1,%s\n", channel_get_name(channel));
htsbuf_qprintf(hq, "http://%s%s?ticket=%s", host, buf,
access_ticket_create(buf));
access_ticket_create(buf, hc->hc_access));

#if ENABLE_LIBAV
transcoder_props_t props;
Expand Down Expand Up @@ -506,7 +506,7 @@ http_tag_playlist(http_connection_t *hc, channel_tag_t *tag)
snprintf(buf, sizeof(buf), "/stream/channelid/%d", channel_get_id(ctm->ctm_channel));
htsbuf_qprintf(hq, "#EXTINF:-1,%s\n", channel_get_name(ctm->ctm_channel));
htsbuf_qprintf(hq, "http://%s%s?ticket=%s", host, buf,
access_ticket_create(buf));
access_ticket_create(buf, hc->hc_access));
htsbuf_qprintf(hq, "&mux=%s\n", muxer_container_type2txt(mc));
}

Expand Down Expand Up @@ -543,7 +543,7 @@ http_tag_list_playlist(http_connection_t *hc)
snprintf(buf, sizeof(buf), "/playlist/tagid/%d", idnode_get_short_uuid(&ct->ct_id));
htsbuf_qprintf(hq, "#EXTINF:-1,%s\n", ct->ct_name);
htsbuf_qprintf(hq, "http://%s%s?ticket=%s", host, buf,
access_ticket_create(buf));
access_ticket_create(buf, hc->hc_access));
htsbuf_qprintf(hq, "&mux=%s\n", muxer_container_type2txt(mc));
}

Expand Down Expand Up @@ -607,7 +607,7 @@ http_channel_list_playlist(http_connection_t *hc)

htsbuf_qprintf(hq, "#EXTINF:-1,%s\n", channel_get_name(ch));
htsbuf_qprintf(hq, "http://%s%s?ticket=%s", host, buf,
access_ticket_create(buf));
access_ticket_create(buf, hc->hc_access));
htsbuf_qprintf(hq, "&mux=%s\n", muxer_container_type2txt(mc));
}

Expand Down Expand Up @@ -662,7 +662,7 @@ http_dvr_list_playlist(http_connection_t *hc)

snprintf(buf, sizeof(buf), "/dvrfile/%s", uuid);
htsbuf_qprintf(hq, "http://%s%s?ticket=%s\n", host, buf,
access_ticket_create(buf));
access_ticket_create(buf, hc->hc_access));
}

http_output_content(hc, "audio/x-mpegurl");
Expand Down Expand Up @@ -702,7 +702,7 @@ http_dvr_playlist(http_connection_t *hc, dvr_entry_t *de)
htsbuf_qprintf(hq, "#EXT-X-PROGRAM-DATE-TIME:%s\n", buf);

snprintf(buf, sizeof(buf), "/dvrfile/%s", uuid);
ticket_id = access_ticket_create(buf);
ticket_id = access_ticket_create(buf, hc->hc_access);
htsbuf_qprintf(hq, "http://%s%s?ticket=%s\n", host, buf, ticket_id);

http_output_content(hc, "application/x-mpegURL");
Expand Down

0 comments on commit a510248

Please sign in to comment.