|
---|
|
---|
4 |
|
4 |
|
5 |
const FLAG_RETURN_FALSE = 1 << 0; |
5 |
const FLAG_RETURN_FALSE = 1 << 0; |
6 |
const FLAG_WRONG_PASSWORD = 1 << 1; |
6 |
const FLAG_WRONG_PASSWORD = 1 << 1; |
7 |
|
7 |
|
8 |
const nsIAuthPrompt2 = Components.interfaces.nsIAuthPrompt2; |
8 |
const nsIAuthPrompt2 = Components.interfaces.nsIAuthPrompt2; |
9 |
const nsIAuthInformation = Components.interfaces.nsIAuthInformation; |
9 |
const nsIAuthInformation = Components.interfaces.nsIAuthInformation; |
10 |
|
10 |
|
11 |
|
11 |
|
12 |
function AuthPrompt1(flags) { |
12 |
function AuthPrompt1(flags, user, pass) { |
13 |
this.flags = flags; |
13 |
this.flags = flags; |
|
|
14 |
this.user = user || "guest"; |
15 |
this.pass = pass || "guest"; |
14 |
} |
16 |
} |
15 |
|
17 |
|
16 |
AuthPrompt1.prototype = { |
18 |
AuthPrompt1.prototype = { |
17 |
user: "guest", |
|
|
18 |
pass: "guest", |
19 |
|
19 |
|
20 |
expectedRealm: "secret", |
20 |
expectedRealm: "secret", |
21 |
|
21 |
|
22 |
QueryInterface: function authprompt_qi(iid) { |
22 |
QueryInterface: function authprompt_qi(iid) { |
23 |
if (iid.equals(Components.interfaces.nsISupports) || |
23 |
if (iid.equals(Components.interfaces.nsISupports) || |
24 |
iid.equals(Components.interfaces.nsIAuthPrompt)) |
24 |
iid.equals(Components.interfaces.nsIAuthPrompt)) |
25 |
return this; |
25 |
return this; |
26 |
throw Components.results.NS_ERROR_NO_INTERFACE; |
26 |
throw Components.results.NS_ERROR_NO_INTERFACE; |
Lines 59-81
AuthPrompt1.prototype = {
|
Link Here
|
---|
|
---|
59 |
}, |
59 |
}, |
60 |
|
60 |
|
61 |
promptPassword: function ap1_promptPW(title, text, realm, save, pwd) { |
61 |
promptPassword: function ap1_promptPW(title, text, realm, save, pwd) { |
62 |
do_throw("unexpected promptPassword call"); |
62 |
do_throw("unexpected promptPassword call"); |
63 |
} |
63 |
} |
64 |
|
64 |
|
65 |
}; |
65 |
}; |
66 |
|
66 |
|
67 |
function AuthPrompt2(flags) { |
67 |
function AuthPrompt2(flags, user, pass) { |
68 |
this.flags = flags; |
68 |
this.flags = flags; |
|
|
69 |
this.user = user || "guest"; |
70 |
this.pass = pass || "guest"; |
69 |
} |
71 |
} |
70 |
|
72 |
|
71 |
AuthPrompt2.prototype = { |
73 |
AuthPrompt2.prototype = { |
72 |
user: "guest", |
|
|
73 |
pass: "guest", |
74 |
|
74 |
|
75 |
expectedRealm: "secret", |
75 |
expectedRealm: "secret", |
76 |
|
76 |
|
77 |
QueryInterface: function authprompt2_qi(iid) { |
77 |
QueryInterface: function authprompt2_qi(iid) { |
78 |
if (iid.equals(Components.interfaces.nsISupports) || |
78 |
if (iid.equals(Components.interfaces.nsISupports) || |
79 |
iid.equals(Components.interfaces.nsIAuthPrompt2)) |
79 |
iid.equals(Components.interfaces.nsIAuthPrompt2)) |
80 |
return this; |
80 |
return this; |
81 |
throw Components.results.NS_ERROR_NO_INTERFACE; |
81 |
throw Components.results.NS_ERROR_NO_INTERFACE; |
Lines 126-170
AuthPrompt2.prototype = {
|
Link Here
|
---|
|
---|
126 |
return true; |
126 |
return true; |
127 |
}, |
127 |
}, |
128 |
|
128 |
|
129 |
asyncPromptAuth: function ap2_async(chan, cb, ctx, lvl, info) { |
129 |
asyncPromptAuth: function ap2_async(chan, cb, ctx, lvl, info) { |
130 |
throw 0x80004001; |
130 |
throw 0x80004001; |
131 |
} |
131 |
} |
132 |
}; |
132 |
}; |
133 |
|
133 |
|
134 |
function Requestor(flags, versions, username) { |
134 |
function Requestor(flags, versions, user, pass) { |
135 |
this.flags = flags; |
135 |
this.flags = flags; |
136 |
this.versions = versions; |
136 |
this.versions = versions; |
137 |
this.username = username; |
137 |
this.user = user; |
|
|
138 |
this.pass = pass; |
138 |
} |
139 |
} |
139 |
|
140 |
|
140 |
Requestor.prototype = { |
141 |
Requestor.prototype = { |
141 |
QueryInterface: function requestor_qi(iid) { |
142 |
QueryInterface: function requestor_qi(iid) { |
142 |
if (iid.equals(Components.interfaces.nsISupports) || |
143 |
if (iid.equals(Components.interfaces.nsISupports) || |
143 |
iid.equals(Components.interfaces.nsIInterfaceRequestor)) |
144 |
iid.equals(Components.interfaces.nsIInterfaceRequestor)) |
144 |
return this; |
145 |
return this; |
145 |
throw Components.results.NS_ERROR_NO_INTERFACE; |
146 |
throw Components.results.NS_ERROR_NO_INTERFACE; |
146 |
}, |
147 |
}, |
147 |
|
148 |
|
148 |
getInterface: function requestor_gi(iid) { |
149 |
getInterface: function requestor_gi(iid) { |
149 |
if (this.versions & 1 && |
150 |
if (this.versions & 1 && |
150 |
iid.equals(Components.interfaces.nsIAuthPrompt)) { |
151 |
iid.equals(Components.interfaces.nsIAuthPrompt)) { |
151 |
// Allow the prompt to store state by caching it here |
152 |
// Allow the prompt to store state by caching it here |
152 |
if (!this.prompt1) |
153 |
if (!this.prompt1) |
153 |
this.prompt1 = new AuthPrompt1(this.flags); |
154 |
this.prompt1 = new AuthPrompt1(this.flags, this.user, this.pass); |
154 |
return this.prompt1; |
155 |
return this.prompt1; |
155 |
} |
156 |
} |
156 |
if (this.versions & 2 && |
157 |
if (this.versions & 2 && |
157 |
iid.equals(Components.interfaces.nsIAuthPrompt2)) { |
158 |
iid.equals(Components.interfaces.nsIAuthPrompt2)) { |
158 |
// Allow the prompt to store state by caching it here |
159 |
// Allow the prompt to store state by caching it here |
159 |
if (!this.prompt2) |
160 |
if (!this.prompt2) |
160 |
this.prompt2 = new AuthPrompt2(this.flags); |
161 |
this.prompt2 = new AuthPrompt2(this.flags, this.user, this.pass); |
161 |
if (this.username) |
|
|
162 |
this.prompt2.user = this.username; |
163 |
return this.prompt2; |
162 |
return this.prompt2; |
164 |
} |
163 |
} |
165 |
|
164 |
|
166 |
throw Components.results.NS_ERROR_NO_INTERFACE; |
165 |
throw Components.results.NS_ERROR_NO_INTERFACE; |
167 |
}, |
166 |
}, |
168 |
|
167 |
|
169 |
prompt1: null, |
168 |
prompt1: null, |
170 |
prompt2: null |
169 |
prompt2: null |
Lines 252-277
function makeChan(url) {
|
Link Here
|
---|
|
---|
252 |
.QueryInterface(Components.interfaces.nsIHttpChannel); |
251 |
.QueryInterface(Components.interfaces.nsIHttpChannel); |
253 |
|
252 |
|
254 |
return chan; |
253 |
return chan; |
255 |
} |
254 |
} |
256 |
|
255 |
|
257 |
var tests = [test_noauth, test_returnfalse1, test_wrongpw1, test_prompt1, |
256 |
var tests = [test_noauth, test_returnfalse1, test_wrongpw1, test_prompt1, |
258 |
test_returnfalse2, test_wrongpw2, test_prompt2, test_ntlm, |
257 |
test_returnfalse2, test_wrongpw2, test_prompt2, test_ntlm, |
259 |
test_auth, test_digest_noauth, test_digest, |
258 |
test_auth, test_digest_noauth, test_digest, |
260 |
test_digest_bogus_user]; |
259 |
test_digest_bogus_user, test_basic_utf8]; |
261 |
|
260 |
|
262 |
var current_test = 0; |
261 |
var current_test = 0; |
263 |
|
262 |
|
264 |
var httpserv = null; |
263 |
var httpserv = null; |
265 |
|
264 |
|
266 |
function run_test() { |
265 |
function run_test() { |
267 |
httpserv = new nsHttpServer(); |
266 |
httpserv = new nsHttpServer(); |
268 |
|
267 |
|
269 |
httpserv.registerPathHandler("/auth", authHandler); |
268 |
httpserv.registerPathHandler("/auth", authHandler); |
|
|
269 |
httpserv.registerPathHandler("/auth/utf8", basicUTF8Handler); |
270 |
httpserv.registerPathHandler("/auth/ntlm/simple", authNtlmSimple); |
270 |
httpserv.registerPathHandler("/auth/ntlm/simple", authNtlmSimple); |
271 |
httpserv.registerPathHandler("/auth/realm", authRealm); |
271 |
httpserv.registerPathHandler("/auth/realm", authRealm); |
272 |
httpserv.registerPathHandler("/auth/digest", authDigest); |
272 |
httpserv.registerPathHandler("/auth/digest", authDigest); |
273 |
|
273 |
|
274 |
httpserv.start(4444); |
274 |
httpserv.start(4444); |
275 |
|
275 |
|
276 |
tests[0](); |
276 |
tests[0](); |
277 |
} |
277 |
} |
Lines 360-375
function test_auth() {
|
Link Here
|
---|
|
---|
360 |
|
360 |
|
361 |
chan.notificationCallbacks = new RealmTestRequestor(); |
361 |
chan.notificationCallbacks = new RealmTestRequestor(); |
362 |
listener.expectedCode = 401; // Unauthorized |
362 |
listener.expectedCode = 401; // Unauthorized |
363 |
chan.asyncOpen(listener, null); |
363 |
chan.asyncOpen(listener, null); |
364 |
|
364 |
|
365 |
do_test_pending(); |
365 |
do_test_pending(); |
366 |
} |
366 |
} |
367 |
|
367 |
|
|
|
368 |
function test_basic_utf8() { |
369 |
var chan = makeChan("http://localhost:4444/auth/utf8"); |
370 |
|
371 |
// big:airplane in Japanese, according to google translate |
372 |
chan.notificationCallbacks = new Requestor(0, 1, "\u5927\u304d\u3044", "\u98db\u884c\u6a5f"); |
373 |
listener.expectedCode = 200; // Unauthorized |
374 |
chan.asyncOpen(listener, null); |
375 |
|
376 |
do_test_pending(); |
377 |
} |
378 |
|
379 |
|
368 |
function test_digest_noauth() { |
380 |
function test_digest_noauth() { |
369 |
var chan = makeChan("http://localhost:4444/auth/digest"); |
381 |
var chan = makeChan("http://localhost:4444/auth/digest"); |
370 |
|
382 |
|
371 |
//chan.notificationCallbacks = new Requestor(FLAG_RETURN_FALSE, 2); |
383 |
//chan.notificationCallbacks = new Requestor(FLAG_RETURN_FALSE, 2); |
372 |
listener.expectedCode = 401; // Unauthorized |
384 |
listener.expectedCode = 401; // Unauthorized |
373 |
chan.asyncOpen(listener, null); |
385 |
chan.asyncOpen(listener, null); |
374 |
|
386 |
|
375 |
do_test_pending(); |
387 |
do_test_pending(); |
Lines 391-411
function test_digest_bogus_user() {
|
Link Here
|
---|
|
---|
391 |
listener.expectedCode = 401; // unauthorized |
403 |
listener.expectedCode = 401; // unauthorized |
392 |
chan.asyncOpen(listener, null); |
404 |
chan.asyncOpen(listener, null); |
393 |
|
405 |
|
394 |
do_test_pending(); |
406 |
do_test_pending(); |
395 |
} |
407 |
} |
396 |
|
408 |
|
397 |
// PATH HANDLERS |
409 |
// PATH HANDLERS |
398 |
|
410 |
|
399 |
// /auth |
411 |
function sendBasicResponse(metadata, response, expectedHeader) { |
400 |
function authHandler(metadata, response) { |
|
|
401 |
// btoa("guest:guest"), but that function is not available here |
402 |
var expectedHeader = "Basic Z3Vlc3Q6Z3Vlc3Q="; |
403 |
|
404 |
var body; |
412 |
var body; |
405 |
if (metadata.hasHeader("Authorization") && |
413 |
if (metadata.hasHeader("Authorization") && |
406 |
metadata.getHeader("Authorization") == expectedHeader) |
414 |
metadata.getHeader("Authorization") == expectedHeader) |
407 |
{ |
415 |
{ |
408 |
response.setStatusLine(metadata.httpVersion, 200, "OK, authorized"); |
416 |
response.setStatusLine(metadata.httpVersion, 200, "OK, authorized"); |
409 |
response.setHeader("WWW-Authenticate", 'Basic realm="secret"', false); |
417 |
response.setHeader("WWW-Authenticate", 'Basic realm="secret"', false); |
410 |
|
418 |
|
411 |
body = "success"; |
419 |
body = "success"; |
Lines 417-432
function authHandler(metadata, response)
|
Link Here
|
---|
|
---|
417 |
response.setHeader("WWW-Authenticate", 'Basic realm="secret"', false); |
425 |
response.setHeader("WWW-Authenticate", 'Basic realm="secret"', false); |
418 |
|
426 |
|
419 |
body = "failed"; |
427 |
body = "failed"; |
420 |
} |
428 |
} |
421 |
|
429 |
|
422 |
response.bodyOutputStream.write(body, body.length); |
430 |
response.bodyOutputStream.write(body, body.length); |
423 |
} |
431 |
} |
424 |
|
432 |
|
|
|
433 |
// /auth |
434 |
function authHandler(metadata, response) { |
435 |
// btoa("guest:guest"), but that function is not available here |
436 |
var expectedHeader = "Basic Z3Vlc3Q6Z3Vlc3Q="; |
437 |
sendBasicResponse(metadata, response, expectedHeader); |
438 |
} |
439 |
|
440 |
// /auth/utf8 |
441 |
function basicUTF8Handler(metadata, response) { |
442 |
// btoa("\u5927\u304d\u3044:\u98db\u884c\u6a5f"), but that function is not available here |
443 |
var expectedHeader = "Basic 5aSn44GN44GEOumjm+ihjOapnw=="; |
444 |
sendBasicResponse(metadata, response, expectedHeader); |
445 |
} |
446 |
|
425 |
// /auth/ntlm/simple |
447 |
// /auth/ntlm/simple |
426 |
function authNtlmSimple(metadata, response) { |
448 |
function authNtlmSimple(metadata, response) { |
427 |
response.setStatusLine(metadata.httpVersion, 401, "Unauthorized"); |
449 |
response.setStatusLine(metadata.httpVersion, 401, "Unauthorized"); |
428 |
response.setHeader("WWW-Authenticate", "NTLM" /* + ' realm="secret"' */, false); |
450 |
response.setHeader("WWW-Authenticate", "NTLM" /* + ' realm="secret"' */, false); |
429 |
|
451 |
|
430 |
var body = "NOTE: This just sends an NTLM challenge, it never\n" + |
452 |
var body = "NOTE: This just sends an NTLM challenge, it never\n" + |
431 |
"accepts the authentication. It also closes\n" + |
453 |
"accepts the authentication. It also closes\n" + |
432 |
"the connection after sending the challenge\n"; |
454 |
"the connection after sending the challenge\n"; |