Sunshine master
Self-hosted game stream host for Moonlight.
nvhttp Namespace Reference

Contains all the functions and variables related to the nvhttp (GameStream) server. More...

Classes

struct  client_t
 Persisted pairing data for one Moonlight client. More...
 
struct  conf_intern_t
 Internal HTTPS credential paths for the configuration server. More...
 
struct  named_cert_t
 Certificate entry associated with a client name and UUID. More...
 
struct  pair_session_t
 Pairing handshake state exchanged with a Moonlight client. More...
 
class  SunshineHTTPS
 Simple-Web-Server HTTPS backend configured for Sunshine certificate handling. More...
 
class  SunshineHTTPSServer
 HTTPS server backend that adds Sunshine's client-certificate verification. More...
 
struct  tunnel
 
struct  tunnel< SimpleWeb::HTTP >
 Plain HTTP server wrapper used for non-TLS endpoints. More...
 
struct  tunnel< SunshineHTTPS >
 HTTPS tunnel session used for encrypted client requests. More...
 

Typedefs

using http_server_t = SimpleWeb::Server<SimpleWeb::HTTP>
 Plain HTTP server type used for GameStream endpoints without TLS.
 
using https_server_t = SunshineHTTPSServer
 HTTPS server type used for GameStream endpoints requiring TLS.
 
using req_http_t = std::shared_ptr<typename SimpleWeb::ServerBase<SimpleWeb::HTTP>::Request>
 Shared HTTP request object received by redirect and discovery handlers.
 
using req_https_t = std::shared_ptr<typename SimpleWeb::ServerBase<SunshineHTTPS>::Request>
 Shared HTTPS request object received by GameStream handlers.
 
using resp_http_t = std::shared_ptr<typename SimpleWeb::ServerBase<SimpleWeb::HTTP>::Response>
 Shared HTTP response object passed to redirect and discovery handlers.
 
using resp_https_t = std::shared_ptr<typename SimpleWeb::ServerBase<SunshineHTTPS>::Response>
 Shared HTTPS response object passed to GameStream handlers.
 

Enumerations

enum class  op_e { ADD , REMOVE }
 Certificate operations supported by the pairing API. More...
 
enum class  PAIR_PHASE {
  NONE , GETSERVERCERT , CLIENTCHALLENGE , SERVERCHALLENGERESP ,
  CLIENTPAIRINGSECRET
}
 Enumerates supported pAIR PHASE options. More...
 

Functions

void add_authorized_client (const std::string &name, std::string &&cert)
 Add authorized client data.
 
void appasset (resp_https_t response, req_https_t request)
 Return an application asset requested by the client.
 
void applist (resp_https_t response, req_https_t request)
 Build the GameStream application list response.
 
void cancel (resp_https_t response, req_https_t request)
 Check whether cel.
 
void clientchallenge (pair_session_t &sess, boost::property_tree::ptree &tree, const std::string &challenge)
 Pair, phase 2.
 
void clientchallenge (pair_session_t &sess, pt::ptree &tree, const std::string &challenge)
 Handle the client-challenge phase of GameStream pairing.
 
void clientpairingsecret (pair_session_t &sess, std::shared_ptr< safe::queue_t< crypto::x509_t > > &add_cert, boost::property_tree::ptree &tree, const std::string &client_pairing_secret)
 Pair, phase 4 (final)
 
void clientpairingsecret (pair_session_t &sess, std::shared_ptr< safe::queue_t< crypto::x509_t > > &add_cert, pt::ptree &tree, const std::string &client_pairing_secret)
 Handle the client pairing-secret phase of GameStream pairing.
 
void erase_all_clients ()
 Remove all paired clients.
 
void fail_pair (pair_session_t &sess, pt::ptree &tree, const std::string status_msg)
 Return the GameStream pairing failure response.
 
nlohmann::json get_all_clients ()
 Get all paired clients.
 
