~ubuntu-branches/ubuntu/trusty/puppet/trusty

« back to all changes in this revision

Viewing changes to lib/puppet/face/ca.rb

  • Committer: Package Import Robot
  • Author(s): Stig Sandbeck Mathisen
  • Date: 2011-10-22 14:08:22 UTC
  • mfrom: (1.1.25) (3.1.32 sid)
  • Revision ID: package-import@ubuntu.com-20111022140822-odxde5lohc45yhuz
Tags: 2.7.6-1
* New upstream release (CVE-2011-3872)
* Remove cherry-picked "groupadd_aix_warning" patch
* Install all new manpages

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
require 'puppet/face'
 
2
 
 
3
Puppet::Face.define(:ca, '0.1.0') do
 
4
  copyright "Puppet Labs", 2011
 
5
  license   "Apache 2 license; see COPYING"
 
6
 
 
7
  summary "Local Puppet Certificate Authority management."
 
8
 
 
9
  description <<-TEXT
 
10
    This provides local management of the Puppet Certificate Authority.
 
11
 
 
12
    You can use this subcommand to sign outstanding certificate requests, list
 
13
    and manage local certificates, and inspect the state of the CA.
 
14
  TEXT
 
15
 
 
16
  action :list do
 
17
    summary "List certificates and/or certificate requests."
 
18
 
 
19
    description <<-TEXT
 
20
      This will list the current certificates and certificate signing requests
 
21
      in the Puppet CA.  You will also get the fingerprint, and any certificate
 
22
      verification failure reported.
 
23
    TEXT
 
24
 
 
25
    option "--[no-]all" do
 
26
      summary "Include all certificates and requests."
 
27
    end
 
28
 
 
29
    option "--[no-]pending" do
 
30
      summary "Include pending certificate signing requests."
 
31
    end
 
32
 
 
33
    option "--[no-]signed" do
 
34
      summary "Include signed certificates."
 
35
    end
 
36
 
 
37
    option "--subject PATTERN" do
 
38
      summary "Only list if the subject matches PATTERN."
 
39
 
 
40
      description <<-TEXT
 
41
        Only include certificates or requests where subject matches PATTERN.
 
42
 
 
43
        PATTERN is interpreted as a regular expression, allowing complex
 
44
        filtering of the content.
 
45
      TEXT
 
46
    end
 
47
 
 
48
    when_invoked do |options|
 
49
      raise "Not a CA" unless Puppet::SSL::CertificateAuthority.ca?
 
50
      unless ca = Puppet::SSL::CertificateAuthority.instance
 
51
        raise "Unable to fetch the CA"
 
52
      end
 
53
 
 
54
      pattern = options[:subject].nil? ? nil :
 
55
        Regexp.new(options[:subject], Regexp::IGNORECASE)
 
56
 
 
57
      pending = options[:pending].nil? ? options[:all] : options[:pending]
 
58
      signed  = options[:signed].nil?  ? options[:all] : options[:signed]
 
59
 
 
60
      # By default we list pending, so if nothing at all was requested...
 
61
      unless pending or signed then pending = true end
 
62
 
 
63
      hosts = []
 
64
 
 
65
      pending and hosts += ca.waiting?
 
66
      signed  and hosts += ca.list
 
67
 
 
68
      pattern and hosts = hosts.select {|hostname| pattern.match hostname }
 
69
 
 
70
      hosts.sort.map {|host| Puppet::SSL::Host.new(host) }
 
71
    end
 
72
 
 
73
    when_rendering :console do |hosts|
 
74
      unless ca = Puppet::SSL::CertificateAuthority.instance
 
75
        raise "Unable to fetch the CA"
 
76
      end
 
77
 
 
78
      length = hosts.map{|x| x.name.length }.max + 1
 
79
 
 
80
      hosts.map do |host|
 
81
        name = host.name.ljust(length)
 
82
        if host.certificate_request then
 
83
          "  #{name} (#{host.certificate_request.fingerprint})"
 
84
        else
 
85
          begin
 
86
            ca.verify(host.certificate)
 
87
            "+ #{name} (#{host.certificate.fingerprint})"
 
88
          rescue Puppet::SSL::CertificateAuthority::CertificateVerificationError => e
 
89
            "- #{name} (#{host.certificate.fingerprint}) (#{e.to_s})"
 
90
          end
 
91
        end
 
92
      end.join("\n")
 
93
    end
 
94
  end
 
95
 
 
96
  action :destroy do
 
97
    when_invoked do |host, options|
 
98
      raise "Not a CA" unless Puppet::SSL::CertificateAuthority.ca?
 
99
      unless ca = Puppet::SSL::CertificateAuthority.instance
 
100
        raise "Unable to fetch the CA"
 
101
      end
 
102
 
 
103
      ca.destroy host
 
104
    end
 
105
  end
 
106
 
 
107
  action :revoke do
 
108
    when_invoked do |host, options|
 
109
      raise "Not a CA" unless Puppet::SSL::CertificateAuthority.ca?
 
110
      unless ca = Puppet::SSL::CertificateAuthority.instance
 
