Skip to content

Commit 33ada32

Browse files
author
8go
committed
added options --safety and --wipe, made encrypted files read-only, minor bug fix
1 parent 0927d7a commit 33ada32

6 files changed

Lines changed: 213 additions & 714 deletions

File tree

LICENSE

Lines changed: 0 additions & 674 deletions
This file was deleted.

README.md

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ Run:
7474
Run-time command line options are
7575

7676
```
77-
TrezorSymmetricFileEncryption.py [-v] [-h] [-l <level>] [-t] [-2] [-o | -e | -d | -n] [-p <passphrase>] <files>
77+
TrezorSymmetricFileEncryption.py [-v] [-h] [-l <level>] [-t] [-2] [-s] [-w] [-o | -e | -d | -n] [-p <passphrase>] <files>
7878
-v, --verion
7979
print the version number
8080
-h, --help
@@ -107,6 +107,15 @@ TrezorSymmetricFileEncryption.py [-v] [-h] [-l <level>] [-t] [-2] [-o | -e | -d
107107
master passphrase used for Trezor.
108108
It is recommended that you do not use this command line option
109109
but rather give the passphrase through a small window interaction.
110+
-s, --safety
111+
doublechecks the encryption process by decrypting the just
112+
encrypted file immediately and comparing it to original file;
113+
only relevant for `-e` and `-o`; ignored in all other cases.
114+
Primarily useful for testing.
115+
-w, --wipe
116+
shred the plaintext file after encryption;
117+
only relevant for `-e` and `-o`; ignored in all other cases.
118+
Use with caution. May be used together with `-s`.
110119
<files>
111120
one or multiple files to be encrypted or decrypted
112121
@@ -139,6 +148,30 @@ TrezorSymmetricFileEncryption.py [-v] [-h] [-l <level>] [-t] [-2] [-o | -e | -d
139148
Be aware of computation time and file sizes when you use `-2` option.
140149
Encrypting on the Trezor takes time: 1M roughtly 75sec. 50M about 1h.
141150
Without `-2` it is very fast, a 1G file taking roughly 15 seconds.
151+
152+
For safety the file permission of encrypted files is set to read-only.
153+
154+
Examples:
155+
# specify everything in the GUI
156+
TrezorSymmetricFileEncryption.py
157+
158+
# specify everything in the GUI, set logging to verbose Debug level
159+
TrezorSymmetricFileEncryption.py -l 1
160+
161+
# encrypt contract producing contract.doc.tsfe
162+
TrezorSymmetricFileEncryption.py contract.doc
163+
164+
# encrypt contract and obfuscate output producing e.g. TQFYqK1nha1IfLy_qBxdGwlGRytelGRJ
165+
TrezorSymmetricFileEncryption.py -o contract.doc
166+
167+
# decrypt contract producing contract.doc
168+
TrezorSymmetricFileEncryption.py contract.doc.tsfe
169+
170+
# decrypt obfuscated contract producing contract.doc
171+
TrezorSymmetricFileEncryption.py TQFYqK1nha1IfLy_qBxdGwlGRytelGRJ
172+
173+
# shows plaintext name of encrypted file, e.g. contract.doc
174+
TrezorSymmetricFileEncryption.py -n TQFYqK1nha1IfLy_qBxdGwlGRytelGRJ
142175
```
143176

144177
# Testing

TrezorSymmetricFileEncryption.py

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ def chooseDevice(self, devices):
147147
deviceStr = dialog.chosenDeviceStr()
148148
return HidTransport([deviceStr, None])
149149

