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.
- data/lib/anachronism.rb +9 -0
- data/lib/anachronism/channel.rb +59 -0
- data/lib/anachronism/libanachronism.so +0 -0
- data/lib/anachronism/native.rb +139 -0
- data/lib/anachronism/nvt.rb +150 -0
- data/lib/anachronism/version.rb +3 -0
- data/lib/anachronism/version.rbc +130 -0
- metadata +106 -0
data/lib/anachronism.rb
ADDED
@@ -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
|
Binary file
|
@@ -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,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
|
+
|