summaryrefslogtreecommitdiff
path: root/lib/chef/http
diff options
context:
space:
mode:
authorNoah Kantrowitz <noah@coderanger.net>2018-05-30 15:59:57 -0700
committerNoah Kantrowitz <noah@coderanger.net>2018-05-30 15:59:57 -0700
commit3f7ffb322fb8f414ebf28eaa4b6fe4c94d7857a9 (patch)
tree848b088488ae5f92f0d785e8c4ba0165d302c2b5 /lib/chef/http
parenta074d491722bf665da843e76672ffbadf92e3661 (diff)
downloadchef-3f7ffb322fb8f414ebf28eaa4b6fe4c94d7857a9.tar.gz
Add support for signing requests using ssh-agent.
Signed-off-by: Noah Kantrowitz <noah@coderanger.net>
Diffstat (limited to 'lib/chef/http')
-rw-r--r--lib/chef/http/auth_credentials.rb8
-rw-r--r--lib/chef/http/authenticator.rb9
2 files changed, 11 insertions, 6 deletions
diff --git a/lib/chef/http/auth_credentials.rb b/lib/chef/http/auth_credentials.rb
index e2494c9405..eeb9136607 100644
--- a/lib/chef/http/auth_credentials.rb
+++ b/lib/chef/http/auth_credentials.rb
@@ -28,8 +28,10 @@ class Chef
class AuthCredentials
attr_reader :client_name, :key
- def initialize(client_name = nil, key = nil)
- @client_name, @key = client_name, key
+ def initialize(client_name = nil, key = nil, use_ssh_agent: false)
+ @client_name = client_name
+ @key = key
+ @use_ssh_agent = use_ssh_agent
end
def sign_requests?
@@ -48,7 +50,7 @@ class Chef
host = request_params.delete(:host) || "localhost"
sign_obj = Mixlib::Authentication::SignedHeaderAuth.signing_object(request_params)
- signed = sign_obj.sign(key).merge({ :host => host })
+ signed = sign_obj.sign(key, use_ssh_agent: @use_ssh_agent).merge({ :host => host })
signed.inject({}) { |memo, kv| memo["#{kv[0].to_s.upcase}"] = kv[1]; memo }
end
diff --git a/lib/chef/http/authenticator.rb b/lib/chef/http/authenticator.rb
index 65367af107..a20653a055 100644
--- a/lib/chef/http/authenticator.rb
+++ b/lib/chef/http/authenticator.rb
@@ -40,7 +40,7 @@ class Chef
@sign_request = true
@signing_key_filename = opts[:signing_key_filename]
@key = load_signing_key(opts[:signing_key_filename], opts[:raw_key])
- @auth_credentials = AuthCredentials.new(opts[:client_name], @key)
+ @auth_credentials = AuthCredentials.new(opts[:client_name], @key, use_ssh_agent: opts[:ssh_agent_signing])
@version_class = opts[:version_class]
@api_version = opts[:api_version]
end
@@ -89,12 +89,15 @@ class Chef
else
return nil
end
- @key = OpenSSL::PKey::RSA.new(@raw_key)
+ # Pass in '' as the passphrase to avoid OpenSSL prompting on the TTY if
+ # given an encrypted key. This also helps if using a single file for
+ # both the public and private key with ssh-agent mode.
+ @key = OpenSSL::PKey::RSA.new(@raw_key, '')
rescue SystemCallError, IOError => e
Chef::Log.warn "Failed to read the private key #{key_file}: #{e.inspect}"
raise Chef::Exceptions::PrivateKeyMissing, "I cannot read #{key_file}, which you told me to use to sign requests!"
rescue OpenSSL::PKey::RSAError
- msg = "The file #{key_file} or :raw_key option does not contain a correctly formatted private key.\n"
+ msg = "The file #{key_file} or :raw_key option does not contain a correctly formatted private key or the key is encrypted.\n"
msg << "The key file should begin with '-----BEGIN RSA PRIVATE KEY-----' and end with '-----END RSA PRIVATE KEY-----'"
raise Chef::Exceptions::InvalidPrivateKey, msg
end