Module: GPGStatusParser

Defined in:
lib/gpg_status_parser.rb,
lib/gpg_status_parser/status_codes.rb,
lib/gpg_status_parser/status_message.rb

Defined Under Namespace

Modules: Arguments Classes: InvalidStatus, NotGPGStatus, StatusMessage

Constant Summary collapse

STATUS_CODES =
{
  :NEWSIG => "",
  :GOODSIG => "<long_keyid_or_fpr>  <username>",
  :EXPSIG => "<long_keyid_or_fpr>  <username>",
  :EXPKEYSIG => "<long_keyid_or_fpr> <username>",
  :REVKEYSIG => "<long_keyid_or_fpr>  <username>",
  :BADSIG => "<long_keyid_or_fpr>  <username>",
  :ERRSIG => "<keyid>  <pkalgo> <hashalgo> <sig_class> <time> <rc>",
  :VALIDSIG => "<fingerprint_in_hex> <sig_creation_date> <sig-timestamp> <expire-timestamp> <sig-version> <reserved> <pubkey-algo> <hash-algo> <sig-class> [ <primary-key-fpr> ]",
  :SIG_ID => "<radix64_string>  <sig_creation_date>  <sig-timestamp>",
  :ENC_TO => "<long_keyid>  <keytype>  <keylength>",
  :BEGIN_DECRYPTION => "",
  :END_DECRYPTION => "",
  :DECRYPTION_INFO => "<mdc_method> <sym_algo>",
  :DECRYPTION_FAILED => "",
  :DECRYPTION_OKAY => "",
  :SESSION_KEY => "<algo>:<hexdigits>",
  :BEGIN_ENCRYPTION => "<mdc_method> <sym_algo>",
  :END_ENCRYPTION => "",
  :FILE_START => "<what> <filename>",
  :FILE_DONE => "",
  :BEGIN_SIGNING => "",
  :ALREADY_SIGNED => "<long-keyid>",
  :SIG_CREATED => "<type> <pk_algo> <hash_algo> <class> <timestamp> <keyfpr>",
  :NOTATION_NAME => "<name>",
  :NOTATION_DATA => "<string>",
  :POLICY_URL => "<string>",
  :PLAINTEXT => "<format> <timestamp> <filename>",
  :PLAINTEXT_LENGTH => "<length>",
  :ATTRIBUTE => "<arguments>",
  :SIG_SUBPACKET => "<type> <flags> <len> <data>",
  :INV_RECP => "",
  :INV_SGNR => "",
  :NO_RECP => "<reserved>",
  :NO_SGNR => "<reserved>",
  :KEYEXPIRED => "<expire-timestamp>",
  :SIGEXPIRED => "",
  :KEYREVOKED => "",
  :NO_PUBKEY => "<long keyid>",
  :NO_SECKEY => "<long keyid>",
  :KEY_CREATED => "<type> <fingerprint> [<handle>]",
  :KEY_NOT_CREATED => "[<handle>]",
  :TRUST_UNDEFINED => "<error_token>",
  :TRUST_NEVER => "<error_token>",
  :TRUST_MARGINAL => "[<zero> [<validation_model>]]",
  :TRUST_FULLY => "[<zero> [<validation_model>]]",
  :TRUST_ULTIMATE => "[<zero> [<validation_model>]]",
  :PKA_TRUST_GOOD => "<mailbox>",
  :PKA_TRUST_BAD => "<mailbox>",
  :GET_BOOL => "",
  :GET_LINE => "",
  :GET_HIDDEN => "",
  :GOT_IT => "",
  :USERID_HINT => "<long main keyid> <username>",
  :NEED_PASSPHRASE => "<long keyid> <long main keyid> <keytype> <keylength>",
  :NEED_PASSPHRASE_SYM => "<cipher_algo> <s2k_mode> <s2k_hash>",
  :NEED_PASSPHRASE_PIN => "<card_type> <chvno> [<serialno>]",
  :MISSING_PASSPHRASE => "",
  :BAD_PASSPHRASE => "<long keyid>",
  :GOOD_PASSPHRASE => "",
  :IMPORT_CHECK => "<long keyid> <fingerprint> <user ID>",
  :IMPORTED => "<long keyid>  <username>",
  :IMPORT_OK => "<reason> [<fingerprint>]",
  :IMPORT_PROBLEM => "<reason> [<fingerprint>]",
  :IMPORT_RES => "<count> <no_user_id> <imported> <imported_rsa> <unchanged> <n_uids> <n_subk> <n_sigs> <n_revoc> <sec_read> <sec_imported> <sec_dups> <skipped_new_keys> <not_imported>",
  :CARDCTRL => "<what> [<serialno>]",
  :SC_OP_FAILURE => "[<code>]",
  :SC_OP_SUCCESS => "",
  :NODATA => "<what>",
  :UNEXPECTED => "<what>",
  :TRUNCATED => "<maxno>",
  :ERROR => "<error location> <error code> [<more>]",
  :SUCCESS => "[<location>]",
  :BADARMOR => "",
  :DELETE_PROBLEM => "<reason_code>",
  :PROGRESS => "<what> <char> <cur> <total>",
  :BACKUP_KEY_CREATED => "<fingerprint> <fname>",
  :MOUNTPOINT => "<name>",
  :PINENTRY_LAUNCHED => "<pid>"
}

Class Method Summary collapse

Class Method Details

.parse(file_or_string, &block) ⇒ Object

Takes a file or string and optional block and either yields or returns a list of status messages



13
14
15
16
17
18
19
# File 'lib/gpg_status_parser.rb', line 13

def self.parse(file_or_string, &block)
  if block
    file_or_string.each_line { |line| yield parse_line(line)}
  else
    file_or_string.each_line.map{ |line| parse_line(line)}
  end
end

.parse_line(line) ⇒ Object

Parse a single line



7
8
9
# File 'lib/gpg_status_parser.rb', line 7

def self.parse_line(line)
  GPGStatusParser::StatusMessage.new(line.strip)
end

.run_gpg(args, data = nil, &block) ⇒ Object

Run a gpg command, and take care of setting up and tearing down the required temporary files. Just pass in the arguments you want to send to gpg:

GPGStatusParser.run_gpg("--verify foo.txt.asc foo.txt")

and not:

GPGStatusParser.run_gpg("gpg --verify foo.txt.asc foo.txt")

It is highly advised that you escape and/or scrub any user generated input to make sure it is safe. See Shellwords#shell_escape in the ruby standard library.



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/gpg_status_parser.rb', line 34

def self.run_gpg args, data=nil, &block
  exit_status = nil
  status_file = Tempfile.new("status")

  full_gpg_command = "gpg --status-file #{status_file.path} #{args}"
  gpg_results = Open3.popen3(full_gpg_command) do |stdin, stdout, stderr, wait_thr|
    stdin.write data if data
    stdin.close
    exit_status = wait_thr.value
    parse(status_file, &block)
    out = stdout.read()
    err = stderr.read()
    {:status => exit_status, :stdout => out, :err => err}
  end
  gpg_results
ensure
  status_file.close
  status_file.unlink
end