mypki 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 29b0e1ca9d86843362a76292865c1d5e0e7c4b39
4
+ data.tar.gz: f38a3df9e6f9e2ff3ad5eaf999b822bb91bee9ff
5
+ SHA512:
6
+ metadata.gz: 09ec984e8eeb92bc2210c66f7465d62a1420016a0a6f4cb161b3037eb19be248cf2a34d4776ad1fa9d0561b27ca0c9ca322004f881b0f5c4dd8e53c9403e3eff
7
+ data.tar.gz: 819fa0717376a6af75f66af6b71838b5065f92f0c7ba72a9270ffb3ff00c5510da991483b80e304831d8723353dd0d8d1bd8dd8822def4c4604878ced4c6b393
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ pkg/
2
+ Gemfile.lock
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source 'http://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mypki.gemspec
4
+ gemspec
5
+
6
+ gem 'iruby', group: 'development'
7
+ gem 'erector', group: 'development'
8
+ gem 'ffi-rzmq', group: 'development'
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) [year] [fullname]
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,83 @@
1
+ # MyPKI
2
+
3
+ PKI-enables Ruby's OpenSSL libraries, which PKI-enables most libraries and gems written in Ruby.
4
+
5
+ ## Installation
6
+
7
+ ```
8
+ $ gem install mypki
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ Simply `require 'mypki'` at the top of your script. If you don't want to PKI-enable everything, see the *Adapters* section.
14
+
15
+ ## Configuration
16
+
17
+ By default, MyPKI saves PKI information in the `.mypki`. Passwords are never saved to the configuration. If a configuration does not exist, MyPKI will prompt you for your PKI path the first time it is run. Should you need to change things, run the mypki utility:
18
+
19
+ ```
20
+ $ mypki --reconfigure
21
+ ```
22
+
23
+ MyPKI support P12s, PEMs, and key pairs. The P12 loader supports a `password` field in it's section of the ~/.mypki configuration file. I don't recommend keeping your password in the MyPKI config file.
24
+
25
+ ## Headless configuration
26
+
27
+ If you are using MyPKI on a server, then you can specify the location of the MyPKI configuration file by setting the `MYPKI_CONFIG` environment variable.
28
+
29
+ ## The MyPKI Utility
30
+
31
+ MyPKI ships with a command-line utility that will PKI-enable any other command-line tool written in Ruby. For example, to PKI the `geminabox` uploader:
32
+
33
+ ```
34
+ $ mypki gem inabox my-gem-1.0.0.gem
35
+ ```
36
+
37
+ IF you do this often, you can alias a command like this:
38
+
39
+ ```
40
+ alias gem='mypki gem'
41
+ ```
42
+
43
+ ## Adapters
44
+
45
+ By default, MyPKI PKI-enables all OpenSSL contexts. If you would only like to PKI-enable a particular library, you can use an adapter. For example:
46
+
47
+ ```ruby
48
+ require 'mypki/adapters/httpclient'
49
+ ```
50
+
51
+ The following adapters are available:
52
+
53
+ * httpclient
54
+ * http_persistent
55
+ * net_http
56
+ * openssl (default)
57
+
58
+ ## How does MyPKI work?
59
+
60
+ MyPKI modifies `OpenSSL::SSL::SSLContext` to use your PKCS#12 certificate and key. If you're working in a context where you want to be specific about what is PKI-enabled, you can. Here's an example of using my PKI to PKI-enable only `HTTPClient`.
61
+
62
+ ```ruby
63
+ require 'mypki/core'
64
+ require 'httpclient'
65
+
66
+ class HTTPClient
67
+ class SSLSocketWrap
68
+ def create_openssl_socket socket
69
+ context = MyPKI::Context.new
70
+ @context.set_context(context)
71
+ ssl_socket = OpenSSL::SSL::SSLSocket.new(socket, context)
72
+ end
73
+ end
74
+ end
75
+ ```
76
+
77
+ ## A note about PEMs
78
+
79
+ If you're trying to configure with PEM and are getting errors, make sure that your client certificates (and **only** your client certificates) are included in your PEM. For example:
80
+
81
+ ```
82
+ $ openssl pkcs12 -in pki.p12 -clcerts -out pki.pem
83
+ ```
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ task :default => :spec
data/exe/mypki ADDED
@@ -0,0 +1,57 @@
1
+ #! /usr/bin/env ruby
2
+ require 'mypki'
3
+ require 'trollop'
4
+
5
+ args = []
6
+
7
+ while arg = ARGV.first
8
+ if arg == '--'
9
+ ARGV.shift
10
+ break
11
+ elsif arg.start_with? '-'
12
+ args << ARGV.shift
13
+ else
14
+ break
15
+ end
16
+ end
17
+
18
+ options = Trollop::options args do
19
+ version MyPKI::VERSION
20
+ banner "MyPKI #{MyPKI::VERSION}: PKI-enables Ruby's OpenSSL libraries, which PKI-enables most libraries and gems written in Ruby.\n\nUSAGE:"
21
+ opt :ssh, "Also configure ssh to use your PKI"
22
+ opt :init, "Don't lazy-load, immediately prompting for a password if needed"
23
+ opt :no_verify, "Don't verify the certificate", depends: [:reconfigure]
24
+ opt :reconfigure, "Configure MyPKI, deleting any existing configuration"
25
+ end
26
+
27
+ if options[:reconfigure]
28
+ MyPKI.init reconfigure: true, no_verify: options[:no_verify]
29
+ end
30
+
31
+ if options[:init]
32
+ MyPKI.init
33
+ end
34
+
35
+ ARGV.shift args.size
36
+
37
+ if ARGV.empty?
38
+ Trollop::die "you must specify a program or option"
39
+ end
40
+
41
+ executable = ARGV.shift
42
+
43
+ path = if File.file?(executable) && File.executable?(executable)
44
+ executable
45
+ elsif ENV['PATH']
46
+ path = ENV['PATH'].split(File::PATH_SEPARATOR).find do |p|
47
+ abs_path = File.join(p, executable)
48
+ File.file?(abs_path) && File.executable?(abs_path)
49
+ end
50
+ path && File.expand_path(executable, path)
51
+ end
52
+
53
+ if path.nil?
54
+ raise "Could not find #{executable}"
55
+ else
56
+ exec "/usr/bin/env ruby -r mypki #{path} #{ARGV.join(' ')}"
57
+ end
data/lib/mypki.rb ADDED
@@ -0,0 +1,5 @@
1
+ # there are some jruby configurations that must be
2
+ # made before openssl is loaded
3
+ require 'mypki/jruby' if RUBY_PLATFORM == 'java'
4
+ require 'mypki/core'
5
+ require 'mypki/adapters/openssl'
@@ -0,0 +1,13 @@
1
+ require 'net/http/persistent'
2
+
3
+ class Net::HTTP::Persistent
4
+ alias :old_initialize :initialize
5
+
6
+ def initialize *args
7
+ old_initialize *args
8
+ context = MyPKI::Context.new
9
+ self.private_key = context.key
10
+ self.certificate = context.cert
11
+ self.verify_mode = context.verify_mode
12
+ end
13
+ end
@@ -0,0 +1,12 @@
1
+ require 'mypki/core'
2
+ require 'httpclient'
3
+
4
+ class HTTPClient
5
+ class SSLSocketWrap
6
+ def create_openssl_socket socket
7
+ context = MyPKI::Context.new
8
+ @context.set_context(context)
9
+ ssl_socket = OpenSSL::SSL::SSLSocket.new(socket, context)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,19 @@
1
+ require 'mypki/core'
2
+ require 'net/https'
3
+
4
+ class Net::HTTP
5
+ alias :old_initialize :initialize
6
+
7
+ def initialize *args, &block
8
+ old_initialize *args, &block
9
+ context = MyPKI::Context.new
10
+
11
+ SSL_ATTRIBUTES.each do |method|
12
+ if [context,self].all? {|o| o.respond_to? method}
13
+ if value = context.send(method)
14
+ send "#{method}=", value
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,8 @@
1
+ require 'openssl'
2
+ require 'mypki/core'
3
+
4
+ class OpenSSL::SSL::SSLContext
5
+ def self.new
6
+ MyPKI::Context.new
7
+ end
8
+ end
@@ -0,0 +1,78 @@
1
+ require 'multi_json'
2
+
3
+ module MyPKI
4
+ class Configuration < Hash
5
+ include Prompter
6
+ attr_reader :options
7
+
8
+ def initialize path, **options
9
+ @options = options
10
+ @path = File.expand_path path
11
+ @loaders = loaders.map{|loader| loader.new options}
12
+
13
+ if File.exist? @path
14
+ begin
15
+ merge! MultiJson.load(File.read(@path))
16
+ @loaders.each {|l| l.load self}
17
+ rescue => ex
18
+ raise "Bad MyPKI configuration (#{ex.message})"
19
+ end
20
+ else
21
+ retriable on_retry: proc { warn $! } do
22
+ clear
23
+ create
24
+ end
25
+ end
26
+ end
27
+
28
+ def create
29
+ pki = file_prompt 'Path to your PKI: '
30
+
31
+ @loaders.each do |loader|
32
+ loader.configure self, pki
33
+ loader.load self unless options[:no_verify]
34
+ end
35
+
36
+ if Instance.cert.nil? and Instance.key.nil? and not options[:no_verify]
37
+ fail 'Unknown PKI type - add an extension or try another file'
38
+ end
39
+
40
+ if File.writable? File.dirname(@path)
41
+ File.write @path, MultiJson.dump(Hash[keys.zip(values)], :pretty => true)
42
+ else
43
+ warn "warning: #{File.dirname(@path)} is not writable! MyPKI will not save a configuration."
44
+ end
45
+ end
46
+
47
+ class << self
48
+ attr_accessor :loaders
49
+ end
50
+
51
+ def loaders
52
+ self.class.loaders ||= []
53
+ end
54
+
55
+ module Loader
56
+ # options passed to MyPKI.init
57
+ attr_reader :options
58
+
59
+ def initialize options
60
+ @options = options
61
+ end
62
+
63
+ # once a config is established, it is passed to each loader to load
64
+ # whatever they need
65
+ def load config
66
+ end
67
+
68
+ # runs during configuration, before anything has been loaded,
69
+ # to give loaders a chance to insert anything they need into the config
70
+ def configure config, path
71
+ end
72
+
73
+ def self.included klass
74
+ (Configuration.loaders ||= []) << klass
75
+ end
76
+ end
77
+ end
78
+ end
data/lib/mypki/core.rb ADDED
@@ -0,0 +1,76 @@
1
+ require 'set'
2
+ require 'metaid'
3
+ require 'openssl'
4
+
5
+ require 'mypki/version'
6
+ require 'mypki/prompter'
7
+ require 'mypki/configuration'
8
+
9
+ require 'mypki/loaders/p12'
10
+ require 'mypki/loaders/pem'
11
+ require 'mypki/loaders/ca'
12
+ require 'mypki/loaders/ssh'
13
+
14
+ module MyPKI
15
+ Instance = OpenSSL::SSL::SSLContext.new
16
+
17
+ Instance.instance_eval do
18
+ @verify_mode = OpenSSL::SSL::VERIFY_NONE
19
+ @immutable_attributes = [:verify_mode].to_set
20
+
21
+ meta_eval do
22
+ (instance_methods - methods).each do |method|
23
+ if method['=']
24
+ getter, setter = method[0..-2].to_sym, method
25
+ alias_method :"original_#{setter}", setter
26
+
27
+ # keep track of set attributes
28
+ define_method setter do |*args, &block|
29
+ @immutable_attributes << getter
30
+ send :"original_#{setter}", *args, &block
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ class Context
38
+ def self.new **options
39
+ if Instance.key.nil? or Instance.cert.nil?
40
+ Configuration.new ENV['MYPKI_CONFIG']||'~/.mypki', **options
41
+ end
42
+
43
+ context = Instance.dup
44
+
45
+ context.instance_eval do
46
+ # make immutable attributes immutable
47
+ @immutable_attributes.each do |getter|
48
+ meta_def("#{getter}=") {|*a,&b| send getter}
49
+ end
50
+
51
+ # don't allow set_params to bypass setters
52
+ meta_def :set_params do |params|
53
+ params.each {|k,v| send "#{k}=", v}
54
+ end
55
+ end
56
+
57
+ context
58
+ end
59
+ end
60
+
61
+ module_function
62
+
63
+ def init reconfigure: false, **options
64
+ if reconfigure
65
+ path = File.expand_path(ENV['MYPKI_CONFIG'] || '~/.mypki')
66
+ File.delete path if File.exist? path
67
+ end
68
+
69
+ Context.new **options; true
70
+ end
71
+
72
+ def dn
73
+ init
74
+ Instance.cert.subject.to_s
75
+ end
76
+ end
@@ -0,0 +1,14 @@
1
+ java_import 'javax.crypto.JceSecurity'
2
+
3
+ # disable SNI since our servers don't support them
4
+ java.lang.System.set_property 'jsse.enableSNIExtension', 'false'
5
+
6
+ # we must remove cryptographic restrictions to communicate
7
+ # with our servers
8
+ begin
9
+ isRestricted = JceSecurity.java_class.declared_field 'isRestricted'
10
+ isRestricted.accessible = true
11
+ isRestricted.set_value nil, false
12
+ rescue => ex
13
+ warn "Could not remove cryptographic restrictions: #{ex.message}"
14
+ end
@@ -0,0 +1,39 @@
1
+ require 'retriable/core_ext/kernel'
2
+
3
+ module MyPKI
4
+ class CA
5
+ include Prompter
6
+ include Configuration::Loader
7
+
8
+ DEFAULT_PATH = '/etc/pki/tls/certs/ca-bundle.crt'
9
+
10
+ def configure config, path
11
+ if File.readable? DEFAULT_PATH
12
+ config['ca'] = DEFAULT_PATH
13
+ elsif config['ca'].nil?
14
+ prompt = "Path to CA chains (press enter to skip): "
15
+ path = file_prompt prompt, required: false
16
+
17
+ if path.nil?
18
+ config['ca'] = ''
19
+ else
20
+ if File.directory? path
21
+ fail "'#{path}' is a directory"
22
+ elsif not File.readable? path
23
+ fail "Cannot read '#{path}'"
24
+ else
25
+ config['ca'] = path
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ def load config
32
+ unless config['ca'].empty?
33
+ Instance.cert_store = OpenSSL::X509::Store.new
34
+ Instance.cert_store.add_file config['ca']
35
+ Instance.verify_mode = OpenSSL::SSL::VERIFY_PEER
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,31 @@
1
+ require 'retriable/core_ext/kernel'
2
+
3
+ module MyPKI
4
+ class P12
5
+ include Prompter
6
+ include Configuration::Loader
7
+
8
+ def configure config, path
9
+ if path.end_with? '.p12' or path.end_with? '.pfx'
10
+ config['p12'] = { 'path' => path }
11
+ end
12
+ end
13
+
14
+ def load config
15
+ if config['p12']
16
+ p12 = File.read config['p12']['path']
17
+
18
+ begin
19
+ retriable do
20
+ password = config['p12']['password']
21
+ password ||= pass_prompt 'Enter P12 pass phrase:'
22
+ pki = OpenSSL::PKCS12.new(p12, password)
23
+ Instance.key, Instance.cert = pki.key, pki.certificate
24
+ end
25
+ rescue OpenSSL::PKCS12::PKCS12Error
26
+ fail "Error: bad password"
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,61 @@
1
+ require 'retriable/core_ext/kernel'
2
+
3
+ module MyPKI
4
+ class PEM
5
+ include Prompter
6
+ include Configuration::Loader
7
+
8
+ def configure config, path
9
+ if %w[pem id_rsa key crt cert].any? {|ext| path.end_with? ext}
10
+ contents = File.read path
11
+ config['pem'] = {}
12
+ has_cert = false
13
+
14
+ if contents['PRIVATE KEY']
15
+ config['pem']['path'] = path
16
+ end
17
+
18
+ if contents['BEGIN CERTIFICATE']
19
+ has_cert = true
20
+ end
21
+
22
+ if config['pem']['path']
23
+ unless has_cert
24
+ config['pem']['cert'] = file_prompt('Path to your certificate: ')
25
+ end
26
+ elsif has_cert
27
+ config['pem']['cert'] = path
28
+ config['pem']['path'] = file_prompt('Path to your private key: ')
29
+ end
30
+ end
31
+ end
32
+
33
+ def load config
34
+ if config['pem']
35
+ pem = File.read config['pem']['path']
36
+ cert = (config['pem']['cert'])? File.read(config['pem']['cert']) : pem
37
+
38
+ begin
39
+ Instance.cert = OpenSSL::X509::Certificate.new cert
40
+ rescue OpenSSL::X509::CertificateError
41
+ config['pem'] = {}
42
+ Instance.key = Instance.cert = nil
43
+ fail "No certificate found! Regenerate with --nocerts or provide a .key and .crt file separately."
44
+ end
45
+
46
+ begin
47
+ retriable do
48
+ if pem['ENCRYPTED']
49
+ password = pass_prompt('PEM Passphrase:')
50
+ Instance.key = OpenSSL::PKey::RSA.new pem, password
51
+ else
52
+ Instance.key = OpenSSL::PKey::RSA.new pem
53
+ end
54
+ end
55
+ rescue OpenSSL::PKey::RSAError
56
+ fail "Error: bad password"
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,52 @@
1
+ require 'fileutils'
2
+ require 'shellwords'
3
+
4
+ module MyPKI
5
+ class SSH
6
+ include Prompter
7
+ include Configuration::Loader
8
+
9
+ def initialize options
10
+ super options
11
+
12
+ if options[:ssh]
13
+ Prompter.send :alias_method, :original, :pass_prompt
14
+ Prompter.send(:define_method, :pass_prompt) do |*a|
15
+ options[:password] = original *a
16
+ end
17
+ end
18
+ end
19
+
20
+ def load config
21
+ if options[:ssh] and Instance.cert and Instance.key
22
+ ssh_path = File.expand_path '~/.ssh/'
23
+ FileUtils.mkdir ssh_path unless File.exist? ssh_path
24
+ FileUtils.chmod 0700, ssh_path
25
+
26
+ key_path = File.expand_path '~/.ssh/id_rsa'
27
+ pub_path = File.expand_path '~/.ssh/id_rsa.pub'
28
+ authorized_keys = File.expand_path '~/.ssh/authorized_keys'
29
+
30
+ if password = options.delete(:password)
31
+ pass = Shellwords.escape password
32
+ result = `echo "#{Instance.key.to_pem}" | \
33
+ openssl pkcs8 -topk8 -out #{key_path} -v2 des3 -passout pass:#{pass} 2>&1`
34
+ else
35
+ result = `echo "#{Instance.key.to_pem}" | \
36
+ openssl pkcs8 -topk8 -out #{key_path} -v2 des3 -nocrypt 2>&1`
37
+ end
38
+
39
+ fail result unless result.empty?
40
+ FileUtils.chmod 0600, key_path
41
+
42
+ if password
43
+ `ssh-keygen -f #{key_path} -y -P #{pass} > #{pub_path}`
44
+ else
45
+ `ssh-keygen -f #{key_path} -y > #{pub_path}`
46
+ end
47
+
48
+ FileUtils.cp pub_path, authorized_keys
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,43 @@
1
+ require 'retriable/core_ext/kernel'
2
+
3
+ module MyPKI
4
+ module Prompter
5
+ def prompter
6
+ if defined? IRuby and defined? IRuby::VERSION
7
+ require 'mypki/prompters/iruby'
8
+ @prompter = IRubyPrompter.new
9
+ elsif RUBY_PLATFORM == 'java'
10
+ require 'mypki/prompters/jruby'
11
+ @prompter = JRubyPrompter.new
12
+ else
13
+ require 'mypki/prompters/cli'
14
+ @prompter = CommandLinePrompter.new
15
+ end
16
+ end
17
+
18
+ def file_prompt prompt, required: true
19
+ file = prompter.file_prompt(prompt)
20
+
21
+ if file.nil? or file.empty?
22
+ required ? fail('cancelled') : nil
23
+ else
24
+ expanded = File.expand_path file.strip
25
+
26
+ if File.directory? expanded
27
+ fail "'#{expanded}' is a directory"
28
+ end
29
+
30
+ unless File.readable? expanded
31
+ fail "Cannot read '#{expanded}'"
32
+ end
33
+
34
+ expanded
35
+ end
36
+ end
37
+
38
+ def pass_prompt prompt
39
+ pass = prompter.pass_prompt(prompt)
40
+ pass.strip if pass
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,23 @@
1
+ module MyPKI
2
+ module Prompter
3
+ class CommandLinePrompter
4
+ def file_prompt prompt
5
+ require 'readline'
6
+ Readline.completion_append_character = ''
7
+
8
+ Readline.completion_proc = proc do |key|
9
+ path = File.expand_path key
10
+ path += '/' if key.end_with? '/'
11
+ Dir["#{path}*"]
12
+ end
13
+
14
+ Readline.readline(prompt, true)
15
+ end
16
+
17
+ def pass_prompt prompt
18
+ require 'highline/import'
19
+ ask("#{prompt} ") {|q| q.echo = false}
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,69 @@
1
+ require 'shellwords'
2
+
3
+ module MyPKI
4
+ module Prompter
5
+ class IRubyPrompter
6
+ def file_prompt prompt
7
+
8
+ if prompt['PKI']
9
+ title = 'Configure MyPKI'
10
+ prompt = 'Your script requires access to a PKI-enabled resource. Please select the PKI certificate you would like to use to access that resource.'
11
+ label = :certificate
12
+
13
+ elsif prompt['certificate']
14
+ title = 'Missing Certificate'
15
+ prompt = "You're missing a certificate. If you have a certificate to go with your key, upload it below. Press Cancel to start over."
16
+ label = :certificate
17
+
18
+ elsif prompt['private key']
19
+ title = 'Missing Private Key'
20
+ prompt = "You're missing a private key. If you have a private key to go with your certificate, upload it below. Press Cancel to start over."
21
+ label = :private_key
22
+
23
+ elsif prompt['CA']
24
+ title = 'Add Trust Chains (Optional)'
25
+ prompt = 'Please select the trust chain you would like to use to authenticate servers. Hit cancel if you do not want to verify servers.'
26
+ label = :chains
27
+
28
+ else
29
+ abort "IRuby integration is missing a corresponding graphical prompt for '#{prompt}'"
30
+ end
31
+
32
+ iruby_file_prompt title, prompt, label
33
+ end
34
+
35
+ def pass_prompt prompt
36
+ response = IRuby.popup 'PKI Password' do
37
+ password
38
+ cancel
39
+ button
40
+ end
41
+ response[:password] if response
42
+ end
43
+
44
+ private
45
+
46
+ def iruby_file_prompt title, prompt, label
47
+ response = IRuby.popup title do
48
+ text prompt
49
+ html { br; br }
50
+ file label
51
+ cancel
52
+ button
53
+ end
54
+
55
+ if response && response[label]
56
+ filename = File.join(Dir.home, ".#{response[label][:name]}")
57
+ File.write(filename, response[label][:data])
58
+
59
+ if RUBY_PLATFORM['cygwin']
60
+ win_path = `cygpath -d #{Shellwords.escape(filename)}`.strip
61
+ `ATTRIB +H #{win_path.gsub("\\", "\\\\")}`
62
+ end
63
+
64
+ filename
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,13 @@
1
+ require 'mypki/prompters/readline'
2
+ require 'mypki/jruby/jline-2.12.1.jar'
3
+ java_import 'jline.console.ConsoleReader'
4
+
5
+ module MyPKI
6
+ module Prompter
7
+ class JRubyPrompter < ReadlinePrompter
8
+ def pass_prompt prompt
9
+ ConsoleReader.new.read_line prompt, ' '.ord
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,3 @@
1
+ module MyPKI
2
+ VERSION = "4.0.0"
3
+ end
data/mypki.gemspec ADDED
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'mypki/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "mypki"
8
+ spec.version = MyPKI::VERSION
9
+ spec.authors = ["Kyle King"]
10
+ spec.email = ["kylejking@gmail.com"]
11
+
12
+ spec.summary = %q{PKI-enable Ruby}
13
+ spec.description = %q{PKI-enables Ruby's OpenSSL libraries, which PKI-enables most libraries and gems written in Ruby.}
14
+ spec.homepage = "https://github.com/jupyter-gallery/mypki"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.bindir = "exe"
18
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency 'multi_json'
22
+ spec.add_dependency 'trollop'
23
+ spec.add_dependency 'metaid'
24
+ spec.add_dependency 'highline'
25
+ spec.add_dependency 'retriable'
26
+
27
+ spec.add_development_dependency "pry"
28
+ spec.add_development_dependency "bundler"
29
+ spec.add_development_dependency "rake"
30
+ end
metadata ADDED
@@ -0,0 +1,181 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mypki
3
+ version: !ruby/object:Gem::Version
4
+ version: 4.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Kyle King
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-05-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: multi_json
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: trollop
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: metaid
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: highline
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: retriable
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: pry
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: bundler
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rake
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ description: PKI-enables Ruby's OpenSSL libraries, which PKI-enables most libraries
126
+ and gems written in Ruby.
127
+ email:
128
+ - kylejking@gmail.com
129
+ executables:
130
+ - mypki
131
+ extensions: []
132
+ extra_rdoc_files: []
133
+ files:
134
+ - ".gitignore"
135
+ - Gemfile
136
+ - LICENSE
137
+ - README.md
138
+ - Rakefile
139
+ - exe/mypki
140
+ - lib/mypki.rb
141
+ - lib/mypki/adapters/http_persistent.rb
142
+ - lib/mypki/adapters/httpclient.rb
143
+ - lib/mypki/adapters/net_http.rb
144
+ - lib/mypki/adapters/openssl.rb
145
+ - lib/mypki/configuration.rb
146
+ - lib/mypki/core.rb
147
+ - lib/mypki/jruby.rb
148
+ - lib/mypki/loaders/ca.rb
149
+ - lib/mypki/loaders/p12.rb
150
+ - lib/mypki/loaders/pem.rb
151
+ - lib/mypki/loaders/ssh.rb
152
+ - lib/mypki/prompter.rb
153
+ - lib/mypki/prompters/cli.rb
154
+ - lib/mypki/prompters/iruby.rb
155
+ - lib/mypki/prompters/jruby.rb
156
+ - lib/mypki/version.rb
157
+ - mypki.gemspec
158
+ homepage: https://github.com/jupyter-gallery/mypki
159
+ licenses: []
160
+ metadata: {}
161
+ post_install_message:
162
+ rdoc_options: []
163
+ require_paths:
164
+ - lib
165
+ required_ruby_version: !ruby/object:Gem::Requirement
166
+ requirements:
167
+ - - ">="
168
+ - !ruby/object:Gem::Version
169
+ version: '0'
170
+ required_rubygems_version: !ruby/object:Gem::Requirement
171
+ requirements:
172
+ - - ">="
173
+ - !ruby/object:Gem::Version
174
+ version: '0'
175
+ requirements: []
176
+ rubyforge_project:
177
+ rubygems_version: 2.4.5.1
178
+ signing_key:
179
+ specification_version: 4
180
+ summary: PKI-enable Ruby
181
+ test_files: []