class Net::SSH::Authentication::Pageant::Socket
simply by replacing the socket factory used by the Agent class.
the pageant daemon. This allows pageant support to be implemented
a socket, translating each request into a Windows messaging call to
This is the pseudo-socket implementation that mimics the interface of
def self.open(location=nil)
parameter is ignored, and is only needed for compatibility with
The factory method for creating a new Socket instance. The location
def self.open(location=nil) new end
def close
Conceptually close the socket. This doesn't really do anthing
def close @res = nil @pos = 0 end
def closed?
this doesn't really do anything significant, but merely
Conceptually asks if the socket is closed. As with #close,
def closed? @res.nil? && @pos.zero? end
def initialize
Create a new instance that communicates with the running pageant
def initialize @win = Win.FindWindow("Pageant", "Pageant") if @win == 0 raise Net::SSH::Exception, "pageant process not running" end @res = nil @pos = 0 end
def read(n = nil)
Reads +n+ bytes from the cached result of the last query. If +n+
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
def send(data, *args)
Forwards the data to #send_query, ignoring any arguments after
def send(data, *args) @res = send_query(data) @pos = 0 end
def send_query(query)
process via the Windows messaging subsystem. The result is
Packages the given query string and sends it to the pageant
def send_query(query) res = nil filemap = 0 ptr = nil id = DL::PtrData.malloc(DL.sizeof("L")) mapname = "PageantRequest%08x\000" % 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