Module: Gitlab::Gpg

Extended by:
Gpg
Included in:
Gpg
Defined in:
lib/gitlab/gpg.rb,
lib/gitlab/gpg/commit.rb,
lib/gitlab/gpg/invalid_gpg_signature_updater.rb

Defined Under Namespace

Modules: CurrentKeyChain Classes: Commit, InvalidGpgSignatureUpdater

Constant Summary collapse

CleanupError =
Class.new(StandardError)
BG_CLEANUP_RUNTIME_S =
10
FG_CLEANUP_RUNTIME_S =
1
MUTEX =
Mutex.new

Instance Method Summary collapse

Instance Method Details

#current_home_dirObject

  1. Returns the custom home directory if one has been set by calling `GPGME::Engine.home_dir=`

  2. Returns the default home directory otherwise


91
92
93
# File 'lib/gitlab/gpg.rb', line 91

def current_home_dir
  GPGME::Engine.info.first.home_dir || GPGME::Engine.dirinfo('homedir')
end

#fingerprints_from_key(key) ⇒ Object


29
30
31
32
33
# File 'lib/gitlab/gpg.rb', line 29

def fingerprints_from_key(key)
  using_tmp_keychain do
    CurrentKeyChain.fingerprints_from_key(key)
  end
end

#primary_keyids_from_key(key) ⇒ Object


35
36
37
38
39
40
41
# File 'lib/gitlab/gpg.rb', line 35

def primary_keyids_from_key(key)
  using_tmp_keychain do
    fingerprints = CurrentKeyChain.fingerprints_from_key(key)

    GPGME::Key.find(:public, fingerprints).map { |raw_key| raw_key.primary_subkey.keyid }
  end
end

#subkeys_from_key(key) ⇒ Object


43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/gitlab/gpg.rb', line 43

def subkeys_from_key(key)
  using_tmp_keychain do
    fingerprints = CurrentKeyChain.fingerprints_from_key(key)
    raw_keys     = GPGME::Key.find(:public, fingerprints)

    raw_keys.each_with_object({}) do |raw_key, grouped_subkeys|
      primary_subkey_id = raw_key.primary_subkey.keyid

      grouped_subkeys[primary_subkey_id] = raw_key.subkeys[1..].map do |s|
        { keyid: s.keyid, fingerprint: s.fingerprint }
      end
    end
  end
end

#user_infos_from_key(key) ⇒ Object


58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/gitlab/gpg.rb', line 58

def user_infos_from_key(key)
  using_tmp_keychain do
    fingerprints = CurrentKeyChain.fingerprints_from_key(key)

    GPGME::Key.find(:public, fingerprints).flat_map do |raw_key|
      raw_key.uids.each_with_object([]) do |uid, arr|
        name = uid.name.force_encoding('UTF-8')
        email = uid.email.force_encoding('UTF-8')
        arr << { name: name, email: email.downcase } if name.valid_encoding? && email.valid_encoding?
      end
    end
  end
end

#using_tmp_keychain(&block) ⇒ Object

Allows thread safe switching of temporary keychain files

  1. The current thread may use nesting of temporary keychain

  2. Another thread needs to wait for the lock to be released


76
77
78
79
80
81
82
83
84
85
86
# File 'lib/gitlab/gpg.rb', line 76

def using_tmp_keychain(&block)
  if MUTEX.locked? && MUTEX.owned?
    optimistic_using_tmp_keychain(&block)
  else
    ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
      MUTEX.synchronize do
        optimistic_using_tmp_keychain(&block)
      end
    end
  end
end