diff --git a/src/zms.cpp b/src/zms.cpp index 9ff4be502..581682395 100644 --- a/src/zms.cpp +++ b/src/zms.cpp @@ -259,7 +259,7 @@ int main(int argc, const char *argv[], char **envp) { fputs("HTTP/1.0 403 Forbidden\r\n\r\n", stdout); const char *referer = getenv("HTTP_REFERER"); - Error("Unable to authenticate user from %s", referer); + Warning("Unable to authenticate user from %s", referer); return exit_zm(0); } if ( !ValidateAccess(user, monitor_id) ) { diff --git a/web/includes/Event.php b/web/includes/Event.php index 7b154f705..89d036c8d 100644 --- a/web/includes/Event.php +++ b/web/includes/Event.php @@ -291,6 +291,9 @@ class Event extends ZM_Object { if ( ZM_OPT_USE_AUTH ) { if ( ZM_AUTH_RELAY == 'hashed' ) { $args['auth'] = generateAuthHash(ZM_AUTH_HASH_IPS); + // Include username so zms can filter by indexed Username column + // instead of iterating all users to validate the auth hash + if (!empty($_SESSION['username'])) $args['user'] = $_SESSION['username']; } else if ( ZM_AUTH_RELAY == 'plain' ) { $args['user'] = $_SESSION['username']; $args['pass'] = $_SESSION['password']; @@ -406,6 +409,9 @@ class Event extends ZM_Object { if ( ZM_OPT_USE_AUTH ) { if ( ZM_AUTH_RELAY == 'hashed' ) { $args['auth'] = generateAuthHash(ZM_AUTH_HASH_IPS); + // Include username so zms can filter by indexed Username column + // instead of iterating all users to validate the auth hash + if (!empty($_SESSION['username'])) $args['user'] = $_SESSION['username']; } else if ( ZM_AUTH_RELAY == 'plain' ) { $args['user'] = $_SESSION['username']; $args['pass'] = $_SESSION['password']; diff --git a/web/includes/Monitor.php b/web/includes/Monitor.php index 3275099bb..6f9c05cfb 100644 --- a/web/includes/Monitor.php +++ b/web/includes/Monitor.php @@ -553,8 +553,9 @@ class Monitor extends ZM_Object { if (ZM_OPT_USE_AUTH) { if (ZM_AUTH_RELAY == 'hashed') { $args['auth'] = generateAuthHash(ZM_AUTH_HASH_IPS); - # Include user so that db lookups can be more efficient - $args['user'] = isset($_SESSION['username']) ? $_SESSION['username'] : ''; + // Include username so zms can filter by indexed Username column + // instead of iterating all users to validate the auth hash + if (!empty($_SESSION['username'])) $args['user'] = $_SESSION['username']; } elseif ( ZM_AUTH_RELAY == 'plain' ) { $args['user'] = isset($_SESSION['username']) ? $_SESSION['username'] : ''; $args['pass'] = isset($_SESSION['password']) ? $_SESSION['password'] : ''; diff --git a/web/includes/auth.php b/web/includes/auth.php index 456600a5f..0917d4daa 100644 --- a/web/includes/auth.php +++ b/web/includes/auth.php @@ -504,7 +504,13 @@ function userFromSession() { function get_auth_relay() { if (ZM_OPT_USE_AUTH) { if (ZM_AUTH_RELAY == 'hashed') { - return 'auth='.generateAuthHash(ZM_AUTH_HASH_IPS); + $relay = 'auth='.generateAuthHash(ZM_AUTH_HASH_IPS); + // Include username so zms can filter by indexed Username column + // instead of iterating all users to validate the auth hash + if (!empty($_SESSION['username'])) { + $relay .= '&user='.$_SESSION['username']; + } + return $relay; } else if (ZM_AUTH_RELAY == 'plain') { // password probably needs to be escaped return 'username='.(isset($_SESSION['username'])?$_SESSION['username']:'').'&password='.urlencode(isset($_SESSION['password']) ? $_SESSION['password'] : ''); diff --git a/web/js/MonitorStream.js b/web/js/MonitorStream.js index b9136cf6d..03a37d6cf 100644 --- a/web/js/MonitorStream.js +++ b/web/js/MonitorStream.js @@ -590,12 +590,17 @@ function MonitorStream(monitorData) { } stream.onerror = this.img_onerror.bind(this); stream.onload = this.img_onload.bind(this); - if (this.activePlayer == 'zms') { - // Only if we were already zms streaming + // Check if the auth hash in the current img src is still valid. + // On long-running pages the hash from page load may have expired. + const srcAuthMatch = stream.src ? stream.src.match(/auth=(\w+)/i) : null; + const srcAuthCurrent = srcAuthMatch && srcAuthMatch[1] === auth_hash; + + if (srcAuthCurrent && this.activePlayer == 'zms') { + // Auth is current and zms was already the active player — just resume this.streamCmdTimer = setInterval(this.streamCmdQuery.bind(this), statusRefreshTimeout); this.streamCommand(CMD_PLAY); - } else if (-1 != stream.src.indexOf('mode=paused')) { - // Initial page load has zms with mode=paused + } else if (srcAuthCurrent && (-1 != stream.src.indexOf('mode=paused'))) { + // Initial page load has zms with mode=paused, auth is still valid this.streamCmdTimer = setInterval(this.streamCmdQuery.bind(this), statusRefreshTimeout); this.streamCommand(CMD_PLAY); } else {