diff options
author | danielsdeleo <dan@getchef.com> | 2014-03-25 16:51:03 -0700 |
---|---|---|
committer | danielsdeleo <dan@getchef.com> | 2014-03-25 16:51:03 -0700 |
commit | 6231d5f3faa6d94051c3a7878742b3b9a684e374 (patch) | |
tree | d49aa16f17f5fb47ccf53e17df46861b33abf30a /lib | |
parent | 6b045b48bb40b0fc912d7077b7de5f7987c6cdc9 (diff) | |
download | chef-6231d5f3faa6d94051c3a7878742b3b9a684e374.tar.gz |
Add optional client-side key generation when registering
Diffstat (limited to 'lib')
-rw-r--r-- | lib/chef/api_client/registration.rb | 55 | ||||
-rw-r--r-- | lib/chef/config.rb | 11 |
2 files changed, 57 insertions, 9 deletions
diff --git a/lib/chef/api_client/registration.rb b/lib/chef/api_client/registration.rb index f44c326d5d..213d0b7f49 100644 --- a/lib/chef/api_client/registration.rb +++ b/lib/chef/api_client/registration.rb @@ -30,14 +30,13 @@ class Chef # a new client/node identity by borrowing the validator client identity # when creating a new client. class Registration - attr_reader :private_key attr_reader :destination attr_reader :name def initialize(name, destination) @name = name @destination = destination - @private_key = nil + @server_generated_private_key = nil end # Runs the client registration process, including creating the client on @@ -90,29 +89,67 @@ class Chef end def create - response = http_api.post("clients", :name => name, :admin => false) - @private_key = response["private_key"] + response = http_api.post("clients", post_data) + @server_generated_private_key = response["private_key"] response end def update - response = http_api.put("clients/#{name}", :name => name, - :admin => false, - :private_key => true) + response = http_api.put("clients/#{name}", put_data) if response.respond_to?(:private_key) # Chef 11 - @private_key = response.private_key + @server_generated_private_key = response.private_key else # Chef 10 - @private_key = response["private_key"] + @server_generated_private_key = response["private_key"] end response end + def put_data + base_put_data = { :name => name, :admin => false } + if self_generate_keys? + base_put_data[:public_key] = generated_public_key + else + base_put_data[:private_key] = true + end + base_put_data + end + + def post_data + post_data = { :name => name, :admin => false } + post_data[:public_key] = generated_public_key if self_generate_keys? + post_data + end + + def http_api @http_api_as_validator ||= Chef::REST.new(Chef::Config[:chef_server_url], Chef::Config[:validation_client_name], Chef::Config[:validation_key]) end + # Whether or not to generate keys locally and post the public key to the + # server. Delegates to `Chef::Config.local_key_generation`. Servers + # before 11.0 do not support this feature. + def self_generate_keys? + Chef::Config.local_key_generation + end + + def private_key + if self_generate_keys? + generated_private_key.to_pem + else + @server_generated_private_key + end + end + + def generated_private_key + @generated_key ||= OpenSSL::PKey::RSA.generate(2048) + end + + def generated_public_key + generated_private_key.public_key.to_pem + end + def file_flags base_flags = File::CREAT|File::TRUNC|File::RDWR # Windows doesn't have symlinks, so it doesn't have NOFOLLOW diff --git a/lib/chef/config.rb b/lib/chef/config.rb index da3f3790f6..3099d876c1 100644 --- a/lib/chef/config.rb +++ b/lib/chef/config.rb @@ -432,6 +432,17 @@ class Chef default(:validation_key) { chef_zero.enabled ? nil : platform_specific_path("/etc/chef/validation.pem") } default :validation_client_name, "chef-validator" + # When creating a new client via the validation_client account, Chef 11 + # servers allow the client to generate a key pair locally and sent the + # public key to the server. This is more secure and helps offload work from + # the server, enhancing scalability. If enabled and the remote server + # implements only the Chef 10 API, client registration will not work + # properly. + # + # The default value is `false` (Server generates client keys). Set to + # `true` to enable client-side key generation. + default(:local_key_generation) { false } + # Zypper package provider gpg checks. Set to true to enable package # gpg signature checking. This will be default in the # future. Setting to false disables the warnings. |