From e90fe56f2ba4c4e0fd17ac6b043a651ed7dd29e5 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Mon, 9 May 2016 19:19:26 -0400 Subject: [PATCH] Generate a unique remote input key per connection. This closes #54 --- main.cpp | 21 ++++++++++++++++++++- static/js/index.js | 10 ++++++---- static/js/utils.js | 11 +++++++++++ 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/main.cpp b/main.cpp index 94b3051..5ad0e1a 100644 --- a/main.cpp +++ b/main.cpp @@ -9,6 +9,8 @@ #include "ppapi/cpp/input_event.h" +#include + // Requests the NaCl module to connection to the server specified after the : #define MSG_START_REQUEST "startRequest" // Requests the NaCl module stop streaming @@ -155,6 +157,12 @@ void MoonlightInstance::HandleMessage(const pp::Var& var_message) { } } +static void hexStringToBytes(const char* str, char* output) { + for (int i = 0; i < strlen(str); i += 2) { + sscanf(&str[i], "%2hhx", &output[i / 2]); + } +} + void MoonlightInstance::HandleStartStream(int32_t callbackId, pp::VarArray args) { std::string host = args.Get(0).AsString(); std::string width = args.Get(1).AsString(); @@ -162,6 +170,8 @@ void MoonlightInstance::HandleStartStream(int32_t callbackId, pp::VarArray args) std::string fps = args.Get(3).AsString(); std::string bitrate = args.Get(4).AsString(); std::string serverMajorVersion = args.Get(5).AsString(); + std::string rikey = args.Get(6).AsString(); + std::string rikeyid = args.Get(7).AsString(); pp::Var response("Setting stream width to: " + width); PostMessage(response); @@ -175,14 +185,20 @@ void MoonlightInstance::HandleStartStream(int32_t callbackId, pp::VarArray args) PostMessage(response); response = ("Setting server major version to: " + serverMajorVersion); PostMessage(response); + response = ("Setting rikey to: " + rikey); + PostMessage(response); + response = ("Setting rikeyid to: " + rikeyid); + PostMessage(response); // Populate the stream configuration + LiInitializeStreamConfiguration(&m_StreamConfig); m_StreamConfig.width = stoi(width); m_StreamConfig.height = stoi(height); m_StreamConfig.fps = stoi(fps); m_StreamConfig.bitrate = stoi(bitrate); // kilobits per second m_StreamConfig.streamingRemotely = 0; m_StreamConfig.audioConfiguration = AUDIO_CONFIGURATION_STEREO; + m_ServerMajorVersion = stoi(serverMajorVersion); // The overhead of receiving a packet is much higher in NaCl because we must // pass through various layers of abstraction on each recv() call. We're using a @@ -190,7 +206,10 @@ void MoonlightInstance::HandleStartStream(int32_t callbackId, pp::VarArray args) // receiving packets. The possible cost is greater network losses. m_StreamConfig.packetSize = 1392; - m_ServerMajorVersion = stoi(serverMajorVersion); + // Load the rikey and rikeyid into the stream configuration + hexStringToBytes(rikey.c_str(), m_StreamConfig.remoteInputAesKey); + int rikeyiv = htonl(stoi(rikeyid)); + memcpy(m_StreamConfig.remoteInputAesIv, &rikeyiv, sizeof(rikeyiv)); // Initialize the rendering surface before starting the connection InitializeRenderingSurface(m_StreamConfig.width, m_StreamConfig.height); diff --git a/static/js/index.js b/static/js/index.js index cc1288a..d613f39 100644 --- a/static/js/index.js +++ b/static/js/index.js @@ -290,15 +290,16 @@ function startSelectedGame() { var bitrate = parseInt($("#bitrateSlider").val()) * 1000; console.log('startRequest:' + host + ":" + streamWidth + ":" + streamHeight + ":" + frameRate + ":" + bitrate); - var rikey = '00000000000000000000000000000000'; - var rikeyid = 0; + var rikey = generateRemoteInputKey(); + var rikeyid = generateRemoteInputKeyId(); $('#loadingMessage').text('Starting ' + $("#selectGame option:selected").text() + '...'); playGameMode(); if(api.currentGame == appID) // if user wants to launch the already-running app, then we resume it. return api.resumeApp(rikey, rikeyid).then(function (ret) { - sendMessage('startRequest', [host, streamWidth, streamHeight, frameRate, bitrate.toString(), api.serverMajorVersion.toString()]); + sendMessage('startRequest', [host, streamWidth, streamHeight, frameRate, + bitrate.toString(), api.serverMajorVersion.toString(), rikey, rikeyid.toString()]); }, function (failedResumeApp) { console.log('ERROR: failed to resume the app!'); console.log('Returned error was: ' + failedResumeApp); @@ -312,7 +313,8 @@ function startSelectedGame() { 0, // Play audio locally too 0x030002 // Surround channel mask << 16 | Surround channel count ).then(function (ret) { - sendMessage('startRequest', [host, streamWidth, streamHeight, frameRate, bitrate.toString(), api.serverMajorVersion.toString()]); + sendMessage('startRequest', [host, streamWidth, streamHeight, frameRate, + bitrate.toString(), api.serverMajorVersion.toString(), rikey, rikeyid.toString()]); }, function (failedLaunchApp) { console.log('ERROR: failed to launch app with appID: ' + appID); console.log('Returned error was: ' + failedLaunchApp); diff --git a/static/js/utils.js b/static/js/utils.js index bf27073..a81d9ee 100644 --- a/static/js/utils.js +++ b/static/js/utils.js @@ -12,6 +12,17 @@ function uniqueid() { }); } +function generateRemoteInputKey() { + return 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'.replace(/[x]/g, function(c) { + var r = Math.random()*16|0; + return r.toString(16); + }); +} + +function generateRemoteInputKeyId() { + return ((Math.random()-0.5) * 0x7FFFFFFF)|0; +} + String.prototype.toHex = function() { var hex = ''; for(var i = 0; i < this.length; i++) {