Class: Puppet::Network::HTTPServer::WEBrick

Inherits:
WEBrick::HTTPServer
  • Object
show all
Includes:
SSLCertificates::Support
Defined in:
lib/puppet/network/http_server/webrick.rb

Overview

The old-school, pure ruby webrick server, which is the default serving mechanism.

Instance Attribute Summary

Attributes included from SSLCertificates::Support

#cacert

Instance Method Summary collapse

Methods included from SSLCertificates::Support

keytype, #rename_files_with_uppercase, #requestcert

Constructor Details

#initialize(hash = {}) ⇒ WEBrick

Create our server, yo.



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/puppet/network/http_server/webrick.rb', line 67

def initialize(hash = {})
  Puppet.info "Starting server for Puppet version #{Puppet.version}"

  if handlers = hash[:Handlers]
    handler_instances = setup_handlers(handlers)
  else
    raise ServerError, "A server must have handlers"
  end

  unless self.read_cert
    if ca = handler_instances.find { |handler| handler.is_a?(Puppet::Network::Handler.ca) }
      request_cert(ca)
    else
      raise Puppet::Error, "No certificate and no CA; cannot get cert"
    end
  end

  setup_webrick(hash)

  begin
    super(hash)
  rescue => detail
    puts detail.backtrace if Puppet[:trace]
    raise Puppet::Error, "Could not start WEBrick: #{detail}"
  end

  # make sure children don't inherit the sockets
  listeners.each { |sock|
    sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
  }

  Puppet.info "Listening on port #{hash[:Port]}"

  # this creates a new servlet for every connection,
  # but all servlets have the same list of handlers
  # thus, the servlets can have their own state -- passing
  # around the requests and such -- but the handlers
  # have a global state

  # mount has to be called after the server is initialized
  servlet = Puppet::Network::XMLRPC::WEBrickServlet.new( handler_instances)
  self.mount("/RPC2", servlet)
end

Instance Method Details

#httplogObject

Set up the http log.



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/puppet/network/http_server/webrick.rb', line 40

def httplog
  args = []

  # yuck; separate http logs
  file = nil
  Puppet.settings.use(:main, :ssl, Puppet[:name])
  if Puppet.run_mode.master?
    file = Puppet[:masterhttplog]
  else
    file = Puppet[:httplog]
  end

  # open the log manually to prevent file descriptor leak
  file_io = open(file, "a+")
  file_io.sync
  file_io.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)

  args << file_io
  args << WEBrick::Log::DEBUG if Puppet[:debug]

  log = WEBrick::Log.new(*args)


  log
end

#request_cert(ca) ⇒ Object

Create a ca client to set up our cert for us.

Raises:



112
113
114
115
# File 'lib/puppet/network/http_server/webrick.rb', line 112

def request_cert(ca)
  client = Puppet::Network::Client.ca.new(:CA => ca)
  raise Puppet::Error, "Could get certificate" unless client.request_cert
end

#setup_handlers(handlers) ⇒ Object

Create all of our handler instances.

Raises:



118
119
120
121
122
123
124
125
126
127
128
# File 'lib/puppet/network/http_server/webrick.rb', line 118

def setup_handlers(handlers)
  raise ServerError, "Handlers must have arguments" unless handlers.is_a?(Hash)

  handlers.collect { |handler, args|
    hclass = nil
    unless hclass = Puppet::Network::Handler.handler(handler)
      raise ServerError, "Invalid handler #{handler}"
    end
    hclass.new(args)
  }
end

#setup_webrick(hash) ⇒ Object

Handle all of the many webrick arguments.



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/puppet/network/http_server/webrick.rb', line 131

def setup_webrick(hash)
  hash[:Port] ||= Puppet[:masterport]
  hash[:Logger] ||= self.httplog
  hash[:AccessLog] ||= [
    [ self.httplog, WEBrick::AccessLog::COMMON_LOG_FORMAT ],
    [ self.httplog, WEBrick::AccessLog::REFERER_LOG_FORMAT ]
  ]

  hash[:SSLCertificateStore] = x509store
  hash[:SSLCertificate] = self.cert
  hash[:SSLPrivateKey] = self.key
  hash[:SSLStartImmediately] = true
  hash[:SSLEnable] = true
  hash[:SSLCACertificateFile] = Puppet[:localcacert]
  hash[:SSLVerifyClient] = OpenSSL::SSL::VERIFY_PEER
  hash[:SSLCertName] = nil

  if addr = Puppet[:bindaddress] and addr != ""
    hash[:BindAddress] = addr
  end
end

#x509storeObject

Read the CA cert and CRL and populate an OpenSSL::X509::Store with them, with flags appropriate for checking client certificates for revocation

Raises:



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/puppet/network/http_server/webrick.rb', line 23

def x509store
  unless File.exist?(Puppet[:cacrl])
    # No CRL, no store needed
    return nil
  end
  crl = OpenSSL::X509::CRL.new(File.read(Puppet[:cacrl]))
  store = OpenSSL::X509::Store.new
  store.purpose = OpenSSL::X509::PURPOSE_ANY
  store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL|OpenSSL::X509::V_FLAG_CRL_CHECK if Puppet.settings[:certificate_revocation]
  raise Puppet::Error, "Could not find CA certificate" unless self.ca_cert

  store.add_file(Puppet[:localcacert])
  store.add_crl(crl)
  store
end