Module: Xolo::Core::SecurityCmd

Defined in:
lib/xolo/core/security_cmd.rb

Overview

Personal credentials for users of ‘xadm’, stored in the login keychain

Constant Summary collapse

SEC_COMMAND =

The security command

'/usr/bin/security'
SEC_STATUS_NO_GUI_ERROR =

exit status when the login keychain can’t be accessed because we aren’t in a GUI session

36
SEC_STATUS_AUTH_ERROR =

exit status when the keychain password provided is incorrect

51
SEC_STATUS_NOT_FOUND_ERROR =

exit status when the desired item isn’t found in the keychain

44

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(includer) ⇒ Object

when this module is included



40
41
42
# File 'lib/xolo/core/security_cmd.rb', line 40

def self.included(includer)
  Xolo.verbose_include includer, self
end

Instance Method Details

#run_security(cmd) ⇒ String

Run the security command in interactive mode on a given keychain, passing in a subcommand and its arguments. so that they don’t appear in the ‘ps` output

Parameters:

  • cmd (String)

    the subcommand being passed to ‘security’ with all needed options. It will not be visible outide this process, so its OK to put passwords into the options.

Returns:

  • (String)

    the stdout of the ‘security’ command.



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/xolo/core/security_cmd.rb', line 59

def run_security(cmd)
  output = Xolo::BLANK
  errs = Xolo::BLANK

  Open3.popen3("#{SEC_COMMAND} -i") do |stdin, stdout, stderr, wait_thr|
    # pid = wait_thr.pid # pid of the started process.
    stdin.puts cmd
    stdin.close

    output = stdout.read
    errs = stderr.read

    @security_exit_status = wait_thr.value # Process::Status object returned.
  end

  # exit 44 is 'The specified item could not be found in the keychain'
  return output.chomp if @security_exit_status.success?

  case @security_exit_status.exitstatus
  when SEC_STATUS_AUTH_ERROR
    raise Xolo::KeychainError, 'Problem accessing login keychain. Is it locked?'

  when SEC_STATUS_NOT_FOUND_ERROR
    raise Xolo::NoSuchItemError, "No xolo admin password. Please run 'xadm config'"

  else
    errs.chomp!
    errs =~ /: returned\s+(-?\d+)$/
    errnum = Regexp.last_match(1)
    desc = errnum ? security_error_desc(errnum) : errs
    desc ||= errs
    raise Xolo::KeychainError, "#{desc.gsub("\n", '; ')}; exit status #{@security_exit_status.exitstatus}"
  end # case
end

#security_error_desc(num) ⇒ Object

use ‘security error` to get a description of an error number



96
97
98
99
100
101
102
103
# File 'lib/xolo/core/security_cmd.rb', line 96

def security_error_desc(num)
  desc = `#{SEC_COMMAND} error #{num}`
  return if desc.include?('unknown error')

  desc.chomp.split(num).last
rescue
  nil
end

#security_escape(str) ⇒ String

given a string, wrap it in single quotes and escape internal single quotes and backslashes so it can be used in the interactive ‘security’ command

Parameters:

  • str (String)

    the string to escape

Returns:

  • (String)

    the escaped string



112
113
114
115
116
117
118
119
120
121
122
# File 'lib/xolo/core/security_cmd.rb', line 112

def security_escape(str)
  # first escape backslashes
  str = str.to_s.gsub '\\', '\\\\\\'

  # then single quotes
  str.gsub! "'", "\\\\'"

  # if other things need escaping, add them here

  "'#{str}'"
end