anchor-pki 0.3.0 → 0.4.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -1
- data/README.md +2 -0
- data/lib/anchor/auto_cert/configuration.rb +5 -3
- data/lib/anchor/auto_cert/managed_certificate.rb +63 -0
- data/lib/anchor/auto_cert/manager.rb +17 -32
- data/lib/anchor/auto_cert/renewal_busy_wait.rb +39 -0
- data/lib/anchor/auto_cert.rb +2 -1
- data/lib/anchor/version.rb +1 -1
- data/lib/puma/dsl.rb +28 -0
- data/lib/puma/plugin/auto_cert.rb +97 -0
- metadata +6 -4
- data/lib/anchor/auto_cert/integration/puma.rb +0 -17
- data/lib/anchor/auto_cert/integration.rb +0 -11
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 342dadd5c28835816da2c07cdd1d4b7b546cc2a35ca80738cc98707d2a048cd4
|
|
4
|
+
data.tar.gz: 97cb3d7c9c9bbb770c8a3a52eae0690bc7f18cadd5f3a31689d6d00239f5a523
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 06b0f93d4bc1962f60a4122bd2f4a046818e36c49779eae9255ff24d6cbb7ba9bd9029bb4f72f516b96c5fa8aef98cea7fbbd6f29ae3b69e42e6cb31e5990ade
|
|
7
|
+
data.tar.gz: f220a29a0c170f74b8926a1ae804f65d1719a4f9956edc04c6844ac27b2404f15c56908cf5b608a35fec1fe10679b74442ace2b3f6034af3eab814d564da670d
|
data/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
-
## [0.
|
|
3
|
+
## [0.4.0] - 2023-06-06
|
|
4
|
+
|
|
5
|
+
- add a puma plugin and configuration dsl for better integration
|
|
6
|
+
- auto restart of puma when a certificate is renewed
|
|
7
|
+
- improve tests
|
|
8
|
+
- internal refactor to support the puma plugin
|
|
9
|
+
|
|
10
|
+
## [0.3.0] - 2023-06-05
|
|
4
11
|
|
|
5
12
|
- improve gem packaging
|
|
6
13
|
- extract out a configuration class for Acme
|
data/README.md
CHANGED
|
@@ -14,6 +14,8 @@ The Following environment variables are available to configure the default
|
|
|
14
14
|
* `ACME_HMAC_KEY` - your EAB HMAC_KEY for authenticating with the ACME directory above
|
|
15
15
|
* `ACME_RENEW_BEFORE_SECONDS` - **optional** Start a renewal this number number of seconds before the cert expires. This defaults to 30 days (2592000 seconds)
|
|
16
16
|
* `ACME_RENEW_BEFORE_FRACTION` - **optional** Start the renewal when this fraction of a cert's valid window is left. This defaults to 0.5, which means when the cert is in the last 50% of its lifespan a renewal is attempted.
|
|
17
|
+
* `AUTO_CERT_CHECK_EVERY` - **optional** the number of seconds to wait between checking if the certificate has expired. This defaults to 1 hour (3600 seconds)
|
|
18
|
+
* `AUTO_CERT_NAME` - **optional** the name to use to lookup the default `AutoCert::Configuration` in the `AutoCert::Registry`. This is `default` by default
|
|
17
19
|
|
|
18
20
|
If both `ACME_RENEW_BEFORE_SECONDS` and `ACME_RENEW_BEFORE_FRACTION` are set,
|
|
19
21
|
the one that causes the renewal to take place earlier is used.
|
|
@@ -60,10 +60,12 @@ module Anchor
|
|
|
60
60
|
}
|
|
61
61
|
end
|
|
62
62
|
|
|
63
|
-
# Enabled means that the configuration
|
|
64
|
-
# directory url set.
|
|
63
|
+
# Enabled just means that the configuration is valid
|
|
65
64
|
def enabled?
|
|
66
|
-
|
|
65
|
+
validate!
|
|
66
|
+
true
|
|
67
|
+
rescue ConfigurationError => _e
|
|
68
|
+
false
|
|
67
69
|
end
|
|
68
70
|
|
|
69
71
|
def validate!
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'forwardable'
|
|
4
|
+
|
|
5
|
+
module Anchor
|
|
6
|
+
module AutoCert
|
|
7
|
+
# ManagedCertificate is a class that represents a certificate and its manager
|
|
8
|
+
# for renewal
|
|
9
|
+
class ManagedCertificate
|
|
10
|
+
attr_reader :cert_pem, :cert_path, :key_pem, :key_path, :key, :manager, :x509
|
|
11
|
+
|
|
12
|
+
extend Forwardable
|
|
13
|
+
def_delegators :@manager, :enabled?
|
|
14
|
+
def_delegators :@x509, :not_after, :not_before, :serial
|
|
15
|
+
|
|
16
|
+
def self.from(manager:, cert_path:, key_path:)
|
|
17
|
+
cert_pem = File.read(cert_path)
|
|
18
|
+
key_pem = File.read(key_path)
|
|
19
|
+
new(manager: manager, cert_pem: cert_pem, key_pem: key_pem)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def initialize(manager:, cert_pem:, key_pem:)
|
|
23
|
+
@manager = manager
|
|
24
|
+
@cert_pem = cert_pem
|
|
25
|
+
@key_pem = key_pem
|
|
26
|
+
@x509 = OpenSSL::X509::Certificate.new(cert_pem)
|
|
27
|
+
|
|
28
|
+
hex_serial_basename = hex_serial('-')
|
|
29
|
+
@cert_path = manager.work_dir / "#{hex_serial_basename}.crt"
|
|
30
|
+
@key_path = manager.work_dir / "#{hex_serial_basename}.key"
|
|
31
|
+
|
|
32
|
+
write_working_files
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def hex_serial(joiner = ':')
|
|
36
|
+
x509.serial.to_s(16).scan(/.{2}/).join(joiner)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def needs_renewal?(now = Time.now.utc)
|
|
40
|
+
manager.needs_renewal?(cert: x509, now: now)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def identifiers
|
|
44
|
+
alt_names = x509&.extensions&.find { |ext| ext.oid == 'subjectAltName' }&.value&.split(', ') || []
|
|
45
|
+
alt_names.map { |name| name.sub(/^DNS:/, '') }
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def common_name
|
|
49
|
+
x509.subject.to_a.find { |name, _, _| name == 'CN' }[1]
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def write_working_files
|
|
53
|
+
cert_path.open('w') { |f| f << cert_pem }
|
|
54
|
+
key_path.open('w') { |f| f << key_pem }
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def purge_working_files
|
|
58
|
+
cert_path.delete if cert_path.exist?
|
|
59
|
+
key_path.delete if key_path.exist?
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -26,7 +26,8 @@ module Anchor
|
|
|
26
26
|
:configuration,
|
|
27
27
|
:directory_url,
|
|
28
28
|
:identifier_policies,
|
|
29
|
-
:tos_acceptors
|
|
29
|
+
:tos_acceptors,
|
|
30
|
+
:work_dir
|
|
30
31
|
|
|
31
32
|
def self.for(configuration)
|
|
32
33
|
new(configuration: configuration)
|
|
@@ -50,23 +51,10 @@ module Anchor
|
|
|
50
51
|
@enabled = true
|
|
51
52
|
end
|
|
52
53
|
|
|
53
|
-
# It is currently assumed that the common name is the first of the
|
|
54
|
-
# `identifiers` passed into this method. If that is not the case, then the
|
|
55
|
-
# `common_name` parameter needs to be set explicitly
|
|
56
|
-
def certificate_paths(identifiers:, algorithm: :ecdsa, common_name: Array(identifiers).first, **opts)
|
|
57
|
-
cert_pem, key_pem = certificate(identifiers: identifiers, algorithm: algorithm, common_name: common_name,
|
|
58
|
-
**opts)
|
|
59
|
-
|
|
60
|
-
cert = (@work_dir / common_name).open('w') { |f| f << cert_pem }.path
|
|
61
|
-
key = (@work_dir / "#{common_name}+#{algorithm}").open('w') { |f| f << key_pem }.path
|
|
62
|
-
|
|
63
|
-
[cert, key]
|
|
64
|
-
end
|
|
65
|
-
|
|
66
54
|
# It is currently assumed that the common name is the first of the
|
|
67
55
|
# `identifiers` passed into this method. If that is not the case, then
|
|
68
56
|
# the `common_name` parameter needs to be set explicitly
|
|
69
|
-
def
|
|
57
|
+
def managed_certificate(identifiers:, algorithm: :ecdsa, common_name: Array(identifiers).first, **opts)
|
|
70
58
|
if (arr = denied_identifiers(identifiers)).size.positive?
|
|
71
59
|
raise IdentifierNotAllowedError, "denied identifiers'#{arr.join(',')}'"
|
|
72
60
|
end
|
|
@@ -74,7 +62,7 @@ module Anchor
|
|
|
74
62
|
key_pem = cache&.read("#{common_name}+#{algorithm}")
|
|
75
63
|
cert_pem = cache&.read(common_name)
|
|
76
64
|
|
|
77
|
-
if key_pem.nil? || cert_pem.nil?
|
|
65
|
+
if key_pem.nil? || cert_pem.nil?
|
|
78
66
|
cert_pem, key_pem = provision(identifiers: identifiers, algorithm: algorithm, common_name: common_name,
|
|
79
67
|
**opts)
|
|
80
68
|
|
|
@@ -82,15 +70,25 @@ module Anchor
|
|
|
82
70
|
cache&.write(common_name, cert_pem)
|
|
83
71
|
end
|
|
84
72
|
|
|
85
|
-
|
|
73
|
+
ManagedCertificate.new(manager: self, cert_pem: cert_pem, key_pem: key_pem)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def needs_renewal?(cert:, now: Time.now.utc)
|
|
77
|
+
renew_after = [
|
|
78
|
+
renew_after_from_seconds(cert: cert),
|
|
79
|
+
renew_after_from_fraction(cert: cert),
|
|
80
|
+
renew_after_fallback(cert: cert),
|
|
81
|
+
cert.not_after # cert expired, get a new one
|
|
82
|
+
].compact.min
|
|
83
|
+
|
|
84
|
+
(now > renew_after)
|
|
86
85
|
end
|
|
87
86
|
|
|
88
87
|
def disable
|
|
89
88
|
@enabled = false
|
|
90
89
|
end
|
|
91
90
|
|
|
92
|
-
#
|
|
93
|
-
# test for other configuration options.
|
|
91
|
+
# if the manager is enabled && the configuration is enabled
|
|
94
92
|
def enabled?
|
|
95
93
|
@enabled && configuration.enabled?
|
|
96
94
|
end
|
|
@@ -128,19 +126,6 @@ module Anchor
|
|
|
128
126
|
external_account_binding: external_account_binding)
|
|
129
127
|
end
|
|
130
128
|
|
|
131
|
-
def needs_renewal?(cert_pem:, now: Time.now.utc)
|
|
132
|
-
cert = OpenSSL::X509::Certificate.new(cert_pem)
|
|
133
|
-
|
|
134
|
-
renew_after = [
|
|
135
|
-
renew_after_from_seconds(cert: cert),
|
|
136
|
-
renew_after_from_fraction(cert: cert),
|
|
137
|
-
renew_after_fallback(cert: cert),
|
|
138
|
-
cert.not_after # cert expired, get a new one
|
|
139
|
-
].compact.min
|
|
140
|
-
|
|
141
|
-
(now > renew_after)
|
|
142
|
-
end
|
|
143
|
-
|
|
144
129
|
def renew_after_from_seconds(cert:, before_seconds: renew_before_seconds)
|
|
145
130
|
return nil unless before_seconds
|
|
146
131
|
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Anchor
|
|
4
|
+
module AutoCert
|
|
5
|
+
# RenewalBusyWait is a class that will loop to check if a certificate needs to
|
|
6
|
+
# to be renewed, and if it does, return
|
|
7
|
+
#
|
|
8
|
+
# Generally this class should be used inside its own thread as it will sleep
|
|
9
|
+
# and loop until the pem file is able to be renewed.
|
|
10
|
+
#
|
|
11
|
+
# Every 'check_every' interval it will check if the certificate needs to be
|
|
12
|
+
# renewed. If it does, the loop will end and `wait_for_it` will return. If
|
|
13
|
+
# it does not need renewal, the block will be called, and if the result of
|
|
14
|
+
# the block is falsy, the loop will exit early
|
|
15
|
+
#
|
|
16
|
+
class RenewalBusyWait
|
|
17
|
+
ONE_HOUR = 60 * 60
|
|
18
|
+
|
|
19
|
+
def self.wait_for_it(managed_certificate:, check_every: ONE_HOUR, &keep_going)
|
|
20
|
+
waiter = new(managed_certificate: managed_certificate, check_every: check_every)
|
|
21
|
+
waiter.wait_for_it(&keep_going)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def initialize(managed_certificate:, check_every: ONE_HOUR)
|
|
25
|
+
@managed_certificate = managed_certificate
|
|
26
|
+
@check_every = check_every
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def wait_for_it
|
|
30
|
+
loop do
|
|
31
|
+
break if @managed_certificate.needs_renewal?
|
|
32
|
+
break unless yield
|
|
33
|
+
|
|
34
|
+
sleep @check_every
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
data/lib/anchor/auto_cert.rb
CHANGED
|
@@ -13,8 +13,9 @@ end
|
|
|
13
13
|
require_relative 'auto_cert/terms_of_service_acceptor'
|
|
14
14
|
require_relative 'auto_cert/configuration'
|
|
15
15
|
require_relative 'auto_cert/manager'
|
|
16
|
+
require_relative 'auto_cert/managed_certificate'
|
|
16
17
|
require_relative 'auto_cert/identifier_policy'
|
|
17
18
|
require_relative 'auto_cert/registry'
|
|
18
|
-
require_relative 'auto_cert/
|
|
19
|
+
require_relative 'auto_cert/renewal_busy_wait'
|
|
19
20
|
|
|
20
21
|
require_relative 'auto_cert/railtie' if defined?(Rails::Railtie)
|
data/lib/anchor/version.rb
CHANGED
data/lib/puma/dsl.rb
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
# Extend the ::Puma::DSL module with the configuration options we want for
|
|
5
|
+
# autocert
|
|
6
|
+
#
|
|
7
|
+
|
|
8
|
+
require 'puma/dsl'
|
|
9
|
+
|
|
10
|
+
module Puma
|
|
11
|
+
# Extend the ::Puma::DSL module with the configuration options we want
|
|
12
|
+
class DSL
|
|
13
|
+
def auto_cert_name(name = nil)
|
|
14
|
+
@options[:auto_cert_name] = name if name
|
|
15
|
+
@options[:auto_cert_name]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def auto_cert_port(port = nil)
|
|
19
|
+
@options[:auto_cert_port] = port if port
|
|
20
|
+
@options[:auto_cert_port]
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def auto_cert_check_every(check_every = nil)
|
|
24
|
+
@options[:auto_cert_check_every] = check_every if check_every
|
|
25
|
+
@options[:auto_cert_check_every]
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../dsl'
|
|
4
|
+
module Puma
|
|
5
|
+
class Plugin
|
|
6
|
+
# This is a plugin for Puma that will automatically renew a certificate
|
|
7
|
+
#
|
|
8
|
+
# This module is here in order to communicate plugin configuration options
|
|
9
|
+
# to the plugin since the plugin is created dynamically and it is loaded and
|
|
10
|
+
# initialized without any configuration options.
|
|
11
|
+
module AutoCert
|
|
12
|
+
class << self
|
|
13
|
+
def ssl_bind_options(managed_certificate:)
|
|
14
|
+
{
|
|
15
|
+
cert: managed_certificate.cert_path,
|
|
16
|
+
key: managed_certificate.key_path
|
|
17
|
+
}
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Instance methods that are included in the dynamic Puma Plugin class when
|
|
22
|
+
# a plugin is created
|
|
23
|
+
module PluginInstanceMethods
|
|
24
|
+
attr_accessor :managed_certificate
|
|
25
|
+
|
|
26
|
+
def config(dsl)
|
|
27
|
+
port = dsl.auto_cert_port || ENV.fetch('HTTPS_PORT', nil)
|
|
28
|
+
name = dsl.auto_cert_name || ENV.fetch('AUTO_CERT_NAME', 'default')
|
|
29
|
+
configuration = ::Anchor::AutoCert::Registry.fetch(name)
|
|
30
|
+
identifiers = configuration.allow_identifiers
|
|
31
|
+
manager = ::Anchor::AutoCert::Manager.new(configuration: configuration)
|
|
32
|
+
|
|
33
|
+
@managed_certificate = manager.managed_certificate(identifiers: identifiers)
|
|
34
|
+
|
|
35
|
+
options = ::Puma::Plugin::AutoCert.ssl_bind_options(managed_certificate: @managed_certificate)
|
|
36
|
+
|
|
37
|
+
dsl.ssl_bind '[::]', port, options
|
|
38
|
+
rescue StandardError
|
|
39
|
+
@managed_certificate = nil
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def start(launcher)
|
|
43
|
+
@launcher = launcher
|
|
44
|
+
unless managed_certificate&.enabled?
|
|
45
|
+
log_writer.log 'AutoCert >> Not enabled - skipping certificate renewal process'
|
|
46
|
+
return
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
log_writer.log "AutoCert >> Configured for #{managed_certificate.identifiers.join(', ')}"
|
|
50
|
+
check_every = launcher.config.options[:auto_cert_check_every] ||
|
|
51
|
+
ENV.fetch('AUTO_CERT_CHECK_EVERY', nil) ||
|
|
52
|
+
::Anchor::AutoCert::RenewalBusyWait::ONE_HOUR
|
|
53
|
+
|
|
54
|
+
in_background do
|
|
55
|
+
Anchor::AutoCert::RenewalBusyWait.wait_for_it(managed_certificate: managed_certificate,
|
|
56
|
+
check_every: check_every) do
|
|
57
|
+
dump_cert_info
|
|
58
|
+
|
|
59
|
+
# if ssl server is up, then it has already read the local working
|
|
60
|
+
# files, which means we can purge them - if there's a disk cache, those still
|
|
61
|
+
# probably exist
|
|
62
|
+
ssl_server = launcher.binder.ios.find { |io| io.instance_of?(Puma::MiniSSL::Server) }
|
|
63
|
+
managed_certificate.purge_working_files if ssl_server
|
|
64
|
+
|
|
65
|
+
true
|
|
66
|
+
end
|
|
67
|
+
log_writer.log 'AutoCert >> Restarting Puma in order to renew certificate'
|
|
68
|
+
@launcher.restart
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
private
|
|
73
|
+
|
|
74
|
+
def dump_cert_info
|
|
75
|
+
log_writer.debug "AutoCert >> Bound cert : #{managed_certificate.hex_serial}"
|
|
76
|
+
log_writer.debug "AutoCert >> common name : #{managed_certificate.common_name}"
|
|
77
|
+
log_writer.debug "AutoCert >> identifiers : #{managed_certificate.identifiers.join(', ')}"
|
|
78
|
+
log_writer.debug "AutoCert >> not before : #{managed_certificate.not_before}"
|
|
79
|
+
log_writer.debug "AutoCert >> not after : #{managed_certificate.not_after}"
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def log_writer
|
|
83
|
+
if Gem::Version.new(Puma::Const::PUMA_VERSION) >= Gem::Version.new(6)
|
|
84
|
+
@launcher.log_writer
|
|
85
|
+
else
|
|
86
|
+
@launcher.events
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# This is the entry point for the plugin
|
|
95
|
+
Puma::Plugin.create do
|
|
96
|
+
include Puma::Plugin::AutoCert::PluginInstanceMethods
|
|
97
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: anchor-pki
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Anchor Security, Inc
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2023-06-
|
|
11
|
+
date: 2023-06-06 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: acme-client
|
|
@@ -142,8 +142,7 @@ files:
|
|
|
142
142
|
- lib/anchor/auto_cert.rb
|
|
143
143
|
- lib/anchor/auto_cert/configuration.rb
|
|
144
144
|
- lib/anchor/auto_cert/identifier_policy.rb
|
|
145
|
-
- lib/anchor/auto_cert/
|
|
146
|
-
- lib/anchor/auto_cert/integration/puma.rb
|
|
145
|
+
- lib/anchor/auto_cert/managed_certificate.rb
|
|
147
146
|
- lib/anchor/auto_cert/manager.rb
|
|
148
147
|
- lib/anchor/auto_cert/policy_check.rb
|
|
149
148
|
- lib/anchor/auto_cert/policy_check/for_hostname.rb
|
|
@@ -151,8 +150,11 @@ files:
|
|
|
151
150
|
- lib/anchor/auto_cert/policy_check/for_wildcard_hostname.rb
|
|
152
151
|
- lib/anchor/auto_cert/railtie.rb
|
|
153
152
|
- lib/anchor/auto_cert/registry.rb
|
|
153
|
+
- lib/anchor/auto_cert/renewal_busy_wait.rb
|
|
154
154
|
- lib/anchor/auto_cert/terms_of_service_acceptor.rb
|
|
155
155
|
- lib/anchor/version.rb
|
|
156
|
+
- lib/puma/dsl.rb
|
|
157
|
+
- lib/puma/plugin/auto_cert.rb
|
|
156
158
|
homepage: https://anchor.dev
|
|
157
159
|
licenses:
|
|
158
160
|
- MIT
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Anchor
|
|
4
|
-
module AutoCert
|
|
5
|
-
module Integration
|
|
6
|
-
# Puma integration
|
|
7
|
-
class Puma
|
|
8
|
-
def self.ssl_bind_options(manager:, identifiers: nil)
|
|
9
|
-
identifiers ||= manager.configuration.allow_identifiers
|
|
10
|
-
cert, key = manager.certificate_paths(identifiers: identifiers)
|
|
11
|
-
|
|
12
|
-
{ cert: cert, key: key }
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
end
|