librex 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +4 -0
- data/lib/rex.rb +101 -0
- data/lib/rex.rb.ts.rb +70 -0
- data/lib/rex/LICENSE +29 -0
- data/lib/rex/arch.rb +103 -0
- data/lib/rex/arch/sparc.rb +75 -0
- data/lib/rex/arch/sparc.rb.ut.rb +18 -0
- data/lib/rex/arch/x86.rb +513 -0
- data/lib/rex/arch/x86.rb.ut.rb +93 -0
- data/lib/rex/assembly/nasm.rb +100 -0
- data/lib/rex/assembly/nasm.rb.ut.rb +22 -0
- data/lib/rex/codepage.map +104 -0
- data/lib/rex/compat.rb +281 -0
- data/lib/rex/constants.rb +113 -0
- data/lib/rex/elfparsey.rb +11 -0
- data/lib/rex/elfparsey/elf.rb +123 -0
- data/lib/rex/elfparsey/elfbase.rb +260 -0
- data/lib/rex/elfparsey/exceptions.rb +27 -0
- data/lib/rex/elfscan.rb +12 -0
- data/lib/rex/elfscan/scanner.rb +207 -0
- data/lib/rex/elfscan/search.rb +46 -0
- data/lib/rex/encoder/alpha2.rb +31 -0
- data/lib/rex/encoder/alpha2/alpha_mixed.rb +68 -0
- data/lib/rex/encoder/alpha2/alpha_upper.rb +79 -0
- data/lib/rex/encoder/alpha2/generic.rb +113 -0
- data/lib/rex/encoder/alpha2/unicode_mixed.rb +117 -0
- data/lib/rex/encoder/alpha2/unicode_upper.rb +129 -0
- data/lib/rex/encoder/ndr.rb +89 -0
- data/lib/rex/encoder/ndr.rb.ut.rb +44 -0
- data/lib/rex/encoder/nonalpha.rb +61 -0
- data/lib/rex/encoder/nonupper.rb +64 -0
- data/lib/rex/encoder/xdr.rb +106 -0
- data/lib/rex/encoder/xdr.rb.ut.rb +29 -0
- data/lib/rex/encoder/xor.rb +69 -0
- data/lib/rex/encoder/xor/dword.rb +13 -0
- data/lib/rex/encoder/xor/dword_additive.rb +13 -0
- data/lib/rex/encoders/xor_dword.rb +35 -0
- data/lib/rex/encoders/xor_dword_additive.rb +53 -0
- data/lib/rex/encoders/xor_dword_additive.rb.ut.rb +12 -0
- data/lib/rex/encoding/xor.rb +20 -0
- data/lib/rex/encoding/xor.rb.ts.rb +14 -0
- data/lib/rex/encoding/xor/byte.rb +15 -0
- data/lib/rex/encoding/xor/byte.rb.ut.rb +21 -0
- data/lib/rex/encoding/xor/dword.rb +21 -0
- data/lib/rex/encoding/xor/dword.rb.ut.rb +15 -0
- data/lib/rex/encoding/xor/dword_additive.rb +92 -0
- data/lib/rex/encoding/xor/dword_additive.rb.ut.rb +15 -0
- data/lib/rex/encoding/xor/exceptions.rb +17 -0
- data/lib/rex/encoding/xor/generic.rb +146 -0
- data/lib/rex/encoding/xor/generic.rb.ut.rb +120 -0
- data/lib/rex/encoding/xor/qword.rb +15 -0
- data/lib/rex/encoding/xor/word.rb +21 -0
- data/lib/rex/encoding/xor/word.rb.ut.rb +13 -0
- data/lib/rex/exceptions.rb +275 -0
- data/lib/rex/exceptions.rb.ut.rb +44 -0
- data/lib/rex/exploitation/cmdstager.rb +133 -0
- data/lib/rex/exploitation/egghunter.rb +143 -0
- data/lib/rex/exploitation/egghunter.rb.ut.rb +25 -0
- data/lib/rex/exploitation/encryptjs.rb +77 -0
- data/lib/rex/exploitation/heaplib.js.b64 +331 -0
- data/lib/rex/exploitation/heaplib.rb +94 -0
- data/lib/rex/exploitation/javascriptosdetect.rb +735 -0
- data/lib/rex/exploitation/obfuscatejs.rb +335 -0
- data/lib/rex/exploitation/opcodedb.rb +818 -0
- data/lib/rex/exploitation/opcodedb.rb.ut.rb +279 -0
- data/lib/rex/exploitation/seh.rb +92 -0
- data/lib/rex/exploitation/seh.rb.ut.rb +19 -0
- data/lib/rex/file.rb +84 -0
- data/lib/rex/file.rb.ut.rb +16 -0
- data/lib/rex/image_source.rb +12 -0
- data/lib/rex/image_source/disk.rb +60 -0
- data/lib/rex/image_source/image_source.rb +46 -0
- data/lib/rex/image_source/memory.rb +37 -0
- data/lib/rex/io/bidirectional_pipe.rb +157 -0
- data/lib/rex/io/datagram_abstraction.rb +35 -0
- data/lib/rex/io/stream.rb +313 -0
- data/lib/rex/io/stream_abstraction.rb +186 -0
- data/lib/rex/io/stream_server.rb +211 -0
- data/lib/rex/job_container.rb +202 -0
- data/lib/rex/logging.rb +4 -0
- data/lib/rex/logging/log_dispatcher.rb +179 -0
- data/lib/rex/logging/log_sink.rb +42 -0
- data/lib/rex/logging/sinks/flatfile.rb +55 -0
- data/lib/rex/logging/sinks/stderr.rb +43 -0
- data/lib/rex/machparsey.rb +9 -0
- data/lib/rex/machparsey/exceptions.rb +34 -0
- data/lib/rex/machparsey/mach.rb +209 -0
- data/lib/rex/machparsey/machbase.rb +408 -0
- data/lib/rex/machscan.rb +9 -0
- data/lib/rex/machscan/scanner.rb +217 -0
- data/lib/rex/mime.rb +9 -0
- data/lib/rex/mime/header.rb +75 -0
- data/lib/rex/mime/message.rb +112 -0
- data/lib/rex/mime/part.rb +20 -0
- data/lib/rex/nop/opty2.rb +108 -0
- data/lib/rex/nop/opty2.rb.ut.rb +23 -0
- data/lib/rex/nop/opty2_tables.rb +300 -0
- data/lib/rex/ole.rb +128 -0
- data/lib/rex/ole/clsid.rb +47 -0
- data/lib/rex/ole/difat.rb +141 -0
- data/lib/rex/ole/directory.rb +230 -0
- data/lib/rex/ole/direntry.rb +240 -0
- data/lib/rex/ole/fat.rb +99 -0
- data/lib/rex/ole/header.rb +204 -0
- data/lib/rex/ole/minifat.rb +77 -0
- data/lib/rex/ole/samples/create_ole.rb +27 -0
- data/lib/rex/ole/samples/dir.rb +35 -0
- data/lib/rex/ole/samples/dump_stream.rb +34 -0
- data/lib/rex/ole/samples/ole_info.rb +23 -0
- data/lib/rex/ole/storage.rb +395 -0
- data/lib/rex/ole/stream.rb +53 -0
- data/lib/rex/ole/substorage.rb +49 -0
- data/lib/rex/ole/util.rb +157 -0
- data/lib/rex/parser/arguments.rb +97 -0
- data/lib/rex/parser/arguments.rb.ut.rb +67 -0
- data/lib/rex/parser/ini.rb +185 -0
- data/lib/rex/parser/ini.rb.ut.rb +29 -0
- data/lib/rex/parser/nmap_xml.rb +111 -0
- data/lib/rex/payloads.rb +1 -0
- data/lib/rex/payloads/win32.rb +2 -0
- data/lib/rex/payloads/win32/common.rb +26 -0
- data/lib/rex/payloads/win32/kernel.rb +53 -0
- data/lib/rex/payloads/win32/kernel/common.rb +54 -0
- data/lib/rex/payloads/win32/kernel/migration.rb +12 -0
- data/lib/rex/payloads/win32/kernel/recovery.rb +50 -0
- data/lib/rex/payloads/win32/kernel/stager.rb +171 -0
- data/lib/rex/peparsey.rb +12 -0
- data/lib/rex/peparsey/exceptions.rb +32 -0
- data/lib/rex/peparsey/pe.rb +188 -0
- data/lib/rex/peparsey/pe_memdump.rb +63 -0
- data/lib/rex/peparsey/pebase.rb +1655 -0
- data/lib/rex/peparsey/section.rb +136 -0
- data/lib/rex/pescan.rb +13 -0
- data/lib/rex/pescan/analyze.rb +309 -0
- data/lib/rex/pescan/scanner.rb +206 -0
- data/lib/rex/pescan/search.rb +56 -0
- data/lib/rex/platforms.rb +1 -0
- data/lib/rex/platforms/windows.rb +51 -0
- data/lib/rex/poly.rb +132 -0
- data/lib/rex/poly/block.rb +468 -0
- data/lib/rex/poly/register.rb +100 -0
- data/lib/rex/poly/register/x86.rb +40 -0
- data/lib/rex/post.rb +8 -0
- data/lib/rex/post/dir.rb +51 -0
- data/lib/rex/post/file.rb +172 -0
- data/lib/rex/post/file_stat.rb +220 -0
- data/lib/rex/post/gen.pl +13 -0
- data/lib/rex/post/io.rb +182 -0
- data/lib/rex/post/meterpreter.rb +4 -0
- data/lib/rex/post/meterpreter/channel.rb +438 -0
- data/lib/rex/post/meterpreter/channel_container.rb +54 -0
- data/lib/rex/post/meterpreter/channels/pool.rb +160 -0
- data/lib/rex/post/meterpreter/channels/pools/file.rb +62 -0
- data/lib/rex/post/meterpreter/channels/pools/stream_pool.rb +103 -0
- data/lib/rex/post/meterpreter/channels/stream.rb +87 -0
- data/lib/rex/post/meterpreter/client.rb +335 -0
- data/lib/rex/post/meterpreter/client_core.rb +274 -0
- data/lib/rex/post/meterpreter/dependencies.rb +3 -0
- data/lib/rex/post/meterpreter/extension.rb +32 -0
- data/lib/rex/post/meterpreter/extensions/espia/espia.rb +58 -0
- data/lib/rex/post/meterpreter/extensions/espia/tlv.rb +16 -0
- data/lib/rex/post/meterpreter/extensions/incognito/incognito.rb +94 -0
- data/lib/rex/post/meterpreter/extensions/incognito/tlv.rb +21 -0
- data/lib/rex/post/meterpreter/extensions/priv/fs.rb +118 -0
- data/lib/rex/post/meterpreter/extensions/priv/passwd.rb +61 -0
- data/lib/rex/post/meterpreter/extensions/priv/priv.rb +104 -0
- data/lib/rex/post/meterpreter/extensions/priv/tlv.rb +28 -0
- data/lib/rex/post/meterpreter/extensions/sniffer/sniffer.rb +100 -0
- data/lib/rex/post/meterpreter/extensions/sniffer/tlv.rb +24 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/constants.rb +333 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/fs/dir.rb +273 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb +235 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/fs/file_stat.rb +103 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/fs/io.rb +48 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/net/config.rb +144 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/net/interface.rb +73 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/net/route.rb +56 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/net/socket.rb +137 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_client_channel.rb +167 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_server_channel.rb +167 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/udp_channel.rb +192 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/stdapi.rb +139 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/config.rb +97 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/event_log.rb +184 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/event_log_subsystem/event_record.rb +41 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/power.rb +61 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb +361 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/image.rb +129 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/io.rb +55 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/memory.rb +336 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/thread.rb +141 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb +279 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_key.rb +182 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_value.rb +102 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/thread.rb +174 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb +185 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/ui.rb +227 -0
- data/lib/rex/post/meterpreter/inbound_packet_handler.rb +30 -0
- data/lib/rex/post/meterpreter/object_aliases.rb +83 -0
- data/lib/rex/post/meterpreter/packet.rb +596 -0
- data/lib/rex/post/meterpreter/packet_dispatcher.rb +409 -0
- data/lib/rex/post/meterpreter/packet_parser.rb +94 -0
- data/lib/rex/post/meterpreter/packet_response_waiter.rb +83 -0
- data/lib/rex/post/meterpreter/ui/console.rb +135 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher.rb +62 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +595 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/espia.rb +108 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/incognito.rb +241 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv.rb +61 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/elevate.rb +98 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/passwd.rb +51 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/timestomp.rb +132 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/sniffer.rb +187 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi.rb +63 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +376 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/net.rb +270 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys.rb +484 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb +315 -0
- data/lib/rex/post/meterpreter/ui/console/interactive_channel.rb +95 -0
- data/lib/rex/post/permission.rb +26 -0
- data/lib/rex/post/process.rb +57 -0
- data/lib/rex/post/thread.rb +57 -0
- data/lib/rex/post/ui.rb +52 -0
- data/lib/rex/proto.rb +12 -0
- data/lib/rex/proto.rb.ts.rb +8 -0
- data/lib/rex/proto/dcerpc.rb +6 -0
- data/lib/rex/proto/dcerpc.rb.ts.rb +9 -0
- data/lib/rex/proto/dcerpc/client.rb +358 -0
- data/lib/rex/proto/dcerpc/client.rb.ut.rb +491 -0
- data/lib/rex/proto/dcerpc/exceptions.rb +150 -0
- data/lib/rex/proto/dcerpc/handle.rb +47 -0
- data/lib/rex/proto/dcerpc/handle.rb.ut.rb +85 -0
- data/lib/rex/proto/dcerpc/ndr.rb +72 -0
- data/lib/rex/proto/dcerpc/ndr.rb.ut.rb +41 -0
- data/lib/rex/proto/dcerpc/packet.rb +253 -0
- data/lib/rex/proto/dcerpc/packet.rb.ut.rb +56 -0
- data/lib/rex/proto/dcerpc/response.rb +186 -0
- data/lib/rex/proto/dcerpc/response.rb.ut.rb +15 -0
- data/lib/rex/proto/dcerpc/uuid.rb +84 -0
- data/lib/rex/proto/dcerpc/uuid.rb.ut.rb +46 -0
- data/lib/rex/proto/drda.rb +5 -0
- data/lib/rex/proto/drda.rb.ts.rb +17 -0
- data/lib/rex/proto/drda/constants.rb +49 -0
- data/lib/rex/proto/drda/constants.rb.ut.rb +23 -0
- data/lib/rex/proto/drda/packet.rb +252 -0
- data/lib/rex/proto/drda/packet.rb.ut.rb +109 -0
- data/lib/rex/proto/drda/utils.rb +123 -0
- data/lib/rex/proto/drda/utils.rb.ut.rb +84 -0
- data/lib/rex/proto/http.rb +5 -0
- data/lib/rex/proto/http.rb.ts.rb +12 -0
- data/lib/rex/proto/http/client.rb +817 -0
- data/lib/rex/proto/http/client.rb.ut.rb +93 -0
- data/lib/rex/proto/http/handler.rb +46 -0
- data/lib/rex/proto/http/handler/erb.rb +128 -0
- data/lib/rex/proto/http/handler/erb.rb.ut.rb +21 -0
- data/lib/rex/proto/http/handler/erb.rb.ut.rb.rhtml +1 -0
- data/lib/rex/proto/http/handler/proc.rb +54 -0
- data/lib/rex/proto/http/handler/proc.rb.ut.rb +24 -0
- data/lib/rex/proto/http/header.rb +161 -0
- data/lib/rex/proto/http/header.rb.ut.rb +46 -0
- data/lib/rex/proto/http/packet.rb +394 -0
- data/lib/rex/proto/http/packet.rb.ut.rb +165 -0
- data/lib/rex/proto/http/request.rb +356 -0
- data/lib/rex/proto/http/request.rb.ut.rb +214 -0
- data/lib/rex/proto/http/response.rb +85 -0
- data/lib/rex/proto/http/response.rb.ut.rb +149 -0
- data/lib/rex/proto/http/server.rb +367 -0
- data/lib/rex/proto/http/server.rb.ut.rb +79 -0
- data/lib/rex/proto/smb.rb +7 -0
- data/lib/rex/proto/smb.rb.ts.rb +8 -0
- data/lib/rex/proto/smb/client.rb +1733 -0
- data/lib/rex/proto/smb/client.rb.ut.rb +223 -0
- data/lib/rex/proto/smb/constants.rb +1062 -0
- data/lib/rex/proto/smb/constants.rb.ut.rb +18 -0
- data/lib/rex/proto/smb/crypt.rb +95 -0
- data/lib/rex/proto/smb/crypt.rb.ut.rb +20 -0
- data/lib/rex/proto/smb/evasions.rb +65 -0
- data/lib/rex/proto/smb/exceptions.rb +846 -0
- data/lib/rex/proto/smb/simpleclient.rb +292 -0
- data/lib/rex/proto/smb/simpleclient.rb.ut.rb +128 -0
- data/lib/rex/proto/smb/utils.rb +514 -0
- data/lib/rex/proto/smb/utils.rb.ut.rb +20 -0
- data/lib/rex/proto/sunrpc.rb +1 -0
- data/lib/rex/proto/sunrpc/client.rb +195 -0
- data/lib/rex/script.rb +42 -0
- data/lib/rex/script/base.rb +59 -0
- data/lib/rex/script/meterpreter.rb +9 -0
- data/lib/rex/script/shell.rb +9 -0
- data/lib/rex/service.rb +48 -0
- data/lib/rex/service_manager.rb +141 -0
- data/lib/rex/service_manager.rb.ut.rb +32 -0
- data/lib/rex/services/local_relay.rb +423 -0
- data/lib/rex/socket.rb +586 -0
- data/lib/rex/socket.rb.ut.rb +86 -0
- data/lib/rex/socket/comm.rb +119 -0
- data/lib/rex/socket/comm/local.rb +409 -0
- data/lib/rex/socket/comm/local.rb.ut.rb +75 -0
- data/lib/rex/socket/ip.rb +129 -0
- data/lib/rex/socket/parameters.rb +345 -0
- data/lib/rex/socket/parameters.rb.ut.rb +51 -0
- data/lib/rex/socket/range_walker.rb +295 -0
- data/lib/rex/socket/range_walker.rb.ut.rb +55 -0
- data/lib/rex/socket/ssl_tcp.rb +184 -0
- data/lib/rex/socket/ssl_tcp.rb.ut.rb +39 -0
- data/lib/rex/socket/ssl_tcp_server.rb +122 -0
- data/lib/rex/socket/ssl_tcp_server.rb.ut.rb +51 -0
- data/lib/rex/socket/subnet_walker.rb +75 -0
- data/lib/rex/socket/subnet_walker.rb.ut.rb +28 -0
- data/lib/rex/socket/switch_board.rb +272 -0
- data/lib/rex/socket/switch_board.rb.ut.rb +52 -0
- data/lib/rex/socket/tcp.rb +76 -0
- data/lib/rex/socket/tcp.rb.ut.rb +64 -0
- data/lib/rex/socket/tcp_server.rb +67 -0
- data/lib/rex/socket/tcp_server.rb.ut.rb +44 -0
- data/lib/rex/socket/udp.rb +157 -0
- data/lib/rex/socket/udp.rb.ut.rb +44 -0
- data/lib/rex/struct2.rb +5 -0
- data/lib/rex/struct2/c_struct.rb +181 -0
- data/lib/rex/struct2/c_struct_template.rb +39 -0
- data/lib/rex/struct2/constant.rb +26 -0
- data/lib/rex/struct2/element.rb +44 -0
- data/lib/rex/struct2/generic.rb +73 -0
- data/lib/rex/struct2/restraint.rb +54 -0
- data/lib/rex/struct2/s_string.rb +72 -0
- data/lib/rex/struct2/s_struct.rb +111 -0
- data/lib/rex/sync.rb +6 -0
- data/lib/rex/sync/event.rb +94 -0
- data/lib/rex/sync/read_write_lock.rb +176 -0
- data/lib/rex/sync/ref.rb +57 -0
- data/lib/rex/sync/thread_safe.rb +82 -0
- data/lib/rex/test.rb +35 -0
- data/lib/rex/text.rb +1029 -0
- data/lib/rex/text.rb.ut.rb +168 -0
- data/lib/rex/time.rb +65 -0
- data/lib/rex/transformer.rb +115 -0
- data/lib/rex/transformer.rb.ut.rb +38 -0
- data/lib/rex/ui.rb +21 -0
- data/lib/rex/ui/interactive.rb +252 -0
- data/lib/rex/ui/output.rb +80 -0
- data/lib/rex/ui/output/none.rb +18 -0
- data/lib/rex/ui/progress_tracker.rb +96 -0
- data/lib/rex/ui/subscriber.rb +149 -0
- data/lib/rex/ui/text/color.rb +97 -0
- data/lib/rex/ui/text/color.rb.ut.rb +18 -0
- data/lib/rex/ui/text/dispatcher_shell.rb +382 -0
- data/lib/rex/ui/text/input.rb +117 -0
- data/lib/rex/ui/text/input/buffer.rb +75 -0
- data/lib/rex/ui/text/input/readline.rb +129 -0
- data/lib/rex/ui/text/input/socket.rb +95 -0
- data/lib/rex/ui/text/input/stdio.rb +45 -0
- data/lib/rex/ui/text/irb_shell.rb +55 -0
- data/lib/rex/ui/text/output.rb +80 -0
- data/lib/rex/ui/text/output/buffer.rb +65 -0
- data/lib/rex/ui/text/output/file.rb +37 -0
- data/lib/rex/ui/text/output/socket.rb +43 -0
- data/lib/rex/ui/text/output/stdio.rb +40 -0
- data/lib/rex/ui/text/progress_tracker.rb +56 -0
- data/lib/rex/ui/text/progress_tracker.rb.ut.rb +34 -0
- data/lib/rex/ui/text/shell.rb +321 -0
- data/lib/rex/ui/text/table.rb +254 -0
- data/lib/rex/ui/text/table.rb.ut.rb +55 -0
- data/lib/rex/zip.rb +93 -0
- data/lib/rex/zip/archive.rb +91 -0
- data/lib/rex/zip/blocks.rb +182 -0
- data/lib/rex/zip/entry.rb +95 -0
- data/lib/rex/zip/samples/comment.rb +32 -0
- data/lib/rex/zip/samples/mkwar.rb +138 -0
- data/lib/rex/zip/samples/mkzip.rb +19 -0
- data/lib/rex/zip/samples/recursive.rb +58 -0
- metadata +435 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
require 'rex/proto/http'
|
|
2
|
+
|
|
3
|
+
module Rex
|
|
4
|
+
module Proto
|
|
5
|
+
module Http
|
|
6
|
+
|
|
7
|
+
###
|
|
8
|
+
#
|
|
9
|
+
# HTTP response class.
|
|
10
|
+
#
|
|
11
|
+
###
|
|
12
|
+
class Response < Packet
|
|
13
|
+
|
|
14
|
+
##
|
|
15
|
+
#
|
|
16
|
+
# Builtin response class wrappers.
|
|
17
|
+
#
|
|
18
|
+
##
|
|
19
|
+
|
|
20
|
+
#
|
|
21
|
+
# HTTP 200/OK response class wrapper.
|
|
22
|
+
#
|
|
23
|
+
class OK < Response
|
|
24
|
+
def initialize(message = 'OK', proto = DefaultProtocol)
|
|
25
|
+
super(200, message, proto)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
#
|
|
30
|
+
# HTTP 404/File not found response class wrapper.
|
|
31
|
+
#
|
|
32
|
+
class E404 < Response
|
|
33
|
+
def initialize(message = 'File not found', proto = DefaultProtocol)
|
|
34
|
+
super(404, message, proto)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
#
|
|
39
|
+
# Constructage of the HTTP response with the supplied code, message, and
|
|
40
|
+
# protocol.
|
|
41
|
+
#
|
|
42
|
+
def initialize(code = 200, message = 'OK', proto = DefaultProtocol)
|
|
43
|
+
super()
|
|
44
|
+
|
|
45
|
+
self.code = code.to_i
|
|
46
|
+
self.message = message
|
|
47
|
+
self.proto = proto
|
|
48
|
+
|
|
49
|
+
# Default responses to auto content length on
|
|
50
|
+
self.auto_cl = true
|
|
51
|
+
|
|
52
|
+
# default chunk sizes (if chunked is used)
|
|
53
|
+
self.chunk_min_size = 1
|
|
54
|
+
self.chunk_max_size = 10
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
#
|
|
58
|
+
# Updates the various parts of the HTTP response command string.
|
|
59
|
+
#
|
|
60
|
+
def update_cmd_parts(str)
|
|
61
|
+
if (md = str.match(/HTTP\/(.+?)\s+(\d+)\s?(.+?)\r?\n?$/))
|
|
62
|
+
self.message = md[3].gsub(/\r/, '')
|
|
63
|
+
self.code = md[2].to_i
|
|
64
|
+
self.proto = md[1]
|
|
65
|
+
else
|
|
66
|
+
raise RuntimeError, "Invalid response command string", caller
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
#
|
|
71
|
+
# Returns the response based command string.
|
|
72
|
+
#
|
|
73
|
+
def cmd_string
|
|
74
|
+
"HTTP\/#{proto} #{code}#{(message and message.length > 0) ? ' ' + message : ''}\r\n"
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
attr_accessor :code
|
|
78
|
+
attr_accessor :message
|
|
79
|
+
attr_accessor :proto
|
|
80
|
+
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
$:.unshift(File.join(File.dirname(__FILE__), '..', '..', '..'))
|
|
4
|
+
|
|
5
|
+
require 'test/unit'
|
|
6
|
+
require 'rex/proto/http'
|
|
7
|
+
|
|
8
|
+
class Rex::Proto::Http::Response::UnitTest < Test::Unit::TestCase
|
|
9
|
+
|
|
10
|
+
Klass = Rex::Proto::Http::Response
|
|
11
|
+
|
|
12
|
+
def test_deflate
|
|
13
|
+
h = Klass.new
|
|
14
|
+
h.body = 'hi mom'
|
|
15
|
+
h.compress = 'deflate'
|
|
16
|
+
assert_equal(
|
|
17
|
+
"HTTP/1.1 200 OK\r\n" +
|
|
18
|
+
"Content-Length: 14\r\n" +
|
|
19
|
+
"Content-Encoding: deflate\r\n\r\n" +
|
|
20
|
+
"x\234\313\310T\310\315\317\005\000\a\225\002;",
|
|
21
|
+
h.to_s, 'deflate'
|
|
22
|
+
)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def test_gzip
|
|
26
|
+
h = Klass.new
|
|
27
|
+
h.body = 'hi mom'
|
|
28
|
+
h.compress = 'gzip'
|
|
29
|
+
srand(0)
|
|
30
|
+
|
|
31
|
+
response = h.to_s
|
|
32
|
+
|
|
33
|
+
http_header = response.slice!(0,63)
|
|
34
|
+
|
|
35
|
+
assert_equal(
|
|
36
|
+
"HTTP/1.1 200 OK\r\n" +
|
|
37
|
+
"Content-Length: 26\r\n"+
|
|
38
|
+
"Content-Encoding: gzip\r\n\r\n",
|
|
39
|
+
http_header, 'http headers'
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
assert_equal("\x1f\x8b\x08\x00", response.slice!(0,4), 'gzip headers')
|
|
43
|
+
|
|
44
|
+
# skip the next 6 bytes as it is host & time specific (zlib's example gun does, so why not us too?)
|
|
45
|
+
response.slice!(0,6)
|
|
46
|
+
|
|
47
|
+
assert_equal("\xcb\xc8\x54\xc8\xcd\xcf\x05\x00\x68\xa4\x1c\xf0\x06\x00\x00\x00", response, 'gzip data')
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def test_to_s
|
|
52
|
+
h = Klass.new
|
|
53
|
+
|
|
54
|
+
h.headers['Foo'] = 'Fishing'
|
|
55
|
+
h.headers['Chicken'] = 47
|
|
56
|
+
|
|
57
|
+
assert_equal(
|
|
58
|
+
"HTTP/1.1 200 OK\r\n" +
|
|
59
|
+
"Content-Length: 0\r\n" +
|
|
60
|
+
"Foo: Fishing\r\n" +
|
|
61
|
+
"Chicken: 47\r\n\r\n", h.to_s, 'to_s w/o body')
|
|
62
|
+
|
|
63
|
+
h.body = 'hi mom'
|
|
64
|
+
assert_equal(
|
|
65
|
+
"HTTP/1.1 200 OK\r\n" +
|
|
66
|
+
"Content-Length: 6\r\n" +
|
|
67
|
+
"Foo: Fishing\r\n" +
|
|
68
|
+
"Chicken: 47\r\n\r\nhi mom", h.to_s, 'to_s w/ body')
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def test_chunked
|
|
73
|
+
h = Klass.new
|
|
74
|
+
|
|
75
|
+
h.headers['Foo'] = 'Fishing'
|
|
76
|
+
h.headers['Chicken'] = 47
|
|
77
|
+
h.auto_cl = false
|
|
78
|
+
h.transfer_chunked = true
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
assert_equal(
|
|
82
|
+
"HTTP/1.1 200 OK\r\n" +
|
|
83
|
+
"Transfer-Encoding: chunked\r\n" +
|
|
84
|
+
"Foo: Fishing\r\n" +
|
|
85
|
+
"Chicken: 47\r\n\r\n0\r\n\r\n", h.to_s, 'chunked w/o body'
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
srand(0)
|
|
89
|
+
h.body = Rex::Text.rand_text_alphanumeric(100)
|
|
90
|
+
assert_equal(
|
|
91
|
+
"HTTP/1.1 200 OK\r\n" +
|
|
92
|
+
"Transfer-Encoding: chunked\r\n" +
|
|
93
|
+
"Foo: Fishing\r\n" +
|
|
94
|
+
"Chicken: 47\r\n\r\n" +
|
|
95
|
+
"5\r\nsv1AD\r\n7\r\n7DnJTVy\r\n5\r\nkXGYY\r\n5\r\nM6Bmn\r\n4\r\nXuYR\r\n5\r\nlZNIJ\r\n5\r\nUzQzF\r\n9\r\nPvASjYxzd\r\n5\r\nTTOng\r\n4\r\nBJ5g\r\n8\r\nfK0XjLy3\r\n6\r\nciAAk1\r\n6\r\nFmo0RP\r\n1\r\nE\r\n2\r\npq\r\n6\r\n6f4BBn\r\n4\r\np5jm\r\n1\r\n3\r\n6\r\nLuSbAO\r\n1\r\nj\r\n2\r\n1M\r\n3\r\n5qU\r\n0\r\n\r\n",
|
|
96
|
+
h.to_s, 'random chunk sizes'
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
h.chunk_max_size = 1
|
|
100
|
+
h.body = 'hi mom'
|
|
101
|
+
assert_equal(
|
|
102
|
+
"HTTP/1.1 200 OK\r\n" +
|
|
103
|
+
"Transfer-Encoding: chunked\r\n" +
|
|
104
|
+
"Foo: Fishing\r\n" +
|
|
105
|
+
"Chicken: 47\r\n\r\n" +
|
|
106
|
+
"1\r\nh\r\n1\r\ni\r\n1\r\n \r\n1\r\nm\r\n1\r\no\r\n1\r\nm\r\n0\r\n\r\n",
|
|
107
|
+
h.to_s, '1 byte chunks'
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
h.chunk_min_size = 2
|
|
111
|
+
assert_equal(
|
|
112
|
+
"HTTP/1.1 200 OK\r\n" +
|
|
113
|
+
"Transfer-Encoding: chunked\r\n" +
|
|
114
|
+
"Foo: Fishing\r\n" +
|
|
115
|
+
"Chicken: 47\r\n\r\n" +
|
|
116
|
+
"2\r\nhi\r\n2\r\n m\r\n2\r\nom\r\n0\r\n\r\n",
|
|
117
|
+
h.to_s, '2 byte chunks'
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
h = Klass.new(200, 'OK', '1.0')
|
|
121
|
+
h.body = 'hi mom'
|
|
122
|
+
h.auto_cl = false
|
|
123
|
+
h.transfer_chunked = true
|
|
124
|
+
assert_raise(Rex::RuntimeError, 'chunked encoding via 1.0') {
|
|
125
|
+
h.to_s
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def test_from_s
|
|
131
|
+
h = Klass.new
|
|
132
|
+
|
|
133
|
+
h.from_s(
|
|
134
|
+
"HTTP/1.0 404 File not found\r\n" +
|
|
135
|
+
"Lucifer: Beast\r\n" +
|
|
136
|
+
"HoHo: Satan\r\n" +
|
|
137
|
+
"Eat: Babies\r\n" +
|
|
138
|
+
"\r\n")
|
|
139
|
+
|
|
140
|
+
assert_equal(404, h.code)
|
|
141
|
+
assert_equal('File not found', h.message)
|
|
142
|
+
assert_equal('1.0', h.proto)
|
|
143
|
+
assert_equal("HTTP/1.0 404 File not found\r\n", h.cmd_string)
|
|
144
|
+
h.code = 470
|
|
145
|
+
assert_equal("HTTP/1.0 470 File not found\r\n", h.cmd_string)
|
|
146
|
+
assert_equal('Babies', h['Eat'])
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
end
|
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
require 'rex/socket'
|
|
2
|
+
require 'rex/proto/http'
|
|
3
|
+
require 'rex/proto/http/handler'
|
|
4
|
+
|
|
5
|
+
module Rex
|
|
6
|
+
module Proto
|
|
7
|
+
module Http
|
|
8
|
+
|
|
9
|
+
###
|
|
10
|
+
#
|
|
11
|
+
# Runtime extension of the HTTP clients that connect to the server.
|
|
12
|
+
#
|
|
13
|
+
###
|
|
14
|
+
module ServerClient
|
|
15
|
+
|
|
16
|
+
#
|
|
17
|
+
# Initialize a new request instance.
|
|
18
|
+
#
|
|
19
|
+
def init_cli(server)
|
|
20
|
+
self.request = Request.new
|
|
21
|
+
self.server = server
|
|
22
|
+
self.keepalive = false
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
#
|
|
26
|
+
# Resets the parsing state.
|
|
27
|
+
#
|
|
28
|
+
def reset_cli
|
|
29
|
+
self.request.reset
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
#
|
|
33
|
+
# Transmits a response and adds the appropriate headers.
|
|
34
|
+
#
|
|
35
|
+
def send_response(response)
|
|
36
|
+
# Set the connection to close or keep-alive depending on what the client
|
|
37
|
+
# can support.
|
|
38
|
+
response['Connection'] = (keepalive) ? 'Keep-Alive' : 'close'
|
|
39
|
+
|
|
40
|
+
# Add any other standard response headers.
|
|
41
|
+
server.add_response_headers(response)
|
|
42
|
+
|
|
43
|
+
# Send it off.
|
|
44
|
+
put(response.to_s)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
#
|
|
48
|
+
# The current request context.
|
|
49
|
+
#
|
|
50
|
+
attr_accessor :request
|
|
51
|
+
#
|
|
52
|
+
# Boolean that indicates whether or not the connection supports keep-alive.
|
|
53
|
+
#
|
|
54
|
+
attr_accessor :keepalive
|
|
55
|
+
#
|
|
56
|
+
# A reference to the server the client is associated with.
|
|
57
|
+
#
|
|
58
|
+
attr_accessor :server
|
|
59
|
+
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
###
|
|
63
|
+
#
|
|
64
|
+
# Acts as an HTTP server, processing requests and dispatching them to
|
|
65
|
+
# registered procs. Some of this server was modeled after webrick.
|
|
66
|
+
#
|
|
67
|
+
###
|
|
68
|
+
class Server
|
|
69
|
+
|
|
70
|
+
include Proto
|
|
71
|
+
|
|
72
|
+
#
|
|
73
|
+
# A hash that associated a file extension with a mime type for use as the
|
|
74
|
+
# content type of responses.
|
|
75
|
+
#
|
|
76
|
+
ExtensionMimeTypes =
|
|
77
|
+
{
|
|
78
|
+
"rhtml" => "text/html",
|
|
79
|
+
"html" => "text/html",
|
|
80
|
+
"htm" => "text/htm",
|
|
81
|
+
"jpg" => "image/jpeg",
|
|
82
|
+
"jpeg" => "image/jpeg",
|
|
83
|
+
"jpeg" => "image/jpeg",
|
|
84
|
+
"gif" => "image/gif",
|
|
85
|
+
"png" => "image/png",
|
|
86
|
+
"bmp" => "image/bmp",
|
|
87
|
+
"txt" => "text/plain",
|
|
88
|
+
"css" => "text/css",
|
|
89
|
+
"ico" => "image/x-icon",
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
#
|
|
93
|
+
# The default server name that will be returned in the Server attribute of
|
|
94
|
+
# a response.
|
|
95
|
+
#
|
|
96
|
+
DefaultServer = "Rex"
|
|
97
|
+
|
|
98
|
+
#
|
|
99
|
+
# Initializes an HTTP server as listening on the provided port and
|
|
100
|
+
# hostname.
|
|
101
|
+
#
|
|
102
|
+
def initialize(port = 80, listen_host = '0.0.0.0', ssl = false, context = {})
|
|
103
|
+
self.listen_host = listen_host
|
|
104
|
+
self.listen_port = port
|
|
105
|
+
self.context = context
|
|
106
|
+
self.listener = nil
|
|
107
|
+
self.resources = {}
|
|
108
|
+
self.server_name = DefaultServer
|
|
109
|
+
self.ssl = ssl
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
#
|
|
113
|
+
# Returns the hardcore alias for the HTTP service
|
|
114
|
+
#
|
|
115
|
+
def self.hardcore_alias(*args)
|
|
116
|
+
"#{(args[0] || '')}#{(args[1] || '')}"
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
#
|
|
120
|
+
# HTTP server.
|
|
121
|
+
#
|
|
122
|
+
def alias
|
|
123
|
+
super || "HTTP Server"
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
#
|
|
127
|
+
# Listens on the defined port and host and starts monitoring for clients.
|
|
128
|
+
#
|
|
129
|
+
def start
|
|
130
|
+
|
|
131
|
+
self.listener = Rex::Socket::TcpServer.create(
|
|
132
|
+
'LocalHost' => self.listen_host,
|
|
133
|
+
'LocalPort' => self.listen_port,
|
|
134
|
+
'Context' => self.context,
|
|
135
|
+
'SSL' => self.ssl
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
# Register callbacks
|
|
139
|
+
self.listener.on_client_connect_proc = Proc.new { |cli|
|
|
140
|
+
on_client_connect(cli)
|
|
141
|
+
}
|
|
142
|
+
self.listener.on_client_data_proc = Proc.new { |cli|
|
|
143
|
+
on_client_data(cli)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
self.listener.start
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
#
|
|
150
|
+
# Terminates the monitor thread and turns off the listener.
|
|
151
|
+
#
|
|
152
|
+
def stop
|
|
153
|
+
self.listener.stop
|
|
154
|
+
self.listener.close
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
#
|
|
159
|
+
# Waits for the HTTP service to terminate
|
|
160
|
+
#
|
|
161
|
+
def wait
|
|
162
|
+
self.listener.wait if self.listener
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
#
|
|
166
|
+
# Closes the supplied client, if valid.
|
|
167
|
+
#
|
|
168
|
+
def close_client(cli)
|
|
169
|
+
listener.close_client(cli)
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
#
|
|
173
|
+
# Mounts a directory or resource as being serviced by the supplied handler.
|
|
174
|
+
#
|
|
175
|
+
def mount(root, handler, long_call = false, *args)
|
|
176
|
+
resources[root] = [ handler, long_call, args ]
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
#
|
|
180
|
+
# Remove the mount point.
|
|
181
|
+
#
|
|
182
|
+
def unmount(root)
|
|
183
|
+
resources.delete(root)
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
#
|
|
187
|
+
# Adds a resource handler, such as one for /, which will be called whenever
|
|
188
|
+
# the resource is requested. The ``opts'' parameter can have any of the
|
|
189
|
+
# following:
|
|
190
|
+
#
|
|
191
|
+
# Proc (proc) - The procedure to call when a request comes in for this resource.
|
|
192
|
+
# LongCall (bool) - Hints to the server that this resource may have long
|
|
193
|
+
# request processing times.
|
|
194
|
+
#
|
|
195
|
+
def add_resource(name, opts)
|
|
196
|
+
if (resources[name])
|
|
197
|
+
raise RuntimeError,
|
|
198
|
+
"The supplied resource '#{name}' is already added.", caller
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
# If a procedure was passed, mount the resource with it.
|
|
202
|
+
if (opts['Proc'])
|
|
203
|
+
mount(name, Handler::Proc, false, opts['Proc'], opts['VirtualDirectory'])
|
|
204
|
+
else
|
|
205
|
+
raise ArgumentError, "You must specify a procedure."
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
#
|
|
210
|
+
# Removes the supplied resource handler.
|
|
211
|
+
#
|
|
212
|
+
def remove_resource(name)
|
|
213
|
+
self.resources.delete(name)
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
#
|
|
217
|
+
# Adds Server headers and stuff.
|
|
218
|
+
#
|
|
219
|
+
def add_response_headers(resp)
|
|
220
|
+
resp['Server'] = self.server_name
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
#
|
|
224
|
+
# Returns the mime type associated with the supplied file. Right now the
|
|
225
|
+
# set of mime types is fairly limited.
|
|
226
|
+
#
|
|
227
|
+
def mime_type(file)
|
|
228
|
+
type = nil
|
|
229
|
+
|
|
230
|
+
if (file =~ /\.(.+?)$/)
|
|
231
|
+
type = ExtensionMimeTypes[$1.downcase]
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
type || "text/plain"
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
#
|
|
238
|
+
# Sends a 404 error to the client for a given request.
|
|
239
|
+
#
|
|
240
|
+
def send_e404(cli, request)
|
|
241
|
+
resp = Response::E404.new
|
|
242
|
+
|
|
243
|
+
resp['Content-Type'] = 'text/html'
|
|
244
|
+
|
|
245
|
+
resp.body =
|
|
246
|
+
"<html><head>" +
|
|
247
|
+
"<title>404 Not Found</title>" +
|
|
248
|
+
"</head><body>" +
|
|
249
|
+
"<h1>Not found</h1>" +
|
|
250
|
+
"The requested URL #{html_escape(request.resource)} was not found on this server.<p><hr>" +
|
|
251
|
+
"</body></html>"
|
|
252
|
+
|
|
253
|
+
# Send the response to the client like what
|
|
254
|
+
cli.send_response(resp)
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
attr_accessor :listen_port, :listen_host, :server_name, :context, :ssl
|
|
258
|
+
attr_accessor :listener, :resources
|
|
259
|
+
|
|
260
|
+
protected
|
|
261
|
+
|
|
262
|
+
#
|
|
263
|
+
# Extends new clients with the ServerClient module and initializes them.
|
|
264
|
+
#
|
|
265
|
+
def on_client_connect(cli)
|
|
266
|
+
cli.extend(ServerClient)
|
|
267
|
+
|
|
268
|
+
cli.init_cli(self)
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
#
|
|
272
|
+
# Processes data coming in from a client.
|
|
273
|
+
#
|
|
274
|
+
def on_client_data(cli)
|
|
275
|
+
begin
|
|
276
|
+
#
|
|
277
|
+
# XXX: Handle ParseCode::Partial
|
|
278
|
+
#
|
|
279
|
+
data = cli.get
|
|
280
|
+
|
|
281
|
+
raise ::EOFError if not data
|
|
282
|
+
raise ::EOFError if data.empty?
|
|
283
|
+
|
|
284
|
+
case cli.request.parse(data)
|
|
285
|
+
when Packet::ParseCode::Completed
|
|
286
|
+
dispatch_request(cli, cli.request)
|
|
287
|
+
|
|
288
|
+
cli.reset_cli
|
|
289
|
+
when Packet::ParseCode::Error
|
|
290
|
+
close_client(cli)
|
|
291
|
+
end
|
|
292
|
+
rescue EOFError
|
|
293
|
+
if (cli.request.completed?)
|
|
294
|
+
dispatch_request(cli, cli.request)
|
|
295
|
+
|
|
296
|
+
cli.reset_cli
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
close_client(cli)
|
|
300
|
+
end
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
#
|
|
304
|
+
# Dispatches the supplied request for a given connection.
|
|
305
|
+
#
|
|
306
|
+
def dispatch_request(cli, request)
|
|
307
|
+
# Is the client requesting keep-alive?
|
|
308
|
+
if ((request['Connection']) and
|
|
309
|
+
(request['Connection'].downcase == 'Keep-Alive'.downcase))
|
|
310
|
+
cli.keepalive = true
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
# Search for the resource handler for the requested URL. This is pretty
|
|
314
|
+
# inefficient right now, but we can spruce it up later.
|
|
315
|
+
p = nil
|
|
316
|
+
len = 0
|
|
317
|
+
root = nil
|
|
318
|
+
|
|
319
|
+
resources.each_pair { |k, val|
|
|
320
|
+
if (request.resource =~ /^#{k}/ and k.length > len)
|
|
321
|
+
p = val
|
|
322
|
+
len = k.length
|
|
323
|
+
root = k
|
|
324
|
+
end
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
if (p)
|
|
328
|
+
# Create an instance of the handler for this resource
|
|
329
|
+
handler = p[0].new(self, *p[2])
|
|
330
|
+
|
|
331
|
+
# If the handler class requires a relative resource...
|
|
332
|
+
if (handler.relative_resource_required?)
|
|
333
|
+
# Substituted the mount point root in the request to make things
|
|
334
|
+
# relative to the mount point.
|
|
335
|
+
request.relative_resource = request.resource.gsub(/^#{root}/, '')
|
|
336
|
+
request.relative_resource = '/' + request.relative_resource if (request.relative_resource !~ /^\//)
|
|
337
|
+
end
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
# If we found the resource handler for this resource, call its
|
|
341
|
+
# procedure.
|
|
342
|
+
if (p[1] == true)
|
|
343
|
+
Thread.new {
|
|
344
|
+
handler.on_request(cli, request)
|
|
345
|
+
}
|
|
346
|
+
else
|
|
347
|
+
handler.on_request(cli, request)
|
|
348
|
+
end
|
|
349
|
+
else
|
|
350
|
+
elog("Failed to find handler for resource: #{request.resource}",
|
|
351
|
+
LogSource)
|
|
352
|
+
|
|
353
|
+
send_e404(cli, request)
|
|
354
|
+
end
|
|
355
|
+
|
|
356
|
+
# If keep-alive isn't enabled for this client, close the connection
|
|
357
|
+
if (cli.keepalive == false)
|
|
358
|
+
close_client(cli)
|
|
359
|
+
end
|
|
360
|
+
end
|
|
361
|
+
|
|
362
|
+
end
|
|
363
|
+
|
|
364
|
+
end
|
|
365
|
+
end
|
|
366
|
+
end
|
|
367
|
+
|