selenium-webdriver 0.0.14 → 0.0.15
Sign up to get free protection for your applications and to get access to all the features.
- data/chrome/src/rb/lib/selenium/webdriver/chrome/bridge.rb +12 -0
- data/chrome/src/rb/lib/selenium/webdriver/chrome/command_executor.rb +5 -1
- data/common/src/js/core/scripts/htmlutils.js +404 -76
- data/common/src/js/core/scripts/rpc-optimizing-user-extension.js +5206 -0
- data/common/src/js/core/scripts/selenium-api.js +10 -15
- data/common/src/js/core/scripts/selenium-browserbot.js +26 -21
- data/common/src/rb/lib/selenium/webdriver/child_process.rb +62 -8
- data/common/src/rb/lib/selenium/webdriver/find.rb +12 -11
- data/common/src/rb/lib/selenium/webdriver/platform.rb +34 -36
- data/common/src/rb/lib/selenium/webdriver/target_locator.rb +8 -0
- data/firefox/prebuilt/linux/Release/libwebdriver-firefox.so +0 -0
- data/firefox/src/extension/components/badCertListener.js +121 -19
- data/firefox/src/extension/components/screenshooter.js +1 -1
- data/firefox/src/extension/components/utils.js +19 -10
- data/firefox/src/extension/components/wrappedElement.js +8 -8
- data/firefox/src/rb/lib/selenium/webdriver/firefox.rb +8 -1
- data/firefox/src/rb/lib/selenium/webdriver/firefox/binary.rb +1 -1
- data/firefox/src/rb/lib/selenium/webdriver/firefox/bridge.rb +12 -0
- data/firefox/src/rb/lib/selenium/webdriver/firefox/extension_connection.rb +1 -1
- data/firefox/src/rb/lib/selenium/webdriver/firefox/launcher.rb +4 -0
- data/firefox/src/rb/lib/selenium/webdriver/firefox/profile.rb +18 -9
- data/jobbie/prebuilt/Win32/Release/InternetExplorerDriver.dll +0 -0
- data/jobbie/prebuilt/x64/Release/InternetExplorerDriver.dll +0 -0
- data/jobbie/src/rb/lib/selenium/webdriver/ie/bridge.rb +4 -0
- data/jobbie/src/rb/lib/selenium/webdriver/ie/util.rb +3 -2
- data/remote/client/src/rb/lib/selenium/webdriver/remote/bridge.rb +4 -0
- data/remote/client/src/rb/lib/selenium/webdriver/remote/default_http_client.rb +1 -1
- metadata +3 -2
@@ -2364,7 +2364,7 @@ Selenium.prototype.doAllowNativeXpath = function(allow) {
|
|
2364
2364
|
if ("false" == allow || "0" == allow) { // The strings "false" and "0" are true values in JS
|
2365
2365
|
allow = false;
|
2366
2366
|
}
|
2367
|
-
this.browserbot.
|
2367
|
+
this.browserbot.setAllowNativeXPath(allow);
|
2368
2368
|
}
|
2369
2369
|
|
2370
2370
|
Selenium.prototype.doIgnoreAttributesWithoutValue = function(ignore) {
|
@@ -2386,7 +2386,7 @@ Selenium.prototype.doIgnoreAttributesWithoutValue = function(ignore) {
|
|
2386
2386
|
if ('false' == ignore || '0' == ignore) {
|
2387
2387
|
ignore = false;
|
2388
2388
|
}
|
2389
|
-
this.browserbot.
|
2389
|
+
this.browserbot.setIgnoreAttributesWithoutValue(ignore);
|
2390
2390
|
}
|
2391
2391
|
|
2392
2392
|
Selenium.prototype.doWaitForCondition = function(script, timeout) {
|
@@ -3132,7 +3132,7 @@ Selenium.prototype.doRemoveScript = function(scriptTagId) {
|
|
3132
3132
|
|
3133
3133
|
Selenium.prototype.doUseXpathLibrary = function(libraryName) {
|
3134
3134
|
/**
|
3135
|
-
|
3135
|
+
* Allows choice of one of the available libraries.
|
3136
3136
|
* @param libraryName name of the desired library
|
3137
3137
|
* Only the following three can be chosen:
|
3138
3138
|
* <ul>
|
@@ -3140,22 +3140,17 @@ Selenium.prototype.doUseXpathLibrary = function(libraryName) {
|
|
3140
3140
|
* <li>"javascript-xpath" - Cybozu Labs' faster library</li>
|
3141
3141
|
* <li>"default" - The default library. Currently the default library is "ajaxslt" .</li>
|
3142
3142
|
* </ul>
|
3143
|
-
* If libraryName isn't one of these three,
|
3144
|
-
*
|
3145
|
-
*
|
3143
|
+
* If libraryName isn't one of these three, it may be the name of another
|
3144
|
+
* engine registered to the browserbot's XPathEvaluator, for example by
|
3145
|
+
* overriding XPathEvaluator.prototype.init() . If it is not a registered
|
3146
|
+
* engine either, then no change will be made.
|
3146
3147
|
*/
|
3147
3148
|
|
3148
|
-
if (libraryName
|
3149
|
-
this.browserbot.xpathLibrary = this.browserbot.defaultXpathLibrary;
|
3149
|
+
if (! this.browserbot.getXPathEngine(libraryName)) {
|
3150
3150
|
return;
|
3151
3151
|
}
|
3152
|
-
|
3153
|
-
|
3154
|
-
return;
|
3155
|
-
}
|
3156
|
-
|
3157
|
-
this.browserbot.xpathLibrary = libraryName;
|
3158
|
-
|
3152
|
+
|
3153
|
+
this.browserbot.setXPathEngine(libraryName);
|
3159
3154
|
};
|
3160
3155
|
|
3161
3156
|
/**
|
@@ -37,8 +37,8 @@ var BrowserBot = function(topLevelApplicationWindow) {
|
|
37
37
|
this.currentWindow = this.topWindow;
|
38
38
|
this.currentWindowName = null;
|
39
39
|
this.allowNativeXpath = true;
|
40
|
-
this.
|
41
|
-
|
40
|
+
this.xpathEvaluator = new XPathEvaluator('ajaxslt'); // change to "javascript-xpath" for the newer, faster engine
|
41
|
+
|
42
42
|
// We need to know this in advance, in case the frame closes unexpectedly
|
43
43
|
this.isSubFrameSelected = false;
|
44
44
|
|
@@ -126,7 +126,22 @@ var BrowserBot = function(topLevelApplicationWindow) {
|
|
126
126
|
return self.newPageLoaded && (self.isXhrSent ? (self.abortXhr || self.isXhrDone) : true);
|
127
127
|
}
|
128
128
|
};
|
129
|
-
|
129
|
+
|
130
|
+
this.setAllowNativeXPath = function(allow) {
|
131
|
+
this.xpathEvaluator.setAllowNativeXPath(allow);
|
132
|
+
};
|
133
|
+
|
134
|
+
this.setIgnoreAttributesWithoutValue = function(ignore) {
|
135
|
+
this.xpathEvaluator.setIgnoreAttributesWithoutValue(ignore);
|
136
|
+
};
|
137
|
+
|
138
|
+
this.setXPathEngine = function(engineName) {
|
139
|
+
this.xpathEvaluator.setCurrentEngine(engineName);
|
140
|
+
};
|
141
|
+
|
142
|
+
this.getXPathEngine = function() {
|
143
|
+
return this.xpathEvaluator.getCurrentEngine();
|
144
|
+
};
|
130
145
|
};
|
131
146
|
|
132
147
|
// DGF PageBot exists for backwards compatibility with old user-extensions
|
@@ -1404,7 +1419,9 @@ BrowserBot.prototype.findElement = function(locator, win) {
|
|
1404
1419
|
* we search separately by id and name.
|
1405
1420
|
*/
|
1406
1421
|
BrowserBot.prototype.locateElementByIdentifier = function(identifier, inDocument, inWindow) {
|
1407
|
-
|
1422
|
+
// HBC - use "this" instead of "BrowserBot.prototype"; otherwise we lose
|
1423
|
+
// the non-prototype fields of the object!
|
1424
|
+
return this.locateElementById(identifier, inDocument, inWindow)
|
1408
1425
|
|| BrowserBot.prototype.locateElementByName(identifier, inDocument, inWindow)
|
1409
1426
|
|| null;
|
1410
1427
|
};
|
@@ -1420,8 +1437,7 @@ BrowserBot.prototype.locateElementById = function(identifier, inDocument, inWind
|
|
1420
1437
|
else if (browserVersion.isIE || browserVersion.isOpera) {
|
1421
1438
|
// SEL-484
|
1422
1439
|
var xpath = '/descendant::*[@id=' + identifier.quoteForXPath() + ']';
|
1423
|
-
return
|
1424
|
-
.locateElementByXPath(xpath, inDocument, inWindow);
|
1440
|
+
return this.locateElementByXPath(xpath, inDocument, inWindow);
|
1425
1441
|
}
|
1426
1442
|
else {
|
1427
1443
|
return null;
|
@@ -1475,14 +1491,8 @@ BrowserBot.prototype.locateElementByDomTraversal.prefix = "dom";
|
|
1475
1491
|
* begin with "//".
|
1476
1492
|
*/
|
1477
1493
|
BrowserBot.prototype.locateElementByXPath = function(xpath, inDocument, inWindow) {
|
1478
|
-
|
1479
|
-
|
1480
|
-
ignoreAttributesWithoutValue: this.ignoreAttributesWithoutValue,
|
1481
|
-
allowNativeXpath : this.allowNativeXpath,
|
1482
|
-
xpathLibrary : this.xpathLibrary,
|
1483
|
-
namespaceResolver : this._namespaceResolver
|
1484
|
-
});
|
1485
|
-
return (results.length > 0) ? results[0] : null;
|
1494
|
+
return this.xpathEvaluator.selectSingleNode(inDocument, xpath, null,
|
1495
|
+
this._namespaceResolver);
|
1486
1496
|
};
|
1487
1497
|
|
1488
1498
|
BrowserBot.prototype._namespaceResolver = function(prefix) {
|
@@ -1499,13 +1509,8 @@ BrowserBot.prototype._namespaceResolver = function(prefix) {
|
|
1499
1509
|
* Returns the number of xpath results.
|
1500
1510
|
*/
|
1501
1511
|
BrowserBot.prototype.evaluateXPathCount = function(xpath, inDocument) {
|
1502
|
-
|
1503
|
-
|
1504
|
-
allowNativeXpath : this.allowNativeXpath,
|
1505
|
-
xpathLibrary : this.xpathLibrary,
|
1506
|
-
namespaceResolver : this._namespaceResolver
|
1507
|
-
});
|
1508
|
-
return results.length;
|
1512
|
+
return this.xpathEvaluator.countNodes(inDocument, xpath, null,
|
1513
|
+
this._namespaceResolver);
|
1509
1514
|
};
|
1510
1515
|
|
1511
1516
|
/**
|
@@ -13,6 +13,8 @@ module Selenium
|
|
13
13
|
|
14
14
|
if Platform.jruby?
|
15
15
|
extend JRubyProcess
|
16
|
+
elsif Platform.ironruby?
|
17
|
+
extend IronRubyProcess
|
16
18
|
elsif Platform.os == :windows
|
17
19
|
extend WindowsProcess
|
18
20
|
end
|
@@ -42,28 +44,32 @@ module Selenium
|
|
42
44
|
end
|
43
45
|
|
44
46
|
def wait
|
45
|
-
|
47
|
+
assert_started
|
46
48
|
Process.waitpid2 @pid
|
47
49
|
rescue Errno::ECHILD
|
48
50
|
nil
|
49
51
|
end
|
50
52
|
|
51
53
|
def kill
|
52
|
-
|
54
|
+
assert_started
|
55
|
+
Process.kill('TERM', @pid)
|
53
56
|
end
|
54
57
|
|
55
58
|
def kill!
|
56
|
-
|
59
|
+
assert_started
|
60
|
+
Process.kill('KILL', @pid)
|
61
|
+
end
|
62
|
+
|
63
|
+
def assert_started
|
64
|
+
raise Error::WebDriverError, "process not started" unless @pid
|
57
65
|
end
|
58
66
|
|
59
67
|
module WindowsProcess
|
60
68
|
def start
|
61
|
-
require "win32/process" # adds a dependency on windows
|
69
|
+
require "win32/process" # adds a dependency on windows - perhaps we could just use FFI instead?
|
62
70
|
@pid = Process.create(
|
63
71
|
:app_name => @args.join(" "),
|
64
|
-
:
|
65
|
-
:thread_inherit => true,
|
66
|
-
:inherit => true
|
72
|
+
:inherit => false # don't inherit open file handles
|
67
73
|
).process_id
|
68
74
|
|
69
75
|
self
|
@@ -88,20 +94,68 @@ module Selenium
|
|
88
94
|
end
|
89
95
|
|
90
96
|
def kill
|
91
|
-
|
97
|
+
assert_started
|
98
|
+
@process.destroy
|
92
99
|
end
|
93
100
|
alias_method :kill!, :kill
|
94
101
|
|
95
102
|
def wait
|
103
|
+
assert_started
|
96
104
|
@process.waitFor
|
97
105
|
[nil, @process.exitValue] # no robust way to get pid here
|
98
106
|
end
|
99
107
|
|
100
108
|
def exit_value
|
109
|
+
assert_started
|
101
110
|
@process.exitValue
|
102
111
|
rescue java.lang.IllegalThreadStateException
|
103
112
|
nil
|
104
113
|
end
|
114
|
+
|
115
|
+
def assert_started
|
116
|
+
raise Error::WebDriverError, "process not started" unless @process
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
module IronRubyProcess
|
121
|
+
def start
|
122
|
+
args = @args.dup
|
123
|
+
|
124
|
+
@process = System::Diagnostics::Process.new
|
125
|
+
@process.StartInfo.UseShellExecute = true
|
126
|
+
@process.StartInfo.FileName = args.shift
|
127
|
+
@process.StartInfo.Arguments = args.join ' '
|
128
|
+
@process.start
|
129
|
+
|
130
|
+
self
|
131
|
+
end
|
132
|
+
|
133
|
+
def kill
|
134
|
+
assert_started
|
135
|
+
@process.Kill
|
136
|
+
end
|
137
|
+
|
138
|
+
def wait
|
139
|
+
assert_started
|
140
|
+
@process.WaitForExit
|
141
|
+
[pid, exit_value]
|
142
|
+
end
|
143
|
+
|
144
|
+
def pid
|
145
|
+
assert_started
|
146
|
+
@process.Id
|
147
|
+
end
|
148
|
+
|
149
|
+
def exit_value
|
150
|
+
assert_started
|
151
|
+
return unless @process.HasExited
|
152
|
+
|
153
|
+
@process.ExitCode
|
154
|
+
end
|
155
|
+
|
156
|
+
def assert_started
|
157
|
+
raise Error::WebDriverError, "process not started" unless @process
|
158
|
+
end
|
105
159
|
end
|
106
160
|
|
107
161
|
end # ChildProcess
|
@@ -3,15 +3,16 @@ module Selenium
|
|
3
3
|
module Find
|
4
4
|
|
5
5
|
FINDERS = {
|
6
|
-
:class => '
|
7
|
-
:class_name => '
|
8
|
-
:
|
9
|
-
:
|
10
|
-
:link => '
|
11
|
-
:
|
12
|
-
:name => '
|
13
|
-
:
|
14
|
-
:
|
6
|
+
:class => 'ClassName',
|
7
|
+
:class_name => 'ClassName',
|
8
|
+
:css => 'CssSelector',
|
9
|
+
:id => 'Id',
|
10
|
+
:link => 'LinkText',
|
11
|
+
:link_text => 'LinkText',
|
12
|
+
:name => 'Name',
|
13
|
+
:partial_link_text => 'PartialLinkText',
|
14
|
+
:tag_name => 'TagName',
|
15
|
+
:xpath => 'Xpath',
|
15
16
|
}
|
16
17
|
|
17
18
|
#
|
@@ -31,7 +32,7 @@ module Selenium
|
|
31
32
|
raise ArgumentError, "cannot find element by #{how.inspect}"
|
32
33
|
end
|
33
34
|
|
34
|
-
meth = "
|
35
|
+
meth = "findElementBy#{by}"
|
35
36
|
what = what.to_s
|
36
37
|
|
37
38
|
bridge.send meth, ref, what
|
@@ -52,7 +53,7 @@ module Selenium
|
|
52
53
|
raise ArgumentError, "cannot find elements by #{how.inspect}"
|
53
54
|
end
|
54
55
|
|
55
|
-
meth = "
|
56
|
+
meth = "findElementsBy#{by}"
|
56
57
|
what = what.to_s
|
57
58
|
|
58
59
|
bridge.send meth, ref, what
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require "rbconfig"
|
2
|
+
|
1
3
|
module Selenium
|
2
4
|
module WebDriver
|
3
5
|
module Platform
|
@@ -10,43 +12,39 @@ module Selenium
|
|
10
12
|
end
|
11
13
|
|
12
14
|
def platform
|
13
|
-
@platform ||=
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
when /linux/
|
21
|
-
:linux
|
22
|
-
when /solaris|bsd/
|
23
|
-
:unix
|
24
|
-
else
|
25
|
-
RUBY_PLATFORM
|
26
|
-
end
|
15
|
+
@platform ||= begin
|
16
|
+
if defined? RUBY_ENGINE
|
17
|
+
RUBY_ENGINE.to_sym
|
18
|
+
else
|
19
|
+
:ruby
|
20
|
+
end
|
21
|
+
end
|
27
22
|
end
|
28
23
|
|
29
24
|
def os
|
30
25
|
@os ||= begin
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
os
|
26
|
+
case Config::CONFIG['host_os']
|
27
|
+
when /mswin|msys|mingw32/
|
28
|
+
:windows
|
29
|
+
when /darwin|mac os/
|
30
|
+
:macosx
|
31
|
+
when /linux/
|
32
|
+
:linux
|
33
|
+
when /solaris|bsd/
|
34
|
+
:unix
|
35
|
+
else
|
36
|
+
# unlikely
|
37
|
+
raise Error::WebDriverError, "unknown os #{Config::CONFIG['host_os']}"
|
38
|
+
end
|
45
39
|
end
|
46
40
|
end
|
47
41
|
|
48
42
|
def jruby?
|
49
|
-
platform == :
|
43
|
+
platform == :jruby
|
44
|
+
end
|
45
|
+
|
46
|
+
def ironruby?
|
47
|
+
platform == :ironruby
|
50
48
|
end
|
51
49
|
|
52
50
|
def ruby187?
|
@@ -78,11 +76,11 @@ module Selenium
|
|
78
76
|
end # Selenium
|
79
77
|
|
80
78
|
if __FILE__ == $0
|
81
|
-
p :platform => WebDriver::Platform.platform,
|
82
|
-
:os => WebDriver::Platform.os,
|
83
|
-
:ruby187? => WebDriver::Platform.ruby187?,
|
84
|
-
:ruby19? => WebDriver::Platform.ruby19?,
|
85
|
-
:jruby? => WebDriver::Platform.jruby?,
|
86
|
-
:win? => WebDriver::Platform.win?,
|
87
|
-
:home => WebDriver::Platform.home
|
79
|
+
p :platform => Selenium::WebDriver::Platform.platform,
|
80
|
+
:os => Selenium::WebDriver::Platform.os,
|
81
|
+
:ruby187? => Selenium::WebDriver::Platform.ruby187?,
|
82
|
+
:ruby19? => Selenium::WebDriver::Platform.ruby19?,
|
83
|
+
:jruby? => Selenium::WebDriver::Platform.jruby?,
|
84
|
+
:win? => Selenium::WebDriver::Platform.win?,
|
85
|
+
:home => Selenium::WebDriver::Platform.home
|
88
86
|
end
|
@@ -49,6 +49,14 @@ module Selenium
|
|
49
49
|
@bridge.switchToActiveElement
|
50
50
|
end
|
51
51
|
|
52
|
+
#
|
53
|
+
# selects either the first frame on the page, or the main document when a page contains iframes.
|
54
|
+
#
|
55
|
+
|
56
|
+
def default_content
|
57
|
+
@bridge.switchToDefaultContent
|
58
|
+
end
|
59
|
+
|
52
60
|
end # TargetLocator
|
53
61
|
end # WebDriver
|
54
62
|
end # Selenium
|
Binary file
|
@@ -37,24 +37,52 @@ function localdump(message) {
|
|
37
37
|
}
|
38
38
|
}
|
39
39
|
|
40
|
-
function
|
40
|
+
function getPreferenceFromProfile(prefName, prefDefaultValue) {
|
41
41
|
var prefs =
|
42
42
|
CC["@mozilla.org/preferences-service;1"].getService(CI["nsIPrefBranch"]);
|
43
43
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
44
|
+
if (!prefs.prefHasUserValue(prefName)) {
|
45
|
+
localdump(prefName + ' not set; defaulting to ' + prefDefaultValue);
|
46
|
+
return prefDefaultValue;
|
47
|
+
}
|
48
|
+
|
49
|
+
var prefValue = prefs.getBoolPref(prefName);
|
50
|
+
localdump("Found preference for " + prefName + ": " + prefValue);
|
51
|
+
|
52
|
+
return prefValue;
|
53
|
+
}
|
54
|
+
|
55
|
+
function shouldAcceptUntrustedCerts() {
|
56
|
+
return getPreferenceFromProfile("webdriver_accept_untrusted_certs", true);
|
57
|
+
}
|
58
|
+
|
59
|
+
function shouldAssumeUntrustedIssuer() {
|
60
|
+
return getPreferenceFromProfile("webdriver_assume_untrusted_issuer", true);
|
61
|
+
}
|
62
|
+
|
63
|
+
function WdCertOverrideService() {
|
64
|
+
// Defaults to true - accepting untrusted certificates.
|
65
|
+
// This puts the module into effect - setting it to false
|
66
|
+
// will delegate all calls to the original service.
|
67
|
+
this.acceptAll = shouldAcceptUntrustedCerts();
|
68
|
+
|
69
|
+
// If untrusted issuer is set to false by the user,
|
70
|
+
// the initial bitmask will not include ERROR_UNTRUSTED.
|
71
|
+
//
|
72
|
+
// See the javadoc for FirefoxProfile and documentation
|
73
|
+
// for fillNeededBits for further explanation.
|
74
|
+
var untrusted_issuer = shouldAssumeUntrustedIssuer();
|
75
|
+
if (untrusted_issuer) {
|
76
|
+
this.default_bits = this.ERROR_UNTRUSTED;
|
48
77
|
} else {
|
49
|
-
|
50
|
-
prefs.getBoolPref("webdriver_accept_untrusted_certs"));
|
51
|
-
this.acceptAll = prefs.getBoolPref("webdriver_accept_untrusted_certs");
|
78
|
+
this.default_bits = 0;
|
52
79
|
}
|
53
|
-
// UUID of the original implementor of this service.
|
54
|
-
var ORIGINAL_OVERRIDE_SERVICE_ID = "{67ba681d-5485-4fff-952c-2ee337ffdcd6}";
|
55
80
|
|
56
81
|
localdump("Accept untrusted certificates: " + this.acceptAll);
|
57
82
|
|
83
|
+
// UUID of the original implementor of this service.
|
84
|
+
var ORIGINAL_OVERRIDE_SERVICE_ID = "{67ba681d-5485-4fff-952c-2ee337ffdcd6}";
|
85
|
+
|
58
86
|
// Keep a reference to the original bad certificate listener.
|
59
87
|
var originalService = Components.classesByID[ORIGINAL_OVERRIDE_SERVICE_ID].
|
60
88
|
getService();
|
@@ -64,12 +92,76 @@ function WdCertOverrideService() {
|
|
64
92
|
Components.interfaces.nsICertOverrideService);
|
65
93
|
};
|
66
94
|
|
95
|
+
// Constants needed since WdCertOverrideService implements
|
96
|
+
// nsICertOverrideService
|
67
97
|
WdCertOverrideService.prototype = {
|
68
98
|
ERROR_UNTRUSTED: 1,
|
69
99
|
ERROR_MISMATCH: 2,
|
70
100
|
ERROR_TIME: 4
|
71
101
|
};
|
72
102
|
|
103
|
+
// Returns the bit needed to mask if the certificate has expired, 0 otherwise.
|
104
|
+
WdCertOverrideService.prototype.certificateExpiredBit_ = function
|
105
|
+
(theCert, verification_result) {
|
106
|
+
if ((verification_result & theCert.CERT_EXPIRED) != 0) {
|
107
|
+
localdump("Certificate expired.");
|
108
|
+
return this.ERROR_TIME;
|
109
|
+
}
|
110
|
+
|
111
|
+
return 0;
|
112
|
+
}
|
113
|
+
|
114
|
+
// Returns the bit needed to mask untrusted issuers, 0 otherwise.
|
115
|
+
// Note that this bit is already set by default in default_bits
|
116
|
+
WdCertOverrideService.prototype.certificateIssuerUntrusted_ = function
|
117
|
+
(theCert, verification_result) {
|
118
|
+
if (((verification_result & theCert.ISSUER_UNKNOWN) != 0) ||
|
119
|
+
((verification_result & theCert.ISSUER_NOT_TRUSTED) != 0) ||
|
120
|
+
((verification_result & theCert.CERT_NOT_TRUSTED) != 0) ||
|
121
|
+
((verification_result & theCert.INVALID_CA) != 0)) {
|
122
|
+
localdump("Certificate issuer unknown.");
|
123
|
+
return this.ERROR_UNTRUSTED;
|
124
|
+
}
|
125
|
+
|
126
|
+
return 0;
|
127
|
+
}
|
128
|
+
|
129
|
+
// Returns the bit needed to mask mismatch between actual hostname
|
130
|
+
// and the hostname the certificate was issued for, 0 otherwise.
|
131
|
+
WdCertOverrideService.prototype.certificateHostnameMismatch_ = function
|
132
|
+
(theCert, aHost) {
|
133
|
+
if (theCert.commonName !== aHost) {
|
134
|
+
localdump("Host name mismatch: cert: " + theCert.commonName + " get: " + aHost);
|
135
|
+
return this.ERROR_MISMATCH;
|
136
|
+
}
|
137
|
+
|
138
|
+
return 0;
|
139
|
+
}
|
140
|
+
|
141
|
+
// Given a certificate and the host it was received for, fill in the bits
|
142
|
+
// needed to accept this certificate for this host, even though the
|
143
|
+
// certificate is invalid.
|
144
|
+
//
|
145
|
+
// Note that the bitmask has to be accurate: At the moment, Firefox expects
|
146
|
+
// the returned bitmask to match *exactly* to the errors the certificate
|
147
|
+
// caused. If extra bits will be set, the untrusted certificate screen
|
148
|
+
// will appear.
|
149
|
+
WdCertOverrideService.prototype.fillNeededBits = function(aCert, aHost) {
|
150
|
+
var verification_bits = aCert.verifyForUsage(aCert.CERT_USAGE_SSLClient);
|
151
|
+
var return_bits = this.default_bits;
|
152
|
+
|
153
|
+
localdump("Certificate verification results: " + verification_bits);
|
154
|
+
|
155
|
+
return_bits = return_bits | this.certificateExpiredBit_(
|
156
|
+
aCert, verification_bits);
|
157
|
+
return_bits = return_bits | this.certificateIssuerUntrusted_(
|
158
|
+
aCert, verification_bits);
|
159
|
+
return_bits = return_bits | this.certificateHostnameMismatch_(aCert, aHost);
|
160
|
+
localdump("return_bits now: " + return_bits);
|
161
|
+
return return_bits;
|
162
|
+
};
|
163
|
+
|
164
|
+
// Interface functions from now on.
|
73
165
|
WdCertOverrideService.prototype.hasMatchingOverride = function(
|
74
166
|
aHostName, aPort, aCert, aOverrideBits, aIsTemporary) {
|
75
167
|
var retval = false;
|
@@ -78,9 +170,9 @@ WdCertOverrideService.prototype.hasMatchingOverride = function(
|
|
78
170
|
localdump("Allowing certificate from site: " + aHostName + ":" + aPort);
|
79
171
|
retval = true;
|
80
172
|
aIsTemporary.value = false;
|
81
|
-
|
82
|
-
|
83
|
-
localdump("Bits: " + aOverrideBits.value);
|
173
|
+
|
174
|
+
aOverrideBits.value = this.fillNeededBits(aCert, aHostName);
|
175
|
+
localdump("Override Bits: " + aOverrideBits.value);
|
84
176
|
} else {
|
85
177
|
retval = this.origListener_.hasMatchingOverride(aHostName, aPort,
|
86
178
|
aCert, aOverrideBits, aIsTemporary);
|
@@ -119,15 +211,25 @@ WdCertOverrideService.prototype.rememberValidityOverride = function(
|
|
119
211
|
aHostName, aPort, aCert, aOverrideBits, aTemporary);
|
120
212
|
};
|
121
213
|
|
214
|
+
WdCertOverrideService.prototype.QueryInterface = function(aIID) {
|
215
|
+
if (aIID.equals(Components.interfaces.nsICertOverrideService) ||
|
216
|
+
aIID.equals(Components.interfaces.nsIInterfaceRequestor) ||
|
217
|
+
aIID.equals(Components.interfaces.nsISupports)) {
|
218
|
+
return this;
|
219
|
+
}
|
220
|
+
|
221
|
+
throw Components.results.NS_ERROR_NO_INTERFACE;
|
222
|
+
}
|
223
|
+
|
122
224
|
// Service contract ID which we override
|
123
225
|
const CERTOVERRIDE_CONTRACT_ID = "@mozilla.org/security/certoverride;1";
|
124
226
|
// UUID for this instance specifically.
|
125
|
-
const
|
227
|
+
const DUMMY_CERTOVERRIDE_SERVICE_CLASS_ID =
|
126
228
|
Components.ID('{c8fffaba-9b7a-41aa-872d-7e7366c16715}');
|
127
229
|
|
128
230
|
var service = undefined;
|
129
231
|
|
130
|
-
var
|
232
|
+
var WDCertOverrideFactory = {
|
131
233
|
createInstance: function (aOuter, aIID) {
|
132
234
|
if (aOuter != null)
|
133
235
|
throw Components.results.NS_ERROR_NO_AGGREGATION;
|
@@ -154,7 +256,7 @@ WDBadCertListenerModule.prototype.registerSelf = function(
|
|
154
256
|
aCompMgr = aCompMgr.QueryInterface(
|
155
257
|
Components.interfaces.nsIComponentRegistrar);
|
156
258
|
aCompMgr.registerFactoryLocation(
|
157
|
-
|
259
|
+
DUMMY_CERTOVERRIDE_SERVICE_CLASS_ID, "WebDriver Override Cert Service",
|
158
260
|
CERTOVERRIDE_CONTRACT_ID, aFileSpec, aLocation, aType);
|
159
261
|
};
|
160
262
|
|
@@ -163,7 +265,7 @@ WDBadCertListenerModule.prototype.unregisterSelf = function(
|
|
163
265
|
localdump("Un-registering Override Certificate service.");
|
164
266
|
aCompMgr =
|
165
267
|
aCompMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
|
166
|
-
aCompMgr.unregisterFactoryLocation(
|
268
|
+
aCompMgr.unregisterFactoryLocation(DUMMY_CERTOVERRIDE_SERVICE_CLASS_ID, aLocation);
|
167
269
|
};
|
168
270
|
|
169
271
|
WDBadCertListenerModule.prototype.getClassObject = function(
|
@@ -171,8 +273,8 @@ WDBadCertListenerModule.prototype.getClassObject = function(
|
|
171
273
|
if (!aIID.equals(Components.interfaces.nsIFactory))
|
172
274
|
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
|
173
275
|
|
174
|
-
if (aCID.equals(
|
175
|
-
return
|
276
|
+
if (aCID.equals(DUMMY_CERTOVERRIDE_SERVICE_CLASS_ID))
|
277
|
+
return WDCertOverrideFactory;
|
176
278
|
|
177
279
|
throw Components.results.NS_ERROR_NO_INTERFACE;
|
178
280
|
};
|