Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 13 additions & 8 deletions src/nvhttp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ namespace nvhttp {

// Set by TLS verify callback, read by launch/resume handler (single-threaded HTTPS server)
std::string last_verified_client_cert; ///< Last client certificate accepted by the TLS verify callback. // NOSONAR(cpp:S5421): intentionally mutable global
std::string last_verified_client_name; ///< Friendly name of last client certificate accepted by the TLS verify callback. // NOSONAR(cpp:S5421): intentionally mutable global

/**
* @brief Case-insensitive map used for HTTP headers and query parameters.
Expand Down Expand Up @@ -405,6 +406,7 @@ namespace nvhttp {
}
launch_session->rtsp_url_scheme = launch_session->rtsp_cipher ? "rtspenc://"s : "rtsp://"s;
launch_session->client_cert = last_verified_client_cert;
launch_session->client_name = last_verified_client_name;

// Generate the unique identifiers for this connection that we will send later during RTSP handshake
unsigned char raw_payload[8];
Expand Down Expand Up @@ -1253,12 +1255,13 @@ namespace nvhttp {
}

/**
* @brief Check whether a paired client certificate is allowed to connect.
* @brief Check whether a paired client certificate is allowed to connect and retrieve its friendly name.
*
* @param cert_pem PEM-encoded client certificate to look up.
* @return True when the client certificate belongs to an enabled device.
* @return Pair of (bool enabled, string name) where "enabled" is True when the client certificate belongs to an
enabled device and "name" is the friendly client name set during pairing.
*/
bool is_client_enabled(const std::string_view cert_pem);
std::pair<bool, std::string> get_client_status(const std::string_view cert_pem);

void start() {
platf::set_thread_name("nvhttp");
Expand Down Expand Up @@ -1330,12 +1333,14 @@ namespace nvhttp {

// Check if this client is enabled
auto pem = crypto::pem(x509);
if (!is_client_enabled(pem)) {
auto [enabled, client_name] = get_client_status(pem);
if (!enabled) {
BOOST_LOG(info) << "Client is disabled -- denied"sv;
return verified;
}

last_verified_client_cert = pem;
last_verified_client_name = client_name;
verified = 1;

return verified;
Expand Down Expand Up @@ -1463,15 +1468,15 @@ namespace nvhttp {
}

/**
* @brief Check whether a paired client certificate is allowed to connect.
* @brief Check whether a paired client certificate is allowed to connect and return its friendly name.
*/
bool is_client_enabled(const std::string_view cert_pem) {
std::pair<bool, std::string> get_client_status(const std::string_view cert_pem) {
const client_t &client = client_root;
for (const auto &named_cert : client.named_devices) {
if (named_cert.cert == cert_pem) {
return named_cert.enabled;
return {named_cert.enabled, named_cert.name};
}
}
return true;
return {true, {}};
}
} // namespace nvhttp
1 change: 1 addition & 0 deletions src/process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ namespace proc {
// Add Stream-specific environment variables
_env["SUNSHINE_APP_ID"] = std::to_string(_app_id);
_env["SUNSHINE_APP_NAME"] = _app.name;
_env["SUNSHINE_CLIENT_NAME"] = launch_session->client_name;
_env["SUNSHINE_CLIENT_WIDTH"] = std::to_string(launch_session->width);
_env["SUNSHINE_CLIENT_HEIGHT"] = std::to_string(launch_session->height);
_env["SUNSHINE_CLIENT_FPS"] = std::to_string(launch_session->fps);
Expand Down
1 change: 1 addition & 0 deletions src/rtsp.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ namespace rtsp_stream {
bool continuous_audio; ///< Whether audio packets continue during silence.
bool enable_hdr; ///< Whether HDR streaming is requested.
bool enable_sops; ///< Whether sequence output protection is requested.
std::string client_name; ///< Friendly client name from initial pairing.

std::optional<crypto::cipher::gcm_t> rtsp_cipher; ///< AES-GCM cipher used once encrypted RTSP is negotiated.
std::string rtsp_url_scheme; ///< URL scheme selected by the RTSP SETUP flow.
Expand Down
4 changes: 4 additions & 0 deletions src_assets/common/assets/web/apps.html
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,10 @@ <h4>{{ $t('apps.env_vars_about') }}</h4>
<td style="font-family: monospace">SUNSHINE_APP_NAME</td>
<td>{{ $t('apps.env_app_name') }}</td>
</tr>
<tr>
<td style="font-family: monospace">SUNSHINE_CLIENT_NAME</td>
<td>{{ $t('apps.env_client_name') }}</td>
</tr>
<tr>
<td style="font-family: monospace">SUNSHINE_CLIENT_WIDTH</td>
<td>{{ $t('apps.env_client_width') }}</td>
Expand Down
1 change: 1 addition & 0 deletions src_assets/common/assets/web/public/assets/locale/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
"env_client_hdr": "HDR is enabled by the client (true/false)",
"env_client_height": "The Height requested by the client (int)",
"env_client_host_audio": "The client has requested host audio (true/false)",
"env_client_name": "The Name of the client assigned during pairing (str)",
"env_client_width": "The Width requested by the client (int)",
"env_displayplacer_example": "Example - displayplacer for Resolution Automation:",
"env_qres_example": "Example - QRes for Resolution Automation:",
Expand Down