db_sucker 3.2.0 → 4.0.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 +4 -4
- data/CHANGELOG.md +29 -0
- data/VERSION +1 -1
- data/db_sucker.gemspec +4 -2
- data/lib/db_sucker/application/core.rb +21 -13
- data/lib/db_sucker/application/dispatch.rb +9 -3
- data/lib/db_sucker/application/sklaven_treiber/worker/accessors.rb +6 -6
- data/lib/db_sucker/application/sklaven_treiber/worker/io/pv_wrapper.rb +1 -1
- data/lib/db_sucker/application/sklaven_treiber/worker/io/sftp_native_download.rb +1 -1
- data/lib/db_sucker/application/window/core.rb +4 -0
- data/lib/db_sucker/application/window/keypad.rb +23 -3
- data/lib/db_sucker/application.rb +10 -3
- data/lib/db_sucker/patches/developer.rb +1 -1
- data/lib/db_sucker/version.rb +1 -1
- metadata +50 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3428652bd57c60d1fe769767084d16087d233435ddae9feedf26d079c65b7cde
|
4
|
+
data.tar.gz: d9f2e97f08011eb2df0bdf168cca219c113607fc2b615afb4d90dc5a58098f14
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 52110571e911566e55534ffab44718254393d99eacab96db9b3acef3378db2a8d539b3e32e868465b46639f03f6fec3206bf14ce0b1ae173cdd7cfc2a694e366
|
7
|
+
data.tar.gz: bcbba5adddf4b577d91c85bb25fa081c808f8fc66095609daa2396d47360d5103cb9f59978ed167c162e6fae6dcfafdede8e815a8f2abf2550032c4c3adb5a7f
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,32 @@
|
|
1
|
+
## 4.0.0
|
2
|
+
|
3
|
+
### Updates
|
4
|
+
|
5
|
+
* Updated net-ssh and net-sftp by major versions (to support OpenSSL 3)
|
6
|
+
* Added ed25519 and bcrypt_pbkdf dependency for ed25519 key support
|
7
|
+
|
8
|
+
### Fixes
|
9
|
+
|
10
|
+
* native sftp downloads will immediately stop if worker is cancelled
|
11
|
+
* fix copying downloaded file (`file` option / `with_copy` example)
|
12
|
+
|
13
|
+
-------------------
|
14
|
+
|
15
|
+
## 3.2.1
|
16
|
+
|
17
|
+
### Updates
|
18
|
+
|
19
|
+
* Added means to signal all threads in order to wake them up as they occasionally get stuck for some reason. Press `S` or use `:signal-threads` to execute. Have yet to find the culprint :)
|
20
|
+
* Slight UX improvements, silent commands briefly flash the screen, invalid commands ring the bell
|
21
|
+
|
22
|
+
### Fixes
|
23
|
+
|
24
|
+
* don't warn about orphaned concurrent-ruby threads, debug log trace of remaining threads
|
25
|
+
* join killed threads to ensure they are dead
|
26
|
+
* minor sshdiag fixes/enhancements
|
27
|
+
|
28
|
+
-------------------
|
29
|
+
|
1
30
|
## 3.2.0
|
2
31
|
|
3
32
|
### Updates
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
4.0.0
|
data/db_sucker.gemspec
CHANGED
@@ -20,8 +20,10 @@ Gem::Specification.new do |spec|
|
|
20
20
|
|
21
21
|
spec.add_dependency "curses", "~> 1.2"
|
22
22
|
spec.add_dependency "activesupport", ">= 4.1"
|
23
|
-
spec.add_dependency "net-ssh", "~>
|
24
|
-
spec.add_dependency "
|
23
|
+
spec.add_dependency "net-ssh", "~> 7.0"
|
24
|
+
spec.add_dependency "ed25519", ">= 1.2", "< 2.0"
|
25
|
+
spec.add_dependency "bcrypt_pbkdf", ">= 1.0", "< 2.0"
|
26
|
+
spec.add_dependency "net-sftp", "~> 4.0"
|
25
27
|
spec.add_development_dependency "bundler"
|
26
28
|
spec.add_development_dependency "rake"
|
27
29
|
spec.add_development_dependency "pry"
|
@@ -1,6 +1,12 @@
|
|
1
1
|
module DbSucker
|
2
2
|
class Application
|
3
3
|
module Core
|
4
|
+
def filtered_threads
|
5
|
+
Thread.list.reject do |thr|
|
6
|
+
thr.backtrace[0]["gems/concurrent-ruby"] rescue false
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
4
10
|
def sandboxed &block
|
5
11
|
block.call
|
6
12
|
rescue StandardError => ex
|
@@ -49,20 +55,22 @@ module DbSucker
|
|
49
55
|
end
|
50
56
|
|
51
57
|
# worker info
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
# slot pool
|
58
|
-
f.puts "\n\n#{sklaventreiber.slot_pools.length} slot pools:\n"
|
59
|
-
sklaventreiber.slot_pools.each do |name, pool|
|
60
|
-
f.puts "#{name}: #{pool.slots}"
|
61
|
-
pool.active.each do |thr|
|
62
|
-
f.puts "\tactive\t #{thr} [#{thr[:itype]}]"
|
58
|
+
if sklaventreiber
|
59
|
+
f.puts "\n\n#{sklaventreiber.workers.length} workers:\n"
|
60
|
+
sklaventreiber.workers.each do |w|
|
61
|
+
f.puts "#{"[SSH] " if w.sshing} #{w.descriptive} #{w.state}".strip
|
63
62
|
end
|
64
|
-
|
65
|
-
|
63
|
+
|
64
|
+
# slot pool
|
65
|
+
f.puts "\n\n#{sklaventreiber.slot_pools.length} slot pools:\n"
|
66
|
+
sklaventreiber.slot_pools.each do |name, pool|
|
67
|
+
f.puts "#{name}: #{pool.slots}"
|
68
|
+
pool.active.each do |thr|
|
69
|
+
f.puts "\tactive\t #{thr} [#{thr[:itype]}]"
|
70
|
+
end
|
71
|
+
pool.waiting.each do |wthr, tthr|
|
72
|
+
f.puts "\twaiting\t #{tthr} [#{tthr[:itype]}]"
|
73
|
+
end
|
66
74
|
end
|
67
75
|
end
|
68
76
|
end
|
@@ -101,7 +101,7 @@ module DbSucker
|
|
101
101
|
i += 1
|
102
102
|
end
|
103
103
|
end
|
104
|
-
t.kill
|
104
|
+
t.kill.join
|
105
105
|
puts "Thread priority: -#{m[1].abs}..+#{m[2].abs}"
|
106
106
|
end
|
107
107
|
|
@@ -112,6 +112,10 @@ module DbSucker
|
|
112
112
|
varstr = ARGV.shift
|
113
113
|
|
114
114
|
configful_dispatch(idstr, varstr) do |identifier, ctn, variation, var|
|
115
|
+
unless ctn
|
116
|
+
abort "This test requires a config identifier with an SSH connection!"
|
117
|
+
end
|
118
|
+
|
115
119
|
log c("\nPlease wait while we run some tests...\n", :blue)
|
116
120
|
_identifier = identifier
|
117
121
|
_ctn = ctn
|
@@ -136,7 +140,7 @@ module DbSucker
|
|
136
140
|
}
|
137
141
|
250.times do
|
138
142
|
break if monitor.synchronize { stop }
|
139
|
-
c, r = ctn.blocking_channel_result("sleep
|
143
|
+
c, r = ctn.blocking_channel_result("sleep 900", blocking: false, channel: true, use_sh: true)
|
140
144
|
monitor.synchronize do
|
141
145
|
channels << c
|
142
146
|
print "+"
|
@@ -145,6 +149,7 @@ module DbSucker
|
|
145
149
|
end
|
146
150
|
ensure
|
147
151
|
debug "Stopping sessions (#{channels.length})..."
|
152
|
+
puts # newline for style
|
148
153
|
i = 1
|
149
154
|
loop do
|
150
155
|
break if monitor.synchronize { channels.empty? }
|
@@ -154,6 +159,7 @@ module DbSucker
|
|
154
159
|
print "-"
|
155
160
|
i += 1
|
156
161
|
end
|
162
|
+
maxsessions = "#{maxsessions}+" if maxsessions.to_i >= 250
|
157
163
|
log c("\n\nSSH MaxSessions: #{c maxsessions, :magenta}", :cyan)
|
158
164
|
log "This value determines how many sessions we can multiplex over a single TCP connection."
|
159
165
|
log "Currently, DbSucker can only utilize one connection, thus this value defines the maxmium concurrency."
|
@@ -161,7 +167,7 @@ module DbSucker
|
|
161
167
|
log " * increase the SSHd `MaxSessions' setting on the remote (if you can)"
|
162
168
|
log " * reduce the amount of workers and/or remote slots"
|
163
169
|
log " * fix the mess that is this tool, visit #{c "https://github.com/2called-chaos/db_sucker", :blue}"
|
164
|
-
t.kill
|
170
|
+
t.kill.join
|
165
171
|
end
|
166
172
|
end
|
167
173
|
rescue Net::SSH::AuthenticationFailed => ex
|
@@ -91,12 +91,12 @@ module DbSucker
|
|
91
91
|
d, dt = Time.current.strftime("%Y-%m-%d"), Time.current.strftime("%H-%M-%S")
|
92
92
|
|
93
93
|
File.expand_path dstfile.dup
|
94
|
-
.gsub
|
95
|
-
.gsub
|
96
|
-
.gsub
|
97
|
-
.gsub
|
98
|
-
.gsub
|
99
|
-
.gsub
|
94
|
+
.gsub(":combined", ":datetime_-_:table")
|
95
|
+
.gsub(":datetime", "#{d}_#{dt}")
|
96
|
+
.gsub(":date", d)
|
97
|
+
.gsub(":time", dt)
|
98
|
+
.gsub(":table", table)
|
99
|
+
.gsub(":id", sklaventreiber.trxid)
|
100
100
|
end
|
101
101
|
end
|
102
102
|
end
|
@@ -51,7 +51,7 @@ module DbSucker
|
|
51
51
|
|
52
52
|
@state = :downloading
|
53
53
|
debug "Opening process `#{cmd}'"
|
54
|
-
Open3.popen2e(cmd
|
54
|
+
Open3.popen2e(cmd) do |_stdin, _stdouterr, _thread|
|
55
55
|
# close & exit status
|
56
56
|
_stdin.close_write
|
57
57
|
exit_status = _thread.value
|
@@ -20,12 +20,14 @@ module DbSucker
|
|
20
20
|
["T", "create core dump and open in editor"],
|
21
21
|
["q", "quit prompt"],
|
22
22
|
["Q", "same as ctrl-c"],
|
23
|
+
["S", "signal/wakeup all threads"],
|
23
24
|
[":", "main prompt"],
|
24
25
|
],
|
25
26
|
main_commands: [
|
26
27
|
[["?", %w[h elp]], [], "shows this help"],
|
27
28
|
[[%w[q uit]], [], "quit prompt"],
|
28
29
|
[["q!", "quit!"], [], "same as ctrl-c"],
|
30
|
+
[["signal-threads"], [], "signal/wakeup all threads"],
|
29
31
|
[["kill"], [], "(dirty) interrupts all workers"],
|
30
32
|
[["kill!"], [], "(dirty) essentially SIGKILL (no cleanup)"],
|
31
33
|
[["dump"], [], "create and open coredump"],
|
@@ -50,6 +52,7 @@ module DbSucker
|
|
50
52
|
when "?" then show_help
|
51
53
|
when "q" then quit_dialog
|
52
54
|
when "Q" then $core_runtime_exiting = 1
|
55
|
+
when "S" then signal_threads
|
53
56
|
end
|
54
57
|
end
|
55
58
|
end
|
@@ -71,6 +74,8 @@ module DbSucker
|
|
71
74
|
when "eval" then args.any? ? _eval(args.join(" ")) : eval_prompt
|
72
75
|
when "p", "pause" then pause_workers(args)
|
73
76
|
when "r", "resume" then resume_workers(args)
|
77
|
+
when "signal-threads" then signal_threads
|
78
|
+
else app.print("\a")
|
74
79
|
end
|
75
80
|
end
|
76
81
|
end
|
@@ -125,6 +130,7 @@ module DbSucker
|
|
125
130
|
|
126
131
|
def pause_workers args
|
127
132
|
if args[0].is_a?(String)
|
133
|
+
window.flashbang
|
128
134
|
_detect_worker(args.join(" "), &:pause)
|
129
135
|
else
|
130
136
|
prompt!("Usage: :p(ause) <table_name|--all>", color: :yellow)
|
@@ -133,6 +139,7 @@ module DbSucker
|
|
133
139
|
|
134
140
|
def resume_workers args
|
135
141
|
if args[0].is_a?(String)
|
142
|
+
window.flashbang
|
136
143
|
_detect_worker(args.join(" "), &:unpause)
|
137
144
|
else
|
138
145
|
prompt!("Usage: :r(esume) <table_name|--all>", color: :yellow)
|
@@ -141,6 +148,7 @@ module DbSucker
|
|
141
148
|
|
142
149
|
def cancel_workers args
|
143
150
|
if args[0].is_a?(String)
|
151
|
+
window.flashbang
|
144
152
|
_detect_worker(args.join(" ")) do |wrk|
|
145
153
|
wrk.cancel! "canceled by user"
|
146
154
|
end
|
@@ -150,16 +158,29 @@ module DbSucker
|
|
150
158
|
end
|
151
159
|
|
152
160
|
def kill_ssh_poll
|
153
|
-
|
154
|
-
|
161
|
+
if sklaventreiber.workers.select{|w| !w.done? || w.sshing }.any?
|
162
|
+
app.print("\a")
|
163
|
+
prompt!("Error: cannot kill SSH poll whilst in use", color: :red)
|
164
|
+
else
|
165
|
+
window.flashbang
|
166
|
+
sklaventreiber.poll.try(:kill)
|
167
|
+
end
|
155
168
|
end
|
156
169
|
|
157
170
|
def kill_workers
|
171
|
+
window.flashbang
|
158
172
|
Thread.list.each do |thr|
|
159
173
|
thr.raise(Interrupt) if thr[:managed_worker]
|
160
174
|
end
|
161
175
|
end
|
162
176
|
|
177
|
+
def signal_threads
|
178
|
+
window.flashbang
|
179
|
+
Thread.list.each do |thr|
|
180
|
+
thr.signal if thr.respond_to?(:signal)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
163
184
|
def kill_app
|
164
185
|
exit!
|
165
186
|
end
|
@@ -171,4 +192,3 @@ module DbSucker
|
|
171
192
|
end
|
172
193
|
end
|
173
194
|
end
|
174
|
-
|
@@ -37,10 +37,17 @@ module DbSucker
|
|
37
37
|
else "Unhandled exception terminated application!"
|
38
38
|
end
|
39
39
|
ensure
|
40
|
+
$core_runtime_exiting = 1
|
40
41
|
app.fire(:core_shutdown)
|
41
|
-
remain =
|
42
|
-
if remain > 1
|
43
|
-
app.
|
42
|
+
remain = app.filtered_threads
|
43
|
+
if remain.length > 1
|
44
|
+
app.error "[WARN] #{remain.length} threads remain (should be 1)..."
|
45
|
+
remain.each do |thr|
|
46
|
+
app.debug "[THR] #{Thread.main == thr ? "MAIN" : "THREAD"}\t#{thr.alive? ? "ALIVE" : "DEAD"}\t#{thr.inspect}", 10
|
47
|
+
thr.backtrace.each do |l|
|
48
|
+
app.debug "[THR]\t#{l}", 20
|
49
|
+
end
|
50
|
+
end
|
44
51
|
else
|
45
52
|
app.debug "1 thread remains..."
|
46
53
|
end
|
@@ -12,7 +12,7 @@ module DbSucker
|
|
12
12
|
end
|
13
13
|
app.debug "IO-stats: {#{iostats * ", "}}"
|
14
14
|
end
|
15
|
-
app.dump_core if
|
15
|
+
app.dump_core if app.filtered_threads.length > 1
|
16
16
|
app.debug "RSS: #{app.human_bytes(`ps h -p #{Process.pid} -o rss`.strip.split("\n").last.to_i * 1024)}"
|
17
17
|
end
|
18
18
|
|
data/lib/db_sucker/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: db_sucker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 4.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sven Pachnit
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-10-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: curses
|
@@ -44,28 +44,68 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '7.0'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '7.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: ed25519
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.2'
|
62
|
+
- - "<"
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: '2.0'
|
65
|
+
type: :runtime
|
66
|
+
prerelease: false
|
67
|
+
version_requirements: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '1.2'
|
72
|
+
- - "<"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '2.0'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: bcrypt_pbkdf
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '1.0'
|
82
|
+
- - "<"
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '2.0'
|
85
|
+
type: :runtime
|
86
|
+
prerelease: false
|
87
|
+
version_requirements: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '1.0'
|
92
|
+
- - "<"
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '2.0'
|
55
95
|
- !ruby/object:Gem::Dependency
|
56
96
|
name: net-sftp
|
57
97
|
requirement: !ruby/object:Gem::Requirement
|
58
98
|
requirements:
|
59
99
|
- - "~>"
|
60
100
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
101
|
+
version: '4.0'
|
62
102
|
type: :runtime
|
63
103
|
prerelease: false
|
64
104
|
version_requirements: !ruby/object:Gem::Requirement
|
65
105
|
requirements:
|
66
106
|
- - "~>"
|
67
107
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
108
|
+
version: '4.0'
|
69
109
|
- !ruby/object:Gem::Dependency
|
70
110
|
name: bundler
|
71
111
|
requirement: !ruby/object:Gem::Requirement
|
@@ -195,7 +235,7 @@ homepage: https://github.com/2called-chaos/db_sucker
|
|
195
235
|
licenses:
|
196
236
|
- MIT
|
197
237
|
metadata: {}
|
198
|
-
post_install_message:
|
238
|
+
post_install_message:
|
199
239
|
rdoc_options: []
|
200
240
|
require_paths:
|
201
241
|
- lib
|
@@ -210,9 +250,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
210
250
|
- !ruby/object:Gem::Version
|
211
251
|
version: '0'
|
212
252
|
requirements: []
|
213
|
-
|
214
|
-
|
215
|
-
signing_key:
|
253
|
+
rubygems_version: 3.3.26
|
254
|
+
signing_key:
|
216
255
|
specification_version: 4
|
217
256
|
summary: Sucks your remote databases via SSH for local tampering.
|
218
257
|
test_files: []
|