ruby-saml 1.10.2 → 1.11.0

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

Potentially problematic release.


This version of ruby-saml might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d41dad289f19495a49ad8be046bfc6c37fdcddb5
4
- data.tar.gz: 461bc5c8000ea0124e59cc5782b997c445591e75
3
+ metadata.gz: afcd8a95f66ec94e3bb68b5a5264a651ae623923
4
+ data.tar.gz: eb05bc60959fde11ac20b0af0d14c07b7c5c1b38
5
5
  SHA512:
6
- metadata.gz: 677d7efd58ec482570901bec9ec0c1ef1e234715f2df3ba8983e9202c6af7d50a7dc9b58e4adf2bcb6ac88ba90190866bd16624308f6ce14205f3047587dc38e
7
- data.tar.gz: 084285a2d56ae772430587a3e748e017c1a50cb6090ed1d4990545c0c5e46a8ecf8c20d5de04b284897e81a35f7da33a2e437686fc181a5ea7085af1121244fd
6
+ metadata.gz: e85dc90f8f4bd5433f0078a6b5e316109dc7bbbe1ba60d5f8075d1f5047a71c208144d1da51157cf7220f2c56fb8b421e7b70ac5c828bea713146fc6bc774a29
7
+ data.tar.gz: 7cce3fd10ff5d7753d518b847b7f0ff0976b4ef5a1b7cc39c6e6cd3c8b32df7649e95ab929631b9838df5a4fb3eb3f3c50479f54253094b457a484710381b8f1
@@ -1,19 +1,18 @@
1
- sudo: false
2
1
  language: ruby
3
2
  rvm:
4
3
  - 1.8.7
5
4
  - 1.9.3
6
5
  - 2.0.0
7
- - 2.1.5
8
- - 2.2.0
9
- - 2.3.0
10
- - 2.4.0
11
- - 2.5.0
12
- - 2.6.0
6
+ - 2.1.10
7
+ - 2.2.10
8
+ - 2.3.8
9
+ - 2.4.6
10
+ - 2.5.5
11
+ - 2.6.3
13
12
  - ree
14
13
  - jruby-1.7.27
15
14
  - jruby-9.1.17.0
16
- - jruby-9.2.0.0
15
+ - jruby-9.2.7.0
17
16
  gemfile:
18
17
  - Gemfile
19
18
  - gemfiles/nokogiri-1.5.gemfile
@@ -29,19 +28,19 @@ matrix:
29
28
  gemfile: gemfiles/nokogiri-1.5.gemfile
30
29
  - rvm: jruby-9.1.17.0
31
30
  gemfile: gemfiles/nokogiri-1.5.gemfile
32
- - rvm: jruby-9.2.0.0
31
+ - rvm: jruby-9.2.7.0
33
32
  gemfile: gemfiles/nokogiri-1.5.gemfile
34
33
  - rvm: 2.1.5
35
34
  gemfile: gemfiles/nokogiri-1.5.gemfile
36
- - rvm: 2.2.0
35
+ - rvm: 2.2.10
37
36
  gemfile: gemfiles/nokogiri-1.5.gemfile
38
- - rvm: 2.3.0
37
+ - rvm: 2.3.8
39
38
  gemfile: gemfiles/nokogiri-1.5.gemfile
40
- - rvm: 2.4.0
39
+ - rvm: 2.4.6
41
40
  gemfile: gemfiles/nokogiri-1.5.gemfile
42
- - rvm: 2.5.0
41
+ - rvm: 2.5.5
43
42
  gemfile: gemfiles/nokogiri-1.5.gemfile
44
- - rvm: 2.6.0
43
+ - rvm: 2.6.3
45
44
  gemfile: gemfiles/nokogiri-1.5.gemfile
46
45
  env:
47
46
  - JRUBY_OPTS="--debug"
data/README.md CHANGED
@@ -123,6 +123,17 @@ We created a demo project for Rails4 that uses the latest version of this librar
123
123
 
124
124
  If you believe you have discovered a security vulnerability in this gem, please report it at https://www.onelogin.com/security with a description. We follow responsible disclosure guidelines, and will work with you to quickly find a resolution.
125
125
 
126
+ ### Security warning
127
+
128
+ Some tools may incorrectly report ruby-saml is a potential security vulnerability.
129
+ ruby-saml depends on Nokogiri, and it's possible to use Nokogiri in a dangerous way
130
+ (by enabling its DTDLOAD option and disabling its NONET option).
131
+ This dangerous Nokogiri configuration, which is sometimes used by other components,
132
+ can create an XML External Entity (XXE) vulnerability if the XML data is not trusted.
133
+ However, ruby-saml never enables this dangerous Nokogiri configuration;
134
+ ruby-saml never enables DTDLOAD, and it never disables NONET.
135
+
136
+
126
137
  ## Getting Started
127
138
  In order to use the toolkit you will need to install the gem (either manually or using Bundler), and require the library in your Ruby application:
128
139
 
@@ -238,7 +249,7 @@ def saml_settings
238
249
  settings = OneLogin::RubySaml::Settings.new
239
250
 
240
251
  settings.assertion_consumer_service_url = "http://#{request.host}/saml/consume"
