Class: VNCRec::RFB::Authentication::VncAuthentication

Inherits:
Abstract
  • Object
show all
Defined in:
lib/vncrec/rfb/authentication.rb

Instance Method Summary collapse

Methods inherited from Abstract

#get_security_types, #handle_types, #handshake, #security_result, #send_type, #to_msg

Constructor Details

#initialize(io, *args) ⇒ VncAuthentication

Returns a new instance of VncAuthentication.



129
130
131
132
133
# File 'lib/vncrec/rfb/authentication.rb', line 129

def initialize(io, *args)
  super
  @code = 2
  @password = args.first
end

Instance Method Details

#perform_authenticationObject

The server sends a random 16-byte challenge:

+--------------+--------------+-------------+
| No. of bytes | Type [Value] | Description |
+--------------+--------------+-------------+
| 16           | U8           | challenge   |
+--------------+--------------+-------------+

The client encrypts the challenge with DES (ECB), using a password supplied by the user as the key. To form the key, the password is truncated to eight characters, or padded with null bytes on the right. Actually, each byte is also reversed. Challenge string is split in two chunks of 8 bytes, which are encrypted separately and clashed together again. The client then sends the resulting 16-byte response:

+--------------+--------------+-------------+
| No. of bytes | Type [Value] | Description |
+--------------+--------------+-------------+
| 16           | U8           | response    |
+--------------+--------------+-------------+

The protocol continues with the SecurityResult message.



157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/vncrec/rfb/authentication.rb', line 157

def perform_authentication
  require 'openssl'

  challenge = @io.readpartial(16)
  split_challenge = [challenge.slice(0, 8), challenge.slice(8, 8)]

  cipher = OpenSSL::Cipher::DES.new(:ECB)
  cipher.encrypt
  cipher.key = normalized_password
  encrypted = split_challenge.reduce('') { |a, e| cipher.reset; a << cipher.update(e) }
  @io.syswrite encrypted
end