selenium_tor 2.4.1 → 2.5.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6364e433d9dc6dae22726d13c881c445eecfe34d7ce3deaf6b7a6f018e2e12a5
4
- data.tar.gz: 6cf4824e8b4b0bb836cfa4ee44be05da6efba6dbe880b91de71e93971234415a
3
+ metadata.gz: 16076de37e6507820ad98d174e84997b480006e73e2d397b12d1106c65041fa4
4
+ data.tar.gz: dd48992b164cd81d1bacac5dec6050705781af03ae756ff33d9d9b0481f58e21
5
5
  SHA512:
6
- metadata.gz: f49bbbcc7edbc15b544d06f1d6d1aadc3dc0a37f2e7210fe6b55a567b8dbc177db450fb6047d62a57560e024750b81907ac4581a35264688a81e60d195b82ae8
7
- data.tar.gz: e0e76fc9a1b113221cc735f2b0b785e9d6a062d42bc7938d1303d0161c5950a5efe253cf27f3c94004a71301d152e2cfd80c21117322d162cada0e6fbdedd3a9
6
+ metadata.gz: 69c0d3811af3092236b2c9cfc4090258143ac0688f79a175684809ebc96f5d89759612625bd3d4e9361ec8ebec56daa3d924ab2525316d934544d45af8c94b94
7
+ data.tar.gz: a717b10e0f9595af81ec4233e86a7cbe47e5205eb681c244b56c0aed55c2642ae7cf33da2a825e1a74d1337b95c9136562aad06dfc0a396a712de3b0618611b9
data/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  ## master (unreleased)
2
2
 
