krb5-ruby 0.1.0
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/.document +5 -0
- data/Gemfile +17 -0
- data/Gemfile.lock +116 -0
- data/LICENSE +21 -0
- data/README.md +19 -0
- data/Rakefile +46 -0
- data/VERSION +1 -0
- data/krb5-ruby.gemspec +63 -0
- data/lib/krb5.rb +5 -0
- data/lib/krb5/entry.rb +45 -0
- data/lib/krb5/keytab.rb +80 -0
- data/lib/krb5/keytab_parser.rb +168 -0
- data/lib/krb5/mixin/packer.rb +33 -0
- data/lib/krb5/mixin/unpacker.rb +39 -0
- data/lib/krb5/principal.rb +50 -0
- data/test/helper.rb +34 -0
- data/test/test_krb5-ruby.rb +7 -0
- metadata +105 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a4f472662ee226e8ea0e60998ae5e0e41f5e6675
|
4
|
+
data.tar.gz: 84cd7aa71a0e8298b5aefcd7b0f80c6115087e16
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5d94f52b568f9d0d5d371ee40307c23cfc054a855045d95af43c3d1ec574ad10ae1e253443561f54ba03c6ba85791d9159bad54fbeb00dc5ea27523184caaae7
|
7
|
+
data.tar.gz: fbe54e7f10d9d426e5f3591c84d24cc2bc8c703c27eaf5cd67c1c254c65281f020bc9c0dc74b2833095c95bd7f5a21eac6ae8e7d5644496a989aea3e24f939a3
|
data/.document
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gem 'rake', '~> 12.0', group: [:test, :development, :release]
|
4
|
+
|
5
|
+
group :test do
|
6
|
+
gem 'minitest', '~> 5.10'
|
7
|
+
gem 'coveralls', require: false
|
8
|
+
end
|
9
|
+
|
10
|
+
group :development do
|
11
|
+
gem 'guard', '~> 2.14'
|
12
|
+
gem 'guard-minitest', '~> 2.4'
|
13
|
+
end
|
14
|
+
|
15
|
+
group :release do
|
16
|
+
gem 'jeweler', '~> 2.3', require: false
|
17
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
GEM
|
2
|
+
remote: https://rubygems.org/
|
3
|
+
specs:
|
4
|
+
addressable (2.4.0)
|
5
|
+
builder (3.2.3)
|
6
|
+
coderay (1.1.2)
|
7
|
+
coveralls (0.8.21)
|
8
|
+
json (>= 1.8, < 3)
|
9
|
+
simplecov (~> 0.14.1)
|
10
|
+
term-ansicolor (~> 1.3)
|
11
|
+
thor (~> 0.19.4)
|
12
|
+
tins (~> 1.6)
|
13
|
+
descendants_tracker (0.0.4)
|
14
|
+
thread_safe (~> 0.3, >= 0.3.1)
|
15
|
+
docile (1.1.5)
|
16
|
+
faraday (0.9.2)
|
17
|
+
multipart-post (>= 1.2, < 3)
|
18
|
+
ffi (1.9.18)
|
19
|
+
formatador (0.2.5)
|
20
|
+
git (1.3.0)
|
21
|
+
github_api (0.16.0)
|
22
|
+
addressable (~> 2.4.0)
|
23
|
+
descendants_tracker (~> 0.0.4)
|
24
|
+
faraday (~> 0.8, < 0.10)
|
25
|
+
hashie (>= 3.4)
|
26
|
+
mime-types (>= 1.16, < 3.0)
|
27
|
+
oauth2 (~> 1.0)
|
28
|
+
guard (2.14.2)
|
29
|
+
formatador (>= 0.2.4)
|
30
|
+
listen (>= 2.7, < 4.0)
|
31
|
+
lumberjack (>= 1.0.12, < 2.0)
|
32
|
+
nenv (~> 0.1)
|
33
|
+
notiffany (~> 0.0)
|
34
|
+
pry (>= 0.9.12)
|
35
|
+
shellany (~> 0.0)
|
36
|
+
thor (>= 0.18.1)
|
37
|
+
guard-compat (1.2.1)
|
38
|
+
guard-minitest (2.4.6)
|
39
|
+
guard-compat (~> 1.2)
|
40
|
+
minitest (>= 3.0)
|
41
|
+
hashie (3.5.7)
|
42
|
+
highline (1.7.10)
|
43
|
+
jeweler (2.3.7)
|
44
|
+
builder
|
45
|
+
bundler (>= 1)
|
46
|
+
git (>= 1.2.5)
|
47
|
+
github_api (~> 0.16.0)
|
48
|
+
highline (>= 1.6.15)
|
49
|
+
nokogiri (>= 1.5.10)
|
50
|
+
psych (~> 2.2)
|
51
|
+
rake
|
52
|
+
rdoc
|
53
|
+
semver2
|
54
|
+
json (2.1.0)
|
55
|
+
jwt (1.5.6)
|
56
|
+
listen (3.1.5)
|
57
|
+
rb-fsevent (~> 0.9, >= 0.9.4)
|
58
|
+
rb-inotify (~> 0.9, >= 0.9.7)
|
59
|
+
ruby_dep (~> 1.2)
|
60
|
+
lumberjack (1.0.12)
|
61
|
+
method_source (0.9.0)
|
62
|
+
mime-types (2.99.3)
|
63
|
+
mini_portile2 (2.3.0)
|
64
|
+
minitest (5.11.1)
|
65
|
+
multi_json (1.12.2)
|
66
|
+
multi_xml (0.6.0)
|
67
|
+
multipart-post (2.0.0)
|
68
|
+
nenv (0.3.0)
|
69
|
+
nokogiri (1.8.1)
|
70
|
+
mini_portile2 (~> 2.3.0)
|
71
|
+
notiffany (0.1.1)
|
72
|
+
nenv (~> 0.1)
|
73
|
+
shellany (~> 0.0)
|
74
|
+
oauth2 (1.4.0)
|
75
|
+
faraday (>= 0.8, < 0.13)
|
76
|
+
jwt (~> 1.0)
|
77
|
+
multi_json (~> 1.3)
|
78
|
+
multi_xml (~> 0.5)
|
79
|
+
rack (>= 1.2, < 3)
|
80
|
+
pry (0.11.3)
|
81
|
+
coderay (~> 1.1.0)
|
82
|
+
method_source (~> 0.9.0)
|
83
|
+
psych (2.2.4)
|
84
|
+
rack (2.0.3)
|
85
|
+
rake (12.3.0)
|
86
|
+
rb-fsevent (0.10.2)
|
87
|
+
rb-inotify (0.9.10)
|
88
|
+
ffi (>= 0.5.0, < 2)
|
89
|
+
rdoc (6.0.1)
|
90
|
+
ruby_dep (1.5.0)
|
91
|
+
semver2 (3.4.2)
|
92
|
+
shellany (0.0.1)
|
93
|
+
simplecov (0.14.1)
|
94
|
+
docile (~> 1.1.0)
|
95
|
+
json (>= 1.8, < 3)
|
96
|
+
simplecov-html (~> 0.10.0)
|
97
|
+
simplecov-html (0.10.2)
|
98
|
+
term-ansicolor (1.6.0)
|
99
|
+
tins (~> 1.0)
|
100
|
+
thor (0.19.4)
|
101
|
+
thread_safe (0.3.6)
|
102
|
+
tins (1.16.3)
|
103
|
+
|
104
|
+
PLATFORMS
|
105
|
+
ruby
|
106
|
+
|
107
|
+
DEPENDENCIES
|
108
|
+
coveralls
|
109
|
+
guard (~> 2.14)
|
110
|
+
guard-minitest (~> 2.4)
|
111
|
+
jeweler (~> 2.3)
|
112
|
+
minitest (~> 5.10)
|
113
|
+
rake (~> 12.0)
|
114
|
+
|
115
|
+
BUNDLED WITH
|
116
|
+
1.16.0
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2018 Jason Barnett
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# krb5-ruby
|
2
|
+
|
3
|
+
Ruby native implementation of the KRB5 library for interacting with Kerberos Keytab files.
|
4
|
+
|
5
|
+
## Contributing to krb5-ruby
|
6
|
+
|
7
|
+
- Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
8
|
+
- Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
|
9
|
+
- Fork the project.
|
10
|
+
- Start a feature/bugfix branch.
|
11
|
+
- Commit and push until you are happy with your contribution.
|
12
|
+
- Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
13
|
+
- Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
14
|
+
|
15
|
+
## Copyright
|
16
|
+
|
17
|
+
Copyright (c) 2018 Jason Barnett. See LICENSE for
|
18
|
+
further details.
|
19
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rake'
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'jeweler'
|
7
|
+
Jeweler::Tasks.new do |gem|
|
8
|
+
# gem is a Gem::Specification... see http://guides.rubygems.org/specification-reference/ for more options
|
9
|
+
gem.name = "krb5-ruby"
|
10
|
+
gem.homepage = "http://github.com/jasonwbarnett/krb5-ruby"
|
11
|
+
gem.license = "MIT"
|
12
|
+
gem.summary = %Q{Ruby native implementation of the KRB5 library for interacting with Kerberos Keytab files}
|
13
|
+
gem.description = %Q{This gem adds native Ruby support for KRB5 keytab files}
|
14
|
+
gem.email = "jason.w.barnett@gmail.com"
|
15
|
+
gem.authors = ["Jason Barnett"]
|
16
|
+
# dependencies defined in Gemfile
|
17
|
+
end
|
18
|
+
Jeweler::RubygemsDotOrgTasks.new
|
19
|
+
rescue LoadError => e
|
20
|
+
$stderr.puts e.message + " (normal in CI environment -- otherwise run `bundle install`)"
|
21
|
+
end
|
22
|
+
|
23
|
+
require 'rake/testtask'
|
24
|
+
Rake::TestTask.new(:test) do |test|
|
25
|
+
test.libs << 'lib' << 'test'
|
26
|
+
test.pattern = 'test/**/*_test.rb'
|
27
|
+
test.verbose = true
|
28
|
+
end
|
29
|
+
|
30
|
+
desc "Code coverage detail"
|
31
|
+
task :simplecov do
|
32
|
+
ENV['COVERAGE'] = "true"
|
33
|
+
Rake::Task['test'].execute
|
34
|
+
end
|
35
|
+
|
36
|
+
task :default => :test
|
37
|
+
|
38
|
+
require 'rdoc/task'
|
39
|
+
Rake::RDocTask.new do |rdoc|
|
40
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
41
|
+
|
42
|
+
rdoc.rdoc_dir = 'rdoc'
|
43
|
+
rdoc.title = "krb5-ruby #{version}"
|
44
|
+
rdoc.rdoc_files.include('README*')
|
45
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
46
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/krb5-ruby.gemspec
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
# stub: krb5-ruby 0.1.0 ruby lib
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = "krb5-ruby".freeze
|
9
|
+
s.version = "0.1.0"
|
10
|
+
|
11
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
12
|
+
s.require_paths = ["lib".freeze]
|
13
|
+
s.authors = ["Jason Barnett".freeze]
|
14
|
+
s.date = "2018-01-08"
|
15
|
+
s.description = "This gem adds native Ruby support for KRB5 keytab files".freeze
|
16
|
+
s.email = "jason.w.barnett@gmail.com".freeze
|
17
|
+
s.extra_rdoc_files = [
|
18
|
+
"LICENSE",
|
19
|
+
"README.md"
|
20
|
+
]
|
21
|
+
s.files = [
|
22
|
+
".document",
|
23
|
+
"Gemfile",
|
24
|
+
"Gemfile.lock",
|
25
|
+
"LICENSE",
|
26
|
+
"README.md",
|
27
|
+
"Rakefile",
|
28
|
+
"VERSION",
|
29
|
+
"krb5-ruby.gemspec",
|
30
|
+
"lib/krb5.rb",
|
31
|
+
"lib/krb5/entry.rb",
|
32
|
+
"lib/krb5/keytab.rb",
|
33
|
+
"lib/krb5/keytab_parser.rb",
|
34
|
+
"lib/krb5/mixin/packer.rb",
|
35
|
+
"lib/krb5/mixin/unpacker.rb",
|
36
|
+
"lib/krb5/principal.rb",
|
37
|
+
"test/helper.rb",
|
38
|
+
"test/test_krb5-ruby.rb"
|
39
|
+
]
|
40
|
+
s.homepage = "http://github.com/jasonwbarnett/krb5-ruby".freeze
|
41
|
+
s.licenses = ["MIT".freeze]
|
42
|
+
s.rubygems_version = "2.6.13".freeze
|
43
|
+
s.summary = "Ruby native implementation of the KRB5 library for interacting with Kerberos Keytab files".freeze
|
44
|
+
|
45
|
+
if s.respond_to? :specification_version then
|
46
|
+
s.specification_version = 4
|
47
|
+
|
48
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
49
|
+
s.add_development_dependency(%q<rake>.freeze, ["~> 12.0"])
|
50
|
+
s.add_development_dependency(%q<guard>.freeze, ["~> 2.14"])
|
51
|
+
s.add_development_dependency(%q<guard-minitest>.freeze, ["~> 2.4"])
|
52
|
+
else
|
53
|
+
s.add_dependency(%q<rake>.freeze, ["~> 12.0"])
|
54
|
+
s.add_dependency(%q<guard>.freeze, ["~> 2.14"])
|
55
|
+
s.add_dependency(%q<guard-minitest>.freeze, ["~> 2.4"])
|
56
|
+
end
|
57
|
+
else
|
58
|
+
s.add_dependency(%q<rake>.freeze, ["~> 12.0"])
|
59
|
+
s.add_dependency(%q<guard>.freeze, ["~> 2.14"])
|
60
|
+
s.add_dependency(%q<guard-minitest>.freeze, ["~> 2.4"])
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
data/lib/krb5.rb
ADDED
data/lib/krb5/entry.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'krb5/mixin/packer'
|
2
|
+
|
3
|
+
class KRB5
|
4
|
+
class Entry
|
5
|
+
include KRB5::Mixin::Packer
|
6
|
+
|
7
|
+
# @return [KRB5::Keytab]
|
8
|
+
attr_accessor :keytab
|
9
|
+
|
10
|
+
attr_accessor :principal
|
11
|
+
attr_accessor :timestamp
|
12
|
+
attr_accessor :kvno8
|
13
|
+
attr_accessor :enctype
|
14
|
+
attr_accessor :key
|
15
|
+
attr_accessor :kvno32
|
16
|
+
|
17
|
+
# Place to store byte array for #to_bytes
|
18
|
+
# @return [Sting, nil]
|
19
|
+
attr_accessor :bytes
|
20
|
+
|
21
|
+
def initialize(keytab)
|
22
|
+
@keytab = keytab
|
23
|
+
end
|
24
|
+
|
25
|
+
# entry ::=
|
26
|
+
# principal
|
27
|
+
# timestamp (32 bits)
|
28
|
+
# key version (8 bits)
|
29
|
+
# enctype (16 bits)
|
30
|
+
# key length (16 bits)
|
31
|
+
# key contents
|
32
|
+
# key version (32 bits) [in release 1.14 and later]
|
33
|
+
def to_bytes
|
34
|
+
pack_bytes(principal.to_bytes)
|
35
|
+
pack_int32(timestamp.strftime('%s').to_i)
|
36
|
+
pack_int8(kvno8)
|
37
|
+
pack_int16(enctype)
|
38
|
+
pack_int16(key.length)
|
39
|
+
pack_bytes(key)
|
40
|
+
pack_int32(kvno32) if kvno32
|
41
|
+
|
42
|
+
@bytes.join
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/krb5/keytab.rb
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'krb5/keytab_parser'
|
2
|
+
require 'krb5/mixin/packer'
|
3
|
+
|
4
|
+
class KRB5
|
5
|
+
class Keytab
|
6
|
+
include KRB5::Mixin::Packer
|
7
|
+
|
8
|
+
# Keytab version
|
9
|
+
# @return [Integer]
|
10
|
+
attr_accessor :version
|
11
|
+
|
12
|
+
# Keytab entries
|
13
|
+
# @return [Array<KRB5::Entry>]
|
14
|
+
attr_accessor :entries
|
15
|
+
|
16
|
+
# If parsed, contains source bytes
|
17
|
+
# @return [String, nil]
|
18
|
+
attr_accessor :source_bytes
|
19
|
+
|
20
|
+
# Place to store byte array for #to_bytes
|
21
|
+
# @return [Sting, nil]
|
22
|
+
attr_accessor :bytes
|
23
|
+
|
24
|
+
def initialize
|
25
|
+
@entries = []
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.load(filename)
|
29
|
+
keytab_data = File.binread(filename)
|
30
|
+
KRB5::KeytabParser.parse(keytab_data)
|
31
|
+
end
|
32
|
+
|
33
|
+
def save(filename)
|
34
|
+
File.binwrite(filename, to_bytes)
|
35
|
+
end
|
36
|
+
|
37
|
+
# keytab ::=
|
38
|
+
# 5 (8 bits)
|
39
|
+
# version (8 bits)
|
40
|
+
# entry1 length (32 bits)
|
41
|
+
# entry1 (entry)
|
42
|
+
# entry2 length (32 bits)
|
43
|
+
# entry2 (entry)
|
44
|
+
# ...
|
45
|
+
#
|
46
|
+
# entry ::=
|
47
|
+
# principal
|
48
|
+
# timestamp (32 bits)
|
49
|
+
# key version (8 bits)
|
50
|
+
# enctype (16 bits)
|
51
|
+
# key length (16 bits)
|
52
|
+
# key contents
|
53
|
+
# key version (32 bits) [in release 1.14 and later]
|
54
|
+
#
|
55
|
+
# principal ::=
|
56
|
+
# count of components (16 bits) [includes realm in version 1]
|
57
|
+
# realm (data)
|
58
|
+
# component1 (data)
|
59
|
+
# component2 (data)
|
60
|
+
# ...
|
61
|
+
# name type (32 bits) [omitted in version 1]
|
62
|
+
#
|
63
|
+
# data ::=
|
64
|
+
# length (16 bits)
|
65
|
+
# value (length bytes)
|
66
|
+
def to_bytes
|
67
|
+
# First byte is always a 5
|
68
|
+
pack_int8(5)
|
69
|
+
pack_int8(version)
|
70
|
+
|
71
|
+
entries.each do |entry|
|
72
|
+
entry_bytes = entry.to_bytes
|
73
|
+
pack_int32(entry_bytes.length)
|
74
|
+
pack_bytes(entry_bytes)
|
75
|
+
end
|
76
|
+
|
77
|
+
@bytes.join
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,168 @@
|
|
1
|
+
require 'krb5/keytab'
|
2
|
+
require 'krb5/entry'
|
3
|
+
require 'krb5/principal'
|
4
|
+
require 'krb5/mixin/unpacker'
|
5
|
+
|
6
|
+
require 'pry'
|
7
|
+
|
8
|
+
class KRB5
|
9
|
+
class KeytabParser
|
10
|
+
SUPPORTED_VERSIONS = [1, 2]
|
11
|
+
|
12
|
+
include KRB5::Mixin::Unpacker
|
13
|
+
|
14
|
+
# raw bytes of keytab file
|
15
|
+
# @return [String]
|
16
|
+
attr_accessor :bytes
|
17
|
+
|
18
|
+
# Instance of KRB5::Keytab to unpack bytes into Ruby class
|
19
|
+
# @return [KRB5::Keytab]
|
20
|
+
attr_accessor :keytab
|
21
|
+
|
22
|
+
def initialize
|
23
|
+
@index = 0
|
24
|
+
@keytab = KRB5::Keytab.new
|
25
|
+
end
|
26
|
+
|
27
|
+
# Keep track of where we are in byte array
|
28
|
+
# @return [Integer]
|
29
|
+
def index
|
30
|
+
@index
|
31
|
+
end
|
32
|
+
|
33
|
+
#
|
34
|
+
# Parses byte array and creates relevant Ruby objects
|
35
|
+
#
|
36
|
+
# @return [KRB5::Keytab]
|
37
|
+
#
|
38
|
+
def self.parse(bytes)
|
39
|
+
parser = new
|
40
|
+
parser.bytes = bytes
|
41
|
+
parser.keytab.source_bytes = bytes
|
42
|
+
parser.unpack_byte_array
|
43
|
+
parser.keytab
|
44
|
+
end
|
45
|
+
|
46
|
+
def unpack_byte_array
|
47
|
+
unpack_header
|
48
|
+
|
49
|
+
record_length = unpack_int32
|
50
|
+
while record_length != 0 do
|
51
|
+
if record_length < 0
|
52
|
+
@index += record_length * -1
|
53
|
+
else
|
54
|
+
@curr_entry_first_byte = @index
|
55
|
+
@curr_entry_last_byte = @index + record_length - 1
|
56
|
+
keytab.entries << unpack_entry
|
57
|
+
@index = @curr_entry_first_byte + record_length
|
58
|
+
end
|
59
|
+
|
60
|
+
if @index > bytes.length || bytes[@index..-1].length < 4
|
61
|
+
break
|
62
|
+
end
|
63
|
+
|
64
|
+
record_length = unpack_int32
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
#
|
69
|
+
# Unpacks the Keytab header which is two bytes and contains the
|
70
|
+
# version number of the keytab
|
71
|
+
#
|
72
|
+
# @return [nil]
|
73
|
+
# @raise [RuntimeError] if the file does not have a valid header
|
74
|
+
def unpack_header
|
75
|
+
raise "Invalid keytab data. First byte does not equal 5" if unpack_int8 != 5
|
76
|
+
keytab.version = unpack_int8
|
77
|
+
raise "Invalid keytab data. Keytab version is neither 1 nor 2" unless SUPPORTED_VERSIONS.include?(keytab.version)
|
78
|
+
nil
|
79
|
+
end
|
80
|
+
|
81
|
+
#
|
82
|
+
# entry ::=
|
83
|
+
# principal
|
84
|
+
# timestamp (32 bits)
|
85
|
+
# key version (8 bits)
|
86
|
+
# enctype (16 bits)
|
87
|
+
# key length (16 bits)
|
88
|
+
# key contents
|
89
|
+
# key version (32 bits) [in release 1.14 and later]
|
90
|
+
#
|
91
|
+
# See: https://web.mit.edu/kerberos/krb5-1.16/doc/formats/keytab_file_format.html
|
92
|
+
#
|
93
|
+
# @return [KRB5::Entry]
|
94
|
+
def unpack_entry
|
95
|
+
entry = KRB5::Entry.new(keytab)
|
96
|
+
entry.principal = unpack_principal
|
97
|
+
entry.timestamp = unpack_timestamp
|
98
|
+
entry.kvno8 = unpack_int8
|
99
|
+
entry.enctype = unpack_int16
|
100
|
+
entry.key = unpack_key
|
101
|
+
|
102
|
+
if @curr_entry_last_byte - @index >= 3
|
103
|
+
entry.kvno32 = unpack_int32
|
104
|
+
end
|
105
|
+
|
106
|
+
entry
|
107
|
+
end
|
108
|
+
|
109
|
+
#
|
110
|
+
# principal ::=
|
111
|
+
# count of components (16 bits) [includes realm in version 1]
|
112
|
+
# realm (data)
|
113
|
+
# component1 (data)
|
114
|
+
# component2 (data)
|
115
|
+
# ...
|
116
|
+
# name type (32 bits) [omitted in version 1]
|
117
|
+
#
|
118
|
+
# See: https://web.mit.edu/kerberos/krb5-1.16/doc/formats/keytab_file_format.html
|
119
|
+
#
|
120
|
+
# @return [KRB5::Principal]
|
121
|
+
def unpack_principal
|
122
|
+
principal = KRB5::Principal.new(keytab)
|
123
|
+
|
124
|
+
count_of_components = unpack_int16
|
125
|
+
# Keytab v1 used to include the realm in the component count. This makes
|
126
|
+
# v1 parsing just like v2
|
127
|
+
if keytab.version == 1
|
128
|
+
count_of_components -= 1
|
129
|
+
end
|
130
|
+
|
131
|
+
principal.realm = unpack_data
|
132
|
+
|
133
|
+
count_of_components.times do
|
134
|
+
principal.components << unpack_data
|
135
|
+
end
|
136
|
+
|
137
|
+
principal.name_type = unpack_int32 unless keytab.version == 1
|
138
|
+
|
139
|
+
principal
|
140
|
+
end
|
141
|
+
|
142
|
+
def unpack_timestamp
|
143
|
+
require 'date'
|
144
|
+
epoch = unpack_int32
|
145
|
+
DateTime.strptime(epoch.to_s, '%s')
|
146
|
+
end
|
147
|
+
|
148
|
+
def unpack_key
|
149
|
+
key_length = unpack_int16
|
150
|
+
unpack_bytes(key_length)
|
151
|
+
end
|
152
|
+
|
153
|
+
#
|
154
|
+
# Generic method to unpack Kerberos data
|
155
|
+
#
|
156
|
+
# data ::=
|
157
|
+
# length (16 bits)
|
158
|
+
# value (length bytes)
|
159
|
+
#
|
160
|
+
# See: https://web.mit.edu/kerberos/krb5-1.16/doc/formats/keytab_file_format.html
|
161
|
+
#
|
162
|
+
# @return [String]
|
163
|
+
def unpack_data
|
164
|
+
length = unpack_int16
|
165
|
+
data = unpack_bytes(length)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
class KRB5
|
2
|
+
module Mixin
|
3
|
+
module Packer
|
4
|
+
def pack_bytes(data)
|
5
|
+
@bytes ||= []
|
6
|
+
|
7
|
+
if data.is_a?(Array)
|
8
|
+
@bytes += data
|
9
|
+
elsif data.is_a?(String)
|
10
|
+
@bytes << data
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def pack_int8(data)
|
15
|
+
@bytes ||= []
|
16
|
+
|
17
|
+
@bytes << [data].pack('c')
|
18
|
+
end
|
19
|
+
|
20
|
+
def pack_int16(data)
|
21
|
+
@bytes ||= []
|
22
|
+
|
23
|
+
@bytes << [data].pack('s>')
|
24
|
+
end
|
25
|
+
|
26
|
+
def pack_int32(data)
|
27
|
+
@bytes ||= []
|
28
|
+
|
29
|
+
@bytes << [data].pack('l>')
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
class KRB5
|
2
|
+
module Mixin
|
3
|
+
module Unpacker
|
4
|
+
#
|
5
|
+
# Unpack raw bytes
|
6
|
+
#
|
7
|
+
# @param length [Integer] number of bytes to unpack
|
8
|
+
# @return [Array] raw bytes
|
9
|
+
#
|
10
|
+
def unpack_bytes(length)
|
11
|
+
data = bytes[@index, length]
|
12
|
+
@index += length
|
13
|
+
|
14
|
+
data
|
15
|
+
end
|
16
|
+
|
17
|
+
def unpack_int8
|
18
|
+
data = bytes[@index].unpack1('c')
|
19
|
+
@index += 1
|
20
|
+
|
21
|
+
data
|
22
|
+
end
|
23
|
+
|
24
|
+
def unpack_int16
|
25
|
+
data = bytes[@index, 2].unpack1('s>')
|
26
|
+
@index += 2
|
27
|
+
|
28
|
+
data
|
29
|
+
end
|
30
|
+
|
31
|
+
def unpack_int32
|
32
|
+
data = bytes[@index, 4].unpack1('l>')
|
33
|
+
@index += 4
|
34
|
+
|
35
|
+
data
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'krb5/mixin/packer'
|
2
|
+
|
3
|
+
class KRB5
|
4
|
+
class Principal
|
5
|
+
include KRB5::Mixin::Packer
|
6
|
+
|
7
|
+
# @return [KRB5::Keytab]
|
8
|
+
attr_accessor :keytab
|
9
|
+
|
10
|
+
attr_accessor :realm, :components, :name_type
|
11
|
+
|
12
|
+
# Place to store byte array for #to_bytes
|
13
|
+
# @return [Sting, nil]
|
14
|
+
attr_accessor :bytes
|
15
|
+
|
16
|
+
def initialize(keytab)
|
17
|
+
@keytab = keytab
|
18
|
+
@components = []
|
19
|
+
end
|
20
|
+
|
21
|
+
# principal ::=
|
22
|
+
# count of components (16 bits) [includes realm in version 1]
|
23
|
+
# realm (data)
|
24
|
+
# component1 (data)
|
25
|
+
# component2 (data)
|
26
|
+
# ...
|
27
|
+
# name type (32 bits) [omitted in version 1]
|
28
|
+
def to_bytes
|
29
|
+
pack_count_of_components
|
30
|
+
pack_int16(realm.length)
|
31
|
+
pack_bytes(realm)
|
32
|
+
components.each do |component|
|
33
|
+
pack_int16(component.length)
|
34
|
+
pack_bytes(component)
|
35
|
+
end
|
36
|
+
pack_int32(name_type)
|
37
|
+
|
38
|
+
@bytes.join
|
39
|
+
end
|
40
|
+
|
41
|
+
def pack_count_of_components
|
42
|
+
if keytab.version == 1
|
43
|
+
# Component length includes realm in v1 Keytabs
|
44
|
+
pack_int16(components.length + 1)
|
45
|
+
elsif keytab.version == 2
|
46
|
+
pack_int16(components.length)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'simplecov'
|
2
|
+
|
3
|
+
module SimpleCov::Configuration
|
4
|
+
def clean_filters
|
5
|
+
@filters = []
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
SimpleCov.configure do
|
10
|
+
clean_filters
|
11
|
+
load_adapter 'test_frameworks'
|
12
|
+
end
|
13
|
+
|
14
|
+
ENV["COVERAGE"] && SimpleCov.start do
|
15
|
+
add_filter "/.rvm/"
|
16
|
+
end
|
17
|
+
require 'rubygems'
|
18
|
+
require 'bundler'
|
19
|
+
begin
|
20
|
+
Bundler.setup(:default, :development)
|
21
|
+
rescue Bundler::BundlerError => e
|
22
|
+
$stderr.puts e.message
|
23
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
24
|
+
exit e.status_code
|
25
|
+
end
|
26
|
+
require 'test/unit'
|
27
|
+
require 'shoulda'
|
28
|
+
|
29
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
30
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
31
|
+
require 'krb5-ruby'
|
32
|
+
|
33
|
+
class Test::Unit::TestCase
|
34
|
+
end
|
metadata
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: krb5-ruby
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jason Barnett
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-01-08 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: '12.0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '12.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: guard
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2.14'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '2.14'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: guard-minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '2.4'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '2.4'
|
55
|
+
description: This gem adds native Ruby support for KRB5 keytab files
|
56
|
+
email: jason.w.barnett@gmail.com
|
57
|
+
executables: []
|
58
|
+
extensions: []
|
59
|
+
extra_rdoc_files:
|
60
|
+
- LICENSE
|
61
|
+
- README.md
|
62
|
+
files:
|
63
|
+
- ".document"
|
64
|
+
- Gemfile
|
65
|
+
- Gemfile.lock
|
66
|
+
- LICENSE
|
67
|
+
- README.md
|
68
|
+
- Rakefile
|
69
|
+
- VERSION
|
70
|
+
- krb5-ruby.gemspec
|
71
|
+
- lib/krb5.rb
|
72
|
+
- lib/krb5/entry.rb
|
73
|
+
- lib/krb5/keytab.rb
|
74
|
+
- lib/krb5/keytab_parser.rb
|
75
|
+
- lib/krb5/mixin/packer.rb
|
76
|
+
- lib/krb5/mixin/unpacker.rb
|
77
|
+
- lib/krb5/principal.rb
|
78
|
+
- test/helper.rb
|
79
|
+
- test/test_krb5-ruby.rb
|
80
|
+
homepage: http://github.com/jasonwbarnett/krb5-ruby
|
81
|
+
licenses:
|
82
|
+
- MIT
|
83
|
+
metadata: {}
|
84
|
+
post_install_message:
|
85
|
+
rdoc_options: []
|
86
|
+
require_paths:
|
87
|
+
- lib
|
88
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
requirements: []
|
99
|
+
rubyforge_project:
|
100
|
+
rubygems_version: 2.6.13
|
101
|
+
signing_key:
|
102
|
+
specification_version: 4
|
103
|
+
summary: Ruby native implementation of the KRB5 library for interacting with Kerberos
|
104
|
+
Keytab files
|
105
|
+
test_files: []
|