lenc 1.1.3 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -14,21 +14,15 @@ module RepoInternal
14
14
  def initialize
15
15
  @dirOnly, @negated, @pathMode, @rexp, @dbPattern = nil
16
16
  end
17
-
18
- def inspect
19
- to_s
20
- end
21
- def to_s
22
- s = "Ign<"
23
- s << df(@dirOnly,"dirOnly") << "expr: " << @rexp.to_s << ">"
24
- s
25
- end
26
17
  end
27
18
  end
28
19
 
29
20
 
30
21
  module LEnc
31
22
 
23
+ KEY_LEN_MIN = 8
24
+ KEY_LEN_MAX = 56
25
+
32
26
  class DecryptionError < Exception
33
27
  end
34
28
 
@@ -113,19 +107,51 @@ module LEnc
113
107
  end
114
108
  end
115
109
 
116
-
110
+ # If a password hasn't been defined, ask user for one.
111
+ # Also, pad password out to some minimum size
112
+ #
113
+ def define_password(pwd)
114
+ if !pwd
115
+
116
+ if true
117
+
118
+ # Use the 'highline' gem to allow typing password without echo to screen
119
+ require 'rubygems'
120
+ require 'highline/import'
121
+ pwd = ask("Password: ") {|q| q.echo = false}
122
+
123
+ else
124
+ printf("Password: ")
125
+ pwd = gets
126
+ end
127
+
128
+ if pwd
129
+ pwd.strip!
130
+ pwd = nil if pwd.size == 0
131
+ end
132
+ if !pwd
133
+ raise DecryptionError, "No password given"
134
+ end
135
+ end
136
+
137
+ while pwd.size < KEY_LEN_MIN
138
+ pwd *= 2
139
+ end
140
+ pwd
141
+ end
142
+
143
+
117
144
  # Create a new encryption repository, and open it.
118
145
  #
119
- # @param repo_dir directory of new repository (nil for current directory)
120
- # @param key encryption key, a string from 8 to 56 characters in length
121
- # @param enc_dir directory to store encrypted files; must not yet exist, and must
122
- # not represent a directory lying within the repo_dir tree
123
- # @param original_names if true, the filenames are not encrypted, only the file contents
124
- # @param store_key if true, the key is written to the repository configuration file; otherwise,
125
- # user must supply the key every time the repository is updated
146
+ # @param repo_dir directory of new repository (nil for current directory)
147
+ # @param key encryption key, a string from KEY_LEN_MIN to KEY_LEN_MAX characters in length
148
+ # @param enc_dir if not nil, directory to store encrypted files; must not yet exist, and must
149
+ # not represent a directory lying within the repo_dir tree;
150
+ # if nil, repository will be encrypted in-place
151
+ # @param original_names if true, the filenames are not encrypted, only the file contents
126
152
  # @raise ArgumentError if appropriate
127
153
  #
128
- def create(repo_dir, key, enc_dir, original_names=false, store_key=true)
154
+ def create(repo_dir, key, enc_dir, original_names=false)
129
155
  raise IllegalStateException if @state != STATE_CLOSED
130
156
 
131
157
  db = warndb 0
@@ -149,28 +175,34 @@ module LEnc
149
175
 
150
176
  @orignames = original_names
151
177
 
152
- edir = File.absolute_path(enc_dir)
153
178
  @confFile.set('orignames', @orignames)
154
179
 
155
- if @verbosity >= 0
180
+ if @verbosity >= 1
156
181
  pr("Creating encryption repository %s\n", @confFile.path)
157
182
  end
158
183
 
159
- pp = verifyDirsDistinct([repo_dir, edir])
160
-
161
- if pp
162
- raise ArgumentError, "Directory " + pp[0] + \
163
- " is a subdirectory of " + pp[1]
164
- end
184
+ edir = nil
185
+ if enc_dir
186
+ edir = File.absolute_path(enc_dir)
187
+ pp = verifyDirsDistinct([repo_dir, edir])
188
+
189
+ if pp
190
+ raise ArgumentError, "Directory " + pp[0] + \
191
+ " is a subdirectory of " + pp[1]
192
+ end
165
193
 
