Class: Net::SSH::Authentication::Pageant::Socket
- Inherits:
-
Object
- Object
- Net::SSH::Authentication::Pageant::Socket
- Defined in:
- lib/net/ssh/authentication/pageant.rb
Overview
This is the pseudo-socket implementation that mimics the interface of a socket, translating each request into a Windows messaging call to the pageant daemon. This allows pageant support to be implemented simply by replacing the socket factory used by the Agent class.
Class Method Summary collapse
-
.open(location = nil) ⇒ Object
The factory method for creating a new Socket instance.
Instance Method Summary collapse
- #close ⇒ Object
-
#initialize ⇒ Socket
constructor
Create a new instance that communicates with the running pageant instance.
-
#read(n = nil) ⇒ Object
Reads
nbytes from the cached result of the last query. -
#send(data, *args) ⇒ Object
Forwards the data to #send_query, ignoring any arguments after the first.
-
#send_query(query) ⇒ Object
Packages the given query string and sends it to the pageant process via the Windows messaging subsystem.
Constructor Details
#initialize ⇒ Socket
Create a new instance that communicates with the running pageant instance. If no such instance is running, this will cause an error.
283 284 285 286 287 288 289 290 291 292 293 |
# File 'lib/net/ssh/authentication/pageant.rb', line 283 def initialize @win = Win.FindWindow("Pageant", "Pageant") if @win == 0 raise Net::SSH::Exception, "pageant process not running" end @input_buffer = Net::SSH::Buffer.new @output_buffer = Net::SSH::Buffer.new end |
Class Method Details
.open(location = nil) ⇒ Object
The factory method for creating a new Socket instance. The location parameter is ignored, and is only needed for compatibility with the general Socket interface.
277 278 279 |
# File 'lib/net/ssh/authentication/pageant.rb', line 277 def self.open(location=nil) new end |
Instance Method Details
#close ⇒ Object
319 320 |
# File 'lib/net/ssh/authentication/pageant.rb', line 319 def close end |
#read(n = nil) ⇒ Object
Reads n bytes from the cached result of the last query. If n is nil, returns all remaining data from the last query.
315 316 317 |
# File 'lib/net/ssh/authentication/pageant.rb', line 315 def read(n = nil) @output_buffer.read(n) end |
#send(data, *args) ⇒ Object
Forwards the data to #send_query, ignoring any arguments after the first.
297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 |
# File 'lib/net/ssh/authentication/pageant.rb', line 297 def send(data, *args) @input_buffer.append(data) ret = data.length while true return ret if @input_buffer.length < 4 msg_length = @input_buffer.read_long + 4 @input_buffer.reset! return ret if @input_buffer.length < msg_length msg = @input_buffer.read!(msg_length) @output_buffer.append(send_query(msg)) end end |
#send_query(query) ⇒ Object
Packages the given query string and sends it to the pageant process via the Windows messaging subsystem. The result is cached, to be returned piece-wise when #read is called.
325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 |
# File 'lib/net/ssh/authentication/pageant.rb', line 325 def send_query(query) res = nil filemap = 0 ptr = nil id = Win.malloc_ptr(Win::SIZEOF_DWORD) mapname = "PageantRequest%08x" % Win.GetCurrentThreadId() security_attributes = Win.get_ptr Win.get_security_attributes_for_user filemap = Win.CreateFileMapping(Win::INVALID_HANDLE_VALUE, security_attributes, Win::PAGE_READWRITE, 0, AGENT_MAX_MSGLEN, mapname) if filemap == 0 || filemap == Win::INVALID_HANDLE_VALUE raise Net::SSH::Exception, "Creation of file mapping failed with error: #{Win.GetLastError}" end ptr = Win.MapViewOfFile(filemap, Win::FILE_MAP_WRITE, 0, 0, 0) if ptr.nil? || ptr.null? raise Net::SSH::Exception, "Mapping of file failed" end Win.set_ptr_data(ptr, query) cds = Win.get_ptr [AGENT_COPYDATA_ID, mapname.size + 1, Win.get_cstr(mapname)].pack("LLp") succ = Win.SendMessageTimeout(@win, Win::WM_COPYDATA, Win::NULL, cds, Win::SMTO_NORMAL, 5000, id) if succ > 0 retlen = 4 + ptr.to_s(4).unpack("N")[0] res = ptr.to_s(retlen) else raise Net::SSH::Exception, "Message failed with error: #{Win.GetLastError}" end return res ensure Win.UnmapViewOfFile(ptr) unless ptr.nil? || ptr.null? Win.CloseHandle(filemap) if filemap != 0 end |