bpo-32713: Fix tarfile.itn for large/negative float values. (GH-5434)
[python-delta-tar] / file_crypt.py
CommitLineData
fb2a6083
CH
1#!/usr/bin/env python3
2
6a86cf3e 3""" Encrypt/decrypt a single file
fb2a6083
CH
4
5low-cost quick-devel badly-documented
6
7.. codeauthor:: Intra2net <info@intra2net.com>
8"""
9
10import sys
056a457c 11from deltatar import crypto
fb2a6083
CH
12from deltatar import tarfile
13from traceback import print_exc
14
15
056a457c
PG
16CRYPTO_MODE_ENCRYPT = 0
17CRYPTO_MODE_DECRYPT = 1
18
19
20def initialize_encryption (mode, password=None, key=None, nacl=None):
21 if key is None and password is None:
22 raise Exception ("encryption requires either a key or a password")
23 if mode == CRYPTO_MODE_ENCRYPT:
24 return crypto.Encrypt (password=password,
25 key=key,
26 nacl=nacl,
27 version=crypto.PDTCRYPT_DEFAULT_VER,
28 paramversion=crypto.PDTCRYPT_DEFAULT_PVER)
29 if mode == CRYPTO_MODE_DECRYPT:
30 return crypto.Decrypt (password=password, key=key)
31
32
ed00ce08 33def main(do_encrypt, in_file, out_file, password, comptype='gz',
e37669e3 34 bufsize=tarfile.RECORDSIZE, encoding='UTF-8'):
fb2a6083
CH
35 """ Main function, called when running file as script
36
37 see module doc for more info
38 """
39
40 write_handle = read_handle = None
41 return_code = 4
42
43 try:
44 # open file to read
45 if do_encrypt:
68a5e96d 46 read_handle = open(in_file, 'rb')
fb2a6083 47 else:
056a457c
PG
48 decryptor = initialize_encryption (CRYPTO_MODE_DECRYPT,
49 password=password)
50 read_handle = tarfile._Stream(name=in_file, mode="r",
fb2a6083 51 comptype=comptype, bufsize=bufsize,
056a457c 52 fileobj=None, encryption=decryptor)
fb2a6083
CH
53 return_code = 3
54
55 # open file to write
56 if do_encrypt:
056a457c
PG
57 encryptor = initialize_encryption (CRYPTO_MODE_ENCRYPT,
58 password=password)
fb2a6083
CH
59 write_handle = tarfile._Stream(name=out_file, mode='w',
60 comptype=comptype, bufsize=bufsize,
056a457c 61 fileobj=None, encryption=encryptor)
fb2a6083 62 else:
68a5e96d 63 write_handle = open(out_file, 'wb')
fb2a6083
CH
64 return_code = 1
65
66 # convert
68a5e96d 67 total = 0
fb2a6083
CH
68 while True:
69 buf = read_handle.read(bufsize)
68a5e96d 70 total += len(buf)
fb2a6083
CH
71 print('.', end='')
72 if do_encrypt:
68a5e96d 73 write_handle.write(buf)
fb2a6083 74 else:
68a5e96d
PG
75 # write_handle.write(buf.decode(encoding, errors='replace'))
76 write_handle.write(buf)
fb2a6083
CH
77 if len(buf) < bufsize:
78 if do_encrypt:
79 print('successfully encrypted {} into {}'
80 .format(in_file, out_file))
81 else:
82 print('successfully decrypted {} into {}'
83 .format(in_file, out_file))
84 break # reached EOF
85
86 return_code = 0
87
88 except Exception:
89 print('error encrypting file')
90 print_exc()
91
92 finally:
93 # close everything
94 if write_handle:
95 try:
96 write_handle.close()
97 except Exception:
98 return_code += 8
99 print('error closing out file')
100 print_exc()
101
102 if read_handle:
103 try:
104 read_handle.close()
105 except Exception:
106 return_code += 16
107 print('error closing in file')
108 print_exc()
109
110 # done
111 return return_code
112
113
114if __name__ == '__main__':
115 if len(sys.argv) < 4:
fe646953 116 print('file_crypt.py [-c] {enc|dec} INFILE OUTFILE PASSWORD')
fb2a6083
CH
117 sys.exit(2)
118 elif sys.argv[1] == '-h':
fe646953 119 print('file_crypt.py [-c] {enc|dec} INFILE OUTFILE PASSWORD')
fb2a6083
CH
120 sys.exit(0)
121
122 comptype = 'tar' # auto-detect, not sure whether this would work
123 idx = 1
124 if sys.argv[idx] == '-c':
125 print('assuming gzip compression')
126 comptype = 'gz'
127 idx += 1
128
129 do_encrypt = None
130 if sys.argv[idx] == 'enc':
131 do_encrypt = True
132 elif sys.argv[idx] == 'dec':
133 do_encrypt = False
134 else:
fe646953 135 print('file_crypt.py [-c] {enc|dec} INFILE OUTFILE PASSWORD')
fb2a6083
CH
136 sys.exit(2)
137
138 if len(sys.argv) != idx+4:
fe646953 139 print('file_crypt.py [-c] {enc|dec} INFILE OUTFILE PASSWORD')
fb2a6083
CH
140 sys.exit(2)
141
142 sys.exit(main(do_encrypt, sys.argv[idx+1], sys.argv[idx+2],
143 sys.argv[idx+3], comptype))