166
- if (key.size < 8 || key.size > 56)
194
+ if File.exists?(edir)
195
+ raise ArgumentError, \
196
+ "Encryption directory or file already exists: '#{edir}'"
197
+ end
198
+ @confFile.set('enc_dir', edir)
199
+ end
200
+
201
+ key = define_password(key)
202
+ if (key.size < KEY_LEN_MIN || key.size > KEY_LEN_MAX)
167
203
  raise ArgumentError, "Password length " + key.size.to_s \
168
204
  + " is illegal"
169
205
  end
170
-
171
- if store_key
172
- @confFile.set('key', key)
173
- end
174
206
 
175
207
  # Construct a string that verifies the password is correct
176
208
  en = MyAES.new(true, key )
@@ -181,17 +213,10 @@ module LEnc
181
213
  vs2 = Base64.urlsafe_encode64(verifier_string)
182
214
  @confFile.set('key_verifier', vs2)
183
215
 
184
-
185
- # Create encryption directory
186
- if File.exists?(edir)
187
- raise ArgumentError, \
188
- "Encryption directory or file already exists: '#{edir}'"
189
- end
190
-
191
- @confFile.set('enc_dir', edir)
192
-
193
216
  if not @dryrun
194
- Dir.mkdir(edir)
217
+ if edir
218
+ Dir.mkdir(edir)
219
+ end
195
220
  @confFile.write()
196
221
  end
197
222
 
@@ -208,9 +233,9 @@ module LEnc
208
233
  # @raise IllegalStateException if repository is already open
209
234
  # @raise ArgumentError if directory doesn't exist, or does not lie in a repository
210
235
  #
211
- def open(startDirectory=nil, password = nil)
236
+ def open(startDirectory = nil, password = nil)
212
237
  db = warndb 0
213
- !db || pr("Repo.open startDir=%s\n",d(startDirectory))
238
+ !db || pr("Repo.open startDir=%s, password=%s\n",d(startDirectory),d(password))
214
239
 
215
240
  raise IllegalStateException if @state != STATE_CLOSED
216
241
 
@@ -242,18 +267,7 @@ module LEnc
242
267
 
243
268
  # Read values from configuration to instance vars
244
269
  @encrDir = @confFile.val('enc_dir')
245
- pwd = @confFile.val('key') || password
246
- if !pwd
247
- printf("Password: ")
248
- pwd = gets
249
- if pwd
250
- pwd.strip!
251
- pwd = nil if pwd.size == 0
252
- end
253
- if !pwd
254
- raise DecryptionError, "No password given"
255
- end
256
- end
270
+ pwd = define_password(password)
257
271
 
258
272
  @orignames = @confFile.val('orignames')
259
273
  @encrKey = pwd
@@ -277,29 +291,57 @@ module LEnc
277
291
  reset_state()
278
292
  end
279
293
 
280
- # Update the repository. Finds files that need to be re-encrypted and does so.
294
+ # Encrypt repository's files.
295
+ # If repo is dual, finds files that need to be re-encrypted and does so.
296
+ # If singular, encrypts all those files that are not yet encrypted.
297
+ #
281
298
  # Repository must be open.
282
- #
283
- # @param verifyEncryption for debug purposes; if true, each file that is encrypted is tested to confirm that
284
- # it decrypts correctly.
285
299
  #
286
300
  # @raise IllegalStateException if repository isn't open.
287
301
  #
288
- def perform_update(verifyEncryption=false)
302
+ def perform_encrypt()
289
303
  raise IllegalStateException if @state != STATE_OPEN
290
304
 
291
- setInputOutputDirs(@startDir,@encrDir)
305
+ enc_dir = @encrDir
306
+ if in_place?
307
+ enc_dir = @repoBaseDir
308
+ end
309
+
310
+ setInputOutputDirs(@startDir,enc_dir)
292
311
 
293
- @verifyEncryption = verifyEncryption
312
+ # If encrypting singular repository, ignore all .lencignore files
313
+ if in_place?
314
+ pushIgnoreList('', Repo.parseIgnoreList(".lencignore"))
315
+ end
294
316
 
295
317
  puts("Encrypting...") if @verbosity >= 1
296
318
 
297
319
  begin
298
- encryptDir(@repoBaseDir, @encrDir)
320
+ ecrypt_directory_contents(@repoBaseDir, enc_dir)
299
321
  puts("...done.") if @verbosity >= 1
300
322
  end
301
323
  end
302
324
 