std::string get_arg (const args_t &args, const char *name, const char *default_value=nullptr)
 Read a named query argument from the HTTP request map.
 
std::string get_cert_by_uuid (const std::string_view uuid)
 Get cert by UUID.
 
uint32_t get_codec_mode_flags ()
 Get codec mode flags.
 
void getservercert (pair_session_t &sess, boost::property_tree::ptree &tree, const std::string &pin)
 Pair, phase 1.
 
void getservercert (pair_session_t &sess, pt::ptree &tree, const std::string &pin)
 Return the server certificate text for pairing responses.
 
bool is_client_enabled (const std::string_view cert_pem)
 Check whether a paired client certificate is allowed to connect.
 
void launch (bool &host_audio, resp_https_t response, req_https_t request)
 Launch the requested application for a GameStream session.
 
void load_state ()
 Load state from its backing store.
 
std::shared_ptr< rtsp_stream::launch_session_tmake_launch_session (bool host_audio, const args_t &args)
 Create launch session.
 
template<class T >
void not_found (std::shared_ptr< typename SimpleWeb::ServerBase< T >::Response > response, std::shared_ptr< typename SimpleWeb::ServerBase< T >::Request > request)
 Return a GameStream HTTP not-found response.
 
template<class T >
void pair (std::shared_ptr< safe::queue_t< crypto::x509_t > > &add_cert, std::shared_ptr< typename SimpleWeb::ServerBase< T >::Response > response, std::shared_ptr< typename SimpleWeb::ServerBase< T >::Request > request)
 Dispatch the top-level GameStream pairing request by phase.
 
bool pin (std::string pin, std::string name)
 Compare the user supplied pin to the Moonlight pin.
 
template<class T >
void print_req (std::shared_ptr< typename SimpleWeb::ServerBase< T >::Request > request)
 Write req details to the log.
 
void remove_session (const pair_session_t &sess)
 removes the temporary pairing session
 
void resume (bool &host_audio, resp_https_t response, req_https_t request)
 Resume an existing GameStream session.
 
void save_state ()
 Persist the current state to its backing store.
 
void serverchallengeresp (pair_session_t &sess, boost::property_tree::ptree &tree, const std::string &encrypted_response)
 Pair, phase 3.
 
void serverchallengeresp (pair_session_t &sess, pt::ptree &tree, const std::string &encrypted_response)
 Handle the server-challenge response phase of GameStream pairing.
 
template<class T >
void serverinfo (std::shared_ptr< typename SimpleWeb::ServerBase< T >::Response > response, std::shared_ptr< typename SimpleWeb::ServerBase< T >::Request > request)
 Build the GameStream server-info response.
 
bool set_client_enabled (std::string_view uuid, bool enabled)
 Enable or disable a client.
 
void setup (const std::string &pkey, const std::string &cert)
 Setup the nvhttp server.
 
void start ()
 Start the nvhttp server.
 
bool unpair_client (std::string_view uuid)
 Remove single client.
 

Variables

crypto::cert_chain_t cert_chain
 Certificate chain presented by Sunshine's GameStream HTTPS server.
 
client_t client_root
 In-memory representation of the paired-client database.
 
struct nvhttp::conf_intern_t conf_intern
 TLS credential paths loaded from Sunshine's runtime configuration.
 
constexpr auto GFE_VERSION = "3.23.0.74"
 The GFE version we are replicating.
 
std::string last_verified_client_cert
 Last client certificate accepted by the TLS verify callback. // NOSONAR(cpp:S5421) - intentionally mutable global.
 
std::unordered_map< std::string, pair_session_tmap_id_sess
 Pairing sessions keyed by temporary unique ID.
 
constexpr auto PORT_HTTP = 0
 The HTTP port, as a difference from the config port.
 
constexpr auto PORT_HTTPS = -5
 The HTTPS port, as a difference from the config port.
 
std::atomic< uint32_t > session_id_counter
 Monotonic counter used to allocate GameStream session IDs.
 
