manticore 0.4.0-java → 0.4.1-java

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: 19e1191d64f814d4e5eeac2a74ea1cb9ec964451
4
- data.tar.gz: 973396d996c2d9bb26491fe88e8566ee27809304
3
+ metadata.gz: c68549109cd024c3e482eaed8cd316d9c316570d
4
+ data.tar.gz: 6844c804051ce09e9f31ccf3ffd4d14d5d294fe9
5
5
  SHA512:
6
- metadata.gz: 0dbfd05b0f5a02a31cde7696dac20baacfa9c981ae0c054d91fd203d2165d3fb42bf3add0363a7b49cb1a91e4c9047911be823c0409238783d8b19acad078088
7
- data.tar.gz: 6eeeded09429d4275256cc81a70e8e12314f70ca7d7c9276160d2c0f982323aa23d3658315dec7dac64b11fed97e5d402fdb728d23224d8f7330ac08f06dfd70
6
+ metadata.gz: 5f98cbb04885e180f8b692338648460a6b51220168e648629f5dcea0281871e94f16ca8cfd0470bcd33cceb2fed2914fe50b25e00f5226fc59c9e3786005feb9
7
+ data.tar.gz: d0a49ec53bb0286a2b6eed9cff0d819f80749317d280150040bf43d54126a9ec6e0a5bf2262c0d13b6c2f297fa8b3b8004e8f02b6e3ae0a2e9c179060a9753b6
Binary file
data.tar.gz.sig CHANGED
Binary file
@@ -1,4 +1,9 @@
1
- ## v0.4.1 (pending)
1
+ ## v0.4
2
+
3
+ ### v0.4.1 (pending)
4
+
5
+ * Add support for ssl[:ca_file], ssl[:client_cert], and ssl[:client_key], to emulate OpenSSL features in other Ruby HTTP clients
6
+ * Integrate Faraday adapter for Manticore
2
7
 
3
8
  ### v0.4.0
4
9
 
@@ -0,0 +1,101 @@
1
+ require 'faraday'
2
+
3
+ module Faraday
4
+ class Adapter
5
+ class Manticore < Faraday::Adapter
6
+ dependency { require 'manticore' }
7
+
8
+ class ParallelManager
9
+ def client=(client)
10
+ @client ||= client
11
+ end
12
+
13
+ def run
14
+ @client.execute! if @client
15
+ end
16
+ end
17
+
18
+ self.supports_parallel = true
19
+ def self.setup_parallel_manager(options = {})
20
+ ParallelManager.new
21
+ end
22
+
23
+ def client(env)
24
+ @client ||= begin
25
+ opts = {}
26
+ if ssl = env[:ssl].to_hash
27
+ opts[:ssl] = {}
28
+ opts[:ssl][:verify] = :disable if ssl[:verify] == false
29
+ opts[:ssl][:ca_file] = ssl[:ca_file]
30
+ opts[:ssl][:client_cert] = ssl[:client_cert]
31
+ opts[:ssl][:client_key] = ssl[:client_key]
32
+ end
33
+ ::Manticore::Client.new(opts)
34
+ end
35
+ end
36
+
37
+ def call(env)
38
+ super
39
+
40
+ opts = {}
41
+ if env.key? :request_headers
42
+ opts[:headers] = env[:request_headers]
43
+ opts[:headers].reject! {|k, _| k.downcase == "content-length" } # Manticore computes Content-Length
44
+ end
45
+ body = read_body(env)
46
+ opts[:body] = body if body
47
+
48
+ if req = env[:request]
49
+ opts[:request_timeout] = opts[:connect_timeout] = opts[:socket_timeout] = req[:timeout] if req.key?(:timeout)
50
+ opts[:connect_timeout] = opts[:socket_timeout] = req[:open_timeout] if req.key?(:open_timeout)
51
+ if prx = req[:proxy]
52
+ opts[:proxy] = {
53
+ :url => prx[:uri].to_s,
54
+ :user => prx[:user],
55
+ :password => prx[:password]
56
+ }
57
+ end
58
+ end
59
+
60
+ cl = client(env)
61
+ if parallel?(env)
62
+ env[:parallel_manager].client = cl
63
+ cl = cl.async
64
+ end
65
+
66
+ last_exception = nil
67
+
68
+ req = cl.send(env[:method].to_s.downcase, env[:url].to_s, opts)
69
+ req.on_success do |response|
70
+ save_response(env, response.code, response.body || "", response.headers)
71
+ env[:response].finish(env) if parallel?(env)
72
+ end
73
+
74
+ req.on_failure do |err|
75
+ case err
76
+ when ::Manticore::Timeout
77
+ raise TimeoutError, err
78
+ when ::Manticore::SocketException, ::Java::JavaUtilConcurrent::ExecutionException
79
+ raise ConnectionFailed, err
80
+ when ::Manticore::ClientProtocolException
81
+ raise Faraday::SSLError, err
82
+ else
83
+ raise err
84
+ end
85
+ end
86
+
87
+ req.call unless parallel?(env)
88
+ @app.call env
89
+ end
90
+
91
+ def parallel?(env)
92
+ !env[:parallel_manager].nil?
93
+ end
94
+
95
+ def read_body(env)
96
+ env[:body].respond_to?(:read) ? env[:body].read : env[:body]
97
+ end
98
+ end
99
+ register_middleware nil, :manticore => :Manticore
100
+ end
101
+ end
@@ -1,7 +1,6 @@
1
1
  require 'java'
