ruby-saml-mod 0.2.5 → 0.2.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7e32a73407cbd1dc9486c6dbce36be93fc18ee2d
4
- data.tar.gz: c2cce4b017515e1e0878cf29b12ffc6d4608c3a9
3
+ metadata.gz: c9717bd6a9dffb64cf2ae4f45ff7f386059af316
4
+ data.tar.gz: 363c5cedd4ec2a9705129c559547e5fd0336ebf9
5
5
  SHA512:
6
- metadata.gz: fdc92ccf552bce1ab44d5a59c6582cf5023653314cf192d70847eefd14fae74f36eea0f95f12de5949ae2e508ba5f2659c1d95f6e66fb6b5d6ea0297b9218442
7
- data.tar.gz: 7650aabfd1abba4969558447d7308faa456e51f7d77009ff042376df9d7b3e6a50d0a0e955a90ea207c3150ab4bc4128d6cfb3bc7893aeebe1047933bf1fed4b
6
+ metadata.gz: 466ef19f37dcddd3f17fa608e1fe6981cec73228463adc876fd610ff7b637a9c7cbb9301910e0c44e9153c20dc126baed7ab0007f72ee287bdcb57090864cbdd
7
+ data.tar.gz: fa770d00d673b9c5a5fd42a1492b9260049554c3c146c941f86ed881a63f5bca351f8786560ad06bf31e5f9478914a208905ec531f5e2b8f9311f78adc608e97
data/lib/onelogin/saml.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  require 'zlib'
2
2
  require "base64"
3
- require "xml/libxml"
3
+ require "nokogiri"
4
4
  require "xml_sec"
5
5
  require "cgi"
6
6
 
@@ -29,7 +29,7 @@ module Onelogin::Saml
29
29
  end
30
30
 
31
31
  def document
32
- @document ||= LibXML::XML::Document.string(xml) if xml
32
+ @document ||= Nokogiri::XML(xml) if xml
33
33
  end
34
34
 
35
35
  def xml=(value)
@@ -117,11 +117,11 @@ module Onelogin::Saml
117
117
  end
118
118
 
119
119
  def node_attribute_value(xpath, attribute)
120
- document.root.find_first(xpath, Onelogin::NAMESPACES)[attribute] rescue nil
120
+ document.root.at_xpath(xpath, Onelogin::NAMESPACES)[attribute] rescue nil
121
121
  end
122
122
 
123
123
  def node_content(xpath)
124
- document.root.find_first(xpath, Onelogin::NAMESPACES).content rescue nil
124
+ document.root.at_xpath(xpath, Onelogin::NAMESPACES).content rescue nil
125
125
  end
126
126
 
127
127
  def self.generate_unique_id(length = 42)
@@ -13,7 +13,7 @@ module Onelogin::Saml
13
13
 
14
14
  begin
15
15
  @xml = Base64.decode64(@response)
16
- @document = LibXML::XML::Document.string(@xml)
16
+ @document = Nokogiri::XML(@xml)
17
17
  @document.extend(XMLSecurity::SignedDocument)
18
18
  rescue
19
19
  # could not parse document, everything is invalid
@@ -21,9 +21,9 @@ module Onelogin::Saml
21
21
  return
22
22
  end
23
23
 
24
- @issuer = document.find_first("/samlp:Response/saml:Issuer", Onelogin::NAMESPACES).content.strip rescue nil
25
- @issuer ||= document.find_first("/samlp:Response/saml:Assertion/saml:Issuer", Onelogin::NAMESPACES).content.strip rescue nil
26
- @status_code = document.find_first("/samlp:Response/samlp:Status/samlp:StatusCode", Onelogin::NAMESPACES)["Value"] rescue nil
24
+ @issuer = document.at_xpath("/samlp:Response/saml:Issuer", Onelogin::NAMESPACES).content.strip rescue nil
25
+ @issuer ||= document.at_xpath("/samlp:Response/saml:Assertion/saml:Issuer", Onelogin::NAMESPACES).content.strip rescue nil
26
+ @status_code = document.at_xpath("/samlp:Response/samlp:Status/samlp:StatusCode", Onelogin::NAMESPACES)["Value"] rescue nil
27
27
 
28
28
  process(settings) if settings
29
29
  end
@@ -55,14 +55,15 @@ module Onelogin::Saml
55
55
  end
