lex-kerberos 0.1.7 → 0.1.8
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 +4 -4
- data/.github/workflows/ci.yml +3 -3
- data/.rubocop.yml +2 -15
- data/CHANGELOG.md +5 -0
- data/Gemfile +1 -0
- data/lib/legion/extensions/kerberos/actors/keytab_refresh.rb +8 -10
- data/lib/legion/extensions/kerberos/client.rb +2 -2
- data/lib/legion/extensions/kerberos/helpers/client.rb +8 -8
- data/lib/legion/extensions/kerberos/helpers/ldap.rb +1 -1
- data/lib/legion/extensions/kerberos/helpers/spnego.rb +6 -8
- data/lib/legion/extensions/kerberos/runners/authenticate.rb +12 -16
- data/lib/legion/extensions/kerberos/version.rb +1 -1
- data/lib/legion/extensions/kerberos.rb +2 -2
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: '08560b2f835b1f611a3572b11e1dd4d036a9abd9569c95b80baab7f4b995dc1c'
|
|
4
|
+
data.tar.gz: 79c90f3527d01c44c6093d5023845433dfd53bc62ffd1147bdb7297d6489a077
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: '09ea67d28b7288f7af1f72706c9f1a2f04d466c5fd8e3389727bc2bf6e7386f5c793cf82a4290e7176d0048a600c4dc277dfac03fcccfbc8580cb030aa1eb49d'
|
|
7
|
+
data.tar.gz: 234403c8baa6e49ad0691e764f9c08a6627a51b1d76c73d460e87fa0cf96d4ad4acd0a1d056b812df497493064709348f89f5874eaec5df2226462a53285c224
|
data/.github/workflows/ci.yml
CHANGED
|
@@ -10,8 +10,8 @@ jobs:
|
|
|
10
10
|
ci:
|
|
11
11
|
uses: LegionIO/.github/.github/workflows/ci.yml@main
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
uses: LegionIO/.github/.github/workflows/
|
|
13
|
+
excluded-files:
|
|
14
|
+
uses: LegionIO/.github/.github/workflows/excluded-files.yml@main
|
|
15
15
|
|
|
16
16
|
security:
|
|
17
17
|
uses: LegionIO/.github/.github/workflows/security-scan.yml@main
|
|
@@ -27,7 +27,7 @@ jobs:
|
|
|
27
27
|
uses: LegionIO/.github/.github/workflows/stale.yml@main
|
|
28
28
|
|
|
29
29
|
release:
|
|
30
|
-
needs: [ci,
|
|
30
|
+
needs: [ci, excluded-files]
|
|
31
31
|
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
|
32
32
|
uses: LegionIO/.github/.github/workflows/release.yml@main
|
|
33
33
|
secrets:
|
data/.rubocop.yml
CHANGED
|
@@ -1,15 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
TargetRubyVersion: 3.4
|
|
4
|
-
SuggestExtensions: false
|
|
5
|
-
|
|
6
|
-
Metrics/BlockLength:
|
|
7
|
-
Exclude:
|
|
8
|
-
- 'spec/**/*'
|
|
9
|
-
- '*.gemspec'
|
|
10
|
-
|
|
11
|
-
Metrics/ParameterLists:
|
|
12
|
-
Max: 10
|
|
13
|
-
|
|
14
|
-
Style/Documentation:
|
|
15
|
-
Enabled: false
|
|
1
|
+
inherit_gem:
|
|
2
|
+
rubocop-legion: config/lex.yml
|
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require 'legion/extensions/actors/every'
|
|
3
|
+
require 'legion/extensions/actors/every'
|
|
4
4
|
|
|
5
5
|
module Legion
|
|
6
6
|
module Extensions
|
|
7
7
|
module Kerberos
|
|
8
8
|
module Actor
|
|
9
|
-
class KeytabRefresh < Legion::Extensions::Actors::Every
|
|
9
|
+
class KeytabRefresh < Legion::Extensions::Actors::Every # rubocop:disable Legion/Extension/SelfContainedActorRunnerClass, Legion/Extension/EveryActorRequiresTime
|
|
10
10
|
def initialize(**opts)
|
|
11
11
|
return unless enabled?
|
|
12
12
|
|
|
@@ -19,9 +19,9 @@ module Legion
|
|
|
19
19
|
def check_subtask? = false
|
|
20
20
|
def generate_task? = false
|
|
21
21
|
|
|
22
|
-
def enabled?
|
|
22
|
+
def enabled? # rubocop:disable Legion/Extension/ActorEnabledSideEffects
|
|
23
23
|
defined?(Legion::Extensions::Kerberos::Helpers::Keytab)
|
|
24
|
-
rescue StandardError
|
|
24
|
+
rescue StandardError => _e
|
|
25
25
|
false
|
|
26
26
|
end
|
|
27
27
|
|
|
@@ -29,7 +29,7 @@ module Legion
|
|
|
29
29
|
result = keytab_helper.resolve_keytab(sources: keytab_sources)
|
|
30
30
|
log_result(result)
|
|
31
31
|
rescue StandardError => e
|
|
32
|
-
|
|
32
|
+
log.error(e)
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
private
|
|
@@ -45,17 +45,15 @@ module Legion
|
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
def log_result(result)
|
|
48
|
-
return unless defined?(Legion::Logging)
|
|
49
|
-
|
|
50
48
|
if result[:success]
|
|
51
|
-
|
|
49
|
+
log.debug("KeytabRefresh: refreshed keytab from #{result[:source]}")
|
|
52
50
|
else
|
|
53
|
-
|
|
51
|
+
log.warn("KeytabRefresh: #{result[:error]}")
|
|
54
52
|
end
|
|
55
53
|
end
|
|
56
54
|
|
|
57
55
|
def log_error(err)
|
|
58
|
-
|
|
56
|
+
log.error("KeytabRefresh: #{err.message}")
|
|
59
57
|
end
|
|
60
58
|
end
|
|
61
59
|
end
|
|
@@ -7,19 +7,19 @@ module Legion
|
|
|
7
7
|
module Client
|
|
8
8
|
DEFAULTS = {
|
|
9
9
|
kerberos: {
|
|
10
|
-
enabled:
|
|
11
|
-
realm:
|
|
10
|
+
enabled: true,
|
|
11
|
+
realm: 'MS.DS.UHC.COM',
|
|
12
12
|
service_principal: 'HTTP/legion.uhg.com',
|
|
13
|
-
keytab:
|
|
14
|
-
mutual_auth:
|
|
15
|
-
ldap:
|
|
13
|
+
keytab: ['/etc/legion/krb5.keytab'],
|
|
14
|
+
mutual_auth: true,
|
|
15
|
+
ldap: {
|
|
16
16
|
port: 636, encryption: :simple_tls,
|
|
17
17
|
group_attribute: 'memberOf',
|
|
18
18
|
user_filter: '(sAMAccountName=%<username>s)'
|
|
19
19
|
},
|
|
20
|
-
role_map:
|
|
21
|
-
fallback:
|
|
22
|
-
cache_groups_ttl:
|
|
20
|
+
role_map: {},
|
|
21
|
+
fallback: :entra,
|
|
22
|
+
cache_groups_ttl: 300
|
|
23
23
|
}
|
|
24
24
|
}.freeze
|
|
25
25
|
|
|
@@ -18,7 +18,7 @@ module Legion
|
|
|
18
18
|
country: :co, country_code: :c, city: :l, state: :st, ad_created_at: :whencreated
|
|
19
19
|
}.freeze
|
|
20
20
|
|
|
21
|
-
def lookup_groups(username:, host:, base_dn:, bind_dn:, bind_password:,
|
|
21
|
+
def lookup_groups(username:, host:, base_dn:, bind_dn:, bind_password:, # rubocop:disable Metrics/ParameterLists
|
|
22
22
|
port: 636, encryption: :simple_tls,
|
|
23
23
|
user_filter: '(sAMAccountName=%<username>s)',
|
|
24
24
|
group_attribute: 'memberOf', **)
|
|
@@ -30,9 +30,7 @@ module Legion
|
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
def obtain_spnego_token(service_principal:)
|
|
33
|
-
unless service_principal.include?('/')
|
|
34
|
-
return { success: false, error: "service_principal must contain '/'" }
|
|
35
|
-
end
|
|
33
|
+
return { success: false, error: "service_principal must contain '/'" } unless service_principal.include?('/')
|
|
36
34
|
|
|
37
35
|
token_bytes = init_spnego_context(service_principal)
|
|
38
36
|
{ success: true, token: Base64.strict_encode64(token_bytes) }
|
|
@@ -61,7 +59,7 @@ module Legion
|
|
|
61
59
|
ptr = ctx.instance_variable_get(ivar)
|
|
62
60
|
ptr.autorelease = false if ptr.respond_to?(:autorelease=)
|
|
63
61
|
end
|
|
64
|
-
rescue StandardError # rubocop:disable Lint/SuppressedException
|
|
62
|
+
rescue StandardError => _e # rubocop:disable Lint/SuppressedException
|
|
65
63
|
end
|
|
66
64
|
|
|
67
65
|
def negotiate(input_bytes, service_principal)
|
|
@@ -76,11 +74,11 @@ module Legion
|
|
|
76
74
|
|
|
77
75
|
def build_token_result(principal, output_bytes)
|
|
78
76
|
{
|
|
79
|
-
success:
|
|
80
|
-
principal:
|
|
77
|
+
success: true,
|
|
78
|
+
principal: principal,
|
|
81
79
|
output_token: output_bytes ? Base64.strict_encode64(output_bytes) : nil,
|
|
82
|
-
username:
|
|
83
|
-
realm:
|
|
80
|
+
username: extract_username(principal),
|
|
81
|
+
realm: extract_realm(principal)
|
|
84
82
|
}
|
|
85
83
|
end
|
|
86
84
|
end
|
|
@@ -34,14 +34,10 @@ module Legion
|
|
|
34
34
|
|
|
35
35
|
def negotiate(headers: {}, **)
|
|
36
36
|
auth_header = headers['HTTP_AUTHORIZATION']
|
|
37
|
-
unless auth_header&.match?(/\ANegotiate\s+/i)
|
|
38
|
-
return negotiate_error('negotiate_required', 'Negotiate token required')
|
|
39
|
-
end
|
|
37
|
+
return negotiate_error('negotiate_required', 'Negotiate token required') unless auth_header&.match?(/\ANegotiate\s+/i) # rubocop:disable Legion/Extension/RunnerReturnHash
|
|
40
38
|
|
|
41
39
|
auth_result = negotiate_authenticate(auth_header.sub(/\ANegotiate\s+/i, ''))
|
|
42
|
-
unless auth_result&.dig(:success)
|
|
43
|
-
return negotiate_error('kerberos_auth_failed', 'Kerberos authentication failed')
|
|
44
|
-
end
|
|
40
|
+
return negotiate_error('kerberos_auth_failed', 'Kerberos authentication failed') unless auth_result&.dig(:success) # rubocop:disable Legion/Extension/RunnerReturnHash
|
|
45
41
|
|
|
46
42
|
negotiate_success(auth_result)
|
|
47
43
|
end
|
|
@@ -50,7 +46,7 @@ module Legion
|
|
|
50
46
|
|
|
51
47
|
def resolve_groups(ldap:, cfg:, username:)
|
|
52
48
|
ldap_opts = ldap || cfg[:ldap] || {}
|
|
53
|
-
return [[], nil, {}] unless ldap_opts[:host]
|
|
49
|
+
return [[], nil, {}] unless ldap_opts[:host] # rubocop:disable Legion/Extension/RunnerReturnHash
|
|
54
50
|
|
|
55
51
|
result = lookup_groups(username: username, **ldap_opts)
|
|
56
52
|
if result[:success]
|
|
@@ -69,15 +65,15 @@ module Legion
|
|
|
69
65
|
|
|
70
66
|
def negotiate_authenticate(token)
|
|
71
67
|
Client.new.authenticate(token: token)
|
|
72
|
-
rescue StandardError
|
|
68
|
+
rescue StandardError => _e
|
|
73
69
|
nil
|
|
74
70
|
end
|
|
75
71
|
|
|
76
72
|
def negotiate_error(code, message)
|
|
77
73
|
body = negotiate_json({ error: { code: code, message: message },
|
|
78
|
-
meta:
|
|
74
|
+
meta: { timestamp: Time.now.utc.iso8601 } })
|
|
79
75
|
{
|
|
80
|
-
result:
|
|
76
|
+
result: { error: code },
|
|
81
77
|
response: { status: 401, content_type: 'application/json',
|
|
82
78
|
headers: { 'WWW-Authenticate' => 'Negotiate' }, body: body }
|
|
83
79
|
}
|
|
@@ -94,13 +90,13 @@ module Legion
|
|
|
94
90
|
def negotiate_success_response(auth_result, data)
|
|
95
91
|
hdrs = ({ 'WWW-Authenticate' => "Negotiate #{auth_result[:output_token]}" } if auth_result[:output_token])
|
|
96
92
|
body = negotiate_json({ data: data, meta: { timestamp: Time.now.utc.iso8601 } })
|
|
97
|
-
{ result:
|
|
93
|
+
{ result: data,
|
|
98
94
|
response: { status: 200, content_type: 'application/json',
|
|
99
95
|
headers: hdrs, body: body }.compact }
|
|
100
96
|
end
|
|
101
97
|
|
|
102
98
|
def issue_negotiate_token(auth_result, profile)
|
|
103
|
-
return [nil, []] unless defined?(Legion::Rbac::KerberosClaimsMapper) && defined?(Legion::API::Token)
|
|
99
|
+
return [nil, []] unless defined?(Legion::Rbac::KerberosClaimsMapper) && defined?(Legion::API::Token) # rubocop:disable Legion/Extension/RunnerReturnHash
|
|
104
100
|
|
|
105
101
|
mapped = map_negotiate_claims(auth_result, profile)
|
|
106
102
|
display = mapped[:display_name] || mapped[:first_name]
|
|
@@ -108,7 +104,7 @@ module Legion
|
|
|
108
104
|
msid: mapped[:sub], name: display, roles: mapped[:roles], ttl: 28_800
|
|
109
105
|
)
|
|
110
106
|
[token, mapped[:roles]]
|
|
111
|
-
rescue StandardError
|
|
107
|
+
rescue StandardError => _e
|
|
112
108
|
[nil, []]
|
|
113
109
|
end
|
|
114
110
|
|
|
@@ -121,14 +117,14 @@ module Legion
|
|
|
121
117
|
end
|
|
122
118
|
|
|
123
119
|
def negotiate_json(hash)
|
|
124
|
-
return
|
|
120
|
+
return json_dump(hash) if defined?(Legion::JSON) # rubocop:disable Legion/Extension/RunnerReturnHash
|
|
125
121
|
|
|
126
122
|
require 'json'
|
|
127
123
|
::JSON.generate(hash)
|
|
128
124
|
end
|
|
129
125
|
|
|
130
|
-
include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers) &&
|
|
131
|
-
Legion::Extensions::Helpers.const_defined?(:Lex)
|
|
126
|
+
include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers, false) &&
|
|
127
|
+
Legion::Extensions::Helpers.const_defined?(:Lex, false)
|
|
132
128
|
end
|
|
133
129
|
end
|
|
134
130
|
end
|
|
@@ -6,13 +6,13 @@ require 'legion/extensions/kerberos/helpers/ldap'
|
|
|
6
6
|
require 'legion/extensions/kerberos/helpers/keytab'
|
|
7
7
|
require 'legion/extensions/kerberos/helpers/client'
|
|
8
8
|
require 'legion/extensions/kerberos/runners/authenticate'
|
|
9
|
-
require 'legion/extensions/kerberos/actors/keytab_refresh'
|
|
9
|
+
require 'legion/extensions/kerberos/actors/keytab_refresh'
|
|
10
10
|
require 'legion/extensions/kerberos/client'
|
|
11
11
|
|
|
12
12
|
module Legion
|
|
13
13
|
module Extensions
|
|
14
14
|
module Kerberos
|
|
15
|
-
extend Legion::Extensions::Core if Legion::Extensions.const_defined? :Core
|
|
15
|
+
extend Legion::Extensions::Core if Legion::Extensions.const_defined? :Core, false
|
|
16
16
|
end
|
|
17
17
|
end
|
|
18
18
|
end
|