Adds the Janus_pin to shared_memory, and a -j to zmu to fetch it

add_janus_rtsp_user
Jonathan Bennett 2022-09-05 17:18:23 -05:00
parent db3017de7d
commit c35bbc8c30
12 changed files with 52 additions and 33 deletions

View File

@ -180,6 +180,7 @@ our %mem_data = (
alarm_cause => { type=>'int8[256]', seq=>$mem_seq++ },
video_fifo => { type=>'int8[64]', seq=>$mem_seq++ },
audio_fifo => { type=>'int8[64]', seq=>$mem_seq++ },
janus_pin => { type=>'int8[64]', seq=>$mem_seq++ },
}
},
trigger_data => { type=>'TriggerData', seq=>$mem_seq++, 'contents'=> {

View File

@ -967,6 +967,7 @@ bool Monitor::connect() {
shared_data->alarm_cause[0] = 0;
shared_data->video_fifo_path[0] = 0;
shared_data->audio_fifo_path[0] = 0;
shared_data->janus_pin[0] = 0;
shared_data->last_frame_score = 0;
shared_data->audio_frequency = -1;
shared_data->audio_channels = -1;

View File

@ -228,7 +228,7 @@ protected:
char alarm_cause[256];
char video_fifo_path[64];
char audio_fifo_path[64];
char janus_pin[64];
} SharedData;
enum TriggerState : uint32 {
@ -355,7 +355,6 @@ protected:
int get_janus_session();
int get_janus_handle();
int get_janus_plugin();
std::string get_stream_key();
};
@ -377,6 +376,7 @@ protected:
bool janus_audio_enabled; // Whether we tell Janus to try to include audio.
std::string janus_profile_override; // The Profile-ID to force the stream to use.
bool janus_use_rtsp_restream; // Point Janus at the ZM RTSP output, rather than the camera directly.
std::string janus_pin; // For security, we generate a pin required to view the stream.
std::string protocol;
std::string method;
@ -639,6 +639,10 @@ public:
bool JanusAudioEnabled() {
return janus_audio_enabled;
}
inline const char* get_stream_key() {
return shared_data->janus_pin;
}
bool OnvifEnabled() {
return onvif_event_listener;
}

View File

@ -18,6 +18,7 @@
//
#include "zm_monitor.h"
#include "zm_crypt.h"
#include <regex>
std::string escape_json_string( std::string input );
@ -51,6 +52,9 @@ Monitor::JanusManager::JanusManager(Monitor *parent_) :
} else {
rtsp_path = parent->path;
}
parent->janus_pin = generateKey(16);
Debug(1, "Monitor %u assigned secret %s", parent->id, parent->janus_pin.c_str());
strncpy(parent->shared_data->janus_pin, parent->janus_pin.c_str(), 17); //copy the null termination, as we're in C land
}
Monitor::JanusManager::~JanusManager() {
@ -64,6 +68,8 @@ Monitor::JanusManager::~JanusManager() {
std::string postData = "{\"janus\" : \"message\", \"transaction\" : \"randomString\", \"body\" : {";
postData += "\"request\" : \"destroy\", \"admin_key\" : \"";
postData += config.janus_secret;
postData += "\", \"secret\" : \"";
postData += parent->janus_pin;
postData += "\", \"id\" : ";
postData += std::to_string(parent->id);
postData += "}}";
@ -152,6 +158,12 @@ int Monitor::JanusManager::add_to_janus() {
postData += "\", \"type\" : \"rtsp\", \"rtsp_quirk\" : true, ";
postData += "\"url\" : \"";
postData += rtsp_path;
//secret prevents querying the mount for info, which leaks the camera's secrets.
postData += "\", \"secret\" : \"";
postData += parent->janus_pin;
//pin prevents viewing the video.
postData += "\", \"pin\" : \"";
postData += parent->janus_pin;
if (profile_override[0] != '\0') {
postData += "\", \"videofmtp\" : \"";
postData += profile_override;
@ -206,26 +218,6 @@ size_t Monitor::JanusManager::WriteCallback(void *contents, size_t size, size_t
return size * nmemb;
}
/*
void Monitor::JanusManager::generateKey()
{
const std::string CHARACTERS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
std::random_device random_device;
std::mt19937 generator(random_device());
std::uniform_int_distribution<> distribution(0, CHARACTERS.size() - 1);
std::string random_string;
for (std::size_t i = 0; i < 16; ++i)
{
random_string += CHARACTERS[distribution(generator)];
}
stream_key = random_string;
}
*/
int Monitor::JanusManager::get_janus_session() {
janus_session = "";
curl = curl_easy_init();

View File

@ -112,6 +112,7 @@ void Usage(int status=-1) {
" -q, --query : Query the current settings for the monitor\n"
" -s, --state : Output the current monitor state, 0 = idle, 1 = prealarm, 2 = alarm,\n"
" 3 = alert, 4 = tape\n"
" -j, --janus-pin : Output the pin, if set, used to secure Janus for this monitor \n"
" -B, --brightness [value] : Output the current brightness, set to value if given \n"
" -C, --contrast [value] : Output the current contrast, set to value if given \n"
" -H, --hue [value] : Output the current hue, set to value if given \n"
@ -170,11 +171,12 @@ typedef enum {
ZMU_RESUME = 0x00800000,
ZMU_LIST = 0x10000000,
ZMU_TRIGGER = 0x20000000,
ZMU_JANUS = 0x40000000,
} Function;
bool ValidateAccess(User *user, int mon_id, int function) {
bool allowed = true;
if ( function & (ZMU_STATE|ZMU_IMAGE|ZMU_TIME|ZMU_READ_IDX|ZMU_WRITE_IDX|ZMU_FPS|ZMU_TRIGGER) ) {
if ( function & (ZMU_STATE|ZMU_IMAGE|ZMU_TIME|ZMU_READ_IDX|ZMU_WRITE_IDX|ZMU_FPS|ZMU_TRIGGER|ZMU_JANUS) ) {
if ( user->getStream() < User::PERM_VIEW )
allowed = false;
}
@ -224,6 +226,7 @@ int main(int argc, char *argv[]) {
{"scale", 1, nullptr, 'S'},
{"timestamp", 2, nullptr, 't'},
{"state", 0, nullptr, 's'},
{"janus-pin", 0, nullptr, 'j'},
{"brightness", 2, nullptr, 'B'},
{"contrast", 2, nullptr, 'C'},
{"hue", 2, nullptr, 'H'},
@ -282,7 +285,7 @@ int main(int argc, char *argv[]) {
while (1) {
int option_index = 0;
int c = getopt_long(argc, argv, "d:m:vsEDLurweix::S:t::fz::ancqhlB::C::H::O::RWU:P:A:V:T:", long_options, &option_index);
int c = getopt_long(argc, argv, "d:m:vsjEDLurweix::S:t::fz::ancqhlB::C::H::O::RWU:P:A:V:T:", long_options, &option_index);
if (c == -1) {
break;
}
@ -301,6 +304,9 @@ int main(int argc, char *argv[]) {
case 's':
function |= ZMU_STATE;
break;
case 'j':
function |= ZMU_JANUS;
break;
case 'x':
function |= ZMU_TRIGGER;
break;
@ -521,6 +527,10 @@ int main(int argc, char *argv[]) {
char separator = ' ';
bool have_output = false;
if ( function & ZMU_JANUS ) {
printf("%s", monitor->get_stream_key());
have_output = true;
}
if ( function & ZMU_STATE ) {
Monitor::State state = monitor->GetState();
if ( verbose ) {

View File

@ -268,7 +268,12 @@ public static function getStatuses() {
'ArchivedEvents' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'ArchivedEventDiskSpace' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
);
public function Janus_Pin() {
$cmd = getZmuCommand(' --janus-pin -m '.$this->{'Id'});
$output = shell_exec($cmd);
Debug("Running $cmd output: $output");
return trim($output);
}
public function Control() {
if (!property_exists($this, 'Control')) {
if ($this->ControlId())

View File

@ -11,6 +11,7 @@ function MonitorStream(monitorData) {
this.width = monitorData.width;
this.height = monitorData.height;
this.janusEnabled = monitorData.janusEnabled;
this.janusPin = monitorData.janus_pin;
this.scale = 100;
this.status = {capturefps: 0, analysisfps: 0}; // json object with alarmstatus, fps etc
this.lastAlarmState = STATE_IDLE;
@ -191,7 +192,7 @@ function MonitorStream(monitorData) {
janus = new Janus({server: server}); //new Janus
}});
}
attachVideo(parseInt(this.id));
attachVideo(parseInt(this.id), this.janusPin);
this.statusCmdTimer = setTimeout(this.statusCmdQuery.bind(this), delay);
return;
}
@ -683,14 +684,14 @@ function MonitorStream(monitorData) {
};
} // end function MonitorStream
async function attachVideo(id) {
async function attachVideo(id, pin) {
await waitUntil(() => janus.isConnected() );
janus.attach({
plugin: "janus.plugin.streaming",
opaqueId: "streamingtest-"+Janus.randomString(12),
success: function(pluginHandle) {
streaming[id] = pluginHandle;
var body = {"request": "watch", "id": id};
var body = {"request": "watch", "id": id, "pin": pin};
streaming[id].send({"message": body});
},
error: function(error) {

View File

@ -23,7 +23,8 @@ monitorData[monitorData.length] = {
'onclick': function(){window.location.assign( '?view=watch&mid=<?php echo $monitor->Id() ?>' );},
'type': '<?php echo $monitor->Type() ?>',
'refresh': '<?php echo $monitor->Refresh() ?>',
'janusEnabled': <?php echo $monitor->JanusEnabled() ?>
'janusEnabled': <?php echo $monitor->JanusEnabled() ?>,
'janus_pin': '<?php echo $monitor->Janus_Pin() ?>'
};
<?php
} // end foreach monitor

View File

@ -25,7 +25,8 @@ monitorData[monitorData.length] = {
'url_to_zms': '<?php echo $monitor->UrlToZMS( ZM_MIN_STREAMING_PORT ? ($monitor->Id() + ZM_MIN_STREAMING_PORT) : '') ?>',
'onclick': function(){window.location.assign( '?view=watch&mid=<?php echo $monitor->Id() ?>' );},
'type': '<?php echo $monitor->Type() ?>',
'refresh': '<?php echo $monitor->Refresh() ?>'
'refresh': '<?php echo $monitor->Refresh() ?>',
'janus_pin': '<?php echo $monitor->Janus_Pin() ?>'
};
<?php
} // end foreach monitor

View File

@ -49,7 +49,8 @@ monitorData[monitorData.length] = {
'url': '<?php echo $m->UrlToIndex() ?>',
'onclick': function(){window.location.assign( '?view=watch&mid=<?php echo $m->Id() ?>' );},
'type': '<?php echo $m->Type() ?>',
'refresh': '<?php echo $m->Refresh() ?>'
'refresh': '<?php echo $m->Refresh() ?>',
'janus_pin': '<?php echo $monitor->Janus_Pin() ?>'
};
<?php
} // end foreach monitor

View File

@ -69,7 +69,8 @@ monitorData[monitorData.length] = {
'url': '<?php echo $monitor->UrlToIndex( ZM_MIN_STREAMING_PORT ? ($monitor->Id() + ZM_MIN_STREAMING_PORT) : '') ?>',
'url_to_zms': '<?php echo $monitor->UrlToZMS( ZM_MIN_STREAMING_PORT ? ($monitor->Id() + ZM_MIN_STREAMING_PORT) : '') ?>',
'type': '<?php echo $monitor->Type() ?>',
'refresh': '<?php echo $monitor->Refresh() ?>'
'refresh': '<?php echo $monitor->Refresh() ?>',
'janus_pin': '<?php echo $monitor->Janus_Pin() ?>'
};
var selfIntersecting = <?php echo $selfIntersecting ? 'true' : 'false' ?>;

View File

@ -12,7 +12,8 @@ monitorData[monitorData.length] = {
'url': '<?php echo $monitor->UrlToIndex( ZM_MIN_STREAMING_PORT ? ($monitor->Id() + ZM_MIN_STREAMING_PORT) : '') ?>',
'url_to_zms': '<?php echo $monitor->UrlToZMS( ZM_MIN_STREAMING_PORT ? ($monitor->Id() + ZM_MIN_STREAMING_PORT) : '') ?>',
'type': '<?php echo $monitor->Type() ?>',
'refresh': '<?php echo $monitor->Refresh() ?>'
'refresh': '<?php echo $monitor->Refresh() ?>',
'janus_pin': '<?php echo $monitor->Janus_Pin() ?>'
};
<?php
}