diff --git a/lib/drb/drb.rb b/lib/drb/drb.rb index 69456b1db2e9e0..c56bfe5f68a4a0 100644 --- a/lib/drb/drb.rb +++ b/lib/drb/drb.rb @@ -1437,10 +1437,16 @@ def run ] # Has a method been included in the list of insecure methods? - def insecure_method?(msg_id) - INSECURE_METHOD.include?(msg_id) + # Or, if a list of drb-safe methods has been defined for the + # front object, is this method not included in that list? + def insecure_method?(obj, msg_id) + INSECURE_METHOD.include?(msg_id) || + (obj.public_methods.include?(:drb_safe_methods_list) && + obj.public_methods.include?(msg_id) && + !obj.drb_safe_methods_list.include?(msg_id)) end + # Coerce an object to a string, providing our own representation if # to_s is not defined for the object. def any_to_s(obj) @@ -1460,7 +1466,7 @@ def any_to_s(obj) def check_insecure_method(obj, msg_id) return true if Proc === obj && msg_id == :__drb_yield raise(ArgumentError, "#{any_to_s(msg_id)} is not a symbol") unless Symbol == msg_id.class - raise(SecurityError, "insecure method `#{msg_id}'") if insecure_method?(msg_id) + raise(SecurityError, "insecure method `#{msg_id}'") if insecure_method?(obj, msg_id) if obj.private_methods.include?(msg_id) desc = any_to_s(obj) @@ -1768,6 +1774,31 @@ def fetch_server(uri) module_function :fetch_server end + +# Declare a list of methods to expose to DRb +# +# Allows the optional declaration of a whitelist of methods to expose +# through DRb for any class DRb will be sharing an instance of. If +# drb_safe_methods is used, then any attempt to call a non-whitelisted +# method on that class through DRb will fail. +# +# EXAMPLE USAGE: +# def MyClass +# drb_safe_methods :method1, :method2 +# end +# +# NOTE: if you are using irb as the client and :to_s isn't in the list, +# you will get a DRb::DRbConnError when you create the DRbObject, but only +# because irb calls to_s to display the result; the DRbObject is still +# usable. +class Class + def drb_safe_methods(*symbols) + define_method(:drb_safe_methods_list) do + symbols + end + end +end + # :stopdoc: DRbObject = DRb::DRbObject DRbUndumped = DRb::DRbUndumped