111
        raise "Unable to fetch the CA"
 
112
      end
 
113
 
 
114
      begin
 
115
        ca.revoke host
 
116
      rescue ArgumentError => e
 
117
        # This is a bit naff, but it makes the behaviour consistent with the
 
118
        # destroy action.  The underlying tools could be nicer for that sort
 
119
        # of thing; they have fairly inconsistent reporting of failures.
 
120
        raise unless e.to_s =~ /Could not find a serial number for /
 
121
        "Nothing was revoked"
 
122
      end
 
123
    end
 
124
  end
 
125
 
 
126
  action :generate do
 
127
    option "--dns-alt-names NAMES" do
 
128
      summary "Additional DNS names to add to the certificate request"
 
129
      description Puppet.settings.setting(:dns_alt_names).desc
 
130
    end
 
131
 
 
132
    when_invoked do |host, options|
 
133
      raise "Not a CA" unless Puppet::SSL::CertificateAuthority.ca?
 
134
      unless ca = Puppet::SSL::CertificateAuthority.instance
 
135
        raise "Unable to fetch the CA"
 
136
      end
 
137
 
 
138
      begin
 
139
        ca.generate(host, :dns_alt_names => options[:dns_alt_names])
 
140
      rescue RuntimeError => e
 
141
        if e.to_s =~ /already has a requested certificate/
 
142
          "#{host} already has a certificate request; use sign instead"
 
143
        else
 
144
          raise
 
145
        end
 
146
      rescue ArgumentError => e
 
147
        if e.to_s =~ /A Certificate already exists for /
 
148
          "#{host} already has a certificate"
 
149
        else
 
150
          raise
 
151
        end
 
152
      end
 
153
    end
 
154
  end
 
155
 
 
156
  action :sign do
 
157
    option("--[no-]allow-dns-alt-names") do
 
158
      summary "Whether or not to accept DNS alt names in the certificate request"
 
159
    end
 
160
 
 
161
    when_invoked do |host, options|
 
162
      raise "Not a CA" unless Puppet::SSL::CertificateAuthority.ca?
 
163
      unless ca = Puppet::SSL::CertificateAuthority.instance
 
164
        raise "Unable to fetch the CA"
 
165
      end
 
166
 
 
167
      begin
 
168
        ca.sign(host, options[:allow_dns_alt_names])
 
169
      rescue ArgumentError => e
 
170
        if e.to_s =~ /Could not find certificate request/
 
171
          e.to_s
 
172
        else
 
173
          raise
 
174
        end
 
175
      end
 
176
    end
 
177
  end
 
178
 
 
179
  action :print do
 
180
    when_invoked do |host, options|
 
181
      raise "Not a CA" unless Puppet::SSL::CertificateAuthority.ca?
 
182
      unless ca = Puppet::SSL::CertificateAuthority.instance
 
183
        raise "Unable to fetch the CA"
 
184
      end
 
185
 
 
186
      ca.print host
 
187
    end
 
188
  end
 
189
 
 
190
  action :fingerprint do
 
191
    option "--digest ALGORITHM" do
 
192
      summary "The hash algorithm to use when displaying the fingerprint"
 
193
    end
 
194
 
 
195
    when_invoked do |host, options|
 
196
      raise "Not a CA" unless Puppet::SSL::CertificateAuthority.ca?
 
197
      unless ca = Puppet::SSL::CertificateAuthority.instance
 
198
        raise "Unable to fetch the CA"
 
199
      end
 
200
 
 
201
      begin
 
202
        # I want the default from the CA, not to duplicate it, but passing
 
203
        # 'nil' explicitly means that we don't get that.  This works...
 
204
        if options.has_key? :digest
 
205
          ca.fingerprint host, options[:digest]
 
206
        else
 
207
          ca.fingerprint host
 
208
        end
 
209
      rescue ArgumentError => e
 
210
        raise unless e.to_s =~ /Could not find a certificate or csr for/
 
211
        nil
 
212
      end
 
213
    end
 
214
  end
 
215
 
 
216
  action :verify do
 
217
    when_invoked do |host, options|
 
218
      raise "Not a CA" unless Puppet::SSL::CertificateAuthority.ca?
 
219
      unless ca = Puppet::SSL::CertificateAuthority.instance
 
220
        raise "Unable to fetch the CA"
 
221
      end
 
222
 
 
223
      begin
 
224
        ca.verify host
 
225
        { :host => host, :valid => true }
 
226
      rescue ArgumentError => e
 
227
        raise unless e.to_s =~ /Could not find a certificate for/
 
228
        { :host => host, :valid => false, :error => e.to_s }
 
229
      rescue Puppet::SSL::CertificateAuthority::CertificateVerificationError => e
 
230
        { :host => host, :valid => false, :error => e.to_s }
 
231
      end
 
232
    end
 
233
 
 
234
    when_rendering :console do |value|
 
235
      if value[:valid]
 
236
        nil
 
237
      else
 
238
        "Could not verify #{value[:host]}: #{value[:error]}"
 
239
      end
 
240
    end
 
241
  end
 
242
end