Skip to content
Browse files

Add authenticate option for TCP socket connections

  • Loading branch information...
1 parent db39a43 commit 684919f7c7ca67aae5d85ed69b1c342bc382dbb9 Jennifer Hickey committed
View
28 doc/README
@@ -11,13 +11,12 @@ For example, you can:
* Patch code on the fly, without a restart.
* Let anyone on the net 0wn you if you bind to a public interface. :)
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 I mean.
+friends.
== Stern Security Warning. Grrr.
Have a look at the bugs section. It should be pretty apparent that incorrect
-use of this library could create a large security hole, especially before
-authentication is implemented.
+use of this library could create a large security hole.
== Installation
@@ -80,11 +79,11 @@ you've diagnosed and fixed whatever the problem was.
Additionally, if you want to run LiveConsole on a server, but run netcat
locally, you can use SSH port forwarding to avoid having to open LiveConsole
-to the world:
+to the world:
ssh -L4000:localhost:4000 you@server
-Then, locally, you can do
+Then, locally, you can do
netcat localhost 4000
@@ -101,25 +100,12 @@ a LiveConsole on localhost:3333, use
rlwrap is available with most Linux distributions or at
http://utopia.knoware.nl/~hlub/uck/rlwrap/ . It is seriously an incredibly
useful piece of software.
-
+
Typing exit, hitting ^D, or sending signals (like INT or STOP) doesn't work.
Just exit the program you used to connect to it. This has more to do with the
program you use to connect to the socket.
-For TCP connections, there is no authentication support yet, although it is
-planned for the near future. This creates a security risk: anyone that can
-connect to the socket can run arbitrary Ruby code as the user who owns the
-process. In fact, even binding to localhost can be a security issue if you're
-on a box with any untrusted users. If there's a chance you don't know what
-you're doing, avoid using this library. The Unix Domain Socket version is more
-secure, as you can control access via filesystem permissions.
-
-Only one client can connect at a time. I don't think anyone needs multiple LC
-connections to serve multiple instances of IRB to various clients, but if you
-need it, let me know.
-
-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.
Other than that, LiveConsole doesn't have any known bugs, but it is odd
software that also monkey-patches IRB, so they are likely to be there. Bug
@@ -130,5 +116,7 @@ reports and patches gratefully accepted.
Pete Elmore, author -- (pete.elmore(a)gmail.com)
Roger D. Pack (http://betterlogic.com/roger/) provided patches and Windows
-support
+support
+
+Jennifer Hickey - author of this particular fork
View
32 lib/live_console.rb
@@ -6,7 +6,7 @@
require 'irb'
require 'irb/frame'
require 'socket'
-require 'live_console_config'
+
# LiveConsole provides a socket that can be connected to via netcat or telnet
# to use to connect to an IRB session inside a running process. It listens on the
@@ -18,8 +18,8 @@ class LiveConsole
include Socket::Constants
autoload :IOMethods, 'live_console/io_methods'
- attr_accessor :io_method, :io, :thread, :bind
- private :io_method=, :io=, :thread=
+ attr_accessor :io_method, :io, :thread, :bind, :authenticate
+ private :io_method=, :io=, :thread=, :authenticate=
# call-seq:
# # Bind a LiveConsole to localhost:3030 (only allow clients on this
@@ -27,6 +27,12 @@ class LiveConsole
# LiveConsole.new :socket, :port => 3030
# # Accept connections from anywhere on port 3030. Ridiculously insecure:
# LiveConsole.new(:socket, :port => 3030, :host => '0.0.0.0')
+ # # Accept connections from anywhere on port 3030, secured with a plain-text credentials file
+ # # credentials_file should be of the form:
+ # # username: <username>
+ # # password: <password>
+ # LiveConsole.new(:socket, :port => 3030, :host => '0.0.0.0', :authenticate=>true,
+ # :credentials_file='/path/to/.consoleaccess)
# # Use a Unix Domain Socket (which is more secure) instead:
# LiveConsole.new(:unix_socket, :path => '/tmp/my_liveconsole.sock',
# :mode => 0600, :uid => Process.uid, :gid => Process.gid)
@@ -41,6 +47,7 @@ class LiveConsole
def initialize(io_method, opts = {})
self.io_method = io_method.to_sym
self.bind = opts.delete :bind
+ self.authenticate = opts.delete :authenticate
unless IOMethods::List.include?(self.io_method)
raise ArgumentError, "Unknown IO method: #{io_method}"
end
@@ -76,12 +83,19 @@ def start_blocking
#This will block until a connection is made or a failure occurs
if conn.start
thread = Thread.new(conn) {
- irb_io = GenericIOMethod.new conn.raw_input, conn.raw_output
- begin
- IRB.start_with_io(irb_io, bind)
- rescue Errno::EPIPE => e
- conn.stop
- end
+ start_irb = true
+ if authenticate && !conn.authenticate
+ conn.stop
+ start_irb = false
+ end
+ if start_irb
+ irb_io = GenericIOMethod.new conn.raw_input, conn.raw_output, readline
+ begin
+ IRB.start_with_io(irb_io, bind)
+ rescue Errno::EPIPE => e
+ conn.stop
+ end
+ end
}
end
}
View
25 lib/live_console/io_methods/socket_io/connection.rb
@@ -1,9 +1,12 @@
+require 'yaml'
+
class LiveConsole::IOMethods::SocketIOConnection
attr_accessor :raw_input, :raw_output
- def initialize(server)
+ def initialize(server, opts)
@server = server
+ @opts = opts
end
def start
@@ -26,4 +29,24 @@ def stop
def select
IO.select [@server], [], [], 1 if @server
end
+
+ # Retrieves credentials from I/O and matches them against the specified file
+ # credentials_file should be of the form:
+ # username: <username>
+ # password: <password>
+ def authenticate
+ authenticated = true
+ raw_output.print "Login: "
+ raw_output.flush
+ username = raw_input.gets
+ raw_output.print "Password: "
+ password = raw_input.gets
+ credentials_file= @opts[:credentials_file] || '.consoleaccess'
+ credentials =YAML.load_file(credentials_file)
+ if username.chomp != credentials['username'] || password.chomp != credentials['password']
+ raw_output.puts "Login failed."
+ authenticated = false
+ end
+ authenticated
+ end
end
View
2 lib/live_console/io_methods/socket_io/socket_io.rb
@@ -14,7 +14,7 @@ def initialize(opts)
end
def get_connection
- LiveConsole::IOMethods::SocketIOConnection.new @server
+ LiveConsole::IOMethods::SocketIOConnection.new(@server, opts)
end
end
View
7 lib/live_console/io_methods/unix_socket/connection.rb
@@ -4,8 +4,9 @@ class LiveConsole::IOMethods::UnixSocketConnection
attr_accessor :raw_input, :raw_output
- def initialize(server)
+ def initialize(server, opts)
@server = server
+ @opts = opts
end
def start
@@ -29,4 +30,8 @@ def select
IO.select [@server], [], [], 1 if @server
end
+ def authenticate
+ true
+ end
+
end
View
2 lib/live_console/io_methods/unix_socket/unix_socket.rb
@@ -17,6 +17,6 @@ def initialize(opts)
end
def get_connection
- LiveConsole::IOMethods::UnixSocketConnection.new @server
+ LiveConsole::IOMethods::UnixSocketConnection.new(@server,opts)
end
end

0 comments on commit 684919f

Please sign in to comment.
Something went wrong with that request. Please try again.