From 34edcf8b2e74030447c1d9973aca39f7cfb94735 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Tue, 9 Sep 2014 16:49:54 +0200 Subject: [PATCH] http: access - fix ticked based access --- src/access.c | 2 ++ src/http.c | 32 ++++++++++++++++++++------------ src/http.h | 4 +++- src/webui/webui.c | 10 +++++----- 4 files changed, 30 insertions(+), 18 deletions(-) diff --git a/src/access.c b/src/access.c index 442eb4ab..299b356c 100644 --- a/src/access.c +++ b/src/access.c @@ -160,6 +160,8 @@ access_ticket_verify(const char *id, const char *resource) void access_destroy(access_t *a) { + if (a == NULL) + return; free(a->aa_username); free(a->aa_representative); htsmsg_destroy(a->aa_dvrcfgs); diff --git a/src/http.c b/src/http.c index ef340c5c..0ad98b6a 100644 --- a/src/http.c +++ b/src/http.c @@ -403,11 +403,14 @@ static int http_access_verify_ticket(http_connection_t *hc) { const char *ticket_id = http_arg_get(&hc->hc_req_args, "ticket"); + if (hc->hc_ticket) + 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; @@ -422,13 +425,12 @@ http_access_verify(http_connection_t *hc, int mask) if (!http_access_verify_ticket(hc)) return 0; - if (hc->hc_access) - return access_verify2(hc->hc_access, mask); - - hc->hc_access = access_get(hc->hc_username, hc->hc_password, - (struct sockaddr *)hc->hc_peer); - if (hc->hc_access == NULL) - return -1; + if (hc->hc_access == NULL) { + hc->hc_access = access_get(hc->hc_username, hc->hc_password, + (struct sockaddr *)hc->hc_peer); + if (hc->hc_access == NULL) + return -1; + } return access_verify2(hc->hc_access, mask); } @@ -438,15 +440,22 @@ http_access_verify(http_connection_t *hc, int mask) */ int http_access_verify_channel(http_connection_t *hc, int mask, - struct channel *ch) + struct channel *ch, int ticket) { int res = -1; assert(ch); - if (!http_access_verify_ticket(hc)) + if (ticket && !http_access_verify_ticket(hc)) return 0; + if (hc->hc_access == NULL) { + hc->hc_access = access_get(hc->hc_username, hc->hc_password, + (struct sockaddr *)hc->hc_peer); + if (hc->hc_access == NULL) + return -1; + } + if (channel_access(ch, hc->hc_access, hc->hc_username)) res = 0; return res; @@ -465,12 +474,11 @@ http_exec(http_connection_t *hc, http_path_t *hp, char *remain) if(http_access_verify(hc, hp->hp_accessmask)) err = HTTP_STATUS_UNAUTHORIZED; - else { - /* FIXME: Recode to obtain access only once */ + else err = hp->hp_callback(hc, remain, hp->hp_opaque); - } access_destroy(hc->hc_access); hc->hc_access = NULL; + hc->hc_ticket = 0; if(err == -1) return 1; diff --git a/src/http.h b/src/http.h index 2b0d405c..7a4baf61 100644 --- a/src/http.h +++ b/src/http.h @@ -132,6 +132,7 @@ typedef struct http_connection { char *hc_username; char *hc_password; access_t *hc_access; + int hc_ticket; struct config_head *hc_user_config; @@ -208,7 +209,8 @@ void http_server_register(void); void http_server_done(void); int http_access_verify(http_connection_t *hc, int mask); -int http_access_verify_channel(http_connection_t *hc, int mask, struct channel *ch); +int http_access_verify_channel(http_connection_t *hc, int mask, + struct channel *ch, int ticket); void http_deescape(char *s); diff --git a/src/webui/webui.c b/src/webui/webui.c index c839a947..82234845 100644 --- a/src/webui/webui.c +++ b/src/webui/webui.c @@ -372,7 +372,7 @@ http_channel_playlist(http_connection_t *hc, channel_t *channel) const char *host; muxer_container_type_t mc; - if (http_access_verify_channel(hc, ACCESS_STREAMING, channel)) + if (http_access_verify_channel(hc, ACCESS_STREAMING, channel, 1)) return HTTP_STATUS_UNAUTHORIZED; mc = muxer_container_txt2type(http_arg_get(&hc->hc_req_args, "mux")); @@ -438,7 +438,7 @@ http_tag_playlist(http_connection_t *hc, channel_tag_t *tag) htsbuf_qprintf(hq, "#EXTM3U\n"); LIST_FOREACH(ctm, &tag->ct_ctms, ctm_tag_link) { - if (http_access_verify_channel(hc, ACCESS_STREAMING, ctm->ctm_channel)) + if (http_access_verify_channel(hc, ACCESS_STREAMING, ctm->ctm_channel, 0)) continue; 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)); @@ -537,7 +537,7 @@ http_channel_list_playlist(http_connection_t *hc) for (idx = 0; idx < count; idx++) { ch = chlist[idx]; - if (http_access_verify_channel(hc, ACCESS_STREAMING, ch)) + if (http_access_verify_channel(hc, ACCESS_STREAMING, ch, 0)) continue; snprintf(buf, sizeof(buf), "/stream/channelid/%d", channel_get_id(ch)); @@ -582,7 +582,7 @@ http_dvr_list_playlist(http_connection_t *hc) continue; if (de->de_channel && - http_access_verify_channel(hc, ACCESS_RECORDER, de->de_channel)) + http_access_verify_channel(hc, ACCESS_RECORDER, de->de_channel, 0)) continue; @@ -859,7 +859,7 @@ http_stream_channel(http_connection_t *hc, channel_t *ch, int weight) const char *name; char addrbuf[50]; - if (http_access_verify_channel(hc, ACCESS_STREAMING, ch)) + if (http_access_verify_channel(hc, ACCESS_STREAMING, ch, 1)) return HTTP_STATUS_UNAUTHORIZED; cfg = dvr_config_find_by_name_default("");