Class Net::SSH::UserAuth::Pageant::Socket
In: lib/net/ssh/userauth/pageant.rb
Parent: Object

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.

Methods

close   new   open   read   send   send_query  

Public Class methods

Create a new instance that communicates with the running pageant instance. If no such instance is running, this will cause an error.

[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.

[Source]

     # File lib/net/ssh/userauth/pageant.rb, line 102
102:           def self.open( location=nil )
103:             new
104:           end

Public Instance methods

Conceptually close the socket. This doesn’t really do anthing significant, but merely complies with the Socket interface.

[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.

[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.

[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.

[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

[Validate]