325
+ # Decrypt files within singular repository.
326
+ # Repository must be open.
327
+ #
328
+ # @raise IllegalStateException if repository isn't open.
329
+ #
330
+ def perform_decrypt()
331
+ raise IllegalStateException if (@state != STATE_OPEN || !in_place?)
332
+
333
+ enc_dir = @repoBaseDir
334
+
335
+ setInputOutputDirs(enc_dir,enc_dir)
336
+
337
+ puts("Decrypting...") if @verbosity >= 1
338
+
339
+ begin
340
+ decrypt_directory_contents(enc_dir)
341
+ puts("...done.") if @verbosity >= 1
342
+ end
343
+ end
344
+
303
345
 
304
346
  # Recover files from a repository's encryption folder.
305
347
  #
@@ -316,6 +358,7 @@ module LEnc
316
358
 
317
359
  ret = nil
318
360
 
361
+ key = define_password(key)
319
362
  @encrKey = key
320
363
 
321
364
  rd = File.absolute_path(rDir)
@@ -526,6 +569,10 @@ module LEnc
526
569
  initIgnoreList()
527
570
  end
528
571
 
572
+ def in_place?
573
+ !@encrDir
574
+ end
575
+
529
576
  # Construct the initial ignore list.
530
577
  #
531
578
  # We maintain a stack of these lists, and subsequent operations can push and pop
@@ -580,7 +627,9 @@ module LEnc
580
627
  #
581
628
  # Encrypted filenames are also given a prefix to distinguish them
582
629
  # from files not created by this program (or filenames that have not been encrypted)
583
- #
630
+ # If the given filename already has this prefix, it is assumed that the filename has
631
+ # already been encrypted.
632
+ #
584
633
  # If filenames are not encrypted in this repository, returns filename unchanged.
585
634
  #
586
635
  def encryptFilename(s)
@@ -590,6 +639,8 @@ module LEnc
590
639
 
591
640
  return s if @orignames
592
641
 
642
+ return s if s.start_with?(ENCRFILENAMEPREFIX)
643
+
593
644
  nonce = OpenSSL::Digest::SHA1.new(s).digest
594
645
  !db || pr(" SHA1 applied, nonce=%s\n",dt(nonce))
595
646
  !db || hex_dump(nonce,"SHA1 nonce")
@@ -645,7 +696,7 @@ module LEnc
645
696
  !db || pr("verify_encrypt_pwd key %s, verifier %s\n",d(key),hex_dump_to_string(key_verifier))
646
697
 
647
698
  if !MyAES.is_string_encrypted(key, key_verifier)
648
- raise(DecryptionError, "#{key} is not the correct password for this repository")
699
+ raise(DecryptionError, "incorrect password")
649
700
  end
650
701
  end
651
702
 
@@ -674,14 +725,23 @@ module LEnc
674
725
 
675
726
 
676
727
  # Update a single source file if necessary (not a directory)
728
+ # @param sourceFile absolute path of source file
729
+ # @param encryptFile absolute path of encrypted file
730
+ #
677
731
  def encrypt_file(sourceFile, encryptFile)
678
732
 
679
- # If encrypted file is a directory, delete it
733
+ db = warndb 0
734
+ !db || pr("encrypt_file\n source=#{sourceFile}\n encrypt=#{encryptFile}\n")
735
+
736
+ # If encrypted file is a directory, delete it. This can only occur if it's a dual repository.
680
737
  if File.directory?(encryptFile)
738
+ raise IllegalStateError if in_place?
739
+
681
740
  pth = rel_path(encryptFile, @outputDir)
682
741
 
683
742
  if @verbosity >= 1
684
- msg = "Encrypting file " + rel_path(sourceFile, @inputDir) + " is overwriting existing directory: " + pth
743
+ msg = "Encrypting file " + rel_path(sourceFile, @inputDir) \
744
+ + " is overwriting existing directory: " + pth
685
745
  end
686
746
 
687
747
  if not @dryrun
@@ -690,9 +750,9 @@ module LEnc
690
750
  end
691
751
 
692
752
  # Determine if existing encrypted version exists
693
- # and is up to date
694
- mustUpdate = (not File.file?(encryptFile)) \
695
- or (File.mtime(encryptFile) < File.mtime(sourceFile))
753
+ # and is up to date; only if not in-place
754
+ mustUpdate = in_place? || ((not File.file?(encryptFile)) \
755
+ or (File.mtime(encryptFile) < File.mtime(sourceFile)))
696
756
 
