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.
Direct Known Subclasses
Class Method Summary collapse
-
.open(location = nil) ⇒ Object
The factory method for creating a new Socket instance.
Instance Method Summary collapse
-
#close ⇒ Object
Conceptually close the socket.
-
#closed? ⇒ Boolean
Conceptually asks if the socket is closed.
-
#initialize ⇒ Socket
constructor
Create a new instance that communicates with the running pageant instance.
-
#read(n = nil) ⇒ Object
Reads
n
bytes 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.
105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/net/ssh/authentication/pageant.rb', line 105 def initialize @win = Win.FindWindow("Pageant", "Pageant") if @win == 0 raise Net::SSH::Exception, "pageant process not running" end @res = nil @pos = 0 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.
99 100 101 |
# File 'lib/net/ssh/authentication/pageant.rb', line 99 def self.open(location=nil) new end |
Instance Method Details
#close ⇒ Object
Conceptually close the socket. This doesn’t really do anthing significant, but merely complies with the Socket interface.
170 171 172 173 |
# File 'lib/net/ssh/authentication/pageant.rb', line 170 def close @res = nil @pos = 0 end |
#closed? ⇒ Boolean
Conceptually asks if the socket is closed. As with #close, this doesn’t really do anything significant, but merely complies with the Socket interface.
178 179 180 |
# File 'lib/net/ssh/authentication/pageant.rb', line 178 def closed? @res.nil? && @pos.zero? 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.
184 185 186 187 188 189 190 191 192 193 |
# File 'lib/net/ssh/authentication/pageant.rb', line 184 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 |
#send(data, *args) ⇒ Object
Forwards the data to #send_query, ignoring any arguments after the first. Returns 0.
119 120 121 122 |
# File 'lib/net/ssh/authentication/pageant.rb', line 119 def send(data, *args) @res = send_query(data) @pos = 0 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.
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/net/ssh/authentication/pageant.rb', line 127 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 |