live_console 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/doc/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2007 Peter Elmore (pete.elmore at gmail.com)
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a
4
+ copy of this software and associated documentation files (the "Software"),
5
+ to deal in the Software without restriction, including without limitation
6
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
7
+ and/or sell copies of the Software, and to permit persons to whom the
8
+ Software is furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
19
+ DEALINGS IN THE SOFTWARE.
data/doc/README ADDED
@@ -0,0 +1,84 @@
1
+ = LiveConsole
2
+
3
+ == Summary
4
+
5
+ LiveConsole is a library for providing IRB over a TCP connection . If you add
6
+ it to your application, you can run arbitrary code against your application.
7
+ For example, you can:
8
+ * Inspect the state of a running application
9
+ * Change the state of the application
10
+ * Patch code on the fly, without a restart.
11
+ * Let anyone on the net 0wn you if you bind to anything other than
12
+ localhost. :)
13
+ It's useful as a diagnostic tool, a debugging tool, and a way to impress your friends or get those Lisp guys off your back. You know the ones.
14
+
15
+ == Stern Security Warning. Grrr.
16
+
17
+ Have a look at the bugs section. It should be pretty apparent that incorrect
18
+ use of this library could create a large security hole, especially before
19
+ authentication is implemented.
20
+
21
+ == Installation
22
+
23
+ You can install via rubygems,
24
+
25
+ gem install live_console
26
+
27
+ or plain old setup.rb:
28
+
29
+ ruby setup.rb install
30
+
31
+ == How to use LiveConsole
32
+
33
+ LiveConsole is very easy to use in your own app:
34
+
35
+ require 'rubygems'
36
+ require 'live_console'
37
+
38
+ lc = LiveConsole.new 1337 # Creates a LiveConsole on port 1337
39
+ # We're not yet listening on the port. We need to start it up:
40
+ lc.run # Starts the LiveConsole thread
41
+ # At this point, users can connect and get an IRB prompt.
42
+ lc.stop # Kills the LiveConsole thread
43
+ # Now, no one can connect.
44
+
45
+ Have a look at doc/lc_example.rb for a brief example of how to use LiveConsole.
46
+ Try just running it:
47
+
48
+ $ ruby doc/lc_example.rb 4000 test
49
+ # Then, in a different shell:
50
+ $ netcat localhost 4000
51
+ irb(main):001:0> puts 'Wow, magic!'
52
+
53
+ You can get creative about it, only starting LiveConsole when there's an
54
+ unhandled exception in your server, and then calling LiveConsole#stop when
55
+ you've diagnosed and fixed whatever the problem was.
56
+
57
+ == Bugs
58
+
59
+ LiveConsole lacks many of the niceties of IRB on the console, like Readline
60
+ support.
61
+
62
+ Typing exit, hitting ^D, or sending signals (like INT or STOP) doesn't work.
63
+ Just exit the program you used to connect to it.
64
+
65
+ There is no authentication support yet, although it is planned for the near
66
+ future. This creates a security risk: anyone that can connect to the socket
67
+ can run arbitrary Ruby code as the user who owns the process. In fact, even
68
+ binding to localhost can be a security issue if you're on a box with any
69
+ untrusted users. If there's a chance you don't know what you're doing, avoid
70
+ using this library.
71
+
72
+ The README contains a slur against Lisp guys. Please stop hitting me with that PDP-10 manual. I love your language and the lambda tattoo on your chest.
73
+
74
+ Other than that, LiveConsole doesn't have any known bugs, but it is alpha
75
+ software, so they are likely to be there. Bug reports and patches gratefully
76
+ accepted.
77
+
78
+ == Credits
79
+
80
+ Pete Elmore -- (pete.elmore(a)gmail.com)
81
+
82
+ == Home page
83
+
84
+ http://debu.gs/live-console
data/doc/lc_example.rb ADDED
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'live_console'
5
+
6
+ print <<-EOF
7
+ This is a demo program for LiveConsole. It starts a LiveConsole on the
8
+ specified port, and you can connect to it by using netcat or telnet to connect
9
+ to the specified port.
10
+ Usage:
11
+ #{$0} [port_number [value_for_$x]]
12
+ The default port is 3333, and $x is set by default to nil. Run this program,
13
+ and then in a different terminal, connect to it via netcat or telnet. You can
14
+ check that the value of $x is exactly what you set it to, and that you're
15
+ working inside this process, but there's not much to do inside the example
16
+ script. :)
17
+ EOF
18
+
19
+ port = ARGV.first.to_i
20
+ port = port.zero? ? 3333 : port
21
+ $x = ARGV[1]
22
+
23
+ lc = LiveConsole.new port
24
+ lc.run
25
+
26
+ oldx = $x
27
+ loop {
28
+ if $x != oldx
29
+ puts "The time is now #{Time.now.strftime('%R:%S')}.",
30
+ "The value of $x changed from #{oldx.inspect} to #{$x.inspect}."
31
+ oldx = $x
32
+ end
33
+ sleep 1
34
+ }
@@ -0,0 +1,156 @@
1
+ # LiveConsole
2
+ # Pete Elmore (pete.elmore@gmail.com), 2007-10-18
3
+ # debu.gs/live-console
4
+ # See doc/LICENSE.
5
+
6
+ require 'irb'
7
+ require 'socket'
8
+
9
+ # LiveConsole provides a socket that can be connected to via netcat or telnet
10
+ # to use to connect to an IRB session inside a running process. It creates a
11
+ # thread that listens on the specified address/port, and presents connecting
12
+ # clients with an IRB shell. Using this, you can execute code on a running
13
+ # instance of a Ruby process to inspect the state or even patch code on the
14
+ # fly. There is currently no readline support.
15
+ class LiveConsole
16
+ include Socket::Constants
17
+
18
+ attr_accessor :tcp_server, :lc_thread
19
+ private :tcp_server=, :lc_thread=
20
+
21
+ # call-seq:
22
+ # # Bind a LiveConsole to localhost:3030:
23
+ # LiveConsole.new 3030
24
+ # # Accept connections from anywhere on port 3030. Ridiculously insecure:
25
+ # LiveConsole.new(3030, 'Your.IP.address')
26
+ #
27
+ # Creates a new LiveConsole. You must next call LiveConsole#run when you
28
+ # want to spawn the thread to accept connections and run the console.
29
+ def initialize(listen_port, listen_addr = '127.0.0.1')
30
+ self.tcp_server = TCPServer.new listen_addr, listen_port
31
+ end
32
+
33
+ # LiveConsole#run spawns a thread to listen for, accept, and provide an IRB
34
+ # console to new connections. If a thread is already running, this method
35
+ # simply returns false; otherwise, it returns the new thread.
36
+ def run
37
+ return false if lc_thread
38
+ self.lc_thread = Thread.new {
39
+ loop {
40
+ socket = nil
41
+ begin
42
+ Thread.pass
43
+ socket = tcp_server.accept_nonblock
44
+ io = SocketIOMethod.new(socket)
45
+ IRB.start_with_io(io)
46
+ rescue Errno::EAGAIN, Errno::ECONNABORTED, Errno::EPROTO,
47
+ Errno::EINTR
48
+ socket.close rescue nil
49
+ IO.select([tcp_server], [], [], 1)
50
+
51
+ retry
52
+ end
53
+ }
54
+ }
55
+ lc_thread
56
+ end
57
+
58
+ # Ends the running thread, if it exists. Returns true if a thread was
59
+ # running, false otherwise.
60
+ def stop
61
+ if lc_thread
62
+ lc_thread.exit
63
+ self.lc_thread = nil
64
+ true
65
+ else
66
+ false
67
+ end
68
+ end
69
+
70
+ def init_irb
71
+ return if @@irb_inited_already
72
+ IRB.setup nil
73
+ @@irb_inited_already = true
74
+ end
75
+ end
76
+
77
+ # We need to make a couple of changes to the IRB module to account for using a
78
+ # weird I/O method and re-starting IRB from time to time.
79
+ module IRB
80
+ @inited = false
81
+
82
+ # Overridden a la FXIrb to accomodate our needs.
83
+ def IRB.start_with_io(io, &block)
84
+ unless @inited
85
+ setup '/dev/null'
86
+ IRB.parse_opts
87
+ IRB.load_modules
88
+ @inited = true
89
+ end
90
+
91
+ irb = Irb.new(nil, io, io)
92
+
93
+ @CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC]
94
+ @CONF[:MAIN_CONTEXT] = irb.context
95
+ @CONF[:PROMPT_MODE] = :INF_RUBY
96
+
97
+ catch(:IRB_EXIT) {
98
+ begin
99
+ irb.eval_input
100
+ rescue StandardError => e
101
+ irb.print([e.to_s, e.backtrace].flatten.join("\n") + "\n")
102
+ retry
103
+ end
104
+ }
105
+ print "\n"
106
+ end
107
+
108
+ class Context
109
+ # Fix an IRB bug; it ignores your output method.
110
+ def output *args
111
+ @output_method.print *args
112
+ end
113
+ end
114
+
115
+ class Irb
116
+ # Fix an IRB bug; it ignores your output method.
117
+ def printf(*args)
118
+ context.output(sprintf(*args))
119
+ end
120
+
121
+ # Fix an IRB bug; it ignores your output method.
122
+ def print(*args)
123
+ context.output *args
124
+ end
125
+ end
126
+ end
127
+
128
+ # The SocketIOMethod is a class that wraps I/O over a socket for IRB.
129
+ class SocketIOMethod < IRB::StdioInputMethod
130
+ def initialize(socket)
131
+ @socket = socket
132
+ @line = []
133
+ @line_no = 0
134
+ end
135
+
136
+ def gets
137
+ @socket.print @prompt
138
+ @socket.flush
139
+ @line[@line_no += 1] = @socket.gets
140
+ @socket.flush
141
+ @line[@line_no]
142
+ end
143
+
144
+ # These just pass through to the socket.
145
+ %w(eof? close).each { |mname|
146
+ define_method(mname) { || @socket.send mname }
147
+ }
148
+
149
+ def print(*a)
150
+ @socket.print *a
151
+ end
152
+
153
+ def file_name
154
+ @socket.inspect
155
+ end
156
+ end
@@ -0,0 +1,8 @@
1
+ # This module houses a pile of informative constants for LiveConsole.
2
+ module LiveConsoleConfig
3
+ Authors = 'Pete Elmore'
4
+ Email = 'pete.elmore@gmail.com'
5
+ PkgName = 'live_console'
6
+ Version = '0.1.0'
7
+ URL = 'http://debu.gs/live-console'
8
+ end
metadata ADDED
@@ -0,0 +1,52 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.4
3
+ specification_version: 1
4
+ name: live_console
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.1.0
7
+ date: 2007-10-19 00:00:00 -07:00
8
+ summary: A library to support adding a console to your running application.
9
+ require_paths:
10
+ - lib
11
+ email: pete.elmore@gmail.com
12
+ homepage: http://debu.gs/live-console
13
+ rubyforge_project:
14
+ description:
15
+ autorequire: live_console
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Pete Elmore
31
+ files:
32
+ - doc/LICENSE
33
+ - doc/README
34
+ - doc/lc_example.rb
35
+ - lib/live_console.rb
36
+ - lib/live_console_config.rb
37
+ test_files: []
38
+
39
+ rdoc_options: []
40
+
41
+ extra_rdoc_files:
42
+ - doc/README
43
+ - doc/LICENSE
44
+ - doc/lc_example.rb
45
+ executables: []
46
+
47
+ extensions: []
48
+
49
+ requirements: []
50
+
51
+ dependencies: []
52
+