selenium-webdriver 0.0.14 → 0.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
};
|