puppet 0.9.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of puppet might be problematic. Click here for more details.

Files changed (182) hide show
  1. data/CHANGELOG +0 -0
  2. data/COPYING +340 -0
  3. data/LICENSE +17 -0
  4. data/README +24 -0
  5. data/Rakefile +294 -0
  6. data/TODO +4 -0
  7. data/bin/cf2puppet +186 -0
  8. data/bin/puppet +176 -0
  9. data/bin/puppetca +213 -0
  10. data/bin/puppetd +246 -0
  11. data/bin/puppetdoc +184 -0
  12. data/bin/puppetmasterd +258 -0
  13. data/examples/code/allatonce +13 -0
  14. data/examples/code/assignments +11 -0
  15. data/examples/code/classing +35 -0
  16. data/examples/code/components +73 -0
  17. data/examples/code/execs +16 -0
  18. data/examples/code/failers/badclassnoparam +10 -0
  19. data/examples/code/failers/badclassparam +10 -0
  20. data/examples/code/failers/badcompnoparam +9 -0
  21. data/examples/code/failers/badcompparam +9 -0
  22. data/examples/code/failers/badtypeparam +3 -0
  23. data/examples/code/file.bl +11 -0
  24. data/examples/code/filedefaults +10 -0
  25. data/examples/code/fileparsing +116 -0
  26. data/examples/code/filerecursion +15 -0
  27. data/examples/code/functions +3 -0
  28. data/examples/code/groups +7 -0
  29. data/examples/code/head +30 -0
  30. data/examples/code/importing +8 -0
  31. data/examples/code/nodes +20 -0
  32. data/examples/code/one +8 -0
  33. data/examples/code/relationships +34 -0
  34. data/examples/code/selectors +28 -0
  35. data/examples/code/simpletests +11 -0
  36. data/examples/code/snippets/argumentdefaults +14 -0
  37. data/examples/code/snippets/casestatement +39 -0
  38. data/examples/code/snippets/classheirarchy.pp +15 -0
  39. data/examples/code/snippets/classincludes.pp +17 -0
  40. data/examples/code/snippets/classpathtest +11 -0
  41. data/examples/code/snippets/dirchmod +19 -0
  42. data/examples/code/snippets/failmissingexecpath.pp +13 -0
  43. data/examples/code/snippets/falsevalues.pp +3 -0
  44. data/examples/code/snippets/filecreate +11 -0
  45. data/examples/code/snippets/implicititeration +15 -0
  46. data/examples/code/snippets/multipleinstances +7 -0
  47. data/examples/code/snippets/namevartest +9 -0
  48. data/examples/code/snippets/scopetest +13 -0
  49. data/examples/code/snippets/selectorvalues.pp +22 -0
  50. data/examples/code/snippets/simpledefaults +5 -0
  51. data/examples/code/snippets/simpleselector +38 -0
  52. data/examples/code/svncommit +13 -0
  53. data/examples/root/bin/sleeper +69 -0
  54. data/examples/root/etc/configfile +0 -0
  55. data/examples/root/etc/debian-passwd +29 -0
  56. data/examples/root/etc/debian-syslog.conf +71 -0
  57. data/examples/root/etc/init.d/sleeper +65 -0
  58. data/examples/root/etc/otherfile +0 -0
  59. data/examples/root/etc/puppet/fileserver.conf +3 -0
  60. data/examples/root/etc/puppet/puppetmasterd.conf +10 -0
  61. data/ext/module:puppet +195 -0
  62. data/install.rb +270 -0
  63. data/lib/puppet.rb +249 -0
  64. data/lib/puppet/base64.rb +19 -0
  65. data/lib/puppet/client.rb +519 -0
  66. data/lib/puppet/config.rb +49 -0
  67. data/lib/puppet/daemon.rb +208 -0
  68. data/lib/puppet/element.rb +71 -0
  69. data/lib/puppet/event.rb +259 -0
  70. data/lib/puppet/log.rb +321 -0
  71. data/lib/puppet/metric.rb +250 -0
  72. data/lib/puppet/parsedfile.rb +38 -0
  73. data/lib/puppet/parser/ast.rb +1560 -0
  74. data/lib/puppet/parser/interpreter.rb +150 -0
  75. data/lib/puppet/parser/lexer.rb +226 -0
  76. data/lib/puppet/parser/parser.rb +1354 -0
  77. data/lib/puppet/parser/scope.rb +755 -0
  78. data/lib/puppet/server.rb +170 -0
  79. data/lib/puppet/server/authstore.rb +227 -0
  80. data/lib/puppet/server/ca.rb +140 -0
  81. data/lib/puppet/server/filebucket.rb +147 -0
  82. data/lib/puppet/server/fileserver.rb +477 -0
  83. data/lib/puppet/server/logger.rb +43 -0
  84. data/lib/puppet/server/master.rb +103 -0
  85. data/lib/puppet/server/servlet.rb +247 -0
  86. data/lib/puppet/sslcertificates.rb +737 -0
  87. data/lib/puppet/statechange.rb +150 -0
  88. data/lib/puppet/storage.rb +95 -0
  89. data/lib/puppet/transaction.rb +179 -0
  90. data/lib/puppet/transportable.rb +151 -0
  91. data/lib/puppet/type.rb +1354 -0
  92. data/lib/puppet/type/component.rb +141 -0
  93. data/lib/puppet/type/cron.rb +543 -0
  94. data/lib/puppet/type/exec.rb +316 -0
  95. data/lib/puppet/type/group.rb +152 -0
  96. data/lib/puppet/type/nameservice.rb +3 -0
  97. data/lib/puppet/type/nameservice/netinfo.rb +173 -0
  98. data/lib/puppet/type/nameservice/objectadd.rb +146 -0
  99. data/lib/puppet/type/nameservice/posix.rb +200 -0
  100. data/lib/puppet/type/package.rb +420 -0
  101. data/lib/puppet/type/package/apt.rb +70 -0
  102. data/lib/puppet/type/package/dpkg.rb +108 -0
  103. data/lib/puppet/type/package/rpm.rb +81 -0
  104. data/lib/puppet/type/package/sun.rb +117 -0
  105. data/lib/puppet/type/package/yum.rb +58 -0
  106. data/lib/puppet/type/pfile.rb +569 -0
  107. data/lib/puppet/type/pfile/checksum.rb +219 -0
  108. data/lib/puppet/type/pfile/create.rb +108 -0
  109. data/lib/puppet/type/pfile/group.rb +129 -0
  110. data/lib/puppet/type/pfile/mode.rb +131 -0
  111. data/lib/puppet/type/pfile/source.rb +264 -0
  112. data/lib/puppet/type/pfile/type.rb +31 -0
  113. data/lib/puppet/type/pfile/uid.rb +166 -0
  114. data/lib/puppet/type/pfilebucket.rb +80 -0
  115. data/lib/puppet/type/pprocess.rb +97 -0
  116. data/lib/puppet/type/service.rb +347 -0
  117. data/lib/puppet/type/service/base.rb +17 -0
  118. data/lib/puppet/type/service/debian.rb +50 -0
  119. data/lib/puppet/type/service/init.rb +145 -0
  120. data/lib/puppet/type/service/smf.rb +29 -0
  121. data/lib/puppet/type/state.rb +182 -0
  122. data/lib/puppet/type/symlink.rb +183 -0
  123. data/lib/puppet/type/tidy.rb +183 -0
  124. data/lib/puppet/type/typegen.rb +149 -0
  125. data/lib/puppet/type/typegen/filerecord.rb +243 -0
  126. data/lib/puppet/type/typegen/filetype.rb +316 -0
  127. data/lib/puppet/type/user.rb +290 -0
  128. data/lib/puppet/util.rb +138 -0
  129. data/test/certmgr/certmgr.rb +265 -0
  130. data/test/client/client.rb +203 -0
  131. data/test/executables/puppetbin.rb +53 -0
  132. data/test/executables/puppetca.rb +79 -0
  133. data/test/executables/puppetd.rb +71 -0
  134. data/test/executables/puppetmasterd.rb +153 -0
  135. data/test/executables/puppetmodule.rb +60 -0
  136. data/test/language/ast.rb +412 -0
  137. data/test/language/interpreter.rb +71 -0
  138. data/test/language/scope.rb +412 -0
  139. data/test/language/snippets.rb +445 -0
  140. data/test/other/events.rb +111 -0
  141. data/test/other/log.rb +195 -0
  142. data/test/other/metrics.rb +92 -0
  143. data/test/other/overrides.rb +115 -0
  144. data/test/other/parsedfile.rb +31 -0
  145. data/test/other/relationships.rb +113 -0
  146. data/test/other/state.rb +106 -0
  147. data/test/other/storage.rb +39 -0
  148. data/test/other/transactions.rb +235 -0
  149. data/test/parser/lexer.rb +120 -0
  150. data/test/parser/parser.rb +180 -0
  151. data/test/puppet/conffiles.rb +104 -0
  152. data/test/puppet/defaults.rb +100 -0
  153. data/test/puppet/error.rb +23 -0
  154. data/test/puppet/utiltest.rb +120 -0
  155. data/test/puppettest.rb +774 -0
  156. data/test/server/authstore.rb +209 -0
  157. data/test/server/bucket.rb +227 -0
  158. data/test/server/ca.rb +201 -0
  159. data/test/server/fileserver.rb +710 -0
  160. data/test/server/logger.rb +175 -0
  161. data/test/server/master.rb +150 -0
  162. data/test/server/server.rb +130 -0
  163. data/test/tagging/tagging.rb +80 -0
  164. data/test/test +51 -0
  165. data/test/types/basic.rb +119 -0
  166. data/test/types/component.rb +272 -0
  167. data/test/types/cron.rb +261 -0
  168. data/test/types/exec.rb +273 -0
  169. data/test/types/file.rb +616 -0
  170. data/test/types/filebucket.rb +167 -0
  171. data/test/types/fileignoresource.rb +287 -0
  172. data/test/types/filesources.rb +587 -0
  173. data/test/types/filetype.rb +162 -0
  174. data/test/types/group.rb +271 -0
  175. data/test/types/package.rb +205 -0
  176. data/test/types/query.rb +101 -0
  177. data/test/types/service.rb +100 -0
  178. data/test/types/symlink.rb +93 -0
  179. data/test/types/tidy.rb +124 -0
  180. data/test/types/type.rb +135 -0
  181. data/test/types/user.rb +371 -0
  182. metadata +243 -0
