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.
Conceptually close the socket. This doesn’t really do anthing significant, but merely complies with the Socket interface.
# File lib/net/ssh/authentication/pageant.rb, line 154 def close @res = nil @pos = 0 end
Reads n bytes from the cached result of the last query. If
n is nil, returns all remaining data from the
last query.
# File lib/net/ssh/authentication/pageant.rb, line 168 def read(n = nil) return nil unless @res if n.nil? start, @pos = @pos, @res.size return @res[start..-1] else start, @pos = @pos, @pos + n return @res[start, n] end end
Forwards the data to send_query, ignoring any arguments after the first. Returns 0.
# File lib/net/ssh/authentication/pageant.rb, line 103 def send(data, *args) @res = send_query(data) @pos = 0 end
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.
# File lib/net/ssh/authentication/pageant.rb, line 111 def send_query(query) res = nil filemap = 0 ptr = nil id = DL::PtrData.malloc(DL.sizeof("L")) mapname = "PageantRequest%08x\0000" % Win.getCurrentThreadId() filemap = Win.createFileMapping(Win::INVALID_HANDLE_VALUE, Win::NULL, Win::PAGE_READWRITE, 0, AGENT_MAX_MSGLEN, mapname) if filemap == 0 raise Net::SSH::Exception, "Creation of file mapping failed" end ptr = Win.mapViewOfFile(filemap, Win::FILE_MAP_WRITE, 0, 0, AGENT_MAX_MSGLEN) if ptr.nil? || ptr.null? raise Net::SSH::Exception, "Mapping of file failed" end ptr[0] = query cds = [AGENT_COPYDATA_ID, mapname.size + 1, mapname]. pack("LLp").to_ptr 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) end return res ensure Win.unmapViewOfFile(ptr) unless ptr.nil? || ptr.null? Win.closeHandle(filemap) if filemap != 0 end
Create a new instance that communicates with the running pageant instance. If no such instance is running, this will cause an error.
# File lib/net/ssh/authentication/pageant.rb, line 89 def initialize @win = Win.findWindow("Pageant", "Pageant") if @win == 0 raise Net::SSH::Exception, "pageant process not running" end @res = nil @pos = 0 end