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 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
@@ -35,7 +35,7 @@
35
35
  Artistic 2.0
36
36
 
37
37
  == Copyright
38
- (C) 2003-2013, Daniel J. Berger, All Rights Reserved
38
+ (C) 2003-2014, Daniel J. Berger, All Rights Reserved
39
39
 
40
40
  == Warranty
41
41
  This package is provided "as is" and without any express or
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::Builder.new(spec).build
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
 
@@ -1,7 +1,7 @@
1
- require File.join(File.dirname(__FILE__), 'security', 'constants')
2
- require File.join(File.dirname(__FILE__), 'security', 'structs')
3
- require File.join(File.dirname(__FILE__), 'security', 'functions')
4
- require File.join(File.dirname(__FILE__), 'security', 'helper')
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.3'
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).delete(0.chr)
266
- domain = domain.read_string(domain_size.read_ulong * 2).delete(0.chr)
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
- raise TypeError unless file.is_a?(String)
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.wincode,
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.wincode,
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).tr(0.chr, '').strip
727
- domain = dom.read_string(dom.size).tr(0.chr, '').strip
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.wincode,
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.wincode,
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).tr(0.chr, '').strip
790
- domain = dom.read_string(dom.size).tr(0.chr, '').strip
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
- # Make FFI functions private
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
- extend FFI::Library
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.3', File::WIN32_FILE_SECURITY_VERSION)
11
+ assert_equal('1.0.4', File::WIN32_FILE_SECURITY_VERSION)
12
12
  end
13
13
  end
@@ -2,7 +2,7 @@ require 'rubygems'
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = 'win32-file-security'
5
- spec.version = '1.0.3'
5
+ spec.version = '1.0.4'
6
6
  spec.authors = ['Daniel J. Berger', 'Park Heesob']
7
7
  spec.license = 'Artistic 2.0'
8
8
  spec.email = 'djberg96@gmail.com'
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.3
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: 2013-04-15 00:00:00.000000000 Z
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: ! " The win32-file-security library adds security related methods
80
- to the\n core File class for MS Windows. This includes the ability to get or\n
81
- \ set permissions, as well as encrypt or decrypt files.\n"
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: 1.8.24
118
+ rubygems_version: 2.2.2
128
119
  signing_key:
129
- specification_version: 3
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