Require RTSP encryption when encryption mode is set to mandatory
This also lets us provide a friendly error to the client when it is rejected.
This commit is contained in:
@@ -3,6 +3,7 @@
|
|||||||
* @brief todo
|
* @brief todo
|
||||||
*/
|
*/
|
||||||
#include "network.h"
|
#include "network.h"
|
||||||
|
#include "config.h"
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
@@ -174,6 +175,22 @@ namespace net {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the encryption mode for the given remote endpoint address.
|
||||||
|
* @param address The address used to look up the desired encryption mode.
|
||||||
|
* @return The WAN or LAN encryption mode, based on the provided address.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
encryption_mode_for_address(boost::asio::ip::address address) {
|
||||||
|
auto nettype = net::from_address(address.to_string());
|
||||||
|
if (nettype == net::net_e::PC || nettype == net::net_e::LAN) {
|
||||||
|
return config::stream.lan_encryption_mode;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return config::stream.wan_encryption_mode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
host_t
|
host_t
|
||||||
host_create(af_e af, ENetAddress &addr, std::size_t peers, std::uint16_t port) {
|
host_create(af_e af, ENetAddress &addr, std::size_t peers, std::uint16_t port) {
|
||||||
static std::once_flag enet_init_flag;
|
static std::once_flag enet_init_flag;
|
||||||
|
|||||||
@@ -84,4 +84,12 @@ namespace net {
|
|||||||
*/
|
*/
|
||||||
std::string
|
std::string
|
||||||
addr_to_url_escaped_string(boost::asio::ip::address address);
|
addr_to_url_escaped_string(boost::asio::ip::address address);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the encryption mode for the given remote endpoint address.
|
||||||
|
* @param address The address used to look up the desired encryption mode.
|
||||||
|
* @return The WAN or LAN encryption mode, based on the provided address.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
encryption_mode_for_address(boost::asio::ip::address address);
|
||||||
} // namespace net
|
} // namespace net
|
||||||
|
|||||||
@@ -820,6 +820,17 @@ namespace nvhttp {
|
|||||||
host_audio = util::from_view(get_arg(args, "localAudioPlayMode"));
|
host_audio = util::from_view(get_arg(args, "localAudioPlayMode"));
|
||||||
auto launch_session = make_launch_session(host_audio, args);
|
auto launch_session = make_launch_session(host_audio, args);
|
||||||
|
|
||||||
|
auto encryption_mode = net::encryption_mode_for_address(request->remote_endpoint().address());
|
||||||
|
if (!launch_session->rtsp_cipher && encryption_mode == config::ENCRYPTION_MODE_MANDATORY) {
|
||||||
|
BOOST_LOG(error) << "Rejecting client that cannot comply with mandatory encryption requirement"sv;
|
||||||
|
|
||||||
|
tree.put("root.<xmlattr>.status_code", 403);
|
||||||
|
tree.put("root.<xmlattr>.status_message", "Encryption is mandatory for this host but unsupported by the client");
|
||||||
|
tree.put("root.gamesession", 0);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (appid > 0) {
|
if (appid > 0) {
|
||||||
auto err = proc::proc.execute(appid, launch_session);
|
auto err = proc::proc.execute(appid, launch_session);
|
||||||
if (err) {
|
if (err) {
|
||||||
@@ -906,6 +917,17 @@ namespace nvhttp {
|
|||||||
|
|
||||||
auto launch_session = make_launch_session(host_audio, args);
|
auto launch_session = make_launch_session(host_audio, args);
|
||||||
|
|
||||||
|
auto encryption_mode = net::encryption_mode_for_address(request->remote_endpoint().address());
|
||||||
|
if (!launch_session->rtsp_cipher && encryption_mode == config::ENCRYPTION_MODE_MANDATORY) {
|
||||||
|
BOOST_LOG(error) << "Rejecting client that cannot comply with mandatory encryption requirement"sv;
|
||||||
|
|
||||||
|
tree.put("root.<xmlattr>.status_code", 403);
|
||||||
|
tree.put("root.<xmlattr>.status_message", "Encryption is mandatory for this host but unsupported by the client");
|
||||||
|
tree.put("root.gamesession", 0);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
tree.put("root.<xmlattr>.status_code", 200);
|
tree.put("root.<xmlattr>.status_code", 200);
|
||||||
tree.put("root.sessionUrl0", launch_session->rtsp_url_scheme +
|
tree.put("root.sessionUrl0", launch_session->rtsp_url_scheme +
|
||||||
net::addr_to_url_escaped_string(request->local_endpoint().address()) + ':' +
|
net::addr_to_url_escaped_string(request->local_endpoint().address()) + ':' +
|
||||||
|
|||||||
18
src/rtsp.cpp
18
src/rtsp.cpp
@@ -789,14 +789,7 @@ namespace rtsp_stream {
|
|||||||
uint32_t encryption_flags_requested = SS_ENC_CONTROL_V2;
|
uint32_t encryption_flags_requested = SS_ENC_CONTROL_V2;
|
||||||
|
|
||||||
// Determine the encryption desired for this remote endpoint
|
// Determine the encryption desired for this remote endpoint
|
||||||
auto nettype = net::from_address(sock.remote_endpoint().address().to_string());
|
auto encryption_mode = net::encryption_mode_for_address(sock.remote_endpoint().address());
|
||||||
int encryption_mode;
|
|
||||||
if (nettype == net::net_e::PC || nettype == net::net_e::LAN) {
|
|
||||||
encryption_mode = config::stream.lan_encryption_mode;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
encryption_mode = config::stream.wan_encryption_mode;
|
|
||||||
}
|
|
||||||
if (encryption_mode != config::ENCRYPTION_MODE_NEVER) {
|
if (encryption_mode != config::ENCRYPTION_MODE_NEVER) {
|
||||||
// Advertise support for video encryption if it's not disabled
|
// Advertise support for video encryption if it's not disabled
|
||||||
encryption_flags_supported |= SS_ENC_VIDEO;
|
encryption_flags_supported |= SS_ENC_VIDEO;
|
||||||
@@ -1080,14 +1073,7 @@ namespace rtsp_stream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check that any required encryption is enabled
|
// Check that any required encryption is enabled
|
||||||
auto nettype = net::from_address(sock.remote_endpoint().address().to_string());
|
auto encryption_mode = net::encryption_mode_for_address(sock.remote_endpoint().address());
|
||||||
int encryption_mode;
|
|
||||||
if (nettype == net::net_e::PC || nettype == net::net_e::LAN) {
|
|
||||||
encryption_mode = config::stream.lan_encryption_mode;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
encryption_mode = config::stream.wan_encryption_mode;
|
|
||||||
}
|
|
||||||
if (encryption_mode == config::ENCRYPTION_MODE_MANDATORY &&
|
if (encryption_mode == config::ENCRYPTION_MODE_MANDATORY &&
|
||||||
(config.encryptionFlagsEnabled & (SS_ENC_VIDEO | SS_ENC_AUDIO)) != (SS_ENC_VIDEO | SS_ENC_AUDIO)) {
|
(config.encryptionFlagsEnabled & (SS_ENC_VIDEO | SS_ENC_AUDIO)) != (SS_ENC_VIDEO | SS_ENC_AUDIO)) {
|
||||||
BOOST_LOG(error) << "Rejecting client that cannot comply with mandatory encryption requirement"sv;
|
BOOST_LOG(error) << "Rejecting client that cannot comply with mandatory encryption requirement"sv;
|
||||||
|
|||||||
Reference in New Issue
Block a user