@@ -0,0 +1,170 @@
1
+ # the server
2
+ #
3
+ # allow things to connect to us and communicate, and stuff
4
+
5
+ require 'puppet'
6
+ require 'puppet/daemon'
7
+
8
+ $noservernetworking = false
9
+
10
+ begin
11
+ require 'webrick'
12
+ require 'webrick/https'
13
+ require 'cgi'
14
+ require 'xmlrpc/server'
15
+ require 'xmlrpc/client'
16
+ rescue LoadError => detail
17
+ $noservernetworking = detail
18
+ end
19
+
20
+ module Puppet
21
+ class ServerError < RuntimeError; end
22
+ #---------------------------------------------------------------
23
+ if $noservernetworking
24
+ Puppet.err "Could not create server: %s" % $noservernetworking
25
+ class Server; end
26
+ else
27
+ class Server < WEBrick::HTTPServer
28
+ include Puppet::Daemon
29
+
30
+ def initialize(hash = {})
31
+ daemonize = nil
32
+ if hash.include?(:Daemonize)
33
+ daemonize = hash[:Daemonize]
34
+ end
35
+
36
+ if daemonize
37
+ self.daemonize
38
+ end
39
+ # FIXME we should have some kind of access control here, using
40
+ # :RequestHandler
41
+ hash[:Port] ||= Puppet[:masterport]
42
+ hash[:Logger] ||= self.httplog
43
+ hash[:AccessLog] ||= [
44
+ [ self.httplog, WEBrick::AccessLog::COMMON_LOG_FORMAT ],
45
+ [ self.httplog, WEBrick::AccessLog::REFERER_LOG_FORMAT ]
46
+ ]
47
+
48
+ if hash.include?(:Handlers)
49
+ unless hash[:Handlers].is_a?(Hash)
50
+ raise ServerError, "Handlers must have arguments"
51
+ end
52
+
53
+ @handlers = hash[:Handlers].collect { |handler, args|
54
+ hclass = nil
55
+ unless hclass = Handler.handler(handler)
56
+ raise ServerError, "Invalid handler %s" % handler
57
+ end
58
+ hclass.new(args)
59
+ }
60
+ else
61
+ raise ServerError, "A server must have handlers"
62
+ end
63
+
64
+ # okay, i need to retrieve my cert and set it up, somehow
65
+ # the default case will be that i'm also the ca
66
+ if ca = @handlers.find { |handler| handler.is_a?(Puppet::Server::CA) }
67
+ @driver = ca
68
+ @secureinit = true
69
+ self.fqdn
70
+ end
71
+
72
+ unless self.readcert
73
+ unless self.requestcert
74
+ raise Puppet::Error, "Cannot start without certificates"
75
+ end
76
+ end
77
+
78
+ hash[:SSLCertificate] = @cert
79
+ hash[:SSLPrivateKey] = @key
80
+ hash[:SSLStartImmediately] = true
81
+ hash[:SSLEnable] = true
82
+ hash[:SSLCACertificateFile] = @cacertfile
83
+ hash[:SSLVerifyClient] = OpenSSL::SSL::VERIFY_PEER
84
+ hash[:SSLCertName] = nil
85
+
86
+ super(hash)
87
+
88
+ Puppet.info "Listening on port %s" % hash[:Port]
89
+
90
+ # this creates a new servlet for every connection,
91
+ # but all servlets have the same list of handlers
92
+ # thus, the servlets can have their own state -- passing
93
+ # around the requests and such -- but the handlers
94
+ # have a global state
95
+
96
+ # mount has to be called after the server is initialized
97
+ self.mount("/RPC2", Puppet::Server::Servlet, @handlers)
98
+ end
99
+ end
100
+ end
101
+
102
+ class Server
103
+ # the base class for the different handlers
104
+ class Handler
105
+ attr_accessor :server
106
+ @subclasses = []
107
+
108
+ def self.each
109
+ @subclasses.each { |c| yield c }
110
+ end
111
+
112
+ def self.handler(name)
113
+ @subclasses.find { |h|
114
+ h.name == name
115
+ }
116
+ end
117
+
118
+ def self.inherited(sub)
119
+ @subclasses << sub
120
+ end
121
+
122
+ def self.interface
123
+ if defined? @interface
124
+ return @interface
125
+ else
126
+ raise Puppet::DevError, "Handler %s has no defined interface" %
127
+ self
128
+ end
129
+ end
130
+
131
+ def self.name
132
+ unless defined? @name
133
+ @name = self.to_s.sub(/.+::/, '').intern
134
+ end
135
+
136
+ return @name
137
+ end
138
+
139
+ def initialize(hash = {})
140
+ end
141
+ end
142
+
143
+ class ServerStatus < Handler
144
+
145
+ @interface = XMLRPC::Service::Interface.new("status") { |iface|
146
+ iface.add_method("int status()")
147
+ }
148
+
149
+ @name = :Status
150
+
151
+ def status(status = nil, client = nil, clientip = nil)
152
+ return 1
153
+ end
154
+ end
155
+
156
+ end
157
+
158
+ #---------------------------------------------------------------
159
+ end
160
+
161
+ require 'puppet/server/authstore'
162
+ require 'puppet/server/servlet'
163
+ require 'puppet/server/master'
164
+ require 'puppet/server/ca'
165
+ require 'puppet/server/fileserver'
166
+ require 'puppet/server/filebucket'
167
+ require 'puppet/server/logger'
168
+ require 'puppet/client'
169
+
170
+ # $Id: server.rb 732 2005-10-28 05:39:59Z luke $
@@ -0,0 +1,227 @@
1
+ #!/usr/bin/ruby -w
2
+
3
+ #--------------------
4
+ # standard module for determining whether a given hostname or IP has access to
5
+ # the requested resource
6
+ #
7
+ # $Id: authstore.rb 742 2005-11-16 17:12:11Z luke $
8
+
9
+ require 'ipaddr'
10
+
11
+ module Puppet
12
+ class Server
13
+ class AuthStoreError < Puppet::Error; end
14
+ class AuthorizationError < Puppet::Error; end
15
+
16
+ class AuthStore
17
+ ORDER = {
18
+ :ip => [:ip],
19
+ :name => [:hostname, :domain]
20
+ }
21
+
22
+ Puppet::Util.logmethods(self, false)
23
+
24
+ def allow(pattern)
25
+ # a simple way to allow anyone at all to connect
26
+ if pattern == "*"
27
+ @globalallow = true
28
+ else
29
+ store(pattern, @allow)
30
+ end
31
+ end
32
+
33
+ def allowed?(name, ip)
34
+ if name or ip
35
+ unless name and ip
36
+ raise Puppet::DevError, "Name and IP must be passed to 'allowed?'"
37
+ end
38
+ # else, we're networked and such
39
+ else
40
+ # we're local
41
+ return true
42
+ end
43
+
44
+ # yay insecure overrides
45
+ if @globalallow
46
+ return true
47
+ end
48
+
49
+ value = nil
50
+ ORDER.each { |nametype, array|
51
+ if nametype == :ip
52
+ value = IPAddr.new(ip)
53
+ else
54
+ value = name.split(".").reverse
55
+ end
56
+
57
+ array.each { |type|
58
+ [[@deny, false], [@allow, true]].each { |ary|
59
+ hash, retval = ary
60
+ if hash.include?(type)
61
+ hash[type].each { |pattern|
62
+ if match?(nametype, value, pattern)
63
+ return retval
64
+ end
65
+ }
66
+ end
67
+ }
68
+ }
69
+ }
70
+
71
+ self.info "Defaulting to false for %s" % name
72
+ # default to false
73
+ return false
74
+ end
75
+
76
+ def deny(pattern)
77
+ store(pattern, @deny)
78
+ end
79
+
80
+ def initialize
81
+ @globalallow = nil
82
+ @allow = Hash.new { |hash, key|
83
+ hash[key] = []
84
+ }
85
+ @deny = Hash.new { |hash, key|
86
+ hash[key] = []
87
+ }
88
+ end
89
+
90
+ private
91
+
92
+ def match?(nametype, value, pattern)
93
+ if value == pattern # simplest shortcut
94
+ return true
95
+ end
96
+
97
+ case nametype
98
+ when :ip: matchip?(value, pattern)
99
+ when :name: matchname?(value, pattern)
100
+ else
101
+ raise Puppet::DevError, "Invalid match type %s" % nametype
102
+ end
103
+ end
104
+
105
+ def matchip?(value, pattern)
106
+ # we're just using builtin stuff for this, thankfully
107
+ if pattern.include?(value)
108
+ return true
109
+ else
110
+ return false
111
+ end
112
+ end
113
+
114
+ def matchname?(value, pattern)
115
+ # yay, horribly inefficient
116
+ if pattern[-1] != '*' # the pattern has no metachars and is not equal
117
+ # thus, no match
118
+ #Puppet.info "%s is not equal with no * in %s" % [value, pattern]
119
+ return false
120
+ else
121
+ # we know the last field of the pattern is '*'
122
+ # if everything up to that doesn't match, we're definitely false
123
+ if pattern[0..-2] != value[0..pattern.length-2]
124
+ #Puppet.notice "subpatterns didn't match; %s vs %s" %
125
+ # [pattern[0..-2], value[0..pattern.length-2]]
126
+ return false
127
+ end
128
+
129
+ case value.length <=> pattern.length
130
+ when -1: # value is shorter than pattern
131
+ if pattern.length - value.length == 1
132
+ # only ever allowed when the value is the domain of a
133
+ # splatted pattern
134
+ #Puppet.info "allowing splatted domain %s" % [value]
135
+ return true
136
+ else
137
+ return false
138
+ end
139
+ when 0: # value is the same length as pattern
140
+ if pattern[-1] == "*"
141
+ #Puppet.notice "same length with *"
142
+ return true
143
+ else
144
+ return false
145
+ end
146
+ when 1: # value is longer than pattern
147
+ # at this point we've already verified that everything up to
148
+ # the '*' in the pattern matches, so we are true
149
+ return true
150
+ end
151
+ end
152
+ end
153
+
154
+ def store(pattern, hash)
155
+ type, value = type(pattern)
156
+
157
+ if type and value
158
+ # this won't work once we get beyond simple stuff...
159
+ hash[type] << value
160
+ else
161
+ raise AuthStoreError, "Invalid pattern %s" % pattern
162
+ end
163
+ end
164
+
165
+ def type(pattern)
166
+ type = value = nil
167
+ case pattern
168
+ when /^(\d+\.){3}\d+$/:
169
+ type = :ip
170
+ begin
171
+ value = IPAddr.new(pattern)
172
+ rescue ArgumentError => detail
173
+ raise AuthStoreError, "Invalid IP address pattern %s" % pattern
174
+ end
175
+ when /^(\d+\.){3}\d+\/(\d+)$/:
176
+ mask = Integer($2)
177
+ if mask < 1 or mask > 32
178
+ raise AuthStoreError, "Invalid IP mask %s" % mask
179
+ end
180
+ type = :ip
181
+ begin
182
+ value = IPAddr.new(pattern)
183
+ rescue ArgumentError => detail
184
+ raise AuthStoreError, "Invalid IP address pattern %s" % pattern
185
+ end
186
+ when /^(\d+\.){1,3}\*$/: # an ip address with a '*' at the end
187
+ type = :ip
188
+ match = $1
189
+ match.sub!(".", '')
190
+ ary = pattern.split(".")
191
+
192
+ mask = case ary.index(match)
193
+ when 0: 8
194
+ when 1: 16
195
+ when 2: 24
196
+ else
197
+ raise AuthStoreError, "Invalid IP pattern %s" % pattern
198
+ end
199
+
200
+ ary.pop
201
+ while ary.length < 4
202
+ ary.push("0")
203
+ end
204
+
205
+ begin
206
+ value = IPAddr.new(ary.join(".") + "/" + mask.to_s)
207
+ rescue ArgumentError => detail
208
+ raise AuthStoreError, "Invalid IP address pattern %s" % pattern
209
+ end
210
+ when /^[\d.]+$/: # necessary so incomplete IP addresses can't look
211
+ # like hostnames
212
+ raise AuthStoreError, "Invalid IP address pattern %s" % pattern
213
+ when /^([a-zA-Z][-\w]*\.)+[-\w]+$/: # a full hostname
214
+ type = :hostname
215
+ value = pattern.split(".").reverse
216
+ when /^\*\.([a-zA-Z][-\w]*\.)+[-\w]+$/: # this doesn't match TLDs
217
+ type = :domain
218
+ value = pattern.split(".").reverse
219
+ else
220
+ raise AuthStoreError, "Invalid pattern %s" % pattern
221
+ end
222
+
223
+ return [type, value]
224
+ end
225
+ end
226
+ end
227
+ end
@@ -0,0 +1,140 @@
1
+ require 'openssl'
2
+ require 'puppet'
3
+ require 'puppet/sslcertificates'
4
+ require 'xmlrpc/server'
5
+
6
+ # Much of this was taken from QuickCert:
7
+ # http://segment7.net/projects/ruby/QuickCert/
8
+
9
+ module Puppet
10
+ class Server
11
+ class CAError < Puppet::Error; end
12
+ class CA < Handler
13
+ attr_reader :ca
14
+
15
+ @interface = XMLRPC::Service::Interface.new("puppetca") { |iface|
16
+ iface.add_method("array getcert(csr)")
17
+ }
18
+
19
+ # FIXME autosign? should probably accept both hostnames and IP addresses
20
+ def autosign?(hostname)
21
+ # simple values are easy
22
+ if @autosign == true or @autosign == false
23
+ return @autosign
24
+ end
25
+
26
+ # we only otherwise know how to handle files
27
+ unless @autosign =~ /^\//
28
+ raise Puppet::Error, "Invalid autosign value %s" %
29
+ @autosign
30
+ end
31
+
32
+ unless FileTest.exists?(@autosign)
33
+ Puppet.info "Autosign is enabled but %s is missing" % @autosign
34
+ return false
35
+ end
36
+ auth = Puppet::Server::AuthStore.new
37
+ File.open(@autosign) { |f|
38
+ f.each { |line|
39
+ auth.allow(line.chomp)
40
+ }
41
+ }
42
+
43
+ # for now, just cheat and pass a fake IP address to allowed?
44
+ return auth.allowed?(hostname, "127.1.1.1")
45
+ end
46
+
47
+ def initialize(hash = {})
48
+ @autosign = hash[:autosign] || Puppet[:autosign]
49
+ @ca = Puppet::SSLCertificates::CA.new()
50
+ end
51
+
52
+ # our client sends us a csr, and we either store it for later signing,
53
+ # or we sign it right away
54
+ def getcert(csrtext, client = nil, clientip = nil)
55
+ csr = OpenSSL::X509::Request.new(csrtext)
56
+
57
+ # Use the hostname from the CSR, not from the network.
58
+ subject = csr.subject
59
+
60
+ nameary = subject.to_a.find { |ary|
61
+ ary[0] == "CN"
62
+ }
63
+
64
+ if nameary.nil?
65
+ Puppet.err(
66
+ "Invalid certificate request: could not retrieve server name"
67
+ )
68
+ return "invalid"
69
+ end
70
+
71
+ hostname = nameary[1]
72
+
73
+ unless @ca
74
+ Puppet.notice "Host %s asked for signing from non-CA master" % hostname
75
+ return ""
76
+ end
77
+
78
+ # okay, we're now going to store the public key if we don't already
79
+ # have it
80
+ public_key = csr.public_key
81
+ unless FileTest.directory?(Puppet[:publickeydir])
82
+ Puppet.recmkdir(Puppet[:publickeydir])
83
+ end
84
+ pkeyfile = File.join(Puppet[:publickeydir], [hostname, "pem"].join('.'))
85
+
86
+ if FileTest.exists?(pkeyfile)
87
+ currentkey = File.open(pkeyfile) { |k| k.read }
88
+ unless currentkey == public_key.to_s
89
+ raise Puppet::Error, "public keys for %s differ" % hostname
90
+ end
91
+ else
92
+ File.open(pkeyfile, "w", 0644) { |f|
93
+ f.print public_key.to_s
94
+ }
95
+ end
96
+ unless FileTest.directory?(Puppet[:certdir])
97
+ Puppet.recmkdir(Puppet[:certdir], 0770)
98
+ end
99
+ certfile = File.join(Puppet[:certdir], [hostname, "pem"].join("."))
100
+
101
+ #puts hostname
102
+ #puts certfile
103
+
104
+ unless FileTest.directory?(Puppet[:csrdir])
105
+ Puppet.recmkdir(Puppet[:csrdir], 0770)
106
+ end
107
+ # first check to see if we already have a signed cert for the host
108
+ cert, cacert = ca.getclientcert(hostname)
109
+ if cert and cacert
110
+ Puppet.info "Retrieving existing certificate for %s" % hostname
111
+ #Puppet.info "Cert: %s; Cacert: %s" % [cert.class, cacert.class]
112
+ return [cert.to_pem, cacert.to_pem]
113
+ elsif @ca
114
+ if self.autosign?(hostname) or client.nil?
115
+ if client.nil?
116
+ Puppet.info "Signing certificate for CA server"
117
+ end
118
+ # okay, we don't have a signed cert
119
+ # if we're a CA and autosign is turned on, then go ahead and sign
120
+ # the csr and return the results
121
+ Puppet.info "Signing certificate for %s" % hostname
122
+ cert, cacert = @ca.sign(csr)
123
+ Puppet.info "Cert: %s; Cacert: %s" % [cert.class, cacert.class]
124
+ return [cert.to_pem, cacert.to_pem]
125
+ else # just write out the csr for later signing
126
+ if @ca.getclientcsr(hostname)
127
+ Puppet.info "Not replacing existing request from %s" % hostname
128
+ else
129
+ Puppet.info "Storing certificate request for %s" % hostname
130
+ @ca.storeclientcsr(csr)
131
+ end
132
+ return ["", ""]
133
+ end
134
+ else
135
+ raise "huh?"
136
+ end
137
+ end
138
+ end
139
+ end
140
+ end