241
- settings.issuer = "http://#{request.host}/saml/metadata"
252
+ settings.sp_entity_id = "http://#{request.host}/saml/metadata"
242
253
  settings.idp_entity_id = "https://app.onelogin.com/saml/metadata/#{OneLoginAppId}"
243
254
  settings.idp_sso_target_url = "https://app.onelogin.com/trust/saml2/http-post/sso/#{OneLoginAppId}"
244
255
  settings.idp_slo_target_url = "https://app.onelogin.com/trust/saml2/http-redirect/slo/#{OneLoginAppId}"
@@ -262,6 +273,8 @@ def saml_settings
262
273
  end
263
274
  ```
264
275
 
276
+ The use of settings.issuer is deprecated in favour of settings.sp_entity_id
277
+
265
278
  Some assertion validations can be skipped by passing parameters to `OneLogin::RubySaml::Response.new()`. For example, you can skip the `AuthnStatement`, `Conditions`, `Recipient`, or the `SubjectConfirmation` validations by initializing the response with different options:
266
279
 
267
280
  ```ruby
@@ -301,7 +314,7 @@ class SamlController < ApplicationController
301
314
  settings = OneLogin::RubySaml::Settings.new
302
315
 
303
316
  settings.assertion_consumer_service_url = "http://#{request.host}/saml/consume"
304
- settings.issuer = "http://#{request.host}/saml/metadata"
317
+ settings.sp_entity_id = "http://#{request.host}/saml/metadata"
305
318
  settings.idp_sso_target_url = "https://app.onelogin.com/saml/signon/#{OneLoginAppId}"
306
319
  settings.idp_cert_fingerprint = OneLoginAppCertFingerPrint
307
320
  settings.name_identifier_format = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
@@ -364,7 +377,7 @@ def saml_settings
364
377
  settings = idp_metadata_parser.parse_remote("https://example.com/auth/saml2/idp/metadata")
365
378
 
366
379
  settings.assertion_consumer_service_url = "http://#{request.host}/saml/consume"
367
- settings.issuer = "http://#{request.host}/saml/metadata"
380
+ settings.sp_entity_id = "http://#{request.host}/saml/metadata"
368
381
  settings.name_identifier_format = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
369
382
  # Optional for most SAML IdPs
370
383
  settings.authn_context = "urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport"
@@ -378,8 +391,8 @@ The following attributes are set:
378
391
  * idp_sso_target_url
379
392
  * idp_slo_target_url
380
393
  * idp_attribute_names
381
- * idp_cert
382
- * idp_cert_fingerprint
394
+ * idp_cert
395
+ * idp_cert_fingerprint
383
396
  * idp_cert_multi
384
397
 
385
398
  ### Retrieve one Entity Descriptor when many exist in Metadata
@@ -548,6 +561,8 @@ The settings related to sign are stored in the `security` attribute of the setti
548
561
  # Embeded signature or HTTP GET parameter signature
549
562
  # Note that metadata signature is always embedded regardless of this value.
550
563
  settings.security[:embed_sign] = false