697
757
  if mustUpdate
698
758
  showProgress = (@verbosity >= 0)
@@ -702,38 +762,36 @@ module LEnc
702
762
  pr("%s", srcDisp)
703
763
  end
704
764
 
705
- encPath = convertFile(sourceFile, true, showProgress, false)
706
- FileUtils.mv(encPath, encryptFile)
707
-
708
-
709
- if @verifyEncryption
710
- # Verify that the original and decoded files are identical
711
- decoded_file = convertFile(encryptFile, false, showProgress, true)
712
- files_match = FileUtils.compare_file(sourceFile, decoded_file.path)
713
- decoded_file.unlink
714
-
715
- if !files_match
716
- delete_file_or_dir(encryptFile)
717
- raise EncryptionVerificationException, \
718
- "File '#{srcDisp}' did not encrypt/decrypt correctly"
719
-
720
- end
721
- if @verbosity >= 0
722
- pr(" (file #{srcDisp} encrypted correctly)\n")
723
- end
765
+ temp_enc_path = convertFile(sourceFile, true, showProgress)
766
+ if not @dryrun
767
+ FileUtils.mv(temp_enc_path, encryptFile)
724
768
  end
769
+
725
770
  end
726
771
  end
727
772
 
728
773
  # Determine if a file matches one of the expressions in the ignore stack.
729
774
  # Searches the stack from top to bottom (i.e., the outermost elements are examined last)
730
- def shouldFileBeIgnored(f)
731
- db = false
732
- !db || pr("shouldFileBeIgnored? #{f}\n")
733
- f2 = f
775
+ # @param name_only filename, without path
776
+ # @param full_path full path of file
777
+ #
778
+ def should_file_be_ignored(name_only, full_path)
779
+ db = warndb 0
780
+ !db || pr("should_file_be_ignored? #{name_only}\n")
781
+
782
+ # Let f2 be the filename including the directories corresponding
783
+ # to the ignore stack
784
+
785
+ f2 = name_only
786
+
734
787
  @ignoreStack.reverse.each do |dir,ients|
735
788
  ients.each do |ient|
736
- fArg = ient.pathMode ? f2 : f
789
+
790
+ if ient.dirOnly && !File.directory?(full_path)
791
+ next
792
+ end
793
+
794
+ fArg = ient.pathMode ? f2 : name_only
737
795
 
738
796
  matches = ient.rexp.match(fArg)
739
797
  !db || pr(" ent path=#{ient.pathMode} rexp=#{ient.rexp} neg=#{ient.negated} matches=#{matches}\n")
@@ -742,7 +800,7 @@ module LEnc
742
800
  return !ient.negated
743
801
  end
744
802
  end
745
- f2 = dir + f2
803
+ f2 = File.join(dir,f2)
746
804
  end
747
805
 
748
806
  return false
@@ -760,8 +818,14 @@ module LEnc
760
818
 
761
819
  # Examine all files in repository; reencrypt those that have changed
762
820
  # (by comparing their time stamps with the time stamps of the encyrypted versions)
763
- def encryptDir(sourceDir, encryptDir)
764
- db = warndb 0
821
+ #
822
+ # @param sourceDir absolute path of source directory
823
+ # @param encryptDir absolute path of encryption directory
824
+ #
825
+ def ecrypt_directory_contents(sourceDir, encryptDir)
826
+
827
+ db = (warndb 0)
828
+
765
829
  !db || pr("\n\nencryptDir\n %s =>\n %s\n",d(sourceDir),d(encryptDir))
766
830
 
767
831
  # Add contents of .lencignore to stack. If none exists, treat as if empty
@@ -776,10 +840,14 @@ module LEnc
776
840
  # Create set of encrypted filenames that belong to this directory, so
777
841
  # we can delete encrypted versions of files that are no longer in the source
778
842
  # directory.
779
- encFilenameSet = Set.new
843
+ # Don't do this if repo is in-place.
844
+ encFilenameSet = nil
845
+ if !in_place?
846
+ in_place? || encFilenameSet = Set.new
847
+ end
780
848
 
781
849
  # If no encrypted directory exists, create one
782
- if not File.directory?(encryptDir)
850
+ if !in_place? && !File.directory?(encryptDir)
783
851
  if @verbosity >= 1
