1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// found in the LICENSE file.
4a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)/**
6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * @fileoverview
7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * Class that routes gnubby-auth extension messages to and from the gnubbyd
8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * extension.
9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) */
10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)'use strict';
12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)/** @suppress {duplicate} */
14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)var remoting = remoting || {};
15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)/**
17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * @constructor
18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * @param {!remoting.ClientSession} clientSession The client session to send
19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *     gnubby-auth response messages to.
20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) */
21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)remoting.GnubbyAuthHandler = function(clientSession) {
22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  this.clientSession_ = clientSession;
23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)};
24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)/**
26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * Processes gnubby-auth messages.
27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * @param {string} data The gnubby-auth message data.
28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) */
29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)remoting.GnubbyAuthHandler.prototype.onMessage = function(data) {
30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  var message = getJsonObjectFromString(data);
31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  var messageType = getStringAttr(message, 'type');
32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (messageType == 'data') {
33effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    this.sendMessageToGnubbyd_({
34effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      'type': 'auth-agent@openssh.com',
35effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      'data': getArrayAttr(message, 'data')
36effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    }, this.callback_.bind(this, getNumberAttr(message, 'connectionId')));
37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  } else {
38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    console.error('Invalid gnubby-auth message: ' + messageType);
39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)};
41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)/**
43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * Callback invoked with data to be returned to the host.
44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * @param {number} connectionId The connection id.
45effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch * @param {Object} response The JSON response with the data to send to the host.
46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * @private
47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) */
48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)remoting.GnubbyAuthHandler.prototype.callback_ =
49effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    function(connectionId, response) {
50effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  try {
51effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    this.clientSession_.sendGnubbyAuthMessage({
52effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      'type': 'data',
53effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      'connectionId': connectionId,
54effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      'data': getArrayAttr(response, 'data')
55effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    });
56effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  } catch (err) {
57effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    console.error('gnubby callback failed: ', /** @type {*} */ (err));
58effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    this.clientSession_.sendGnubbyAuthMessage({
59effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      'type': 'error',
60effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      'connectionId': connectionId
61effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    });
62effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return;
63effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)};
65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)/**
67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * Send data to the gnubbyd extension.
68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * @param {Object} jsonObject The JSON object to send to the gnubbyd extension.
69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * @param {function(Object)} callback The callback to invoke with reply data.
70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * @private
71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) */
72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)remoting.GnubbyAuthHandler.prototype.sendMessageToGnubbyd_ =
73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    function(jsonObject, callback) {
74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  var kGnubbydDevExtensionId = 'dlfcjilkjfhdnfiecknlnddkmmiofjbg';
75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  chrome.runtime.sendMessage(
77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      kGnubbydDevExtensionId,
78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      jsonObject,
79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      onGnubbydDevReply_.bind(this, jsonObject, callback));
80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)};
81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)/**
83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * Callback invoked as a result of sending a message to the gnubbyd-dev
84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * extension. If that extension is not installed, reply will be undefined;
85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * otherwise it will be the JSON response object.
86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * @param {Object} jsonObject The JSON object to send to the gnubbyd extension.
87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * @param {function(Object)} callback The callback to invoke with reply data.
88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * @param {Object} reply The reply from the extension (or Chrome, if the
89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *    extension does not exist.
90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * @private
91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) */
92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)function onGnubbydDevReply_(jsonObject, callback, reply) {
93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  var kGnubbydStableExtensionId = 'beknehfpfkghjoafdifaflglpjkojoco';
94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (reply) {
96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    callback(reply);
97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  } else {
98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    chrome.runtime.sendMessage(kGnubbydStableExtensionId, jsonObject, callback);
99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
100effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
101