constexpr auto VERSION = "7.1.431.-1"
 The protocol version.
 

Detailed Description

Contains all the functions and variables related to the nvhttp (GameStream) server.

Enumeration Type Documentation

◆ op_e

enum class nvhttp::op_e
strong

Certificate operations supported by the pairing API.

Enumerator
ADD 

Add certificate.

REMOVE 

Remove certificate.

◆ PAIR_PHASE

enum class nvhttp::PAIR_PHASE
strong

Enumerates supported pAIR PHASE options.

Enumerator
NONE 

Sunshine is not in a pairing phase.

GETSERVERCERT 

Sunshine is in the get server certificate phase.

CLIENTCHALLENGE 

Sunshine is in the client challenge phase.

SERVERCHALLENGERESP 

Sunshine is in the server challenge response phase.

CLIENTPAIRINGSECRET 

Sunshine is in the client pairing secret phase.

Function Documentation

◆ add_authorized_client()

void nvhttp::add_authorized_client ( const std::string & name,
std::string && cert )

Add authorized client data.

Parameters
nameHuman-readable name to assign.
certCertificate data or object used by the operation.

◆ appasset()

void nvhttp::appasset ( resp_https_t response,
req_https_t request )

Return an application asset requested by the client.

Parameters
responseHTTP response object to populate.
requestHTTP request data from the client.

◆ applist()

void nvhttp::applist ( resp_https_t response,
req_https_t request )

Build the GameStream application list response.

Parameters
responseHTTP response object to populate.
requestHTTP request data from the client.

◆ cancel()

void nvhttp::cancel ( resp_https_t response,
req_https_t request )

Check whether cel.

Parameters
responseHTTP response object to populate.
requestHTTP request data from the client.

◆ clientchallenge() [1/2]

void nvhttp::clientchallenge ( pair_session_t & sess,
boost::property_tree::ptree & tree,
const std::string & challenge )

Pair, phase 2.

Using the AES key that we generated in phase 1 we have to decrypt the client challenge,

We generate a SHA256 hash with the following:

  • Decrypted challenge
  • Server certificate signature
  • Server secret: a randomly generated secret

The hash + server_challenge will then be AES encrypted and sent as the challengeresponse in the returned XML

Parameters
sessPairing session that owns the request state.
treeXML property tree used for the response body.
challengeClient challenge bytes from the pairing request.

◆ clientchallenge() [2/2]

void nvhttp::clientchallenge ( pair_session_t & sess,
pt::ptree & tree,
const std::string & challenge )

Handle the client-challenge phase of GameStream pairing.

Parameters
sessPairing session that owns the request state.
treeXML property tree used for the response body.
challengeClient challenge bytes from the pairing request.

◆ clientpairingsecret() [1/2]

void nvhttp::clientpairingsecret ( pair_session_t & sess,
std::shared_ptr< safe::queue_t< crypto::x509_t > > & add_cert,
boost::property_tree::ptree & tree,
const std::string & client_pairing_secret )

Pair, phase 4 (final)

We now have to use everything we exchanged before in order to verify and finally pair the clients

We'll check the client_hash obtained at phase 3, it should contain the following:

  • The original server_challenge
  • The signature of the X509 client_cert
  • The unencrypted client_pairing_secret We'll check that SHA256(server_challenge + client_public_cert_signature + client_secret) == client_hash

Then using the client certificate public key we should be able to verify that the client secret has been signed by Moonlight

Parameters
sessPairing session that owns the request state.
add_certAdd cert.
treeXML property tree used for the response body.
client_pairing_secretClient pairing secret.

◆ clientpairingsecret() [2/2]

void nvhttp::clientpairingsecret ( pair_session_t & sess,
std::shared_ptr< safe::queue_t< crypto::x509_t > > & add_cert,
pt::ptree & tree,
const std::string & client_pairing_secret )

Handle the client pairing-secret phase of GameStream pairing.

