diff options
author | ajwong@chromium.org <ajwong@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-07 01:22:44 +0000 |
---|---|---|
committer | ajwong@chromium.org <ajwong@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-07 01:22:44 +0000 |
commit | f177a378b264032c720c8fdb2e3f994fd14d3c4e (patch) | |
tree | b9c1f18fc4396ba8b7184a2eba55c672ed6d22e1 /remoting | |
parent | 888ed866c56f76d8d7c98ab26839eb5e126b9bb4 (diff) | |
download | chromium_src-f177a378b264032c720c8fdb2e3f994fd14d3c4e.zip chromium_src-f177a378b264032c720c8fdb2e3f994fd14d3c4e.tar.gz chromium_src-f177a378b264032c720c8fdb2e3f994fd14d3c4e.tar.bz2 |
Update Chromoting app-engine to invoke sandboxed connections.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/6758043
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@80733 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting')
-rw-r--r-- | remoting/client/appengine/auth.py | 19 | ||||
-rw-r--r-- | remoting/client/appengine/chromoting_oauth_setup.html | 4 | ||||
-rw-r--r-- | remoting/client/appengine/chromoting_session.html | 8 | ||||
-rw-r--r-- | remoting/client/appengine/main.py | 7 | ||||
-rw-r--r-- | remoting/client/appengine/static_files/chromoting_session.js | 95 | ||||
-rw-r--r-- | remoting/client/appengine/static_files/client.js | 11 |
6 files changed, 138 insertions, 6 deletions
diff --git a/remoting/client/appengine/auth.py b/remoting/client/appengine/auth.py index f40cbdd..b1b0132 100644 --- a/remoting/client/appengine/auth.py +++ b/remoting/client/appengine/auth.py @@ -46,6 +46,7 @@ class OAuthConfig(db.Model): """ consumer_key = db.StringProperty() consumer_secret = db.StringProperty() + httpxmppproxy = db.StringProperty() def GetChromotingToken(throws=True): @@ -288,9 +289,20 @@ class SetupOAuthHandler(webapp.RequestHandler): # If there is an existing key, only allow updating if you know the old # key. This is a simple safeguard against random users hitting this page. config = GetOAuthConfig(throws=False) + httpxmppproxy = self.request.get('httpxmppproxy') + # TODO(ajwong): THIS IS A TOTAL HACK! FIX WITH OWN PAGE. + # Currently, this form has one submit button, and 3 pieces of input: + # consumer_key, oauth_secret, and the httpxmppproxy address. The first + # two only get committed if the secret + key match. The third always + # get committed via this hack. Really, it should just be a separate + # field/page to set this up. + if httpxmppproxy: + config.httpxmppproxy = httpxmppproxy + config.put() + config.consumer_key = self.request.get('consumer_key') if config: if config.consumer_secret != old_consumer_secret: - self.response.out.set_status(400) + self.response.set_status(400) self.response.out.write('Incorrect old consumer secret') return else: @@ -301,6 +313,11 @@ class SetupOAuthHandler(webapp.RequestHandler): config.put() self.redirect('/') +def GetHttpXmppProxy(): + config = GetOAuthConfig(throws=True) + if not config.httpxmppproxy: + raise OAuthInvalidSetup() + return config.httpxmppproxy def main(): application = webapp.WSGIApplication( diff --git a/remoting/client/appengine/chromoting_oauth_setup.html b/remoting/client/appengine/chromoting_oauth_setup.html index 3fc4664..1b1537c 100644 --- a/remoting/client/appengine/chromoting_oauth_setup.html +++ b/remoting/client/appengine/chromoting_oauth_setup.html @@ -13,10 +13,14 @@ found in the LICENSE file. <p>This is an administration page to setup the consumer key and secret to be used with chromoting. Please don't play with this unless you are on the Chromoting dev team. + <p> + Move the HttpXmppProxy setup out of this page, and make the semantics less + hacky! <form method="post" name="auth"> Consumer Key: <input type="text" name="consumer_key" /> New Consumer Secret: <input type="password" name="new_consumer_secret" /> Old Consumer Secret: <input type="password" name="old_consumer_secret" /> + HttpXmppProxy Address: <input type="text" name="httpxmppproxy" /> <input type="submit" value="Submit" /> </form> </body> diff --git a/remoting/client/appengine/chromoting_session.html b/remoting/client/appengine/chromoting_session.html index fecd5142..794ac56 100644 --- a/remoting/client/appengine/chromoting_session.html +++ b/remoting/client/appengine/chromoting_session.html @@ -11,11 +11,15 @@ found in the LICENSE file. <link rel="stylesheet" type="text/css" href="static_files/main.css" /> <script type="text/javascript"> <!-- - // TODO(ajwong): Total Hack. Do this nicer. - document.xmpp_auth_token="{{xmpp_token.token_string}}"; + // TODO(ajwong): Total Hack. We should be able to read the URL parameters + // from JS, and also avoid passing in the connection tokens here. + document.xmppAuthToken="{{xmpp_token.token_string}}"; + document.httpXmppProxy="{{http_xmpp_proxy}}"; document.username="{{username}}"; document.hostname="{{hostname}}"; document.hostjid="{{hostjid}}"; + document.connectMethod="{{connect_method}}"; + document.insecure="{{insecure}}"; --> </script> <script type="text/javascript" src="static_files/base.js"></script> diff --git a/remoting/client/appengine/main.py b/remoting/client/appengine/main.py index 78900c2..36f81d7 100644 --- a/remoting/client/appengine/main.py +++ b/remoting/client/appengine/main.py @@ -1,5 +1,9 @@ #!/usr/bin/env python +# Copyright (c) 2011 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + import logging import os @@ -36,7 +40,10 @@ class ChromotingSessionHandler(webapp.RequestHandler): 'hostname': self.request.get('hostname'), 'username': users.get_current_user().email(), 'hostjid': self.request.get('hostjid'), + 'connect_method': self.request.get('connect_method'), + 'insecure': self.request.get('insecure'), 'xmpp_token': auth.GetXmppToken(), + 'http_xmpp_proxy': auth.GetHttpXmppProxy(), } path = os.path.join(os.path.dirname(__file__), 'chromoting_session.html') self.response.out.write(template.render(path, template_params)) diff --git a/remoting/client/appengine/static_files/chromoting_session.js b/remoting/client/appengine/static_files/chromoting_session.js index 3e22c85..8c7b216 100644 --- a/remoting/client/appengine/static_files/chromoting_session.js +++ b/remoting/client/appengine/static_files/chromoting_session.js @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -10,6 +10,78 @@ var MAX_DEBUG_LOG_SIZE = 1000; // old messages. This starts at 1 and is incremented for each new message. chromoting.messageId = 1; +// Default to trying to sandboxed connections. +chromoting.connectMethod = 'sandboxed'; + +// This executes a poll loop on the server for more Iq packets, and feeds them +// to the plugin. +function feedIq() { + var xhr = new XMLHttpRequest(); + xhr.open("GET", chromoting.httpXmppProxy + '/readIq?host_jid=' + + encodeURIComponent(document.hostjid), true); + xhr.withCredentials = true; + xhr.onreadystatechange = function() { + if (xhr.readyState == 4) { + if (xhr.status == 200 || xhr.status == 204) { + addToDebugLog('Receiving Iq: --' + xhr.responseText + '--'); + chromoting.plugin.onIq(xhr.responseText); + window.setTimeout(feedIq, 0); + } else { + addToDebugLog("HttpXmpp gateway returned code: " + xhr.status); + } + } + } + xhr.send(null); +} + +function registerConnection() { + var xhr = new XMLHttpRequest(); + xhr.open("POST", chromoting.httpXmppProxy + '/newConnection', true); + xhr.withCredentials = true; + xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); + xhr.onreadystatechange = function() { + if (xhr.readyState == 4) { + if (xhr.status == 200) { + addToDebugLog('Receiving Iq: --' + xhr.responseText + '--'); + var clientjid = xhr.responseText; + + chromoting.plugin.sendIq = sendIq; + chromoting.plugin.connectSandboxed(clientjid, chromoting.hostjid); + // TODO(ajwong): This should just be feedIq(); + window.setTimeout(feedIq, 1000); + } else { + addToDebugLog('FailedToConnect: --' + xhr.responseText + '--'); + } + } + } + xhr.send('host_jid=' + encodeURIComponent(chromoting.hostjid) + + '&username=' + encodeURIComponent(chromoting.username) + + '&password=' + encodeURIComponent(chromoting.xmppAuthToken)); +} + +function sendIq(msg) { + addToDebugLog('Sending Iq: ' + msg); + + // Extract the top level fields of the Iq packet. + // TODO(ajwong): Can the plugin just return these fields broken out. + parser = new DOMParser(); + iqNode = parser.parseFromString(msg,"text/xml").firstChild; + id = iqNode.getAttribute("id"); + type = iqNode.getAttribute("type"); + to = iqNode.getAttribute("to"); + serializer = new XMLSerializer(); + payload_xml = serializer.serializeToString(iqNode.firstChild); + + var xhr = new XMLHttpRequest(); + xhr.open("POST", chromoting.httpXmppProxy + '/sendIq', true); + xhr.withCredentials = true; + xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); + xhr.send("to=" + encodeURIComponent(to) + + "&payload_xml=" + encodeURIComponent(payload_xml) + + "&id=" + id + "&type=" + type + + "&host_jid=" + encodeURIComponent(chromoting.hostjid)); +} + function init() { // Kick off the connection. var plugin = document.getElementById('chromoting'); @@ -18,6 +90,19 @@ function init() { chromoting.username = document.username; chromoting.hostname = document.hostname; chromoting.hostjid = document.hostjid; + chromoting.xmppAuthToken = document.xmppAuthToken; + chromoting.connectMethod = document.connectMethod; + + // Only allow https connections to the httpXmppProxy unless we're running in + // insecure mode. + if (document.insecure != "1" && + document.httpXmppProxy.search(/^ *https:\/\//) == -1) { + addToDebugLog('Aborting. httpXmppProxy does not specify https protocol: ' + + document.httpXmppProxy); + return; + } + + chromoting.httpXmppProxy = document.httpXmppProxy; // Setup the callback that the plugin will call when the connection status // has changes and the UI needs to be updated. It needs to be an object with @@ -32,8 +117,12 @@ function init() { // TODO(garykac): Clean exit if |connect| isn't a funtion. if (typeof plugin.connect === 'function') { - plugin.connect(chromoting.username, chromoting.hostjid, - document.xmpp_auth_token); + if (chromoting.connectMethod == "sandboxed") { + registerConnection(); + } else { + plugin.connect(chromoting.username, chromoting.hostjid, + chromoting.xmppAuthToken); + } } else { console.log('ERROR: chromoting plugin not loaded'); } diff --git a/remoting/client/appengine/static_files/client.js b/remoting/client/appengine/static_files/client.js index 7252128..b485467 100644 --- a/remoting/client/appengine/static_files/client.js +++ b/remoting/client/appengine/static_files/client.js @@ -186,12 +186,23 @@ function addHostInfo(host) { var span = document.createElement('span'); span.setAttribute('class', 'connect'); var connect = document.createElement('input'); + connect.setAttribute('type', 'button'); connect.setAttribute('value', 'Connect'); connect.setAttribute('onclick', "window.open('session?hostname=" + encodeURIComponent(host.hostName) + "&hostjid=" + encodeURIComponent(host.jabberId) + "');"); span.appendChild(connect); + + var connectSandboxed = document.createElement('input'); + connectSandboxed.setAttribute('type', 'button'); + connectSandboxed.setAttribute('value', 'Connect Sandboxed'); + connectSandboxed.setAttribute('onclick', + "window.open('session?hostname=" + encodeURIComponent(host.hostName) + + "&hostjid=" + encodeURIComponent(host.jabberId) + + "&connect_method=sandboxed');"); + span.appendChild(connectSandboxed); + hostEntry.appendChild(span); hostIcon.setAttribute('src', 'static_files/online.png'); } else { |