summaryrefslogtreecommitdiffstats
path: root/remoting
diff options
context:
space:
mode:
authorajwong@chromium.org <ajwong@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-07 01:22:44 +0000
committerajwong@chromium.org <ajwong@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-07 01:22:44 +0000
commitf177a378b264032c720c8fdb2e3f994fd14d3c4e (patch)
treeb9c1f18fc4396ba8b7184a2eba55c672ed6d22e1 /remoting
parent888ed866c56f76d8d7c98ab26839eb5e126b9bb4 (diff)
downloadchromium_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.py19
-rw-r--r--remoting/client/appengine/chromoting_oauth_setup.html4
-rw-r--r--remoting/client/appengine/chromoting_session.html8
-rw-r--r--remoting/client/appengine/main.py7
-rw-r--r--remoting/client/appengine/static_files/chromoting_session.js95
-rw-r--r--remoting/client/appengine/static_files/client.js11
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 {