anachronism 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,9 @@
1
+ require "ffi"
2
+
3
+ module Anachronism
4
+ require 'anachronism/version'
5
+
6
+ require 'anachronism/native'
7
+ require 'anachronism/nvt'
8
+ require 'anachronism/channel'
9
+ end
@@ -0,0 +1,59 @@
1
+ class Anachronism::Channel
2
+ attr_reader :telnet, :telopt
3
+
4
+ def initialize (telopt, telnet)
5
+ telnet.bind(telopt, self)
6
+
7
+ @telnet = telnet
8
+ @telopt = telopt
9
+ end
10
+
11
+ def send (data)
12
+ @telnet.send_subnegotiation(@telopt, data)
13
+ end
14
+
15
+
16
+ def request_remote_enable (opts={})
17
+ @telnet.request_remote_enable(@telopt, opts)
18
+ end
19
+
20
+ def request_remote_disable
21
+ @telnet.request_remote_disable(@telopt)
22
+ end
23
+
24
+ def request_local_enable (opts={})
25
+ @telnet.request_local_enable(@telopt, opts)
26
+ end
27
+
28
+ def request_local_disable
29
+ @telnet.request_local_disable(@telopt)
30
+ end
31
+
32
+
33
+ def local_enabled?
34
+ @telnet.local_enabled?(@telopt)
35
+ end
36
+
37
+ def remote_enabled?
38
+ @telnet.remote_enabled?(@telopt)
39
+ end
40
+
41
+
42
+ #
43
+ # Callbacks
44
+ ##
45
+ def on_focus
46
+ end
47
+
48
+ def on_blur
49
+ end
50
+
51
+ def on_text (text)
52
+ end
53
+
54
+ def on_local_toggle (active)
55
+ end
56
+
57
+ def on_remote_toggle (active)
58
+ end
59
+ end
@@ -0,0 +1,139 @@
1
+ require "ffi"
2
+
3
+ module Anachronism::Native
4
+ extend FFI::Library
5
+ ffi_lib 'anachronism'
6
+
7
+ typedef :pointer, :nvt
8
+ typedef :uchar, :telopt
9
+
10
+ enum :error, [
11
+ :bad_parser, -3,
12
+ :bad_nvt,
13
+ :invalid_command,
14
+ :alloc,
15
+ :ok,
16
+ :interrupt,
17
+ ]
18
+
19
+ enum :telopt_mode, [
20
+ :off,
21
+ :on,
22
+ :lazy,
23
+ ]
24
+
25
+ enum :telopt_location, [
26
+ :local,
27
+ :remote
28
+ ]
29
+
30
+
31
+ #
32
+ # NVT Events
33
+ ##
34
+ enum :nvt_event_type, [
35
+ :data,
36
+ :command,
37
+ :warning,
38
+ :send,
39
+ ]
40
+
41
+ class Event < FFI::Struct
42
+ layout(
43
+ :type, :nvt_event_type
44
+ )
45
+ end
46
+
47
+ class DataEvent < FFI::Struct
48
+ layout(
49
+ :SUPER_, Event,
50
+ :data, :pointer,
51
+ :length, :size_t
52
+ )
53
+ end
54
+
55
+ class CommandEvent < FFI::Struct
56
+ layout(
57
+ :SUPER_, Event,
58
+ :command, :uchar
59
+ )
60
+ end
61
+
62
+ class WarningEvent < FFI::Struct
63
+ layout(
64
+ :SUPER_, Event,
65
+ :message, :string,
66
+ :position, :size_t
67
+ )
68
+ end
69
+
70
+ class SendEvent < FFI::Struct
71
+ layout(
72
+ :SUPER_, Event,
73
+ :data, :pointer,
74
+ :length, :size_t
75
+ )
76
+ end
77
+
78
+ #
79
+ # Telopt Events
80
+ ##
81
+ enum :telopt_event_type, [
82
+ :toggle,
83
+ :focus,
84
+ :data,
85
+ ]
86
+
87
+ class TeloptEvent < FFI::Struct
88
+ layout(
89
+ :type, :telopt_event_type
90
+ )
91
+ end
92
+
93
+ class ToggleTeloptEvent < FFI::Struct
94
+ layout(
95
+ :SUPER_, TeloptEvent,
96
+ :where, :telopt_location,
97
+ :status, :telopt_mode
98
+ )
99
+ end
100
+
101
+ class FocusTeloptEvent < FFI::Struct
102
+ layout(
103
+ :SUPER_, TeloptEvent,
104
+ :focus, :uchar
105
+ )
106
+ end
107
+
108
+ class DataTeloptEvent < FFI::Struct
109
+ layout(
110
+ :SUPER_, TeloptEvent,
111
+ :data, :pointer,
112
+ :length, :size_t
113
+ )
114
+ end
115
+
116
+
117
+ # Event callbacks
118
+ callback :nvt_event_callback, [:nvt, :pointer], :void
119
+ callback :telopt_event_callback, [:nvt, :telopt, :pointer], :void
120
+
121
+ # NVT
122
+ attach_function :new_nvt, :telnet_nvt_new, [:nvt_event_callback, :telopt_event_callback, :pointer], :nvt
123
+ attach_function :free_nvt, :telnet_nvt_free, [:nvt], :void
124
+
125
+ attach_function :get_userdata, :telnet_get_userdata, [:nvt, :pointer], :error
126
+ attach_function :interrupt, :telnet_interrupt, [:nvt], :error
127
+
128
+ attach_function :receive, :telnet_receive, [:nvt, :buffer_in, :size_t, :pointer], :error
129
+ attach_function :send_data, :telnet_send_data, [:nvt, :buffer_in, :size_t], :error
130
+ attach_function :send_command, :telnet_send_command, [:nvt, :uchar], :error
131
+ attach_function :send_subnegotiation, :telnet_send_subnegotiation, [:nvt, :telopt, :buffer_in, :size_t], :error
132
+
133
+ attach_function :telopt_enable_local, :telnet_telopt_enable_local, [:nvt, :telopt, :uchar], :error
134
+ attach_function :telopt_enable_remote, :telnet_telopt_enable_remote, [:nvt, :telopt, :uchar], :error
135
+ attach_function :telopt_disable_local, :telnet_telopt_disable_local, [:nvt, :telopt], :error
136
+ attach_function :telopt_disable_remote, :telnet_telopt_disable_remote, [:nvt, :telopt], :error
137
+ attach_function :telopt_status_local, :telnet_telopt_status_local, [:nvt, :telopt, :pointer], :error
138
+ attach_function :telopt_status_remote, :telnet_telopt_status_remote, [:nvt, :telopt, :pointer], :error
139
+ end
@@ -0,0 +1,150 @@
1
+ class Anachronism::Telnet
2
+ def initialize
3
+ # Make sure these aren't GC'd while the object exists.
4
+ @_on_nvt_event = proc {|_, ev| process_nvt_event(ev)}
5
+ @_on_telopt_event = proc {|_, telopt, ev| process_telopt_event(telopt, ev)}
6
+
7
+ @telnet_nvt = Anachronism::Native.new_nvt(
8
+ @_on_nvt_event,
9
+ @_on_telopt_event,
10
+ FFI::Pointer.new(0))
11
+ raise NoMemoryError if @telnet_nvt == FFI::Pointer.new(0)
12
+ @telopt_callbacks = Array.new(256)
13
+ end
14
+
15
+ def receive (data)
16
+ ptr = FFI::MemoryPointer.new :pointer
17
+ err = Anachronism::Native.receive(@telnet_nvt, data, data.length, ptr)
18
+ raise NoMemoryError if err == :alloc
19
+ data[ptr.read_int..-1]
20
+ end
21
+
22
+ # Halts the Telnet parser at the current point, usually so the remainder of
23
+ # the data can be preprocessed before continuing.
24
+ def interrupt_parser
25
+ Anachronism::Native.interrupt(@telnet_nvt)
26
+ nil
27
+ end
28
+
29
+
30
+ def send_text (data)
31
+ err = Anachronism::Native.send_data(@telnet_nvt, data, data.length)
32
+ raise NoMemoryError if err == :alloc
33
+ end
34
+
35
+ def send_command (command)
36
+ err = Anachronism::Native.send_command(@telnet_nvt, command)
37
+ raise ArgumentError, "#{command} is not a valid single-byte command" if err == :invalid_command
38
+ end
39
+
40
+ def send_subnegotiation (telopt, data)
41
+ err = Anachronism::Native.send_subnegotiation(@telnet_nvt, telopt, data, data.length)
42
+ raise NoMemoryError if err == :alloc
43
+ end
44
+
45
+
46
+ def request_local_enable (telopt, opts={})
47
+ Anachronism::Native.telopt_enable_local(@telnet_nvt, telopt, (opts[:lazy]) ? 1 : 0)
48
+ nil
49
+ end
50
+
51
+ def request_local_disable (telopt)
52
+ Anachronism::Native.telopt_disable_local(@telnet_nvt, telopt)
53
+ nil
54
+ end
55
+
56
+ def request_remote_enable (telopt, opts={})
57
+ Anachronism::Native.telopt_enable_remote(@telnet_nvt, telopt, (opts[:lazy]) ? 1 : 0)
58
+ nil
59
+ end
60
+
61
+ def request_remote_disable (telopt)
62
+ Anachronism::Native.telopt_disable_remote(@telnet_nvt, telopt)
63
+ nil
64
+ end
65
+
66
+
67
+ def remote_enabled? (telopt)
68
+ ptr = FFI::MemoryPointer.new :int
69
+ Anachronism::Native.telopt_status_local(@telnet_nvt, telopt, ptr)
70
+ !!ptr.read_int
71
+ end
72
+
73
+ def local_enabled? (telopt)
74
+ ptr = FFI::MemoryPointer.new :int
75
+ Anachronism::Native.telopt_status_remote(@telnet_nvt, telopt, ptr)
76
+ !!ptr.read_int
77
+ end
78
+
79
+
80
+ def bind (telopt, receiver)
81
+ raise "Can't bind to a bound telopt." if @telopt_callbacks[telopt]
82
+ @telopt_callbacks[telopt] = receiver
83
+ end
84
+
85
+ def unbind (telopt)
86
+ @telopt_callbacks[telopt] = nil
87
+ end
88
+
89
+
90
+ #
91
+ # Callbacks
92
+ ##
93
+ def on_text (text)
94
+ end
95
+
96
+ def on_command (command)
97
+ end
98
+
99
+ def on_send (data)
100
+ end
101
+
102
+ def on_warning (message, position)
103
+ end
104
+
105
+
106
+ def process_nvt_event (event_ptr) # :nodoc:
107
+ ev = Anachronism::Native::Event.new(event_ptr)
108
+
109
+ case ev[:type]
110
+ when :data
111
+ ev = Anachronism::Native::DataEvent.new(event_ptr)
112
+ on_text ev[:data].read_string(ev[:length])
113
+ when :command
114
+ ev = Anachronism::Native::CommandEvent.new(event_ptr)
115
+ on_command ev[:command]
116
+ when :send
117
+ ev = Anachronism::Native::SendEvent.new(event_ptr)
118
+ on_send ev[:data].read_string(ev[:length])
119
+ when :warning
120
+ ev = Anachronism::Native::WarningEvent.new(event_ptr)
121
+ on_warning ev[:message], ev[:position]
122
+ end
123
+ end
124
+
125
+ def process_telopt_event (telopt, event_ptr) # :nodoc:
126
+ receiver = @telopt_callbacks[telopt]
127
+ return unless receiver
128
+
129
+ ev = Anachronism::Native::TeloptEvent.new(event_ptr)
130
+ case ev[:type]
131
+ when :toggle
132
+ ev = Anachronism::Native::ToggleTeloptEvent.new(event_ptr)
133
+ if ev[:where] == :local
134
+ receiver.on_local_toggle(ev[:status] == :on)
135
+ elsif ev[:where] == :remote
136
+ receiver.on_remote_toggle(ev[:status] == :on)
137
+ end
138
+ when :focus
139
+ ev = Anachronism::Native::FocusTeloptEvent.new(event_ptr)
140
+ if ev[:focus] == 0
141
+ receiver.on_blur
142
+ else
143
+ receiver.on_focus
144
+ end
145
+ when :data
146
+ ev = Anachronism::Native::DataTeloptEvent.new(event_ptr)
147
+ receiver.on_text ev[:data].read_string(ev[:length])
148
+ end
149
+ end
150
+ end
@@ -0,0 +1,3 @@
1
+ module Anachronism
2
+ VERSION = "0.2.0"
3
+ end
@@ -0,0 +1,130 @@
1
+ !RBIX
2
+ 14718323382541880341
3
+ x
4
+ M
5
+ 1
6
+ n
7
+ n
8
+ x
9
+ 10
10
+ __script__
11
+ i
12
+ 28
13
+ 99
14
+ 7
15
+ 0
16
+ 65
17
+ 49
18
+ 1
19
+ 2
20
+ 13
21
+ 99
22
+ 12
23
+ 7
24
+ 2
25
+ 12
26
+ 7
27
+ 3
28
+ 12
29
+ 65
30
+ 12
31
+ 49
32
+ 4
33
+ 4
34
+ 15
35
+ 49
36
+ 2
37
+ 0
38
+ 15
39
+ 2
40
+ 11
41
+ I
42
+ 6
43
+ I
44
+ 0
45
+ I
46
+ 0
47
+ I
48
+ 0
49
+ n
50
+ p
51
+ 5
52
+ x
53
+ 11
54
+ Anachronism
55
+ x
56
+ 11
57
+ open_module
58
+ x
59
+ 15
60
+ __module_init__
61
+ M
62
+ 1
63
+ n
64
+ n
65
+ x
66
+ 11
67
+ Anachronism
68
+ i
69
+ 12
70
+ 5
71
+ 66
72
+ 65
73
+ 7
74
+ 0
75
+ 7
76
+ 1
77
+ 64
78
+ 49
79
+ 2
80
+ 2
81
+ 11
82
+ I
83
+ 3
84
+ I
85
+ 0
86
+ I
87
+ 0
88
+ I
89
+ 0
90
+ n
91
+ p
92
+ 3
93
+ x
94
+ 7
95
+ VERSION
96
+ s
97
+ 5
98
+ 0.2.0
99
+ x
100
+ 9
101
+ const_set
102
+ p
103
+ 3
104
+ I
105
+ 2
106
+ I
107
+ 2
108
+ I
109
+ c
110
+ x
111
+ 65
112
+ /home/jonathan/Projects/anachronism-rb/lib/anachronism/version.rb
113
+ p
114
+ 0
115
+ x
116
+ 13
117
+ attach_method
118
+ p
119
+ 3
120
+ I
121
+ 0
122
+ I
123
+ 1
124
+ I
125
+ 1c
126
+ x
127
+ 65
128
+ /home/jonathan/Projects/anachronism-rb/lib/anachronism/version.rb
129
+ p
130
+ 0
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: anachronism
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 2
9
+ - 0
10
+ version: 0.2.0
11
+ platform: ruby
12
+ authors:
13
+ - Jonathan Castello
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-07-25 00:00:00 -07:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: ffi
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 25
30
+ segments:
31
+ - 1
32
+ - 0
33
+ - 7
34
+ version: 1.0.7
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: bundler
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ hash: 25
46
+ segments:
47
+ - 1
48
+ - 0
49
+ - 7
50
+ version: 1.0.7
51
+ type: :development
52
+ version_requirements: *id002
53
+ description: Anachronism provides a simple Ruby interface to the Telnet protocol.
54
+ email: jonathan@jonathan.com
55
+ executables: []
56
+
57
+ extensions: []
58
+
59
+ extra_rdoc_files: []
60
+
61
+ files:
62
+ - lib/anachronism.rb
63
+ - lib/anachronism/native.rb
64
+ - lib/anachronism/nvt.rb
65
+ - lib/anachronism/libanachronism.so
66
+ - lib/anachronism/channel.rb
67
+ - lib/anachronism/version.rbc
68
+ - lib/anachronism/version.rb
69
+ has_rdoc: true
70
+ homepage: https://github.com/Twisol/anachronism
71
+ licenses:
72
+ - MIT
73
+ post_install_message:
74
+ rdoc_options: []
75
+
76
+ require_paths:
77
+ - lib
78
+ required_ruby_version: !ruby/object:Gem::Requirement
79
+ none: false
80
+ requirements:
81
+ - - ~>
82
+ - !ruby/object:Gem::Version
83
+ hash: 51
84
+ segments:
85
+ - 1
86
+ - 9
87
+ - 0
88
+ version: 1.9.0
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ hash: 3
95
+ segments:
96
+ - 0
97
+ version: "0"
98
+ requirements: []
99
+
100
+ rubyforge_project:
101
+ rubygems_version: 1.5.2
102
+ signing_key:
103
+ specification_version: 3
104
+ summary: A binding to libanachronism, a Telnet processing library.
105
+ test_files: []
106
+