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