Module: Net::SSH::Authentication::Pageant::Win

Extended by:
DL::Importable, DL::Importer, Fiddle::Importer
Includes:
DL::Win32Types, Fiddle::Win32Types
Defined in:
lib/net/ssh/authentication/pageant.rb

Overview

The definition of the Windows methods and data structures used in communicating with the pageant process.

Defined Under Namespace

Modules: LibC

Constant Summary collapse

SIZEOF_DWORD =
Fiddle::SIZEOF_LONG
INVALID_HANDLE_VALUE =

From winbase.h, winnt.h

-1
NULL =
nil
PAGE_READWRITE =
0x0004
FILE_MAP_WRITE =
2
WM_COPYDATA =
74
SMTO_NORMAL =

From winuser.h

0
SUFFIX =
if RUBY_ENGINE == "jruby"
  "A"
else
  ""
end
TOKEN_QUERY =

Constants needed for security attribute retrieval. Specifies the access mask corresponding to the desired access rights.

0x8
TOKEN_USER_INFORMATION_CLASS =

The value of TOKEN_USER from the TOKEN_INFORMATION_CLASS enum.

1
REVISION =

The initial revision level assigned to the security descriptor.

1
TOKEN_USER =

Structs for security attribute functions. Holds the retrieved user access token.

struct ['void * SID', 'DWORD ATTRIBUTES']
SECURITY_ATTRIBUTES =

Contains the security descriptor, this gets passed to the function that constructs the shared memory map.

struct ['DWORD nLength',
'LPVOID lpSecurityDescriptor',
'BOOL bInheritHandle']
SECURITY_DESCRIPTOR =

The security descriptor holds security information.

struct ['UCHAR Revision', 'UCHAR Sbz1',
'USHORT Control', 'LPVOID Owner',
'LPVOID Group', 'LPVOID Sacl',
'LPVOID Dacl']
COPYDATASTRUCT =

The COPYDATASTRUCT is used to send WM_COPYDATA messages

if RUBY_ENGINE == "jruby"
  struct ['ULONG_PTR dwData', 'DWORD cbData', 'LPVOID lpData']
else
  struct ['uintptr_t dwData', 'DWORD cbData', 'LPVOID lpData']
end

Class Method Summary collapse

Class Method Details

.get_cstr(str) ⇒ Object

Get a null-terminated string given a string.


384
385
386
# File 'lib/net/ssh/authentication/pageant.rb', line 384

def self.get_cstr(str)
  return str + "\000"
end

.get_current_userObject


332
333
334
335
336
337
338
# File 'lib/net/ssh/authentication/pageant.rb', line 332

def self.get_current_user
  token_handle = open_process_token(Win.GetCurrentProcess,
                                    Win::TOKEN_QUERY)
  token_user = get_token_information(token_handle,
                  Win::TOKEN_USER_INFORMATION_CLASS)
  return token_user
end

.get_ptr(data) ⇒ Object


204
205
206
# File 'lib/net/ssh/authentication/pageant.rb', line 204

def self.get_ptr(data)
  return data.to_ptr
end

.get_security_attributes_for_userObject


249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
# File 'lib/net/ssh/authentication/pageant.rb', line 249

def self.get_security_attributes_for_user
  user = get_current_user
    
  psd_information = malloc_ptr(Win::SECURITY_DESCRIPTOR.size)
  raise_error_if_zero(
    Win.InitializeSecurityDescriptor(psd_information,
                                     Win::REVISION)
  )
  raise_error_if_zero(
    Win.SetSecurityDescriptorOwner(psd_information, get_sid_ptr(user),
                                   0)
  )
  raise_error_if_zero(
    Win.IsValidSecurityDescriptor(psd_information)
  )
    
  sa = Win::SECURITY_ATTRIBUTES.new(to_struct_ptr(malloc_ptr(Win::SECURITY_ATTRIBUTES.size)))
  sa.nLength = Win::SECURITY_ATTRIBUTES.size
  sa.lpSecurityDescriptor = psd_information.to_i
  sa.bInheritHandle = 1
    
  return sa
