2 * Copyright (c) 2014, JANET(UK)
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of JANET(UK) nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
31 * OF THE POSSIBILITY OF SUCH DAMAGE.
35 console.log('Loading navigator.gss.js - #9');
38 navigator.generateNonce = function() {
39 // TODO: Make sure that we don't have a collision!
40 // Random integer in the range [0..(2^32-1)]
41 return Math.floor(Math.random() * ( 4294967295 )) ;
47 /* This file gets injected into the web page verbatim */
49 var GSSEap = (function ()
51 function GSSEap(config)
54 this.version = "0.0.1";
55 this.implemented_methods = ["gss_import_name", "gss_display_name", "gss_init_sec_context", "gss_acquire_cred"];
56 // MRW -- combine success/error callback hashes?
59 this.appTag = config.appTag || "";
60 this.default_error = config.error ||
61 function (major, minor, error, appTag) {
64 window.addEventListener(
66 this.dispatch_responses.bind(this)
69 GSSEap.prototype.dispatch_responses = function (event)
77 /* This message is destined for us only if all the following apply:
78 * - The data.method_name is one of the methods implemented by this
80 * - data.return_values exists or data.error_mssage exists
81 * - data.cookies exists
82 * - One of my callbacks matches the nonce in
83 * data.cookies.navigator_gss_tag
84 * - One of my methods matches the nonce in
85 * data.cookies.navigator_gss_tag and that method matches
88 method = event.data.method;
90 ( -1 == this.implemented_methods.indexOf(method) ) ||
91 ( ("undefined" == typeof (event.data.return_values) ) &&
92 ("undefined" == typeof (event.data.error_message) ) ) ||
93 ("undefined" == typeof (event.data.cookies)))
98 nonce = event.data.cookies.navigator_gss_tag;
99 event.data.cookies.navigator_gss_tag = undefined;
100 callback = this.callbacks[nonce];
101 if ("undefined" == typeof (callback)) {
105 // We now know that this message is for us!
106 this.callbacks[nonce] = undefined;
107 app_tag = event.data.cookies.app_tag;
108 error = this.errors[nonce] || this.default_error;
110 if ("undefined" != typeof(event.data.error_message) )
112 error(-1, -1, "Error parsing message: " + event.data.error_message, app_tag);
114 else if (this.gss_error(event.data.return_values.major_status))
116 var errMsg = "Error during " + method + ": " +
117 "Major status message: " +
118 event.data.return_values.errors.major_status_message +
119 "; Minor status message: " +
120 event.data.return_values.errors.minor_status_message;
122 event.data.return_values.major_status,
123 event.data.return_values.minor_status,
127 callback(event.data.return_values, app_tag);
132 GSSEap.prototype.init_sec_context = function (params)
135 // internal variables
138 // Required parameters
139 var target_name = params.target_name;
140 var callback = params.success || this.success;
142 // Optional & defaulted parameters (some are defaulted at lower layer)
143 var context_handle = params.context_handle;
144 var cred_handle = params.cred_handle;
145 var mech_type = params.mech_type;
146 var req_flags = params.req_flags;
147 var time_req = params.time_req;
148 var input_token = params.input_token;
150 var error = params.error || this.default_error;
151 var app_tag = params.app_tag || this.appTag;
154 // Call an error if we don't have the required parameters.
157 if ( "undefined" == typeof(target_name) ||
158 "undefined" == typeof(callback) )
161 "init_sec_context called missing either target_name or success callback"
167 nonce = navigator.generateNonce();
169 /* Main processing */
170 // Save our callback, method name, and error function
171 this.callbacks[nonce] = callback;
172 this.errors[nonce] = error;
174 // Now pass the request on to the C code
176 "method":"gss_init_sec_context",
179 "target_name": target_name,
180 "context_handle": context_handle,
181 "cred_handle": cred_handle,
182 "mech_type": mech_type,
183 "req_flags": req_flags,
184 "time_req": time_req,
185 "input_token": input_token
190 "navigator_gss_tag": nonce,
197 GSSEap.prototype.display_name = function(params)
200 // required parameters
201 var input_name = params.input_name;
202 var callback = params.success;
204 if ( "undefined" == typeof(name) ||
205 "undefined" == typeof(callback) )
208 "import_name called missing either name or success callback"
213 var error = params.error || this.default_error;
214 var app_tag = params.app_tag || this.appTag;
217 nonce = navigator.generateNonce();
220 /* Main processing */
221 // Save our callback, method name, and error function
222 this.callbacks[nonce] = callback;
223 this.errors[nonce] = error;
225 // Now pass the request on to the C code
227 "method":"gss_display_name",
230 "input_name": input_name,
234 "navigator_gss_tag": nonce,
241 GSSEap.prototype.import_name = function (params)
244 // internal variables
247 // Required parameters
248 var name = params.name;
249 var callback = params.success;
251 // Optional & defaulted parameters
252 var name_type = params.name_type || "{1 2 840 113554 1 2 1 4 }";
253 var error = params.error || this.default_error;
254 var app_tag = params.app_tag || this.appTag;
258 // Call an error if we don't have the required parameters.
261 if ( "undefined" == typeof(name) ||
262 "undefined" == typeof(callback) )
265 "import_name called missing either name or success callback"
272 nonce = navigator.generateNonce();
275 /* Main processing */
276 // Save our callback, method name, and error function
277 this.callbacks[nonce] = callback;
278 this.errors[nonce] = error;
280 // Now pass the request on to the C code
282 "method":"gss_import_name",
286 "input_name_type": name_type
290 "navigator_gss_tag": nonce,
297 GSSEap.prototype.gss_error = function (major)
303 callingMask = 255 << 24;
304 routineMask = 255 << 16;
305 mask = callingMask | routineMask;
307 return (0 != (major & mask));
312 function newGSSEap(config)
314 return new GSSEap(config);
317 //var nav = createObjectIn(unsafeWindow, {defineAs: "navigator"});
318 var bob = createObjectIn(unsafeWindow, {defineAs: "bob"});
319 var gss_eap = createObjectIn(bob, {defineAs: "gss_eap"});
320 var gss_eap_proto = createObjectIn(gss_eap, {defineAs: "prototype"});
322 exportFunction(GSSEap.prototype.constructor, gss_eap_proto, {allowCallbacks: true, :defineAs: 'constructor'});
325 exportFunction(, gss_eap, {allowCallbacks: true});
326 exportFunction(, gss_eap, {allowCallbacks: true});
327 exportFunction(, gss_eap, {allowCallbacks: true});
328 exportFunction(, gss_eap, {allowCallbacks: true});
329 exportFunction(, gss_eap, {allowCallbacks: true});
332 /* exportFunction(GSSEap, nav, {defineAs: "gss_eap"});
333 exportFunction(GSSEap, unsafeWindow.navigator, {defineAs: "gss_eap_2"})
334 exportFunction(newGSSEap, nav, {defineAs: "gss_eap_3"})
338 exportFunction(newGSSEap, bob, {defineAs: 'newbob'});
340 exportFunction(doHello, bob, {defineAs: 'doHello'});