Parameters
sessPairing session that owns the request state.
add_certAdd cert.
treeXML property tree used for the response body.
client_pairing_secretClient pairing secret.

◆ erase_all_clients()

void nvhttp::erase_all_clients ( )

Remove all paired clients.

*Examples**

void erase_all_clients()
Remove all paired clients.
Definition nvhttp.cpp:1417

◆ fail_pair()

void nvhttp::fail_pair ( pair_session_t & sess,
pt::ptree & tree,
const std::string status_msg )

Return the GameStream pairing failure response.

Parameters
sessPairing session that owns the request state.
treeXML property tree used for the response body.
status_msgStatus msg.

◆ get_all_clients()

nlohmann::json nvhttp::get_all_clients ( )

Get all paired clients.

Returns
The list of all paired clients.

*Examples**

nlohmann::json clients = nvhttp::get_all_clients();
nlohmann::json get_all_clients()
Get all paired clients.
Definition nvhttp.cpp:936

◆ get_arg()

std::string nvhttp::get_arg ( const args_t & args,
const char * name,
const char * default_value = nullptr )

Read a named query argument from the HTTP request map.

Parameters
argsParsed query-string argument map.
nameQuery parameter name to read.
default_valueValue returned when the parameter is absent.
Returns
Query parameter value, default value, or an empty string.

◆ get_cert_by_uuid()

std::string nvhttp::get_cert_by_uuid ( std::string_view uuid)

Get cert by UUID.

Parameters
uuidClient UUID being looked up or removed.
Returns
PEM certificate for the paired client, or an empty string when unknown.

◆ get_codec_mode_flags()

uint32_t nvhttp::get_codec_mode_flags ( )

Get codec mode flags.

Returns
Moonlight codec capability bitmask for the currently probed encoders.

◆ getservercert() [1/2]

void nvhttp::getservercert ( pair_session_t & sess,
boost::property_tree::ptree & tree,
const std::string & pin )

Pair, phase 1.

Moonlight will send a salt and client certificate, we'll also need the user provided pin.

PIN and SALT will be used to derive a shared AES key that needs to be stored in order to be used to decrypt_symmetric in the next phases.

At this stage we only have to send back our public certificate.

Parameters
sessPairing session that owns the request state.
treeXML property tree used for the response body.
pinPIN supplied by the client during pairing.

◆ getservercert() [2/2]

void nvhttp::getservercert ( pair_session_t & sess,
pt::ptree & tree,
const std::string & pin )

Return the server certificate text for pairing responses.

Parameters
sessPairing session that owns the request state.
treeXML property tree used for the response body.
pinPIN supplied by the client during pairing.

◆ is_client_enabled()

bool nvhttp::is_client_enabled ( const std::string_view cert_pem)

Check whether a paired client certificate is allowed to connect.

Parameters
cert_pemPEM-encoded client certificate to look up.
Returns
True when the client certificate belongs to an enabled device.

◆ launch()

void nvhttp::launch ( bool & host_audio,
resp_https_t response,
req_https_t request )

Launch the requested application for a GameStream session.

Parameters
host_audioHost audio.
responseHTTP response object to populate.
requestHTTP request data from the client.

◆ make_launch_session()

std::shared_ptr< rtsp_stream::launch_session_t > nvhttp::make_launch_session ( bool host_audio,
const args_t & args )

Create launch session.

Parameters
host_audioHost audio.
argsArguments forwarded to the callable or parser.
Returns
Constructed launch session object.

◆ not_found()

template<class T >
void nvhttp::not_found ( std::shared_ptr< typename SimpleWeb::ServerBase< T >::Response > response,
std::shared_ptr< typename SimpleWeb::ServerBase< T >::Request > request )

Return a GameStream HTTP not-found response.

Parameters
responseHTTP response object to populate.
requestHTTP request data from the client.

◆ pair()

