puppetserver-ca 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/lib/puppetserver/ca/action/clean.rb +102 -0
  3. data/lib/puppetserver/ca/action/create.rb +161 -0
  4. data/lib/puppetserver/ca/action/generate.rb +313 -0
  5. data/lib/puppetserver/ca/action/import.rb +132 -0
  6. data/lib/puppetserver/ca/action/list.rb +132 -0
  7. data/lib/puppetserver/ca/action/revoke.rb +101 -0
  8. data/lib/puppetserver/ca/action/sign.rb +126 -0
  9. data/lib/puppetserver/ca/certificate_authority.rb +224 -0
  10. data/lib/puppetserver/ca/cli.rb +17 -16
  11. data/lib/puppetserver/ca/config/puppet.rb +242 -0
  12. data/lib/puppetserver/ca/config/puppetserver.rb +85 -0
  13. data/lib/puppetserver/ca/utils/cli_parsing.rb +82 -0
  14. data/lib/puppetserver/ca/utils/config.rb +13 -0
  15. data/lib/puppetserver/ca/utils/file_system.rb +90 -0
  16. data/lib/puppetserver/ca/utils/http_client.rb +129 -0
  17. data/lib/puppetserver/ca/utils/signing_digest.rb +27 -0
  18. data/lib/puppetserver/ca/version.rb +1 -1
  19. metadata +17 -17
  20. data/lib/puppetserver/ca/clean_action.rb +0 -157
  21. data/lib/puppetserver/ca/config_utils.rb +0 -11
  22. data/lib/puppetserver/ca/create_action.rb +0 -265
  23. data/lib/puppetserver/ca/generate_action.rb +0 -227
  24. data/lib/puppetserver/ca/import_action.rb +0 -153
  25. data/lib/puppetserver/ca/list_action.rb +0 -153
  26. data/lib/puppetserver/ca/puppet_config.rb +0 -197
  27. data/lib/puppetserver/ca/puppetserver_config.rb +0 -83
  28. data/lib/puppetserver/ca/revoke_action.rb +0 -136
  29. data/lib/puppetserver/ca/sign_action.rb +0 -190
  30. data/lib/puppetserver/ca/utils.rb +0 -80
  31. data/lib/puppetserver/settings/ttl_setting.rb +0 -48
  32. data/lib/puppetserver/utils/file_utilities.rb +0 -78
  33. data/lib/puppetserver/utils/http_client.rb +0 -129
  34. data/lib/puppetserver/utils/signing_digest.rb +0 -25
