lib/ermir/evil_registry.rb in ermir-0.1.1 vs lib/ermir/evil_registry.rb in ermir-0.1.2

- old
+ new

@@ -20,26 +20,26 @@ unless rmi_header_valid? Utils.print_rmi_transport_msg("Ermir received an invalid RMI protocol header from the remote peer.", @peeraddr, "red") return end Utils.print_rmi_transport_msg("received a valid RMI protocol header.", @peeraddr) + case @socket.getbyte + when TransportConstants::STREAM_PROTOCOL + @socket.putc(TransportConstants::PROTOCOL_ACK) + @socket.write([@peeraddr[-1].size].pack("S>")) + @socket.write(@peeraddr[-1]) + @socket.write([@peeraddr[1]].pack("L>")) + Utils.print_rmi_transport_msg("sent acknowledgement of the RMI connection to the remote peer.", @peeraddr) - @socket.putc(TransportConstants::PROTOCOL_ACK) - @socket.write([@peeraddr[-1].size].pack("S>")) - @socket.write(@peeraddr[-1]) - @socket.write([@peeraddr[1]].pack("L>")) - Utils.print_rmi_transport_msg("sent acknowledgement of the RMI connection to the remote peer.", @peeraddr) - - len = @socket.read(2).unpack("S>")[0] - rmi_server_ip = @socket.read(len) - rmi_server_port = @socket.read(4).unpack("L>")[0] - if rmi_server_port.zero? - Utils.print_rmi_transport_msg("the remote peer is an RMI Client.", @peeraddr) + # read and discard the endpoint + len = @socket.read(2).unpack("S>")[0] + rmi_server_ip = @socket.read(len) + rmi_server_port = @socket.read(4).unpack("L>")[0] + when TransportConstants::SINGLE_OP_PROTOCOL else - Utils.print_rmi_transport_msg("the remote peer is an RMI Server, listening for remote invocations @ #{rmi_server_ip}:#{rmi_server_port}.", @peeraddr) + Utils.print_rmi_transport_msg("received an invalid RMI protocol type.", @peeraddr, "red") end - unless rmi_message_valid? Utils.print_rmi_transport_msg("received an invalid RMI message.", @peeraddr, "red") return end Utils.print_rmi_transport_msg("received a valid RMI message header from remote peer.", @peeraddr) @@ -49,26 +49,29 @@ unless interface_hash.eql?(rmi_server_port.zero? ? TransportConstants::INTERFACE_STUB_HASH : TransportConstants::INTERFACE_SKEL_HASH) Utils.print_rmi_transport_msg("received an incorrect Registry interface hash.", @peeraddr, "red") return end - - ret = self.send("handle_#{TransportConstants::OPS[op]}") - if ret.is_a?(String) - Utils.print_rmi_transport_msg("error: #{ret}.", @peeraddr, "red") + if (0..4).include?(op) + ret = self.send("handle_#{TransportConstants::OPS[op]}") + if ret.is_a?(String) + Utils.print_rmi_transport_msg("error: #{ret}.", @peeraddr, "red") + end + else + Utils.print_rmi_transport_msg("error: received an invalid RMI CALL OP.", @peeraddr, "red") end + end def close_connection! @socket.close end private def rmi_header_valid? @socket.read(4).unpack("L>")[0].eql?(TransportConstants::MAGIC) \ - && @socket.read(2).unpack("S>")[0].eql?(TransportConstants::VERSION) \ - && @socket.getbyte.eql?(TransportConstants::STREAM_PROTOCOL) + && @socket.read(2).unpack("S>")[0].eql?(TransportConstants::VERSION) end def rmi_message_valid? @socket.getbyte.eql?(TransportConstants::CALL) \ && Utils.stream_header_valid?(@socket.read(4)) \ @@ -97,26 +100,39 @@ unless @socket.getbyte.eql?(TransportConstants::TC_STRING) return "received a corrupted RMI message" # first bind() arg is always TC_STRING end bind_key_size = @socket.read(2).unpack("S>")[0] bind_key = @socket.read(bind_key_size) - if @socket.getbyte.eql?(TransportConstants::TC_OBJECT) - if @socket.getbyte.eql?(TransportConstants::TC_PROXYCLASSDESC) + case @socket.getbyte + when TransportConstants::TC_OBJECT + case @socket.getbyte + when TransportConstants::TC_PROXYCLASSDESC interfaces_count = @socket.read(4).unpack("L>")[0] implemented_interfaces = [] interfaces_count.times do interface_name_size = @socket.read(2).unpack("S>")[0] return "the received interface name length exceeds the max length" if interface_name_size > 100 implemented_interfaces << @socket.read(interface_name_size) end if implemented_interfaces[0] == "java.rmi.Remote" - Utils.print_rmi_transport_msg("Ermir.#{rebind && 're'}bind(#{bind_key.inspect}, new <class (?) implements #{implemented_interfaces[1]}>()) was called by the remote peer.", @peeraddr) + Utils.print_rmi_transport_msg("Ermir.#{rebind && 're' || ''}bind(#{bind_key.inspect}, new <class (?) implements #{implemented_interfaces[1]}>()) was called by the remote peer.", @peeraddr) else - Utils.print_rmi_transport_msg("Ermir.#{rebind && 're'}bind(#{bind_key.inspect}, <java.lang.reflect.Proxy handling <#{implemented_interfaces*', '}> interfaces>) was called by the remote peer.", @peeraddr) + Utils.print_rmi_transport_msg("Ermir.#{rebind && 're' || ''}bind(#{bind_key.inspect}, <java.lang.reflect.Proxy handling <#{implemented_interfaces*', '}> interfaces>) was called by the remote peer.", @peeraddr) end + when TransportConstants::TC_CLASSDESC + class_name_size = @socket.read(2).unpack("S>")[0] + return "the received class name length exceeds the max length" if class_name_size > 100 + class_name = @socket.read(class_name_size) + if class_name == "com.sun.jndi.rmi.registry.ReferenceWrapper_Stub" + Utils.print_rmi_transport_msg("Ermir.#{rebind && 're' || ''}bind(#{bind_key.inspect}, Reference(\"className\")) was called by the remote peer.", @peeraddr) + else + Utils.print_rmi_transport_msg("Ermir.#{rebind && 're' || ''}bind(#{bind_key.inspect}, #{class_name}) was called by the remote peer.", @peeraddr) + end else - return "received a corrupted RMI message body" + return "received a corrupted/unimplemented RMI message body" end + else + return "received an corrupted/unimplemented object" end write_return_block normal_return: false write_object end