2
2
  require 'uri'
3
3
  require 'cgi'
4
- require 'cgi/cookie'
5
4
 
6
5
  jars = ["httpcore-4.3.3", "httpclient-4.3.6", "commons-logging-1.1.3", "commons-codec-1.6.jar", "httpmime-4.3.6.jar"]
7
6
  jars.each do |jar|
@@ -1,4 +1,5 @@
1
1
  require 'thread'
2
+ require 'base64'
2
3
 
3
4
  module Manticore
4
5
  # General Timeout exception thrown for various Manticore timeouts
@@ -72,9 +73,11 @@ module Manticore
72
73
  include_package "java.util.concurrent"
73
74
  include_package "org.apache.http.client.protocol"
74
75
  include_package 'org.apache.http.conn.ssl'
76
+ include_package "java.security.cert"
77
+ include_package "java.security.spec"
78
+ include_package "java.security"
75
79
  java_import "org.apache.http.HttpHost"
76
80
  java_import "javax.net.ssl.SSLContext"
77
- java_import "java.security.KeyStore"
78
81
  java_import "org.manticore.HttpGetWithEntity"
79
82
  java_import "org.apache.http.auth.UsernamePasswordCredentials"
80
83
 
@@ -141,6 +144,9 @@ module Manticore
141
144
  # @option options [String] ssl[:keystore] (nil) Path to a custom key store to use for client certificate authentication
142
145
  # @option options [String] ssl[:keystore_password] (nil) Password used for decrypting the client auth key store
143
146
  # @option options [String] ssl[:keystore_type] (nil) Format of the key store, ie "JKS" or "PKCS12". If left nil, the type will be inferred from the keystore filename.
147
+ # @option options [String] ssl[:ca_file] (nil) OpenSSL-style path to an X.509 certificate to use to validate SSL certificates
148
+ # @option options [String] ssl[:client_cert] (nil) OpenSSL-style path to an X.509 certificate to use for client authentication
149
+ # @option options [String] ssl[:client_key] (nil) OpenSSL-style path to an RSA key to use for client authentication
144
150
  # @option options [boolean] ssl[:track_state] (false) Turn on or off connection state tracking. This helps prevent SSL information from leaking across threads, but means that connections
145
151
  # can't be shared across those threads. This should generally be left off unless you know what you're doing.
146
152
  def initialize(options = {})
@@ -554,18 +560,59 @@ module Manticore
554
560
  raise "Invalid value for :verify. Valid values are (:all, :browser, :default)"
555
561
  end
556
562
 
557
-
558
563
  context = SSLContexts.custom
564
+ setup_trust_store ssl_options, context, trust_strategy
565
+ setup_key_store ssl_options, context
559
566
 