784
852
  puts("Creating encrypted directory: " + d(rel_path(encryptDir, @outputDir)))
785
853
  end
@@ -805,9 +873,6 @@ module LEnc
805
873
  # Convert string to ASCII-8BIT encoding.
806
874
  f = to_ascii8(f2)
807
875
 
808
- !db || pr(" testing if file should be ignored: #{f}\n")
809
- ignore = shouldFileBeIgnored(f)
810
-
811
876
  filePath = File.join(sourceDir,f)
812
877
 
813
878
  if File.symlink?(filePath)
@@ -817,81 +882,198 @@ module LEnc
817
882
  next
818
883
  end
819
884
 
820
- if ignore
885
+ !db || pr(" testing if file should be ignored: #{f}\n")
886
+ if should_file_be_ignored(f, filePath)
821
887
  !db || pr("(ignoring %s)\n", rel_path(filePath, @inputDir)) if @verbosity >= 1
822
888
  next
823
889
  end
824
890
 
825
- if f.start_with?(ENCRFILENAMEPREFIX)
826
- if @verbosity >= 0
827
- pr("(Omitting source file / dir with name that looks encrypted: #{d(f)})\n")
891
+ # If we're doing in-place encryption, file is not a directory, and it's already encrypted, ignore
892
+ if in_place?
893
+ next if (!File.directory?(filePath) && f.start_with?(ENCRFILENAMEPREFIX))
894
+ next if (@orignames && MyAES.is_file_encrypted(@encrKey,filePath))
895
+ else
896
+ if f.start_with?(ENCRFILENAMEPREFIX)
897
+ if @verbosity >= 0
898
+ pr("(Omitting source file / dir with name that looks encrypted: #{d(f)})\n")
899
+ end
900
+ next
828
901
  end
829
902
  end
830
903
 
831
- encrName = encryptFilename(f)
832
- !db || pr(" encrypted filename %s => %s\n",d(f),d(encrName))
833
904
 
834
- if @verifyEncryption
835
- decrName = decryptFilename(encrName, false)
836
- if !decrName || decrName != f
837
- !db || pr("decrName encoding=#{decrName.encoding}\n f encoding=#{f.encoding}\n")
838
- !db || hex_dump(decrName,"decrName")
839
- !db || hex_dump(f,"f")
840
-
841
- raise EncryptionVerificationException, \
842
- "Filename #{f} did not encrypt/decrypt properly"
905
+ if !in_place?
906
+ encrName = encryptFilename(f)
907
+ !db || pr(" encrypted filename %s => %s\n",d(f),d(encrName))
908
+ encFilenameSet.add(encrName)
909
+ encrPath = File.join(encryptDir, encrName)
910
+
911
+ if File.directory?(filePath)
912
+ ecrypt_directory_contents(filePath, encrPath)
913
+ else
914
+ !db || pr("...attempting to encrypt file #{filePath} to #{encrPath}...\n")
915
+ encrypt_file(filePath, encrPath)
843
916
  end
844
- pr(" (filename #{f} encrypted correctly)\n") if @verbosity >= 0
845
- end
846
-
847
- encFilenameSet.add(encrName)
848
- encrPath = File.join(encryptDir, encrName)
849
917
 
850
- if File.directory?(filePath)
851
- encryptDir(filePath, encrPath)
852
- else
853
- !db || pr("...attempting to encrypt file #{filePath} to #{encrPath}...\n")
854
- encrypt_file(filePath, encrPath)
918
+ else
919
+
920
+ encrPath = filePath
921
+ if !@origNames
922
+ encrName = encryptFilename(f)
923
+ encrPath = File.join(sourceDir, encrName)
924
+ end
925
+
926
+ if File.directory?(filePath)
927
+ ecrypt_directory_contents(filePath, filePath)
928
+ # Rename the directory to its encrypted form, if necessary
929
+ if filePath != encrPath
930
+ !db || pr(" renaming now-encrypted file from\n #{filePath}\n to\n #{encrPath}\n")
931
+ FileUtils.mv(filePath,encrPath)
932
+ end
933
+ else
934
+ encrypt_file(filePath, encrPath)
935
+ # Delete unencrypted file, if not using original names
936
+ if !@orignames && !@dryrun
937
+ FileUtils.rm(filePath)
938
+ end
939
+ end
855
940
  end
941
+
856
942
  end
857
943
 
