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

### Public Instance Methods

authenticate() click to toggle source

Start the authentication process.

    # File lib/dbus/auth.rb, line 127
    def authenticate
      if (RbConfig::CONFIG["target_os"] =~ /freebsd/)
        @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 154
    def next_authenticator
      begin
        raise AuthenticationFailed if @auth_list.size == 0
        @authenticator = @auth_list.shift.new
        auth_msg = ["AUTH", @authenticator.name, @authenticator.authenticate]
        DBus.logger.debug "auth_msg: #{auth_msg.inspect}"
        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 169
    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(" ")
      DBus.logger.debug "readline: #{readline.inspect}"
      return readline
    end

next_state() click to toggle source

    # Read data (a buffer) from the bus until CR LF is encountered.
    # Return the buffer without the CR LF characters.
    def next_msg
      @socket.readline.chomp.split(" ")
    end

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

    # File lib/dbus/auth.rb, line 193
    def next_state
      msg = next_msg
      if @state == :Starting
        DBus.logger.debug ":Starting msg: #{msg[0].inspect}"
        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
      DBus.logger.debug "state: #{@state}"
      case @state
      when :WaitingForData
        DBus.logger.debug ":WaitingForData msg: #{msg[0].inspect}"
        case msg[0]
        when "DATA"
          chall = msg[1]
          resp, chall = @authenticator.data(chall)
          DBus.logger.debug ":WaitingForData/DATA resp: #{resp.inspect}"
          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
        DBus.logger.debug ":WaitingForOk msg: #{msg[0].inspect}"
        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
        DBus.logger.debug ":WaitingForReject msg: #{msg[0].inspect}"
        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 148
    def send(meth, *args)
      o = ([meth] + args).join(" ")
      @socket.write(o + "\r\n")
    end