rkerberos 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.
- data/CHANGES +3 -0
- data/MANIFEST +16 -0
- data/README +51 -0
- data/Rakefile +148 -0
- data/ext/rkerberos/ccache.c +250 -0
- data/ext/rkerberos/config.c +312 -0
- data/ext/rkerberos/context.c +77 -0
- data/ext/rkerberos/extconf.rb +14 -0
- data/ext/rkerberos/kadm5.c +991 -0
- data/ext/rkerberos/keytab.c +509 -0
- data/ext/rkerberos/keytab_entry.c +84 -0
- data/ext/rkerberos/policy.c +196 -0
- data/ext/rkerberos/principal.c +263 -0
- data/ext/rkerberos/rkerberos.c +566 -0
- data/ext/rkerberos/rkerberos.h +95 -0
- data/rkerberos.gemspec +28 -0
- data/test/test_config.rb +129 -0
- data/test/test_context.rb +33 -0
- data/test/test_credentials_cache.rb +153 -0
- data/test/test_kadm5.rb +424 -0
- data/test/test_keytab_entry.rb +66 -0
- data/test/test_krb5.rb +198 -0
- data/test/test_krb5_keytab.rb +294 -0
- data/test/test_policy.rb +123 -0
- data/test/test_principal.rb +134 -0
- metadata +155 -0
@@ -0,0 +1,95 @@
|
|
1
|
+
#ifndef KRB5_AUTH_H_INCLUDED
|
2
|
+
#define KRB5_AUTH_H_INCLUDED
|
3
|
+
|
4
|
+
#include <ruby.h>
|
5
|
+
#include <krb5.h>
|
6
|
+
#include <string.h>
|
7
|
+
|
8
|
+
#ifdef HAVE_KADM5_ADMIN_H
|
9
|
+
#include <kadm5/admin.h>
|
10
|
+
#endif
|
11
|
+
|
12
|
+
// Function Prototypes
|
13
|
+
void Init_context();
|
14
|
+
void Init_kadm5();
|
15
|
+
void Init_config();
|
16
|
+
void Init_policy();
|
17
|
+
void Init_principal();
|
18
|
+
void Init_keytab();
|
19
|
+
void Init_keytab_entry();
|
20
|
+
void Init_ccache();
|
21
|
+
|
22
|
+
// Defined in rkerberos.c
|
23
|
+
VALUE rb_hash_aref2(VALUE, char*);
|
24
|
+
|
25
|
+
// Variable declarations
|
26
|
+
extern VALUE mKerberos;
|
27
|
+
extern VALUE cKrb5;
|
28
|
+
extern VALUE cKrb5CCache;
|
29
|
+
extern VALUE cKrb5Context;
|
30
|
+
extern VALUE cKrb5Keytab;
|
31
|
+
extern VALUE cKrb5KtEntry;
|
32
|
+
extern VALUE cKrb5Exception;
|
33
|
+
extern VALUE cKrb5Principal;
|
34
|
+
extern VALUE cKadm5;
|
35
|
+
extern VALUE cKadm5Config;
|
36
|
+
extern VALUE cKadm5Exception;
|
37
|
+
extern VALUE cKadm5Policy;
|
38
|
+
|
39
|
+
// Kerberos::Krb5
|
40
|
+
typedef struct {
|
41
|
+
krb5_context ctx;
|
42
|
+
krb5_creds creds;
|
43
|
+
krb5_principal princ;
|
44
|
+
krb5_keytab keytab;
|
45
|
+
} RUBY_KRB5;
|
46
|
+
|
47
|
+
// Kerberos::Context
|
48
|
+
typedef struct {
|
49
|
+
krb5_context ctx;
|
50
|
+
krb5_enctype etypes;
|
51
|
+
} RUBY_KRB5_CONTEXT;
|
52
|
+
|
53
|
+
// Kerberos::Kadm5
|
54
|
+
typedef struct {
|
55
|
+
krb5_context ctx;
|
56
|
+
krb5_principal princ;
|
57
|
+
void* handle;
|
58
|
+
} RUBY_KADM5;
|
59
|
+
|
60
|
+
// Kerberos::Krb5::Keytab::Entry
|
61
|
+
typedef struct {
|
62
|
+
krb5_principal principal;
|
63
|
+
krb5_timestamp timestamp;
|
64
|
+
krb5_kvno vno;
|
65
|
+
krb5_keyblock key;
|
66
|
+
} RUBY_KRB5_KT_ENTRY;
|
67
|
+
|
68
|
+
// Kerberos::Krb5::Keytab
|
69
|
+
typedef struct {
|
70
|
+
krb5_context ctx;
|
71
|
+
krb5_creds creds;
|
72
|
+
krb5_keytab keytab;
|
73
|
+
} RUBY_KRB5_KEYTAB;
|
74
|
+
|
75
|
+
typedef struct {
|
76
|
+
krb5_context ctx;
|
77
|
+
krb5_principal principal;
|
78
|
+
} RUBY_KRB5_PRINC;
|
79
|
+
|
80
|
+
typedef struct {
|
81
|
+
krb5_context ctx;
|
82
|
+
krb5_ccache ccache;
|
83
|
+
krb5_principal principal;
|
84
|
+
} RUBY_KRB5_CCACHE;
|
85
|
+
|
86
|
+
typedef struct {
|
87
|
+
krb5_context ctx;
|
88
|
+
kadm5_config_params config;
|
89
|
+
} RUBY_KADM5_CONFIG;
|
90
|
+
|
91
|
+
typedef struct {
|
92
|
+
krb5_context ctx;
|
93
|
+
kadm5_policy_ent_rec policy;
|
94
|
+
} RUBY_KADM5_POLICY;
|
95
|
+
#endif
|
data/rkerberos.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = 'rkerberos'
|
5
|
+
spec.version = '0.1.0'
|
6
|
+
spec.author = 'Daniel Berger'
|
7
|
+
spec.license = 'Artistic 2.0'
|
8
|
+
spec.email = 'djberg96@gmail.com'
|
9
|
+
spec.homepage = 'http://github.com/djberg96/rkerberos'
|
10
|
+
spec.platform = Gem::Platform::RUBY
|
11
|
+
spec.summary = 'A Ruby interface for the the Kerberos library'
|
12
|
+
spec.test_files = Dir['test/test*']
|
13
|
+
spec.extensions = ['ext/rkerberos/extconf.rb']
|
14
|
+
spec.files = Dir['**/*'].reject{ |f| f.include?('git') || f.include?('tmp') }
|
15
|
+
|
16
|
+
spec.rubyforge_project = 'rkerberos'
|
17
|
+
spec.extra_rdoc_files = ['README', 'CHANGES', 'MANIFEST'] + Dir['ext/rkerberos/*.c']
|
18
|
+
|
19
|
+
spec.add_dependency('rake-compiler')
|
20
|
+
|
21
|
+
spec.add_development_dependency('test-unit', '>= 2.1.0')
|
22
|
+
spec.add_development_dependency('dbi-dbrc', '>= 1.1.6')
|
23
|
+
|
24
|
+
spec.description = <<-EOF
|
25
|
+
The rkerberos library is an interface for the Kerberos 5 network
|
26
|
+
authentication protocol. It wraps the Kerberos C API.
|
27
|
+
EOF
|
28
|
+
end
|
data/test/test_config.rb
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
########################################################################
|
2
|
+
# test_config.rb
|
3
|
+
#
|
4
|
+
# Test suite for the Kerberos::Kadm5::Config class.
|
5
|
+
########################################################################
|
6
|
+
require 'rubygems'
|
7
|
+
gem 'test-unit'
|
8
|
+
|
9
|
+
require 'test/unit'
|
10
|
+
require 'rkerberos'
|
11
|
+
|
12
|
+
class TC_Kadm5_Config < Test::Unit::TestCase
|
13
|
+
def setup
|
14
|
+
@config = Kerberos::Kadm5::Config.new
|
15
|
+
end
|
16
|
+
|
17
|
+
test "config object is frozen" do
|
18
|
+
assert_true(@config.frozen?)
|
19
|
+
end
|
20
|
+
|
21
|
+
test "realm basic functionality" do
|
22
|
+
assert_respond_to(@config, :realm)
|
23
|
+
assert_kind_of(String, @config.realm)
|
24
|
+
end
|
25
|
+
|
26
|
+
test "kadmind_port basic functionality" do
|
27
|
+
assert_respond_to(@config, :kadmind_port)
|
28
|
+
assert_kind_of(Fixnum, @config.kadmind_port)
|
29
|
+
end
|
30
|
+
|
31
|
+
test "kpasswd_port basic functionality" do
|
32
|
+
assert_respond_to(@config, :kpasswd_port)
|
33
|
+
assert_kind_of(Fixnum, @config.kpasswd_port)
|
34
|
+
end
|
35
|
+
|
36
|
+
test "admin_server basic functionality" do
|
37
|
+
assert_respond_to(@config, :admin_server)
|
38
|
+
assert_kind_of(String, @config.admin_server)
|
39
|
+
end
|
40
|
+
|
41
|
+
test "admin_keytab basic functionality" do
|
42
|
+
assert_respond_to(@config, :admin_keytab)
|
43
|
+
assert_kind_of(String, @config.admin_keytab)
|
44
|
+
end
|
45
|
+
|
46
|
+
test "acl_file basic functionality" do
|
47
|
+
assert_respond_to(@config, :acl_file)
|
48
|
+
assert_kind_of(String, @config.acl_file)
|
49
|
+
end
|
50
|
+
|
51
|
+
test "dict_file basic functionality" do
|
52
|
+
assert_respond_to(@config, :dict_file)
|
53
|
+
assert_kind_of([String, NilClass], @config.dict_file)
|
54
|
+
end
|
55
|
+
|
56
|
+
test "stash_file basic functionality" do
|
57
|
+
assert_respond_to(@config, :stash_file)
|
58
|
+
assert_kind_of([String, NilClass], @config.stash_file)
|
59
|
+
end
|
60
|
+
|
61
|
+
test "mkey_name basic functionality" do
|
62
|
+
assert_respond_to(@config, :mkey_name)
|
63
|
+
assert_kind_of([String, NilClass], @config.mkey_name)
|
64
|
+
end
|
65
|
+
|
66
|
+
test "mkey_from_kbd basic functionality" do
|
67
|
+
assert_respond_to(@config, :mkey_from_kbd)
|
68
|
+
assert_kind_of([Fixnum, NilClass], @config.mkey_from_kbd)
|
69
|
+
end
|
70
|
+
|
71
|
+
test "enctype basic functionality" do
|
72
|
+
assert_respond_to(@config, :enctype)
|
73
|
+
assert_kind_of(Fixnum, @config.enctype)
|
74
|
+
end
|
75
|
+
|
76
|
+
test "max_life basic functionality" do
|
77
|
+
assert_respond_to(@config, :max_life)
|
78
|
+
assert_kind_of([Fixnum, NilClass], @config.max_life)
|
79
|
+
end
|
80
|
+
|
81
|
+
test "max_rlife basic functionality" do
|
82
|
+
assert_respond_to(@config, :max_rlife)
|
83
|
+
assert_kind_of([Fixnum, NilClass], @config.max_rlife)
|
84
|
+
end
|
85
|
+
|
86
|
+
test "expiration basic functionality" do
|
87
|
+
assert_respond_to(@config, :expiration)
|
88
|
+
assert_kind_of([Time, NilClass], @config.expiration)
|
89
|
+
end
|
90
|
+
|
91
|
+
test "kvno basic functionality" do
|
92
|
+
assert_respond_to(@config, :kvno)
|
93
|
+
assert_kind_of([Fixnum, NilClass], @config.kvno)
|
94
|
+
end
|
95
|
+
|
96
|
+
test "iprop_enabled basic functionality" do
|
97
|
+
assert_respond_to(@config, :iprop_enabled)
|
98
|
+
assert_boolean(@config.iprop_enabled)
|
99
|
+
end
|
100
|
+
|
101
|
+
test "iprop_logfile basic functionality" do
|
102
|
+
assert_respond_to(@config, :iprop_logfile)
|
103
|
+
assert_kind_of(String, @config.iprop_logfile)
|
104
|
+
end
|
105
|
+
|
106
|
+
test "iprop_polltime basic functionality" do
|
107
|
+
assert_respond_to(@config, :iprop_poll_time)
|
108
|
+
assert_kind_of(Fixnum, @config.iprop_poll_time)
|
109
|
+
end
|
110
|
+
|
111
|
+
test "iprop_port basic functionality" do
|
112
|
+
assert_respond_to(@config, :iprop_port)
|
113
|
+
assert_kind_of([Fixnum, NilClass], @config.iprop_port)
|
114
|
+
end
|
115
|
+
|
116
|
+
test "num_keysalts basic functionality" do
|
117
|
+
assert_respond_to(@config, :num_keysalts)
|
118
|
+
assert_kind_of(Fixnum, @config.num_keysalts)
|
119
|
+
end
|
120
|
+
|
121
|
+
test "keysalts basic functionality" do
|
122
|
+
assert_respond_to(@config, :keysalts)
|
123
|
+
assert_kind_of(Fixnum, @config.keysalts)
|
124
|
+
end
|
125
|
+
|
126
|
+
def teardown
|
127
|
+
@config = nil
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
########################################################################
|
2
|
+
# test_context.rb
|
3
|
+
#
|
4
|
+
# Test suite for the Kerberos::Krb5::Context class.
|
5
|
+
########################################################################
|
6
|
+
require 'rubygems'
|
7
|
+
gem 'test-unit'
|
8
|
+
|
9
|
+
require 'open3'
|
10
|
+
require 'test/unit'
|
11
|
+
require 'rkerberos'
|
12
|
+
|
13
|
+
class TC_Krb5_Context < Test::Unit::TestCase
|
14
|
+
def setup
|
15
|
+
@context = Kerberos::Krb5::Context.new
|
16
|
+
end
|
17
|
+
|
18
|
+
test "close basic functionality" do
|
19
|
+
assert_respond_to(@context, :close)
|
20
|
+
assert_nothing_raised{ @context.close }
|
21
|
+
end
|
22
|
+
|
23
|
+
test "calling close multiple times is harmless" do
|
24
|
+
assert_nothing_raised{ @context.close }
|
25
|
+
assert_nothing_raised{ @context.close }
|
26
|
+
assert_nothing_raised{ @context.close }
|
27
|
+
end
|
28
|
+
|
29
|
+
def teardown
|
30
|
+
@context.close
|
31
|
+
@context = nil
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,153 @@
|
|
1
|
+
#######################################################################
|
2
|
+
# test_credentials_cache.rb
|
3
|
+
#
|
4
|
+
# Tests for the Kerberos::Krb5::Credentials class.
|
5
|
+
#######################################################################
|
6
|
+
require 'rubygems'
|
7
|
+
gem 'test-unit'
|
8
|
+
|
9
|
+
require 'etc'
|
10
|
+
require 'test/unit'
|
11
|
+
require 'rkerberos'
|
12
|
+
require 'open3'
|
13
|
+
require 'tmpdir'
|
14
|
+
|
15
|
+
class TC_Krb5_Credentials_Cache < Test::Unit::TestCase
|
16
|
+
def setup
|
17
|
+
@login = Etc.getlogin
|
18
|
+
@princ = @login + '@' + Kerberos::Krb5.new.default_realm
|
19
|
+
@cfile = File.join(Dir.tmpdir, 'krb5cc_' + Etc.getpwnam(@login).uid.to_s)
|
20
|
+
@ccache = nil
|
21
|
+
end
|
22
|
+
|
23
|
+
# Helper method that uses the command line utility for external verification
|
24
|
+
def cache_found
|
25
|
+
found = true
|
26
|
+
|
27
|
+
Open3.popen3('klist') do |stdin, stdout, stderr|
|
28
|
+
found = false unless stderr.gets.nil?
|
29
|
+
end
|
30
|
+
|
31
|
+
found
|
32
|
+
end
|
33
|
+
|
34
|
+
# Constructor
|
35
|
+
|
36
|
+
test "calling constructor with no arguments is legal" do
|
37
|
+
assert_nothing_raised{ @ccache = Kerberos::Krb5::CredentialsCache.new }
|
38
|
+
end
|
39
|
+
|
40
|
+
test "calling constructor with no arguments does not create a cache" do
|
41
|
+
assert_nothing_raised{ @ccache = Kerberos::Krb5::CredentialsCache.new }
|
42
|
+
assert_false(File.exists?(@cfile))
|
43
|
+
assert_false(cache_found)
|
44
|
+
end
|
45
|
+
|
46
|
+
test "calling constructor with a principal argument creates a credentials cache" do
|
47
|
+
assert_nothing_raised{ @ccache = Kerberos::Krb5::CredentialsCache.new(@princ) }
|
48
|
+
assert_true(File.exists?(@cfile))
|
49
|
+
assert_true(cache_found)
|
50
|
+
end
|
51
|
+
|
52
|
+
test "calling constructor with an explicit cache name works as expected" do
|
53
|
+
assert_nothing_raised{ @ccache = Kerberos::Krb5::CredentialsCache.new(@princ, @cfile) }
|
54
|
+
assert_nothing_raised{ @ccache = Kerberos::Krb5::CredentialsCache.new(nil, @cfile) }
|
55
|
+
end
|
56
|
+
|
57
|
+
test "calling constructor with a non string argument raises an error" do
|
58
|
+
assert_raise(TypeError){ Kerberos::Krb5::CredentialsCache.new(true) }
|
59
|
+
end
|
60
|
+
|
61
|
+
test "constructor only accepts up to two arguments" do
|
62
|
+
assert_raise(ArgumentError){ Kerberos::Krb5::CredentialsCache.new(@princ, @cfile, @cfile) }
|
63
|
+
end
|
64
|
+
|
65
|
+
test "close method basic functionality" do
|
66
|
+
@ccache = Kerberos::Krb5::CredentialsCache.new(@princ)
|
67
|
+
assert_respond_to(@ccache, :close)
|
68
|
+
end
|
69
|
+
|
70
|
+
test "close method does not delete credentials cache" do
|
71
|
+
@ccache = Kerberos::Krb5::CredentialsCache.new(@princ)
|
72
|
+
assert_nothing_raised{ @ccache.close }
|
73
|
+
assert_true(cache_found)
|
74
|
+
end
|
75
|
+
|
76
|
+
test "calling close multiple times on the same object does not raise an error" do
|
77
|
+
@ccache = Kerberos::Krb5::CredentialsCache.new(@princ)
|
78
|
+
assert_nothing_raised{ @ccache.close }
|
79
|
+
assert_nothing_raised{ @ccache.close }
|
80
|
+
assert_nothing_raised{ @ccache.close }
|
81
|
+
end
|
82
|
+
|
83
|
+
test "calling a method on a closed object raises an error" do
|
84
|
+
@ccache = Kerberos::Krb5::CredentialsCache.new(@princ)
|
85
|
+
@ccache.close
|
86
|
+
assert_raise(Kerberos::Krb5::Exception){ @ccache.default_name }
|
87
|
+
end
|
88
|
+
|
89
|
+
test "default_name basic functionality" do
|
90
|
+
@ccache = Kerberos::Krb5::CredentialsCache.new(@princ)
|
91
|
+
assert_respond_to(@ccache, :default_name)
|
92
|
+
assert_nothing_raised{ @ccache.default_name }
|
93
|
+
end
|
94
|
+
|
95
|
+
test "default_name returns a string" do
|
96
|
+
@ccache = Kerberos::Krb5::CredentialsCache.new(@princ)
|
97
|
+
assert_kind_of(String, @ccache.default_name)
|
98
|
+
end
|
99
|
+
|
100
|
+
test "primary_principal basic functionality" do
|
101
|
+
@ccache = Kerberos::Krb5::CredentialsCache.new(@princ)
|
102
|
+
assert_respond_to(@ccache, :primary_principal)
|
103
|
+
assert_nothing_raised{ @ccache.primary_principal }
|
104
|
+
end
|
105
|
+
|
106
|
+
test "primary_principal returns expected results" do
|
107
|
+
@ccache = Kerberos::Krb5::CredentialsCache.new(@princ)
|
108
|
+
assert_kind_of(String, @ccache.primary_principal)
|
109
|
+
assert_true(@ccache.primary_principal.size > 0)
|
110
|
+
assert_true(@ccache.primary_principal.include?("@"))
|
111
|
+
end
|
112
|
+
|
113
|
+
test "destroy method basic functionality" do
|
114
|
+
@ccache = Kerberos::Krb5::CredentialsCache.new(@princ)
|
115
|
+
assert_respond_to(@ccache, :destroy)
|
116
|
+
end
|
117
|
+
|
118
|
+
test "destroy method deletes credentials cache" do
|
119
|
+
@ccache = Kerberos::Krb5::CredentialsCache.new(@princ)
|
120
|
+
assert_nothing_raised{ @ccache.destroy }
|
121
|
+
assert_false(cache_found)
|
122
|
+
end
|
123
|
+
|
124
|
+
test "delete is an alias for destroy" do
|
125
|
+
@ccache = Kerberos::Krb5::CredentialsCache.new(@princ)
|
126
|
+
assert_respond_to(@ccache, :delete)
|
127
|
+
assert_alias_method(@ccache, :destroy, :delete)
|
128
|
+
end
|
129
|
+
|
130
|
+
test "calling destroy when there is no credentials cache returns false" do
|
131
|
+
@ccache = Kerberos::Krb5::CredentialsCache.new
|
132
|
+
assert_false(@ccache.destroy)
|
133
|
+
end
|
134
|
+
|
135
|
+
test "calling a method on a destroyed object raises an error" do
|
136
|
+
@ccache = Kerberos::Krb5::CredentialsCache.new(@princ)
|
137
|
+
@ccache.destroy
|
138
|
+
assert_raise(Kerberos::Krb5::Exception){ @ccache.default_name }
|
139
|
+
end
|
140
|
+
|
141
|
+
test "destroy method does not accept any arguments" do
|
142
|
+
@ccache = Kerberos::Krb5::CredentialsCache.new(@princ)
|
143
|
+
assert_raise(ArgumentError){ @ccache.destroy(true) }
|
144
|
+
end
|
145
|
+
|
146
|
+
def teardown
|
147
|
+
@login = nil
|
148
|
+
@princ = nil
|
149
|
+
@ccache = nil
|
150
|
+
@cname = nil
|
151
|
+
Open3.popen3('kdestroy'){ sleep 0.1 } # Ignore errors and wait a tiny bit
|
152
|
+
end
|
153
|
+
end
|
data/test/test_kadm5.rb
ADDED
@@ -0,0 +1,424 @@
|
|
1
|
+
########################################################################
|
2
|
+
# test_kadm5.rb
|
3
|
+
#
|
4
|
+
# Tests for the Kerberos::Kadm5 class.
|
5
|
+
#
|
6
|
+
# This test suite requires that you have an entry in your .dbrc file
|
7
|
+
# for 'local-kerberos' which includes an admin principal, password and
|
8
|
+
# optional $KRB5_CONFIG file.
|
9
|
+
#
|
10
|
+
# Some keytab tests will fail if your local-kerberos entry is not
|
11
|
+
# also in the keytab file.
|
12
|
+
########################################################################
|
13
|
+
require 'rubygems'
|
14
|
+
gem 'test-unit'
|
15
|
+
|
16
|
+
require 'test/unit'
|
17
|
+
require 'dbi/dbrc'
|
18
|
+
require 'rkerberos'
|
19
|
+
require 'socket'
|
20
|
+
|
21
|
+
class TC_Kerberos_Kadm5 < Test::Unit::TestCase
|
22
|
+
def self.startup
|
23
|
+
@@server = Kerberos::Kadm5::Config.new.admin_server
|
24
|
+
@@info = DBI::DBRC.new('local-kerberos')
|
25
|
+
@@host = Socket.gethostname
|
26
|
+
|
27
|
+
# For local testing the FQDN may or may not be available, so let's assume
|
28
|
+
# that hosts with the same name are on the same domain.
|
29
|
+
if @@server.include?('.') && !@@host.include?('.')
|
30
|
+
@@server = @@server.split('.').first
|
31
|
+
end
|
32
|
+
|
33
|
+
ENV['KRB5_CONFIG'] = @@info.driver || ENV['KRB5_CONFIG'] || '/etc/krb5.conf'
|
34
|
+
end
|
35
|
+
|
36
|
+
def setup
|
37
|
+
@user = @@info.user
|
38
|
+
@pass = @@info.passwd
|
39
|
+
@kadm = nil
|
40
|
+
@princ = nil
|
41
|
+
@policy = nil
|
42
|
+
@test_princ = "zztop"
|
43
|
+
@test_policy = "test_policy"
|
44
|
+
|
45
|
+
@keytab = Kerberos::Krb5::Keytab.new.default_name.split(':').last
|
46
|
+
|
47
|
+
unless File.exists?(@keytab)
|
48
|
+
@keytab = '/etc/krb5.keytab'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
test "constructor basic functionality" do
|
53
|
+
assert_respond_to(Kerberos::Kadm5, :new)
|
54
|
+
end
|
55
|
+
|
56
|
+
test "constructor with valid user and password works as expected" do
|
57
|
+
assert_nothing_raised{
|
58
|
+
@kadm = Kerberos::Kadm5.new(:principal => @user, :password => @pass)
|
59
|
+
}
|
60
|
+
end
|
61
|
+
|
62
|
+
test "constructor with valid service works as expected" do
|
63
|
+
assert_nothing_raised{
|
64
|
+
@kadm = Kerberos::Kadm5.new(
|
65
|
+
:principal => @user,
|
66
|
+
:password => @pass,
|
67
|
+
:service => "kadmin/admin"
|
68
|
+
)
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
test "constructor with valid user and default keytab works as expected" do
|
73
|
+
omit_unless(@@host == @@server, "keytab on different host, skipping")
|
74
|
+
omit_unless(File.exists?(@keytab), "default keytab file '#{@keytab}' not found")
|
75
|
+
|
76
|
+
assert_nothing_raised{
|
77
|
+
@kadm = Kerberos::Kadm5.new(:principal => @user, :keytab => true)
|
78
|
+
}
|
79
|
+
end
|
80
|
+
|
81
|
+
test "constructor with valid user and explicit keytab works as expected" do
|
82
|
+
omit_unless(@@host == @@server, "keytab on different host, skipping")
|
83
|
+
omit_unless(File.exists?(@keytab), "keytab file '#{@keytab}' not found")
|
84
|
+
|
85
|
+
assert_nothing_raised{
|
86
|
+
@kadm = Kerberos::Kadm5.new(:principal => @user, :keytab => @keytab)
|
87
|
+
}
|
88
|
+
end
|
89
|
+
|
90
|
+
test "constructor only accepts a hash argument" do
|
91
|
+
assert_raise(TypeError){ Kerberos::Kadm5.new(@user) }
|
92
|
+
assert_raise(TypeError){ Kerberos::Kadm5.new(1) }
|
93
|
+
end
|
94
|
+
|
95
|
+
test "constructor accepts a block and yields itself" do
|
96
|
+
assert_nothing_raised{ Kerberos::Kadm5.new(:principal => @user, :password => @pass){} }
|
97
|
+
Kerberos::Kadm5.new(:principal => @user, :password => @pass){ |kadm5|
|
98
|
+
assert_kind_of(Kerberos::Kadm5, kadm5)
|
99
|
+
}
|
100
|
+
end
|
101
|
+
|
102
|
+
test "principal must be specified" do
|
103
|
+
assert_raise(ArgumentError){ Kerberos::Kadm5.new({}) }
|
104
|
+
assert_raise_message("principal must be specified"){ Kerberos::Kadm5.new({}) }
|
105
|
+
end
|
106
|
+
|
107
|
+
test "principal value must be a string" do
|
108
|
+
assert_raise(TypeError){ Kerberos::Kadm5.new(:principal => 1) }
|
109
|
+
end
|
110
|
+
|
111
|
+
test "password value must be a string" do
|
112
|
+
assert_raise(TypeError){ Kerberos::Kadm5.new(:principal => @user, :password => 1) }
|
113
|
+
end
|
114
|
+
|
115
|
+
test "keytab value must be a string or a boolean" do
|
116
|
+
assert_raise(TypeError){ Kerberos::Kadm5.new(:principal => @user, :keytab => 1) }
|
117
|
+
end
|
118
|
+
|
119
|
+
test "service value must be a string" do
|
120
|
+
assert_raise(TypeError){
|
121
|
+
Kerberos::Kadm5.new(:principal => @user, :password => @pass, :service => 1)
|
122
|
+
}
|
123
|
+
end
|
124
|
+
|
125
|
+
test "an error is raised if an invalid service name is used" do
|
126
|
+
assert_raise(Kerberos::Kadm5::Exception){
|
127
|
+
Kerberos::Kadm5.new(:principal => @user, :password => @pass, :service => 'bogus')
|
128
|
+
}
|
129
|
+
end
|
130
|
+
|
131
|
+
test "an error is raised if both a keytab and a password are provided" do
|
132
|
+
assert_raise(ArgumentError){
|
133
|
+
Kerberos::Kadm5.new(:principal => @user, :keytab => true, :password => "xxx")
|
134
|
+
}
|
135
|
+
assert_raise_message("cannot use both a password and a keytab"){
|
136
|
+
Kerberos::Kadm5.new(:principal => @user, :keytab => true, :password => "xxx")
|
137
|
+
}
|
138
|
+
end
|
139
|
+
|
140
|
+
test "constructor with invalid user or password raises an error" do
|
141
|
+
assert_raise(Kerberos::Kadm5::Exception){
|
142
|
+
Kerberos::Kadm5.new(:principal => @user, :password => 'bogus')
|
143
|
+
}
|
144
|
+
assert_raise(Kerberos::Kadm5::Exception){
|
145
|
+
Kerberos::Kadm5.new(:principal => 'bogus', :password => @pass)
|
146
|
+
}
|
147
|
+
end
|
148
|
+
|
149
|
+
test "constructor with invalid user or password raises a specific error message" do
|
150
|
+
assert_raise_message('kadm5_init_with_password: Incorrect password'){
|
151
|
+
Kerberos::Kadm5.new(:principal => @user, :password => 'bogus')
|
152
|
+
}
|
153
|
+
assert_raise_message('kadm5_init_with_password: Client not found in Kerberos database'){
|
154
|
+
Kerberos::Kadm5.new(:principal => 'bogus', :password => @pass)
|
155
|
+
}
|
156
|
+
end
|
157
|
+
|
158
|
+
test "set_password basic functionality" do
|
159
|
+
@kadm5 = Kerberos::Kadm5.new(:principal => @user, :password => @pass)
|
160
|
+
assert_respond_to(@kadm5, :set_password)
|
161
|
+
end
|
162
|
+
|
163
|
+
test "set_password requires two arguments" do
|
164
|
+
@kadm5 = Kerberos::Kadm5.new(:principal => @user, :password => @pass)
|
165
|
+
assert_raise(ArgumentError){ @kadm5.set_password }
|
166
|
+
assert_raise(ArgumentError){ @kadm5.set_password('user') }
|
167
|
+
assert_raise(ArgumentError){ @kadm5.set_password('user', 'xxx', 'yyy') }
|
168
|
+
end
|
169
|
+
|
170
|
+
test "set_password requires string arguments" do
|
171
|
+
@kadm5 = Kerberos::Kadm5.new(:principal => @user, :password => @pass)
|
172
|
+
assert_raise(TypeError){ @kadm5.set_password('user',2) }
|
173
|
+
assert_raise(TypeError){ @kadm5.set_password(1, 'xxxx') }
|
174
|
+
end
|
175
|
+
|
176
|
+
test "attempting to set the password for an invalid user raises an error" do
|
177
|
+
@kadm5 = Kerberos::Kadm5.new(:principal => @user, :password => @pass)
|
178
|
+
assert_raise(Kerberos::Kadm5::Exception){ @kadm5.set_password('bogususer', 'xxxyyy') }
|
179
|
+
end
|
180
|
+
|
181
|
+
### Policy
|
182
|
+
|
183
|
+
test "create_policy basic functionality" do
|
184
|
+
@kadm = Kerberos::Kadm5.new(:principal => @user, :password => @pass)
|
185
|
+
assert_respond_to(@kadm, :create_policy)
|
186
|
+
end
|
187
|
+
|
188
|
+
test "create_policy accepts a Policy object" do
|
189
|
+
hash = {:name => @test_policy, :min_length => 5, :max_life => 10000, :min_classes => 2}
|
190
|
+
policy = Kerberos::Kadm5::Policy.new(hash)
|
191
|
+
assert_nothing_raised{ @kadm = Kerberos::Kadm5.new(:principal => @user, :password => @pass) }
|
192
|
+
assert_nothing_raised{ @kadm.create_policy(policy) }
|
193
|
+
end
|
194
|
+
|
195
|
+
test "create_policy accepts a hash" do
|
196
|
+
hash = {:name => @test_policy, :min_length => 5, :max_life => 10000, :min_classes => 2}
|
197
|
+
assert_nothing_raised{ @kadm = Kerberos::Kadm5.new(:principal => @user, :password => @pass) }
|
198
|
+
assert_nothing_raised{ @kadm.create_policy(hash) }
|
199
|
+
end
|
200
|
+
|
201
|
+
test "policy can be found after creation" do
|
202
|
+
hash = {:name => @test_policy, :min_length => 5, :max_life => 10000, :min_classes => 2}
|
203
|
+
@kadm = Kerberos::Kadm5.new(:principal => @user, :password => @pass)
|
204
|
+
@kadm.create_policy(hash)
|
205
|
+
assert_nothing_raised{ @kadm.get_policy(@test_policy) }
|
206
|
+
end
|
207
|
+
|
208
|
+
test "create_policy only accepts one argument" do
|
209
|
+
hash = {:name => @test_policy, :min_length => 5, :max_life => 10000, :min_classes => 2}
|
210
|
+
@kadm = Kerberos::Kadm5.new(:principal => @user, :password => @pass)
|
211
|
+
assert_raise(ArgumentError){ @kadm.create_policy(hash, hash) }
|
212
|
+
end
|
213
|
+
|
214
|
+
test "attempting to create a policy that already exists raises an error" do
|
215
|
+
hash = {:name => @test_policy, :min_length => 5, :max_life => 10000, :min_classes => 2}
|
216
|
+
@kadm = Kerberos::Kadm5.new(:principal => @user, :password => @pass)
|
217
|
+
assert_nothing_raised{ @kadm.create_policy(hash) }
|
218
|
+
assert_raise(Kerberos::Kadm5::Exception){ @kadm.create_policy(hash) }
|
219
|
+
end
|
220
|
+
|
221
|
+
test "delete_policy basic functionality" do
|
222
|
+
@kadm = Kerberos::Kadm5.new(:principal => @user, :password => @pass)
|
223
|
+
assert_respond_to(@kadm, :delete_policy)
|
224
|
+
end
|
225
|
+
|
226
|
+
test "delete_policy works as expected" do
|
227
|
+
@kadm = Kerberos::Kadm5.new(:principal => @user, :password => @pass)
|
228
|
+
assert_nothing_raised{ @kadm.create_policy(:name => @test_policy) }
|
229
|
+
assert_nothing_raised{ @kadm.delete_policy(@test_policy) }
|
230
|
+
end
|
231
|
+
|
232
|
+
test "delete_policy takes one argument and only one argument" do
|
233
|
+
@kadm = Kerberos::Kadm5.new(:principal => @user, :password => @pass)
|
234
|
+
assert_raise(ArgumentError){ @kadm.delete_policy }
|
235
|
+
assert_raise(ArgumentError){ @kadm.delete_policy(@test_policy, @test_policy) }
|
236
|
+
end
|
237
|
+
|
238
|
+
### Principal
|
239
|
+
|
240
|
+
test "create_principal basic functionality" do
|
241
|
+
@kadm = Kerberos::Kadm5.new(:principal => @user, :password => @pass)
|
242
|
+
assert_respond_to(@kadm, :create_principal)
|
243
|
+
end
|
244
|
+
|
245
|
+
test "create_principal creates a user as expected" do
|
246
|
+
assert_nothing_raised{ @kadm = Kerberos::Kadm5.new(:principal => @user, :password => @pass) }
|
247
|
+
assert_nothing_raised{ @kadm.create_principal(@test_princ, "changeme") }
|
248
|
+
end
|
249
|
+
|
250
|
+
test "create_principal requires two arguments" do
|
251
|
+
assert_nothing_raised{ @kadm = Kerberos::Kadm5.new(:principal => @user, :password => @pass) }
|
252
|
+
assert_raise(ArgumentError){ @kadm.create_principal }
|
253
|
+
assert_raise(ArgumentError){ @kadm.create_principal(@user) }
|
254
|
+
assert_raise(ArgumentError){ @kadm.create_principal(@user, @pass, @pass) }
|
255
|
+
end
|
256
|
+
|
257
|
+
test "attempting to create a principal that already exists raises an error" do
|
258
|
+
assert_nothing_raised{ @kadm = Kerberos::Kadm5.new(:principal => @user, :password => @pass) }
|
259
|
+
assert_nothing_raised{ @kadm.create_principal(@test_princ, "changeme") }
|
260
|
+
assert_raise(Kerberos::Kadm5::Exception){ @kadm.create_principal(@test_princ, "changeme") }
|
261
|
+
end
|
262
|
+
|
263
|
+
test "delete_principal basic functionality" do
|
264
|
+
assert_nothing_raised{ @kadm = Kerberos::Kadm5.new(:principal => @user, :password => @pass) }
|
265
|
+
assert_respond_to(@kadm, :delete_principal)
|
266
|
+
end
|
267
|
+
|
268
|
+
test "delete_principal works as expected" do
|
269
|
+
assert_nothing_raised{ @kadm = Kerberos::Kadm5.new(:principal => @user, :password => @pass) }
|
270
|
+
assert_nothing_raised{ @kadm.create_principal(@test_princ, "changeme") }
|
271
|
+
assert_nothing_raised{ @kadm.delete_principal(@test_princ) }
|
272
|
+
end
|
273
|
+
|
274
|
+
test "delete_principal takes one argument and only one argument" do
|
275
|
+
assert_nothing_raised{ @kadm = Kerberos::Kadm5.new(:principal => @user, :password => @pass) }
|
276
|
+
assert_raise(ArgumentError){ @kadm.delete_principal }
|
277
|
+
assert_raise(ArgumentError){ @kadm.delete_principal(@user, @pass) }
|
278
|
+
end
|
279
|
+
|
280
|
+
test "find_principal basic functionality" do
|
281
|
+
assert_nothing_raised{ @kadm = Kerberos::Kadm5.new(:principal => @user, :password => @pass) }
|
282
|
+
assert_respond_to(@kadm, :find_principal)
|
283
|
+
end
|
284
|
+
|
285
|
+
test "find_principal returns a Struct::Principal object if found" do
|
286
|
+
assert_nothing_raised{ @kadm = Kerberos::Kadm5.new(:principal => @user, :password => @pass) }
|
287
|
+
assert_nothing_raised{ @kadm.create_principal(@test_princ, "changeme") }
|
288
|
+
assert_nothing_raised{ @princ = @kadm.find_principal(@test_princ) }
|
289
|
+
assert_kind_of(Kerberos::Krb5::Principal, @princ)
|
290
|
+
end
|
291
|
+
|
292
|
+
test "find_principal returns nil if not found" do
|
293
|
+
assert_nothing_raised{ @kadm = Kerberos::Kadm5.new(:principal => @user, :password => @pass) }
|
294
|
+
assert_nil(@kadm.find_principal('bogus'))
|
295
|
+
end
|
296
|
+
|
297
|
+
test "find_principal requires a string argument" do
|
298
|
+
assert_nothing_raised{ @kadm = Kerberos::Kadm5.new(:principal => @user, :password => @pass) }
|
299
|
+
assert_raise(TypeError){ @kadm.find_principal(1) }
|
300
|
+
end
|
301
|
+
|
302
|
+
test "find_principal requires one and only one argument" do
|
303
|
+
assert_nothing_raised{ @kadm = Kerberos::Kadm5.new(:principal => @user, :password => @pass) }
|
304
|
+
assert_raise(ArgumentError){ @kadm.find_principal }
|
305
|
+
assert_raise(ArgumentError){ @kadm.find_principal(@user, @user) }
|
306
|
+
end
|
307
|
+
|
308
|
+
test "generate_random_key basic functionality" do
|
309
|
+
@kadm = Kerberos::Kadm5.new(:principal => @user, :password => @pass)
|
310
|
+
@kadm.create_principal(@test_princ, "changeme")
|
311
|
+
assert_respond_to(@kadm, :generate_random_key)
|
312
|
+
assert_nothing_raised{ @kadm.generate_random_key(@test_princ) }
|
313
|
+
end
|
314
|
+
|
315
|
+
test "generate_random_key returns the number of keys generated" do
|
316
|
+
@kadm = Kerberos::Kadm5.new(:principal => @user, :password => @pass)
|
317
|
+
@kadm.create_principal(@test_princ, "changeme")
|
318
|
+
assert_kind_of(Fixnum, @kadm.generate_random_key(@test_princ))
|
319
|
+
assert_true(@kadm.generate_random_key(@test_princ) > 0)
|
320
|
+
end
|
321
|
+
|
322
|
+
test "generate_random_key requires one argument" do
|
323
|
+
@kadm = Kerberos::Kadm5.new(:principal => @user, :password => @pass)
|
324
|
+
assert_raise(ArgumentError){ @kadm.generate_random_key }
|
325
|
+
assert_raise(ArgumentError){ @kadm.generate_random_key(@test_princ, @test_princ) }
|
326
|
+
end
|
327
|
+
|
328
|
+
test "generate_random_key requires a string argument" do
|
329
|
+
@kadm = Kerberos::Kadm5.new(:principal => @user, :password => @pass)
|
330
|
+
assert_raise(TypeError){ @kadm.generate_random_key(7) }
|
331
|
+
end
|
332
|
+
|
333
|
+
test "generate_random_key raises an error if the principal cannot be found" do
|
334
|
+
@kadm = Kerberos::Kadm5.new(:principal => @user, :password => @pass)
|
335
|
+
assert_raise(Kerberos::Kadm5::Exception){ @kadm.generate_random_key('bogus') }
|
336
|
+
end
|
337
|
+
|
338
|
+
test "get_policy basic functionality" do
|
339
|
+
assert_nothing_raised{ @kadm = Kerberos::Kadm5.new(:principal => @user, :password => @pass) }
|
340
|
+
assert_respond_to(@kadm, :get_policy)
|
341
|
+
end
|
342
|
+
|
343
|
+
test "get_policy returns a Policy object if found" do
|
344
|
+
assert_nothing_raised{ @kadm = Kerberos::Kadm5.new(:principal => @user, :password => @pass) }
|
345
|
+
assert_nothing_raised{ @kadm.create_policy(:name => @test_policy, :min_length => 5) }
|
346
|
+
assert_nothing_raised{ @policy = @kadm.get_policy(@test_policy) }
|
347
|
+
assert_kind_of(Kerberos::Kadm5::Policy, @policy)
|
348
|
+
end
|
349
|
+
|
350
|
+
test "get_principal basic functionality" do
|
351
|
+
assert_nothing_raised{ @kadm = Kerberos::Kadm5.new(:principal => @user, :password => @pass) }
|
352
|
+
assert_respond_to(@kadm, :get_principal)
|
353
|
+
end
|
354
|
+
|
355
|
+
test "get_principal returns a Struct::Principal object if found" do
|
356
|
+
assert_nothing_raised{ @kadm = Kerberos::Kadm5.new(:principal => @user, :password => @pass) }
|
357
|
+
assert_nothing_raised{ @kadm.create_principal(@test_princ, "changeme") }
|
358
|
+
assert_nothing_raised{ @princ = @kadm.get_principal(@test_princ) }
|
359
|
+
assert_kind_of(Kerberos::Krb5::Principal, @princ)
|
360
|
+
end
|
361
|
+
|
362
|
+
test "get_principal raises an error if not found" do
|
363
|
+
assert_nothing_raised{ @kadm = Kerberos::Kadm5.new(:principal => @user, :password => @pass) }
|
364
|
+
assert_raise(Kerberos::Kadm5::PrincipalNotFoundException){ @kadm.get_principal('bogus') }
|
365
|
+
end
|
366
|
+
|
367
|
+
test "get_principal requires a string argument" do
|
368
|
+
assert_nothing_raised{ @kadm = Kerberos::Kadm5.new(:principal => @user, :password => @pass) }
|
369
|
+
assert_raise(TypeError){ @kadm.get_principal(1) }
|
370
|
+
end
|
371
|
+
|
372
|
+
test "get_principal requires one and only one argument" do
|
373
|
+
assert_nothing_raised{ @kadm = Kerberos::Kadm5.new(:principal => @user, :password => @pass) }
|
374
|
+
assert_raise(ArgumentError){ @kadm.get_principal }
|
375
|
+
assert_raise(ArgumentError){ @kadm.get_principal(@user, @user) }
|
376
|
+
end
|
377
|
+
|
378
|
+
test "close basic functionality" do
|
379
|
+
assert_nothing_raised{ @kadm = Kerberos::Kadm5.new(:principal => @user, :password => @pass) }
|
380
|
+
assert_respond_to(@kadm, :close)
|
381
|
+
assert_nothing_raised{ @kadm.close }
|
382
|
+
end
|
383
|
+
|
384
|
+
test "calling close multiple times is a no-op" do
|
385
|
+
assert_nothing_raised{ @kadm = Kerberos::Kadm5.new(:principal => @user, :password => @pass) }
|
386
|
+
assert_nothing_raised{ @kadm.close }
|
387
|
+
assert_nothing_raised{ @kadm.close }
|
388
|
+
assert_nothing_raised{ @kadm.close }
|
389
|
+
end
|
390
|
+
|
391
|
+
test "close does not accept any arguments" do
|
392
|
+
@kadm = Kerberos::Kadm5.new(:principal => @user, :password => @pass)
|
393
|
+
assert_raise(ArgumentError){ @kadm.close(1) }
|
394
|
+
end
|
395
|
+
|
396
|
+
test "calling close on an already closed object raises an error" do
|
397
|
+
@kadm = Kerberos::Kadm5.new(:principal => @user, :password => @pass)
|
398
|
+
@kadm.create_principal(@test_princ, "changeme")
|
399
|
+
@kadm.close
|
400
|
+
|
401
|
+
assert_raise(Kerberos::Kadm5::Exception){ @kadm.get_principal(@test_princ) }
|
402
|
+
assert_raise_message('no context has been established'){ @kadm.get_principal(@test_princ) }
|
403
|
+
end
|
404
|
+
|
405
|
+
def teardown
|
406
|
+
if @kadm
|
407
|
+
@kadm.delete_principal(@test_princ) rescue nil
|
408
|
+
@kadm.delete_policy(@test_policy) rescue nil
|
409
|
+
@kadm.close
|
410
|
+
end
|
411
|
+
|
412
|
+
@user = nil
|
413
|
+
@pass = nil
|
414
|
+
@kadm = nil
|
415
|
+
@princ = nil
|
416
|
+
@policy = nil
|
417
|
+
end
|
418
|
+
|
419
|
+
def self.shutdown
|
420
|
+
@@host = nil
|
421
|
+
@@info = nil
|
422
|
+
@@server = nil
|
423
|
+
end
|
424
|
+
end
|