Ejemplo n.º 1
0
static int open_input(struct variant *var)
{
    AVDictionary *opts = NULL;
    int ret;
    struct segment *seg = var->segments[var->cur_seq_no - var->start_seq_no];
    av_dict_set(&opts, "seekable", "0", 0);
    if (seg->key_type == KEY_NONE) {
        ret = ffurl_open(&var->input, seg->url, AVIO_FLAG_READ,
                          &var->parent->interrupt_callback, &opts);
        goto cleanup;
    } else if (seg->key_type == KEY_AES_128) {
        char iv[33], key[33], url[MAX_URL_SIZE];
        if (strcmp(seg->key, var->key_url)) {
            URLContext *uc;
            if (ffurl_open(&uc, seg->key, AVIO_FLAG_READ,
                           &var->parent->interrupt_callback, &opts) == 0) {
                if (ffurl_read_complete(uc, var->key, sizeof(var->key))
                    != sizeof(var->key)) {
                    av_log(NULL, AV_LOG_ERROR, "Unable to read key file %s\n",
                           seg->key);
                }
                ffurl_close(uc);
            } else {
                av_log(NULL, AV_LOG_ERROR, "Unable to open key file %s\n",
                       seg->key);
            }
            av_strlcpy(var->key_url, seg->key, sizeof(var->key_url));
        }
        ff_data_to_hex(iv, seg->iv, sizeof(seg->iv), 0);
        ff_data_to_hex(key, var->key, sizeof(var->key), 0);
        iv[32] = key[32] = '\0';
        if (strstr(seg->url, "://"))
            snprintf(url, sizeof(url), "crypto+%s", seg->url);
        else
            snprintf(url, sizeof(url), "crypto:%s", seg->url);
        if ((ret = ffurl_alloc(&var->input, url, AVIO_FLAG_READ,
                               &var->parent->interrupt_callback)) < 0)
            goto cleanup;
        av_opt_set(var->input->priv_data, "key", key, 0);
        av_opt_set(var->input->priv_data, "iv", iv, 0);
        /* Need to repopulate options */
        av_dict_free(&opts);
        av_dict_set(&opts, "seekable", "0", 0);
        if ((ret = ffurl_connect(var->input, &opts)) < 0) {
            ffurl_close(var->input);
            var->input = NULL;
            goto cleanup;
        }
        ret = 0;
    }
    else
      ret = AVERROR(ENOSYS);

cleanup:
    av_dict_free(&opts);
    return ret;
}
Ejemplo n.º 2
0
static int open_input(struct variant *var)
{
    struct segment *seg = var->segments[var->cur_seq_no - var->start_seq_no];
    if (seg->key_type == KEY_NONE) {
        return ffurl_open(&var->input, seg->url, AVIO_FLAG_READ);
    } else if (seg->key_type == KEY_AES_128) {
        char iv[33], key[33], url[MAX_URL_SIZE];
        int ret;
        if (strcmp(seg->key, var->key_url)) {
            URLContext *uc;
            if (ffurl_open(&uc, seg->key, AVIO_FLAG_READ) == 0) {
                if (ffurl_read_complete(uc, var->key, sizeof(var->key))
                    != sizeof(var->key)) {
                    av_log(NULL, AV_LOG_ERROR, "Unable to read key file %s\n",
                           seg->key);
                }
                ffurl_close(uc);
            } else {
                av_log(NULL, AV_LOG_ERROR, "Unable to open key file %s\n",
                       seg->key);
            }
            av_strlcpy(var->key_url, seg->key, sizeof(var->key_url));
        }
        ff_data_to_hex(iv, seg->iv, sizeof(seg->iv), 0);
        ff_data_to_hex(key, var->key, sizeof(var->key), 0);
        iv[32] = key[32] = '\0';
        if (strstr(seg->url, "://"))
            snprintf(url, sizeof(url), "crypto+%s", seg->url);
        else
            snprintf(url, sizeof(url), "crypto:%s", seg->url);
        if ((ret = ffurl_alloc(&var->input, url, AVIO_FLAG_READ)) < 0)
            return ret;
        av_set_string3(var->input->priv_data, "key", key, 0, NULL);
        av_set_string3(var->input->priv_data, "iv", iv, 0, NULL);
        if ((ret = ffurl_connect(var->input)) < 0) {
            ffurl_close(var->input);
            var->input = NULL;
            return ret;
        }
        return 0;
    }
    return AVERROR(ENOSYS);
}
Ejemplo n.º 3
0
static char *extradata2config(AVCodecContext *c)
{
    char *config;

    if (c->extradata_size > MAX_EXTRADATA_SIZE) {
        av_log(c, AV_LOG_ERROR, "Too much extradata!\n");

        return NULL;
    }
    config = av_malloc(10 + c->extradata_size * 2);
    if (config == NULL) {
        av_log(c, AV_LOG_ERROR, "Cannot allocate memory for the config info.\n");
        return NULL;
    }
    memcpy(config, "; config=", 9);
    ff_data_to_hex(config + 9, c->extradata, c->extradata_size, 0);
    config[9 + c->extradata_size * 2] = 0;

    return config;
}
Ejemplo n.º 4
0
void
ff_rdt_calc_response_and_checksum(char response[41], char chksum[9],
                                  const char *challenge)
{
	int ch_len = strlen (challenge), i;
	unsigned char zres[16],
	         buf[64] = { 0xa1, 0xe9, 0x14, 0x9d, 0x0e, 0x6b, 0x3b, 0x59 };
#define XOR_TABLE_SIZE 37
	const unsigned char xor_table[XOR_TABLE_SIZE] =
	{
		0x05, 0x18, 0x74, 0xd0, 0x0d, 0x09, 0x02, 0x53,
		0xc0, 0x01, 0x05, 0x05, 0x67, 0x03, 0x19, 0x70,
		0x08, 0x27, 0x66, 0x10, 0x10, 0x72, 0x08, 0x09,
		0x63, 0x11, 0x03, 0x71, 0x08, 0x08, 0x70, 0x02,
		0x10, 0x57, 0x05, 0x18, 0x54
	};

	/* some (length) checks */
	if (ch_len == 40) /* what a hack... */
		ch_len = 32;
	else if (ch_len > 56)
		ch_len = 56;
	memcpy(buf + 8, challenge, ch_len);

	/* xor challenge bytewise with xor_table */
	for (i = 0; i < XOR_TABLE_SIZE; i++)
		buf[8 + i] ^= xor_table[i];

	av_md5_sum(zres, buf, 64);
	ff_data_to_hex(response, zres, 16, 1);

	/* add tail */
	strcpy (response + 32, "01d0a8e3");

	/* calculate checksum */
	for (i = 0; i < 8; i++)
		chksum[i] = response[i * 4];
	chksum[8] = 0;
}
Ejemplo n.º 5
0
static void *circular_buffer_task( void *_handle)
{
    CacheHttpContext * s = (CacheHttpContext *)_handle;
    URLContext *h = NULL;
    float config_value = 0.0;
    void * fp = NULL;
    int config_ret = 0;

    while(!s->EXIT) {

        av_log(h, AV_LOG_ERROR, "----------circular_buffer_task  item ");
        s->reset_flag = 1;
        if (url_interrupt_cb()) {
            s->circular_buffer_error = EINTR;
            goto FAIL;
        }

        if(h) {
            CacheHttp_ffurl_close(h);
            config_ret = am_getconfig_float("libplayer.hls.dump",&config_value);
            if(config_ret >= 0 && (int)config_value == 2)
                CacheHttp_dump_close(fp);
            h = NULL;
        }

        list_item_t * item = getCurrentSegment(NULL);
        if(!item||(!item->file&&!item->flags&ENDLIST_FLAG)) {
            usleep(WAIT_TIME);
            continue;
        }

        s->reset_flag = 0;
        s->item_starttime = item->start_time;
        s->item_duration = item->duration;
        s->have_list_end = item->have_list_end;
        s->ktype = item->ktype;
        if(item->key_ctx!=NULL&& s->ktype==KEY_AES_128) {
            ff_data_to_hex(s->iv, item->key_ctx->iv, sizeof(item->key_ctx->iv), 0);
            ff_data_to_hex(s->key, item->key_ctx->key, sizeof(item->key_ctx->key), 0);
            s->iv[32] = s->key[32] = '\0';
        }
        if(item&&item->flags&ENDLIST_FLAG) {
            s->finish_flag =1;
        } else {
            s->finish_flag =0;
        }

        if(s->finish_flag) {
            av_log(NULL, AV_LOG_INFO, "ENDLIST_FLAG, return 0\n");
            //break;
            usleep(500*1000);
            continue;
        }

        int err, http_code;
        char* filename = NULL;
        if(s->ktype == KEY_NONE) {
            filename = av_strdup(item->file);

        } else {
            char url[MAX_URL_SIZE];
            if (strstr(item->file, "://"))
                snprintf(url, sizeof(url), "crypto+%s", item->file);
            else
                snprintf(url, sizeof(url), "crypto:%s", item->file);

            filename = av_strdup(url);

        }
        int retry_num = 0;
OPEN_RETRY:
        if(s->RESET)
            goto SKIP;
        err = CacheHttp_advanced_ffurl_open_h(&h, filename,AVIO_FLAG_READ|AVIO_FLAG_NONBLOCK, s->headers, &http_code,s);
        if (err) {
            if(url_interrupt_cb()) {
                if(filename) {
                    av_free(filename);
                    filename = NULL;
                }
                break;
            }
            if(1 == http_code && !s->have_list_end) {
                av_log(h, AV_LOG_ERROR, "----------CacheHttpContext : ffurl_open_h 404\n");
                if(retry_num++ < LIVE_HTTP_RETRY_TIMES) {
                    usleep(WAIT_TIME);
                    goto OPEN_RETRY;
                } else {
                    goto SKIP;
                }
            } else if(s->have_list_end || ((2 == http_code || 3 == http_code)&& !s->have_list_end)) {
                usleep(1000*20);
                goto OPEN_RETRY;
            } else if(!s->have_list_end&&err ==AVERROR(EIO)) {
                if(retry_num++ < LIVE_HTTP_RETRY_TIMES) {//if live streaming,just keep on 2s.
                    usleep(WAIT_TIME);
                    goto OPEN_RETRY;
                } else {
                    av_log(h, AV_LOG_ERROR, "----------CacheHttpContext : ffurl_open_h failed ,%d\n",err);
                    if(filename) {
                        av_free(filename);
                        filename = NULL;
                    }
                    break;
                }

            } else {
                av_log(h, AV_LOG_ERROR, "----------CacheHttpContext : ffurl_open_h failed ,%d\n",err);
                if(filename) {
                    av_free(filename);
                    filename = NULL;
                }
                break;
            }
        }

        if(h && s->seek_flag) {
            int64_t cur_pos = CacheHttp_ffurl_seek(h, 0, SEEK_CUR);
            int64_t pos_ret = CacheHttp_ffurl_seek(h, s->seek_pos-cur_pos, SEEK_CUR);
            av_log(NULL,AV_LOG_INFO,"--------------> cachehttp_seek   seek_pos=%lld, pos_ret=%lld", s->seek_pos, pos_ret);
            s->seek_flag = 0;
        }

        s->hd = h;
        s->item_pos = 0;
        s->item_size = CacheHttp_ffurl_seek(s->hd, 0, AVSEEK_SIZE);
        item->item_size = s->item_size;
        char tmpbuf[TMP_BUFFER_SIZE];
        int left = 0;
        int tmpdatasize = 0;
        config_ret = am_getconfig_float("libplayer.hls.dump",&config_value);
        if(config_ret >= 0 && config_value > 0)
            CacheHttp_dump_open(&fp, filename, (int)config_value);

        while(!s->EXIT) {

            if(s->RESET)
                break;

            if (url_interrupt_cb()) {
                s->circular_buffer_error = EINTR;
                break;
            }

            if(!s->hd)
                break;

            if(s->hd && tmpdatasize <= 0) {
                bandwidth_measure_start_read(s->bandwidth_measure);
                tmpdatasize = CacheHttp_ffurl_read(s->hd, tmpbuf, TMP_BUFFER_SIZE);
                bandwidth_measure_finish_read(s->bandwidth_measure,tmpdatasize);
            }

            //if(tmpdatasize > 0) {
            pthread_mutex_lock(&s->read_mutex);
            left = av_fifo_space(s->fifo);
            left = FFMIN(left, s->fifo->end - s->fifo->wptr);


            if( !left) {
                pthread_mutex_unlock(&s->read_mutex);
                usleep(WAIT_TIME);
                continue;
            }
            left = FFMIN(left, tmpdatasize);
            if(left >0) {
                memcpy(s->fifo->wptr, tmpbuf , left);
                tmpdatasize-=left;
            }
            if(tmpdatasize>0) {
                memmove(tmpbuf, tmpbuf+left , tmpdatasize);
            }

            if (left > 0) {
                config_ret = am_getconfig_float("libplayer.hls.dump",&config_value);
                if(config_ret >= 0 && config_value > 0)
                    CacheHttp_dump_write(fp, s->fifo->wptr, left);
                s->fifo->wptr += left;
                if (s->fifo->wptr >= s->fifo->end)
                    s->fifo->wptr = s->fifo->buffer;
                s->fifo->wndx += left;
                s->item_pos += left;
            } else if(left == AVERROR(EAGAIN) || (left < 0 && s->have_list_end&& left != AVERROR_EOF)) {
                pthread_mutex_unlock(&s->read_mutex);
                continue;
            } else {
                pthread_mutex_unlock(&s->read_mutex);
                av_log(h, AV_LOG_ERROR, "---------- circular_buffer_task read left = %d\n", left);
                break;
            }
            pthread_mutex_unlock(&s->read_mutex);
            //}

            //usleep(WAIT_TIME);

        }

SKIP:
        if(filename) {
            av_free(filename);
            filename = NULL;
        }
        if(!s->RESET)
            switchNextSegment(NULL);
    }

FAIL:

    if(h)
        CacheHttp_ffurl_close(h);
    s->hd = NULL;
    s->EXITED = 1;
    config_ret = am_getconfig_float("libplayer.hls.dump",&config_value);
    if(config_ret >= 0 && config_value > 0)
        CacheHttp_dump_close(fp);
    av_log(NULL, AV_LOG_ERROR, "---------> CacheHttp thread quit !");
    return NULL;
}
Ejemplo n.º 6
0
/* Generate a digest reply, according to RFC 2617. */
static char *make_digest_auth(HTTPAuthState *state, const char *username,
                              const char *password, const char *uri,
                              const char *method)
{
    DigestParams *digest = &state->digest_params;
    int len;
    uint32_t cnonce_buf[2];
    char cnonce[17];
    char nc[9];
    int i;
    char A1hash[33], A2hash[33], response[33];
    struct AVMD5 *md5ctx;
    uint8_t hash[16];
    char *authstr;

    digest->nc++;
    snprintf(nc, sizeof(nc), "%08x", digest->nc);

    /* Generate a client nonce. */
    for (i = 0; i < 2; i++)
        cnonce_buf[i] = av_get_random_seed();
    ff_data_to_hex(cnonce, (const uint8_t*) cnonce_buf, sizeof(cnonce_buf), 1);
    cnonce[2*sizeof(cnonce_buf)] = 0;

    md5ctx = av_md5_alloc();
    if (!md5ctx)
        return NULL;

    av_md5_init(md5ctx);
    update_md5_strings(md5ctx, username, ":", state->realm, ":", password, NULL);
    av_md5_final(md5ctx, hash);
    ff_data_to_hex(A1hash, hash, 16, 1);
    A1hash[32] = 0;

    if (!strcmp(digest->algorithm, "") || !strcmp(digest->algorithm, "MD5")) {
    } else if (!strcmp(digest->algorithm, "MD5-sess")) {
        av_md5_init(md5ctx);
        update_md5_strings(md5ctx, A1hash, ":", digest->nonce, ":", cnonce, NULL);
        av_md5_final(md5ctx, hash);
        ff_data_to_hex(A1hash, hash, 16, 1);
        A1hash[32] = 0;
    } else {
        /* Unsupported algorithm */
        av_free(md5ctx);
        return NULL;
    }

    av_md5_init(md5ctx);
    update_md5_strings(md5ctx, method, ":", uri, NULL);
    av_md5_final(md5ctx, hash);
    ff_data_to_hex(A2hash, hash, 16, 1);
    A2hash[32] = 0;

    av_md5_init(md5ctx);
    update_md5_strings(md5ctx, A1hash, ":", digest->nonce, NULL);
    if (!strcmp(digest->qop, "auth") || !strcmp(digest->qop, "auth-int")) {
        update_md5_strings(md5ctx, ":", nc, ":", cnonce, ":", digest->qop, NULL);
    }
    update_md5_strings(md5ctx, ":", A2hash, NULL);
    av_md5_final(md5ctx, hash);
    ff_data_to_hex(response, hash, 16, 1);
    response[32] = 0;

    av_free(md5ctx);

    if (!strcmp(digest->qop, "") || !strcmp(digest->qop, "auth")) {
    } else if (!strcmp(digest->qop, "auth-int")) {
        /* qop=auth-int not supported */
        return NULL;
    } else {
        /* Unsupported qop value. */
        return NULL;
    }

    len = strlen(username) + strlen(state->realm) + strlen(digest->nonce) +
              strlen(uri) + strlen(response) + strlen(digest->algorithm) +
              strlen(digest->opaque) + strlen(digest->qop) + strlen(cnonce) +
              strlen(nc) + 150;

    authstr = av_malloc(len);
    if (!authstr)
        return NULL;
    snprintf(authstr, len, "Authorization: Digest ");

    /* TODO: Escape the quoted strings properly. */
    av_strlcatf(authstr, len, "username=\"%s\"",   username);
    av_strlcatf(authstr, len, ", realm=\"%s\"",     state->realm);
    av_strlcatf(authstr, len, ", nonce=\"%s\"",     digest->nonce);
    av_strlcatf(authstr, len, ", uri=\"%s\"",       uri);
    av_strlcatf(authstr, len, ", response=\"%s\"",  response);

    if (digest->algorithm[0])
        av_strlcatf(authstr, len, ", algorithm=%s",  digest->algorithm);
    if (digest->opaque[0])
        av_strlcatf(authstr, len, ", opaque=\"%s\"", digest->opaque);
    if (digest->qop[0]) {
        av_strlcatf(authstr, len, ", qop=\"%s\"",    digest->qop);
        av_strlcatf(authstr, len, ", cnonce=\"%s\"", cnonce);
        av_strlcatf(authstr, len, ", nc=%s",         nc);
    }

    av_strlcatf(authstr, len, "\r\n");

    return authstr;
}
Ejemplo n.º 7
0
static int open_input(HLSContext *c, struct playlist *pls)
{
    AVDictionary *opts = NULL;
    AVDictionary *opts2 = NULL;
    int ret;
    struct segment *seg = pls->segments[pls->cur_seq_no - pls->start_seq_no];

    // broker prior HTTP options that should be consistent across requests
    av_dict_set(&opts, "user-agent", c->user_agent, 0);
    av_dict_set(&opts, "cookies", c->cookies, 0);
    av_dict_set(&opts, "headers", c->headers, 0);
    av_dict_set(&opts, "seekable", "0", 0);

    // Same opts for key request (ffurl_open mutilates the opts so it cannot be used twice)
    av_dict_copy(&opts2, opts, 0);

    if (seg->key_type == KEY_NONE) {
        ret = ffurl_open(&pls->input, seg->url, AVIO_FLAG_READ,
                          &pls->parent->interrupt_callback, &opts);
        goto cleanup;
    } else if (seg->key_type == KEY_AES_128) {
        char iv[33], key[33], url[MAX_URL_SIZE];
        if (strcmp(seg->key, pls->key_url)) {
            URLContext *uc;
            if (ffurl_open(&uc, seg->key, AVIO_FLAG_READ,
                           &pls->parent->interrupt_callback, &opts2) == 0) {
                if (ffurl_read_complete(uc, pls->key, sizeof(pls->key))
                    != sizeof(pls->key)) {
                    av_log(NULL, AV_LOG_ERROR, "Unable to read key file %s\n",
                           seg->key);
                }
                ffurl_close(uc);
            } else {
                av_log(NULL, AV_LOG_ERROR, "Unable to open key file %s\n",
                       seg->key);
            }
            av_strlcpy(pls->key_url, seg->key, sizeof(pls->key_url));
        }
        ff_data_to_hex(iv, seg->iv, sizeof(seg->iv), 0);
        ff_data_to_hex(key, pls->key, sizeof(pls->key), 0);
        iv[32] = key[32] = '\0';
        if (strstr(seg->url, "://"))
            snprintf(url, sizeof(url), "crypto+%s", seg->url);
        else
            snprintf(url, sizeof(url), "crypto:%s", seg->url);
        if ((ret = ffurl_alloc(&pls->input, url, AVIO_FLAG_READ,
                               &pls->parent->interrupt_callback)) < 0)
            goto cleanup;
        av_opt_set(pls->input->priv_data, "key", key, 0);
        av_opt_set(pls->input->priv_data, "iv", iv, 0);

        if ((ret = ffurl_connect(pls->input, &opts)) < 0) {
            ffurl_close(pls->input);
            pls->input = NULL;
            goto cleanup;
        }
        ret = 0;
    }
    else
      ret = AVERROR(ENOSYS);

cleanup:
    av_dict_free(&opts);
    av_dict_free(&opts2);
    return ret;
}