567
+ SSLConnectionSocketFactory.new context.build, ssl_options[:protocols].to_java(:string), ssl_options[:cipher_suites].to_java(:string), verifier
568
+ end
569
+
570
+ def setup_trust_store(ssl_options, context, trust_strategy)
560
571
  trust_store = get_store(:truststore, ssl_options) if ssl_options.key?(:truststore)
572
+
573
+ # Support OpenSSL-style ca_file. We don't support ca_path for now.
574
+ if ssl_options[:ca_file]
575
+ trust_store ||= blank_keystore
576
+ open(ssl_options[:ca_file]) do |fp|
577
+ cert_collection = CertificateFactory.get_instance("X509").generate_certificates(fp.to_inputstream).to_a
578
+ cert_collection.each do |cert|
579
+ trust_store.set_certificate_entry(cert.getSubjectX500Principal.name, cert)
580
+ end
581
+ end
582
+ end
583
+
561
584
  context.load_trust_material(trust_store, trust_strategy)
585
+ end
586
+
587
+ KEY_EXTRACTION_REGEXP = /(?:^-----BEGIN(.* )PRIVATE KEY-----\n)(.*?)(?:-----END\1PRIVATE KEY.*$)/m
588
+ def setup_key_store(ssl_options, context)
589
+ key_store = get_store(:keystore, ssl_options) if ssl_options.key?(:keystore)
562
590
 
563
- if ssl_options.key?(:keystore)
564
- key_store = get_store(:keystore, ssl_options)
565
- context.load_key_material(key_store, ssl_options.fetch(:keystore_password, nil).to_java.toCharArray)
591
+ # Support OpenSSL-style bare X.509 certs with an RSA key
592
+ # This is really dumb - we have to b64-decode the key ourselves.
593
+ if ssl_options[:client_cert] && ssl_options[:client_key]
594
+ key_store ||= blank_keystore
595
+ certs, key = nil, nil
596
+ open(ssl_options[:client_cert]) do |fp|
597
+ certs = CertificateFactory.get_instance("X509").generate_certificates(fp.to_inputstream).to_array([].to_java(Certificate))
598
+ end
599
+
600
+ keystore_password = ssl_options.fetch(:keystore_password, "").to_java.toCharArray
601
+ # Add each of the keys in the given keyfile into the keystore.
602
+ open(ssl_options[:client_key]) do |fp|
603
+ key_parts = fp.read.scan(KEY_EXTRACTION_REGEXP)
604
+ key_parts.each do |type, b64key|
605
+ body = Base64.decode64 b64key
606
+ spec = PKCS8EncodedKeySpec.new(body.to_java_bytes)
607
+ type = type.strip
608
+ type = "RSA" if type == ""
609
+ key = KeyFactory.getInstance(type).generatePrivate(spec)
610
+ key_store.set_key_entry("key-#{Digest::SHA1.hexdigest(body)}", key, keystore_password, certs)
611
+ end
612
+ end
566
613
  end
567
614
 
568
- SSLConnectionSocketFactory.new context.build, ssl_options[:protocols].to_java(:string), ssl_options[:cipher_suites].to_java(:string), verifier
615
+ context.load_key_material(key_store, keystore_password) if key_store
569
616
  end
570
617
 
571
618
  def get_trust_store(options)
@@ -583,6 +630,10 @@ module Manticore
583
630
  end
584
631
  end
585
632
 
633
+ def blank_keystore
634
+ KeyStore.get_instance(KeyStore.get_default_type).tap {|k| k.load(nil, nil) }
635
+ end
636
+
586
637
  def guess_store_type(filename)
587
638
  if filename.end_with?(".p12")
588
639
  "pkcs12"
@@ -1,3 +1,3 @@
1
1
  module Manticore
2
- VERSION = "0.4.0"
2
+ VERSION = "0.4.1"
3
3
  end
@@ -112,6 +112,29 @@ describe Manticore::Client do
112
112
  end
113
113
  end
114
114
 
