From 352b7d4551ba0a693b706594866cb2aaeb7a94ac Mon Sep 17 00:00:00 2001 From: Matthias H Date: Fri, 21 Feb 2014 20:21:02 +0100 Subject: [remote] removed due to security concerns --- Rakefile | 2 +- bin/rbot-remote | 76 -------- data/rbot/plugins/remotectl.rb | 29 --- lib/rbot/core/remote.rb | 401 ----------------------------------------- man/rbot-remote.xml | 217 ---------------------- rbot.gemspec | 5 +- 6 files changed, 3 insertions(+), 727 deletions(-) delete mode 100755 bin/rbot-remote delete mode 100644 data/rbot/plugins/remotectl.rb delete mode 100644 lib/rbot/core/remote.rb delete mode 100644 man/rbot-remote.xml diff --git a/Rakefile b/Rakefile index 97b3e1f3..7bf643e3 100644 --- a/Rakefile +++ b/Rakefile @@ -7,7 +7,7 @@ rule '.1' => ['.xml'] do |t| sh "xsltproc -nonet -o #{t.name} /usr/share/sgml/docbook/stylesheet/xsl/nwalsh/manpages/docbook.xsl #{t.source}" end -task :manpages => ['man/rbot.1', 'man/rbot-remote.1'] +task :manpages => ['man/rbot.1'] SPECFILE = 'rbot.gemspec' # The Rakefile is also used after installing the gem, to build diff --git a/bin/rbot-remote b/bin/rbot-remote deleted file mode 100755 index 353bb06d..00000000 --- a/bin/rbot-remote +++ /dev/null @@ -1,76 +0,0 @@ -#! /usr/bin/ruby -require 'drb' -require 'optparse' - -#++ -# -# :title: RemoteCtl example script -# -# Author:: jsn (dmitry kim) -# Copyright:: (C) 2007 dmitry kim -# License:: in public domain - -user = nil -pw = nil -dst = nil -uri = 'druby://localhost:7268' - -opts = OptionParser.new -opts.on('-u', '--user ', "remote user (mandatory)") { |v| user = v } -opts.on('-p', '--password ', "remote user password (mandatory)") { |v| pw = v } -opts.on('-d', '--destination ') { |v| dst = v } -opts.on('-r', '--uri ', "rbot url (#{uri})") { |v| uri = v } -opts.on('-h', '--help', "this message") { |v| pw = nil } # sorry! -opts.on('-a', '--about', "what it's all about.") { |v| - puts < user create rmuser rmpw - created botuser remote - - 2) # add a remotectl permission to your newly created remote user: - - permissions set +remotectl for rmuser - okies! - - 3) # add specific permissions for the commands you want to allow via - # remote interface. for example, in this script we want 'say', - # 'action' and other basic commands to work: - - permissions set +basics::talk::do for rmuser - alright - - 4) # run the #{$0} and type something. the message should - # show up on your channel / arrive as an irc private message. - - [you@yourhost ~]$ ./bin/rbot-remote -u rmuser -p rmpw -d '#your-channel' - hello, world! - - [you@yourhost ~]$ -EOF - exit 0 -} -opts.parse! - -if !pw || !user || !dst - puts opts.to_s - exit 0 -end - -rbot = DRbObject.new_with_uri(uri) -id = rbot.delegate(nil, "remote login #{user} #{pw}")[:return] -puts "id is #{id.inspect}" -loop { - s = gets or break - s.chomp! - rv = rbot.delegate(id, "dispatch say #{dst} #{s}") or break - puts "rv is #{rv.inspect}" -} - diff --git a/data/rbot/plugins/remotectl.rb b/data/rbot/plugins/remotectl.rb deleted file mode 100644 index 31d48fe3..00000000 --- a/data/rbot/plugins/remotectl.rb +++ /dev/null @@ -1,29 +0,0 @@ -#-- vim:sw=4:et -#++ -# -# :title: RemoteCtl plugin -# -# Author:: jsn (dmitry kim) -# Copyright:: (C) 2007 dmitry kim -# License:: in public domain -# -# Adds druby remote command execution to rbot. See 'bin/rbot-remote' for -# example usage. - -class RemoteCtlPlugin < Plugin - include RemotePlugin - - def remote_command(m, params) - s = params[:string].to_s - u = @bot.server.user("remote:#{m.source.username}") - @bot.auth.login(u, m.source.username, m.source.password) - fake_message(s, :source => u) - end -end - -me = RemoteCtlPlugin.new - -me.remote_map 'dispatch *string', - :action => 'remote_command' - -me.default_auth('*', false) diff --git a/lib/rbot/core/remote.rb b/lib/rbot/core/remote.rb deleted file mode 100644 index d8d43533..00000000 --- a/lib/rbot/core/remote.rb +++ /dev/null @@ -1,401 +0,0 @@ -#-- vim:sw=2:et -#++ -# -# :title: Remote service provider for rbot -# -# Author:: Giuseppe Bilotta (giuseppe.bilotta@gmail.com) -# -# From an idea by halorgium . -# -# TODO find a way to manage session id (logging out, manually and/or -# automatically) - -require 'drb/drb' - -module ::Irc -class Bot - - module Auth - - # We extend the BotUser class to handle remote logins - # - class BotUser - - # A rather simple method to handle remote logins. Nothing special, just a - # password check. - # - def remote_login(password) - if password == @password - debug "remote login for #{self.inspect} succeeded" - return true - else - return false - end - end - end - - # We extend the ManagerClass to handle remote logins - # - class ManagerClass - - MAX_SESSION_ID = 2**128 - 1 - - # Creates a session id when the given password matches the given - # botusername - # - def remote_login(botusername, pwd) - @remote_users = Hash.new unless defined? @remote_users - n = BotUser.sanitize_username(botusername) - k = n.to_sym - raise "No such BotUser #{n}" unless include?(k) - bu = @allbotusers[k] - if bu.remote_login(pwd) - raise "ran out of session ids!" if @remote_users.length == MAX_SESSION_ID - session_id = rand(MAX_SESSION_ID) - while @remote_users.has_key?(session_id) - session_id = rand(MAX_SESSION_ID) - end - @remote_users[session_id] = bu - return session_id - end - return false - end - - # Returns the botuser associated with the given session id - def remote_user(session_id) - return everyone unless session_id - return nil unless defined? @remote_users - if @remote_users.has_key?(session_id) - return @remote_users[session_id] - else - return nil - end - end - end - - end - - - # A RemoteMessage is similar to a BasicUserMessage - # - class RemoteMessage - # associated bot - attr_reader :bot - - # when the message was received - attr_reader :time - - # remote client that originated the message - attr_reader :source - - # contents of the message - attr_accessor :message - - def initialize(bot, source, message) - @bot = bot - @source = source - @message = message - @time = Time.now - end - - # The target of a RemoteMessage - def target - @bot - end - - # Remote messages are always 'private' - def private? - true - end - end - - # The RemoteDispatcher is a kind of MessageMapper, tuned to handle - # RemoteMessages - # - class RemoteDispatcher < MessageMapper - - # It is initialized by passing it the bot instance - # - def initialize(bot) - super - end - - # The map method for the RemoteDispatcher returns the index of the inserted - # template - # - def map(botmodule, *args) - super - return @templates.length - 1 - end - - # The unmap method for the RemoteDispatcher nils the template at the given index, - # therefore effectively removing the mapping - # - def unmap(botmodule, handle) - tmpl = @templates[handle] - raise "Botmodule #{botmodule.name} tried to unmap #{tmpl.inspect} that was handled by #{tmpl.botmodule}" unless tmpl.botmodule == botmodule.name - debug "Unmapping #{tmpl.inspect}" - @templates[handle] = nil - @templates.clear unless @templates.compact.size > 0 - end - - # We redefine the handle() method from MessageMapper, taking into account - # that @parent is a bot, and that we don't handle fallbacks. - # - # On failure to dispatch anything, the method returns false. If dispatching - # is successfull, the method returns a Hash. - # - # Presently, the hash returned on success has only one key, :return, whose - # value is the actual return value of the successfull dispatch. - # - # TODO this same kind of mechanism could actually be used in MessageMapper - # itself to be able to handle the case of multiple plugins having the same - # 'first word' ... - # - # - def handle(m) - return false if @templates.empty? - failures = [] - @templates.each do |tmpl| - # Skip this element if it was unmapped - next unless tmpl - botmodule = @parent.plugins[tmpl.botmodule] - options = tmpl.recognize(m) - if options.kind_of? Failure - failures << options - else - action = tmpl.options[:action] - unless botmodule.respond_to?(action) - failures << NoActionFailure.new(tmpl, m) - next - end - auth = tmpl.options[:full_auth_path] - debug "checking auth for #{auth}" - # We check for private permission - if m.bot.auth.permit?(m.source, auth, '?') - debug "template match found and auth'd: #{action.inspect} #{options.inspect}" - return :return => botmodule.send(action, m, options) - end - debug "auth failed for #{auth}" - # if it's just an auth failure but otherwise the match is good, - # don't try any more handlers - return false - end - end - failures.each {|r| - debug "#{r.template.inspect} => #{r}" - } - debug "no handler found" - return false - end - - end - - # The Irc::Bot::RemoteObject class represents and object that will take care - # of interfacing with remote clients - # - # Example client session: - # - # require 'drb' - # rbot = DRbObject.new_with_uri('druby://localhost:7268') - # id = rbot.delegate(nil, 'remote login someuser somepass')[:return] - # rbot.delegate(id, 'some secret command') - # - # Of course, the remote login is only neede for commands which may not be available - # to everyone - # - class RemoteObject - - # We don't want this object to be copied clientside, so we make it undumpable - include DRbUndumped - - # Initialization is simple - def initialize(bot) - @bot = bot - end - - # The delegate method. This is the main method used by remote clients to send - # commands to the bot. Most of the time, the method will be called with only - # two parameters (session id and a String), but we allow more parameters - # for future expansions. - # - # The session_id can be nil, meaning that the remote client wants to work as - # an anoynomus botuser. - # - def delegate(session_id, *pars) - warn "Ignoring extra parameters" if pars.length > 1 - cmd = pars.first - client = @bot.auth.remote_user(session_id) - raise "No such session id #{session_id}" unless client - debug "Trying to dispatch command #{cmd.inspect} from #{client.inspect} authorized by #{session_id.inspect}" - m = RemoteMessage.new(@bot, client, cmd) - @bot.remote_dispatcher.handle(m) - end - - private :instance_variables, :instance_variable_get, :instance_variable_set - end - - # The bot also manages a single (for the moment) remote dispatcher. This method - # makes it accessible to the outside world, creating it if necessary. - # - def remote_dispatcher - if defined? @remote_dispatcher - @remote_dispatcher - else - @remote_dispatcher = RemoteDispatcher.new(self) - end - end - - # The bot also manages a single (for the moment) remote object. This method - # makes it accessible to the outside world, creating it if necessary. - # - def remote_object - if defined? @remote_object - @remote_object - else - @remote_object = RemoteObject.new(self) - end - end - - module Plugins - - # We create a new Ruby module that can be included by BotModules that want to - # provide remote interfaces - # - module RemoteBotModule - - # The remote_map acts just like the BotModule#map method, except that - # the map is registered to the @bot's remote_dispatcher. Also, the remote map handle - # is handled for the cleanup management - # - def remote_map(*args) - @remote_maps = Array.new unless defined? @remote_maps - @remote_maps << @bot.remote_dispatcher.map(self, *args) - end - - # Unregister the remote maps. - # - def remote_cleanup - return unless defined? @remote_maps - @remote_maps.each { |h| - @bot.remote_dispatcher.unmap(self, h) - } - @remote_maps.clear - end - - # Redefine the default cleanup method. - # - def cleanup - super - remote_cleanup - end - end - - # And just because I like consistency: - # - module RemoteCoreBotModule - include RemoteBotModule - end - - module RemotePlugin - include RemoteBotModule - end - - end - -end -end - -class RemoteModule < CoreBotModule - - include RemoteCoreBotModule - - Config.register Config::BooleanValue.new('remote.autostart', - :default => false, - :requires_rescan => true, - :desc => "Whether the remote service provider should be started automatically") - - Config.register Config::IntegerValue.new('remote.port', - :default => 7268, # that's 'rbot' - :requires_rescan => true, - :desc => "Port on which the remote interface will be presented") - - Config.register Config::StringValue.new('remote.host', - :default => '127.0.0.1', - :requires_rescan => true, - :desc => "Host on which the remote interface will be presented") - - def initialize - super - @port = @bot.config['remote.port'] - @host = @bot.config['remote.host'] - @drb = nil - begin - start_service if @bot.config['remote.autostart'] - rescue => e - error "couldn't start remote service provider: #{e.inspect}" - end - end - - def start_service - raise "Remote service provider already running" if @drb - @drb = DRb.start_service("druby://#{@host}:#{@port}", @bot.remote_object) - end - - def stop_service - @drb.stop_service if @drb - @drb = nil - end - - def cleanup - stop_service - super - end - - def handle_start(m, params) - if @drb - rep = "remote service provider already running" - rep << " on port #{@port}" if m.private? - else - begin - start_service(@port) - rep = "remote service provider started" - rep << " on port #{@port}" if m.private? - rescue - rep = "couldn't start remote service provider" - end - end - m.reply rep - end - - def remote_test(m, params) - @bot.say params[:channel], "This is a remote test" - end - - def remote_login(m, params) - id = @bot.auth.remote_login(params[:botuser], params[:password]) - raise "login failed" unless id - return id - end - -end - -remote = RemoteModule.new - -remote.map "remote start", - :action => 'handle_start', - :auth_path => ':manage:' - -remote.map "remote stop", - :action => 'handle_stop', - :auth_path => ':manage:' - -remote.default_auth('*', false) - -remote.remote_map "remote test :channel", - :action => 'remote_test' - -remote.remote_map "remote login :botuser :password", - :action => 'remote_login' - -remote.default_auth('login', true) diff --git a/man/rbot-remote.xml b/man/rbot-remote.xml deleted file mode 100644 index b68b4ef0..00000000 --- a/man/rbot-remote.xml +++ /dev/null @@ -1,217 +0,0 @@ - -.
will be generated. You may view the -manual page with: nroff -man .
| less'. A -typical entry in a Makefile or Makefile.am is: - -DB2MAN=/usr/share/sgml/docbook/stylesheet/xsl/nwalsh/\ -manpages/docbook.xsl -XP=xsltproc -''-nonet - -manpage.1: manpage.dbk - $(XP) $(DB2MAN) $< - -The xsltproc binary is found in the xsltproc package. The -XSL files are in docbook-xsl. Please remember that if you -create the nroff version in one of the debian/rules file -targets (such as build), you will need to include xsltproc -and docbook-xsl in your Build-Depends control field. - ---> - - - Marc"> - Dequènes"> - Giuseppe"> - Bilotta"> - - 20100701"> - - 1"> - Duck@DuckCorp.org"> - giuseppe.bilotta@gmail.com"> - - - RBOT-REMOTE"> - - - - - Debian"> - GNU"> - GPL"> -]> - - - - - &dhapp; - - - &dhfirstname; - &dhsurname; - &dhemail; - &debian; package maintainer - - - &gbgname; - &gbfname; - &gbemail; - &dhapp; maintainer - - - - 2004-2009 - &dhusername; - - - 2010 - &gbusername; - - &dhdate; - - - - &dhucapp; - &dhsection; - &dhapp; man page - &dhpackage; - &dhpackageversion; - - - - &dhapp; - - IRC bot written in ruby - - - - - &dhapp; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - DESCRIPTION - - &dhapp; is a proof-of-concept example for - rbot druby-based api. This program reads lines of text from the standard - input and sends them to a specified irc channel or user via rbot. - - - Make sure you have the remotectl plugin loaded and assigned the needed - rights to the user before use. - - - - - OPTIONS - - This program follow the usual &gnu; command line syntax, - with long options starting with two dashes (`-'). A summary of - options is included below. - - - - - - - Remote user. - - - - - - - - Remote user password. - - - - - - - - Destination for message (user or channel). - - - - - - - - Rbot url. - - - - - - - - Show summary of options. - - - - - - - - Tell what it's all about. - - - - - - VERSION - - This manual page was written by &dhusername; &dhemail; for - the &debian; system (but may be used by others). Permission is - granted to copy, distribute and/or modify this document under - the terms of the &gnu; General Public License, Version 3 or - any later version published by the Free Software Foundation. - - - On Debian systems, the complete text of the GNU General Public - License can be found in /usr/share/common-licenses/GPL. - - - - - diff --git a/rbot.gemspec b/rbot.gemspec index 5d563b53..29d88c1f 100644 --- a/rbot.gemspec +++ b/rbot.gemspec @@ -7,7 +7,7 @@ Gem::Specification.new do |s| s.description = <<-EOF A modular ruby IRC bot specifically designed for ease of extension via plugins. EOF - s.requirements << 'Ruby, version 1.8.0 (or newer)' + s.requirements << 'Ruby, version 1.9.3 (or newer)' s.files = FileList[ 'lib/**/*.rb', @@ -24,7 +24,6 @@ Gem::Specification.new do |s| 'INSTALL', 'Usage_en.txt', 'man/rbot.1', - 'man/rbot-remote.1', 'setup.rb', 'launch_here.rb', 'po/*.pot', @@ -32,7 +31,7 @@ Gem::Specification.new do |s| ] s.bindir = 'bin' - s.executables = ['rbot', 'rbot-remote'] + s.executables = ['rbot', 'rbotdb'] s.default_executable = 'rbot' s.extensions = 'Rakefile' -- cgit v1.2.3