template<class T >
void nvhttp::pair ( std::shared_ptr< safe::queue_t< crypto::x509_t > > & add_cert,
std::shared_ptr< typename SimpleWeb::ServerBase< T >::Response > response,
std::shared_ptr< typename SimpleWeb::ServerBase< T >::Request > request )

Dispatch the top-level GameStream pairing request by phase.

Parameters
add_certAdd cert.
responseHTTP response object to populate.
requestHTTP request data from the client.

◆ pin()

bool nvhttp::pin ( std::string pin,
std::string name )

Compare the user supplied pin to the Moonlight pin.

Parameters
pinThe user supplied pin.
nameThe user supplied name.
Returns
true if the pin is correct, false otherwise.

*Examples**

bool pin_status = nvhttp::pin("1234", "laptop");
bool pin(std::string pin, std::string name)
Compare the user supplied pin to the Moonlight pin.
Definition nvhttp.cpp:774

◆ print_req()

template<class T >
void nvhttp::print_req ( std::shared_ptr< typename SimpleWeb::ServerBase< T >::Request > request)

Write req details to the log.

Parameters
requestHTTP request data from the client.

◆ remove_session()

void nvhttp::remove_session ( const pair_session_t & sess)

removes the temporary pairing session

Parameters
sess

◆ resume()

void nvhttp::resume ( bool & host_audio,
resp_https_t response,
req_https_t request )

Resume an existing GameStream session.

Parameters
host_audioHost audio.
responseHTTP response object to populate.
requestHTTP request data from the client.

◆ serverchallengeresp() [1/2]

void nvhttp::serverchallengeresp ( pair_session_t & sess,
boost::property_tree::ptree & tree,
const std::string & encrypted_response )

Pair, phase 3.

Moonlight will send back a serverchallengeresp: an AES encrypted client hash, we have to send back the pairingsecret: using our private key we have to sign the certificate_signature + server_secret (generated in phase 2)

Parameters
sessPairing session that owns the request state.
treeXML property tree used for the response body.
encrypted_responseEncrypted response.

◆ serverchallengeresp() [2/2]

void nvhttp::serverchallengeresp ( pair_session_t & sess,
pt::ptree & tree,
const std::string & encrypted_response )

Handle the server-challenge response phase of GameStream pairing.

Parameters
sessPairing session that owns the request state.
treeXML property tree used for the response body.
encrypted_responseEncrypted response.

◆ serverinfo()

template<class T >
void nvhttp::serverinfo ( std::shared_ptr< typename SimpleWeb::ServerBase< T >::Response > response,
std::shared_ptr< typename SimpleWeb::ServerBase< T >::Request > request )

Build the GameStream server-info response.

Parameters
responseHTTP response object to populate.
requestHTTP request data from the client.

◆ set_client_enabled()

bool nvhttp::set_client_enabled ( std::string_view uuid,
bool enabled )

Enable or disable a client.

Parameters
uuidThe UUID of the client.
enabledWhether the client should be enabled.
Returns
true if the client was found and updated.

◆ setup()

void nvhttp::setup ( const std::string & pkey,
const std::string & cert )

Setup the nvhttp server.

Parameters
pkey
cert

◆ start()

void nvhttp::start ( )

Start the nvhttp server.

*Examples**

void start()
Start the nvhttp server.
Definition nvhttp.cpp:1263

◆ unpair_client()

bool nvhttp::unpair_client ( std::string_view uuid)

Remove single client.

Parameters
uuidThe UUID of the client to remove.

*Examples**

nvhttp::unpair_client("4D7BB2DD-5704-A405-B41C-891A022932E1");
bool unpair_client(const std::string_view uuid)
Remove single client.
Definition nvhttp.cpp:1424
Returns
True when the client entry was found and removed.

Variable Documentation

◆ VERSION

auto nvhttp::VERSION = "7.1.431.-1"
constexpr

The protocol version.

The version of the GameStream protocol we are mocking.

Note
The negative 4th number indicates to Moonlight that this is Sunshine.