samlr 2.1.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of samlr might be problematic. Click here for more details.

@@ -1,45 +0,0 @@
1
- require File.expand_path("test/test_helper")
2
-
3
- describe Samlr::Fingerprint do
4
- describe "#new" do
5
- it "generates an invalid fingerprint for nil" do
6
- refute Samlr::Fingerprint.new(nil).valid?
7
- end
8
- end
9
-
10
- describe "::normalize!" do
11
- it "converts input to fingerprint normal form" do
12
- assert_equal "AF:44", Samlr::Fingerprint.normalize("aF44 :-+6t")
13
- end
14
- end
15
-
16
- describe "#==" do
17
- it "compares two fingerprints" do
18
- assert (Samlr::Fingerprint.new("aa:33") == Samlr::Fingerprint.new("AA:33"))
19
- assert (Samlr::Fingerprint.new("aa:33") != Samlr::Fingerprint.new("AA:34"))
20
- assert (Samlr::Fingerprint.new("") != Samlr::Fingerprint.new(""))
21
- end
22
- end
23
-
24
- describe "#compare!" do
25
- it "raises when fingerprints do not equal" do
26
- assert_raises(Samlr::FingerprintError) do
27
- Samlr::Fingerprint.new("aa:34").compare!(Samlr::Fingerprint.new("bb:35"))
28
- end
29
- end
30
-
31
- it "stores fingerprints on the exception" do
32
- begin
33
- Samlr::Fingerprint.new("aa:34").compare!(Samlr::Fingerprint.new("bb:35"))
34
- flunk "Exception expected"
35
- rescue Samlr::FingerprintError => e
36
- assert_equal "Fingerprint mismatch", e.message
37
- assert_equal "AA:34 vs. BB:35", e.details
38
- end
39
- end
40
-
41
- it "doesn't raise when fingerprints are equal" do
42
- assert Samlr::Fingerprint.new("aa:34").compare!(Samlr::Fingerprint.new("aa:34"))
43
- end
44
- end
45
- end
@@ -1,73 +0,0 @@
1
- require File.expand_path("test/test_helper")
2
-
3
- describe Samlr::LogoutRequest do
4
- let(:options) {
5
- {
6
- :issuer => "https://sp.example.com/saml2",
7
- :name_id => "test@test.com"
8
- }
9
- }
10
-
11
- before do
12
- @request = Samlr::LogoutRequest.new(options)
13
- end
14
-
15
- describe "#body" do
16
- it "should return the generated XML" do
17
- document = Nokogiri::XML(@request.body) { |c| c.strict }
18
- assert document.at("/samlp:LogoutRequest", Samlr::NS_MAP)
19
- end
20
-
21
- it "should delegate the building to the LogoutRequestBuilder" do
22
- Samlr::Tools::LogoutRequestBuilder.stub(:build, "hello") do
23
- assert_match "hello", @request.body
24
- end
25
- end
26
- end
27
-
28
- describe "#param" do
29
- it "returns the encoded body" do
30
- @request.stub(:body, "hello") do
31
- assert_equal Samlr::Tools.encode("hello"), @request.param
32
- end
33
- end
34
- end
35
-
36
- describe "#url" do
37
- it "returns a valid URL" do
38
- @request.stub(:param, "hello") do
39
- assert_equal("https://foo.com/?SAMLRequest=hello&foo=bar", @request.url("https://foo.com/", :foo => "bar"))
40
- end
41
- end
42
- end
43
-
44
- describe "with optional params" do
45
- it "understands name_id_format" do
46
- options.merge!(:name_id_format => "some format")
47
- request = Samlr::LogoutRequest.new(options)
48
-
49
- assert_match /<saml:NameID Format="some format">/, request.body
50
- end
51
-
52
- it "understands [:name_id_options][:format]" do
53
- options.merge!(:name_id_options => {:format => "some format"})
54
- request = Samlr::LogoutRequest.new(options)
55
-
56
- assert_match /<saml:NameID Format="some format">/, request.body
57
- end
58
-
59
- it "understands NameQualifier" do
60
- options.merge!(:name_id_options => {:name_qualifier => "Some name qualifier"})
61
- request = Samlr::LogoutRequest.new(options)
62
-
63
- assert_match /NameQualifier="Some name qualifier"/, request.body
64
- end
65
-
66
- it "understands SPNameQualifier" do
67
- options.merge!(:name_id_options => {:spname_qualifier => "Some SPName qualifier"})
68
- request = Samlr::LogoutRequest.new(options)
69
-
70
- assert_match /SPNameQualifier="Some SPName qualifier"/, request.body
71
- end
72
- end
73
- end
@@ -1,32 +0,0 @@
1
- require File.expand_path("test/test_helper")
2
-
3
- describe Samlr::Reference do
4
- before do
5
- @response = fixed_saml_response
6
- @reference = @response.signature.send(:references).first
7
- end
8
-
9
- describe "#uri" do
10
- it "should return the normalized URI" do
11
- assert_equal "samlr123", @reference.uri
12
- end
13
- end
14
-
15
- describe "#digest_method" do
16
- it "should return the digest implementation" do
17
- assert_equal OpenSSL::Digest::SHA1, @reference.digest_method
18
- end
19
- end
20
-
21
- describe "#digest_value" do
22
- it "should return the verbatim value" do
23
- assert_equal "OSVXSTu8W+eGao6muxUHXcKQwZU=", @reference.digest_value
24
- end
25
- end
26
-
27
- describe "namespaces" do
28
- it "should return the inclusive namespaces" do
29
- assert_equal ["#default", "samlp", "saml", "ds", "xs", "xsi"].sort, @reference.namespaces.sort
30
- end
31
- end
32
- end
@@ -1,34 +0,0 @@
1
- require File.expand_path("test/test_helper")
2
-
3
- describe Samlr::Request do
4
- before { @request = Samlr::Request.new }
5
-
6
- describe "#body" do
7
- it "should return the generated XML" do
8
- document = Nokogiri::XML(@request.body) { |c| c.strict }
9
- assert document.at("/samlp:AuthnRequest", Samlr::NS_MAP)
10
- end
11
-
12
- it "should delegate the building to the RequestBuilder" do
13
- Samlr::Tools::RequestBuilder.stub(:build, "hello") do
14
- assert_match "hello", @request.body
15
- end
16
- end
17
- end
18
-
19
- describe "#param" do
20
- it "returns the encoded body" do
21
- @request.stub(:body, "hello") do
22
- assert_equal Samlr::Tools.encode("hello"), @request.param
23
- end
24
- end
25
- end
26
-
27
- describe "#url" do
28
- it "returns a valid URL" do
29
- @request.stub(:param, "hello") do
30
- assert_equal("https://foo.com/?SAMLRequest=hello&foo=bar", @request.url("https://foo.com/", :foo => "bar"))
31
- end
32
- end
33
- end
34
- end
@@ -1,94 +0,0 @@
1
- require File.expand_path("test/test_helper")
2
-
3
- describe Samlr::Response do
4
-
5
- subject { fixed_saml_response }
6
-
7
- describe "#name_id" do
8
- it "delegates to the assertion" do
9
- subject.assertion.stub(:name_id, "george") do
10
- assert_equal("george", subject.name_id)
11
- end
12
- end
13
- end
14
-
15
- describe "#attributes" do
16
- it "delegates to the assertion" do
17
- subject.assertion.stub(:attributes, { :name => "george" }) do
18
- assert_equal({ :name => "george" }, subject.attributes)
19
- end
20
- end
21
- end
22
-
23
- describe "#location" do
24
- it "should return proper assertion location" do
25
- assert_equal "//saml:Assertion[@ID='samlr456']", subject.assertion.location
26
- end
27
- end
28
-
29
- describe "XSW attack" do
30
- it "should not validate if SAML response is hacked" do
31
- document = saml_response_document(:certificate => TEST_CERTIFICATE)
32
-
33
- modified_document = Nokogiri::XML(document)
34
-
35
- original_assertion = modified_document.xpath("/samlp:Response/saml:Assertion", Samlr::NS_MAP).first
36
-
37
- response_signature = modified_document.xpath("/samlp:Response/ds:Signature", Samlr::NS_MAP).first
38
-
39
- extensions = Nokogiri::XML::Node.new "Extensions", modified_document
40
- extensions << original_assertion.to_xml(:save_with => Nokogiri::XML::Node::SaveOptions::AS_XML)
41
- response_signature.add_next_sibling(extensions)
42
- response_signature.remove()
43
-
44
- modified_document.xpath("/samlp:Response/samlp:Extensions/saml:Assertion/ds:Signature", Samlr::NS_MAP).remove
45
- modified_document.xpath("/samlp:Response/saml:Assertion/saml:Subject/saml:NameID", Samlr::NS_MAP).first.content="evil@example.org"
46
- modified_document.xpath("/samlp:Response/saml:Assertion", Samlr::NS_MAP).first["ID"] = "evil_id"
47
-
48
- response = Samlr::Response.new(modified_document.to_xml(:save_with => Nokogiri::XML::Node::SaveOptions::AS_XML), {:certificate => TEST_CERTIFICATE.x509})
49
- assert_raises(Samlr::FormatError) { response.verify! }
50
- end
51
- end
52
-
53
- describe "::parse" do
54
- before { @document = saml_response_document(:certificate => TEST_CERTIFICATE) }
55
-
56
- describe "when given a raw XML response" do
57
- it "constructs and XML document" do
58
- assert_equal Nokogiri::XML::Document, Samlr::Response.parse(@document).class
59
- end
60
- end
61
-
62
- describe "when given a Base64 encoded response" do
63
- subject { Base64.encode64(@document) }
64
-
65
- it "constructs and XML document" do
66
- assert_equal Nokogiri::XML::Document, Samlr::Response.parse(subject).class
67
- end
68
- end
69
-
70
- describe "when given an invalid string" do
71
- it "fails" do
72
- assert_raises(Samlr::FormatError) { Samlr::Response.parse("hello") }
73
- end
74
- end
75
-
76
- describe "when given a malformed XML response" do
77
- subject { saml_response_document(:certificate => TEST_CERTIFICATE).gsub("Assertion", "AyCaramba") }
78
- after { Samlr.validation_mode = :reject }
79
-
80
- describe "and Samlr.validation_mode == :log" do
81
- before { Samlr.validation_mode = :log }
82
- it "does not raise" do
83
- assert Samlr::Response.parse(subject)
84
- end
85
- end
86
-
87
- describe "and Samlr.validation_mode != :log" do
88
- it "raises" do
89
- assert_raises(Samlr::FormatError) { Samlr::Response.parse(subject) }
90
- end
91
- end
92
- end
93
- end
94
- end
@@ -1,126 +0,0 @@
1
- require File.expand_path("test/test_helper")
2
-
3
- # The tests in here are integraton level tests. They pass various mutations of a response
4
- # document to the stack and asserts behavior.
5
- describe Samlr do
6
-
7
- describe "a valid response" do
8
- subject { saml_response(:certificate => TEST_CERTIFICATE) }
9
-
10
- it "verifies" do
11
- assert subject.verify!
12
- assert_equal "someone@example.org", subject.name_id
13
- end
14
- end
15
-
16
- describe "an invalid fingerprint" do
17
- subject { saml_response(:certificate => TEST_CERTIFICATE, :fingerprint => "hello") }
18
- it "fails" do
19
- assert_raises(Samlr::FingerprintError) { subject.verify! }
20
- end
21
- end
22
-
23
- describe "an unsatisfied before condition" do
24
- subject { saml_response(:certificate => TEST_CERTIFICATE, :not_before => Samlr::Tools::Timestamp.stamp(Time.now + 60)) }
25
-
26
- it "fails" do
27
- assert_raises(Samlr::ConditionsError) { subject.verify! }
28
- end
29
-
30
- describe "when jitter is in effect" do
31
- after { Samlr.jitter = nil }
32
-
33
- it "passes" do
34
- Samlr.jitter = 500
35
- assert subject.verify!
36
- end
37
- end
38
- end
39
-
40
- describe "an unsatisfied after condition" do
41
- subject { saml_response(:certificate => TEST_CERTIFICATE, :not_on_or_after => Samlr::Tools::Timestamp.stamp(Time.now - 60)) }
42
-
43
- it "fails" do
44
- assert_raises(Samlr::ConditionsError) { subject.verify! }
45
- end
46
-
47
- describe "when jitter is in effect" do
48
- after { Samlr.jitter = nil }
49
-
50
- it "passes" do
51
- Samlr.jitter = 500
52
- assert subject.verify!
53
- end
54
- end
55
- end
56
-
57
- describe "when there are no attributes" do
58
- subject { saml_response(:certificate => TEST_CERTIFICATE, :attributes => {}) }
59
-
60
- it "returns an empty hash" do
61
- assert_equal({}, subject.attributes)
62
- end
63
- end
64
-
65
- describe "when there are no signatures" do
66
- subject { saml_response(:certificate => TEST_CERTIFICATE, :sign_assertion => false, :sign_response => false) }
67
-
68
- it "fails" do
69
- assert_raises(Samlr::SignatureError) { subject.verify! }
70
- end
71
- end
72
-
73
- describe "when there is no keyinfo" do
74
- subject { saml_response(:certificate => TEST_CERTIFICATE, :skip_response_keyinfo => true, :skip_assertion_keyinfo => true) }
75
-
76
- it "fails" do
77
- assert_raises(Samlr::SignatureError) { subject.verify! }
78
- end
79
-
80
- describe "when a matching external cert is provided" do
81
- it "passes" do
82
- subject.options[:certificate] = TEST_CERTIFICATE.x509
83
- assert subject.verify!
84
- end
85
- end
86
-
87
- describe "when a non-matching external cert is provided" do
88
- it "fails" do
89
- subject.options[:certificate] = Samlr::Tools::CertificateBuilder.new.x509
90
- assert_raises(Samlr::FingerprintError) { subject.verify! }
91
- end
92
- end
93
- end
94
-
95
- describe "when there's no assertion" do
96
- subject { saml_response(:certificate => TEST_CERTIFICATE, :sign_assertion => false, :skip_assertion => true) }
97
-
98
- it "fails" do
99
- assert_raises(Samlr::FormatError) { subject.verify! }
100
- end
101
- end
102
-
103
- describe "duplicate element ids" do
104
- subject { saml_response(:certificate => TEST_CERTIFICATE, :response_id => "abcdef", :assertion_id => "abcdef") }
105
-
106
- it "fails" do
107
- assert_raises(Samlr::FormatError) { subject.verify! }
108
- end
109
- end
110
-
111
- describe "when only the response signature is missing a certificate" do
112
- subject { saml_response(:certificate => TEST_CERTIFICATE, :skip_response_keyinfo => true) }
113
-
114
- it "verifies" do
115
- assert subject.verify!
116
- end
117
- end
118
-
119
- describe "when only the assertion signature is missing a certificate" do
120
- subject { saml_response(:certificate => TEST_CERTIFICATE, :skip_assertion_keyinfo => true) }
121
-
122
- it "verifies" do
123
- assert subject.verify!
124
- end
125
- end
126
- end
@@ -1,54 +0,0 @@
1
- require File.expand_path("test/test_helper")
2
- require "openssl"
3
-
4
- describe Samlr::Signature do
5
- before do
6
- @response = fixed_saml_response
7
- @signature = @response.signature
8
- end
9
-
10
- describe "#signature_algorithm" do
11
- it "should defer to Samlr::Tools::algorithm" do
12
- Samlr::Tools.stub(:algorithm, "hello") do
13
- assert_match "hello", @signature.send(:signature_method)
14
- end
15
- end
16
- end
17
-
18
- describe "#references" do
19
- it "should extract the reference to the signed document" do
20
- assert_equal @response.document.children.first, @response.document.at(".//*[@ID='#{@signature.send(:references).first.uri}']")
21
- end
22
- end
23
-
24
- describe "#certificate!" do
25
- it "should extract the certificate" do
26
- assert_equal TEST_CERTIFICATE.to_certificate, @signature.send(:certificate!)
27
- end
28
-
29
- describe "when there is no X509 certificate" do
30
- it "should raise a signature error" do
31
- @signature.stub(:certificate_node, nil) do
32
- assert_raises(Samlr::SignatureError) { @signature.send(:certificate!) }
33
- end
34
- end
35
- end
36
- end
37
-
38
- describe "#verify_digests!" do
39
- describe "when there are duplicate element ids" do
40
- before do
41
- @signature.document.at("/samlp:Response/saml:Assertion")["ID"] = @signature.document.root["ID"]
42
- end
43
-
44
- it "should raise" do
45
- begin
46
- @signature.send(:verify_digests!)
47
- flunk("Excepted to raise due to duplicate elements")
48
- rescue Samlr::SignatureError => e
49
- assert_equal "Reference validation error: Invalid element references", e.message
50
- end
51
- end
52
- end
53
- end
54
- end