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, line 115
def initialize(socket)
  @socket = socket
  @state = nil
  @auth_list = [External,DBusCookieSHA1]
end

Public Instance Methods

authenticate() click to toggle source

Start the authentication process.

# File lib/dbus/auth.rb, line 122
def authenticate
  if (RbConfig::CONFIG["target_os"] =~ /bsd/)
    @socket.sendmsg(0.chr, 0, nil, [:SOCKET, :SCM_CREDS, ""])
  else
    @socket.write(0.chr)
  end
  next_authenticator
  @state = :Starting
  while @state != :Authenticated
    r = next_state
    return r if not r
  end
  true
end

Private Instance Methods

next_authenticator() click to toggle source

Try authentication using the next authenticator.

# File lib/dbus/auth.rb, line 149
def next_authenticator
  begin
    raise AuthenticationFailed if @auth_list.size == 0
    @authenticator = @auth_list.shift.new
    auth_msg = ["AUTH", @authenticator.name, @authenticator.authenticate]
    puts "DEBUG: auth_msg: #{auth_msg.inspect}" if $debug
    send(auth_msg)
  rescue AuthenticationFailed
    @socket.close
    raise
  end
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, line 164
def next_msg
  data,crlf = "","\r\n"
  left = 1024 #1024 byte, no idea if it's ever getting bigger
  while left > 0
    buf = @socket.read( left > 1 ? 1 : left )
    break if buf.nil?
    left -= buf.bytesize
    data += buf
    break if data.include? crlf #crlf means line finished, the TCP socket keeps on listening, so we break
  end
  readline = data.chomp.split(" ")
  puts "DEBUG: readline: #{readline.inspect}" if $debug
  return readline
end
next_state() click to toggle source

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

# File lib/dbus/auth.rb, line 188
def next_state
  msg = next_msg
  if @state == :Starting
    puts "DEBUG: :Starting msg: #{msg[0].inspect}" if $debug
    case msg[0]
    when "OK"
      @state = :WaitingForOk    
    when "CONTINUE"
      @state = :WaitingForData
    when "REJECTED" #needed by tcp, unix-path/abstract doesn't get here
      @state = :WaitingForData
    end
  end
  puts "DEBUG: state: #{@state}" if $debug
  case @state
  when :WaitingForData
    puts "DEBUG: :WaitingForData msg: #{msg[0].inspect}" if $debug
    case msg[0]
    when "DATA"
      chall = msg[1]
      resp, chall = @authenticator.data(chall)
      puts "DEBUG: :WaitingForData/DATA resp: #{resp.inspect}" if $debug
      case resp
      when :AuthContinue
        send("DATA", chall)
        @state = :WaitingForData
      when :AuthOk
        send("DATA", chall)
        @state = :WaitingForOk
      when :AuthError
        send("ERROR")
        @state = :WaitingForData
      end
    when "REJECTED"
      next_authenticator
      @state = :WaitingForData
    when "ERROR"
      send("CANCEL")
      @state = :WaitingForReject
    when "OK"
      send("BEGIN")
      @state = :Authenticated
    else
      send("ERROR")
      @state = :WaitingForData
    end
  when :WaitingForOk
    puts "DEBUG: :WaitingForOk msg: #{msg[0].inspect}" if $debug
    case msg[0]
    when "OK"
      send("BEGIN")
      @state = :Authenticated
    when "REJECT"
      next_authenticator
      @state = :WaitingForData
    when "DATA", "ERROR"
      send("CANCEL")
      @state = :WaitingForReject
    else
      send("ERROR")
      @state = :WaitingForOk
    end
  when :WaitingForReject
    puts "DEBUG: :WaitingForReject msg: #{msg[0].inspect}" if $debug
    case msg[0]
    when "REJECT"
      next_authenticator
      @state = :WaitingForOk
    else
      @socket.close
      return false
    end
  end
  return true
end
send(meth, *args) click to toggle source

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

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