eventmachine-vnc 0.1.20101208010250
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/eventmachine/protocols/vnc.rb +151 -0
- data/lib/eventmachine-vnc.rb +1 -0
- metadata +82 -0
@@ -0,0 +1,151 @@
|
|
1
|
+
|
2
|
+
require "rubygems"
|
3
|
+
require "eventmachine"
|
4
|
+
require "logger"
|
5
|
+
|
6
|
+
module EventMachine; module Protocols
|
7
|
+
module VNC
|
8
|
+
module Client
|
9
|
+
VERSION = "RFB 003.003"
|
10
|
+
SECURITY_TYPES = {
|
11
|
+
0 => "Invalid",
|
12
|
+
1 => "None",
|
13
|
+
2 => "VNC Authentication",
|
14
|
+
5 => "RA2",
|
15
|
+
6 => "RA2ne",
|
16
|
+
16 => "Tight",
|
17
|
+
17 => "Ultra",
|
18
|
+
18 => "TLS",
|
19
|
+
19 => "VeNCrypt",
|
20
|
+
20 => "GTK-VNC SASL",
|
21
|
+
21 => "MD5 hash authentication",
|
22
|
+
22 => "Colin Dean xvp",
|
23
|
+
}
|
24
|
+
|
25
|
+
KEY_EVENT = 4
|
26
|
+
POINTER_EVENT = 5
|
27
|
+
|
28
|
+
def receive_data(data)
|
29
|
+
@logger ||= Logger.new(STDERR)
|
30
|
+
@buffer ||= ''
|
31
|
+
@state ||= :handshake
|
32
|
+
@buffer += data
|
33
|
+
@logger.info ("Got #{data.length} bytes: #{data}")
|
34
|
+
|
35
|
+
# Process all data in the buffer.
|
36
|
+
while @buffer.length > 0
|
37
|
+
@logger.info [@state, @buffer.length].inspect
|
38
|
+
result = send(@state)
|
39
|
+
puts [result, @buffer.length].inspect
|
40
|
+
break if result == :wait
|
41
|
+
end
|
42
|
+
end # def receive_data
|
43
|
+
|
44
|
+
def handshake
|
45
|
+
return :wait if @buffer.length < 12
|
46
|
+
|
47
|
+
@server_version = consume(12)
|
48
|
+
if @server_version !~ /^RFB [0-9]{3}\.[0-9]{3}\n$/
|
49
|
+
error "Invalid protocol message: #{@server_version}"
|
50
|
+
end
|
51
|
+
send_data("#{VERSION}\n")
|
52
|
+
@state = :security
|
53
|
+
end # def handshake
|
54
|
+
|
55
|
+
def security
|
56
|
+
return :wait if @buffer.length < 4
|
57
|
+
security_type = consume(4).unpack("N").first
|
58
|
+
|
59
|
+
@logger.info("Security: #{security_type}")
|
60
|
+
case security_type
|
61
|
+
when 0
|
62
|
+
@state = :read_error
|
63
|
+
#error "Connection failed (during security handshake)"
|
64
|
+
# TODO(sissel): Should set state ':read_string_and_fail'
|
65
|
+
# RFP protocol says this 0 will be followed by a string reason.
|
66
|
+
when 1
|
67
|
+
# No authentication to do
|
68
|
+
client_init
|
69
|
+
when 2
|
70
|
+
@state = :security_vnc_authentication
|
71
|
+
@logger.info("VNC AUTH")
|
72
|
+
else
|
73
|
+
error "Unsupported security type #{SECURITY_TYPES[security_type]}"
|
74
|
+
end # case security_type
|
75
|
+
end # def security
|
76
|
+
|
77
|
+
# Page 14, RFB 3.7 PDF
|
78
|
+
def security_vnc_authentication
|
79
|
+
# TODO(sissel): implement VNC auth (DES a 16 byte challenge + password)
|
80
|
+
# Except the password is bitwise-reversed.
|
81
|
+
# http://www.vidarholen.net/contents/junk/vnc.html
|
82
|
+
# For now, use the Cipher::DES that comes with ruby-vnc
|
83
|
+
return :wait if @buffer.length < 16
|
84
|
+
require "cipher/des" # from rubygem ruby-vnc
|
85
|
+
challenge = consume(16)
|
86
|
+
password = ENV["VNCPASS"]
|
87
|
+
response = Cipher::DES.encrypt(password, challenge)
|
88
|
+
send_data(response)
|
89
|
+
@state = :security_result
|
90
|
+
end # def security_vnc_authentication
|
91
|
+
|
92
|
+
def security_result
|
93
|
+
return :wait if @buffer.length < 4
|
94
|
+
result = consume(4).unpack("N").first
|
95
|
+
if result == 0
|
96
|
+
client_init
|
97
|
+
else
|
98
|
+
error "Authentication failed"
|
99
|
+
end
|
100
|
+
end # def security_result
|
101
|
+
|
102
|
+
# ClientInit is 1 byte, U8. Value is 'shared-flag' nonzero is true.
|
103
|
+
def client_init
|
104
|
+
shared = [1].pack("C")
|
105
|
+
send_data(shared)
|
106
|
+
@state = :server_init
|
107
|
+
end
|
108
|
+
|
109
|
+
# ServerInit
|
110
|
+
# bytes type description
|
111
|
+
# 2, U16, framebuffer-width
|
112
|
+
# 2, U16, framebuffer-height
|
113
|
+
# 16, PIXEL_FORMAT, server-pixel-format
|
114
|
+
# 4, U32, name-length
|
115
|
+
# <name-length>, U8 array, name-string
|
116
|
+
def server_init
|
117
|
+
return :wait if @buffer.length < 24
|
118
|
+
@screen_width, @screen_height, @pixel_format, @name_length = \
|
119
|
+
consume(24).unpack("nnA16N")
|
120
|
+
puts "Screen: #{@screen_width} x #{@screen_height}"
|
121
|
+
@state = :server_init_name
|
122
|
+
end
|
123
|
+
|
124
|
+
def server_init_name
|
125
|
+
return :wait if @buffer.length < @name_length
|
126
|
+
@name = consume(@name_length)
|
127
|
+
@logger.info("Name; #{@name}")
|
128
|
+
@state = :normal
|
129
|
+
ready if self.respond_to?(:ready)
|
130
|
+
end
|
131
|
+
|
132
|
+
def read_error
|
133
|
+
error(@buffer)
|
134
|
+
end
|
135
|
+
|
136
|
+
def consume(bytes)
|
137
|
+
result = @buffer[0 .. bytes - 1]
|
138
|
+
@buffer = @buffer[bytes .. -1]
|
139
|
+
return result
|
140
|
+
end # def consume
|
141
|
+
|
142
|
+
def error(message)
|
143
|
+
if self.respond_to?(:errback)
|
144
|
+
self.errback(message)
|
145
|
+
else
|
146
|
+
raise message
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end # module Client
|
150
|
+
end # module VNC
|
151
|
+
end; end # module EventMachine::Protocols
|
@@ -0,0 +1 @@
|
|
1
|
+
require "eventmachine/protocols/vnc"
|
metadata
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: eventmachine-vnc
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 40202416020495
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 20101208010250
|
10
|
+
version: 0.1.20101208010250
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Jordan Sissel
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-12-08 00:00:00 -08:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: eventmachine
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
33
|
+
type: :runtime
|
34
|
+
version_requirements: *id001
|
35
|
+
description: VNC for EventMachine
|
36
|
+
email: jls@semicomplete.com
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files: []
|
42
|
+
|
43
|
+
files:
|
44
|
+
- lib/eventmachine-vnc.rb
|
45
|
+
- lib/eventmachine/protocols/vnc.rb
|
46
|
+
has_rdoc: true
|
47
|
+
homepage: https://github.com/jordansissel/eventmachine-vnc
|
48
|
+
licenses: []
|
49
|
+
|
50
|
+
post_install_message:
|
51
|
+
rdoc_options: []
|
52
|
+
|
53
|
+
require_paths:
|
54
|
+
- lib
|
55
|
+
- lib
|
56
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
hash: 3
|
62
|
+
segments:
|
63
|
+
- 0
|
64
|
+
version: "0"
|
65
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
hash: 3
|
71
|
+
segments:
|
72
|
+
- 0
|
73
|
+
version: "0"
|
74
|
+
requirements: []
|
75
|
+
|
76
|
+
rubyforge_project:
|
77
|
+
rubygems_version: 1.3.7
|
78
|
+
signing_key:
|
79
|
+
specification_version: 3
|
80
|
+
summary: eventmachine vnc - vnc/rfb protocol support
|
81
|
+
test_files: []
|
82
|
+
|