@@ -1,48 +0,0 @@
1
- # A setting that represents a span of time to live, and evaluates to Numeric
2
- # seconds to live where 0 means shortest possible time to live, a positive numeric value means time
3
- # to live in seconds, and the symbolic entry 'unlimited' is an infinite amount of time.
4
- #
5
- module Puppetserver
6
- module Settings
7
- class TTLSetting
8
- # How we convert from various units to seconds.
9
- UNITMAP = {
10
- # 365 days isn't technically a year, but is sufficient for most purposes
11
- "y" => 365 * 24 * 60 * 60,
12
- "d" => 24 * 60 * 60,
13
- "h" => 60 * 60,
14
- "m" => 60,
15
- "s" => 1
16
- }
17
-
18
- # A regex describing valid formats with groups for capturing the value and units
19
- FORMAT = /^(\d+)(y|d|h|m|s)?$/
20
-
21
- attr_reader :errors, :munged_value
22
-
23
- def initialize(name, setting_value)
24
- @errors = []
25
- @munged_value = munge(setting_value, name)
26
- end
27
-
28
- # Convert the value to Numeric, parsing numeric string with units if necessary.
29
- def munge(value, name)
30
- case
31
- when value.is_a?(Numeric)
32
- if value < 0
33
- @errors << "Invalid negative 'time to live' #{value.inspect} - did you mean 'unlimited'?"
34
- end
35
- value
36
-
37
- when value == 'unlimited'
38
- Float::INFINITY
39
-
40
- when (value.is_a?(String) and value =~ FORMAT)
41
- $1.to_i * UNITMAP[$2 || 's']
42
- else
43
- @errors << "Invalid 'time to live' format '#{value.inspect}' for parameter: #{name}"
44
- end
45
- end
46
- end
47
- end
48
- end
@@ -1,78 +0,0 @@
1
- require 'fileutils'
2
- require 'etc'
3
-
4
- module Puppetserver
5
- module Utils
6
- class FileUtilities
7
-
8
- def self.instance
9
- @instance ||= new
10
- end
11
-
12
- def self.write_file(*args)
13
- instance.write_file(*args)
14
- end
15
-
16
- def self.ensure_dir(setting)
17
- instance.ensure_dir(setting)
18
- end
19
-
20
- def self.ensure_file(location, content, mode)
21
- if !File.exist?(location)
22
- instance.write_file(location, content, mode)
23
- end
24
- end
25
-
26
- def self.validate_file_paths(one_or_more_paths)
27
- errors = []
28
- Array(one_or_more_paths).each do |path|
29
- if !File.exist?(path) || !File.readable?(path)
30
- errors << "Could not read file '#{path}'"
31
- end
32
- end
33
-
34
- errors
35
- end
36
-
37
- def initialize
38
- @user, @group = find_user_and_group
39
- end
40
-
41
- def find_user_and_group
42
- if !running_as_root?
43
- return Process.euid, Process.egid
44
- else
45
- if pe_puppet_exists?
46
- return 'pe-puppet', 'pe-puppet'
47
- else
48
- return 'puppet', 'puppet'
49
- end
50
- end
51
- end
52
-
53
- def running_as_root?
54
- !Gem.win_platform? && Process.euid == 0
55
- end
56
-
57
- def pe_puppet_exists?
58
- !!(Etc.getpwnam('pe-puppet') rescue nil)
59
- end
60
-
61
- def write_file(path, one_or_more_objects, mode)
62
- File.open(path, 'w', mode) do |f|
63
- Array(one_or_more_objects).each do |object|
64
- f.puts object.to_s
65
- end
66
- end
67
- FileUtils.chown(@user, @group, path)
68
- end
69
-
70
- def ensure_dir(setting)
71
- if !File.exist?(setting)
72
- FileUtils.mkdir_p(setting, mode: 0750)
73
- FileUtils.chown(@user, @group, setting)
74
- end
75
- end
76
- end
77
- end
78
- end
@@ -1,129 +0,0 @@
1
- require 'openssl'
2
- require 'net/https'
3
-
4
- module Puppetserver
5
- module Utils
6
- # Utilities for doing HTTPS against the CA that wraps Net::HTTP constructs
7
- class HttpClient
8
-
9
- HEADERS = {
10
- 'User-Agent' => 'PuppetserverCaCli',
11
- 'Content-Type' => 'application/json',
12
- 'Accept' => 'application/json'
13
- }
14
-
15
- attr_reader :store
16
-
17
- def initialize(settings)
18
- @store = make_store(settings[:localcacert],
19
- settings[:certificate_revocation],
20
- settings[:hostcrl])
21
- @cert = load_cert(settings[:hostcert])
22
- @key = load_key(settings[:hostprivkey])
23
- end
24
-
25
- def load_cert(cert_path)
26
- OpenSSL::X509::Certificate.new(File.read(cert_path))
27
- end
28
-
29
- def load_key(key_path)
30
- OpenSSL::PKey.read(File.read(key_path))
31
- end
32
-
33
- # Returns a URI-like wrapper around CA specific urls
34
- def make_ca_url(host, port, resource_type = nil, certname = nil)
35
- URL.new('https', host, port, 'puppet-ca', 'v1', resource_type, certname)
36
- end
37
-
38
- # Takes an instance URL (defined lower in the file), and creates a
39
- # connection. The given block is passed our own Connection object.
40
- # The Connection object should have HTTP verbs defined on it that take
41
- # a body (and optional overrides). Returns whatever the block given returned.
42
- def with_connection(url, &block)
43
- request = ->(conn) { block.call(Connection.new(conn, url)) }
44
-
45
- Net::HTTP.start(url.host, url.port,
46
- use_ssl: true, cert_store: @store,
47
- cert: @cert, key: @key,
48
- &request)
49
- end
50
-
51
- private
52
- # Helper class that wraps a Net::HTTP connection, a HttpClient::URL
53
- # and defines methods named after HTTP verbs that are called on the
54
- # saved connection, returning a Result.
55
- class Connection
56
- def initialize(net_http_connection, url_struct)
57
- @conn = net_http_connection
58
- @url = url_struct
59
- end
60
-
61
- def get(url_overide = nil)
62
- url = url_overide || @url
63
-
64
- request = Net::HTTP::Get.new(url.to_uri, HEADERS)
65
- result = @conn.request(request)
66
-
67
- Result.new(result.code, result.body)
68
- end
69
-
70
- def put(body, url_override = nil)
71
- url = url_override || @url
72
-
73
- request = Net::HTTP::Put.new(url.to_uri, HEADERS)
74
- request.body = body
75
- result = @conn.request(request)
76
-
77
- Result.new(result.code, result.body)
78
- end
79
-
80
- def delete(url_override = nil)
81
- url = url_override || @url
82
-
83
- result = @conn.request(Net::HTTP::Delete.new(url.to_uri, HEADERS))
84
-
85
- Result.new(result.code, result.body)
86
- end
87
- end
88
-
89
- # Just provide the bits of Net::HTTPResponse we care about
90
- Result = Struct.new(:code, :body)
91
-
92
- # Like URI, but not... maybe of suspicious value
93
- URL = Struct.new(:protocol, :host, :port,
94
- :endpoint, :version,
95
- :resource_type, :resource_name) do
96
- def full_url
97
- protocol + '://' + host + ':' + port + '/' +
98
- [endpoint, version, resource_type, resource_name].join('/')
99
- end
100
-
101
- def to_uri
102
- URI(full_url)
103
- end
104
- end
105
-
106
- def make_store(bundle, crl_usage, crls = nil)
107
- store = OpenSSL::X509::Store.new
108
- store.purpose = OpenSSL::X509::PURPOSE_ANY
109
- store.add_file(bundle)
110
-
111
- if crl_usage != :ignore
112
-
113
- flags = OpenSSL::X509::V_FLAG_CRL_CHECK
114
- if crl_usage == :chain
115
- flags |= OpenSSL::X509::V_FLAG_CRL_CHECK_ALL
116
- end
117
-
118
- store.flags = flags
119
- delimiter = /-----BEGIN X509 CRL-----.*?-----END X509 CRL-----/m
120
- File.read(crls).scan(delimiter).each do |crl|
121
- store.add_crl(OpenSSL::X509::CRL.new(crl))
122
- end
123
- end
124
-
125
- store
126
- end
127
- end
128
- end
129
- end
@@ -1,25 +0,0 @@
1
- module Puppetserver
2
- module Utils
3
- class SigningDigest
4
-
5
- attr_reader :errors, :digest
6
-
7
- def initialize
8
- @errors = []
9
- if OpenSSL::Digest.const_defined?('SHA256')
10
- @digest = OpenSSL::Digest::SHA256.new
11
- elsif OpenSSL::Digest.const_defined?('SHA1')
12
- @digest = OpenSSL::Digest::SHA1.new
13
- elsif OpenSSL::Digest.const_defined?('SHA512')
14
- @digest = OpenSSL::Digest::SHA512.new
15
- elsif OpenSSL::Digest.const_defined?('SHA384')
16
- @digest = OpenSSL::Digest::SHA384.new
17
- elsif OpenSSL::Digest.const_defined?('SHA224')
18
- @digest = OpenSSL::Digest::SHA224.new
19
- else
20
- @errors << "Error: No FIPS 140-2 compliant digest algorithm in OpenSSL::Digest"
21
- end
22
- end
23
- end
24
- end
25
- end