diff options
author | Bryan McLellan <btm@loftninjas.org> | 2012-08-06 13:18:03 -0700 |
---|---|---|
committer | Bryan McLellan <btm@loftninjas.org> | 2012-08-06 13:18:03 -0700 |
commit | 92872c4fe201bcacfef76b281684e5164c9f935b (patch) | |
tree | d48cb04e5d5800a6122e6d506beb37f64ea86806 | |
parent | 10e5932e10071d22256f67fbec9edae1281de682 (diff) | |
parent | 791478bfefa1ea68908bd11a3bb0b07b32c8daf6 (diff) | |
download | chef-92872c4fe201bcacfef76b281684e5164c9f935b.tar.gz |
Merge branch 'CHEF-3095-w-backcompat'
-rw-r--r-- | chef/chef.gemspec | 2 | ||||
-rw-r--r-- | chef/lib/chef/client.rb | 6 | ||||
-rw-r--r-- | chef/lib/chef/config.rb | 29 | ||||
-rw-r--r-- | chef/lib/chef/knife.rb | 4 | ||||
-rw-r--r-- | chef/lib/chef/rest/auth_credentials.rb | 7 | ||||
-rw-r--r-- | chef/spec/unit/client_spec.rb | 24 | ||||
-rw-r--r-- | chef/spec/unit/rest/auth_credentials_spec.rb | 50 |
7 files changed, 104 insertions, 18 deletions
diff --git a/chef/chef.gemspec b/chef/chef.gemspec index 34f39790f6..ccdd5bccb0 100644 --- a/chef/chef.gemspec +++ b/chef/chef.gemspec @@ -16,7 +16,7 @@ Gem::Specification.new do |s| s.add_dependency "mixlib-config", ">= 1.1.2" s.add_dependency "mixlib-cli", ">= 1.1.0" s.add_dependency "mixlib-log", ">= 1.3.0" - s.add_dependency "mixlib-authentication", ">= 1.1.0" + s.add_dependency "mixlib-authentication", ">= 1.3.0" s.add_dependency "mixlib-shellout" s.add_dependency "ohai", ">= 0.6.0" diff --git a/chef/lib/chef/client.rb b/chef/lib/chef/client.rb index ed052c1fdd..8f57cdd5a0 100644 --- a/chef/lib/chef/client.rb +++ b/chef/lib/chef/client.rb @@ -224,6 +224,12 @@ class Chef raise Chef::Exceptions::CannotDetermineNodeName, msg end + # node names > 90 bytes only work with authentication protocol >= 1.1 + # see discussion in config.rb. + if name.bytesize > 90 + Chef::Config[:authentication_protocol_version] = "1.1" + end + name end diff --git a/chef/lib/chef/config.rb b/chef/lib/chef/config.rb index 727314280f..65e985848b 100644 --- a/chef/lib/chef/config.rb +++ b/chef/lib/chef/config.rb @@ -232,7 +232,36 @@ class Chef # (persist across rabbitmq restarts) amqp_consumer_id "default" + # Sets the version of the signed header authentication protocol to use (see + # the 'mixlib-authorization' project for more detail). Currently, versions + # 1.0 and 1.1 are available; however, the chef-server must first be + # upgraded to support version 1.1 before clients can begin using it. + # + # Version 1.1 of the protocol is required when using a `node_name` greater + # than ~90 bytes (~90 ascii characters), so chef-client will automatically + # switch to using version 1.1 when `node_name` is too large for the 1.0 + # protocol. If you intend to use large node names, ensure that your server + # supports version 1.1. Automatic detection of large node names means that + # users will generally not need to manually configure this. + # + # In the future, this configuration option may be replaced with an + # automatic negotiation scheme. + authentication_protocol_version "1.0" + + # This key will be used to sign requests to the Chef server. This location + # must be writable by Chef during initial setup when generating a client + # identity on the server. + # + # The chef-server will look up the public key for the client using the + # `node_name` of the client. client_key platform_specific_path("/etc/chef/client.pem") + + # If there is no file in the location given by `client_key`, chef-client + # will temporarily use the "validator" identity to generate one. If the + # `client_key` is not present and the `validation_key` is also not present, + # chef-client will not be able to authenticate to the server. + # + # The `validation_key` is never used if the `client_key` exists. validation_key platform_specific_path("/etc/chef/validation.pem") validation_client_name "chef-validator" web_ui_client_name "chef-webui" diff --git a/chef/lib/chef/knife.rb b/chef/lib/chef/knife.rb index 03b8ef4690..c664503cee 100644 --- a/chef/lib/chef/knife.rb +++ b/chef/lib/chef/knife.rb @@ -352,6 +352,10 @@ class Chef if Chef::Config[:node_name].nil? #raise ArgumentError, "No user specified, pass via -u or specifiy 'node_name' in #{config[:config_file] ? config[:config_file] : "~/.chef/knife.rb"}" + elsif Chef::Config[:node_name].bytesize > 90 + # node names > 90 bytes only work with authentication protocol >= 1.1 + # see discussion in config.rb. + Chef::Config[:authentication_protocol_version] = "1.1" end end diff --git a/chef/lib/chef/rest/auth_credentials.rb b/chef/lib/chef/rest/auth_credentials.rb index ec9341015b..b95defcdb5 100644 --- a/chef/lib/chef/rest/auth_credentials.rb +++ b/chef/lib/chef/rest/auth_credentials.rb @@ -43,9 +43,10 @@ class Chef Chef::Log.debug("Signing the request as #{client_name}") # params_in = {:http_method => :GET, :path => "/clients", :body => "", :host => "localhost"} - request_params = request_params.dup - request_params[:timestamp] = Time.now.utc.iso8601 - request_params[:user_id] = client_name + request_params = request_params.dup + request_params[:timestamp] = Time.now.utc.iso8601 + request_params[:user_id] = client_name + request_params[:proto_version] = Chef::Config[:authentication_protocol_version] host = request_params.delete(:host) || "localhost" sign_obj = Mixlib::Authentication::SignedHeaderAuth.signing_object(request_params) diff --git a/chef/spec/unit/client_spec.rb b/chef/spec/unit/client_spec.rb index 64bb8799de..d1f0fe130e 100644 --- a/chef/spec/unit/client_spec.rb +++ b/chef/spec/unit/client_spec.rb @@ -51,6 +51,30 @@ shared_examples_for Chef::Client do @client.node = @node end + describe "authentication protocol selection" do + after do + Chef::Config[:authentication_protocol_version] = "1.0" + end + + context "when the node name is <= 90 bytes" do + it "does not force the authentication protocol to 1.1" do + Chef::Config[:node_name] = ("f" * 90) + # ugly that this happens as a side effect of a getter :( + @client.node_name + Chef::Config[:authentication_protocol_version].should == "1.0" + end + end + + context "when the node name is > 90 bytes" do + it "sets the authentication protocol to version 1.1" do + Chef::Config[:node_name] = ("f" * 91) + # ugly that this happens as a side effect of a getter :( + @client.node_name + Chef::Config[:authentication_protocol_version].should == "1.1" + end + end + end + describe "run" do it "should identify the node and run ohai, then register the client" do diff --git a/chef/spec/unit/rest/auth_credentials_spec.rb b/chef/spec/unit/rest/auth_credentials_spec.rb index 8dcc48a8b6..a2034f96ed 100644 --- a/chef/spec/unit/rest/auth_credentials_spec.rb +++ b/chef/spec/unit/rest/auth_credentials_spec.rb @@ -97,20 +97,42 @@ describe Chef::REST::AuthCredentials do it "generates signature headers for the request" do Time.stub!(:now).and_return(@request_time) - expected = {} - expected["HOST"] = "localhost" - expected["X-OPS-AUTHORIZATION-1"] = "kBssX1ENEwKtNYFrHElN9vYGWS7OeowepN9EsYc9csWfh8oUovryPKDxytQ/" - expected["X-OPS-AUTHORIZATION-2"] = "Wc2/nSSyxdWJjjfHzrE+YrqNQTaArOA7JkAf5p75eTUonCWcvNPjFrZVgKGS" - expected["X-OPS-AUTHORIZATION-3"] = "yhzHJQh+lcVA9wwARg5Hu9q+ddS8xBOdm3Vp5atl5NGHiP0loiigMYvAvzPO" - expected["X-OPS-AUTHORIZATION-4"] = "r9853eIxwYMhn5hLGhAGFQznJbE8+7F/lLU5Zmk2t2MlPY8q3o1Q61YD8QiJ" - expected["X-OPS-AUTHORIZATION-5"] = "M8lIt53ckMyUmSU0DDURoiXLVkE9mag/6Yq2tPNzWq2AdFvBqku9h2w+DY5k" - expected["X-OPS-AUTHORIZATION-6"] = "qA5Rnzw5rPpp3nrWA9jKkPw4Wq3+4ufO2Xs6w7GCjA==" - expected["X-OPS-CONTENT-HASH"] = "1tuzs5XKztM1ANrkGNPah6rW9GY=" - expected["X-OPS-SIGN"] = "version=1.0" - expected["X-OPS-TIMESTAMP"] = "2010-04-10T17:34:20Z" - expected["X-OPS-USERID"] = "client-name" - - @auth_credentials.signature_headers(@request_params).should == expected + actual = @auth_credentials.signature_headers(@request_params) + actual["HOST"].should == "localhost" + actual["X-OPS-AUTHORIZATION-1"].should == "kBssX1ENEwKtNYFrHElN9vYGWS7OeowepN9EsYc9csWfh8oUovryPKDxytQ/" + actual["X-OPS-AUTHORIZATION-2"].should == "Wc2/nSSyxdWJjjfHzrE+YrqNQTaArOA7JkAf5p75eTUonCWcvNPjFrZVgKGS" + actual["X-OPS-AUTHORIZATION-3"].should == "yhzHJQh+lcVA9wwARg5Hu9q+ddS8xBOdm3Vp5atl5NGHiP0loiigMYvAvzPO" + actual["X-OPS-AUTHORIZATION-4"].should == "r9853eIxwYMhn5hLGhAGFQznJbE8+7F/lLU5Zmk2t2MlPY8q3o1Q61YD8QiJ" + actual["X-OPS-AUTHORIZATION-5"].should == "M8lIt53ckMyUmSU0DDURoiXLVkE9mag/6Yq2tPNzWq2AdFvBqku9h2w+DY5k" + actual["X-OPS-AUTHORIZATION-6"].should == "qA5Rnzw5rPpp3nrWA9jKkPw4Wq3+4ufO2Xs6w7GCjA==" + actual["X-OPS-CONTENT-HASH"].should == "1tuzs5XKztM1ANrkGNPah6rW9GY=" + actual["X-OPS-SIGN"].should =~ %r{(version=1\.0)|(algorithm=sha1;version=1.0;)} + actual["X-OPS-TIMESTAMP"].should == "2010-04-10T17:34:20Z" + actual["X-OPS-USERID"].should == "client-name" + + end + + describe "when configured for version 1.1 of the authn protocol" do + before do + Chef::Config[:authentication_protocol_version] = "1.1" + end + + after do + Chef::Config[:authentication_protocol_version] = "1.0" + end + + it "generates the correct signature for version 1.1" do + Time.stub!(:now).and_return(@request_time) + actual = @auth_credentials.signature_headers(@request_params) + actual["HOST"].should == "localhost" + actual["X-OPS-CONTENT-HASH"].should == "1tuzs5XKztM1ANrkGNPah6rW9GY=" + actual["X-OPS-SIGN"].should == "algorithm=sha1;version=1.1;" + actual["X-OPS-TIMESTAMP"].should == "2010-04-10T17:34:20Z" + actual["X-OPS-USERID"].should == "client-name" + + # mixlib-authN will test the actual signature stuff for each version of + # the protocol so we won't test it again here. + end end end end |