localhost 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 47320a58186ec6b563f8b2f33605a8a5b089bad34372b96b8f75bcf5e46bc702
4
+ data.tar.gz: d5881e19b6cfc2e12dabd2b8a0fc05d1a5e58e9440f45013d0220c5f398999c1
5
+ SHA512:
6
+ metadata.gz: a14c685f31632fec950b0adad3717497a1981f94ca19b3851d955a97422035d12809677106e3515a29dc2575bd3edbd457c7eb5401506c474e09b180e103e52d
7
+ data.tar.gz: 2e47b4b98fb60fdc885a971b744d8eeda298e29aa3cbe2d9a47586d8926758e56fd9e547ff05840fd0b34153e714c97d7f1022f100c11a4959589aff87b275c6
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
@@ -0,0 +1,23 @@
1
+ language: ruby
2
+ sudo: required
3
+ dist: xenial
4
+ cache: bundler
5
+
6
+ before_script:
7
+ - gem update --system
8
+ - gem install bundler
9
+
10
+ matrix:
11
+ include:
12
+ - rvm: 2.3
13
+ - rvm: 2.4
14
+ - rvm: 2.5
15
+ - rvm: 2.6
16
+ - rvm: jruby-head
17
+ env: JRUBY_OPTS="--debug -X+O"
18
+ - rvm: ruby-head
19
+ - rvm: rbx-3
20
+ allow_failures:
21
+ - rvm: ruby-head
22
+ - rvm: jruby-head
23
+ - rvm: rbx-3
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in localhost.gemspec
6
+ gemspec
@@ -0,0 +1,76 @@
1
+ # Localhost [![Build Status](https://travis-ci.com/socketry/localhost.svg)](https://travis-ci.com/socketry/localhost)
2
+
3
+ This gem provides a convenient API for generating per-user self-signed root certificates.
4
+
5
+ ## Motivation
6
+
7
+ HTTP/2 requires SSL in web browsers. If you want to use HTTP/2 for development (and you should), you need to start using URLs like `https://localhost:8080`. In most cases, this requires adding a self-signed certificate to your certificate store (e.g. Keychain on macOS), and storing the private key for the web-server to use.
8
+
9
+ I wanted to provide a server-agnostic way of doing this, primarily because I think it makes sense to minimise the amount of junky self-signed keys you add to your certificate store for `localhost`.
10
+
11
+ ## Installation
12
+
13
+ Add this line to your application's Gemfile:
14
+
15
+ ```ruby
16
+ gem 'localhost'
17
+ ```
18
+
19
+ And then execute:
20
+
21
+ $ bundle
22
+
23
+ Or install it yourself as:
24
+
25
+ $ gem install localhost
26
+
27
+ ## Usage
28
+
29
+ This example shows how to generate a certificate for an SSL secured web server:
30
+
31
+ ```ruby
32
+ require 'localhost/authority'
33
+
34
+ authority = Localhost::Authority.fetch
35
+
36
+ OpenSSL::SSL::SSLContext.new.tap do |context|
37
+ context.cert = authority.certificate
38
+ context.key = authority.key
39
+ end
40
+ ```
41
+
42
+ ## Contributing
43
+
44
+ 1. Fork it
45
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
46
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
47
+ 4. Push to the branch (`git push origin my-new-feature`)
48
+ 5. Create new Pull Request
49
+
50
+ ## See Also
51
+
52
+ - [falcon](https://github.com/socketry/falcon) — Uses this `Localhost::Authority` to provide HTTP/2 with minimal configuration for `localhost`.
53
+
54
+ ## License
55
+
56
+ Released under the MIT license.
57
+
58
+ Copyright, 2018, by [Samuel G. D. Williams](http://www.codeotaku.com/samuel-williams).
59
+
60
+ Permission is hereby granted, free of charge, to any person obtaining a copy
61
+ of this software and associated documentation files (the "Software"), to deal
62
+ in the Software without restriction, including without limitation the rights
63
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
64
+ copies of the Software, and to permit persons to whom the Software is
65
+ furnished to do so, subject to the following conditions:
66
+
67
+ The above copyright notice and this permission notice shall be included in
68
+ all copies or substantial portions of the Software.
69
+
70
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
71
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
72
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
73
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
74
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
75
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
76
+ THE SOFTWARE.
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,21 @@
1
+ # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require "localhost/version"
@@ -0,0 +1,112 @@
1
+ # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require 'yaml'
22
+ require 'openssl'
23
+
24
+ module Localhost
25
+ class Authority
26
+ def self.path
27
+ File.expand_path("~/.localhost")
28
+ end
29
+
30
+ def self.fetch(*args)
31
+ authority = self.new(*args)
32
+ path = self.path
33
+
34
+ unless authority.load(path)
35
+ Dir.mkdir(path, 0700) unless File.directory?(path)
36
+
37
+ authority.save(path)
38
+ end
39
+
40
+ return authority
41
+ end
42
+
43
+ def initialize(hostname = "localhost")
44
+ @hostname = hostname
45
+
46
+ @key = nil
47
+ @name = nil
48
+ @certificate = nil
49
+ end
50
+
51
+ def key
52
+ @key ||= OpenSSL::PKey::RSA.new(1024)
53
+ end
54
+
55
+ def name
56
+ @name ||= OpenSSL::X509::Name.parse("O=Development/CN=#{@hostname}")
57
+ end
58
+
59
+ def certificate
60
+ @certificate ||= OpenSSL::X509::Certificate.new.tap do |certificate|
61
+ certificate.subject = self.name
62
+ # We use the same issuer as the subject, which makes this certificate self-signed:
63
+ certificate.issuer = self.name
64
+
65
+ certificate.public_key = self.key.public_key
66
+
67
+ certificate.serial = 1
68
+
69
+ certificate.not_before = Time.now
70
+ certificate.not_after = Time.now + (3600 * 24 * 365 * 10)
71
+
72
+ extension_factory = OpenSSL::X509::ExtensionFactory.new
73
+ extension_factory.subject_certificate = certificate
74
+ extension_factory.issuer_certificate = certificate
75
+
76
+ certificate.sign self.key, OpenSSL::Digest::SHA256.new
77
+ end
78
+ end
79
+
80
+ # The certificate store which is used for validating the server certificate:
81
+ def store
82
+ @store ||= OpenSSL::X509::Store.new.tap do |store|
83
+ store.add_cert(self.certificate)
84
+ end
85
+ end
86
+
87
+ def load(path)
88
+ if File.directory? path
89
+ key_path = File.join(path, "#{@hostname}.key")
90
+ return false unless File.exist?(key_path)
91
+ @key = OpenSSL::PKey::RSA.new(File.read(key_path))
92
+
93
+ certificate_path = File.join(path, "#{@hostname}.crt")
94
+ @certificate = OpenSSL::X509::Certificate.new(File.read(certificate_path))
95
+
96
+ return true
97
+ end
98
+ end
99
+
100
+ def save(path)
101
+ File.write(
102
+ File.join(path, "#{@hostname}.crt"),
103
+ self.certificate.to_pem
104
+ )
105
+
106
+ File.write(
107
+ File.join(path, "#{@hostname}.key"),
108
+ self.key.to_pem
109
+ )
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,23 @@
1
+ # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ module Localhost
22
+ VERSION = "1.0.0"
23
+ end
@@ -0,0 +1,22 @@
1
+
2
+ require_relative "lib/localhost/version"
3
+
4
+ Gem::Specification.new do |spec|
5
+ spec.name = "localhost"
6
+ spec.version = Localhost::VERSION
7
+ spec.authors = ["Samuel Williams"]
8
+ spec.email = ["samuel.williams@oriontransfer.co.nz"]
9
+
10
+ spec.summary = "Manage a local certificate authority for self-signed localhost development servers."
11
+ spec.homepage = "https://github.com/socketry/localhost"
12
+
13
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
14
+ f.match(%r{^(test|spec|features)/})
15
+ end
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.require_paths = ["lib"]
18
+
19
+ spec.add_development_dependency "bundler", "~> 1.16"
20
+ spec.add_development_dependency "rake", "~> 10.0"
21
+ spec.add_development_dependency "rspec", "~> 3.0"
22
+ end
metadata ADDED
@@ -0,0 +1,96 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: localhost
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Samuel Williams
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-08-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.16'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.16'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ description:
56
+ email:
57
+ - samuel.williams@oriontransfer.co.nz
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - ".rspec"
64
+ - ".travis.yml"
65
+ - Gemfile
66
+ - README.md
67
+ - Rakefile
68
+ - lib/localhost.rb
69
+ - lib/localhost/authority.rb
70
+ - lib/localhost/version.rb
71
+ - localhost.gemspec
72
+ homepage: https://github.com/socketry/localhost
73
+ licenses: []
74
+ metadata: {}
75
+ post_install_message:
76
+ rdoc_options: []
77
+ require_paths:
78
+ - lib
79
+ required_ruby_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ required_rubygems_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ requirements: []
90
+ rubyforge_project:
91
+ rubygems_version: 2.7.6
92
+ signing_key:
93
+ specification_version: 4
94
+ summary: Manage a local certificate authority for self-signed localhost development
95
+ servers.
96
+ test_files: []