56
56
 
57
57
  def decrypted_document
58
- @decrypted_document ||= LibXML::XML::Document.document(document).tap do |doc|
59
- doc.extend(XMLSecurity::SignedDocument)
60
- doc.decrypt!(settings)
58
+ unless @decrypted_document
59
+ document.decrypt!(settings)
60
+ @decrypted_document = document
61
61
  end
62
+ @decrypted_document
62
63
  end
63
64
 
64
65
  def untrusted_find_first(xpath)
65
- decrypted_document.find(xpath, Onelogin::NAMESPACES).first
66
+ decrypted_document.at_xpath(xpath, Onelogin::NAMESPACES)
66
67
  end
67
68
 
68
69
  def trusted_find_first(xpath)
@@ -71,7 +72,7 @@ module Onelogin::Saml
71
72
 
72
73
  def trusted_find(xpath)
73
74
  trusted_roots.map do |trusted_root|
74
- trusted_root.find("descendant-or-self::#{xpath}", Onelogin::NAMESPACES).to_a
75
+ trusted_root.xpath("descendant-or-self::#{xpath}", Onelogin::NAMESPACES).to_a
75
76
  end.flatten.compact
76
77
  end
77
78
 
@@ -141,7 +142,7 @@ module Onelogin::Saml
141
142
  end
142
143
 
143
144
  def fingerprint_from_idp
144
- if base64_cert = decrypted_document.find_first("//ds:X509Certificate", Onelogin::NAMESPACES)
145
+ if base64_cert = decrypted_document.at_xpath("//ds:X509Certificate", Onelogin::NAMESPACES)
145
146
  cert_text = Base64.decode64(base64_cert.content)
146
147
  cert = OpenSSL::X509::Certificate.new(cert_text)
147
148
  Digest::SHA1.hexdigest(cert.to_der)
data/lib/xml_sec.rb CHANGED
@@ -25,7 +25,7 @@
25
25
  require 'rubygems'
26
26
  require 'ffi'
27
27
  require 'base64'
28
- require "xml/libxml"
28
+ require "nokogiri"
29
29
  require "openssl"
30
30
  require "digest/sha1"
31
31
 
@@ -330,7 +330,7 @@ module XMLSecurity
330
330
 
331
331
  def signed_roots
332
332
  signatures.map do |sig|
