lenc 1.1.3 → 1.2.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.
- checksums.yaml +4 -4
- data/README.md +40 -10
- data/bin/encr +5 -0
- data/lib/lenc.rb +1 -0
- data/lib/lenc/aes.rb +127 -52
- data/lib/lenc/encr.rb +64 -0
- data/lib/lenc/lencrypt.rb +13 -21
- data/lib/lenc/repo.rb +340 -160
- data/lib/lenc/tools.rb +22 -0
- data/test/test.rb +100 -32
- metadata +24 -5
data/lib/lenc/tools.rb
CHANGED
@@ -678,6 +678,7 @@ end
|
|
678
678
|
def simple_str(s)
|
679
679
|
if s.encoding.name != 'ASCII-8BIT' && s.encoding.name != 'UTF-8'
|
680
680
|
pr("string [%s]\n encoding is %s,\n expected ASCII-8BIT\n",s,s.encoding.name)
|
681
|
+
pr("ruby version = #{RUBY_VERSION}\n")
|
681
682
|
assert!(false)
|
682
683
|
end
|
683
684
|
end
|
@@ -703,6 +704,27 @@ def windows?
|
|
703
704
|
$__windows__
|
704
705
|
end
|
705
706
|
|
707
|
+
# Make a system call
|
708
|
+
#
|
709
|
+
# @param cmd command to execute
|
710
|
+
# @param abort_if_problem if return code is nonzero, aborts
|
711
|
+
# @return [captured output, return code]
|
712
|
+
#
|
713
|
+
def scall(cmd, abort_if_problem = true)
|
714
|
+
# printf("...(making system call: #{cmd} )...\n")
|
715
|
+
|
716
|
+
res = `#{cmd} 2>&1`
|
717
|
+
succ = $?.success?
|
718
|
+
if !succ && abort_if_problem
|
719
|
+
puts("Failed system call '#{cmd}':\n\n#{res}")
|
720
|
+
exit
|
721
|
+
end
|
722
|
+
|
723
|
+
[res, succ]
|
724
|
+
end
|
725
|
+
|
726
|
+
|
727
|
+
|
706
728
|
# Mark all constants ending with '_' as private constants
|
707
729
|
#
|
708
730
|
# @param entity the class to examine
|
data/test/test.rb
CHANGED
@@ -4,13 +4,17 @@ require_relative '../lib/lenc/tools.rb'
|
|
4
4
|
req('repo lencrypt')
|
5
5
|
|
6
6
|
|
7
|
-
#SINGLETEST = "
|
7
|
+
#SINGLETEST = "test_121_update_repo_with_lencrypt_program"
|
8
8
|
if defined? SINGLETEST
|
9
9
|
if main?(__FILE__)
|
10
10
|
ARGV.concat("-n #{SINGLETEST}".split)
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
+
# Enable to display verbose output
|
15
|
+
#ARGV.concat("-v")
|
16
|
+
|
17
|
+
|
14
18
|
class RepoTest < MyTestSuite
|
15
19
|
|
16
20
|
include LEnc
|
@@ -32,6 +36,7 @@ class RepoTest < MyTestSuite
|
|
32
36
|
mkdir(@@testDir)
|
33
37
|
|
34
38
|
@@sourceDir = File.join(@@testDir,"__source__")
|
39
|
+
@@sourceDir2 = File.join(@@testDir,"ip")
|
35
40
|
@@encryptDir = File.join(@@testDir,"__encrypted__")
|
36
41
|
@@recoverDir = File.join(@@testDir,"__recovered__")
|
37
42
|
@@repoFile = File.join(@@sourceDir,Repo::LENC_REPO_FILENAME)
|
@@ -41,7 +46,7 @@ class RepoTest < MyTestSuite
|
|
41
46
|
if !File.directory?(@@sourceDir)
|
42
47
|
create_source_tree()
|
43
48
|
end
|
44
|
-
|
49
|
+
|
45
50
|
clean()
|
46
51
|
|
47
52
|
# Construct a list of the source subdirectories, since some of them have
|
@@ -144,18 +149,18 @@ class RepoTest < MyTestSuite
|
|
144
149
|
pluto|
|
145
150
|
SCR
|
146
151
|
|
147
|
-
|
152
|
+
# Script of predetermined file lengths:
|
148
153
|
cs = RepoInternal::CHUNK_SIZE_ENCR
|
149
154
|
hs = RepoInternal::CHUNK_HEADER_SIZE
|
150
155
|
flens = [0, cs - 1, cs, cs + 1, cs + hs - 1, cs + hs, cs + hs + 1,
|
151
|
-
|
156
|
+
(2 * cs) - 1, 2 * cs, 2 * cs + 1, 2 * (cs + hs) - 1, 2 * (cs + hs), 2 * (cs + hs) + 1]
|
152
157
|
fNum = 0
|
153
|
-
|
158
|
+
|
154
159
|
srand(1983)
|
155
|
-
|
156
|
-
dr = @@sourceDir
|
160
|
+
|
161
|
+
dr = @@sourceDir
|
157
162
|
mkdir(dr)
|
158
|
-
|
163
|
+
|
159
164
|
dirStack = []
|
160
165
|
k = 0
|
161
166
|
k0 = k
|
@@ -163,29 +168,36 @@ SCR
|
|
163
168
|
c = scr[k]
|
164
169
|
k += 1
|
165
170
|
next if !"|/^".index(c)
|
166
|
-
|
171
|
+
|
167
172
|
nm = scr[k0...k-1].strip
|
168
|
-
|
173
|
+
|
169
174
|
k0 = k
|
170
|
-
|
171
|
-
if c == '|'
|
175
|
+
|
176
|
+
if c == '|'
|
172
177
|
# create a file; use our predetermined lengths, if we still have some;
|
173
178
|
# otherwise, choose a random file length
|
174
179
|
if fNum < flens.size
|
175
180
|
j = flens[fNum]
|
176
|
-
else
|
181
|
+
else
|
177
182
|
j = (rand() * rand() * 130000).to_i + 3
|
178
183
|
end
|
184
|
+
|
185
|
+
# Make the length end with a particular sequence of digits so we can quickly determine whether
|
186
|
+
# file has been encrypted or decrypted
|
187
|
+
q = (j - 11) % 100
|
188
|
+
j -= q
|
189
|
+
j += 100 if j <= 0
|
190
|
+
|
179
191
|
fNum += 1
|
180
192
|
makeFile(File.join(dr, nm), j)
|
181
193
|
elsif c == '/'
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
elsif c == '^'
|
186
|
-
|
187
|
-
end
|
188
|
-
end
|
194
|
+
dirStack.push(dr)
|
195
|
+
dr = File.join(dr,nm)
|
196
|
+
mkdir(dr)
|
197
|
+
elsif c == '^'
|
198
|
+
dr = dirStack.pop
|
199
|
+
end
|
200
|
+
end
|
189
201
|
|
190
202
|
# Store some .lencignore files
|
191
203
|
dr = @@sourceDir
|
@@ -199,6 +211,18 @@ end
|
|
199
211
|
end
|
200
212
|
|
201
213
|
|
214
|
+
# Create in-place source tree as copy of normal source tree
|
215
|
+
def create_source_tree2
|
216
|
+
if !File.exist?(@@sourceDir2)
|
217
|
+
remove_file_or_dir(@@sourceDir2)
|
218
|
+
FileUtils.cp_r(@@sourceDir,@@sourceDir2)
|
219
|
+
end
|
220
|
+
remove_file_or_dir(File.join(@@sourceDir2,".lenc"))
|
221
|
+
end
|
222
|
+
|
223
|
+
|
224
|
+
|
225
|
+
|
202
226
|
def writeIgnore(dr, contents)
|
203
227
|
pth = File.join(dr,Repo::IGNOREFILENAME)
|
204
228
|
File.open(pth,'w') do |f|
|
@@ -210,7 +234,8 @@ end
|
|
210
234
|
if args.is_a? String
|
211
235
|
args = args.split
|
212
236
|
end
|
213
|
-
args.concat(["-w", @@sourceDir
|
237
|
+
args.concat(["-w", @@sourceDir])
|
238
|
+
args.concat(["-q"])
|
214
239
|
LEncApp.new().run(args)
|
215
240
|
end
|
216
241
|
|
@@ -234,14 +259,14 @@ end
|
|
234
259
|
|
235
260
|
def update_repo(silent = true)
|
236
261
|
rp = build_repo_obj(silent)
|
237
|
-
rp.open(@@sourceDir)
|
238
|
-
rp.
|
262
|
+
rp.open(@@sourceDir,@@key)
|
263
|
+
rp.perform_encrypt
|
239
264
|
rp.close
|
240
265
|
end
|
241
266
|
|
242
267
|
def do_recover
|
243
268
|
rp = build_repo_obj
|
244
|
-
rp.perform_recovery(@@key, @@encryptDir
|
269
|
+
rp.perform_recovery(@@key, @@encryptDir, @@recoverDir)
|
245
270
|
rp.close
|
246
271
|
end
|
247
272
|
|
@@ -304,25 +329,25 @@ end
|
|
304
329
|
end
|
305
330
|
|
306
331
|
# Create repo using lencrypt program
|
307
|
-
def
|
332
|
+
def test_101_create_repo_with_lencrypt_program
|
308
333
|
clean
|
309
|
-
a = "
|
334
|
+
a = "--init #{@@encryptDir} --key #{@@key}"
|
310
335
|
ex(a)
|
311
336
|
end
|
312
337
|
|
313
338
|
def test_101_update_repo_with_verify
|
314
339
|
clean
|
315
|
-
ex("
|
340
|
+
ex("--init #{@@encryptDir} --key #{@@key}")
|
316
341
|
rp = build_repo_obj
|
317
|
-
rp.open(@@sourceDir)
|
318
|
-
rp.
|
342
|
+
rp.open(@@sourceDir,@@key)
|
343
|
+
rp.perform_encrypt()
|
319
344
|
rp.close
|
320
345
|
end
|
321
346
|
|
322
347
|
def test_110_open_repo_using_Repo_class
|
323
348
|
# (assumes repo exists at this point; preceding test creates it)
|
324
349
|
rp = build_repo_obj
|
325
|
-
rp.open(@@sourceDir)
|
350
|
+
rp.open(@@sourceDir,@@key)
|
326
351
|
end
|
327
352
|
|
328
353
|
def test_120_update_repo_using_Repo_class
|
@@ -331,8 +356,11 @@ end
|
|
331
356
|
end
|
332
357
|
|
333
358
|
def test_121_update_repo_with_lencrypt_program
|
359
|
+
create_repo
|
334
360
|
remove_file_or_dir(@@encryptDir)
|
335
|
-
|
361
|
+
|
362
|
+
ex("--key #{@@key}")
|
363
|
+
|
336
364
|
assert(File.directory?(@@encryptDir))
|
337
365
|
end
|
338
366
|
|
@@ -353,7 +381,7 @@ end
|
|
353
381
|
|
354
382
|
def test_200_recover_with_incorrect_password
|
355
383
|
create_repo
|
356
|
-
ex("") # updates repo
|
384
|
+
ex("--key #{@@key}") # updates repo
|
357
385
|
assert_raise(DecryptionError) do
|
358
386
|
remove_file_or_dir(@@recoverDir)
|
359
387
|
rp = build_repo_obj()
|
@@ -362,4 +390,44 @@ end
|
|
362
390
|
end
|
363
391
|
end
|
364
392
|
|
393
|
+
def test_300_singular_repo
|
394
|
+
create_source_tree2
|
395
|
+
|
396
|
+
# Create in-place repository
|
397
|
+
rp = build_repo_obj
|
398
|
+
rp.create(@@sourceDir2,@@key,nil)
|
399
|
+
rp.close
|
400
|
+
|
401
|
+
# Update the repo
|
402
|
+
rp = build_repo_obj
|
403
|
+
rp.open(@@sourceDir2, @@key)
|
404
|
+
rp.perform_encrypt()
|
405
|
+
rp.close
|
406
|
+
|
407
|
+
|
408
|
+
end
|
409
|
+
|
410
|
+
def test_310_singular_encrypt_then_decrypt
|
411
|
+
|
412
|
+
create_source_tree2
|
413
|
+
|
414
|
+
# Create in-place repository
|
415
|
+
rp = build_repo_obj
|
416
|
+
rp.create(@@sourceDir2,@@key,nil)
|
417
|
+
rp.close
|
418
|
+
|
419
|
+
# Update the repo
|
420
|
+
rp = build_repo_obj
|
421
|
+
rp.open(@@sourceDir2, @@key)
|
422
|
+
rp.perform_encrypt()
|
423
|
+
rp.close
|
424
|
+
|
425
|
+
# Try decrypting
|
426
|
+
rp = build_repo_obj
|
427
|
+
rp.open(@@sourceDir2, @@key)
|
428
|
+
rp.perform_decrypt()
|
429
|
+
rp.close
|
430
|
+
end
|
431
|
+
|
432
|
+
|
365
433
|
end
|
metadata
CHANGED
@@ -1,22 +1,39 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lenc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeff Sember
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
12
|
-
dependencies:
|
11
|
+
date: 2013-05-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: highline
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
description: "Encrypts a set of local files, and copies the encrypted versions to
|
14
28
|
a repository, \nwhich may be located within a free cloud service (Dropbox, Google
|
15
29
|
Drive, Microsoft SkyDrive). \nThe program uses the trusted AES 256-bit encryption
|
16
30
|
standard. \nAll files are encrypted on the user machine; \npasswords and unencrypted
|
17
|
-
files are never seen by the cloud service. \n
|
31
|
+
files are never seen by the cloud service. \n\nIt can also encrypt or decrypt directory
|
32
|
+
trees 'in place', so that the original files are\noverwritten by their encrypted
|
33
|
+
versions.\n\n"
|
18
34
|
email: jpsember@gmail.com
|
19
35
|
executables:
|
36
|
+
- encr
|
20
37
|
- lencrypt
|
21
38
|
extensions: []
|
22
39
|
extra_rdoc_files: []
|
@@ -25,10 +42,12 @@ files:
|
|
25
42
|
- lib/lenc/_OLD_tools.rb
|
26
43
|
- lib/lenc/aes.rb
|
27
44
|
- lib/lenc/config_file.rb
|
45
|
+
- lib/lenc/encr.rb
|
28
46
|
- lib/lenc/lencrypt.rb
|
29
47
|
- lib/lenc/repo.rb
|
30
48
|
- lib/lenc/tools.rb
|
31
49
|
- lib/lenc/trollop.rb
|
50
|
+
- bin/encr
|
32
51
|
- bin/lencrypt
|
33
52
|
- CHANGELOG.txt
|
34
53
|
- README.md
|
@@ -53,7 +72,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
53
72
|
version: '0'
|
54
73
|
requirements: []
|
55
74
|
rubyforge_project:
|
56
|
-
rubygems_version: 2.0.
|
75
|
+
rubygems_version: 2.0.0
|
57
76
|
signing_key:
|
58
77
|
specification_version: 4
|
59
78
|
summary: Maintains an encrypted repository of a set of files for secure cloud storage.
|