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.
Create a new instance that communicates with the running pageant instance. If no such instance is running, this will cause an error.
[ show source ]
# File lib/net/ssh/userauth/pageant.rb, line 108 108: def initialize 109: @win = Win.findWindow( "Pageant", "Pageant" ) 110: 111: if @win == 0 112: raise Net::SSH::Exception, 113: "pageant process not running" 114: end 115: 116: @res = nil 117: @pos = 0 118: end
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.
[ show source ]
# File lib/net/ssh/userauth/pageant.rb, line 102 102: def self.open( location=nil ) 103: new 104: end
Conceptually close the socket. This doesn’t really do anthing significant, but merely complies with the Socket interface.
[ show source ]
# File lib/net/ssh/userauth/pageant.rb, line 173 173: def close 174: @res = nil 175: @pos = 0 176: end
Reads n bytes from the cached result of the last query. If n is nil, returns all remaining data from the last query.
[ show source ]
# File lib/net/ssh/userauth/pageant.rb, line 180 180: def read(n = nil) 181: return nil unless @res 182: if n.nil? 183: start, @pos = @pos, @res.size 184: return @res[start..-1] 185: else 186: start, @pos = @pos, @pos + n 187: return @res[start, n] 188: end 189: end
Forwards the data to send_query, ignoring any arguments after the first. Returns 0.
[ show source ]
# File lib/net/ssh/userauth/pageant.rb, line 122 122: def send( data, *args ) 123: @res = send_query( data ) 124: @pos = 0 125: 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.
[ show source ]
# File lib/net/ssh/userauth/pageant.rb, line 130 130: def send_query( query ) 131: res = nil 132: filemap = 0 133: ptr = nil 134: id = DL::PtrData.malloc( DL.sizeof("L") ) 135: 136: mapname = "PageantRequest%08x\000" % Win.getCurrentThreadId() 137: filemap = Win.createFileMapping(Win::INVALID_HANDLE_VALUE, 138: Win::NULL, 139: Win::PAGE_READWRITE, 0, 140: AGENT_MAX_MSGLEN, mapname) 141: if filemap == 0 142: raise Net::SSH::Exception, 143: "Creation of file mapping failed" 144: end 145: 146: ptr = Win.mapViewOfFile( filemap, Win::FILE_MAP_WRITE, 0, 0, 147: AGENT_MAX_MSGLEN ) 148: 149: if ptr.nil? || ptr.null? 150: raise Net::SSH::Exception, "Mapping of file failed" 151: end 152: 153: ptr[0] = query 154: 155: cds = [AGENT_COPYDATA_ID, mapname.size + 1, mapname]. 156: pack("LLp").to_ptr 157: succ = Win.sendMessageTimeout( @win, Win::WM_COPYDATA, Win::NULL, 158: cds, Win::SMTO_NORMAL, 5000, id ) 159: 160: if succ > 0 161: retlen = 4 + ptr.to_s(4).unpack("N")[0] 162: res = ptr.to_s(retlen) 163: end 164: 165: return res 166: ensure 167: Win.unmapViewOfFile( ptr ) unless ptr.nil? || ptr.null? 168: Win.closeHandle( filemap ) if filemap != 0 169: end