win32-file-security 1.0.3 → 1.0.4
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/CHANGES +6 -0
- data/README +1 -1
- data/Rakefile +7 -2
- data/lib/win32/file/security.rb +40 -28
- data/lib/win32/file/security/functions.rb +6 -8
- data/lib/win32/file/security/helper.rb +6 -0
- data/test/test_win32_file_security_ownership.rb +16 -2
- data/test/test_win32_file_security_version.rb +1 -1
- data/win32-file-security.gemspec +1 -1
- metadata +23 -32
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d0cbba9bdb2c474a89f0c9a7bfd316d11f5340ed
|
4
|
+
data.tar.gz: fe8f1a9b21770c3adefd4753bd1dde13e3b126ed
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ed0b4e85d4864cace4bd070483b4c7efbfd131c15a9c35236494ca1142d4b4cd674f31a2d2dd46f06970a8b6bb73f83b204737dab63f5775ef2ebfea1f5120d4
|
7
|
+
data.tar.gz: 31d4bec21d22a52d3f889c8631b1cf63eb61cc52317ee5356ca1816195a0b11dbdab1c379dab25d29496afe5a960a78b4d0611ecb212fbb373f971ea4f212e86
|
data/CHANGES
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
= 1.0.4 - 2-May-2014
|
2
|
+
* All methods that accept a filename argument now honor objects that implement
|
3
|
+
either to_str or to_path.
|
4
|
+
* Added some pathname tests.
|
5
|
+
* Updated the gem:create Rakefile task.
|
6
|
+
|
1
7
|
= 1.0.3 - 15-Apr-2013
|
2
8
|
* Added the File.group method.
|
3
9
|
* Added a working implementation of File.grpowned?
|
data/README
CHANGED
data/Rakefile
CHANGED
@@ -8,13 +8,18 @@ namespace :gem do
|
|
8
8
|
desc 'Build the win32-file-security gem'
|
9
9
|
task :create => [:clean] do
|
10
10
|
spec = eval(IO.read('win32-file-security.gemspec'))
|
11
|
-
Gem::
|
11
|
+
if Gem::VERSION < "2.0"
|
12
|
+
Gem::Builder.new(spec).build
|
13
|
+
else
|
14
|
+
require 'rubygems/package'
|
15
|
+
Gem::Package.build(spec)
|
16
|
+
end
|
12
17
|
end
|
13
18
|
|
14
19
|
desc "Install the win32-file-security gem"
|
15
20
|
task :install => [:create] do
|
16
21
|
file = Dir["*.gem"].first
|
17
|
-
sh "gem install #{file}"
|
22
|
+
sh "gem install -l #{file}"
|
18
23
|
end
|
19
24
|
end
|
20
25
|
|
data/lib/win32/file/security.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
require_relative 'security/constants'
|
2
|
+
require_relative 'security/structs'
|
3
|
+
require_relative 'security/functions'
|
4
|
+
require_relative 'security/helper'
|
5
5
|
require 'socket'
|
6
6
|
|
7
7
|
class File
|
@@ -12,7 +12,7 @@ class File
|
|
12
12
|
extend Windows::File::Functions
|
13
13
|
|
14
14
|
# The version of the win32-file library
|
15
|
-
WIN32_FILE_SECURITY_VERSION = '1.0.
|
15
|
+
WIN32_FILE_SECURITY_VERSION = '1.0.4'
|
16
16
|
|
17
17
|
class << self
|
18
18
|
remove_method(:chown)
|
@@ -31,7 +31,7 @@ class File
|
|
31
31
|
# * unknown
|
32
32
|
#
|
33
33
|
def encryption_status(file)
|
34
|
-
wide_file = file.wincode
|
34
|
+
wide_file = string_check(file).wincode
|
35
35
|
status_ptr = FFI::MemoryPointer.new(:ulong)
|
36
36
|
|
37
37
|
unless FileEncryptionStatusW(wide_file, status_ptr)
|
@@ -77,7 +77,7 @@ class File
|
|
77
77
|
flags_ptr = FFI::MemoryPointer.new(:ulong)
|
78
78
|
|
79
79
|
if file
|
80
|
-
file = File.expand_path(file)
|
80
|
+
file = File.expand_path(string_check(file))
|
81
81
|
wide_file = file.wincode
|
82
82
|
|
83
83
|
if !PathIsRootW(wide_file)
|
@@ -114,7 +114,7 @@ class File
|
|
114
114
|
# file is compressed the file will be decompressed before encrypting it.
|
115
115
|
#
|
116
116
|
def encrypt(file)
|
117
|
-
unless EncryptFileW(file.wincode)
|
117
|
+
unless EncryptFileW(string_check(file).wincode)
|
118
118
|
raise SystemCallError.new("EncryptFile", FFI.errno)
|
119
119
|
end
|
120
120
|
self
|
@@ -131,7 +131,7 @@ class File
|
|
131
131
|
# is NOT raised, it's simply a no-op.
|
132
132
|
#
|
133
133
|
def decrypt(file)
|
134
|
-
unless DecryptFileW(file.wincode, 0)
|
134
|
+
unless DecryptFileW(string_check(file).wincode, 0)
|
135
135
|
raise SystemCallError.new("DecryptFile", FFI.errno)
|
136
136
|
end
|
137
137
|
self
|
@@ -159,12 +159,12 @@ class File
|
|
159
159
|
# }
|
160
160
|
#
|
161
161
|
def get_permissions(file, host=nil)
|
162
|
+
wide_file = string_check(file).wincode
|
163
|
+
wide_host = host ? host.wincode : nil
|
164
|
+
|
162
165
|
size_needed_ptr = FFI::MemoryPointer.new(:ulong)
|
163
166
|
security_ptr = FFI::MemoryPointer.new(:ulong)
|
164
167
|
|
165
|
-
wide_file = file.wincode
|
166
|
-
wide_host = host ? host.wincode : nil
|
167
|
-
|
168
168
|
# First pass, get the size needed
|
169
169
|
bool = GetFileSecurityW(
|
170
170
|
wide_file,
|
@@ -262,8 +262,8 @@ class File
|
|
262
262
|
raise SystemCallError.new("LookupAccountSid", FFI.errno) unless bool
|
263
263
|
|
264
264
|
# The x2 multiplier is necessary due to wide char strings.
|
265
|
-
name = name.read_string(name_size.read_ulong * 2).
|
266
|
-
domain = domain.read_string(domain_size.read_ulong * 2).
|
265
|
+
name = name.read_string(name_size.read_ulong * 2).wstrip
|
266
|
+
domain = domain.read_string(domain_size.read_ulong * 2).wstrip
|
267
267
|
|
268
268
|
unless domain.empty?
|
269
269
|
name = domain + '\\' + name
|
@@ -321,11 +321,9 @@ class File
|
|
321
321
|
# File.set_permissions(file, "host\\userid" => File::GENERIC_ALL)
|
322
322
|
#
|
323
323
|
def set_permissions(file, perms)
|
324
|
-
|
324
|
+
wide_file = string_check(file).wincode
|
325
325
|
raise TypeError unless perms.kind_of?(Hash)
|
326
326
|
|
327
|
-
wide_file = file.wincode
|
328
|
-
|
329
327
|
account_rights = 0
|
330
328
|
sec_desc = FFI::MemoryPointer.new(:pointer, SECURITY_DESCRIPTOR_MIN_LENGTH)
|
331
329
|
|
@@ -478,8 +476,9 @@ class File
|
|
478
476
|
# This method was redefined for MS Windows.
|
479
477
|
#
|
480
478
|
def owned?(file)
|
479
|
+
wide_file = string_check(file).wincode
|
480
|
+
|
481
481
|
return_value = false
|
482
|
-
wide_file = file.wincode
|
483
482
|
size_needed_ptr = FFI::MemoryPointer.new(:ulong)
|
484
483
|
|
485
484
|
# First pass, get the size needed
|
@@ -626,7 +625,7 @@ class File
|
|
626
625
|
end
|
627
626
|
|
628
627
|
files.each{ |file|
|
629
|
-
wfile = file.wincode
|
628
|
+
wfile = string_check(file).wincode
|
630
629
|
|
631
630
|
size = FFI::MemoryPointer.new(:ulong)
|
632
631
|
sec = FFI::MemoryPointer.new(:ulong)
|
@@ -673,11 +672,12 @@ class File
|
|
673
672
|
# p File.owner('some_file.txt') # => "your_domain\\some_user"
|
674
673
|
#
|
675
674
|
def owner(file)
|
675
|
+
file = string_check(file).wincode
|
676
676
|
size_needed = FFI::MemoryPointer.new(:ulong)
|
677
677
|
|
678
678
|
# First pass, get the size needed
|
679
679
|
bool = GetFileSecurityW(
|
680
|
-
file
|
680
|
+
file,
|
681
681
|
OWNER_SECURITY_INFORMATION,
|
682
682
|
nil,
|
683
683
|
0,
|
@@ -688,7 +688,7 @@ class File
|
|
688
688
|
|
689
689
|
# Second pass, this time with the appropriately sized security pointer
|
690
690
|
bool = GetFileSecurityW(
|
691
|
-
file
|
691
|
+
file,
|
692
692
|
OWNER_SECURITY_INFORMATION,
|
693
693
|
security,
|
694
694
|
security.size,
|
@@ -723,8 +723,8 @@ class File
|
|
723
723
|
raise SystemCallError.new("LookupAccountSid", FFI.errno)
|
724
724
|
end
|
725
725
|
|
726
|
-
name = name.read_string(name.size).
|
727
|
-
domain = dom.read_string(dom.size).
|
726
|
+
name = name.read_string(name.size).wstrip
|
727
|
+
domain = dom.read_string(dom.size).wstrip
|
728
728
|
|
729
729
|
domain << "\\" << name
|
730
730
|
end
|
@@ -736,11 +736,12 @@ class File
|
|
736
736
|
# p File.group('some_file.txt') # => "your_domain\\some_group"
|
737
737
|
#
|
738
738
|
def group(file)
|
739
|
+
file = string_check(file).wincode
|
739
740
|
size_needed = FFI::MemoryPointer.new(:ulong)
|
740
741
|
|
741
742
|
# First pass, get the size needed
|
742
743
|
bool = GetFileSecurityW(
|
743
|
-
file
|
744
|
+
file,
|
744
745
|
GROUP_SECURITY_INFORMATION,
|
745
746
|
nil,
|
746
747
|
0,
|
@@ -751,7 +752,7 @@ class File
|
|
751
752
|
|
752
753
|
# Second pass, this time with the appropriately sized security pointer
|
753
754
|
bool = GetFileSecurityW(
|
754
|
-
file
|
755
|
+
file,
|
755
756
|
GROUP_SECURITY_INFORMATION,
|
756
757
|
security,
|
757
758
|
security.size,
|
@@ -786,8 +787,8 @@ class File
|
|
786
787
|
raise SystemCallError.new("LookupAccountSid", FFI.errno)
|
787
788
|
end
|
788
789
|
|
789
|
-
name = name.read_string(name.size).
|
790
|
-
domain = dom.read_string(dom.size).
|
790
|
+
name = name.read_string(name.size).wstrip
|
791
|
+
domain = dom.read_string(dom.size).wstrip
|
791
792
|
|
792
793
|
domain << "\\" << name
|
793
794
|
end
|
@@ -803,8 +804,9 @@ class File
|
|
803
804
|
# This method was redefined for MS Windows.
|
804
805
|
#
|
805
806
|
def grpowned?(file)
|
807
|
+
wide_file = string_check(file).wincode
|
808
|
+
|
806
809
|
return_value = false
|
807
|
-
wide_file = file.wincode
|
808
810
|
size_needed_ptr = FFI::MemoryPointer.new(:ulong)
|
809
811
|
|
810
812
|
# First pass, get the size needed
|
@@ -880,5 +882,15 @@ class File
|
|
880
882
|
|
881
883
|
return_value
|
882
884
|
end
|
885
|
+
|
886
|
+
private
|
887
|
+
|
888
|
+
# Simulate MRI's contortions for a stringiness check.
|
889
|
+
def string_check(arg)
|
890
|
+
return arg if arg.is_a?(String)
|
891
|
+
return arg.send(:to_str) if arg.respond_to?(:to_str, true) # MRI honors it, even if private
|
892
|
+
return arg.to_path if arg.respond_to?(:to_path)
|
893
|
+
raise TypeError
|
894
|
+
end
|
883
895
|
end
|
884
896
|
end
|
@@ -3,16 +3,14 @@ require 'ffi'
|
|
3
3
|
module Windows
|
4
4
|
module File
|
5
5
|
module Functions
|
6
|
+
extend FFI::Library
|
6
7
|
|
7
|
-
|
8
|
-
module FFI::Library
|
9
|
-
def attach_pfunc(*args)
|
10
|
-
attach_function(*args)
|
11
|
-
private args[0]
|
12
|
-
end
|
13
|
-
end
|
8
|
+
private
|
14
9
|
|
15
|
-
|
10
|
+
def self.attach_pfunc(*args)
|
11
|
+
attach_function(*args)
|
12
|
+
private args[0]
|
13
|
+
end
|
16
14
|
|
17
15
|
# For convenience
|
18
16
|
typedef :pointer, :ptr
|
@@ -4,4 +4,10 @@ class String
|
|
4
4
|
def wincode
|
5
5
|
(self.tr(File::SEPARATOR, File::ALT_SEPARATOR) + 0.chr).encode('UTF-16LE')
|
6
6
|
end
|
7
|
+
|
8
|
+
# Read a wide character string up until the first double null, and delete
|
9
|
+
# any remaining null characters.
|
10
|
+
def wstrip
|
11
|
+
self.force_encoding('UTF-16LE').encode('UTF-8',:invalid=>:replace,:undef=>:replace).split("\x00")[0].encode(Encoding.default_external)
|
12
|
+
end
|
7
13
|
end
|
@@ -9,12 +9,12 @@ require 'sys/admin'
|
|
9
9
|
require 'test-unit'
|
10
10
|
require 'win32/security'
|
11
11
|
require 'win32/file/security'
|
12
|
+
require 'pathname'
|
12
13
|
|
13
14
|
class TC_Win32_File_Security_Ownership < Test::Unit::TestCase
|
14
15
|
def self.startup
|
15
16
|
Dir.chdir(File.dirname(File.expand_path(File.basename(__FILE__))))
|
16
17
|
@@file = File.join(Dir.pwd, 'ownership_test.txt')
|
17
|
-
File.open(@@file, 'w'){ |fh| fh.puts "This is an ownership test." }
|
18
18
|
|
19
19
|
@@host = Socket.gethostname
|
20
20
|
@@temp = "Temp"
|
@@ -27,6 +27,7 @@ class TC_Win32_File_Security_Ownership < Test::Unit::TestCase
|
|
27
27
|
|
28
28
|
def setup
|
29
29
|
@elevated = Win32::Security.elevated_security?
|
30
|
+
File.open(@@file, 'w'){ |fh| fh.puts "This is an ownership test." }
|
30
31
|
end
|
31
32
|
|
32
33
|
test "owned? method basic functionality" do
|
@@ -69,6 +70,10 @@ class TC_Win32_File_Security_Ownership < Test::Unit::TestCase
|
|
69
70
|
assert_raise(ArgumentError){ File.owner(@@file, @@file) }
|
70
71
|
end
|
71
72
|
|
73
|
+
test "owner allows a pathname object" do
|
74
|
+
assert_nothing_raised{ File.owner(Pathname.new(@@file)) }
|
75
|
+
end
|
76
|
+
|
72
77
|
test "grpowned? method basic functionality" do
|
73
78
|
assert_respond_to(File, :grpowned?)
|
74
79
|
assert_nothing_raised{ File.grpowned?(@@file) }
|
@@ -104,6 +109,15 @@ class TC_Win32_File_Security_Ownership < Test::Unit::TestCase
|
|
104
109
|
assert_equal(expected, File.group(@@file))
|
105
110
|
end
|
106
111
|
|
112
|
+
test "group method allows a pathname object" do
|
113
|
+
assert_nothing_raised{ File.group(Pathname.new(@@file)) }
|
114
|
+
end
|
115
|
+
|
116
|
+
test "group method requires a stringy argument" do
|
117
|
+
assert_raise(TypeError){ File.group(nil) }
|
118
|
+
assert_raise(TypeError){ File.group([]) }
|
119
|
+
end
|
120
|
+
|
107
121
|
test "chown method basic functionality" do
|
108
122
|
assert_respond_to(File, :chown)
|
109
123
|
end
|
@@ -131,11 +145,11 @@ class TC_Win32_File_Security_Ownership < Test::Unit::TestCase
|
|
131
145
|
|
132
146
|
def teardown
|
133
147
|
@elevated = nil
|
148
|
+
File.delete(@@file) if File.exists?(@@file)
|
134
149
|
end
|
135
150
|
|
136
151
|
def self.shutdown
|
137
152
|
Sys::Admin.delete_user(@@temp) if Win32::Security.elevated_security?
|
138
|
-
File.delete(@@file) if File.exists?(@@file)
|
139
153
|
@@file = nil
|
140
154
|
@@login = nil
|
141
155
|
@@host = nil
|
@@ -8,6 +8,6 @@ require 'win32/file/security'
|
|
8
8
|
|
9
9
|
class TC_Win32_File_Security_Version < Test::Unit::TestCase
|
10
10
|
test "version is set to expected value" do
|
11
|
-
assert_equal('1.0.
|
11
|
+
assert_equal('1.0.4', File::WIN32_FILE_SECURITY_VERSION)
|
12
12
|
end
|
13
13
|
end
|
data/win32-file-security.gemspec
CHANGED
metadata
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: win32-file-security
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
5
|
-
prerelease:
|
4
|
+
version: 1.0.4
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Daniel J. Berger
|
@@ -10,75 +9,68 @@ authors:
|
|
10
9
|
autorequire:
|
11
10
|
bindir: bin
|
12
11
|
cert_chain: []
|
13
|
-
date:
|
12
|
+
date: 2014-05-03 00:00:00.000000000 Z
|
14
13
|
dependencies:
|
15
14
|
- !ruby/object:Gem::Dependency
|
16
15
|
name: ffi
|
17
16
|
requirement: !ruby/object:Gem::Requirement
|
18
|
-
none: false
|
19
17
|
requirements:
|
20
|
-
- -
|
18
|
+
- - '>='
|
21
19
|
- !ruby/object:Gem::Version
|
22
20
|
version: '0'
|
23
21
|
type: :runtime
|
24
22
|
prerelease: false
|
25
23
|
version_requirements: !ruby/object:Gem::Requirement
|
26
|
-
none: false
|
27
24
|
requirements:
|
28
|
-
- -
|
25
|
+
- - '>='
|
29
26
|
- !ruby/object:Gem::Version
|
30
27
|
version: '0'
|
31
28
|
- !ruby/object:Gem::Dependency
|
32
29
|
name: test-unit
|
33
30
|
requirement: !ruby/object:Gem::Requirement
|
34
|
-
none: false
|
35
31
|
requirements:
|
36
|
-
- -
|
32
|
+
- - '>='
|
37
33
|
- !ruby/object:Gem::Version
|
38
34
|
version: '0'
|
39
35
|
type: :development
|
40
36
|
prerelease: false
|
41
37
|
version_requirements: !ruby/object:Gem::Requirement
|
42
|
-
none: false
|
43
38
|
requirements:
|
44
|
-
- -
|
39
|
+
- - '>='
|
45
40
|
- !ruby/object:Gem::Version
|
46
41
|
version: '0'
|
47
42
|
- !ruby/object:Gem::Dependency
|
48
43
|
name: win32-security
|
49
44
|
requirement: !ruby/object:Gem::Requirement
|
50
|
-
none: false
|
51
45
|
requirements:
|
52
|
-
- -
|
46
|
+
- - '>='
|
53
47
|
- !ruby/object:Gem::Version
|
54
48
|
version: '0'
|
55
49
|
type: :development
|
56
50
|
prerelease: false
|
57
51
|
version_requirements: !ruby/object:Gem::Requirement
|
58
|
-
none: false
|
59
52
|
requirements:
|
60
|
-
- -
|
53
|
+
- - '>='
|
61
54
|
- !ruby/object:Gem::Version
|
62
55
|
version: '0'
|
63
56
|
- !ruby/object:Gem::Dependency
|
64
57
|
name: sys-admin
|
65
58
|
requirement: !ruby/object:Gem::Requirement
|
66
|
-
none: false
|
67
59
|
requirements:
|
68
|
-
- -
|
60
|
+
- - '>='
|
69
61
|
- !ruby/object:Gem::Version
|
70
62
|
version: '0'
|
71
63
|
type: :development
|
72
64
|
prerelease: false
|
73
65
|
version_requirements: !ruby/object:Gem::Requirement
|
74
|
-
none: false
|
75
66
|
requirements:
|
76
|
-
- -
|
67
|
+
- - '>='
|
77
68
|
- !ruby/object:Gem::Version
|
78
69
|
version: '0'
|
79
|
-
description:
|
80
|
-
|
81
|
-
|
70
|
+
description: |2
|
71
|
+
The win32-file-security library adds security related methods to the
|
72
|
+
core File class for MS Windows. This includes the ability to get or
|
73
|
+
set permissions, as well as encrypt or decrypt files.
|
82
74
|
email: djberg96@gmail.com
|
83
75
|
executables: []
|
84
76
|
extensions: []
|
@@ -88,14 +80,14 @@ extra_rdoc_files:
|
|
88
80
|
- MANIFEST
|
89
81
|
files:
|
90
82
|
- CHANGES
|
83
|
+
- MANIFEST
|
84
|
+
- README
|
85
|
+
- Rakefile
|
86
|
+
- lib/win32/file/security.rb
|
91
87
|
- lib/win32/file/security/constants.rb
|
92
88
|
- lib/win32/file/security/functions.rb
|
93
89
|
- lib/win32/file/security/helper.rb
|
94
90
|
- lib/win32/file/security/structs.rb
|
95
|
-
- lib/win32/file/security.rb
|
96
|
-
- MANIFEST
|
97
|
-
- Rakefile
|
98
|
-
- README
|
99
91
|
- test/test_win32_file_security_constants.rb
|
100
92
|
- test/test_win32_file_security_encryption.rb
|
101
93
|
- test/test_win32_file_security_ffi.rb
|
@@ -106,27 +98,26 @@ files:
|
|
106
98
|
homepage: http://github.com/djberg96/win32-file-security
|
107
99
|
licenses:
|
108
100
|
- Artistic 2.0
|
101
|
+
metadata: {}
|
109
102
|
post_install_message:
|
110
103
|
rdoc_options: []
|
111
104
|
require_paths:
|
112
105
|
- lib
|
113
106
|
required_ruby_version: !ruby/object:Gem::Requirement
|
114
|
-
none: false
|
115
107
|
requirements:
|
116
|
-
- -
|
108
|
+
- - '>='
|
117
109
|
- !ruby/object:Gem::Version
|
118
110
|
version: '0'
|
119
111
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
|
-
none: false
|
121
112
|
requirements:
|
122
|
-
- -
|
113
|
+
- - '>='
|
123
114
|
- !ruby/object:Gem::Version
|
124
115
|
version: '0'
|
125
116
|
requirements: []
|
126
117
|
rubyforge_project: win32utils
|
127
|
-
rubygems_version:
|
118
|
+
rubygems_version: 2.2.2
|
128
119
|
signing_key:
|
129
|
-
specification_version:
|
120
|
+
specification_version: 4
|
130
121
|
summary: File security methods for the File class on MS Windows
|
131
122
|
test_files:
|
132
123
|
- test/test_win32_file_security_constants.rb
|