150-
def showGui(trezor, settings, fileMap, logger):
150+
def showGui(trezor, settings, fileMap, logger, feedback):
151151
"""
152152
Initialize, ask for encrypt/decrypt options,
153153
ask for files to be decrypted/encrypted,
@@ -165,16 +165,23 @@ def showGui(trezor, settings, fileMap, logger):
165165
settings.settings2Gui(dialog, trezor)
166166
if settings.logger.getEffectiveLevel() <= logging.INFO:
167167
dialog.appendDescription("<br>Trezor label: " + trezor.features.label)
168+
if settings.WArg and settings.logger.getEffectiveLevel() <= logging.WARN:
169+
dialog.appendDescription("<br>Warning: The option `--wipe` is set. Plaintext files will "
170+
"be shredded after encryption. Abort if you are uncertain or don't understand.")
168171
if not dialog.exec_():
169-
logger.debug("Shutting down due to user request (Done/Quit was called).")
172+
settings.guiExists = False
173+
processing.reportLogging("Shutting down due to user request "
174+
"(Done/Quit was called).", logging.DEBUG,
175+
"GUI IO", settings, logger)
170176
sys.exit(4) # Esc or exception
171177
settings.guiExists = False
172178
settings.gui2Settings(dialog,trezor)
173179

174180
# root
175181

176182
logging.basicConfig(stream=sys.stderr, level=basics.LOGGINGLEVEL)
177-
logger = logging.getLogger('')
183+
logger = logging.getLogger('tsfe')
184+
feedback = processing.Feedback()
178185

179186
app = QtGui.QApplication(sys.argv)
180187

@@ -186,21 +193,13 @@ def showGui(trezor, settings, fileMap, logger):
186193
trezorChooser = TrezorChooser()
187194
trezor = trezorChooser.getDevice()
188195
except (ConnectionError, RuntimeError), e:
189-
if settings.TArg:
190-
logger.critical("Connection to Trezor failed: %s", e.message)
191-
else:
192-
msgBox = QtGui.QMessageBox(QtGui.QMessageBox.Critical,
193-
"Trezor error", "Error: Connection to Trezor failed: " + e.message)
194-
msgBox.exec_()
196+
processing.reportLogging("Connection to Trezor failed: %s" % e.message,
197+
logging.CRITICAL, "Trezor Error", settings, logger)
195198
sys.exit(1)
196199

197200
if trezor is None:
198-
if settings.TArg:
199-
logger.critical("No available Trezor found, quitting.")
200-
else:
201-
msgBox = QtGui.QMessageBox(QtGui.QMessageBox.Critical,
202-
"Trezor error", "No available Trezor found, quitting.")
203-
msgBox.exec_()
201+
processing.reportLogging("No available Trezor found, quitting.",
202+
logging.CRITICAL, "Trezor Error", settings, logger)
204203
sys.exit(1)
205204

206205
trezor.clear_session()
@@ -213,13 +212,12 @@ def showGui(trezor, settings, fileMap, logger):
213212
# if everything is specified in the command line then do not call the GUI
214213
if ((settings.PArg is None) or (len(settings.inputFiles) <= 0)) and (not settings.TArg):
215214
# something was not specified, so we call the GUI
216-
showGui(trezor, settings, fileMap, logger)
215+
showGui(trezor, settings, fileMap, logger, feedback)
217216
else:
218217
logger.info("Everything was specified or --terminal was set, "
219218
"hence the GUI will not be called.")
220-
if settings.PArg is None:
221-
settings.PArg = ""
219+
if settings.PArg is not None:
220+
trezor.prefillPassphrase(settings.PArg)
222221

223-
feedback = processing.Feedback()
224222
processing.processAll(trezor, settings, fileMap, logger, feedback)
225223
sys.exit(0)

basics.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
TSFEFILEFORMATVERSION = 1
88

99
# Name of software version, must be less than 16 long
10-
TSFEVERSION = "v0.3.1"
10+
TSFEVERSION = "v0.3.2"
1111

1212
# default log level
1313
LOGGINGLEVEL = logging.INFO # CRITICAL, ERROR, WARNING, INFO, DEBUG

dialogs.py

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
1-
from PyQt4 import QtGui, QtCore
2-
31
import os
42
import os.path
53
import base64
64
import hashlib
5+
import logging
6+
7+
from PyQt4 import QtGui, QtCore
78

89
from ui_trezor_passphrase_dialog import Ui_TrezorPassphraseDialog
910
from ui_dialog import Ui_Dialog
1011
from ui_enter_pin_dialog import Ui_EnterPinDialog
1112
from ui_trezor_chooser_dialog import Ui_TrezorChooserDialog
1213

1314
from encoding import q2s, s2q
14-
from processing import processAllFromApply
15+
from processing import processAllFromApply, reportLogging
1516

1617
class TrezorPassphraseDialog(QtGui.QDialog, Ui_TrezorPassphraseDialog):
1718

@@ -79,12 +80,15 @@ def selectionChanged(self):
7980
called whenever selected text in textarea is changed
8081
"""
8182
# self.textBrowser.copy() # copy selected to clipboard
82-
# print self.clipboard.text() # print clipboard
83+
# reportLogging("Copied text to clipboard: %s" % self.clipboard.text(),
84+
# logging.DEBUG, "Clipboard", self.settings, self.logger)
8385
""" empty """
8486