115
+ context 'when ca_file is given' do
116
+ let(:client) { Manticore::Client.new :ssl => {verify: :strict, ca_file: File.expand_path("../../ssl/ca_cert.crt", __FILE__) } }
117
+
118
+ it "should verify the request and succeed" do
119
+ expect { client.get("https://localhost:55444/").body }.to_not raise_exception
120
+ end
121
+ end
122
+
123
+ context 'when client_cert and client_key are given' do
124
+ let(:client) { Manticore::Client.new(
125
+ :ssl => {
126
+ verify: :strict,
127
+ ca_file: File.expand_path("../../ssl/ca_cert.crt", __FILE__),
128
+ client_cert: File.expand_path("../../ssl/client.crt", __FILE__),
129
+ client_key: File.expand_path("../../ssl/client.key", __FILE__)
130
+ })
131
+ }
132
+
133
+ it "should successfully auth requests" do
134
+ expect(client.get("https://localhost:55445/").body).to match("hello")
135
+ end
136
+ end
137
+
115
138
  context 'when off' do
116
139
  let(:client) { Manticore::Client.new :ssl => {:verify => :none} }
117
140
 
Binary file
@@ -0,0 +1,22 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDlTCCAX0CAQEwDQYJKoZIhvcNAQEFBQAwYTELMAkGA1UEBhMCVVMxCzAJBgNV
3
+ BAgMAk1EMRIwEAYDVQQHDAlCYWx0aW1vcmUxEDAOBgNVBAMMB1Rlc3QgQ0ExHzAd
4
+ BgkqhkiG9w0BCQEWEHRlc3RAZXhhbXBsZS5jb20wIBcNMTQxMjEwMjIwMzMxWhgP
5
+ MjExNDExMTYyMjAzMzFaMEIxCzAJBgNVBAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0
6
+ IENpdHkxHDAaBgNVBAoME0RlZmF1bHQgQ29tcGFueSBMdGQwgZ8wDQYJKoZIhvcN
7
+ AQEBBQADgY0AMIGJAoGBANf8i2rFB1llfRuNuERJyvXCR9cHEvW7jAXXUbrWRAFJ
8
+ yAE466ZYPWBZZ241iQOFsEAtjldly80USyD0Nfx18M6FR6dppH/cqEsLKT6Esa5X
9
+ ASOMJhgftiU2CvjIkVSVlIdTACetnoLLGF926F7lyNgAS4b9PZdg4QFr2Ih04NSx
10
+ AgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAKWAYd1Cgzu9lvhjweeO2HI9eLk7pr/c
11
+ 1f6yOLxwfZyxCVYkQ906/YVcO+vvb+R1gbHEw3cHED9SgIZARvNNM9I2YFk/KFEg
12
+ 3N8mo37KOHu4HGyhRcJqB90P7umwVyWJn2iXe8Wus/eWsszBgXyPM3Xa7Wwy7aBw
13
+ AXAnrRhESethWI3vH3yAJeT1RG1rGjEqEuojfDxgzKvt08PgMwkN8VY0b7XdAdXj
14
+ ycXCmhaTLveM9BQVYY/LrrMR4ynVM6Fv3GXR3Sz/Eup4sJTXo3DhZ4rSBAPkyHCD
15
+ wxcmrjEL9eMG8kqXT4y/UQyXYhWKbFB3InnfZCh/QJ1+JqpIhi+tEMrVRvMrYp7l
16
+ /6ZGml4wHlCL+ky/wG30sgTHpj+S8PG96LnJ+kXnkxycq6vCRJEfRmXhh70swIiv
17
+ Pgh6RAZu6AdVX+gztnD0oSbez39hb4qcolLjlSO2msBTbQ2lp9zNrB4MqzuAgC1K
18
+ CWs2oBm6NrrR4+Sx/JjLmQcoSeuFooUmloL1c5XRv1B7vpx9P2Do0aF6Xksvli0w
19
+ 62n72nI7nF8VfyKjjEABk6dNBK0dYFrO+5pWJ4KEdOt2fVw5pduB4K2TN12z0LlY
20
+ ItFnYxmFPzUGleMHZsHASsMPlNtroE4p6O+ofNfrwwBzSQ+G+KDoC94TzOF2pf69
21
+ A3NjNKNgxgG5
22
+ -----END CERTIFICATE-----
@@ -0,0 +1,16 @@
1
+ -----BEGIN PRIVATE KEY-----
2
+ MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBANf8i2rFB1llfRuN
3
+ uERJyvXCR9cHEvW7jAXXUbrWRAFJyAE466ZYPWBZZ241iQOFsEAtjldly80USyD0
4
+ Nfx18M6FR6dppH/cqEsLKT6Esa5XASOMJhgftiU2CvjIkVSVlIdTACetnoLLGF92
5
+ 6F7lyNgAS4b9PZdg4QFr2Ih04NSxAgMBAAECgYEAg0qy/P40D3WP7VXiszAgPfAR
6
+ d3aHYfTVkx9mQSrKP/Y3q/aL2Jw/AviV1PqaBRgZIYoPwrTQhCNX3/pTbtnKvMDr
7
+ Py5l9AHGvzWx9ThYV/ErcVNEFUNegTeiIKPcX8jh72s62PVRU0ZYUNPUh2cShZjr
8
+ qcLn+QKpxpnuuMPxgDkCQQD7NRFbkfq3Q7lwDN8/GMmBHxv/HOpLdLmWT7ua9OE9
9
+ JnVjml89fT31rM9D/YVZaf3kIe6y1xehRhCUfrlhnufnAkEA3Bt0E5DT0/utRgXS
10
+ 4xA5LHvnZ0R5mHGPd6m0/3c7uf3epeHUakE3HBvsp9Ys/87hByq/R7QCoTE2MVhg
11
+ uSZrpwJAIgeoWE1IN3dXMZSs0XFcKr+6HS8fliUz1ubqNS2jLZN+J4YMDNpggF1u
12
+ nnlDjT9Mg5ENMvDsZI6HRHZ+SnkqVQJAApzo0dqkSR3xvqUPDdcBdr+5zYYIk4C1
13
+ nUwMdAPsV5bl774wkVpY1yKVuqBWRGsmTLl7L9S5O0SkSg2siEYmfQJBAOEwqhs7
14
+ tkLpUpWv3+0V2Lv/0CuXrqgacXxebQ8MfcH9YpWV0M54kJ7u/4gNCXgj66pDAqfE
15
+ bU+RhxY82ohb5uo=
16
+ -----END PRIVATE KEY-----
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: manticore
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.1
5
5
  platform: java
