autosign 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +73 -0
- data/README.rdoc +6 -0
- data/Rakefile +44 -0
- data/autosign.gemspec +29 -0
- data/autosign.rdoc +5 -0
- data/bin/autosign +169 -0
- data/bin/autosign-validator +41 -0
- data/features/autosign.feature +78 -0
- data/features/step_definitions/autosign_steps.rb +44 -0
- data/features/support/env.rb +17 -0
- data/features/validate.feature +20 -0
- data/fixtures/i-7672fe81.pem +34 -0
- data/lib/autosign.rb +9 -0
- data/lib/autosign/config.rb +131 -0
- data/lib/autosign/decoder.rb +32 -0
- data/lib/autosign/journal.rb +123 -0
- data/lib/autosign/logger.rb +7 -0
- data/lib/autosign/token.rb +143 -0
- data/lib/autosign/validator.rb +133 -0
- data/lib/autosign/validators/jwt.rb +63 -0
- data/lib/autosign/version.rb +3 -0
- metadata +213 -0
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'logging'
|
2
|
+
require 'require_all'
|
3
|
+
|
4
|
+
module Autosign
|
5
|
+
class Validator
|
6
|
+
def initialize()
|
7
|
+
@log = Logging.logger[self.name]
|
8
|
+
settings() # just run to validate settings
|
9
|
+
setup()
|
10
|
+
end
|
11
|
+
|
12
|
+
def name
|
13
|
+
# override this after inheriting
|
14
|
+
# should return a string with no spaces
|
15
|
+
# this is the name used to reference the validator in config files
|
16
|
+
raise NotImplementedError
|
17
|
+
end
|
18
|
+
|
19
|
+
def validate(challenge_password, certname)
|
20
|
+
@log.debug "running validate"
|
21
|
+
fail unless challenge_password.is_a?(String)
|
22
|
+
fail unless certname.is_a?(String)
|
23
|
+
|
24
|
+
case perform_validation(challenge_password, certname)
|
25
|
+
when true
|
26
|
+
@log.debug "validated successfully"
|
27
|
+
@log.info "Validated '#{certname}' using '#{name}' validator"
|
28
|
+
return true
|
29
|
+
when false
|
30
|
+
@log.debug "validation failed"
|
31
|
+
@log.debug "Unable to validate '#{certname}' using '#{name}' validator"
|
32
|
+
return false
|
33
|
+
else
|
34
|
+
@log.error "perform_validation returned a non-boolean result"
|
35
|
+
raise "perform_validation returned a non-boolean result"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.any_validator(challenge_password, certname)
|
40
|
+
@log = Logging.logger[self.name]
|
41
|
+
# iterate over all known validators and attempt to validate using them
|
42
|
+
results = self.descendants.map {|c|
|
43
|
+
validator = c.new()
|
44
|
+
@log.debug "attempting to validate using #{validator.name}"
|
45
|
+
result = validator.validate(challenge_password, certname)
|
46
|
+
@log.debug "result: #{result.to_s}"
|
47
|
+
result
|
48
|
+
}
|
49
|
+
@log.debug "validator results: " + results.to_s
|
50
|
+
success = results.inject(true) { |sum, n| n and sum }
|
51
|
+
if success
|
52
|
+
@log.info "successfully validated using one or more validators"
|
53
|
+
return true
|
54
|
+
else
|
55
|
+
@log.info "unable to validate using any validator"
|
56
|
+
return false
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
def perform_validation(challenge_password, certname)
|
62
|
+
# override this after inheriting
|
63
|
+
# should return true to indicate success validating
|
64
|
+
# or false to indicate that the validator was unable to validate
|
65
|
+
raise NotImplementedError
|
66
|
+
end
|
67
|
+
|
68
|
+
# perform any steps you want to take during initialization
|
69
|
+
def setup
|
70
|
+
true
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.descendants
|
74
|
+
ObjectSpace.each_object(Class).select { |klass| klass < self }
|
75
|
+
end
|
76
|
+
|
77
|
+
def settings
|
78
|
+
@log.debug "merging settings"
|
79
|
+
setting_sources = [default_settings, load_config, get_override_settings]
|
80
|
+
merged_settings = setting_sources.inject({}) { |merged, hash| merged.deep_merge(hash) }
|
81
|
+
@log.debug "using merged settings: " + merged_settings.to_s
|
82
|
+
@log.debug "validating merged settings"
|
83
|
+
if validate_settings(merged_settings)
|
84
|
+
@log.debug "successfully validated merged settings"
|
85
|
+
return merged_settings
|
86
|
+
else
|
87
|
+
@log.warn "validation of merged settings failed"
|
88
|
+
@log.warn "unable to validate settings in #{self.name} validator"
|
89
|
+
raise "settings validation error"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# this hash will be merged with the configuration section's hash
|
94
|
+
# override this when inheriting if you need to set config defaults
|
95
|
+
def default_settings
|
96
|
+
{}
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
# override this to perform validation checks on the merged config hash
|
101
|
+
# of default settings, config file settings, and override settings.
|
102
|
+
# return either true or false
|
103
|
+
def validate_settings(settings)
|
104
|
+
settings.is_a?(Hash)
|
105
|
+
end
|
106
|
+
|
107
|
+
# load any required configuration
|
108
|
+
def load_config
|
109
|
+
@log.debug "loading validator-specific configuration"
|
110
|
+
config = Autosign::Config.new
|
111
|
+
|
112
|
+
if config.settings.to_hash[self.name].nil?
|
113
|
+
@log.warning "Unable to load validator-specific configuration"
|
114
|
+
@log.warning "Cannot load configuration section named '#{self.name}'"
|
115
|
+
return {}
|
116
|
+
else
|
117
|
+
@log.debug "Set validator-specific settings from config file: " + config.settings.to_hash[self.name].to_s
|
118
|
+
return config.settings.to_hash[self.name]
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
# this hook gets run to get settings from the CLI etc
|
123
|
+
# this is how you override defaults and config file settings
|
124
|
+
def get_override_settings
|
125
|
+
{}
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# must run at the end because the validators inherit this class
|
132
|
+
# this loads all validators
|
133
|
+
require_rel 'validators'
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Autosign
|
2
|
+
module Validators
|
3
|
+
class JWT < Autosign::Validator
|
4
|
+
def name
|
5
|
+
"jwt_token"
|
6
|
+
end
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def perform_validation(token, certname)
|
11
|
+
puts "attempting to validate JWT token"
|
12
|
+
return false unless Autosign::Token.validate(certname, token, settings['secret'])
|
13
|
+
puts "validated JWT token"
|
14
|
+
@log.debug "validated JWT token, checking reusability"
|
15
|
+
|
16
|
+
return true if is_reusable?(token)
|
17
|
+
return true if add_to_journal(token)
|
18
|
+
return false
|
19
|
+
end
|
20
|
+
|
21
|
+
def is_reusable?(token)
|
22
|
+
Autosign::Token.from_token(token, settings['secret']).reusable
|
23
|
+
end
|
24
|
+
|
25
|
+
def add_to_journal(token)
|
26
|
+
validated_token = Autosign::Token.from_token(token, settings['secret'])
|
27
|
+
journal = Autosign::Journal.new({'journalfile' => settings['journalfile']})
|
28
|
+
token_expiration = Autosign::Token.token_validto(token, settings['secret'])
|
29
|
+
|
30
|
+
# adding will return false if the token is already in the journal
|
31
|
+
if journal.add(validated_token.uuid, token_expiration, validated_token.to_hash)
|
32
|
+
@log.info "added token with UUID '#{validated_token.uuid}' to journal"
|
33
|
+
return true
|
34
|
+
else
|
35
|
+
@log.warn "journal cannot validate one-time token; may already have been used"
|
36
|
+
return false
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def default_settings
|
41
|
+
{
|
42
|
+
'journalfile' => '/var/autosign/autosign.journal'
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
def get_override_settings
|
47
|
+
{}
|
48
|
+
end
|
49
|
+
|
50
|
+
def validate_settings(settings)
|
51
|
+
@log.debug "validating settings: " + settings.to_s
|
52
|
+
if settings['secret'].is_a?(String)
|
53
|
+
@log.info "validated settings successfully"
|
54
|
+
return true
|
55
|
+
else
|
56
|
+
@log.error "no secret setting found"
|
57
|
+
return false
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
metadata
ADDED
@@ -0,0 +1,213 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: autosign
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Your Name Here
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-07-13 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rdoc
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: aruba
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: puppet
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: gli
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '2'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '2'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: jwt
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '1'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '1'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: iniparse
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '1'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '1'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: logging
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: deep_merge
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: require_all
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :runtime
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
description:
|
154
|
+
email: your@email.address.com
|
155
|
+
executables:
|
156
|
+
- autosign
|
157
|
+
extensions: []
|
158
|
+
extra_rdoc_files:
|
159
|
+
- README.rdoc
|
160
|
+
- autosign.rdoc
|
161
|
+
files:
|
162
|
+
- Gemfile
|
163
|
+
- Gemfile.lock
|
164
|
+
- README.rdoc
|
165
|
+
- Rakefile
|
166
|
+
- autosign.gemspec
|
167
|
+
- autosign.rdoc
|
168
|
+
- bin/autosign
|
169
|
+
- bin/autosign-validator
|
170
|
+
- features/autosign.feature
|
171
|
+
- features/step_definitions/autosign_steps.rb
|
172
|
+
- features/support/env.rb
|
173
|
+
- features/validate.feature
|
174
|
+
- fixtures/i-7672fe81.pem
|
175
|
+
- lib/autosign.rb
|
176
|
+
- lib/autosign/config.rb
|
177
|
+
- lib/autosign/decoder.rb
|
178
|
+
- lib/autosign/journal.rb
|
179
|
+
- lib/autosign/logger.rb
|
180
|
+
- lib/autosign/token.rb
|
181
|
+
- lib/autosign/validator.rb
|
182
|
+
- lib/autosign/validators/jwt.rb
|
183
|
+
- lib/autosign/version.rb
|
184
|
+
homepage: http://your.website.com
|
185
|
+
licenses: []
|
186
|
+
metadata: {}
|
187
|
+
post_install_message:
|
188
|
+
rdoc_options:
|
189
|
+
- "--title"
|
190
|
+
- autosign
|
191
|
+
- "--main"
|
192
|
+
- README.rdoc
|
193
|
+
- "-ri"
|
194
|
+
require_paths:
|
195
|
+
- lib
|
196
|
+
- lib
|
197
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
198
|
+
requirements:
|
199
|
+
- - ">="
|
200
|
+
- !ruby/object:Gem::Version
|
201
|
+
version: '0'
|
202
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
203
|
+
requirements:
|
204
|
+
- - ">="
|
205
|
+
- !ruby/object:Gem::Version
|
206
|
+
version: '0'
|
207
|
+
requirements: []
|
208
|
+
rubyforge_project:
|
209
|
+
rubygems_version: 2.2.2
|
210
|
+
signing_key:
|
211
|
+
specification_version: 4
|
212
|
+
summary: A description of your project
|
213
|
+
test_files: []
|