Beispiel #1
0
        /// <summary>
        /// Pair with the hostname in the textbox
        /// </summary>
        public async Task Pair(CoreDispatcher uiDispatcher, Computer c)
        {
            Debug.WriteLine("Pairing...");

            // Get the pair state.
            bool?pairState = await QueryPairState();

            if (pairState == true)
            {
                DialogUtils.DisplayDialog(uiDispatcher, "This device is already paired to the host PC", "Already Paired");
                return;
            }
            // pairstate = null. We've encountered an error
            else if (!pairState.HasValue)
            {
                DialogUtils.DisplayDialog(uiDispatcher, "Failed to query pair state", "Pairing failed");
                return;
            }

            bool challenge = await PairingCryptoHelpers.PerformPairingHandshake(uiDispatcher, new WindowsCryptoProvider(), nv, nv.GetUniqueId());

            if (!challenge)
            {
                Debug.WriteLine("Challenges failed");
                return;
            }

            // Otherwise, everything was successful
            MainPage.SaveComputer(c);

            // FIXME: We can't have two dialogs open at once.
            // DialogUtils.DisplayDialog(uiDispatcher, "Pairing successful", "Success");
        }
Beispiel #2
0
        private static async Task<X509Certificate> ExtractPlainCert(XmlQuery q, String tag)
        {
            String certHexString = await q.ReadXmlElement(tag);
            byte[] certBytes = PairingCryptoHelpers.HexToBytes(certHexString);
            String certText = Encoding.UTF8.GetString(certBytes, 0, certBytes.Length);

            PemReader certReader = new PemReader(new StringReader(certText));
            return (X509Certificate)certReader.ReadObject();
        }
        /// Get the local device's name
        /// </summary>
        /// <returns>Unique ID for the device</returns>
        public String GetUniqueId()
        {
            var settings = ApplicationData.Current.RoamingSettings;

            byte[] bytes;

            if (settings.Values.ContainsKey("uniqueid"))
            {
                bytes = (byte[])settings.Values["uniqueid"];
            }
            else
            {
                bytes = PairingCryptoHelpers.GenerateRandomBytes(8);
                settings.Values["uniqueid"] = bytes;
            }

            return(PairingCryptoHelpers.BytesToHex(bytes));
        }
Beispiel #4
0
        /// <summary>
        /// Executed when the user presses "Start Streaming Steam!"
        /// </summary>
        private async Task StreamButton_Click_Common()
        {
            Debug.WriteLine("Start Streaming button pressed");

            selected = (Computer)computerPicker.SelectedItem;

            // User hasn't selected a machine or selected a placeholder
            if (selected == null || String.IsNullOrWhiteSpace(selected.IpAddress))
            {
                DialogUtils.DisplayDialog(this.Dispatcher, "No machine selected", "Streaming Failed");
            }
            else
            {
                // Stop enumerating machines while we're trying to check pair state
                mDnsTimer.Stop();

                byte[] aesKey = PairingCryptoHelpers.GenerateRandomBytes(16);

                // GameStream only uses 4 bytes of a 16 byte IV. Go figure.
                byte[] aesRiIndex = PairingCryptoHelpers.GenerateRandomBytes(4);
                byte[] aesIv      = new byte[16];
                Array.ConstrainedCopy(aesRiIndex, 0, aesIv, 0, aesRiIndex.Length);
                SettingsPage s = new SettingsPage();
                MoonlightStreamConfiguration config = new MoonlightStreamConfiguration(
                    s.GetStreamWidth(),
                    s.GetStreamHeight(),
                    s.GetStreamFps(),
                    10000, // FIXME: Scale by resolution
                    1024,
                    aesKey, aesIv);

                StreamContext context = await ConnectionManager.StartStreaming(this.Dispatcher, selected, config);

                if (context != null)
                {
                    this.Frame.Navigate(typeof(StreamFrame), context);
                }
            }
        }
        /// <summary>
        /// Create start HTTP request
        /// </summary>
        private async Task <bool> StartOrResumeApp(NvHttp nv, MoonlightStreamConfiguration streamConfig)
        {
            XmlQuery serverInfo        = new XmlQuery(nv.BaseUrl + "/serverinfo?uniqueid=" + nv.GetUniqueId());
            string   currentGameString = await serverInfo.ReadXmlElement("currentgame");

            if (currentGameString == null)
            {
                return(false);
            }

            string versionString = await serverInfo.ReadXmlElement("appversion");

            if (versionString == null)
            {
                return(false);
            }

            serverMajorVersion = Convert.ToInt32(versionString.Substring(0, 1));

            byte[] aesIv   = streamConfig.GetRiAesIv();
            int    riKeyId =
                (int)(((aesIv[0] << 24) & 0xFF000000U) |
                      ((aesIv[1] << 16) & 0xFF0000U) |
                      ((aesIv[2] << 8) & 0xFF00U) |
                      (aesIv[3] & 0xFFU));
            string riConfigString =
                "&rikey=" + PairingCryptoHelpers.BytesToHex(streamConfig.GetRiAesKey()) +
                "&rikeyid=" + riKeyId;

            // Launch a new game if nothing is running
            if (currentGameString == null || currentGameString.Equals("0"))
            {
                XmlQuery x = new XmlQuery(nv.BaseUrl + "/launch?uniqueid=" + nv.GetUniqueId() + "&appid=" + context.appId +
                                          "&mode=" + streamConfig.GetWidth() + "x" + streamConfig.GetHeight() + "x" + streamConfig.GetFps() +
                                          "&additionalStates=1&sops=1" + // FIXME: make sops configurable
                                          riConfigString);

                string sessionStr = await x.ReadXmlElement("gamesession");

                if (sessionStr == null || sessionStr.Equals("0"))
                {
                    return(false);
                }

                return(true);
            }
            else
            {
                // A game was already running, so resume it
                // FIXME: Quit and relaunch if it's not the game we came to start
                XmlQuery x = new XmlQuery(nv.BaseUrl + "/resume?uniqueid=" + nv.GetUniqueId() + riConfigString);

                string resumeStr = await x.ReadXmlElement("resume");

                if (resumeStr == null || resumeStr.Equals("0"))
                {
                    return(false);
                }

                return(true);
            }
        }