end

.get_sid(user) ⇒ Object


299
300
301
# File 'lib/net/ssh/authentication/pageant.rb', line 299

def self.get_sid(user)
  ptr_to_s(user.to_ptr.ptr,Win::SIZEOF_DWORD).unpack('L')[0]
end

.get_sid_ptr(user) ⇒ Object


303
304
305
# File 'lib/net/ssh/authentication/pageant.rb', line 303

def self.get_sid_ptr(user)
  user.to_ptr.ptr
end

.get_token_information(token_handle, token_information_class) ⇒ Object


351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
# File 'lib/net/ssh/authentication/pageant.rb', line 351

def self.get_token_information(token_handle,
                               token_information_class)
  # Hold the size of the information to be returned
  preturn_length = malloc_ptr(Win::SIZEOF_DWORD)
    
  # Going to throw an INSUFFICIENT_BUFFER_ERROR, but that is ok
  # here. This is retrieving the size of the information to be
  # returned.
  Win.GetTokenInformation(token_handle,
                          token_information_class,
                          Win::NULL, 0, preturn_length)
  ptoken_information = malloc_ptr(ptr_to_dword(preturn_length))
    
  # This call is going to write the requested information to
  # the memory location referenced by token_information.
  raise_error_if_zero(
    Win.GetTokenInformation(token_handle,
                            token_information_class,
                            ptoken_information,
                            ptoken_information.size,
                            preturn_length)
  )
    
  return to_token_user(ptoken_information)
end

.malloc_ptr(size) ⇒ Object


200
201
202
# File 'lib/net/ssh/authentication/pageant.rb', line 200

def self.malloc_ptr(size)
  return DL.malloc(size)
end

.open_process_token(process_handle, desired_access) ⇒ Object


340
341
342
343
344
345
346
347
348
349
# File 'lib/net/ssh/authentication/pageant.rb', line 340

def self.open_process_token(process_handle, desired_access)
  ptoken_handle = malloc_ptr(Win::SIZEOF_DWORD)
    
  raise_error_if_zero(
    Win.OpenProcessToken(process_handle, desired_access,
                         ptoken_handle)
  )
  token_handle = ptr_to_handle(ptoken_handle)
  return token_handle
end

.ptr_to_dword(ptr) ⇒ Object


284
285
286
287
288
289
# File 'lib/net/ssh/authentication/pageant.rb', line 284

def self.ptr_to_dword(ptr)
  first = ptr.ptr.to_i
  second = ptr_to_s(ptr,Win::SIZEOF_DWORD).unpack('L')[0]
  raise "Error" unless first == second
  first
end

.ptr_to_handle(phandle) ⇒ Object


280
281
282
# File 'lib/net/ssh/authentication/pageant.rb', line 280

def self.ptr_to_handle(phandle)
  phandle.ptr
end

.ptr_to_s(ptr, size) ⇒ Object


274
275
276
277
278
# File 'lib/net/ssh/authentication/pageant.rb', line 274

def self.ptr_to_s(ptr, size)
  ret = ptr.to_s(size)
  ret << "\x00" while ret.size < size
  ret
end

.raise_error_if_zero(result) ⇒ Object


377
378
379
380
381
# File 'lib/net/ssh/authentication/pageant.rb', line 377

def self.raise_error_if_zero(result)
  if result == 0
    raise "Windows error: #{Win.GetLastError}"
  end
end

.set_ptr_data(ptr, data) ⇒ Object


208
209
210
# File 'lib/net/ssh/authentication/pageant.rb', line 208

def self.set_ptr_data(ptr, data)
  ptr[0] = data
end

.to_struct_ptr(ptr) ⇒ Object


295
296
297
# File 'lib/net/ssh/authentication/pageant.rb', line 295

def self.to_struct_ptr(ptr)
  ptr.to_ptr
end

.to_token_user(ptoken_information) ⇒ Object


291
292
293
# File 'lib/net/ssh/authentication/pageant.rb', line 291

def self.to_token_user(ptoken_information)
  TOKEN_USER.new(ptoken_information.to_ptr)
end