8587
def copy2Clipboard(self):
8688
self.textBrowser.copy() # copy selected to clipboard
87-
self.logger.debug("Copied to clipboard: %s", self.clipboard.text()) # print clipboard
89+
# This is content from the Status textarea, so no secrets here, we can log it
90+
reportLogging("Copied text to clipboard: %s" % self.clipboard.text(), logging.DEBUG,
91+
"Clipboard", self.settings, self.logger)
8892

8993
def setVersion(self, version):
9094
self.version = version
@@ -231,14 +235,16 @@ def validate(self):
231235
# feedback = processAllFromApply(self, self.trezor, self.settings, self.fileMap, self.logger) #
232236
# self.appendDescription(feedback)
233237
# # elif sb == QtGui.QDialogButtonBox.Reset:
234-
# # print('Reset Clicked, quitting now...')
238+
# # reportLogging("Reset Clicked, quitting now...", logging.DEBUG,
239+
# # "UI", self.settings, self.logger)
235240

236241
def accept(self):
237242
"""
238-
Apply button was pinpadPressed
243+
Apply button was pressed
239244
"""
240245
if self.validate():
241-
self.logger.debug("Apply was called by user request. Start processing now.")
246+
reportLogging("Apply was called by user request. Start processing now.",
247+
logging.DEBUG, "GUI IO", self.settings, self.logger)
242248
feedback = processAllFromApply(self, self.trezor, self.settings, self.fileMap, self.logger) #
243249
self.appendDescription(feedback)
244250
# move the cursor to the end of the text, scroll to the bottom
@@ -247,7 +253,9 @@ def accept(self):
247253
self.textBrowser.ensureCursorVisible()
248254
self.textBrowser.setTextCursor(cursor)
249255
else:
250-
self.logger.debug("Apply was called by user request. Apply is denied. User input is not valid for processing. Did you select a file?")
256+
reportLogging("Apply was called by user request. Apply is denied. "
257+
"User input is not valid for processing. Did you select a file?",
258+
logging.DEBUG, "GUI IO", self.settings, self.logger)
251259

252260
# Don't set up a reject() method, it is automatically created.
253261
# If created here again it would overwrite the default one
@@ -270,7 +278,8 @@ def selectFile(self):
270278

271279
qFnameList = dialog.selectedFiles() # QStringList
272280
self.fileNames = str(qFnameList.join("<join>")).split("<join>") # convert to Py list
273-
self.logger.debug("Selected files are: " + str(self.fileNames))
281+
reportLogging("Selected files are: %s" % str(self.fileNames),
282+
logging.DEBUG, "GUI IO", self.settings, self.logger)
274283
self.setSelectedFile(self.fileNames)
275284

276285
class EnterPinDialog(QtGui.QDialog, Ui_EnterPinDialog):

0 commit comments

Comments
 (0)