acmesmith 0.5.1 → 0.6.0

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: 8f7314678f48d9decad7c7bedda283390a42f7b2
4
- data.tar.gz: c65377ad9caf33a936fb75c2529f70eb80500879
3
+ metadata.gz: 63bbb87b41e2ab5fbe44ca6ad4026795e314519f
4
+ data.tar.gz: c1d0645c4dc6d710e0422afd4caade86ed46c745
5
5
  SHA512:
6
- metadata.gz: bf2a7d3e56f5d99454eba7e1cb9940be726c880d0fd8b395396e7f4bf8181b1187d136c7ea9c3e56e629c9a164583cd4480e217bf90ce88ac7dba83d91344093
7
- data.tar.gz: db4c635849f2c0f37493c0a1cadbb34404104ada41509ce6a8b0a3ea27b17330b7adf5349e9f0496434909d2a9a5fb203884585a2580dbc2b0214aad24141720
6
+ metadata.gz: d01c1960e2fa8eae938260f3bb9a2f52f7caedf31d4540c667ab6061f4c8095bb1855e34d1170b409b5d7f396438dc69b38474bf2d25458563e1924a1ddf0c47
7
+ data.tar.gz: f5ae0c2375fb018564e5c5dbb5fe107613d35dbac0227e8c62e58b4037e6936acd5adef2a46f96eceaa93115af687375e08388973a66389d3037ddb99625b131
@@ -22,42 +22,81 @@ module Acmesmith
22
22
  puts "Generated:\n#{key.private_key.public_key.to_pem}"
23
23
  end
24
24
 
25
- desc "authorize DOMAIN", "Get authz for DOMAIN."
26
- def authorize(domain)
27
- authz = acme.authorize(domain: domain)
28
-
29
- challenges = [authz.http01, authz.dns01, authz.tls_sni01].compact
30
-
31
- challenge = nil
32
- responder = config.challenge_responders.find do |x|
33
- challenge = challenges.find { |_| x.support?(_.class::CHALLENGE_TYPE) }
25
+ desc "authorize DOMAIN [DOMAIN ...]", "Get authz for DOMAIN."
26
+ def authorize(*domains)
27
+ targets = domains.map do |domain|
28
+ authz = acme.authorize(domain: domain)
29
+ challenges = [authz.http01, authz.dns01, authz.tls_sni01].compact
30
+ challenge = nil
31
+ responder = config.challenge_responders.find do |x|
32
+ challenge = challenges.find { |_| x.support?(_.class::CHALLENGE_TYPE) }
33
+ end
34
+ {domain: domain, authz: authz, responder: responder, challenge: challenge}
34
35
  end
35
36
 
36
- responder.respond(domain, challenge)
37
-
38
37
  begin
39
- puts "=> Requesting verification..."
40
- challenge.request_verification
41
- loop do
42
- status = challenge.verify_status
43
- puts " * verify_status: #{status}"
44
- break if status == 'valid'
45
- if status == "invalid"
46
- err = challenge.error
47
- puts "#{err["type"]}: #{err["detail"]}"
48
- end
49
- sleep 3
38
+ targets.each do |target|
39
+ target[:responder].respond(target[:domain], target[:challenge])
50
40
  end
51
- puts "=> Done"
41
+
42
+ targets.each do |target|
43
+ puts "=> Requesting verifications..."
44
+ target[:challenge].request_verification
45
+ end
46
+ loop do
47
+ all_valid = true
48
+ targets.each do |target|
49
+ next if target[:valid]
50
+
51
+ status = target[:challenge].verify_status
52
+ puts " * [#{target[:domain]}] verify_status: #{status}"
53
+
54
+ if status == 'valid'
55
+ target[:valid] = true
56
+ next
57
+ end
58
+
59
+ all_valid = false
60
+ if status == "invalid"
61
+ err = target[:challenge].error
62
+ puts " ! [#{target[:domain]}] #{err["type"]}: #{err["detail"]}"
63
+ end
64
+ end
65
+ break if all_valid
66
+ sleep 3
67
+ end
68
+ puts "=> Done"
52
69
  ensure
53
- responder.cleanup(domain, challenge)
70
+ targets.each do |target|
71
+ target[:responder].cleanup(target[:domain], target[:challenge])
72
+ end
54
73
  end
55
74
  end
56
75
 
57
76
  desc "request COMMON_NAME [SAN]", "request certificate for CN +COMMON_NAME+ with SANs +SAN+"
58
77
  def request(common_name, *sans)
59
78
  csr = Acme::Client::CertificateRequest.new(common_name: common_name, names: sans)
60
- acme_cert = acme.new_certificate(csr)
79
+ retried = false
80
+ acme_cert = begin
81
+ acme.new_certificate(csr)
82
+ rescue Acme::Client::Error::Unauthorized => e
83
+ raise unless config.auto_authorize_on_request
84
+
85
+ puts "=> Authorizing unauthorized domain names"
86
+ # https://github.com/letsencrypt/boulder/blob/b9369a481415b3fe31e010b34e2ff570b89e42aa/ra/ra.go#L604
87
+ m = e.message.match(/authorizations for these names not found or expired: ((?:[a-zA-Z0-9_.\-]+(?:,\s+|$))+)/)
88
+ if m && m[1]
89
+ domains = m[1].split(/,\s+/)
90
+ else
91
+ warn " ! Error message on certificate request was #{e.message.inspect} and acmesmith couldn't determine which domain names are unauthorized (maybe a bug)"
92
+ warn " ! Attempting to authorize all domains in this certificate reuqest for now."
93
+ domains = [common_name, *sans]
94
+ end
95
+ puts " * #{domains.join(', ')}"
96
+ authorize(*domains)
97
+ retried = true
98
+ retry unless retried
99
+ end
61
100
 
62
101
  cert = Certificate.from_acme_client_certificate(acme_cert)
63
102
  storage.put_certificate(cert, certificate_key_passphrase)
@@ -36,6 +36,10 @@ module Acmesmith
36
36
  @config['certificate_key_passphrase']
37
37
  end
38
38
 
39
+ def auto_authorize_on_request
40
+ @config.fetch('auto_authorize_on_request', true)
41
+ end
42
+
39
43
  def storage
40
44
  @storage ||= begin
41
45
  c = @config['storage'].dup
@@ -1,3 +1,3 @@
1
1
  module Acmesmith
2
- VERSION = "0.5.1"
2
+ VERSION = "0.6.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: acmesmith
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - sorah (Shota Fukumori)
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-03-19 00:00:00.000000000 Z
11
+ date: 2017-05-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: acme-client
@@ -157,7 +157,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
157
157
  version: '0'
158
158
  requirements: []
159
159
  rubyforge_project:
160
- rubygems_version: 2.6.10
160
+ rubygems_version: 2.6.8
161
161
  signing_key:
162
162
  specification_version: 4
163
163
  summary: ACME client (Let's encrypt client) to manage certificate in multi server