564
+ settings.security[:check_idp_cert_expiration] = false # Enable or not IdP x509 cert expiration check
565
+ settings.security[:check_sp_cert_expiration] = false # Enable or not SP x509 cert expiration check
551
566
  ```
552
567
 
553
568
  Notice that the RelayState parameter is used when creating the Signature on the HTTP-Redirect Binding.
@@ -117,9 +117,9 @@ module OneLogin
117
117
  if settings.assertion_consumer_service_url != nil
118
118
  root.attributes["AssertionConsumerServiceURL"] = settings.assertion_consumer_service_url
119
119
  end
120
- if settings.issuer != nil
120
+ if settings.sp_entity_id != nil
121
121
  issuer = root.add_element "saml:Issuer"
122
- issuer.text = settings.issuer
122
+ issuer.text = settings.sp_entity_id
123
123
  end
124
124
 
125
125
  if settings.name_identifier_value_requested != nil
@@ -8,9 +8,9 @@ module OneLogin
8
8
 
9
9
  def self.logger
10
10
  @logger ||= begin
11
- (defined?(::Rails) && Rails.respond_to?(:logger) && Rails.logger) ||
12
- DEFAULT_LOGGER
13
- end
11
+ (defined?(::Rails) && Rails.respond_to?(:logger) && Rails.logger) ||
12
+ DEFAULT_LOGGER
13
+ end
14
14
  end
15
15
 
16
16
  def self.logger=(logger)
@@ -105,9 +105,9 @@ module OneLogin
105
105
  root.attributes['Version'] = "2.0"
106
106
  root.attributes['Destination'] = settings.idp_slo_target_url unless settings.idp_slo_target_url.nil?
107
107
 
108
- if settings.issuer
108
+ if settings.sp_entity_id
109
109
  issuer = root.add_element "saml:Issuer"
110
- issuer.text = settings.issuer
110
+ issuer.text = settings.sp_entity_id
111
111
  end
112
112
 
113
113
  nameid = root.add_element "saml:NameID"
@@ -163,7 +163,7 @@ module OneLogin
163
163
 
164
164
  return append_error("No settings on logout response") if settings.nil?
165
165
 
166
- return append_error("No issuer in settings of the logout response") if settings.issuer.nil?
166
+ return append_error("No sp_entity_id in settings of the logout response") if settings.sp_entity_id.nil?
167
167
 
168
168
  if settings.idp_cert_fingerprint.nil? && settings.idp_cert.nil? && settings.idp_cert_multi.nil?
169
169
  return append_error("No fingerprint or certificate on settings of the logout response")
@@ -228,13 +228,19 @@ module OneLogin
228
228
  :raw_sig_alg => options[:raw_get_params]['SigAlg']
229
229
  )
230
230
 
231
+ expired = false
231
232
  if idp_certs.nil? || idp_certs[:signing].empty?
232
233
  valid = OneLogin::RubySaml::Utils.verify_signature(
233
- :cert => settings.get_idp_cert,
234
+ :cert => idp_cert,
234
235
  :sig_alg => options[:get_params]['SigAlg'],
235
236
  :signature => options[:get_params]['Signature'],
236
237
  :query_string => query_string
237
238
  )
239
+ if valid && settings.security[:check_idp_cert_expiration]
240
+ if OneLogin::RubySaml::Utils.is_cert_expired(idp_cert)
241
+ expired = true
242
+ end
243
+ end
238
244
  else
239
245
  valid = false
240
246
  idp_certs[:signing].each do |signing_idp_cert|
@@ -245,11 +251,20 @@ module OneLogin
245
251
  :query_string => query_string
246
252
  )
247
253
  if valid
254
+ if settings.security[:check_idp_cert_expiration]
255
+ if OneLogin::RubySaml::Utils.is_cert_expired(signing_idp_cert)
256
+ expired = true
257
+ end
258
+ end
248
259
  break
249
260
  end
250
261
  end
251
262
  end
252
263
 
264
+ if expired
265
+ error_msg = "IdP x509 certificate expired"
266
+ return append_error(error_msg)
267
+ end
253
268
  unless valid
254
269
  error_msg = "Invalid Signature on Logout Response"
255
270
  return append_error(error_msg)
@@ -57,8 +57,8 @@ module OneLogin
57
57
  end
58
58
 
59
59
  root.attributes["ID"] = OneLogin::RubySaml::Utils.uuid
60
- if settings.issuer
61
- root.attributes["entityID"] = settings.issuer
60
+ if settings.sp_entity_id
61
+ root.attributes["entityID"] = settings.sp_entity_id
62
62
  end
63
63
  if settings.single_logout_service_url
64
64
  sp_sso.add_element "md:SingleLogoutService", {
@@ -589,11 +589,11 @@ module OneLogin
589
589
  # @raise [ValidationError] if soft == false and validation fails
590
590
  #
591
591
  def validate_audience
592
- return true if audiences.empty? || settings.issuer.nil? || settings.issuer.empty?
592
+ return true if audiences.empty? || settings.sp_entity_id.nil? || settings.sp_entity_id.empty?
593
593
 
594
- unless audiences.include? settings.issuer
594
+ unless audiences.include? settings.sp_entity_id
595
595
  s = audiences.count > 1 ? 's' : '';
596
- error_msg = "Invalid Audience#{s}. The audience#{s} #{audiences.join(',')}, did not match the expected audience #{settings.issuer}"
596
+ error_msg = "Invalid Audience#{s}. The audience#{s} #{audiences.join(',')}, did not match the expected audience #{settings.sp_entity_id}"
597
597
  return append_error(error_msg)
598
598
  end
599
599
 
@@ -781,8 +781,8 @@ module OneLogin
781
781
  return append_error("An empty NameID value found")
782
782
  end
783
783
 
784
- unless settings.issuer.nil? || settings.issuer.empty? || name_id_spnamequalifier.nil? || name_id_spnamequalifier.empty?
785
- if name_id_spnamequalifier != settings.issuer
784
+ unless settings.sp_entity_id.nil? || settings.sp_entity_id.empty? || name_id_spnamequalifier.nil? || name_id_spnamequalifier.empty?
785
+ if name_id_spnamequalifier != settings.sp_entity_id
786
786
  return append_error("The SPNameQualifier value mistmatch the SP entityID value.")
787
787
  end
788
788
  end
@@ -829,24 +829,43 @@ module OneLogin
829
829
  return append_error(error_msg)
830
830
  end
831
831
 
832
+
832
833
  idp_certs = settings.get_idp_cert_multi
833
834
  if idp_certs.nil? || idp_certs[:signing].empty?
834
835
  opts = {}
835
836
  opts[:fingerprint_alg] = settings.idp_cert_fingerprint_algorithm
836
- opts[:cert] = settings.get_idp_cert
837
+ idp_cert = settings.get_idp_cert
837
838
  fingerprint = settings.get_fingerprint
839
+ opts[:cert] = idp_cert
838
840
 
839
- unless fingerprint && doc.validate_document(fingerprint, @soft, opts)
841
+ if fingerprint && doc.validate_document(fingerprint, @soft, opts)
842
+ if settings.security[:check_idp_cert_expiration]
843
+ if OneLogin::RubySaml::Utils.is_cert_expired(idp_cert)
844
+ error_msg = "IdP x509 certificate expired"
845
+ return append_error(error_msg)
846
+ end
847
+ end
848
+ else
840
849
  return append_error(error_msg)
841
850
  end
842
851
  else
843
852
  valid = false
853
+ expired = false
844
854
  idp_certs[:signing].each do |idp_cert|
845
855
  valid = doc.validate_document_with_cert(idp_cert)
846
856
  if valid
857
+ if settings.security[:check_idp_cert_expiration]
858
+ if OneLogin::RubySaml::Utils.is_cert_expired(idp_cert)
859
+ expired = true
860
+ end
861
+ end
847
862
  break
848
863
  end
849
864
  end
865
+ if expired
866
+ error_msg = "IdP x509 certificate expired"
867
+ return append_error(error_msg)
868
+ end
850
869
  unless valid
851
870
  return append_error(error_msg)
852
871
  end
@@ -1,6 +1,7 @@
1
1
  require "xml_security"
2
2
  require "onelogin/ruby-saml/attribute_service"
3
3
  require "onelogin/ruby-saml/utils"
4
+ require "onelogin/ruby-saml/validation_error"
4
5
 
5
6
  # Only supports SAML 2.0
6
7
  module OneLogin
@@ -40,7 +41,6 @@ module OneLogin
40
41
  attr_accessor :idp_name_qualifier
41
42
  attr_accessor :valid_until
42
43
  # SP Data
43
- attr_accessor :issuer
44
44
  attr_accessor :assertion_consumer_service_url
45
45
  attr_accessor :assertion_consumer_service_binding
46
46
  attr_accessor :sp_name_qualifier
@@ -68,6 +68,28 @@ module OneLogin
68
68
  # Compability
69
69
  attr_accessor :assertion_consumer_logout_service_url
70
70
  attr_accessor :assertion_consumer_logout_service_binding
71
+ attr_accessor :issuer
72
+
73
+ # @return [String] SP Entity ID
74
+ #
75
+ def sp_entity_id
76
+ val = nil
77
+ if @sp_entity_id.nil?
78
+ if @issuer
79
+ val = @issuer
80
+ end
81
+ else
82
+ val = @sp_entity_id
83
+ end
84
+ val
85
+ end
86
+
87
+ # Setter for SP Entity ID.
88
+ # @param val [String].
89
+ #
90
+ def sp_entity_id=(val)
91
+ @sp_entity_id = val
92
+ end
71
93
 
72
94
  # @return [String] Single Logout Service URL.
73
95
  #
@@ -167,7 +189,15 @@ module OneLogin
167
189
  return nil if certificate.nil? || certificate.empty?
168
190
 
169
191
  formatted_cert = OneLogin::RubySaml::Utils.format_cert(certificate)
170
- OpenSSL::X509::Certificate.new(formatted_cert)
192
+ cert = OpenSSL::X509::Certificate.new(formatted_cert)
193
+
194
+ if security[:check_sp_cert_expiration]
195
+ if OneLogin::RubySaml::Utils.is_cert_expired(cert)
196
+ raise OneLogin::RubySaml::ValidationError.new("The SP certificate expired.")
197
+ end
198
+ end
199
+
200
+ cert
171
201
  end
172
202
 
173
203
  # @return [OpenSSL::X509::Certificate|nil] Build the New SP certificate from the settings (previously format it)
@@ -197,6 +227,7 @@ module OneLogin
197
227
  :compress_request => true,
198
228
  :compress_response => true,
199
229
  :soft => true,
230
+ :double_quote_xml_attribute_values => false,
200
231
  :security => {
201
232
  :authn_requests_signed => false,
202
233
  :logout_requests_signed => false,
@@ -207,9 +238,10 @@ module OneLogin
207
238
  :metadata_signed => false,
208
239
  :embed_sign => false,
209
240
  :digest_method => XMLSecurity::Document::SHA1,
210
- :signature_method => XMLSecurity::Document::RSA_SHA1
211
- }.freeze,
212
- :double_quote_xml_attribute_values => false,
241
+ :signature_method => XMLSecurity::Document::RSA_SHA1,
242
+ :check_idp_cert_expiration => false,
243
+ :check_sp_cert_expiration => false
244
+ }.freeze
213
245
  }.freeze
214
246
  end
215
247
  end
@@ -280,13 +280,19 @@ module OneLogin
280
280
  :raw_sig_alg => options[:raw_get_params]['SigAlg']
281
281
  )
282
282
 
283
+ expired = false
283
284
  if idp_certs.nil? || idp_certs[:signing].empty?
284
285
  valid = OneLogin::RubySaml::Utils.verify_signature(
285
- :cert => settings.get_idp_cert,
286
+ :cert => idp_cert,
286
287
  :sig_alg => options[:get_params]['SigAlg'],
287
288
  :signature => options[:get_params]['Signature'],
288
289
  :query_string => query_string
289
290
  )
291
+ if valid && settings.security[:check_idp_cert_expiration]
292
+ if OneLogin::RubySaml::Utils.is_cert_expired(idp_cert)
293
+ expired = true
294
+ end
295
+ end
290
296
  else
291
297
  valid = false
292
298
  idp_certs[:signing].each do |signing_idp_cert|
@@ -297,11 +303,20 @@ module OneLogin
297
303
  :query_string => query_string
298
304
  )
299
305
  if valid
306
+ if settings.security[:check_idp_cert_expiration]
307
+ if OneLogin::RubySaml::Utils.is_cert_expired(signing_idp_cert)
308
+ expired = true
309
+ end
310
+ end
300
311
  break
301
312
  end
302
313
  end
303
314
  end
304
315
 
316
+ if expired
317
+ error_msg = "IdP x509 certificate expired"
318
+ return append_error(error_msg)
319
+ end
305
320
  unless valid
306
321
  return append_error("Invalid Signature on Logout Request")
307
322
  end
@@ -114,9 +114,9 @@ module OneLogin
114
114
  root.attributes['InResponseTo'] = request_id unless request_id.nil?
115
115
  root.attributes['Destination'] = settings.idp_slo_target_url unless settings.idp_slo_target_url.nil?
116
116
 
117
- if settings.issuer != nil
117
+ if settings.sp_entity_id != nil
118
118
  issuer = root.add_element "saml:Issuer"
119
- issuer.text = settings.issuer
119
+ issuer.text = settings.sp_entity_id
120
120
  end
121
121
 
122
122
  # add success message
@@ -3,6 +3,7 @@ if RUBY_VERSION < '1.9'
3
3
  else
4
4
  require 'securerandom'
5
5
  end
6
+ require "openssl"
6
7
 
7
8
  module OneLogin
8
9
  module RubySaml
@@ -15,6 +16,18 @@ module OneLogin
15
16
  DSIG = "http://www.w3.org/2000/09/xmldsig#"
16
17
  XENC = "http://www.w3.org/2001/04/xmlenc#"
17
18
 
19
+ # Checks if the x509 cert provided is expired
20
+ #
21
+ # @param cert [Certificate] The x509 certificate
22
+ #
23
+ def self.is_cert_expired(cert)
24
+ if cert.is_a?(String)
25
+ cert = OpenSSL::X509::Certificate.new(cert)
26
+ end
27
+
28
+ return cert.not_after < Time.now
29
+ end
30
+
18
31
  # Return a properly formatted x509 certificate
19
32
  #
20
33
  # @param cert [String] The original certificate
@@ -1,5 +1,5 @@
1
1
  module OneLogin
2
2
  module RubySaml
3
- VERSION = '1.10.2'
3
+ VERSION = '1.11.0'
4
4
  end
5
5
  end
@@ -17,7 +17,6 @@ Gem::Specification.new do |s|
17
17
  ]
18
18
  s.files = `git ls-files`.split("\n")
19
19
  s.homepage = %q{http://github.com/onelogin/ruby-saml}
20
- s.rubyforge_project = %q{http://www.rubygems.org/gems/ruby-saml}
21
20
  s.rdoc_options = ["--charset=UTF-8"]
22
21
  s.require_paths = ["lib"]
23
22
  s.rubygems_version = %q{1.3.7}
@@ -44,6 +43,7 @@ Gem::Specification.new do |s|
44
43
  s.add_runtime_dependency('nokogiri', '>= 1.5.10')
45
44
  end
46
45
 
46
+ s.add_development_dependency('coveralls')
47
47
  s.add_development_dependency('minitest', '~> 5.5')
48
48
  s.add_development_dependency('mocha', '~> 0.14')
49
49
  s.add_development_dependency('rake', '~> 10')
@@ -62,7 +62,7 @@ class RubySamlTest < Minitest::Test
62
62
 
63
63
  assert logoutresponse.validate
64
64
 
65
- assert_equal settings.issuer, logoutresponse.issuer
65
+ assert_equal settings.sp_entity_id, logoutresponse.issuer
66
66
  assert_equal in_relation_to_request_id, logoutresponse.in_response_to
67
67
 
68
68
  assert logoutresponse.success?
@@ -123,12 +123,13 @@ class RubySamlTest < Minitest::Test
123
123
  assert_includes logoutresponse.errors, "The status code of the Logout Response was not Success, was Requester -> Logoutrequest expired"
124
124
  end
125
125
 
126
- it "invalidate logout response when in lack of issuer setting" do
126
+ it "invalidate logout response when in lack of sp_entity_id setting" do
127
127
  bad_settings = settings
128
128
  bad_settings.issuer = nil
129
+ bad_settings.sp_entity_id = nil
129
130
  logoutresponse = OneLogin::RubySaml::Logoutresponse.new(unsuccessful_logout_response_document, bad_settings)
130
131
  assert !logoutresponse.validate
131
- assert_includes logoutresponse.errors, "No issuer in settings of the logout response"
132
+ assert_includes logoutresponse.errors, "No sp_entity_id in settings of the logout response"
132
133
  end
133
134
 
134
135
  it "invalidate logout response with wrong issuer" do
@@ -139,7 +140,7 @@ class RubySamlTest < Minitest::Test
139
140
  assert_includes logoutresponse.errors, "Doesn't match the issuer, expected: <#{logoutresponse.settings.idp_entity_id}>, but was: <http://app.muda.no>"
140
141
  end
141
142
 
142
- it "collect errors when collect_errors=true" do
143
+ it "collect errors when collect_errors=true" do
143
144
  settings.idp_entity_id = 'http://invalid.issuer.example.com/'
144
145
  logoutresponse = OneLogin::RubySaml::Logoutresponse.new(unsuccessful_logout_response_document, settings)
145
146
  collect_errors = true
@@ -184,7 +185,7 @@ class RubySamlTest < Minitest::Test
184
185
  opts = { :matches_request_id => expected_request_id}
185
186
 
186
187
  logoutresponse = OneLogin::RubySaml::Logoutresponse.new(valid_logout_response_document, settings, opts)
187
- assert_raises(OneLogin::RubySaml::ValidationError) { logoutresponse.validate }
188
+ assert_raises(OneLogin::RubySaml::ValidationError) { logoutresponse.validate }
188
189
  assert_includes logoutresponse.errors, "The InResponseTo of the Logout Response: #{logoutresponse.in_response_to}, does not match the ID of the Logout Request sent by the SP: #{expected_request_id}"
189
190
  end
190
191
 
@@ -202,11 +203,12 @@ class RubySamlTest < Minitest::Test
202
203
  assert_includes logoutresponse.errors, "The status code of the Logout Response was not Success, was Requester"
203
204
  end
204
205
 
205
- it "raise validation error when in lack of issuer setting" do
206
+ it "raise validation error when in lack of sp_entity_id setting" do
206
207
  settings.issuer = nil
208
+ settings.sp_entity_id = nil
207
209
  logoutresponse = OneLogin::RubySaml::Logoutresponse.new(unsuccessful_logout_response_document, settings)
208
210
  assert_raises(OneLogin::RubySaml::ValidationError) { logoutresponse.validate }
209
- assert_includes logoutresponse.errors, "No issuer in settings of the logout response"
211
+ assert_includes logoutresponse.errors, "No sp_entity_id in settings of the logout response"
210
212
  end
211
213
 
212
214
  it "raise validation error when logout response with wrong issuer" do
@@ -392,6 +394,21 @@ class RubySamlTest < Minitest::Test
392
394
  assert logoutresponse_sign_test.send(:validate_signature)
393
395
  end
394
396
 
397
+ it "return false when cert expired and check_idp_cert_expiration expired" do
398
+ params['RelayState'] = params[:RelayState]
399
+ options = {}
400
+ options[:get_params] = params
401
+ settings.security[:check_idp_cert_expiration] = true
402
+ settings.idp_cert = nil
403
+ settings.idp_cert_multi = {
404
+ :signing => [ruby_saml_cert_text],
405
+ :encryption => []
406
+ }
407
+ logoutresponse_sign_test = OneLogin::RubySaml::Logoutresponse.new(params['SAMLResponse'], settings, options)
408
+ assert !logoutresponse_sign_test.send(:validate_signature)
409
+ assert_includes logoutresponse_sign_test.errors, "IdP x509 certificate expired"
410
+ end
411
+
395
412
  it "return false when none cert on idp_cert_multi is valid" do
396
413
  params['RelayState'] = params[:RelayState]
397
414
  options = {}
@@ -402,6 +419,7 @@ class RubySamlTest < Minitest::Test
402
419
  }
403
420
  logoutresponse_sign_test = OneLogin::RubySaml::Logoutresponse.new(params['SAMLResponse'], settings, options)
404
421
  assert !logoutresponse_sign_test.send(:validate_signature)
422
+ assert_includes logoutresponse_sign_test.errors, "Invalid Signature on Logout Response"
405
423
  end
406
424
  end
407
425
  end
@@ -12,7 +12,7 @@ class MetadataTest < Minitest::Test
12
12
  let(:acs) { REXML::XPath.first(xml_doc, "//md:AssertionConsumerService") }
13
13
 
14
14
  before do
15
- settings.issuer = "https://example.com"
15
+ settings.sp_entity_id = "https://example.com"
16
16
  settings.name_identifier_format = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
17
17
  settings.assertion_consumer_service_url = "https://foo.example/saml/consume"
18
18
  end
@@ -259,10 +259,10 @@ class RubySamlTest < Minitest::Test
259
259
 
260
260
  it "raise when there is no valid audience" do
261
261
  settings.idp_cert_fingerprint = signature_fingerprint_1
262
- settings.issuer = 'invalid'
262
+ settings.sp_entity_id = 'invalid'
263
263
  response_valid_signed.settings = settings
264
264
  response_valid_signed.soft = false
265
- error_msg = generate_audience_error(response_valid_signed.settings.issuer, ['https://someone.example.com/audience'])
265
+ error_msg = generate_audience_error(response_valid_signed.settings.sp_entity_id, ['https://someone.example.com/audience'])
266
266
  assert_raises(OneLogin::RubySaml::ValidationError, error_msg) do
267
267
  response_valid_signed.is_valid?
268
268
  end
@@ -415,11 +415,11 @@ class RubySamlTest < Minitest::Test
415
415
 
416
416
  it "return false when there is no valid audience" do
417
417
  settings.idp_cert_fingerprint = signature_fingerprint_1
418
- settings.issuer = 'invalid'
418
+ settings.sp_entity_id = 'invalid'
419
419
  response_valid_signed.settings = settings
420
420
  response_valid_signed.is_valid?
421
421
 
422
- assert_includes response_valid_signed.errors, generate_audience_error(response_valid_signed.settings.issuer, ['https://someone.example.com/audience'])
422
+ assert_includes response_valid_signed.errors, generate_audience_error(response_valid_signed.settings.sp_entity_id, ['https://someone.example.com/audience'])
423
423
  end
424
424
 
425
425
  it "return false when no ID present in the SAML Response" do
@@ -451,7 +451,7 @@ class RubySamlTest < Minitest::Test
451
451
 
452
452
  it "collect errors when collect_errors=true" do
453
453
  settings.idp_cert = ruby_saml_cert_text
454
- settings.issuer = 'invalid'
454
+ settings.sp_entity_id = 'invalid'
455
455
  response_invalid_subjectconfirmation_recipient.settings = settings
456
456
  collect_errors = true
457
457
  response_invalid_subjectconfirmation_recipient.is_valid?(collect_errors)
@@ -464,23 +464,23 @@ class RubySamlTest < Minitest::Test
464
464
  describe "#validate_audience" do
465
465
  it "return true when the audience is valid" do
466
466
  response.settings = settings
467
- response.settings.issuer = '{audience}'
467
+ response.settings.sp_entity_id = '{audience}'
468
468
  assert response.send(:validate_audience)
469
469
  assert_empty response.errors
470
470
  end
471
471
 
472
472
  it "return true when the audience is self closing" do
473
473
  response_audience_self_closed.settings = settings
474
- response_audience_self_closed.settings.issuer = '{audience}'
474
+ response_audience_self_closed.settings.sp_entity_id = '{audience}'
475
475
  assert response_audience_self_closed.send(:validate_audience)
476
476
  assert_empty response_audience_self_closed.errors
477
477
  end
478
478
 
479
479
  it "return false when the audience is valid" do
480
480
  response.settings = settings
481
- response.settings.issuer = 'invalid_audience'
481
+ response.settings.sp_entity_id = 'invalid_audience'
482
482
  assert !response.send(:validate_audience)
483
- assert_includes response.errors, generate_audience_error(response.settings.issuer, ['{audience}'])
483
+ assert_includes response.errors, generate_audience_error(response.settings.sp_entity_id, ['{audience}'])
484
484
  end
485
485
  end
486
486
 
@@ -665,23 +665,23 @@ class RubySamlTest < Minitest::Test
665
665
  describe "#validate_audience" do
666
666
  it "return true when the audience is valid" do
667
667
  response_valid_signed.settings = settings
668
- response_valid_signed.settings.issuer = "https://someone.example.com/audience"
668
+ response_valid_signed.settings.sp_entity_id = "https://someone.example.com/audience"
669
669
  assert response_valid_signed.send(:validate_audience)
670
670
  assert_empty response_valid_signed.errors
671
671
  end
672
672
 
673
- it "return true when there is not issuer defined" do
673
+ it "return true when there is not sp_entity_id defined" do
674
674
  response_valid_signed.settings = settings
675
- response_valid_signed.settings.issuer = nil
675
+ response_valid_signed.settings.sp_entity_id = nil
676
676
  assert response_valid_signed.send(:validate_audience)
677
677
  assert_empty response_valid_signed.errors
678
678
  end
679
679
 
680
680
  it "return false when there is no valid audience" do
681
681
  response_invalid_audience.settings = settings
682
- response_invalid_audience.settings.issuer = "https://invalid.example.com/audience"
682
+ response_invalid_audience.settings.sp_entity_id = "https://invalid.example.com/audience"
683
683
  assert !response_invalid_audience.send(:validate_audience)
684
- assert_includes response_invalid_audience.errors, generate_audience_error(response_invalid_audience.settings.issuer, ['http://invalid.audience.com'])
684
+ assert_includes response_invalid_audience.errors, generate_audience_error(response_invalid_audience.settings.sp_entity_id, ['http://invalid.audience.com'])
685
685
  end
686
686
  end
687
687
 
@@ -880,6 +880,15 @@ class RubySamlTest < Minitest::Test
880
880
  assert_includes response_valid_signed_without_x509certificate.errors, "Invalid Signature on SAML Response"
881
881
  end
882
882
 
883
+ it "return false when cert expired and check_idp_cert_expiration enabled" do
884
+ settings.idp_cert_fingerprint = nil
885
+ settings.idp_cert = ruby_saml_cert_text
886
+ settings.security[:check_idp_cert_expiration] = true
887
+ response_valid_signed.settings = settings
888
+ assert !response_valid_signed.send(:validate_signature)
889
+ assert_includes response_valid_signed.errors, "IdP x509 certificate expired"
890
+ end
891
+
883
892
  it "return false when no X509Certificate and the cert provided at settings mismatches" do
884
893
  settings.idp_cert_fingerprint = nil
885
894
  settings.idp_cert = signature_1
@@ -953,7 +962,7 @@ class RubySamlTest < Minitest::Test
953
962
  end
954
963
 
955
964
  it "return false when wrong_spnamequalifier" do
956
- settings.issuer = 'sp_entity_id'
965
+ settings.sp_entity_id = 'sp_entity_id'
957
966
  response_wrong_spnamequalifier.settings = settings
958
967
  assert !response_wrong_spnamequalifier.send(:validate_name_id)
959
968
  assert_includes response_wrong_spnamequalifier.errors, "The SPNameQualifier value mistmatch the SP entityID value."
@@ -966,7 +975,7 @@ class RubySamlTest < Minitest::Test
966
975
  end
967
976
 
968
977
  it "return true when nameid is valid and response_wrong_spnamequalifier matches the SP issuer" do
969
- settings.issuer = 'wrong-sp-entityid'
978
+ settings.sp_entity_id = 'wrong-sp-entityid'
970
979
  response_wrong_spnamequalifier.settings = settings
971
980
  assert response_wrong_spnamequalifier.send(:validate_name_id)
972
981
  end
@@ -1398,7 +1407,7 @@ class RubySamlTest < Minitest::Test
1398
1407
 
1399
1408
  before do
1400
1409
  settings.idp_cert_fingerprint = 'EE:17:4E:FB:A8:81:71:12:0D:2A:78:43:BC:E7:0C:07:58:79:F4:F4'
1401
- settings.issuer = 'http://rubysaml.com:3000/saml/metadata'
1410
+ settings.sp_entity_id = 'http://rubysaml.com:3000/saml/metadata'
1402
1411
  settings.assertion_consumer_service_url = 'http://rubysaml.com:3000/saml/acs'
1403
1412
  settings.certificate = ruby_saml_cert_text
1404
1413
  settings.private_key = ruby_saml_key_text
@@ -1,6 +1,7 @@
1
1
  require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
2
2
 
3
3
  require 'onelogin/ruby-saml/settings'
4
+ require 'onelogin/ruby-saml/validation_error'
4
5
 
5
6
  class SettingsTest < Minitest::Test
6
7
 
@@ -243,6 +244,13 @@ class SettingsTest < Minitest::Test
243
244
  }
244
245
  end
245
246
 
247
+ it "raises an error if SP certificate expired and check_sp_cert_expiration enabled" do
248
+ @settings.certificate = ruby_saml_cert_text
249
+ @settings.security[:check_sp_cert_expiration] = true
250
+ assert_raises(OneLogin::RubySaml::ValidationError) {
251
+ settings.get_sp_cert
252
+ }
253
+ end
246
254
  end
247
255
 
248
256
  describe "#get_sp_cert_new" do
@@ -429,6 +429,23 @@ class RubySamlTest < Minitest::Test
429
429
  assert logout_request_sign_test.send(:validate_signature)
430
430
  end
431
431
 
432
+ it "return false when cert expired and check_idp_cert_expiration expired" do
433
+ params = OneLogin::RubySaml::Logoutrequest.new.create_params(settings, :RelayState => 'http://example.com')
434
+ params['RelayState'] = params[:RelayState]
435
+ options = {}
436
+ options[:get_params] = params
437
+ settings.security[:check_idp_cert_expiration] = true
438
+ logout_request_sign_test = OneLogin::RubySaml::SloLogoutrequest.new(params['SAMLRequest'], options)
439
+ settings.idp_cert = nil
440
+ settings.idp_cert_multi = {
441
+ :signing => [ruby_saml_cert_text],
442
+ :encryption => []
443
+ }
444
+ logout_request_sign_test.settings = settings
445
+ assert !logout_request_sign_test.send(:validate_signature)
446
+ assert_includes logout_request_sign_test.errors, "IdP x509 certificate expired"
447
+ end
448
+
432
449
  it "return false when none cert on idp_cert_multi is valid" do
433
450
  params = OneLogin::RubySaml::Logoutrequest.new.create_params(settings, :RelayState => 'http://example.com')
434
451
  params['RelayState'] = params[:RelayState]
@@ -442,6 +459,8 @@ class RubySamlTest < Minitest::Test
442
459
  }
443
460
  logout_request_sign_test.settings = settings
444
461
  assert !logout_request_sign_test.send(:validate_signature)
462
+ assert_includes logout_request_sign_test.errors, "Invalid Signature on Logout Request"
463
+
445
464
  end
446
465
  end
447
466
  end
@@ -1,5 +1,7 @@
1
1
  require 'simplecov'
2
+ require 'coveralls'
2
3
 
4
+ SimpleCov.formatter = Coveralls::SimpleCov::Formatter
3
5
  SimpleCov.start do
4
6
  add_filter "test/"
5
7
  add_filter "vendor/"
@@ -239,7 +239,7 @@ class XmlSecurityTest < Minitest::Test
239
239
  settings.idp_sso_target_url = "https://idp.example.com/sso"
240
240
  settings.protocol_binding = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
241
241
  settings.idp_slo_target_url = "https://idp.example.com/slo",
242
- settings.issuer = "https://sp.example.com/saml2"
242
+ settings.sp_entity_id = "https://sp.example.com/saml2"
243
243
  settings.assertion_consumer_service_url = "https://sp.example.com/acs"
244
244
  settings.single_logout_service_url = "https://sp.example.com/sls"
245
245
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-saml
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.10.2
4
+ version: 1.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - OneLogin LLC
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-04-29 00:00:00.000000000 Z
11
+ date: 2019-07-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 1.5.10
27
+ - !ruby/object:Gem::Dependency
28
+ name: coveralls
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: minitest
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -344,8 +358,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
344
358
  - !ruby/object:Gem::Version
345
359
  version: '0'
346
360
  requirements: []
347
- rubyforge_project: http://www.rubygems.org/gems/ruby-saml
348
- rubygems_version: 2.4.8
361
+ rubyforge_project:
362
+ rubygems_version: 2.5.2.1
349
363
  signing_key:
350
364
  specification_version: 4
351
365
  summary: SAML Ruby Tookit