Create browsers directory and browsers/common for common navigator.gssEap.js, move...
[gssweb.git] / browsers / chrome / app / navigator.gss.js
1 /*
2  * Copyright (c) 2014, JANET(UK)
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
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.
15  *
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.
19  *
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.
32  *
33  */
34
35 console.log('Loading navigator.gss.js - #9');
36
37 /* This file gets injected into the web page verbatim */
38
39 var GSSEap = (function () 
40   {
41     function GSSEap(config)
42     {
43         // Public attributes
44         this.version = "0.0.1";
45         this.implemented_methods = ["gss_import_name", "gss_display_name", "gss_init_sec_context", "gss_acquire_cred"];
46         // MRW -- combine success/error callback hashes?
47         this.callbacks = {};
48         this.errors = {};
49         this.appTag = config.appTag || "";
50         this.default_error = config.error || 
51             function (major, minor, error, appTag) {
52                 console.warn(error);
53             };
54         window.addEventListener(
55             "message",
56             this.dispatch_responses.bind(this)
57         );
58     }
59     GSSEap.prototype.dispatch_responses = function (event) 
60     {
61         var method;
62         var nonce;
63         var callback;
64         var app_tag;
65         var error;
66
67         /* This message is destined for us only if all the following apply:
68         * - The data.method_name is one of the methods implemented by this
69         *   object
70         * - data.return_values exists or data.error_mssage exists
71         * - data.cookies exists
72         * - One of my callbacks matches the nonce in
73         *   data.cookies.navigator_gss_tag
74         * - One of my methods matches the nonce in 
75         *   data.cookies.navigator_gss_tag and that method matches
76         *   data.method
77         */
78         method = event.data.method;
79         if (
80              ( -1 == this.implemented_methods.indexOf(method) ) ||
81              (  ("undefined" == typeof (event.data.return_values) ) &&
82                 ("undefined" == typeof (event.data.error_message) ) ) ||
83              ("undefined" == typeof (event.data.cookies)))
84         {
85             return;
86         }
87
88         nonce = event.data.cookies.navigator_gss_tag;
89         event.data.cookies.navigator_gss_tag = undefined;
90         callback = this.callbacks[nonce];
91         if ("undefined" == typeof (callback)) {
92             return;
93         }
94
95         // We now know that this message is for us!
96         this.callbacks[nonce] = undefined;
97         app_tag = event.data.cookies.app_tag;
98         error = this.errors[nonce] || this.default_error;
99
100         if ("undefined" != typeof(event.data.error_message) )
101         {
102             error(-1, -1, "Error parsing message: " + event.data.error_message, app_tag);
103         }
104         else if (this.gss_error(event.data.return_values.major_status))
105         {
106             var errMsg = "Error during " + method + ": " + 
107               "Major status message: " + 
108               event.data.return_values.errors.major_status_message + 
109               "; Minor status message: " + 
110               event.data.return_values.errors.minor_status_message;
111             error(
112               event.data.return_values.major_status,
113               event.data.return_values.minor_status, 
114               errMsg,
115               app_tag);
116         } else {
117             callback(event.data.return_values, app_tag);
118         }
119     };
120
121
122     GSSEap.prototype.init_sec_context = function (params) 
123     {
124         /* variables */
125         // internal variables
126         var nonce;
127         
128         // Required parameters
129         var target_name = params.target_name;
130         var callback = params.success || this.success;
131
132         // Optional & defaulted parameters (some are defaulted at lower layer)
133         var context_handle = params.context_handle;
134         var cred_handle = params.cred_handle; 
135         var mech_type = params.mech_type; 
136         var req_flags = params.req_flags;
137         var time_req = params.time_req;
138         var input_token = params.input_token;
139
140         var error = params.error || this.default_error; 
141         var app_tag = params.app_tag || this.appTag;
142
143         /* Error checking */
144         // Call an error if we don't have the required parameters.
145         // - name
146         // - success()
147         if ( "undefined" == typeof(target_name) ||
148              "undefined" == typeof(callback) )
149         {
150           error(-1, -1, 
151             "init_sec_context called missing either target_name or success callback"
152           );
153           return;
154         }
155         
156         /* Setup */
157         nonce = navigator.generateNonce();
158
159         /* Main processing */
160         // Save our callback, method name, and error function
161         this.callbacks[nonce] = callback;
162         this.errors[nonce] = error;
163         
164         // Now pass the request on to the C code
165         window.postMessage({
166             "method":"gss_init_sec_context",
167             "arguments":
168             {
169                 "target_name": target_name,
170                 "context_handle": context_handle,
171                 "cred_handle": cred_handle,
172                 "mech_type": mech_type,
173                 "req_flags": req_flags,
174                 "time_req": time_req,
175                 "input_token": input_token
176                 
177             },
178             "cookies":
179             {
180                 "navigator_gss_tag": nonce,
181                 "app_tag": app_tag
182             }
183         }, "*");
184         
185     };
186
187     GSSEap.prototype.display_name = function(params)
188     {
189         /* Variables */
190         // required parameters
191         var input_name = params.input_name;
192         var callback = params.success;
193
194         if ( "undefined" == typeof(name) ||
195              "undefined" == typeof(callback) )
196         {
197           error(-1, -1, 
198             "import_name called missing either name or success callback"
199           );
200           return;
201         }
202
203         var error = params.error || this.default_error; 
204         var app_tag = params.app_tag || this.appTag;
205         
206         /* Setup */
207         nonce = navigator.generateNonce();
208
209
210         /* Main processing */
211         // Save our callback, method name, and error function
212         this.callbacks[nonce] = callback;
213         this.errors[nonce] = error;
214         
215         // Now pass the request on to the C code
216         window.postMessage({
217             "method":"gss_display_name",
218             "arguments":
219             {
220                 "input_name": input_name,
221             },
222             "cookies":
223             {
224                 "navigator_gss_tag": nonce,
225                 "app_tag": app_tag
226             }
227         }, "*");
228         
229     }
230
231     GSSEap.prototype.import_name = function (params) 
232     {
233         /* variables */
234         // internal variables
235         var nonce;
236         
237         // Required parameters
238         var name = params.name;
239         var callback = params.success;
240         
241         // Optional & defaulted parameters
242         var name_type = params.name_type || "{1 2 840 113554 1 2 1 4 }";
243         var error = params.error || this.default_error; 
244         var app_tag = params.app_tag || this.appTag;
245
246
247         /* Error checking */
248         // Call an error if we don't have the required parameters.
249         // - name
250         // - success()
251         if ( "undefined" == typeof(name) ||
252              "undefined" == typeof(callback) )
253         {
254           error(-1, -1, 
255             "import_name called missing either name or success callback"
256           );
257           return;
258         }
259
260         
261         /* Setup */
262         nonce = navigator.generateNonce();
263
264
265         /* Main processing */
266         // Save our callback, method name, and error function
267         this.callbacks[nonce] = callback;
268         this.errors[nonce] = error;
269         
270         // Now pass the request on to the C code
271         window.postMessage({
272             "method":"gss_import_name",
273             "arguments":
274             {
275                 "input_name": name,
276                 "input_name_type": name_type
277             },
278             "cookies":
279             {
280                 "navigator_gss_tag": nonce,
281                 "app_tag": app_tag
282             }
283         }, "*");
284         
285     };
286
287     GSSEap.prototype.gss_error = function (major) 
288     {
289         var callingMask;
290         var routineMask;
291         var mask;
292
293         callingMask = 255 << 24;
294         routineMask = 255 << 16;
295         mask = callingMask | routineMask;
296
297         return (0 != (major & mask));
298     };
299     return GSSEap;
300 })();
301
302 navigator.gssEap = GSSEap;