6
6
  authors:
7
7
  - Chris Heald
@@ -92,6 +92,7 @@ files:
92
92
  - ext/manticore/org/manticore/HttpGetWithEntity.java
93
93
  - ext/manticore/org/manticore/Manticore.java
94
94
  - gem-public_cert.pem
95
+ - lib/faraday/adapter/manticore.rb
95
96
  - lib/jar/commons-codec-1.6.jar
96
97
  - lib/jar/commons-logging-1.1.3.jar
97
98
  - lib/jar/httpclient-4.3.6.jar
@@ -114,8 +115,11 @@ files:
114
115
  - spec/manticore/response_spec.rb
115
116
  - spec/manticore/stubbed_response_spec.rb
116
117
  - spec/spec_helper.rb
118
+ - spec/ssl/ca_cert.crt
117
119
  - spec/ssl/ca_cert.pem
118
120
  - spec/ssl/ca_key.pem
121
+ - spec/ssl/client.crt
122
+ - spec/ssl/client.key
119
123
  - spec/ssl/client.p12
120
124
  - spec/ssl/localhost.key
121
125
  - spec/ssl/localhost.pem
@@ -153,8 +157,11 @@ test_files:
153
157
  - spec/manticore/response_spec.rb
154
158
  - spec/manticore/stubbed_response_spec.rb
155
159
  - spec/spec_helper.rb
160
+ - spec/ssl/ca_cert.crt
156
161
  - spec/ssl/ca_cert.pem
157
162
  - spec/ssl/ca_key.pem
163
+ - spec/ssl/client.crt
164
+ - spec/ssl/client.key
158
165
  - spec/ssl/client.p12
159
166
  - spec/ssl/localhost.key
160
167
  - spec/ssl/localhost.pem
metadata.gz.sig CHANGED
Binary file