anachronism 0.2.0

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.
@@ -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
+