333
- ref = sig.find('./ds:SignedInfo/ds:Reference', Onelogin::NAMESPACES).first
333
+ ref = sig.at_xpath('./ds:SignedInfo/ds:Reference', Onelogin::NAMESPACES)
334
334
  signed_element_id = ref['URI'].sub(/^#/, '')
335
335
 
336
336
  if signed_element_id.empty?
@@ -338,19 +338,19 @@ module XMLSecurity
338
338
  else
339
339
  xpath_id_query = %Q(ancestor::*[@ID = "#{signed_element_id}"])
340
340
 
341
- ref.find(xpath_id_query, Onelogin::NAMESPACES).first
341
+ ref.at_xpath(xpath_id_query, Onelogin::NAMESPACES)
342
342
  end
343
343
  end.compact
344
344
  end
345
345
 
346
346
  def signatures
347
347
  # we only return the first, cause our signature validation only checks the first
348
- @signatures ||= [self.find_first("//ds:Signature", Onelogin::NAMESPACES)]
348
+ @signatures ||= [self.at_xpath("//ds:Signature", Onelogin::NAMESPACES)].compact
349
349
  end
350
350
 
351
351
  def validate(idp_cert_fingerprint, logger = nil)
352
352
  # get cert from response
353
- base64_cert = self.find_first("//ds:X509Certificate", Onelogin::NAMESPACES).content
353
+ base64_cert = self.at_xpath("//ds:X509Certificate", Onelogin::NAMESPACES).content
354
354
  cert_text = Base64.decode64(base64_cert)
355
355
  cert = OpenSSL::X509::Certificate.new(cert_text)
356
356
 
@@ -364,21 +364,8 @@ module XMLSecurity
364
364
  end
365
365
  end
366
366
 
367
- # create a copy of the document with the certificate removed
368
- doc = LibXML::XML::Document.new
369
- # doc.encoding = self.encoding == XML::Encoding::NONE ? XML::Encoding::ISO_8859_1 : self.encoding
370
-
371
- # for some reason xmlsec doesn't like it when its UTF-8 and has other
372
- # characters with umlauts and the like. We will just force it to another encoding.
373
- # This should work fine since we are just validating the signature.
374
- doc.encoding = XML::Encoding::ISO_8859_1
375
-
376
- doc.root = doc.import(self.root)
377
- sigcert = doc.find_first("//ds:Signature/ds:KeyInfo", Onelogin::NAMESPACES)
378
- sigcert.remove!
379
-
380
367
  # Force encoding of the xml and the xml string for validation
381
- xml = doc.to_s(:indent => false, :encoding => doc.encoding).encode(doc.rb_encoding)
368
+ xml = to_xml(save_with: Nokogiri::XML::Node::SaveOptions::AS_XML, encoding: "ISO-8859-1")
382
369
 
383
370
  # validate it!
384
371
  validate_doc(xml, SignedDocument.format_cert(cert))
@@ -432,14 +419,13 @@ module XMLSecurity
432
419
  # replaces EncryptedData nodes with decrypted copies
433
420
  def decrypt!(settings)
434
421
  if settings.encryption_configured?
435
- find("//xenc:EncryptedData", Onelogin::NAMESPACES).each do |node|
422
+ xpath("//xenc:EncryptedData", Onelogin::NAMESPACES).each do |node|
436
423
  decrypted_xml = decrypt_node(settings, node.to_s)
437
424
  if decrypted_xml
438
- decrypted_doc = LibXML::XML::Document.string(decrypted_xml)
425
+ decrypted_doc = Nokogiri::XML(decrypted_xml)
439
426
  decrypted_node = decrypted_doc.root
440
- decrypted_node = self.import(decrypted_node)
441
427
  node.parent.next = decrypted_node
442
- node.parent.remove!
428
+ node.parent.unlink
443
429
  end
444
430
  end
445
431
  end
@@ -43,18 +43,18 @@ describe Onelogin::Saml::LogoutRequest do
43
43
  let(:forward_url) { logout_request.forward_url }
44
44
 
45
45
  it "includes destination in the saml:LogoutRequest attributes" do
46
- logout_xml = LibXML::XML::Document.string(logout_request.xml)
47
- logout_xml.find_first('/samlp:LogoutRequest', Onelogin::NAMESPACES).attributes['Destination'].should == "http://idp.example.com/saml2"
46
+ logout_xml = Nokogiri::XML(logout_request.xml)
47
+ logout_xml.at_xpath('/samlp:LogoutRequest', Onelogin::NAMESPACES)['Destination'].should == "http://idp.example.com/saml2"
48
48
  end
49
49
 
50
50
  it "properly sets the Format attribute NameID based on settings" do
51
- logout_xml = LibXML::XML::Document.string(logout_request.xml)
52
- logout_xml.find_first('/samlp:LogoutRequest/saml:NameID', Onelogin::NAMESPACES).attributes['Format'].should == Onelogin::Saml::NameIdentifiers::UNSPECIFIED
51
+ logout_xml = Nokogiri::XML(logout_request.xml)
52
+ logout_xml.at_xpath('/samlp:LogoutRequest/saml:NameID', Onelogin::NAMESPACES)['Format'].should == Onelogin::Saml::NameIdentifiers::UNSPECIFIED
53
53
  end
54
54
 
55
55
  it "does not include the signature in the request xml" do
56
- logout_xml = LibXML::XML::Document.string(logout_request.xml)
57
- logout_xml.find_first('/samlp:LogoutRequest/ds:Signature', Onelogin::NAMESPACES).should be_nil
56
+ logout_xml = Nokogiri::XML(logout_request.xml)
57
+ logout_xml.at_xpath('/samlp:LogoutRequest/ds:Signature', Onelogin::NAMESPACES).should be_nil
58
58
  end
59
59
 
60
60
  it "can sign the generated query string" do
@@ -25,37 +25,37 @@ describe Onelogin::Saml::LogoutResponse do
25
25
  end
26
26
 
27
27
  it "includes destination in the saml:LogoutRequest attributes" do
28
- value = xml.find_first('/samlp:LogoutResponse', Onelogin::NAMESPACES).attributes['Destination']
28
+ value = xml.at_xpath('/samlp:LogoutResponse', Onelogin::NAMESPACES)['Destination']
29
29
  expect(value).to eq "http://idp.example.com/saml2?existing=param&existing=param"
30
30
  end
31
31
 
32
32
  it "includes id in the saml:LogoutRequest attributes" do
33
- value = xml.find_first('/samlp:LogoutResponse', Onelogin::NAMESPACES).attributes['ID']
33
+ value = xml.at_xpath('/samlp:LogoutResponse', Onelogin::NAMESPACES)['ID']
34
34
  expect(value).to eq id
35
35
  end
36
36
 
37
37
  it "includes issue_instant in the saml:LogoutRequest attributes" do
38
- value = xml.find_first('/samlp:LogoutResponse', Onelogin::NAMESPACES).attributes['IssueInstant']
38
+ value = xml.at_xpath('/samlp:LogoutResponse', Onelogin::NAMESPACES)['IssueInstant']
39
39
  expect(value).to eq issue_instant
40
40
  end
41
41
 
42
42
  it "includes in_response_to in the saml:LogoutRequest attributes" do
43
- value = xml.find_first('/samlp:LogoutResponse', Onelogin::NAMESPACES).attributes['InResponseTo']
43
+ value = xml.at_xpath('/samlp:LogoutResponse', Onelogin::NAMESPACES)['InResponseTo']
44
44
  expect(value).to eq in_response_to
45
45
  end
46
46
 
47
47
  it "includes issuer tag" do
48
- value = xml.find_first("/samlp:LogoutResponse/saml:Issuer", Onelogin::NAMESPACES).content
48
+ value = xml.at_xpath("/samlp:LogoutResponse/saml:Issuer", Onelogin::NAMESPACES).content
49
49
  expect(value).to eq issuer
50
50
  end
51
51
 
52
52
  it "includes status code tag" do
53
- value = xml.find_first("/samlp:LogoutResponse/samlp:Status/samlp:StatusCode", Onelogin::NAMESPACES).attributes['Value']
53
+ value = xml.at_xpath("/samlp:LogoutResponse/samlp:Status/samlp:StatusCode", Onelogin::NAMESPACES)['Value']
54
54
  expect(value).to eq Onelogin::Saml::StatusCodes::SUCCESS_URI
55
55
  end
56
56
 
57
57
  it "includes status message tag" do
58
- value = xml.find_first("/samlp:LogoutResponse/samlp:Status/samlp:StatusMessage", Onelogin::NAMESPACES).content
58
+ value = xml.at_xpath("/samlp:LogoutResponse/samlp:Status/samlp:StatusMessage", Onelogin::NAMESPACES).content
59
59
  expect(value).to eq Onelogin::Saml::LogoutResponse::STATUS_MESSAGE
60
60
  end
61
61
 
@@ -32,7 +32,7 @@ describe Onelogin::Saml::MetaData do
32
32
  )
