class DBus::Client

Authentication client class.

Class tha performs the actional authentication.

Public Class Methods

new(socket) click to toggle source

Create a new authentication client.

    # File lib/dbus/auth.rb
119 def initialize(socket)
120   @socket = socket
121   @state = nil
122   @auth_list = [External, DBusCookieSHA1, Anonymous]
123 end

Public Instance Methods

authenticate() click to toggle source

Start the authentication process.

    # File lib/dbus/auth.rb
126 def authenticate
127   if RbConfig::CONFIG["target_os"] =~ /freebsd/
128     @socket.sendmsg(0.chr, 0, nil, [:SOCKET, :SCM_CREDS, ""])
129   else
130     @socket.write(0.chr)
131   end
132   next_authenticator
133   @state = :Starting
134   while @state != :Authenticated
135     r = next_state
136     return r if !r
137   end
138   true
139 end

Private Instance Methods

next_authenticator() click to toggle source

Try authentication using the next authenticator.

    # File lib/dbus/auth.rb
155 def next_authenticator
156   raise AuthenticationFailed if @auth_list.empty?
157   @authenticator = @auth_list.shift.new
158   auth_msg = ["AUTH", @authenticator.name, @authenticator.authenticate]
159   DBus.logger.debug "auth_msg: #{auth_msg.inspect}"
160   send(auth_msg)
161 rescue AuthenticationFailed
162   @socket.close
163   raise
164 end
next_msg() click to toggle source

Read data (a buffer) from the bus until CR LF is encountered. Return the buffer without the CR LF characters.

    # File lib/dbus/auth.rb
168 def next_msg
169   data = ""
170   crlf = "\r\n"
171   left = 1024 # 1024 byte, no idea if it's ever getting bigger
172   while left > 0
173     buf = @socket.read(left > 1 ? 1 : left)
174     break if buf.nil?
175     left -= buf.bytesize
176     data += buf
177     break if data.include? crlf # crlf means line finished, the TCP socket keeps on listening, so we break
178   end
179   readline = data.chomp.split(" ")
180   DBus.logger.debug "readline: #{readline.inspect}"
181   readline
182 end
next_state() click to toggle source

Try to reach the next state based on the current state.

    # File lib/dbus/auth.rb
191 def next_state
192   msg = next_msg
193   if @state == :Starting
194     DBus.logger.debug ":Starting msg: #{msg[0].inspect}"
195     case msg[0]
196     when "OK"
197       @state = :WaitingForOk
198     when "CONTINUE"
199       @state = :WaitingForData
200     when "REJECTED" # needed by tcp, unix-path/abstract doesn't get here
201       @state = :WaitingForData
202     end
203   end
204   DBus.logger.debug "state: #{@state}"
205   case @state
206   when :WaitingForData
207     DBus.logger.debug ":WaitingForData msg: #{msg[0].inspect}"
208     case msg[0]
209     when "DATA"
210       chall = msg[1]
211       resp, chall = @authenticator.data(chall)
212       DBus.logger.debug ":WaitingForData/DATA resp: #{resp.inspect}"
213       case resp
214       when :AuthContinue
215         send("DATA", chall)
216         @state = :WaitingForData
217       when :AuthOk
218         send("DATA", chall)
219         @state = :WaitingForOk
220       when :AuthError
221         send("ERROR")
222         @state = :WaitingForData
223       end
224     when "REJECTED"
225       next_authenticator
226       @state = :WaitingForData
227     when "ERROR"
228       send("CANCEL")
229       @state = :WaitingForReject
230     when "OK"
231       send("BEGIN")
232       @state = :Authenticated
233     else
234       send("ERROR")
235       @state = :WaitingForData
236     end
237   when :WaitingForOk
238     DBus.logger.debug ":WaitingForOk msg: #{msg[0].inspect}"
239     case msg[0]
240     when "OK"
241       send("BEGIN")
242       @state = :Authenticated
243     when "REJECT"
244       next_authenticator
245       @state = :WaitingForData
246     when "DATA", "ERROR"
247       send("CANCEL")
248       @state = :WaitingForReject
249     else
250       send("ERROR")
251       @state = :WaitingForOk
252     end
253   when :WaitingForReject
254     DBus.logger.debug ":WaitingForReject msg: #{msg[0].inspect}"
255     case msg[0]
256     when "REJECT"
257       next_authenticator
258       @state = :WaitingForOk
259     else
260       @socket.close
261       return false
262     end
263   end
264   true
265 end
send(meth, *args) click to toggle source

Send an authentication method meth with arguments args to the server.

    # File lib/dbus/auth.rb
149 def send(meth, *args)
150   o = ([meth] + args).join(" ")
151   @socket.write(o + "\r\n")
152 end