3
+ ## [2.5.0] - 2026-05-15
4
+
5
+ * added ControlPort ("auto") & ControlPortWriteToFile to `Tor::Torrc` fixed config
6
+ * added methods `Tor::TorProcess#control_port` and `Tor::TorProcess#socks_port`
7
+ * start tor process before instantiating driver
8
+
9
+ ### Bug fixes
10
+
11
+ * set `extensions.torlauncher.control_port` pref before driver starts and quit driver *before* ending tor process [#23](https://gitlab.com/matzfan/selenium-tor/-/issues/23)
12
+
13
+ ### Breaking changes
14
+
15
+ * `FirefoxJsHelper#es6_const_call` and `FirefoxJsHelper#es6_function_call` es6: kwarg is replaced by es6_uri:
16
+ es6: required just the module name, es6_uri: requires the full module uri - e.g. "moz-src:///toolkit/modules/TorConnect.sys.mjs"
17
+ Upstream issue & full list of new URI's in 16.0a6 is here: https://gitlab.torproject.org/tpo/applications/tor-browser/-/work_items/43824#note_3389196
18
+
3
19
  ## [2.4.1] - 2026-03-12
4
20
 
5
21
  * add Tor::TBB_TOR_GEOIP_DIR const for changed tor geoip files location in 16.0a4 (see tor-browser-build bug 40892)
@@ -12,18 +12,18 @@ module Selenium
12
12
  in_chrome_context { execute_script(...) }
13
13
  end
14
14
 
15
- def es6_const_call(es6:, const:)
16
- es6_import(es6) << "return m.#{const}"
15
+ def es6_const_call(es6_uri:, const:)
16
+ es6_import(es6_uri) << "return m.#{const}"
17
17
  end
18
18
 
19
- def es6_function_call(es6:, func:, args:)
20
- es6_import(es6) << "return m.#{es6}.#{func}('#{args}')"
19
+ def es6_function_call(es6_uri:, func:, args:)
20
+ es6_import(es6_uri) << "return m.#{es6_uri.split('/').last}.#{func}('#{args}')"
21
21
  end
22
22
 
23
23
  private
24
24
 
25
- def es6_import(es6)
26
- "let m = ChromeUtils.importESModule('resource://gre/modules/#{es6}.sys.mjs');"
25
+ def es6_import(es6_uri)
26
+ "let m = ChromeUtils.importESModule('#{es6_uri}.sys.mjs');"
27
27
  end
28
28
 
29
29
  def in_chrome_context
data/lib/tor/driver.rb CHANGED
@@ -4,6 +4,7 @@ require 'open-uri'
4
4
  require_relative '../service'
5
5
  require_relative '../options'
6
6
  require_relative '../firefox_prefs'
7
+ require_relative 'error'
7
8
  require_relative 'libxul_patchable'
8
9
  require_relative 'profile'
9
10
  require_relative 'tor_process'
@@ -23,13 +24,16 @@ module Selenium
23
24
  PREF_BROWSER_SECURITY_LEVEL = 'browser.security_level.security_slider'
24
25
  PREF_TORRC_PATH = 'extensions.torlauncher.torrc_path'
25
26
  PREF_SOCKS_PORT = 'network.proxy.socks_port'
27
+ PREF_CONTROL_PORT = 'extensions.torlauncher.control_port'
26
28
 
27
- DOMAIN_ISOLATOR = 'TorDomainIsolator' # ES6 module
28
- NEW_CIRCUIT = 'newCircuitForDomain' # js function
29
+ DOMAIN_ISOLATOR_URI = 'moz-src:///toolkit/components/tor-launcher/TorDomainIsolator' # ES6 module URI
30
+ DOMAIN_ISOLATOR_OLD_URI = 'resource://gre/modules/TorDomainIsolator' # ES6 module URI
29
31
 
30
- TB_SEC_LEVELS = { 'standard' => 4, 'safer' => 2, 'safest' => 1 }.freeze
32
+ NEW_CIRCUIT = 'newCircuitForDomain' # js function
31
33
 
32
- LOCALHOST_PORT_REGEXP = /127\.0\.0\.1:(\d+)/
34
+ TB_SEC_LEVELS = { 'standard' => 4, 'safer' => 2, 'safest' => 1 }.freeze
35
+
36
+ LOCALHOST_PORT_REGEXP = /127\.0\.0\.1:(\d+)/
33
37
 
34
38
  attr_reader :tor_process
35
39
 
@@ -38,10 +42,10 @@ module Selenium
38
42
  @options = options || Options.new # fix for issue #11, 'tis a puzzlement
39
43
  @options.add_argument '-remote-allow-system-access' # FF 138+
40
44
  add_torrc_path_to_options
45
+ create_tor_process_and_start_tor(@options.tor_opts) # sets @tor_process
46
+ add_ports_to_option_prefs
41
47
  @instance = while_in_tbb_browser_directory { DriverDelegate.new(options: @options, **) } # fixes #22
42
48
  install_extensions @instance
43
- pid = create_tor_process_and_start_tor(@options.tor_opts)
44
- @instance.pref[PREF_SOCKS_PORT] = socks_port(pid)
45
49
  super(@instance)
46
50
  end
47
51
 
@@ -50,9 +54,10 @@ module Selenium
50
54
  end
51
55
 
52
56
  def quit
57
+ super # 16.0a6 on; popup dialog blocks quit unless tor process (& control port) closed *after* browser
58
+ ensure
53
59
  @tor_process&.stop_tor
54
60
  FileUtils.rm_rf @data_dir
55
- super
56
61
  end
57
62
 
58
63
  def security_level
@@ -67,7 +72,9 @@ module Selenium
67
72
  # end
68
73
 
69
74
  def new_circuit_for_site
70
- execute_script_in_chrome_context es6_function_call(es6: DOMAIN_ISOLATOR, func: NEW_CIRCUIT, args: domain)
75
+ uri = DOMAIN_ISOLATOR_URI
76
+ uri = DOMAIN_ISOLATOR_OLD_URI if Gem::Version.new(Tor::TBB_VERSION) < '16.0a6' # DEPRECATE when 16 stable
77
+ execute_script_in_chrome_context es6_function_call(es6_uri: uri, func: NEW_CIRCUIT, args: domain)
71
78
  end
72
79
 
73
80
  alias new_circuit_for_page new_circuit_for_site
@@ -107,9 +114,8 @@ module Selenium
107
114
  URI(current_url).host&.match(/[^.]+\.\w+$/)
108
115
  end
109
116
 
110
- def socks_port(pid)
111
- str = `netstat -tnlp 2>/dev/null|grep #{pid}/tor` # net-tools dep
112
- str.match(LOCALHOST_PORT_REGEXP)[1].to_i
117
+ def add_ports_to_option_prefs
118
+ @options.prefs.merge! PREF_CONTROL_PORT => tor_process.control_port, PREF_SOCKS_PORT => tor_process.socks_port
113
119
  end
114
120
  end
115
121
  end
@@ -1,4 +1,12 @@
1
1
  ---
2
+ 16.0a6:
3
+ unpatched_libxul: 953e6739ed12e7040969532a8ffd8ca9ee4ac57bcd26217ee7ef6be07e671577
4
+ patched_libxul: 0a51fcad914d091d7dffdb8fd3ac83ea3fc0fa4ab9f4ffdbfe3e1a158291025b
5
+ patch_checksum: 3679851db2713292c2ce91e962e6237b032fcc38243b6b31c41225c003b1e1dd
6
+ 16.0a5:
7
+ unpatched_libxul: 78dc4e14b71be5522aa5530571371d84c070fd620681955d590a2d12c5ac632f
8
+ patched_libxul: 21c888f7c99cb9b946a1a7a03fbad0b2934e0eb5fee81e540c6dbb357d9810d9
9
+ patch_checksum: 031cb83ebdda6566699d22a7015ff9f1cf45f4eb2ade87b47c9ac609c3634aa3
2
10
  16.0a4:
3
11
  unpatched_libxul: 432205c32f39e9d78c2b525d4f8158cb1489bef85f9fdad6961b9c7493cb9a3a
4
12
  patched_libxul: 61ee89195b06b6ed01581cf34a23bc324da3817ea703f8ad57f984664888c579
@@ -15,6 +23,30 @@
15
23
  unpatched_libxul: 031bb945f33ab3c735c5a83005a73c0969eaff5c354e3d84aed2d7d39d0e05e1
16
24
  patched_libxul: 7b87200bb0a406f8d4c0660413aab05b61eb539e7596082b8f4c78d083b072a1
17
25
  patch_checksum: 6315196938fa4c3bae59b300426f2dac1141fb075c19fcdbebd656d0c3452dd5
26
+ 15.0.13:
27
+ unpatched_libxul: c48ec76b7011319f0b225fa99587e6f75e49ff9a99a334a3b1b01b9daf184f73
28
+ patched_libxul: 45d88d2244f24250c11c7115287ef27f69b371659ec2a0eb0a484cf5bb42446d
29
+ patch_checksum: 272c97a05d968f1eb6a13e9fc660a1ce47e3ec8406749407b3c2238ae3097062
30
+ 15.0.12:
31
+ unpatched_libxul: 33d5f416b406d2b11687920e2248760a8f012e4a2473d6813968b33948ec0c2e
32
+ patched_libxul: 8bd0aeb1b2f78e5d2e7a721e7d495872c5049c995f8b04accc47aa2c699eaec9
33
+ patch_checksum: 1b726b56fc6a6e5937d0f69a1cd8e6224f9709e7e46d51afa28d02395cf387c5
34
+ 15.0.11:
35
+ unpatched_libxul: 0936946a38d718e6cd18945de19b189ae0b95a0ec0f9b2214607ab0eb58f1437
36
+ patched_libxul: ff9cfd8e9a94f2f358d23c33442b017d11990fe28169c508762cd506b8870ab6
37
+ patch_checksum: 40b472e86423026f341257d50ed1a3fb88586eddd34fa161444e6b4bab7b7b09
38
+ 15.0.10:
39
+ unpatched_libxul: 08f4f5d2a435fd7fdea075a5cf15492099b7ce6c5b7a8b096ee0f135052c2088
40
+ patched_libxul: ad1eca9ebac396ab22d1e13e5d5804091ab3bb26ec533c4ab8ce414f68d45845
41
+ patch_checksum: 694dbf57259f194839ba4ea9d487097cc83d1faa9339093fa5368ad4a49b8935
42
+ 15.0.9:
43
+ unpatched_libxul: 7106d33aeb8f4ecb4d87b88ee9e28ec3562e8ffff78f79a35c12622e2342acf9
44
+ patched_libxul: 5527d040bc73ef330fd52a135cd800c8026df87477467d93d600864ae4a542fe
45
+ patch_checksum: b748eba77d408a85fc893a99a3fe7eb64ab90785f65718fdb7c48b8716af42b1
46
+ 15.0.8:
47
+ unpatched_libxul: 91988852045f96a6f9d7bd0a58ef21c902fd6798d51b48770d83b7e542b14dbd
48
+ patched_libxul: 184c98c6ed443d8fd685983715ea82df793032e3773a94b2e92379db0f6c9fb4
49
+ patch_checksum: 5bd27f79d0d2a346b4d7fe7b933e5333dcaf7dfece14df2c1bb411be173a00b8
18
50
  15.0.7:
19
51
  unpatched_libxul: 46c9b9c8882645386a3ca9714f6abc09198fbd1ae233509cb658ebc6b689e444
20
52
  patched_libxul: b1770187f513bd6bfb8a86fbd4617b1de142c43529f350e9ba79ac52216b4e5a
@@ -11,6 +11,7 @@ module Selenium
11
11
  class TorProcess
12
12
  BOOTSTRAP_SUCCESS_REGEX = /Bootstrapped 100% \(done\): Done$/
13
13
  BOOTSTRAP_FAIL_REGEX = /^[A-Z][a-z]{2} \d{2} \d{2}:\d{2}:\d{2}\.\d{3} \[err\] .*/
14
+ SOCKS_PORT_REGEX = /Opened Socks listener connection \(ready\) on 127\.0\.0\.1:(\d+)$/
14
15
 
15
16
  DIR_MSG = 'data_dir must exist and be a dir'
16
17
  DATA_FILES = %w[cached-certs cached-microdesc-consensus cached-microdescs.new].freeze
@@ -19,7 +20,7 @@ module Selenium
19
20
  attr_accessor :cached_certs, :cached_microdesc_consensus, :cached_microdescs # set when tor first started
20
21
  end
21
22
 
22
- attr_reader :pid, :config
23
+ attr_reader :pid, :config, :socks_port
23
24
 
24
25
  def initialize(data_dir, opts = {})
25
26
  setup_data_dir data_dir
@@ -28,13 +29,14 @@ module Selenium
28
29
  @opts = map_opts_to_torrc_keys opts
29
30
  @torrc = Torrc.new(@data_dir)
30
31
  @config ||= setup_config # Hash to store torrc config
32
+ @socks_port = 0
31
33
  end
32
34
 
33
- def start_tor(timeout: 10)
35
+ def start_tor(timeout: 120)
34
36
  r, io = IO.pipe
35
37
  pid = Process.spawn tor_command, out: io, err: :out
36
38
  io.close
37
- parse_tor_bootstrap_errors_with_timeout(r, timeout: timeout)
39
+ parse_tor_bootstrap_with_timeout(r, timeout: timeout)
38
40
  # tor process now bootstrapped
39
41
  read_from_data_files
40
42
  @pid = pid
@@ -50,6 +52,10 @@ module Selenium
50
52
  @pid = nil
51
53
  end
52
54
 
55
+ def control_port
56
+ File.read(@torrc.control_port_file_path).split(':').last.to_i # "PORT=127.0.0.1:<port>"
57
+ end
58
+
53
59
  private
54
60
 
55
61
  def setup_data_dir(dir)
@@ -79,11 +85,12 @@ module Selenium
79
85
  "#{TBB_TOR_BINARY_PATH} -f #{@torrc.path}"
80
86
  end
81
87
 
82
- def parse_tor_bootstrap_errors_with_timeout(io, timeout:)
88
+ def parse_tor_bootstrap_with_timeout(io, timeout:)
83
89
  lines = []
84
90
  errors = Timeout.timeout timeout do
85
91
  io.each_line do |line|
86
92
  lines << line
93
+ parse_socks_port line
87
94
  break lines.join if line.match BOOTSTRAP_FAIL_REGEX
88
95
  break '' if line.match BOOTSTRAP_SUCCESS_REGEX
89
96
  end
@@ -103,6 +110,12 @@ module Selenium
103
110
  Process.kill 'KILL', pid if pid
104
111
  raise WebDriver::Error::TimeoutError, "Tor not bootstrapped after #{timeout} seconds" # regular s-w error
105
112
  end
113
+
114
+ def parse_socks_port(string)
115
+ return unless (match = string.match(SOCKS_PORT_REGEX))
116
+
117
+ @socks_port = match[1].to_i
118
+ end
106
119
  end
107
120
  end
108
121
  end
data/lib/tor/torrc.rb CHANGED
@@ -8,16 +8,24 @@ module Selenium
8
8
  module Tor
9
9
  # Respresentation of a torrc file
10
10
  class Torrc
11
- FIXED_CONFIG_KEYS = %w[DataDirectory GeoIPFile GeoIPv6File SocksPort].freeze
11
+ AUTO = 'auto'
12
+ CONTROL_PORT = 'control_port'
13
+ GEOIP = 'geoip'
14
+ GEOIP6 = 'geoip6'
15
+ TORRC = 'torrc'
16
+
17
+ FIXED_CONFIG_KEYS = %w[DataDirectory GeoIPFile GeoIPv6File SocksPort ControlPort ControlPortWriteToFile].freeze
18
+
12
19
  INVALID_OPTION_REGEX = %r{\[warn\] Failed to parse/validate config: (.*).$}
13
20
 
14
21
  GEOIP_LOCATION_CHANGE_VER = Gem::Version.new '16.0a4'
15
22
 
16
- attr_reader :path
23
+ attr_reader :control_port_file_path, :path
17
24
 
18
25
  def initialize(data_dir)
19
26
  @data_dir = data_dir
20
- @torrc_file = File.new File.join(@data_dir, 'torrc'), 'w'
27
+ @torrc_file = File.new File.join(@data_dir, TORRC), 'w'
28
+ @control_port_file_path = File.join @data_dir, CONTROL_PORT
21
29
  @path = @torrc_file.path
22
30
  write_default_config
23
31
  end
@@ -41,21 +49,21 @@ module Selenium
41
49
  end
42
50
 
43
51
  def fixed_config
44
- @fixed_config ||= FIXED_CONFIG_KEYS.zip([@data_dir, geoip_file, geoip6_file, 'auto']).to_h
52
+ FIXED_CONFIG_KEYS.zip([@data_dir, geoip_file, geoip6_file, AUTO, AUTO, control_port_file_path]).to_h
45
53
  end
46
54
 
47
55
  def geoip_file
48
56
  # DEPRECATE after 16 stable
49
- return File.join(TBB_TOR_DATA_DIR, 'geoip') if Gem::Version.new(Tor::TBB_VERSION) < GEOIP_LOCATION_CHANGE_VER
57
+ return File.join(TBB_TOR_DATA_DIR, GEOIP) if Gem::Version.new(Tor::TBB_VERSION) < GEOIP_LOCATION_CHANGE_VER
50
58
 
51
- File.join(TBB_TOR_GEOIP_DIR, 'geoip')
59
+ File.join(TBB_TOR_GEOIP_DIR, GEOIP)
52
60
  end
53
61
 
54
62
  def geoip6_file
55
63
  # DEPRECATE after 16 stable
56
- return File.join(TBB_TOR_DATA_DIR, 'geoip6') if Gem::Version.new(Tor::TBB_VERSION) < GEOIP_LOCATION_CHANGE_VER
64
+ return File.join(TBB_TOR_DATA_DIR, GEOIP6) if Gem::Version.new(Tor::TBB_VERSION) < GEOIP_LOCATION_CHANGE_VER
57
65
 
58
- File.join(TBB_TOR_GEOIP_DIR, 'geoip6')
66
+ File.join(TBB_TOR_GEOIP_DIR, GEOIP6)
59
67
  end
60
68
 
61
69
  def validate_torrc_options(hash)
data/lib/tor/version.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  module Selenium
4
4
  module WebDriver
5
5
  module Tor
6
- VERSION = '2.4.1'
6
+ VERSION = '2.5.0'
7
7
  end
8
8
  end
9
9
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: selenium_tor
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.1
4
+ version: 2.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - MatzFan
@@ -89,7 +89,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
89
89
  - !ruby/object:Gem::Version
90
90
  version: '0'
91
91
  requirements: []
92
- rubygems_version: 4.0.6
92
+ rubygems_version: 4.0.10
93
93
  specification_version: 4
94
94
  summary: Selenium extension for Tor Browser
95
95
  test_files: []