858
944
  # Truncate global ignore list to original length
859
945
  popIgnoreList()
860
946
 
861
- # Examine every file in encrypted directory; delete those that don't correspond to source dir
862
-
863
- # (if doing dry run, encrypt dir may not exist)
864
-
865
- !db || pr("examining files in encrypted dir #{encryptDir} to delete ones that don't belong\n")
866
- if File.directory?(encryptDir)
867
- dire = dir_entries(encryptDir)
868
- else
869
- dire = []
947
+ if !in_place?
948
+ # Examine every file in encrypted directory; delete those that don't correspond to source dir
949
+
950
+ # (if doing dry run, encrypt dir may not exist)
951
+
952
+ !db || pr("examining files in encrypted dir #{encryptDir} to delete ones that don't belong\n")
953
+ if File.directory?(encryptDir)
954
+ dire = dir_entries(encryptDir)
955
+ else
956
+ dire = []
957
+ end
958
+
959
+ dire.each do |f|
960
+ next if not f.start_with?(ENCRFILENAMEPREFIX)
961
+
962
+ if not encFilenameSet.member? f
963
+ begin
964
+ orphanOrigName = decryptFilename(f)
965
+ next if !orphanOrigName
966
+ orphanPath = File.join(encryptDir, f)
967
+ if @verbosity >= 1
968
+ printf("Removing encrypted version of missing (or ignored) file " \
969
+ + rel_path(File.join(sourceDir, orphanOrigName), @inputDir) + ": " + orphanPath)
970
+ end
971
+ if !@dryrun
972
+ remove_file_or_dir(orphanPath)
973
+ end
974
+ rescue DecryptionError
975
+ # ignore...
976
+ end
977
+ end
978
+ end
870
979
  end
980
+ end
981
+
982
+ # Decrypt all files recursively within singular repository subdirectory
983
+ #
984
+ # @param encr_dir_path absolute path of encrypted directory
985
+ # @param decr_dir_name absolute path of directory after decrypting (used for display purposes only);
986
+ # if nil, uses encrypted directory name
987
+ #
988
+ def decrypt_directory_contents(encr_dir_path,decr_dir_name = nil)
989
+
990
+ decr_dir_name ||= encr_dir_path
871
991
 
872
- dire.each do |f|
873
- next if not f.start_with?(ENCRFILENAMEPREFIX)
874
-
875
- if not encFilenameSet.member? f
992
+ db = warndb 0
993
+
994
+ !db || pr("\n\ndecrypt_directory_contents: %s (orignames=#{@orignames})\n",d(encr_dir_path))
995
+
996
+ # Examine each file in source dir
997
+ dirc = dir_entries(encr_dir_path)
998
+
999
+ dirc.each do |f2|
1000
+ # Convert string to ASCII-8BIT encoding.
1001
+ f = to_ascii8(f2)
1002
+
1003
+ filePath = File.join(encr_dir_path,f)
1004
+ if File.symlink?(filePath)
1005
+ if @verbosity >= 0
1006
+ pr("Omitting symlink file '#{rel_path(filePath,@inputDir)}'\n")
1007
+ end
1008
+ next
1009
+ end
1010
+
1011
+ !db || pr(" filePath=#{filePath}\n")
1012
+ decrPath = filePath
1013
+ decrName = f
1014
+ if @orignames
1015
+ if File.file?(filePath)
1016
+ if !MyAES.is_file_encrypted(@encrKey,filePath)
1017
+ !db || pr(" file is not encrypted, skipping\n")
1018
+ next
1019
+ end
1020
+ end
1021
+ else
1022
+ next if !f.start_with?(ENCRFILENAMEPREFIX)
876
1023
  begin
