win32-file-security 1.0.6 → 1.0.7
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
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +2 -0
- data/CHANGES +45 -36
- data/MANIFEST +18 -16
- data/README +47 -47
- data/Rakefile +66 -69
- data/appveyor.yml +50 -0
- data/certs/djberg96_pub.pem +21 -0
- data/lib/win32-file-security.rb +1 -0
- data/lib/win32/file/security.rb +959 -959
- data/lib/win32/file/security/constants.rb +149 -149
- data/lib/win32/file/security/functions.rb +63 -63
- data/lib/win32/file/security/helper.rb +23 -23
- data/lib/win32/file/security/structs.rb +68 -68
- data/test/test_win32_file_security_acls.rb +34 -28
- data/test/test_win32_file_security_constants.rb +54 -54
- data/test/test_win32_file_security_encryption.rb +90 -90
- data/test/test_win32_file_security_ffi.rb +33 -33
- data/test/test_win32_file_security_ownership.rb +174 -174
- data/test/test_win32_file_security_permissions.rb +88 -87
- data/test/test_win32_file_security_version.rb +13 -13
- data/win32-file-security.gemspec +27 -27
- metadata +30 -5
- metadata.gz.sig +0 -0
@@ -1,68 +1,68 @@
|
|
1
|
-
require 'ffi'
|
2
|
-
|
3
|
-
module Windows
|
4
|
-
module File
|
5
|
-
module Structs
|
6
|
-
class ACE_HEADER < FFI::Struct
|
7
|
-
layout(
|
8
|
-
:AceType, :uchar,
|
9
|
-
:AceFlags, :uchar,
|
10
|
-
:AceSize, :ushort
|
11
|
-
)
|
12
|
-
end
|
13
|
-
|
14
|
-
class ACCESS_ALLOWED_ACE < FFI::Struct
|
15
|
-
layout(
|
16
|
-
:Header, ACE_HEADER,
|
17
|
-
:Mask, :ulong,
|
18
|
-
:SidStart, :ulong
|
19
|
-
)
|
20
|
-
end
|
21
|
-
|
22
|
-
class ACCESS_ALLOWED_ACE2 < FFI::Struct
|
23
|
-
layout(
|
24
|
-
:Header, ACE_HEADER,
|
25
|
-
:Mask, :ulong,
|
26
|
-
:SidStart, :ulong,
|
27
|
-
:dummy, [:uchar, 40]
|
28
|
-
)
|
29
|
-
end
|
30
|
-
|
31
|
-
class ACL < FFI::Struct
|
32
|
-
layout(
|
33
|
-
:AclRevision, :uchar,
|
34
|
-
:Sbz1, :uchar,
|
35
|
-
:AclSize, :ushort,
|
36
|
-
:AceCount, :ushort,
|
37
|
-
:Sbz2, :ushort
|
38
|
-
)
|
39
|
-
end
|
40
|
-
|
41
|
-
class LUID < FFI::Struct
|
42
|
-
layout(:LowPart, :ulong, :HighPart, :long)
|
43
|
-
end
|
44
|
-
|
45
|
-
class LUID_AND_ATTRIBUTES < FFI::Struct
|
46
|
-
layout(:Luid, LUID, :Attributes, :ulong)
|
47
|
-
end
|
48
|
-
|
49
|
-
class TOKEN_PRIVILEGES < FFI::Struct
|
50
|
-
layout(
|
51
|
-
:PrivilegeCount, :ulong,
|
52
|
-
:Privileges, [LUID_AND_ATTRIBUTES, 1]
|
53
|
-
)
|
54
|
-
end
|
55
|
-
|
56
|
-
class SID_AND_ATTRIBUTES < FFI::Struct
|
57
|
-
layout(:Sid, :pointer, :Attributes, :ulong)
|
58
|
-
end
|
59
|
-
|
60
|
-
class TOKEN_GROUP < FFI::Struct
|
61
|
-
layout(
|
62
|
-
:GroupCount, :ulong,
|
63
|
-
:Groups, [SID_AND_ATTRIBUTES, 128]
|
64
|
-
)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
1
|
+
require 'ffi'
|
2
|
+
|
3
|
+
module Windows
|
4
|
+
module File
|
5
|
+
module Structs
|
6
|
+
class ACE_HEADER < FFI::Struct
|
7
|
+
layout(
|
8
|
+
:AceType, :uchar,
|
9
|
+
:AceFlags, :uchar,
|
10
|
+
:AceSize, :ushort
|
11
|
+
)
|
12
|
+
end
|
13
|
+
|
14
|
+
class ACCESS_ALLOWED_ACE < FFI::Struct
|
15
|
+
layout(
|
16
|
+
:Header, ACE_HEADER,
|
17
|
+
:Mask, :ulong,
|
18
|
+
:SidStart, :ulong
|
19
|
+
)
|
20
|
+
end
|
21
|
+
|
22
|
+
class ACCESS_ALLOWED_ACE2 < FFI::Struct
|
23
|
+
layout(
|
24
|
+
:Header, ACE_HEADER,
|
25
|
+
:Mask, :ulong,
|
26
|
+
:SidStart, :ulong,
|
27
|
+
:dummy, [:uchar, 40]
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
class ACL < FFI::Struct
|
32
|
+
layout(
|
33
|
+
:AclRevision, :uchar,
|
34
|
+
:Sbz1, :uchar,
|
35
|
+
:AclSize, :ushort,
|
36
|
+
:AceCount, :ushort,
|
37
|
+
:Sbz2, :ushort
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
class LUID < FFI::Struct
|
42
|
+
layout(:LowPart, :ulong, :HighPart, :long)
|
43
|
+
end
|
44
|
+
|
45
|
+
class LUID_AND_ATTRIBUTES < FFI::Struct
|
46
|
+
layout(:Luid, LUID, :Attributes, :ulong)
|
47
|
+
end
|
48
|
+
|
49
|
+
class TOKEN_PRIVILEGES < FFI::Struct
|
50
|
+
layout(
|
51
|
+
:PrivilegeCount, :ulong,
|
52
|
+
:Privileges, [LUID_AND_ATTRIBUTES, 1]
|
53
|
+
)
|
54
|
+
end
|
55
|
+
|
56
|
+
class SID_AND_ATTRIBUTES < FFI::Struct
|
57
|
+
layout(:Sid, :pointer, :Attributes, :ulong)
|
58
|
+
end
|
59
|
+
|
60
|
+
class TOKEN_GROUP < FFI::Struct
|
61
|
+
layout(
|
62
|
+
:GroupCount, :ulong,
|
63
|
+
:Groups, [SID_AND_ATTRIBUTES, 128]
|
64
|
+
)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -1,28 +1,34 @@
|
|
1
|
-
##############################################################################
|
2
|
-
# test_win32_file_acls.rb
|
3
|
-
#
|
4
|
-
# Test case for the File.supports_acls? method.
|
5
|
-
##############################################################################
|
6
|
-
require 'test-unit'
|
7
|
-
require 'win32/file/security'
|
8
|
-
require 'socket'
|
9
|
-
require 'etc'
|
10
|
-
|
11
|
-
class TC_Win32_File_Security_ACLS < Test::Unit::TestCase
|
12
|
-
def setup
|
13
|
-
@dir = "C:/"
|
14
|
-
end
|
15
|
-
|
16
|
-
test "supports_acls? basic functionality" do
|
17
|
-
assert_respond_to(File, :supports_acls?)
|
18
|
-
assert_boolean(File.supports_acls?
|
19
|
-
end
|
20
|
-
|
21
|
-
test "supports_acls? returns the expected results" do
|
22
|
-
assert_true(File.supports_acls?
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
1
|
+
##############################################################################
|
2
|
+
# test_win32_file_acls.rb
|
3
|
+
#
|
4
|
+
# Test case for the File.supports_acls? method.
|
5
|
+
##############################################################################
|
6
|
+
require 'test-unit'
|
7
|
+
require 'win32/file/security'
|
8
|
+
require 'socket'
|
9
|
+
require 'etc'
|
10
|
+
|
11
|
+
class TC_Win32_File_Security_ACLS < Test::Unit::TestCase
|
12
|
+
def setup
|
13
|
+
@dir = "C:/"
|
14
|
+
end
|
15
|
+
|
16
|
+
test "supports_acls? basic functionality" do
|
17
|
+
assert_respond_to(File, :supports_acls?)
|
18
|
+
assert_boolean(File.supports_acls?)
|
19
|
+
end
|
20
|
+
|
21
|
+
test "supports_acls? returns the expected results" do
|
22
|
+
assert_true(File.supports_acls?)
|
23
|
+
assert_true(File.supports_acls?(@dir))
|
24
|
+
end
|
25
|
+
|
26
|
+
test "supports_acls? takes an optional file name" do
|
27
|
+
assert_nothing_raised{ File.supports_acls?(@dir) }
|
28
|
+
assert_boolean(File.supports_acls?(@dir))
|
29
|
+
end
|
30
|
+
|
31
|
+
def teardown
|
32
|
+
@perms = nil
|
33
|
+
end
|
34
|
+
end
|
@@ -1,54 +1,54 @@
|
|
1
|
-
########################################################################
|
2
|
-
# test_win32_file_security_constants.rb
|
3
|
-
#
|
4
|
-
# Tests to ensure that certain constants are defined for the
|
5
|
-
# win32-file-security library.
|
6
|
-
########################################################################
|
7
|
-
require 'test-unit'
|
8
|
-
require 'win32/file/security'
|
9
|
-
|
10
|
-
class TC_Win32_File_Constants < Test::Unit::TestCase
|
11
|
-
test "file security rights constants are defined" do
|
12
|
-
assert_not_nil(File::FILE_READ_DATA)
|
13
|
-
assert_not_nil(File::FILE_WRITE_DATA)
|
14
|
-
assert_not_nil(File::FILE_APPEND_DATA)
|
15
|
-
assert_not_nil(File::FILE_READ_EA)
|
16
|
-
assert_not_nil(File::FILE_EXECUTE)
|
17
|
-
assert_not_nil(File::FILE_DELETE_CHILD)
|
18
|
-
assert_not_nil(File::FILE_READ_ATTRIBUTES)
|
19
|
-
assert_not_nil(File::FILE_WRITE_ATTRIBUTES)
|
20
|
-
end
|
21
|
-
|
22
|
-
test "standard security rights constants are defined" do
|
23
|
-
assert_not_nil(File::STANDARD_RIGHTS_ALL)
|
24
|
-
assert_not_nil(File::STANDARD_RIGHTS_REQUIRED)
|
25
|
-
assert_not_nil(File::STANDARD_RIGHTS_READ)
|
26
|
-
assert_not_nil(File::STANDARD_RIGHTS_WRITE)
|
27
|
-
assert_not_nil(File::STANDARD_RIGHTS_EXECUTE)
|
28
|
-
end
|
29
|
-
|
30
|
-
test "generic security rights constants are defined" do
|
31
|
-
assert_not_nil(File::GENERIC_READ)
|
32
|
-
assert_not_nil(File::GENERIC_WRITE)
|
33
|
-
assert_not_nil(File::GENERIC_EXECUTE)
|
34
|
-
assert_not_nil(File::GENERIC_ALL)
|
35
|
-
end
|
36
|
-
|
37
|
-
test "combined security rights constants are defined" do
|
38
|
-
assert_not_nil(File::FULL)
|
39
|
-
assert_not_nil(File::READ)
|
40
|
-
assert_not_nil(File::CHANGE)
|
41
|
-
assert_not_nil(File::ADD)
|
42
|
-
assert_not_nil(File::DELETE)
|
43
|
-
end
|
44
|
-
|
45
|
-
test "miscellaneous security rights constants are defined" do
|
46
|
-
assert_not_nil(File::READ_CONTROL)
|
47
|
-
assert_not_nil(File::WRITE_DAC)
|
48
|
-
assert_not_nil(File::WRITE_OWNER)
|
49
|
-
assert_not_nil(File::SYNCHRONIZE)
|
50
|
-
assert_not_nil(File::SPECIFIC_RIGHTS_ALL)
|
51
|
-
assert_not_nil(File::ACCESS_SYSTEM_SECURITY)
|
52
|
-
assert_not_nil(File::MAXIMUM_ALLOWED)
|
53
|
-
end
|
54
|
-
end
|
1
|
+
########################################################################
|
2
|
+
# test_win32_file_security_constants.rb
|
3
|
+
#
|
4
|
+
# Tests to ensure that certain constants are defined for the
|
5
|
+
# win32-file-security library.
|
6
|
+
########################################################################
|
7
|
+
require 'test-unit'
|
8
|
+
require 'win32/file/security'
|
9
|
+
|
10
|
+
class TC_Win32_File_Constants < Test::Unit::TestCase
|
11
|
+
test "file security rights constants are defined" do
|
12
|
+
assert_not_nil(File::FILE_READ_DATA)
|
13
|
+
assert_not_nil(File::FILE_WRITE_DATA)
|
14
|
+
assert_not_nil(File::FILE_APPEND_DATA)
|
15
|
+
assert_not_nil(File::FILE_READ_EA)
|
16
|
+
assert_not_nil(File::FILE_EXECUTE)
|
17
|
+
assert_not_nil(File::FILE_DELETE_CHILD)
|
18
|
+
assert_not_nil(File::FILE_READ_ATTRIBUTES)
|
19
|
+
assert_not_nil(File::FILE_WRITE_ATTRIBUTES)
|
20
|
+
end
|
21
|
+
|
22
|
+
test "standard security rights constants are defined" do
|
23
|
+
assert_not_nil(File::STANDARD_RIGHTS_ALL)
|
24
|
+
assert_not_nil(File::STANDARD_RIGHTS_REQUIRED)
|
25
|
+
assert_not_nil(File::STANDARD_RIGHTS_READ)
|
26
|
+
assert_not_nil(File::STANDARD_RIGHTS_WRITE)
|
27
|
+
assert_not_nil(File::STANDARD_RIGHTS_EXECUTE)
|
28
|
+
end
|
29
|
+
|
30
|
+
test "generic security rights constants are defined" do
|
31
|
+
assert_not_nil(File::GENERIC_READ)
|
32
|
+
assert_not_nil(File::GENERIC_WRITE)
|
33
|
+
assert_not_nil(File::GENERIC_EXECUTE)
|
34
|
+
assert_not_nil(File::GENERIC_ALL)
|
35
|
+
end
|
36
|
+
|
37
|
+
test "combined security rights constants are defined" do
|
38
|
+
assert_not_nil(File::FULL)
|
39
|
+
assert_not_nil(File::READ)
|
40
|
+
assert_not_nil(File::CHANGE)
|
41
|
+
assert_not_nil(File::ADD)
|
42
|
+
assert_not_nil(File::DELETE)
|
43
|
+
end
|
44
|
+
|
45
|
+
test "miscellaneous security rights constants are defined" do
|
46
|
+
assert_not_nil(File::READ_CONTROL)
|
47
|
+
assert_not_nil(File::WRITE_DAC)
|
48
|
+
assert_not_nil(File::WRITE_OWNER)
|
49
|
+
assert_not_nil(File::SYNCHRONIZE)
|
50
|
+
assert_not_nil(File::SPECIFIC_RIGHTS_ALL)
|
51
|
+
assert_not_nil(File::ACCESS_SYSTEM_SECURITY)
|
52
|
+
assert_not_nil(File::MAXIMUM_ALLOWED)
|
53
|
+
end
|
54
|
+
end
|
@@ -1,90 +1,90 @@
|
|
1
|
-
#############################################################################
|
2
|
-
# test_win32_file_encryption.rb
|
3
|
-
#
|
4
|
-
# Test case for the encryption related methods of win32-file. You should
|
5
|
-
# run this test via the 'rake test' or 'rake test_encryption' task.
|
6
|
-
#
|
7
|
-
# Note: These tests may fail based on the security setup of your system.
|
8
|
-
#############################################################################
|
9
|
-
require 'test-unit'
|
10
|
-
require 'win32/security'
|
11
|
-
require 'win32/file/security'
|
12
|
-
require 'socket'
|
13
|
-
|
14
|
-
class TC_Win32_File_Security_Encryption < Test::Unit::TestCase
|
15
|
-
def self.startup
|
16
|
-
Dir.chdir(File.dirname(File.expand_path(File.basename(__FILE__))))
|
17
|
-
@@file = File.join(Dir.pwd, 'encryption_test.txt')
|
18
|
-
File.open(@@file, 'w'){ |fh| fh.puts "This is an encryption test." }
|
19
|
-
@@host = Socket.gethostname
|
20
|
-
end
|
21
|
-
|
22
|
-
def setup
|
23
|
-
@msg = '=> Ignore. May not work due to security setup of your system.'
|
24
|
-
@elevated = Win32::Security.elevated_security?
|
25
|
-
@statuses = ['encrypted', 'encryptable', 'unknown']
|
26
|
-
end
|
27
|
-
|
28
|
-
test "encrypt method basic functionality" do
|
29
|
-
omit_unless(@elevated)
|
30
|
-
assert_respond_to(File, :encrypt)
|
31
|
-
assert_nothing_raised(@msg){ File.encrypt(@@file) }
|
32
|
-
end
|
33
|
-
|
34
|
-
test "encrypt requires one argument" do
|
35
|
-
omit_unless(@elevated)
|
36
|
-
assert_raise(ArgumentError){ File.encrypt }
|
37
|
-
assert_raise(ArgumentError){ File.encrypt(@@file, @@file) }
|
38
|
-
end
|
39
|
-
|
40
|
-
test "encrypt requires a string argument" do
|
41
|
-
omit_unless(@elevated)
|
42
|
-
assert_raise(TypeError, NoMethodError){ File.encrypt(1) }
|
43
|
-
end
|
44
|
-
|
45
|
-
test "decrypt method basic functionality" do
|
46
|
-
omit_unless(@elevated)
|
47
|
-
assert_respond_to(File, :decrypt)
|
48
|
-
assert_nothing_raised(@msg){ File.decrypt(@@file) }
|
49
|
-
end
|
50
|
-
|
51
|
-
test "decrypt accepts a single argument only" do
|
52
|
-
omit_unless(@elevated)
|
53
|
-
assert_raise(ArgumentError){ File.decrypt }
|
54
|
-
end
|
55
|
-
|
56
|
-
test "decrypt requires a string argument" do
|
57
|
-
omit_unless(@elevated)
|
58
|
-
assert_raise(TypeError, NoMethodError){ File.decrypt(1) }
|
59
|
-
end
|
60
|
-
|
61
|
-
test "encryptable? basic functionality" do
|
62
|
-
assert_respond_to(File, :encryptable?)
|
63
|
-
end
|
64
|
-
|
65
|
-
test "encryptable? returns a boolean value" do
|
66
|
-
assert_boolean(File.encryptable?("C:\\"))
|
67
|
-
end
|
68
|
-
|
69
|
-
test "encryption_status basic functionality" do
|
70
|
-
assert_respond_to(File, :encryption_status)
|
71
|
-
end
|
72
|
-
|
73
|
-
test "encryption_status returns the expected result" do
|
74
|
-
status = File.encryption_status(@@file)
|
75
|
-
assert_kind_of(String, status)
|
76
|
-
assert_true(@statuses.include?(status))
|
77
|
-
end
|
78
|
-
|
79
|
-
def teardown
|
80
|
-
@msg = nil
|
81
|
-
@statuses = nil
|
82
|
-
@elevated = nil
|
83
|
-
end
|
84
|
-
|
85
|
-
def self.shutdown
|
86
|
-
File.delete(@@file) if File.exist?(@@file)
|
87
|
-
@@file = nil
|
88
|
-
@@host = nil
|
89
|
-
end
|
90
|
-
end
|
1
|
+
#############################################################################
|
2
|
+
# test_win32_file_encryption.rb
|
3
|
+
#
|
4
|
+
# Test case for the encryption related methods of win32-file. You should
|
5
|
+
# run this test via the 'rake test' or 'rake test_encryption' task.
|
6
|
+
#
|
7
|
+
# Note: These tests may fail based on the security setup of your system.
|
8
|
+
#############################################################################
|
9
|
+
require 'test-unit'
|
10
|
+
require 'win32/security'
|
11
|
+
require 'win32/file/security'
|
12
|
+
require 'socket'
|
13
|
+
|
14
|
+
class TC_Win32_File_Security_Encryption < Test::Unit::TestCase
|
15
|
+
def self.startup
|
16
|
+
Dir.chdir(File.dirname(File.expand_path(File.basename(__FILE__))))
|
17
|
+
@@file = File.join(Dir.pwd, 'encryption_test.txt')
|
18
|
+
File.open(@@file, 'w'){ |fh| fh.puts "This is an encryption test." }
|
19
|
+
@@host = Socket.gethostname
|
20
|
+
end
|
21
|
+
|
22
|
+
def setup
|
23
|
+
@msg = '=> Ignore. May not work due to security setup of your system.'
|
24
|
+
@elevated = Win32::Security.elevated_security?
|
25
|
+
@statuses = ['encrypted', 'encryptable', 'unknown']
|
26
|
+
end
|
27
|
+
|
28
|
+
test "encrypt method basic functionality" do
|
29
|
+
omit_unless(@elevated)
|
30
|
+
assert_respond_to(File, :encrypt)
|
31
|
+
assert_nothing_raised(@msg){ File.encrypt(@@file) }
|
32
|
+
end
|
33
|
+
|
34
|
+
test "encrypt requires one argument" do
|
35
|
+
omit_unless(@elevated)
|
36
|
+
assert_raise(ArgumentError){ File.encrypt }
|
37
|
+
assert_raise(ArgumentError){ File.encrypt(@@file, @@file) }
|
38
|
+
end
|
39
|
+
|
40
|
+
test "encrypt requires a string argument" do
|
41
|
+
omit_unless(@elevated)
|
42
|
+
assert_raise(TypeError, NoMethodError){ File.encrypt(1) }
|
43
|
+
end
|
44
|
+
|
45
|
+
test "decrypt method basic functionality" do
|
46
|
+
omit_unless(@elevated)
|
47
|
+
assert_respond_to(File, :decrypt)
|
48
|
+
assert_nothing_raised(@msg){ File.decrypt(@@file) }
|
49
|
+
end
|
50
|
+
|
51
|
+
test "decrypt accepts a single argument only" do
|
52
|
+
omit_unless(@elevated)
|
53
|
+
assert_raise(ArgumentError){ File.decrypt }
|
54
|
+
end
|
55
|
+
|
56
|
+
test "decrypt requires a string argument" do
|
57
|
+
omit_unless(@elevated)
|
58
|
+
assert_raise(TypeError, NoMethodError){ File.decrypt(1) }
|
59
|
+
end
|
60
|
+
|
61
|
+
test "encryptable? basic functionality" do
|
62
|
+
assert_respond_to(File, :encryptable?)
|
63
|
+
end
|
64
|
+
|
65
|
+
test "encryptable? returns a boolean value" do
|
66
|
+
assert_boolean(File.encryptable?("C:\\"))
|
67
|
+
end
|
68
|
+
|
69
|
+
test "encryption_status basic functionality" do
|
70
|
+
assert_respond_to(File, :encryption_status)
|
71
|
+
end
|
72
|
+
|
73
|
+
test "encryption_status returns the expected result" do
|
74
|
+
status = File.encryption_status(@@file)
|
75
|
+
assert_kind_of(String, status)
|
76
|
+
assert_true(@statuses.include?(status))
|
77
|
+
end
|
78
|
+
|
79
|
+
def teardown
|
80
|
+
@msg = nil
|
81
|
+
@statuses = nil
|
82
|
+
@elevated = nil
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.shutdown
|
86
|
+
File.delete(@@file) if File.exist?(@@file)
|
87
|
+
@@file = nil
|
88
|
+
@@host = nil
|
89
|
+
end
|
90
|
+
end
|