Skip to content

Commit

Permalink
For #1109, Support without ssl for HLS key.
Browse files Browse the repository at this point in the history
  • Loading branch information
winlinvip committed Aug 25, 2018
1 parent 522fba9 commit ee068cf
Show file tree
Hide file tree
Showing 6 changed files with 184 additions and 153 deletions.
2 changes: 1 addition & 1 deletion circle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ dependencies:

test:
override:
- (cd trunk && ./configure --with-ssl=openssl --without-valgrind && make)
- (cd trunk && ./configure --without-ssl --without-valgrind && make)
- (cd trunk && ./objs/srs_utest)

10 changes: 5 additions & 5 deletions trunk/configure
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ CORE_OBJS="${MODULE_OBJS[@]}"
#Kernel, depends on core, provides error/log/config, nothing about stream information.
MODULE_ID="KERNEL"
MODULE_DEPENDS=("CORE")
ModuleLibIncs=(${SRS_OBJS_DIR})
ModuleLibIncs=(${SRS_OBJS_DIR} ${LibSSLRoot})
MODULE_FILES=("srs_kernel_error" "srs_kernel_log" "srs_kernel_buffer"
"srs_kernel_utility" "srs_kernel_flv" "srs_kernel_codec" "srs_kernel_io"
"srs_kernel_consts" "srs_kernel_aac" "srs_kernel_mp3" "srs_kernel_ts"
Expand All @@ -177,7 +177,7 @@ PROTOCOL_OBJS="${MODULE_OBJS[@]}"
if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
MODULE_ID="SERVICE"
MODULE_DEPENDS=("CORE" "KERNEL" "PROTOCOL")
ModuleLibIncs=(${LibSTRoot} ${SRS_OBJS_DIR})
ModuleLibIncs=(${LibSTRoot} ${SRS_OBJS_DIR} ${LibSSLRoot})
MODULE_FILES=("srs_service_log" "srs_service_st" "srs_service_http_client"
"srs_service_http_conn" "srs_service_rtmp_conn" "srs_service_utility"
"srs_service_conn")
Expand All @@ -190,7 +190,7 @@ fi
if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
MODULE_ID="APP"
MODULE_DEPENDS=("CORE" "KERNEL" "PROTOCOL" "SERVICE")
ModuleLibIncs=(${LibSTRoot} ${SRS_OBJS_DIR})
ModuleLibIncs=(${LibSTRoot} ${SRS_OBJS_DIR} ${LibSSLRoot})
MODULE_FILES=("srs_app_server" "srs_app_conn" "srs_app_rtmp_conn" "srs_app_source"
"srs_app_refer" "srs_app_hls" "srs_app_forward" "srs_app_encoder" "srs_app_http_stream"
"srs_app_thread" "srs_app_bandwidth" "srs_app_st" "srs_app_log" "srs_app_config"
Expand Down Expand Up @@ -225,7 +225,7 @@ LIBS_OBJS="${MODULE_OBJS[@]}"
if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
MODULE_ID="SERVER"
MODULE_DEPENDS=("CORE" "KERNEL" "PROTOCOL" "SERVICE" "APP")
ModuleLibIncs=(${LibSTRoot} ${SRS_OBJS_DIR} ${LibGperfRoot})
ModuleLibIncs=(${LibSTRoot} ${SRS_OBJS_DIR} ${LibGperfRoot} ${LibSSLRoot})
MODULE_FILES=("srs_main_server")
SERVER_INCS="src/main"; MODULE_DIR=${SERVER_INCS} . auto/modules.sh
SERVER_OBJS="${MODULE_OBJS[@]}"
Expand All @@ -235,7 +235,7 @@ fi
if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
MODULE_ID="MAIN"
MODULE_DEPENDS=("CORE" "KERNEL" "PROTOCOL" "SERVICE")
ModuleLibIncs=(${LibSTRoot} ${SRS_OBJS_DIR} ${LibGperfRoot})
ModuleLibIncs=(${LibSTRoot} ${SRS_OBJS_DIR} ${LibGperfRoot} ${LibSSLRoot})
MODULE_FILES=()
DEFINES=""
# add each modules for main
Expand Down
141 changes: 79 additions & 62 deletions trunk/src/app/srs_app_hls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ using namespace std;
#include <srs_app_http_hooks.hpp>
#include <srs_protocol_format.hpp>

#ifdef SRS_AUTO_SSL
#include <openssl/rand.h>
#endif

// drop the segment when duration of ts too small.
#define SRS_AUTO_HLS_SEGMENT_MIN_DURATION_MS 100
Expand All @@ -62,25 +64,26 @@ using namespace std;
// reset the piece id when deviation overflow this.
#define SRS_JUMP_WHEN_PIECE_DEVIATION 20

SrsHlsSegment::SrsHlsSegment(SrsTsContext* c, SrsAudioCodecId ac, SrsVideoCodecId vc, SrsFileWriter *srswriter)
SrsHlsSegment::SrsHlsSegment(SrsTsContext* c, SrsAudioCodecId ac, SrsVideoCodecId vc, SrsFileWriter* w)
{
sequence_no = 0;

writer = srswriter;

writer = w;
tscw = new SrsTsContextWriter(writer, c, ac, vc);
}

void SrsHlsSegment::SrsSetEncCfg(unsigned char* keyval,unsigned char *ivval)
SrsHlsSegment::~SrsHlsSegment()
{
memcpy(iv,ivval,16);
dynamic_cast<SrsEncFileWriter*>(writer)->SetEncCfg(keyval,ivval);
srs_freep(tscw);
}

SrsHlsSegment::~SrsHlsSegment()
void SrsHlsSegment::config_cipher(unsigned char* key,unsigned char* iv)
{
srs_freep(tscw);
//srs_freep(writer);
memcpy(this->iv, iv,16);

#ifdef SRS_AUTO_SSL
SrsEncFileWriter* fw = (SrsEncFileWriter*)writer;
fw->config_cipher(key, iv);
#endif
}

SrsDvrAsyncCallOnHls::SrsDvrAsyncCallOnHls(int c, SrsRequest* r, string p, string t, string m, string mu, int s, double d)
Expand Down Expand Up @@ -208,6 +211,9 @@ SrsHlsMuxer::SrsHlsMuxer()
async = new SrsAsyncCallWorker();
context = new SrsTsContext();
segments = new SrsFragmentWindow();

memset(key, 0, 16);
memset(iv, 0, 16);
}

SrsHlsMuxer::~SrsHlsMuxer()
Expand Down Expand Up @@ -280,7 +286,7 @@ srs_error_t SrsHlsMuxer::update_config(SrsRequest* r, string entry_prefix,
string path, string m3u8_file, string ts_file, double fragment, double window,
bool ts_floor, double aof_ratio, bool cleanup, bool wait_keyframe, bool keys,
int fragments_per_key, string key_file ,string key_file_path, string key_url)
{
{
srs_error_t err = srs_success;

srs_freep(req);
Expand Down Expand Up @@ -318,8 +324,7 @@ srs_error_t SrsHlsMuxer::update_config(SrsRequest* r, string entry_prefix,
return srs_error_wrap(err, "create dir");
}

if(hls_keys && (hls_path != hls_key_file_path) )
{
if (hls_keys && (hls_path != hls_key_file_path)) {
string key_file = hls_key_file;
key_file = srs_path_build_stream(key_file, req->vhost, req->app, req->stream);

Expand All @@ -329,12 +334,13 @@ srs_error_t SrsHlsMuxer::update_config(SrsRequest* r, string entry_prefix,
}
}

if(hls_keys)
{
if(hls_keys) {
#ifdef SRS_AUTO_SSL
writer = new SrsEncFileWriter();
}
else
{
#else
writer = new SrsFileWriter();
#endif
} else {
writer = new SrsFileWriter();
}

Expand Down Expand Up @@ -382,54 +388,13 @@ srs_error_t SrsHlsMuxer::segment_open()
}

// new segment.
current = new SrsHlsSegment(context, default_acodec, default_vcodec,writer);
current = new SrsHlsSegment(context, default_acodec, default_vcodec, writer);
current->sequence_no = _sequence_no++;

if(hls_keys){

if(current->sequence_no % hls_fragments_per_key == 0)
{
string key_file = hls_key_file;
key_file = srs_path_build_stream(key_file, req->vhost, req->app, req->stream);

if (true) {
std::stringstream ss;
ss << current->sequence_no;
key_file = srs_string_replace(key_file, "[seq]", ss.str());
}

string key_full_path = hls_key_file_path + "/" + key_file;

if (RAND_bytes(key, 16) < 0) {
srs_error_wrap(err, "rand key failed.");
}

if (RAND_bytes(iv, 16) < 0) {
srs_error_wrap(err, "rand iv failed.");
}

int flags = O_CREAT|O_WRONLY|O_TRUNC;
mode_t mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH;
int fd;

if ((fd = ::open(key_full_path.c_str(), flags, mode)) < 0) {
return srs_error_new(ERROR_SYSTEM_FILE_OPENE, "open file %s failed", key_full_path.c_str());
}
ssize_t nwrite;
if ((nwrite = ::write(fd, key, 16)) != 16) {
return srs_error_new(ERROR_SYSTEM_FILE_WRITE, "write to file %s failed", key_full_path.c_str());
}

if (::close(fd) < 0) {
srs_warn("close file %s failed",key_full_path.c_str());
}

}
current->SrsSetEncCfg(key,iv);

if ((err = write_hls_key()) != srs_success) {
return srs_error_wrap(err, "write hls key");
}


// generate filename.
std::string ts_file = hls_ts_file;
ts_file = srs_path_build_stream(ts_file, req->vhost, req->app, req->stream);
Expand Down Expand Up @@ -688,6 +653,58 @@ srs_error_t SrsHlsMuxer::segment_close()
return err;
}

srs_error_t SrsHlsMuxer::write_hls_key()
{
srs_error_t err = srs_success;

#ifndef SRS_AUTO_SSL
if (hls_keys) {
srs_warn("SSL is disabled, ignore HLS key");
}
#endif

#ifdef SRS_AUTO_SSL
if (hls_keys && current->sequence_no % hls_fragments_per_key == 0) {
string key_file = hls_key_file;
key_file = srs_path_build_stream(key_file, req->vhost, req->app, req->stream);

if (true) {
std::stringstream ss;
ss << current->sequence_no;
key_file = srs_string_replace(key_file, "[seq]", ss.str());
}

string key_full_path = hls_key_file_path + "/" + key_file;

if (RAND_bytes(key, 16) < 0) {
srs_error_wrap(err, "rand key failed.");
}

if (RAND_bytes(iv, 16) < 0) {
srs_error_wrap(err, "rand iv failed.");
}

SrsFileWriter fw;

if ((err = fw.open(key_full_path)) != srs_success) {
return srs_error_wrap(err, "open file %s", key_full_path.c_str());
}

if ((err = fw.write(key, 16, NULL)) != srs_success) {
return srs_error_wrap(err, "write key");
}

fw.close();
}

if (hls_keys) {
current->config_cipher(key, iv);
}
#endif

return err;
}

srs_error_t SrsHlsMuxer::refresh_m3u8()
{
srs_error_t err = srs_success;
Expand Down
27 changes: 10 additions & 17 deletions trunk/src/app/srs_app_hls.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,11 @@ class SrsHlsSegment : public SrsFragment
unsigned char iv[16];
// The full key path.
std::string keypath;

public:
SrsHlsSegment(SrsTsContext* c, SrsAudioCodecId ac, SrsVideoCodecId vc, SrsFileWriter *srswriter);
SrsHlsSegment(SrsTsContext* c, SrsAudioCodecId ac, SrsVideoCodecId vc, SrsFileWriter* w);
virtual ~SrsHlsSegment();
public:

void SrsSetEncCfg(unsigned char* keyval,unsigned char * ivval);


void config_cipher(unsigned char* key,unsigned char* iv);
};

/**
Expand Down Expand Up @@ -156,24 +152,20 @@ class SrsHlsMuxer
// used to detect the dup or jmp or ts.
int64_t accept_floor_ts;
int64_t previous_floor_ts;

private:
//encrypted or not
// encrypted or not
bool hls_keys;
int hls_fragments_per_key;
//key file name
// key file name
std::string hls_key_file;
//key file path
// key file path
std::string hls_key_file_path;
//key file url
// key file url
std::string hls_key_url;

// key and iv.
unsigned char key[16];
unsigned char iv[16];

SrsFileWriter *writer;


private:
int _sequence_no;
int max_td;
Expand Down Expand Up @@ -210,8 +202,8 @@ class SrsHlsMuxer
virtual srs_error_t update_config(SrsRequest* r, std::string entry_prefix,
std::string path, std::string m3u8_file, std::string ts_file,
double fragment, double window, bool ts_floor, double aof_ratio,
bool cleanup, bool wait_keyframe , bool keys, int fragments_per_key,
std::string key_file , std::string key_file_path,std::string key_url);
bool cleanup, bool wait_keyframe, bool keys, int fragments_per_key,
std::string key_file, std::string key_file_path, std::string key_url);
/**
* open a new segment(a new ts file)
*/
Expand Down Expand Up @@ -244,6 +236,7 @@ class SrsHlsMuxer
*/
virtual srs_error_t segment_close();
private:
virtual srs_error_t write_hls_key();
virtual srs_error_t refresh_m3u8();
virtual srs_error_t _refresh_m3u8(std::string m3u8_file);
};
Expand Down
Loading

0 comments on commit ee068cf

Please sign in to comment.