877
- orphanOrigName = decryptFilename(f)
878
- next if !orphanOrigName
879
- orphanPath = File.join(encryptDir, f)
880
- if @verbosity >= 1
881
- printf("Removing encrypted version of missing (or ignored) file " \
882
- + rel_path(File.join(sourceDir, orphanOrigName), @inputDir) + ": " + orphanPath)
1024
+ decrName = decryptFilename(f)
1025
+ decrPath = File.join(encr_dir_path, decrName)
1026
+ rescue DecryptionError => e
1027
+ puts "Unable to decrypt filename #{f}"
1028
+ next
1029
+ end
1030
+ end
1031
+
1032
+ if File.directory?(filePath)
1033
+ decrypt_directory_contents(filePath, File.join(decr_dir_name, decrName))
1034
+ # Rename the directory to its decrypted form, if filenames are to be encrypted
1035
+ if !@orignames
1036
+ raise ArgumentError,"decrypted already exists: #{decrPath}" \
1037
+ if File.exist?(decrPath)
1038
+
1039
+ !db || pr(" renaming now-decrypted directory from\n #{filePath}\n to\n #{decrPath}\n")
1040
+ FileUtils.mv(filePath,decrPath)
1041
+ end
1042
+ else
1043
+ decrPathDisp = File.join(decr_dir_name,decrName)
1044
+ pth = rel_path(decrPathDisp, @repoBaseDir)
1045
+ showProgress = @verbosity >= 0
1046
+ if showProgress
1047
+ pr("%s", pth)
1048
+ end
1049
+ begin
1050
+ tmp_file = convertFile(filePath, false, showProgress)
1051
+ if !@orignames
1052
+ raise ArgumentError,"decrypted file or directory already exists: #{decrPath}" \
1053
+ if File.exist?(decrPath)
883
1054
  end
884
- if !@dryrun
885
- remove_file_or_dir(orphanPath)
1055
+
1056
+ if not @dryrun
1057
+ remove_file_or_dir(decrPath)
1058
+ FileUtils.mv(tmp_file.path, decrPath)
1059
+ # Remove the encrypted version, if we aren't using original names
1060
+ if !@orignames
1061
+ FileUtils.rm(filePath)
1062
+ end
1063
+ else
1064
+ tmp_file.unlink
1065
+ end
1066
+
1067
+ rescue DecryptionError => e
1068
+ if @verbosity >= 0
1069
+ msg = "Unable to decrypt file: #{pth} (cause: #{e.message})"
1070
+ pr("\n%s\n", msg)
886
1071
  end
887
- rescue DecryptionError
888
- # ignore...
889
1072
  end
890
1073
  end
891
1074
  end
892
1075
  end
893
-
894
-
1076
+
895
1077
  # Decrypt all files (and, recursively, folders) within a directory to _recover folder
896
1078
  def recover(encryptDir, recoverDir)
897
1079
  db = warndb 0
@@ -916,7 +1098,10 @@ module LEnc
916
1098
  dirc.each do |f|
917
1099
 
918
1100
  !db || pr("...file=%s\n",d(f))
919
- if shouldFileBeIgnored(f)
1101
+
1102
+ encrFullPath = File.join(encryptDir, f)
1103
+
1104
+ if should_file_be_ignored(f, encrFullPath)
920
1105
  if @verbosity >= 1
921
1106
  pr("(ignoring %s)\n", rel_path(f, @inputDir))
922
1107
  end
@@ -943,7 +1128,6 @@ module LEnc
943
1128
  origName = decrName
944
1129
  end
945
1130
  origPath = File.join(recoverDir, origName)
946
- encrFullPath = File.join(encryptDir, f)
947
1131
 
948
1132
 
949
1133
  # If decrypted version already exists, and is more recent than the
@@ -999,7 +1183,7 @@ module LEnc
999
1183
  # @param encrypt true if encrypting
1000
1184
  # @return temporary file containing modified file
1001
1185
  #
1002
- def convertFile(srcPath,encrypt, showProgress=false, verifying=false)
1186
+ def convertFile(srcPath,encrypt, showProgress=false)
1003
1187
 
1004
1188
  db = warndb 0
1005
1189
  !db||pr("\n\n\n\nconvertFile\n %s\n",d(srcPath))
@@ -1023,10 +1207,6 @@ module LEnc
1023
1207
  showDots = showProgress && chunksRemaining >= dotSize
1024
1208
  !db || (showDots = false)
1025
1209
 
1026
- if showDots and verifying
1027
- pr(" verifying:")
1028
- end
1029
-
1030
1210
  !db || pr("\n encrKey=%s\n",dt(@encrKey))
1031
1211
 
1032
1212
  bf = MyAES.new(encrypt, @encrKey)
@@ -1072,7 +1252,7 @@ module LEnc
1072
1252
 
1073
1253
  end
1074
1254
 
1075
- if showProgress and (showDots or not verifying)
1255
+ if showProgress
1076
1256
  pr("\n")
1077
1257
  end
1078
1258