33
33
  doc = REXML::Document.new Onelogin::Saml::MetaData.create(settings)
34
34
  key_descriptors = REXML::XPath.match(doc, "//KeyDescriptor")
35
- key_descriptors.should have(2).keys
35
+ key_descriptors.length.should == 2
36
36
  key_descriptors[0].attributes["use"].should == "encryption"
37
37
  key_descriptors[1].attributes["use"].should == "signing"
38
38
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-saml-mod
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5
4
+ version: 0.2.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - OneLogin LLC
@@ -14,22 +14,22 @@ authors:
14
14
  autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
- date: 2015-07-17 00:00:00.000000000 Z
17
+ date: 2015-08-03 00:00:00.000000000 Z
18
18
  dependencies:
19
19
  - !ruby/object:Gem::Dependency
20
- name: libxml-ruby
20
+ name: nokogiri
21
21
  requirement: !ruby/object:Gem::Requirement
22
22
  requirements:
23
- - - ">="
23
+ - - "~>"
24
24
  - !ruby/object:Gem::Version
25
- version: 2.3.0
25
+ version: '1.6'
26
26
  type: :runtime
27
27
  prerelease: false
28
28
  version_requirements: !ruby/object:Gem::Requirement
29
29
  requirements:
30
- - - ">="
30
+ - - "~>"
31
31
  - !ruby/object:Gem::Version
32
- version: 2.3.0
32
+ version: '1.6'
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: ffi
35
35
  requirement: !ruby/object:Gem::Requirement