tomb

the crypto undertaker
git clone git://parazyd.org/tomb.git
Log | Files | Refs | README | LICENSE

commit a6da0dbb93e6e77729839ffbf1bd363072aaaa22
parent 6f0bc82e07c56602988c53dbd8dff95cefe04577
Author: boyska <piuttosto@logorroici.org>
Date:   Sun, 29 Jan 2012 19:18:41 +0100

Merge branch 'qtgui' basic ftrs for create/open

Create is quite good, but has no support for automatic-key-on-usb
Open is very raw, it only supports opening while explicitly choosing
where to get the key from

Python wrapper for tomb is in a distinct library, called "tomblib":
it currently supports tomb, basic undertaker, and parsing output
messages

Diffstat:
Asrc/HACKING.txt | 12++++++++++++
Msrc/Makefile.am | 2+-
Asrc/pytomb/.gitignore | 5+++++
Asrc/pytomb/.wrapper.py.swp | 0
Asrc/pytomb/setup.py | 11+++++++++++
Asrc/pytomb/tomblib/__init__.py | 0
Asrc/pytomb/tomblib/parser.py | 34++++++++++++++++++++++++++++++++++
Asrc/pytomb/tomblib/test_parser.py | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/pytomb/tomblib/tomb.py | 91+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/pytomb/tomblib/undertaker.py | 79+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/qt/.gitignore | 6++++++
Asrc/qt/Makefile | 23+++++++++++++++++++++++
Asrc/qt/notes.txt | 9+++++++++
Asrc/qt/setup.py | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/qt/tombqt/__init__.py | 0
Asrc/qt/tombqt/create.py | 134+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/qt/tombqt/create.ui | 553+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/qt/tombqt/open.py | 109+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/qt/tombqt/open.ui | 239+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/qt/tombqt/open_choosekey.ui | 147+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/qt/tombqt/open_keymethod.ui | 84+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/qt/tombqt/open_success.ui | 34++++++++++++++++++++++++++++++++++
Asrc/qt/tombqt/open_tombfile.ui | 79+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/qt/tombqt/ui_create.py | 282+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/qt/tombqt/ui_open_keymethod.py | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/qt/tombqt/ui_open_success.py | 35+++++++++++++++++++++++++++++++++++
Asrc/qt/tombqt/ui_open_tombfile.py | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/qt/tombqt/worker.py | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/tomb | 73++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
Msrc/undertaker | 32+++++++++++++++++---------------
30 files changed, 2303 insertions(+), 39 deletions(-)

diff --git a/src/HACKING.txt b/src/HACKING.txt @@ -0,0 +1,12 @@ +### Code organization: +* tomblib: a library that wraps on tomb. Meant to be used by various scripts, and every UI +* qt / wx / whatever: directory for different gui implementations + +### QT project: + +status: only create wizard +the graphical part is done through create.ui, which can be edited by designer + +The UI should be (if possible) completely autocontained in this .ui file, and no code (or very few) should be added to make it work. +* ATM, some code has been added for the "password don't match" part. +* Some code need to be added to make the filedialog work diff --git a/src/Makefile.am b/src/Makefile.am @@ -1,5 +1,5 @@ -bin_SCRIPTS = tomb tomb-open +bin_SCRIPTS = tomb tomb-open undertaker bin_PROGRAMS = tomb-status diff --git a/src/pytomb/.gitignore b/src/pytomb/.gitignore @@ -0,0 +1,5 @@ +.*.swp +*.pyc +*.egg-info +build +dist diff --git a/src/pytomb/.wrapper.py.swp b/src/pytomb/.wrapper.py.swp Binary files differ. diff --git a/src/pytomb/setup.py b/src/pytomb/setup.py @@ -0,0 +1,11 @@ +from setuptools import setup + +setup( + name = 'TombLib', + version = '1.1', + packages = ['tomblib'], + + test_suite = 'nose.collector' +) + + diff --git a/src/pytomb/tomblib/__init__.py b/src/pytomb/tomblib/__init__.py diff --git a/src/pytomb/tomblib/parser.py b/src/pytomb/tomblib/parser.py @@ -0,0 +1,34 @@ +''' +Utilities to analyze tomb output +''' +import re + +#found: [m] followed by some ID (usually "found") inside square brackets, then +#something else, then a space, then the content +_found_regex = re.compile(r'^\[m\]\[([^]]+)\] +(([^:]+)://(.+))$') +#generic: programname, then some identifiers in square (or round) brackets, +#then maybe something else, then a space, then the context +_generic_regex = re.compile(r'^[a-z-]+ [[(]([^]]+)[\])] +(.+)$') +types = {'E':'error', 'W':'warning', 'D':'debug', '*':'success'} +def parse_line(line): + '''Analyze a single line. + Return None if no standard format is detected, a dict otherwise. + The fields 'type' and 'content' are always in the dict; 'content' may be + empty + 'type' can be 'error', 'progress' + ''' + + + match = _found_regex.match(line) + if match: + return { 'type': types.get(match.group(1)) or match.group(1), + 'content': match.group(2), 'scheme': match.group(3), + 'path': match.group(4) } + match = _generic_regex.search(line) + if match: + return { 'type': types.get(match.group(1)) or match.group(1), + 'content': match.group(2) } + + return None + + diff --git a/src/pytomb/tomblib/test_parser.py b/src/pytomb/tomblib/test_parser.py @@ -0,0 +1,52 @@ +from tomblib.parser import * + +class TestWrong: + def test_short(self): + '''short format is not supported anymore''' + assert parse_line('[!] foo') is None + def test_colors(self): + '''parsing while using colors should fail''' + parse = parse_line('\033[32mundertaker [W] url protocol not recognized: nonscheme') + assert parse is None + def test_no_spaces_in_programname(self): + parse = parse_line('tomb open [W] url protocol not recognized: nonscheme') + assert parse is None + +class TestFound: + def test_simple(self): + parse = parse_line('[m][found] scheme:///and/path') + assert parse is not None + assert parse['type'] == 'found' + assert parse['content'] == 'scheme:///and/path' + assert 'scheme' in parse + assert parse['scheme'] == 'scheme' + assert 'path' in parse + assert parse['path'] == '/and/path' + +class TestGeneric: + def test_simple(self): + parse = parse_line('undertaker [W] url protocol not recognized: nonscheme') + assert parse is not None + assert parse['type'] == 'warning' + assert parse['content'] == 'url protocol not recognized: nonscheme' + + def test_debug(self): + parse = parse_line('undertaker [D] url protocol not recognized: nonscheme') + assert parse is not None + assert parse['type'] == 'debug' + assert parse['content'] == 'url protocol not recognized: nonscheme' + + def test_success(self): + parse = parse_line('undertaker (*) url protocol not recognized: nonscheme') + assert parse is not None + assert parse['type'] == 'success' + assert parse['content'] == 'url protocol not recognized: nonscheme' + + def test_dash(self): + parse = parse_line('tomb-open [W] url protocol not recognized: nonscheme') + assert parse is not None + assert parse['type'] == 'warning' + assert parse['content'] == 'url protocol not recognized: nonscheme' + + + diff --git a/src/pytomb/tomblib/tomb.py b/src/pytomb/tomblib/tomb.py @@ -0,0 +1,91 @@ +''' +Module structure: + +this contain a class, which is indeed just a collection of functions +(the methods are all static). +It's meant to behave in a way which is similar to the command line, for + +Notes: consider moving to a more typical usage (instantiate, then use method) +to make it more configurable (ie set the tomb executable path). +''' + +import subprocess + +class Tomb(object): + ''' + This is just a collection of static methods, so you should NOT instantiate + + The methods are meant to resemble the command line interface as much as + possible + + There is no support to things like threading, multiprocessing, whatever. + If you want to interact asynchronously with tomb, just do it in a separate + layer. + ''' + tombexec = 'tomb' + def _check_exec_path(self): + '''Checks, using which, if tomb is available. + Returns None on error, the path on success. + ''' + try: + path = subprocess.check_output(['which', 'tomb']) + except subprocess.CalledProcessError: + return None + return path + + @classmethod + def check(cls, command, stdout=None, stderr=None, no_color=True, ignore_swap=False): + args = [command] + if no_color: + args += ['--no-color'] + if ignore_swap: + args += ['--ignore-swap'] + try: + subprocess.check_call([cls.tombexec, 'check'] + args, stdout=stdout, stderr=stderr) + except subprocess.CalledProcessError: + return False + return True + + @classmethod + def create(cls, tombpath, tombsize,keypath, stdout=None, stderr=None, + no_color=True, ignore_swap=False): + '''If keypath is None, it will be created adjacent to the tomb. + This is unsafe, and you should NOT do it. + + Note that this will invoke pinentry + + no_color is supported as an option for short-lived retrocompatibility: + it will be removed as soon as no-color will be integrated + ''' + args = [tombpath, '-s', tombsize] + if keypath is not None: + args += ['-k', keypath] + if no_color: + args += ['--no-color'] + if ignore_swap: + args += ['--ignore-swap'] + try: + subprocess.check_call([cls.tombexec, 'create'] + args, stdout=stdout, stderr=stderr) + except subprocess.CalledProcessError: + return False + return True + + @classmethod + def open(cls, tombpath,keypath=None, no_color=True, ignore_swap=False): + args = [tombpath] + if keypath is not None: + args += ['-k', keypath] + if no_color: + args += ['--no-color'] + if ignore_swap: + args += ['--ignore-swap'] + try: + subprocess.check_call([cls.tombexec, 'open'] + args) + except subprocess.CalledProcessError: + return False + return True + + +if __name__ == '__main__': + #Debug stuff. Also useful for an example + print Tomb.create('/tmp/a.tomb', '10', '/tmp/akey') diff --git a/src/pytomb/tomblib/undertaker.py b/src/pytomb/tomblib/undertaker.py @@ -0,0 +1,79 @@ +import subprocess +from tempfile import NamedTemporaryFile + +import parser + +class Undertaker(object): + ''' + This is similar to Tomb class, and provides a wrapper on undertaker. + + TODO: + * methods for automagical scan + * output parsing, giving meaningful output + + Due to the non-interactive nature of undertaker, it's simpler than Tomb + ''' + undertakerexec = 'undertaker' + @classmethod + def check(cls, paths): + '''Will check if there are keys available there, as in --path + + paths can be a string (one address), or a list of + ''' + #TODO: more solid check: something like + if type(paths) is not str: + out = [] + for p in paths: + try: + res = cls.check(p) + except: + continue + else: + if res: + out.extend(res) + return out + + buf = NamedTemporaryFile() + try: + subprocess.check_call([cls.undertakerexec, paths, '--batch', + '--path'], stderr=buf) + except subprocess.CalledProcessError as exc: + return False + + out = [] + buf.seek(0) + for line in buf: + ret = parser.parse_line(line) + if ret and ret['type'] == 'found': + out.append(ret['content']) + return out + + + @classmethod + def get(cls, paths): + ''' + Similar to check, but truly get the key content. + If paths is iterable, stop at the first successful path + ''' + if type(paths) is not str: + for p in paths: + try: + res = cls.get(p) + except: + continue + else: + if res: + return res + buf = NamedTemporaryFile() + try: + subprocess.check_call([cls.undertakerexec, paths, '--batch'], + stdout=buf) + except subprocess.CalledProcessError: + return False + buf.seek(0) + return buf.read() + + +if __name__ == '__main__': + Undertaker.undertakerexec = '/home/davide/coding/projects/tomb/src/undertaker' + print Undertaker.get('near:///home/davide/Desktop/testing.tomb') diff --git a/src/qt/.gitignore b/src/qt/.gitignore @@ -0,0 +1,6 @@ +.*.swp +*.pyc +TombQt.egg-info +build +dist +disk diff --git a/src/qt/Makefile b/src/qt/Makefile @@ -0,0 +1,23 @@ +TARGETS_OPEN=tombqt/ui_open_tombfile.py tombqt/ui_open_keymethod.py tombqt/ui_open_success.py +TARGETS=tombqt/ui_create.py $(TARGETS_OPEN) + +all: $(TARGETS) +test_create: tombqt/ui_create.py + python2 -3 tombqt/create.py +test_open: $(TARGETS_OPEN) + python2 -3 tombqt/open.py + + +tombqt/ui_create.py: tombqt/create.ui + pyuic4 create.ui -o tombqt/ui_create.py +tombqt/ui_open_tombfile.py: tombqt/open_tombfile.ui + pyuic4 tombqt/open_tombfile.ui -o tombqt/ui_open_tombfile.py +tombqt/ui_open_keymethod.py: tombqt/open_keymethod.ui + pyuic4 tombqt/open_keymethod.ui -o tombqt/ui_open_keymethod.py +tombqt/ui_open_success.py: tombqt/open_success.ui + pyuic4 tombqt/open_success.ui -o tombqt/ui_open_success.py + +clean: + rm $(TARGETS) + +.PHONY: test clean diff --git a/src/qt/notes.txt b/src/qt/notes.txt @@ -0,0 +1,9 @@ +Some conventions: +.ui files are designers files +Sometimes it's necessary to create custom widget to extend the functionality +given by designer in a clean way. These files should be called ui_whatever.py + +.ui files must be "compiled" using pyuic4. This should be done with make, but +won't be right now. So, for the moment, I'll keep compiled files directly in +the sources, for easiness. + diff --git a/src/qt/setup.py b/src/qt/setup.py @@ -0,0 +1,52 @@ +import os +import glob +from setuptools import setup +from StringIO import StringIO + +from distutils import log +from distutils.core import Command +from distutils.dep_util import newer + +class build_ui(Command): +# Stolen from picard + description = "build Qt UI files" + user_options = [] + + def initialize_options(self): + pass + + def finalize_options(self): + pass + + def run(self): + from PyQt4 import uic + for uifile in glob.glob("tombqt/*.ui"): + pyfile = "ui_%s.py" % os.path.splitext(os.path.basename(uifile))[0] + pyfile = os.path.join('tombqt', pyfile) + if newer(uifile, pyfile): + log.info("compiling %s -> %s", uifile, pyfile) + tmp = StringIO() + uic.compileUi(uifile, tmp) + source = tmp.getvalue() + f = open(pyfile, "w") + f.write(source) + f.close() + +setup( + name = 'TombQt', + version = '0.1', + packages = ['tombqt'], + cmdclass = { + 'build_ui': build_ui + }, + entry_points = { + 'gui_scripts': [ + 'tomb-qt-create = tombqt.create:run_create_wizard', + 'tomb-qt-open = tombqt.open:run_open_wizard' + ] + } +) + + + + diff --git a/src/qt/tombqt/__init__.py b/src/qt/tombqt/__init__.py diff --git a/src/qt/tombqt/create.py b/src/qt/tombqt/create.py @@ -0,0 +1,134 @@ +import sys, os + +from PyQt4.QtGui import QApplication, QWizard +from PyQt4 import QtCore +from PyQt4 import QtGui +from ui_create import Ui_Wizard + +if __name__ == '__main__': + parentdir = sys.path[0].split(os.sep)[:-1] + sys.path.append(os.sep.join(parentdir)) +from tomblib.tomb import Tomb +from worker import TombCreateThread + +try: + _fromUtf8 = QtCore.QString.fromUtf8 +except AttributeError: + _fromUtf8 = lambda s: s + +class TombCreateWizard(QWizard): + def __init__(self, *args, **kwargs): + QWizard.__init__(self, *args, **kwargs) + self.ui = ui = Ui_Wizard() + ui.setupUi(self) + #instance attributes: + self.ignore_swap = False + self._tomb_check = False #ugly; it's used by check_progress_complete + + ui.wizardPage_tomb_location.registerField('tombpath*', + ui.lineEdit_tombpath) #required field, note the * + ui.wizardPage_key_location.setCommitPage(True) + + QtCore.QObject.connect(ui.button_tombpath, + QtCore.SIGNAL(_fromUtf8('clicked()')), + self.on_tomb_location_clicked) + QtCore.QObject.connect(self, + QtCore.SIGNAL(_fromUtf8('currentIdChanged(int)')), + self.on_change_page) + QtCore.QObject.connect(ui.radioButton_swapoff, + QtCore.SIGNAL(_fromUtf8('toggled(bool)')), + ui.wizardPage_check.completeChanged) + QtCore.QObject.connect(ui.radioButton_ignore, + QtCore.SIGNAL(_fromUtf8('toggled(bool)')), + ui.wizardPage_check.completeChanged) + def check_progress_complete(*args, **kwargs): + if self.ui.progressBar.value() == 100: + return True + return False + def check_is_solved(): + if self._tomb_check: + return True + if self.ui.radioButton_swapoff.isChecked() or \ + self.ui.radioButton_ignore.isChecked(): + return True + return False + self.ui.wizardPage_progress.isComplete = check_progress_complete + self.ui.wizardPage_check.isComplete = check_is_solved + self.ui.groupBox_swap.setVisible(False) + self.finished.connect(self.on_finish) + + def _keyloc(self): + keyloc = None + if self.ui.radioButton_usb.isChecked(): + print 'Warning: it is not supported' + raise NotImplementedError + elif self.ui.radioButton_near.isChecked(): + print 'going near' + keyloc = None + else: + keyloc = self.ui.lineEdit_custom.text() + if not keyloc: + raise ValueError + return keyloc + + def on_tomb_location_clicked(self, *args, **kwargs): + filename = QtGui.QFileDialog.getSaveFileName(self, 'Create Tomb', + filter="Tomb(*.tomb)") + self.ui.lineEdit_tombpath.setText(filename) + def on_change_page(self, pagenumber): + if self.currentPage() == self.ui.wizardPage_progress: + self.create_tomb() + if self.currentPage() == self.ui.wizardPage_check: + self.check_requisite() + + def on_finish(self, finishedint): + if self.currentPage() != self.ui.wizardPage_end: + #there has been an error + return + + if self.ui.checkBox_open.isChecked(): + Tomb.open(self.ui.lineEdit_tombpath.text(), self._keyloc()) + def on_thread_creation_finished(self): + if self.thread.get_success(): + self.ui.progressBar.setValue(100) + else: + self.ui.progressBar.setEnabled(False) + self.ui.label_progress.setText('Error while creating the tomb!') + self.ui.wizardPage_progress.setFinalPage(True) + self.ui.wizardPage_progress.completeChanged.emit() + def create_tomb(self): + self.thread = TombCreateThread(self.ui.lineEdit_tombpath.text(), + str(self.ui.spinBox_size.value()), self._keyloc(), + no_color=False, ignore_swap=self.ui.radioButton_ignore.isChecked()) + self.thread.finished.connect(self.on_thread_creation_finished) + self.thread.terminated.connect(self.on_thread_creation_finished) + self.thread.line_received.connect(self.ui.textBrowser_log.append) + def err_append_to_log(text): + self.ui.textBrowser_log.append('Error: <strong>' + text + + '</strong>') + self.thread.error_received.connect(err_append_to_log) + self.thread.start() + def check_requisite(self): + self._tomb_check = check = Tomb.check('create', no_color=False) + self.ui.wizardPage_check.completeChanged.emit() + if check: + self.ui.label_check.setText('Everything seems fine!') + return + self.ui.label_check.setText('Some error occurred') + if Tomb.check('create', no_color=False, ignore_swap=True): # swap is the only error + self.ui.groupBox_swap.setVisible(True) + #TODO: support swapoff + #TODO: calculate the amount of ram available vs swap used + self.ui.radioButton_swapoff.setEnabled(False) + self.ui.label_swapoff.setEnabled(False) + + +def run_create_wizard(): + app = QApplication(sys.argv) + window = TombCreateWizard() + window.show() + sys.exit(app.exec_()) + +if __name__ == '__main__': + run_create_wizard() + diff --git a/src/qt/tombqt/create.ui b/src/qt/tombqt/create.ui @@ -0,0 +1,553 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Wizard</class> + <widget class="QWizard" name="Wizard"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>710</width> + <height>368</height> + </rect> + </property> + <property name="windowTitle"> + <string>Wizard</string> + </property> + <property name="options"> + <set>QWizard::HaveHelpButton|QWizard::IndependentPages</set> + </property> + <widget class="QWizardPage" name="wizardPage_intro"> + <property name="title"> + <string>Tomb</string> + </property> + <property name="subTitle"> + <string>tomb creation</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>This wizard will guide you to the creation of a tomb.&lt;br&gt; It will be fun!</string> + </property> + <property name="textFormat"> + <enum>Qt::RichText</enum> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + <widget class="QWizardPage" name="wizardPage_check"> + <property name="title"> + <string>Requirements check</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_12"> + <item> + <widget class="QLabel" name="label_check"> + <property name="text"> + <string>Checking...</string> + </property> + </widget> + </item> + <item> + <widget class="QGroupBox" name="groupBox_swap"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="title"> + <string>Swap error</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_13"> + <item> + <widget class="QLabel" name="label_7"> + <property name="text"> + <string>It seems that you have swap activated. It is very dangerous, since you could leave LOT of traces on your computer UNencrypted. You have some options:</string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <layout class="QVBoxLayout" name="verticalLayout_swapoff"> + <item> + <widget class="QRadioButton" name="radioButton_swapoff"> + <property name="text"> + <string>Swapoff</string> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_6"> + <item> + <spacer name="horizontalSpacer_3"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Maximum</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="label_swapoff"> + <property name="text"> + <string>Note: swapoff could take a long time, and, in case the memory is not enough, could even make your system crash. Your system seems to have %freeram%MB free</string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </item> + <item> + <layout class="QVBoxLayout" name="verticalLayout_11"> + <item> + <widget class="QRadioButton" name="radioButton_ignore"> + <property name="text"> + <string>Ignore</string> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_7"> + <item> + <spacer name="horizontalSpacer_4"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Maximum</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="label_9"> + <property name="text"> + <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt; +&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt; +p, li { white-space: pre-wrap; } +&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'DejaVu Sans'; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt; +&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Note:&lt;/span&gt; You should use this only if you are sure that your swap is encrypted, or that you are using compcache.&lt;/p&gt; +&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;If this is not the case, DON'T select this, as it is &lt;span style=&quot; font-weight:600;&quot;&gt;VERY DANGEROUS &lt;/span&gt;to use encryption with swap activated&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + <widget class="QWizardPage" name="wizardPage_tomb_size"> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Please enter tomb size. Digging the tomb will require some time: usually, one minute per GB, but your mileage may vary. &lt;br&gt;Keep in mind that resizing it in the future is still NOT implemented</string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Enter tomb size, in MB. 1GB=1000MB)</string> + </property> + <property name="buddy"> + <cstring>spinBox_size</cstring> + </property> + </widget> + </item> + <item> + <widget class="QSpinBox" name="spinBox_size"> + <property name="minimum"> + <number>10</number> + </property> + <property name="maximum"> + <number>100000</number> + </property> + <property name="value"> + <number>100</number> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <widget class="QWizardPage" name="wizardPage_tomb_location"> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <item> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>Where do you want your tomb to be digged?</string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + <property name="buddy"> + <cstring>lineEdit_tombpath</cstring> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QLineEdit" name="lineEdit_tombpath"> + <property name="frame"> + <bool>true</bool> + </property> + <property name="placeholderText"> + <string>/path/to/file.tomb</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="button_tombpath"> + <property name="text"> + <string>Open file</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <widget class="QWizardPage" name="wizardPage_key_location"> + <property name="title"> + <string>Key creation</string> + </property> + <property name="subTitle"> + <string>Choose the location for your key</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_6"> + <item> + <widget class="QLabel" name="label_5"> + <property name="text"> + <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt; +&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt; +p, li { white-space: pre-wrap; } +&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt; +&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Now, you have to decide where to put the &lt;span style=&quot; font-weight:600;&quot;&gt;key&lt;/span&gt; for your tomb&lt;br /&gt;You should not leave your key at the door, as this will lower security A LOT&lt;/p&gt; +&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Also, the keyfile is very small (less than a KB), so disk space is not an issue&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> + </property> + <property name="textFormat"> + <enum>Qt::RichText</enum> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <layout class="QVBoxLayout" name="verticalLayout_5"> + <item> + <layout class="QVBoxLayout" name="verticalLayout_4"> + <item> + <widget class="QRadioButton" name="radioButton_usb"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>On a USB pen (best security)</string> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="checked"> + <bool>false</bool> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_4"> + <item> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Maximum</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="label_6"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>If you choose to do so, do not insert it NOW. Do it when you are asked to do so</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </item> + <item> + <widget class="QRadioButton" name="radioButton_near"> + <property name="toolTip"> + <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt; +&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt; +p, li { white-space: pre-wrap; } +&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt; +&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;It will be created as a regular file in the same directory of your tomb.&lt;/p&gt; +&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;It is much easier to use, but also much more &lt;span style=&quot; font-style:italic;&quot;&gt;insecure&lt;/span&gt;: all your security will be guaranteed by your &lt;span style=&quot; font-weight:600;&quot;&gt;password&lt;/span&gt;. If you really want to do this, choose a strong password (lot of random/non-dictionary words, spaces, numbers, odd characters)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> + </property> + <property name="text"> + <string>Near to the tomb itself (this is BAD)</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="radioButton_custom"> + <property name="text"> + <string>Specify location</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Maximum</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLineEdit" name="lineEdit_custom"> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="pushButton_custom"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Choose location</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QLabel" name="label_11"> + <property name="text"> + <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt; +&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt; +p, li { white-space: pre-wrap; } +&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt; +&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Help: &lt;/span&gt;the key file is very small, so disk usage is not an issue&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + <widget class="QWizardPage" name="wizardPage_progress"> + <property name="title"> + <string>Creating</string> + </property> + <property name="subTitle"> + <string>Please wait</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_9"> + <item> + <layout class="QVBoxLayout" name="verticalLayout_7"> + <item> + <widget class="QProgressBar" name="progressBar"> + <property name="value"> + <number>0</number> + </property> + <property name="textVisible"> + <bool>true</bool> + </property> + <property name="invertedAppearance"> + <bool>false</bool> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_5"> + <item> + <widget class="QLabel" name="label_progress"> + <property name="text"> + <string>Creating tomb, please wait...</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </item> + <item> + <widget class="QTextBrowser" name="textBrowser_log"> + <property name="documentTitle"> + <string>Log</string> + </property> + <property name="html"> + <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt; +&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;title&gt;Log&lt;/title&gt;&lt;style type=&quot;text/css&quot;&gt; +p, li { white-space: pre-wrap; } +&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'DejaVu Sans'; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt; +&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Sans Serif'; font-size:9pt; font-weight:600;&quot;&gt;Log&lt;/span&gt;&lt;/p&gt; +&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; font-weight:600;&quot;&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> + </property> + </widget> + </item> + </layout> + </widget> + <widget class="QWizardPage" name="wizardPage_end"> + <layout class="QVBoxLayout" name="verticalLayout_8"> + <item> + <widget class="QLabel" name="label_10"> + <property name="text"> + <string>You successfully created the tomb!</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="checkBox_open"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Open the just-created tomb NOW!</string> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <property name="tristate"> + <bool>false</bool> + </property> + </widget> + </item> + </layout> + </widget> + </widget> + <resources/> + <connections> + <connection> + <sender>radioButton_custom</sender> + <signal>toggled(bool)</signal> + <receiver>lineEdit_custom</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>91</x> + <y>56</y> + </hint> + <hint type="destinationlabel"> + <x>53</x> + <y>56</y> + </hint> + </hints> + </connection> + <connection> + <sender>radioButton_custom</sender> + <signal>toggled(bool)</signal> + <receiver>pushButton_custom</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>98</x> + <y>56</y> + </hint> + <hint type="destinationlabel"> + <x>98</x> + <y>56</y> + </hint> + </hints> + </connection> + <connection> + <sender>Wizard</sender> + <signal>currentIdChanged(int)</signal> + <receiver>label_11</receiver> + <slot>hide()</slot> + <hints> + <hint type="sourcelabel"> + <x>181</x> + <y>335</y> + </hint> + <hint type="destinationlabel"> + <x>99</x> + <y>60</y> + </hint> + </hints> + </connection> + <connection> + <sender>Wizard</sender> + <signal>helpRequested()</signal> + <receiver>label_11</receiver> + <slot>show()</slot> + <hints> + <hint type="sourcelabel"> + <x>135</x> + <y>356</y> + </hint> + <hint type="destinationlabel"> + <x>99</x> + <y>60</y> + </hint> + </hints> + </connection> + </connections> + <slots> + <slot>check_passwords_equal()</slot> + </slots> +</ui> diff --git a/src/qt/tombqt/open.py b/src/qt/tombqt/open.py @@ -0,0 +1,109 @@ +import sys + +from PyQt4 import QtCore, QtGui + +from ui_open_tombfile import Ui_tombfile +from ui_open_keymethod import Ui_keymethod +from ui_open_success import Ui_success + +from tomblib.tomb import Tomb +from tomblib.undertaker import Undertaker + +try: + _fromUtf8 = QtCore.QString.fromUtf8 +except AttributeError: + _fromUtf8 = lambda s: s + +class TombfilePage(QtGui.QWizardPage): + def __init__(self, *args, **kwargs): + QtGui.QWizardPage.__init__(self, *args) + self.ui = Ui_tombfile() + self.ui.setupUi(self) + if 'tombfile' in kwargs and kwargs['tombfile'] is not None: + self.ui.tomb_line.setText(kwargs['tombfile']) + self.ui.tomb_browse.clicked.connect(self.on_tomb_location_clicked) + def on_tomb_location_clicked(self, *args, **kwargs): + filename = QtGui.QFileDialog.getOpenFileName(self, 'Select Tomb', + filter="Tomb (*.tomb)") + self.ui.tomb_line.setText(filename) + +class MethodPage(QtGui.QWizardPage): + def __init__(self, *args, **kwargs): + QtGui.QWizardPage.__init__(self, *args, **kwargs) + self.ui = Ui_keymethod() + self.ui.setupUi(self) + self.group = group = QtGui.QButtonGroup() + for radio in self.children(): + if type(radio) == QtGui.QRadioButton: + group.addButton(radio) + + def initializePage(self): + self.found = Undertaker.check( str('near://' + self.wizard().get_tombfile()) ) or [] + box = self.ui.radio_layout + + for key in self.found: + radio = QtGui.QRadioButton('Automatically found: ' + key, parent=self) + radio.setChecked(True) + radio.setProperty('path', key) + box.insertWidget(0, radio) + self.group.addButton(radio) + + + def nextId(self): + '''Virtual method reimplemented to decide next page''' + if self.ui.fs.isChecked(): + keyfile = QtGui.QFileDialog.getOpenFileName(self.wizard(), 'Key file', + filter="Tomb keys (*.tomb.key);;Buried keys (*.jpeg)") + if keyfile: + #TODO: check if this really is a success :) + if Tomb.open(self.wizard().get_tombfile(), keyfile): #bugs when wrong password + return TombOpenWizard.SUCCESS_PAGE + #else: #TODO: should alert the user that we failed + return TombOpenWizard.METHOD_PAGE + if self.ui.usb.isChecked(): + return TombOpenWizard.USB_PAGE + print self.group.checkedButton().property('path').toPyObject() + return TombOpenWizard.SUCCESS_PAGE + +class SuccessPage(QtGui.QWizardPage): + def __init__(self, *args, **kwargs): + QtGui.QWizardPage.__init__(self, *args, **kwargs) + self.ui = Ui_success() + self.ui.setupUi(self) + +class TombOpenWizard(QtGui.QWizard): + TOMBFILE_PAGE=1 + METHOD_PAGE=2 + SUCCESS_PAGE=99 + USB_PAGE=20 + def __init__(self, *args, **kwargs): + QtGui.QWizard.__init__(self, *args) + self.setPage(TombOpenWizard.TOMBFILE_PAGE, + TombfilePage(self, tombfile = kwargs['tombfile'] + if 'tombfile' in kwargs else None)) + self.setPage(TombOpenWizard.METHOD_PAGE, MethodPage(self)) + self.setPage(TombOpenWizard.SUCCESS_PAGE, SuccessPage(self)) + if 'tombfile' in kwargs and kwargs['tombfile'] is not None: + self.setStartId(TombOpenWizard.METHOD_PAGE) + + def get_tombfile(self): + page = self.page(TombOpenWizard.TOMBFILE_PAGE) + return page.ui.tomb_line.text() + + + +def run_open_wizard(): + app = QtGui.QApplication(sys.argv) + window = TombOpenWizard(tombfile=sys.argv[1] if len(sys.argv) > 1 else None) + window.show() + sys.exit(app.exec_()) + +if __name__ == '__main__': + Undertaker.undertakerexec = '/home/davide/coding/projects/tomb/src/undertaker' + run_open_wizard() + + + + + + diff --git a/src/qt/tombqt/open.ui b/src/qt/tombqt/open.ui @@ -0,0 +1,239 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Dialog</class> + <widget class="QDialog" name="Dialog"> + <property name="windowTitle"> + <string>Tomb open</string> + </property> + <property name="toolTip"> + <string>Open a tomb file; this will require a passphrase</string> + </property> + <property name="autoFillBackground"> + <bool>false</bool> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt; +&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt; +p, li { white-space: pre-wrap; } +&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'DejaVu Sans'; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt; +&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:14pt; font-weight:600;&quot;&gt;Opening %tombname%&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> + </property> + <property name="textFormat"> + <enum>Qt::RichText</enum> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Maximum</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Size: %tombsize%</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>25</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string>Opening key</string> + </property> + <property name="flat"> + <bool>false</bool> + </property> + <property name="checkable"> + <bool>false</bool> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Key found in %autokeypath%</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="pushButton"> + <property name="toolTip"> + <string>Select a key to open the tomb</string> + </property> + <property name="text"> + <string>Choose another key</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>false</bool> + </property> + <property name="flat"> + <bool>false</bool> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <spacer name="verticalSpacer_2"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Preferred</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt; +&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt; +p, li { white-space: pre-wrap; } +&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'DejaVu Sans'; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt; +&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;HELP&lt;/span&gt;&lt;/p&gt; +&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;To open a tomb, you need both:&lt;/p&gt; +&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; 1. a key, which is a file with secret information.&lt;/p&gt; +&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; 2. a passphrase&lt;/p&gt; +&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;This dialog will help you choose the keyfile. We try hard to find the key, but if we can't found the right one, choose it yourself using the button&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Open</set> + </property> + <property name="centerButtons"> + <bool>false</bool> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>Dialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>578</x> + <y>751</y> + </hint> + <hint type="destinationlabel"> + <x>529</x> + <y>381</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>Dialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>447</x> + <y>735</y> + </hint> + <hint type="destinationlabel"> + <x>279</x> + <y>326</y> + </hint> + </hints> + </connection> + <connection> + <sender>Dialog</sender> + <signal>created()</signal> + <receiver>label_4</receiver> + <slot>hide()</slot> + <hints> + <hint type="sourcelabel"> + <x>141</x> + <y>756</y> + </hint> + <hint type="destinationlabel"> + <x>136</x> + <y>692</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>helpRequested()</signal> + <receiver>label_4</receiver> + <slot>hide()</slot> + <hints> + <hint type="sourcelabel"> + <x>39</x> + <y>738</y> + </hint> + <hint type="destinationlabel"> + <x>71</x> + <y>676</y> + </hint> + </hints> + </connection> + </connections> + <slots> + <signal>created()</signal> + </slots> +</ui> diff --git a/src/qt/tombqt/open_choosekey.ui b/src/qt/tombqt/open_choosekey.ui @@ -0,0 +1,147 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Dialog</class> + <widget class="QDialog" name="Dialog"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Minimum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="windowTitle"> + <string>Dialog</string> + </property> + <property name="modal"> + <bool>true</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt; +&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt; +p, li { white-space: pre-wrap; } +&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'DejaVu Sans'; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt; +&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt; font-weight:600;&quot;&gt;Auto-search&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> + </property> + <property name="textFormat"> + <enum>Qt::RichText</enum> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Expanding</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item> + <layout class="QVBoxLayout" name="verticalLayout_radio"> + <item> + <layout class="QVBoxLayout" name="verticalLayout_custom"> + <item> + <widget class="QRadioButton" name="radioButton"> + <property name="text"> + <string>Custom location</string> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_custom_input"> + <item> + <widget class="QLineEdit" name="lineEdit"> + <property name="readOnly"> + <bool>false</bool> + </property> + <property name="placeholderText"> + <string>/path/to/keyfile</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="pushButton"> + <property name="text"> + <string>Choose file</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </item> + </layout> + </item> + <item> + <spacer name="verticalSpacer_2"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Expanding</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>Dialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>247</x> + <y>604</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>Dialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>315</x> + <y>604</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/src/qt/tombqt/open_keymethod.ui b/src/qt/tombqt/open_keymethod.ui @@ -0,0 +1,84 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>keymethod</class> + <widget class="QWizardPage" name="keymethod"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>480</width> + <height>640</height> + </rect> + </property> + <property name="windowTitle"> + <string>WizardPage</string> + </property> + <property name="title"> + <string>Choose key</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>265</height> + </size> + </property> + </spacer> + </item> + <item> + <layout class="QVBoxLayout" name="radio_layout"> + <item> + <widget class="QRadioButton" name="fs"> + <property name="text"> + <string>Filesystem</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="usb"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>USB drive</string> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="bluetooth"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Retrieve via bluetooth (advanced)</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <spacer name="verticalSpacer_2"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>265</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/src/qt/tombqt/open_success.ui b/src/qt/tombqt/open_success.ui @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>success</class> + <widget class="QWizardPage" name="success"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>480</width> + <height>640</height> + </rect> + </property> + <property name="windowTitle"> + <string>WizardPage</string> + </property> + <property name="title"> + <string>Tomb opened</string> + </property> + <property name="subTitle"> + <string>success</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>You successfully opened the tomb</string> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/src/qt/tombqt/open_tombfile.ui b/src/qt/tombqt/open_tombfile.ui @@ -0,0 +1,79 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>tombfile</class> + <widget class="QWizardPage" name="tombfile"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>480</width> + <height>640</height> + </rect> + </property> + <property name="windowTitle"> + <string>WizardPage</string> + </property> + <property name="title"> + <string>Choose tomb</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>276</height> + </size> + </property> + </spacer> + </item> + <item> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Choose a tomb file on your filesystem</string> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QLineEdit" name="tomb_line"> + <property name="placeholderText"> + <string>/path/to/your.tomb</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="tomb_browse"> + <property name="text"> + <string>Browse</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </item> + <item> + <spacer name="verticalSpacer_2"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>276</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/src/qt/tombqt/ui_create.py b/src/qt/tombqt/ui_create.py @@ -0,0 +1,282 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file 'create.ui' +# +# Created: Thu Nov 3 00:16:51 2011 +# by: PyQt4 UI code generator 4.8.6 +# +# WARNING! All changes made in this file will be lost! + +from PyQt4 import QtCore, QtGui + +try: + _fromUtf8 = QtCore.QString.fromUtf8 +except AttributeError: + _fromUtf8 = lambda s: s + +class Ui_Wizard(object): + def setupUi(self, Wizard): + Wizard.setObjectName(_fromUtf8("Wizard")) + Wizard.resize(710, 368) + Wizard.setWindowTitle(QtGui.QApplication.translate("Wizard", "Wizard", None, QtGui.QApplication.UnicodeUTF8)) + Wizard.setOptions(QtGui.QWizard.HaveHelpButton|QtGui.QWizard.IndependentPages) + self.wizardPage_intro = QtGui.QWizardPage() + self.wizardPage_intro.setTitle(QtGui.QApplication.translate("Wizard", "Tomb", None, QtGui.QApplication.UnicodeUTF8)) + self.wizardPage_intro.setSubTitle(QtGui.QApplication.translate("Wizard", "tomb creation", None, QtGui.QApplication.UnicodeUTF8)) + self.wizardPage_intro.setObjectName(_fromUtf8("wizardPage_intro")) + self.verticalLayout = QtGui.QVBoxLayout(self.wizardPage_intro) + self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) + self.label = QtGui.QLabel(self.wizardPage_intro) + self.label.setText(QtGui.QApplication.translate("Wizard", "This wizard will guide you to the creation of a tomb.<br> It will be fun!", None, QtGui.QApplication.UnicodeUTF8)) + self.label.setTextFormat(QtCore.Qt.RichText) + self.label.setWordWrap(True) + self.label.setObjectName(_fromUtf8("label")) + self.verticalLayout.addWidget(self.label) + Wizard.addPage(self.wizardPage_intro) + self.wizardPage_check = QtGui.QWizardPage() + self.wizardPage_check.setTitle(QtGui.QApplication.translate("Wizard", "Requirements check", None, QtGui.QApplication.UnicodeUTF8)) + self.wizardPage_check.setObjectName(_fromUtf8("wizardPage_check")) + self.verticalLayout_12 = QtGui.QVBoxLayout(self.wizardPage_check) + self.verticalLayout_12.setObjectName(_fromUtf8("verticalLayout_12")) + self.label_check = QtGui.QLabel(self.wizardPage_check) + self.label_check.setText(QtGui.QApplication.translate("Wizard", "Checking...", None, QtGui.QApplication.UnicodeUTF8)) + self.label_check.setObjectName(_fromUtf8("label_check")) + self.verticalLayout_12.addWidget(self.label_check) + self.groupBox_swap = QtGui.QGroupBox(self.wizardPage_check) + self.groupBox_swap.setEnabled(True) + self.groupBox_swap.setTitle(QtGui.QApplication.translate("Wizard", "Swap error", None, QtGui.QApplication.UnicodeUTF8)) + self.groupBox_swap.setObjectName(_fromUtf8("groupBox_swap")) + self.verticalLayout_13 = QtGui.QVBoxLayout(self.groupBox_swap) + self.verticalLayout_13.setObjectName(_fromUtf8("verticalLayout_13")) + self.label_7 = QtGui.QLabel(self.groupBox_swap) + self.label_7.setText(QtGui.QApplication.translate("Wizard", "It seems that you have swap activated. It is very dangerous, since you could leave LOT of traces on your computer UNencrypted. You have some options:", None, QtGui.QApplication.UnicodeUTF8)) + self.label_7.setWordWrap(True) + self.label_7.setObjectName(_fromUtf8("label_7")) + self.verticalLayout_13.addWidget(self.label_7) + self.verticalLayout_swapoff = QtGui.QVBoxLayout() + self.verticalLayout_swapoff.setObjectName(_fromUtf8("verticalLayout_swapoff")) + self.radioButton_swapoff = QtGui.QRadioButton(self.groupBox_swap) + self.radioButton_swapoff.setText(QtGui.QApplication.translate("Wizard", "Swapoff", None, QtGui.QApplication.UnicodeUTF8)) + self.radioButton_swapoff.setObjectName(_fromUtf8("radioButton_swapoff")) + self.verticalLayout_swapoff.addWidget(self.radioButton_swapoff) + self.horizontalLayout_6 = QtGui.QHBoxLayout() + self.horizontalLayout_6.setObjectName(_fromUtf8("horizontalLayout_6")) + spacerItem = QtGui.QSpacerItem(20, 20, QtGui.QSizePolicy.Maximum, QtGui.QSizePolicy.Minimum) + self.horizontalLayout_6.addItem(spacerItem) + self.label_swapoff = QtGui.QLabel(self.groupBox_swap) + self.label_swapoff.setText(QtGui.QApplication.translate("Wizard", "Note: swapoff could take a long time, and, in case the memory is not enough, could even make your system crash. Your system seems to have %freeram%MB free", None, QtGui.QApplication.UnicodeUTF8)) + self.label_swapoff.setWordWrap(True) + self.label_swapoff.setObjectName(_fromUtf8("label_swapoff")) + self.horizontalLayout_6.addWidget(self.label_swapoff) + self.verticalLayout_swapoff.addLayout(self.horizontalLayout_6) + self.verticalLayout_13.addLayout(self.verticalLayout_swapoff) + self.verticalLayout_11 = QtGui.QVBoxLayout() + self.verticalLayout_11.setObjectName(_fromUtf8("verticalLayout_11")) + self.radioButton_ignore = QtGui.QRadioButton(self.groupBox_swap) + self.radioButton_ignore.setText(QtGui.QApplication.translate("Wizard", "Ignore", None, QtGui.QApplication.UnicodeUTF8)) + self.radioButton_ignore.setObjectName(_fromUtf8("radioButton_ignore")) + self.verticalLayout_11.addWidget(self.radioButton_ignore) + self.horizontalLayout_7 = QtGui.QHBoxLayout() + self.horizontalLayout_7.setObjectName(_fromUtf8("horizontalLayout_7")) + spacerItem1 = QtGui.QSpacerItem(20, 20, QtGui.QSizePolicy.Maximum, QtGui.QSizePolicy.Minimum) + self.horizontalLayout_7.addItem(spacerItem1) + self.label_9 = QtGui.QLabel(self.groupBox_swap) + self.label_9.setText(QtGui.QApplication.translate("Wizard", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n" +"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n" +"p, li { white-space: pre-wrap; }\n" +"</style></head><body style=\" font-family:\'DejaVu Sans\'; font-size:10pt; font-weight:400; font-style:normal;\">\n" +"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-weight:600;\">Note:</span> You should use this only if you are sure that your swap is encrypted, or that you are using compcache.</p>\n" +"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">If this is not the case, DON\'T select this, as it is <span style=\" font-weight:600;\">VERY DANGEROUS </span>to use encryption with swap activated</p></body></html>", None, QtGui.QApplication.UnicodeUTF8)) + self.label_9.setWordWrap(True) + self.label_9.setObjectName(_fromUtf8("label_9")) + self.horizontalLayout_7.addWidget(self.label_9) + self.verticalLayout_11.addLayout(self.horizontalLayout_7) + self.verticalLayout_13.addLayout(self.verticalLayout_11) + self.verticalLayout_12.addWidget(self.groupBox_swap) + Wizard.addPage(self.wizardPage_check) + self.wizardPage_tomb_size = QtGui.QWizardPage() + self.wizardPage_tomb_size.setObjectName(_fromUtf8("wizardPage_tomb_size")) + self.verticalLayout_2 = QtGui.QVBoxLayout(self.wizardPage_tomb_size) + self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2")) + self.label_2 = QtGui.QLabel(self.wizardPage_tomb_size) + self.label_2.setText(QtGui.QApplication.translate("Wizard", "Please enter tomb size. Digging the tomb will require some time: usually, one minute per GB, but your mileage may vary. <br>Keep in mind that resizing it in the future is still NOT implemented", None, QtGui.QApplication.UnicodeUTF8)) + self.label_2.setWordWrap(True) + self.label_2.setObjectName(_fromUtf8("label_2")) + self.verticalLayout_2.addWidget(self.label_2) + self.horizontalLayout = QtGui.QHBoxLayout() + self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) + self.label_3 = QtGui.QLabel(self.wizardPage_tomb_size) + self.label_3.setText(QtGui.QApplication.translate("Wizard", "Enter tomb size, in MB. 1GB=1000MB)", None, QtGui.QApplication.UnicodeUTF8)) + self.label_3.setObjectName(_fromUtf8("label_3")) + self.horizontalLayout.addWidget(self.label_3) + self.spinBox_size = QtGui.QSpinBox(self.wizardPage_tomb_size) + self.spinBox_size.setMinimum(10) + self.spinBox_size.setMaximum(100000) + self.spinBox_size.setProperty("value", 100) + self.spinBox_size.setObjectName(_fromUtf8("spinBox_size")) + self.horizontalLayout.addWidget(self.spinBox_size) + self.verticalLayout_2.addLayout(self.horizontalLayout) + Wizard.addPage(self.wizardPage_tomb_size) + self.wizardPage_tomb_location = QtGui.QWizardPage() + self.wizardPage_tomb_location.setObjectName(_fromUtf8("wizardPage_tomb_location")) + self.verticalLayout_3 = QtGui.QVBoxLayout(self.wizardPage_tomb_location) + self.verticalLayout_3.setObjectName(_fromUtf8("verticalLayout_3")) + self.label_4 = QtGui.QLabel(self.wizardPage_tomb_location) + self.label_4.setText(QtGui.QApplication.translate("Wizard", "Where do you want your tomb to be digged?", None, QtGui.QApplication.UnicodeUTF8)) + self.label_4.setWordWrap(True) + self.label_4.setObjectName(_fromUtf8("label_4")) + self.verticalLayout_3.addWidget(self.label_4) + self.horizontalLayout_2 = QtGui.QHBoxLayout() + self.horizontalLayout_2.setObjectName(_fromUtf8("horizontalLayout_2")) + self.lineEdit_tombpath = QtGui.QLineEdit(self.wizardPage_tomb_location) + self.lineEdit_tombpath.setFrame(True) + self.lineEdit_tombpath.setPlaceholderText(QtGui.QApplication.translate("Wizard", "/path/to/file.tomb", None, QtGui.QApplication.UnicodeUTF8)) + self.lineEdit_tombpath.setObjectName(_fromUtf8("lineEdit_tombpath")) + self.horizontalLayout_2.addWidget(self.lineEdit_tombpath) + self.button_tombpath = QtGui.QPushButton(self.wizardPage_tomb_location) + self.button_tombpath.setText(QtGui.QApplication.translate("Wizard", "Open file", None, QtGui.QApplication.UnicodeUTF8)) + self.button_tombpath.setObjectName(_fromUtf8("button_tombpath")) + self.horizontalLayout_2.addWidget(self.button_tombpath) + self.verticalLayout_3.addLayout(self.horizontalLayout_2) + Wizard.addPage(self.wizardPage_tomb_location) + self.wizardPage_key_location = QtGui.QWizardPage() + self.wizardPage_key_location.setTitle(QtGui.QApplication.translate("Wizard", "Key creation", None, QtGui.QApplication.UnicodeUTF8)) + self.wizardPage_key_location.setSubTitle(QtGui.QApplication.translate("Wizard", "Choose the location for your key", None, QtGui.QApplication.UnicodeUTF8)) + self.wizardPage_key_location.setObjectName(_fromUtf8("wizardPage_key_location")) + self.verticalLayout_6 = QtGui.QVBoxLayout(self.wizardPage_key_location) + self.verticalLayout_6.setObjectName(_fromUtf8("verticalLayout_6")) + self.label_5 = QtGui.QLabel(self.wizardPage_key_location) + self.label_5.setText(QtGui.QApplication.translate("Wizard", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n" +"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n" +"p, li { white-space: pre-wrap; }\n" +"</style></head><body style=\" font-family:\'Sans Serif\'; font-size:9pt; font-weight:400; font-style:normal;\">\n" +"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Now, you have to decide where to put the <span style=\" font-weight:600;\">key</span> for your tomb<br />You should not leave your key at the door, as this will lower security A LOT</p>\n" +"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Also, the keyfile is very small (less than a KB), so disk space is not an issue</p></body></html>", None, QtGui.QApplication.UnicodeUTF8)) + self.label_5.setTextFormat(QtCore.Qt.RichText) + self.label_5.setWordWrap(True) + self.label_5.setObjectName(_fromUtf8("label_5")) + self.verticalLayout_6.addWidget(self.label_5) + self.verticalLayout_5 = QtGui.QVBoxLayout() + self.verticalLayout_5.setObjectName(_fromUtf8("verticalLayout_5")) + self.verticalLayout_4 = QtGui.QVBoxLayout() + self.verticalLayout_4.setObjectName(_fromUtf8("verticalLayout_4")) + self.radioButton_usb = QtGui.QRadioButton(self.wizardPage_key_location) + self.radioButton_usb.setEnabled(False) + self.radioButton_usb.setText(QtGui.QApplication.translate("Wizard", "On a USB pen (best security)", None, QtGui.QApplication.UnicodeUTF8)) + self.radioButton_usb.setCheckable(True) + self.radioButton_usb.setChecked(False) + self.radioButton_usb.setObjectName(_fromUtf8("radioButton_usb")) + self.verticalLayout_4.addWidget(self.radioButton_usb) + self.horizontalLayout_4 = QtGui.QHBoxLayout() + self.horizontalLayout_4.setObjectName(_fromUtf8("horizontalLayout_4")) + spacerItem2 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Maximum, QtGui.QSizePolicy.Minimum) + self.horizontalLayout_4.addItem(spacerItem2) + self.label_6 = QtGui.QLabel(self.wizardPage_key_location) + self.label_6.setEnabled(False) + self.label_6.setText(QtGui.QApplication.translate("Wizard", "If you choose to do so, do not insert it NOW. Do it when you are asked to do so", None, QtGui.QApplication.UnicodeUTF8)) + self.label_6.setObjectName(_fromUtf8("label_6")) + self.horizontalLayout_4.addWidget(self.label_6) + self.verticalLayout_4.addLayout(self.horizontalLayout_4) + self.verticalLayout_5.addLayout(self.verticalLayout_4) + self.radioButton_near = QtGui.QRadioButton(self.wizardPage_key_location) + self.radioButton_near.setToolTip(QtGui.QApplication.translate("Wizard", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n" +"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n" +"p, li { white-space: pre-wrap; }\n" +"</style></head><body style=\" font-family:\'Sans Serif\'; font-size:9pt; font-weight:400; font-style:normal;\">\n" +"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">It will be created as a regular file in the same directory of your tomb.</p>\n" +"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">It is much easier to use, but also much more <span style=\" font-style:italic;\">insecure</span>: all your security will be guaranteed by your <span style=\" font-weight:600;\">password</span>. If you really want to do this, choose a strong password (lot of random/non-dictionary words, spaces, numbers, odd characters)</p></body></html>", None, QtGui.QApplication.UnicodeUTF8)) + self.radioButton_near.setText(QtGui.QApplication.translate("Wizard", "Near to the tomb itself (this is BAD)", None, QtGui.QApplication.UnicodeUTF8)) + self.radioButton_near.setChecked(True) + self.radioButton_near.setObjectName(_fromUtf8("radioButton_near")) + self.verticalLayout_5.addWidget(self.radioButton_near) + self.radioButton_custom = QtGui.QRadioButton(self.wizardPage_key_location) + self.radioButton_custom.setText(QtGui.QApplication.translate("Wizard", "Specify location", None, QtGui.QApplication.UnicodeUTF8)) + self.radioButton_custom.setObjectName(_fromUtf8("radioButton_custom")) + self.verticalLayout_5.addWidget(self.radioButton_custom) + self.verticalLayout_6.addLayout(self.verticalLayout_5) + self.horizontalLayout_3 = QtGui.QHBoxLayout() + self.horizontalLayout_3.setObjectName(_fromUtf8("horizontalLayout_3")) + spacerItem3 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Maximum, QtGui.QSizePolicy.Minimum) + self.horizontalLayout_3.addItem(spacerItem3) + self.lineEdit_custom = QtGui.QLineEdit(self.wizardPage_key_location) + self.lineEdit_custom.setEnabled(False) + self.lineEdit_custom.setObjectName(_fromUtf8("lineEdit_custom")) + self.horizontalLayout_3.addWidget(self.lineEdit_custom) + self.pushButton_custom = QtGui.QPushButton(self.wizardPage_key_location) + self.pushButton_custom.setEnabled(False) + self.pushButton_custom.setText(QtGui.QApplication.translate("Wizard", "Choose location", None, QtGui.QApplication.UnicodeUTF8)) + self.pushButton_custom.setObjectName(_fromUtf8("pushButton_custom")) + self.horizontalLayout_3.addWidget(self.pushButton_custom) + self.verticalLayout_6.addLayout(self.horizontalLayout_3) + self.label_11 = QtGui.QLabel(self.wizardPage_key_location) + self.label_11.setText(QtGui.QApplication.translate("Wizard", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n" +"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n" +"p, li { white-space: pre-wrap; }\n" +"</style></head><body style=\" font-family:\'Sans Serif\'; font-size:9pt; font-weight:400; font-style:normal;\">\n" +"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-weight:600;\">Help: </span>the key file is very small, so disk usage is not an issue</p></body></html>", None, QtGui.QApplication.UnicodeUTF8)) + self.label_11.setWordWrap(True) + self.label_11.setObjectName(_fromUtf8("label_11")) + self.verticalLayout_6.addWidget(self.label_11) + Wizard.addPage(self.wizardPage_key_location) + self.wizardPage_progress = QtGui.QWizardPage() + self.wizardPage_progress.setTitle(QtGui.QApplication.translate("Wizard", "Creating", None, QtGui.QApplication.UnicodeUTF8)) + self.wizardPage_progress.setSubTitle(QtGui.QApplication.translate("Wizard", "Please wait", None, QtGui.QApplication.UnicodeUTF8)) + self.wizardPage_progress.setObjectName(_fromUtf8("wizardPage_progress")) + self.verticalLayout_9 = QtGui.QVBoxLayout(self.wizardPage_progress) + self.verticalLayout_9.setObjectName(_fromUtf8("verticalLayout_9")) + self.verticalLayout_7 = QtGui.QVBoxLayout() + self.verticalLayout_7.setObjectName(_fromUtf8("verticalLayout_7")) + self.progressBar = QtGui.QProgressBar(self.wizardPage_progress) + self.progressBar.setProperty("value", 0) + self.progressBar.setTextVisible(True) + self.progressBar.setInvertedAppearance(False) + self.progressBar.setObjectName(_fromUtf8("progressBar")) + self.verticalLayout_7.addWidget(self.progressBar) + self.horizontalLayout_5 = QtGui.QHBoxLayout() + self.horizontalLayout_5.setObjectName(_fromUtf8("horizontalLayout_5")) + self.label_progress = QtGui.QLabel(self.wizardPage_progress) + self.label_progress.setText(QtGui.QApplication.translate("Wizard", "Creating tomb, please wait...", None, QtGui.QApplication.UnicodeUTF8)) + self.label_progress.setObjectName(_fromUtf8("label_progress")) + self.horizontalLayout_5.addWidget(self.label_progress) + self.verticalLayout_7.addLayout(self.horizontalLayout_5) + self.verticalLayout_9.addLayout(self.verticalLayout_7) + self.textBrowser_log = QtGui.QTextBrowser(self.wizardPage_progress) + self.textBrowser_log.setDocumentTitle(QtGui.QApplication.translate("Wizard", "Log", None, QtGui.QApplication.UnicodeUTF8)) + self.textBrowser_log.setHtml(QtGui.QApplication.translate("Wizard", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n" +"<html><head><meta name=\"qrichtext\" content=\"1\" /><title>Log</title><style type=\"text/css\">\n" +"p, li { white-space: pre-wrap; }\n" +"</style></head><body style=\" font-family:\'DejaVu Sans\'; font-size:10pt; font-weight:400; font-style:normal;\">\n" +"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'Sans Serif\'; font-size:9pt; font-weight:600;\">Log</span></p>\n" +"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:\'Sans Serif\'; font-size:9pt; font-weight:600;\"></p></body></html>", None, QtGui.QApplication.UnicodeUTF8)) + self.textBrowser_log.setObjectName(_fromUtf8("textBrowser_log")) + self.verticalLayout_9.addWidget(self.textBrowser_log) + Wizard.addPage(self.wizardPage_progress) + self.wizardPage_end = QtGui.QWizardPage() + self.wizardPage_end.setObjectName(_fromUtf8("wizardPage_end")) + self.verticalLayout_8 = QtGui.QVBoxLayout(self.wizardPage_end) + self.verticalLayout_8.setObjectName(_fromUtf8("verticalLayout_8")) + self.label_10 = QtGui.QLabel(self.wizardPage_end) + self.label_10.setText(QtGui.QApplication.translate("Wizard", "You successfully created the tomb!", None, QtGui.QApplication.UnicodeUTF8)) + self.label_10.setObjectName(_fromUtf8("label_10")) + self.verticalLayout_8.addWidget(self.label_10) + self.checkBox_open = QtGui.QCheckBox(self.wizardPage_end) + self.checkBox_open.setEnabled(False) + self.checkBox_open.setText(QtGui.QApplication.translate("Wizard", "Open the just-created tomb NOW!", None, QtGui.QApplication.UnicodeUTF8)) + self.checkBox_open.setChecked(False) + self.checkBox_open.setTristate(False) + self.checkBox_open.setObjectName(_fromUtf8("checkBox_open")) + self.verticalLayout_8.addWidget(self.checkBox_open) + Wizard.addPage(self.wizardPage_end) + self.label_3.setBuddy(self.spinBox_size) + self.label_4.setBuddy(self.lineEdit_tombpath) + + self.retranslateUi(Wizard) + QtCore.QObject.connect(self.radioButton_custom, QtCore.SIGNAL(_fromUtf8("toggled(bool)")), self.lineEdit_custom.setEnabled) + QtCore.QObject.connect(self.radioButton_custom, QtCore.SIGNAL(_fromUtf8("toggled(bool)")), self.pushButton_custom.setEnabled) + QtCore.QObject.connect(Wizard, QtCore.SIGNAL(_fromUtf8("currentIdChanged(int)")), self.label_11.hide) + QtCore.QObject.connect(Wizard, QtCore.SIGNAL(_fromUtf8("helpRequested()")), self.label_11.show) + QtCore.QMetaObject.connectSlotsByName(Wizard) + + def retranslateUi(self, Wizard): + pass + diff --git a/src/qt/tombqt/ui_open_keymethod.py b/src/qt/tombqt/ui_open_keymethod.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file 'tombqt/open_keymethod.ui' +# +# Created: Sat Jan 28 03:36:11 2012 +# by: PyQt4 UI code generator 4.9 +# +# WARNING! All changes made in this file will be lost! + +from PyQt4 import QtCore, QtGui + +try: + _fromUtf8 = QtCore.QString.fromUtf8 +except AttributeError: + _fromUtf8 = lambda s: s + +class Ui_keymethod(object): + def setupUi(self, keymethod): + keymethod.setObjectName(_fromUtf8("keymethod")) + keymethod.resize(480, 640) + self.verticalLayout = QtGui.QVBoxLayout(keymethod) + self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) + spacerItem = QtGui.QSpacerItem(20, 265, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) + self.verticalLayout.addItem(spacerItem) + self.radio_layout = QtGui.QVBoxLayout() + self.radio_layout.setObjectName(_fromUtf8("radio_layout")) + self.fs = QtGui.QRadioButton(keymethod) + self.fs.setObjectName(_fromUtf8("fs")) + self.radio_layout.addWidget(self.fs) + self.usb = QtGui.QRadioButton(keymethod) + self.usb.setEnabled(False) + self.usb.setObjectName(_fromUtf8("usb")) + self.radio_layout.addWidget(self.usb) + self.bluetooth = QtGui.QRadioButton(keymethod) + self.bluetooth.setEnabled(False) + self.bluetooth.setObjectName(_fromUtf8("bluetooth")) + self.radio_layout.addWidget(self.bluetooth) + self.verticalLayout.addLayout(self.radio_layout) + spacerItem1 = QtGui.QSpacerItem(20, 265, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) + self.verticalLayout.addItem(spacerItem1) + + self.retranslateUi(keymethod) + QtCore.QMetaObject.connectSlotsByName(keymethod) + + def retranslateUi(self, keymethod): + keymethod.setWindowTitle(QtGui.QApplication.translate("keymethod", "WizardPage", None, QtGui.QApplication.UnicodeUTF8)) + keymethod.setTitle(QtGui.QApplication.translate("keymethod", "Choose key", None, QtGui.QApplication.UnicodeUTF8)) + self.fs.setText(QtGui.QApplication.translate("keymethod", "Filesystem", None, QtGui.QApplication.UnicodeUTF8)) + self.usb.setText(QtGui.QApplication.translate("keymethod", "USB drive", None, QtGui.QApplication.UnicodeUTF8)) + self.bluetooth.setText(QtGui.QApplication.translate("keymethod", "Retrieve via bluetooth (advanced)", None, QtGui.QApplication.UnicodeUTF8)) + diff --git a/src/qt/tombqt/ui_open_success.py b/src/qt/tombqt/ui_open_success.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file 'tombqt/open_success.ui' +# +# Created: Mon Jan 23 23:06:38 2012 +# by: PyQt4 UI code generator 4.9 +# +# WARNING! All changes made in this file will be lost! + +from PyQt4 import QtCore, QtGui + +try: + _fromUtf8 = QtCore.QString.fromUtf8 +except AttributeError: + _fromUtf8 = lambda s: s + +class Ui_success(object): + def setupUi(self, success): + success.setObjectName(_fromUtf8("success")) + success.resize(480, 640) + self.verticalLayout = QtGui.QVBoxLayout(success) + self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) + self.label = QtGui.QLabel(success) + self.label.setObjectName(_fromUtf8("label")) + self.verticalLayout.addWidget(self.label) + + self.retranslateUi(success) + QtCore.QMetaObject.connectSlotsByName(success) + + def retranslateUi(self, success): + success.setWindowTitle(QtGui.QApplication.translate("success", "WizardPage", None, QtGui.QApplication.UnicodeUTF8)) + success.setTitle(QtGui.QApplication.translate("success", "Tomb opened", None, QtGui.QApplication.UnicodeUTF8)) + success.setSubTitle(QtGui.QApplication.translate("success", "success", None, QtGui.QApplication.UnicodeUTF8)) + self.label.setText(QtGui.QApplication.translate("success", "You successfully opened the tomb", None, QtGui.QApplication.UnicodeUTF8)) + diff --git a/src/qt/tombqt/ui_open_tombfile.py b/src/qt/tombqt/ui_open_tombfile.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file 'tombqt/open_tombfile.ui' +# +# Created: Tue Jan 24 00:49:10 2012 +# by: PyQt4 UI code generator 4.9 +# +# WARNING! All changes made in this file will be lost! + +from PyQt4 import QtCore, QtGui + +try: + _fromUtf8 = QtCore.QString.fromUtf8 +except AttributeError: + _fromUtf8 = lambda s: s + +class Ui_tombfile(object): + def setupUi(self, tombfile): + tombfile.setObjectName(_fromUtf8("tombfile")) + tombfile.resize(480, 640) + self.verticalLayout_2 = QtGui.QVBoxLayout(tombfile) + self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2")) + spacerItem = QtGui.QSpacerItem(20, 276, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) + self.verticalLayout_2.addItem(spacerItem) + self.verticalLayout = QtGui.QVBoxLayout() + self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) + self.label = QtGui.QLabel(tombfile) + self.label.setObjectName(_fromUtf8("label")) + self.verticalLayout.addWidget(self.label) + self.horizontalLayout = QtGui.QHBoxLayout() + self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) + self.tomb_line = QtGui.QLineEdit(tombfile) + self.tomb_line.setObjectName(_fromUtf8("tomb_line")) + self.horizontalLayout.addWidget(self.tomb_line) + self.tomb_browse = QtGui.QPushButton(tombfile) + self.tomb_browse.setObjectName(_fromUtf8("tomb_browse")) + self.horizontalLayout.addWidget(self.tomb_browse) + self.verticalLayout.addLayout(self.horizontalLayout) + self.verticalLayout_2.addLayout(self.verticalLayout) + spacerItem1 = QtGui.QSpacerItem(20, 276, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) + self.verticalLayout_2.addItem(spacerItem1) + + self.retranslateUi(tombfile) + QtCore.QMetaObject.connectSlotsByName(tombfile) + + def retranslateUi(self, tombfile): + tombfile.setWindowTitle(QtGui.QApplication.translate("tombfile", "WizardPage", None, QtGui.QApplication.UnicodeUTF8)) + tombfile.setTitle(QtGui.QApplication.translate("tombfile", "Choose tomb", None, QtGui.QApplication.UnicodeUTF8)) + self.label.setText(QtGui.QApplication.translate("tombfile", "Choose a tomb file on your filesystem", None, QtGui.QApplication.UnicodeUTF8)) + self.tomb_line.setPlaceholderText(QtGui.QApplication.translate("tombfile", "/path/to/your.tomb", None, QtGui.QApplication.UnicodeUTF8)) + self.tomb_browse.setText(QtGui.QApplication.translate("tombfile", "Browse", None, QtGui.QApplication.UnicodeUTF8)) + diff --git a/src/qt/tombqt/worker.py b/src/qt/tombqt/worker.py @@ -0,0 +1,62 @@ +import sys,os +import time +from tempfile import NamedTemporaryFile + +from PyQt4 import QtCore + +parentdir = sys.path[0].split(os.sep)[:-1] +sys.path.append(os.sep.join(parentdir)) +from tomblib.tomb import Tomb +from tomblib.parser import parse_line + +class TombCreateThread(QtCore.QThread): + line_received = QtCore.pyqtSignal(QtCore.QString) + error_received = QtCore.pyqtSignal(QtCore.QString) + def __init__(self, tombpath, size, keypath, **opts): + QtCore.QThread.__init__(self) + self.tombpath = tombpath + self.size = size + self.keypath = keypath + self.opts = opts + + self.err_thread = TombOutputThread() + self.err_thread.line_received.connect(self.line_received) + self.err_thread.error_received.connect(self.error_received) + + def run(self): + self.err_thread.start() + self.status = Tomb.create(str(self.tombpath), str(self.size), + self.keypath, stderr=self.err_thread.buffer, **self.opts) +# self.err_thread.terminate() + + def get_success(self): + return self.status + +class TombOutputThread(QtCore.QThread): + line_received = QtCore.pyqtSignal(QtCore.QString) + error_received = QtCore.pyqtSignal(QtCore.QString) + progressed = QtCore.pyqtSignal(int) #value in percent + + def __init__(self): + QtCore.QThread.__init__(self) + self.buffer = NamedTemporaryFile() + + def run(self): + while True: + where = self.buffer.tell() + line = self.buffer.readline() + if not line: + time.sleep(1) + self.buffer.seek(where) + else: + #ansi color escapes messes this up, but it'ok anyway + self.line_received.emit(line) + self.parse_line(line) + + def parse_line(self, line): + #This could be simplified, and s/search/match, if --no-color supported + #see #59 + #TODO: this should be moved to tomblib.parse + parsed = parse_line(line) + if parsed and parsed['type'] == 'error': + self.error_received.emit(parsed.content) diff --git a/src/tomb b/src/tomb @@ -48,8 +48,8 @@ PATH=/sbin:/bin:/usr/sbin:/usr/bin function _msg() { local command="print -P" - local progname="$fg[magenta]${TOMBEXEC##*/}$fg[reset_color]" - local message="$fg_bold[normal]$fg_no_bold[normal]${2}$fg[reset_color]" + local progname="$fg[magenta]${TOMBEXEC##*/}$reset_color" + local message="$fg_bold[normal]$fg_no_bold[normal]${2}$reset_color" local -i returncode case "$1" in @@ -57,19 +57,19 @@ function _msg() { command+=" -n"; pchars=" > "; pcolor="yellow" ;; message) - pchars=" . "; pcolor="white"; message="$fg_no_bold[$pcolor]${2}$fg[reset_color]" + pchars=" . "; pcolor="white"; message="$fg_no_bold[$pcolor]${2}$reset_color" ;; verbose) pchars="[D]"; pcolor="blue" ;; success) - pchars="(*)"; pcolor="green"; message="$fg_no_bold[$pcolor]${2}$fg[reset_color]" + pchars="(*)"; pcolor="green"; message="$fg_no_bold[$pcolor]${2}$reset_color" ;; warning) - pchars="[W]"; pcolor="yellow"; message="$fg_no_bold[$pcolor]${2}$fg[reset_color]" + pchars="[W]"; pcolor="yellow"; message="$fg_no_bold[$pcolor]${2}$reset_color" ;; failure) - pchars="[E]"; pcolor="red"; message="$fg_no_bold[$pcolor]${2}$fg[reset_color]" + pchars="[E]"; pcolor="red"; message="$fg_no_bold[$pcolor]${2}$reset_color" returncode=1 ;; *) @@ -78,7 +78,7 @@ function _msg() { returncode=127 ;; esac - ${=command} "${progname} $fg_bold[$pcolor]$pchars$fg[reset_color] ${message}$color[reset_color]" >&2 + ${=command} "${progname} $fg_bold[$pcolor]$pchars$reset_color ${message}$color[reset_color]" >&2 return $returncode } function _message say() @@ -298,8 +298,20 @@ EOF return 0 } # }}} -# }}} -# {{{ - TOMB USAGE +check_command() { + #generic checks; useful for interaction, to check if there are problems + #before wasting user's time + + if ! option_is_set --ignore-swap; then + if [[ $1 == 'create' || $1 == 'open' ]]; then + if ! check_swap; then + error "Swap activated. Disable it with swapoff, or use --ignore-swap" + exit 1 + fi + fi + fi +} + usage() { cat <<EOF @@ -1591,19 +1603,19 @@ main() { # to add some options? Well, keep in mind that an option CAN'T # have differente meanings/behaviour in different subcommands. - # For example, "-s" means "size" and accept an argument. If you are tempted to add - # an option "-s" (that means, for example "silent", and doesn't accept an argument) - # DON'T DO IT! + # For example, "-s" means "size" and accept an argument. If you are tempted to add + # an option "-s" (that means, for example "silent", and doesn't accept an argument) + # DON'T DO IT! - # There are two reasons for that: + # There are two reasons for that: # I. usability; user expect that "-s" is "size" - # II. Option parsing WILL EXPLODE if you do this kind of bad things - # (it will say "option defined more than once, and he's right") + # II. Option parsing WILL EXPLODE if you do this kind of bad things + # (it will say "option defined more than once, and he's right") # # If you want to use the same option in multiple commands then # you can only use the non-abbreviated long-option version like: # -force and NOT -f - main_opts=(q -quiet=q D -debug=D h -help=h v -version=v -no-color) + main_opts=(q -quiet=q D -debug=D h -help=h v -version=v -no-color) subcommands_opts[__default]="" subcommands_opts[open]="f n -nohook=n k: -key=k o: -mount-options=o" subcommands_opts[mount]=${subcommands_opts[open]} @@ -1624,6 +1636,7 @@ main() { subcommands_opts[source]="" subcommands_opts[status]="" subcommands_opts[resize]="s: -size=s k: -key=k" + subcommands_opts[check]="-ignore-swap" # subcommands_opts[translate]="" ### Detect subcommand @@ -1635,7 +1648,20 @@ main() { done local -a oldstar oldstar=($argv) - zparseopts -M -E -D -Adiscardme ${every_opts} + #### detect early: useful for --optiion-parsing + zparseopts -M -D -Adiscardme ${every_opts} + if [[ -n ${(k)discardme[--option-parsing]} ]]; then + echo $1 + if [[ -n "$1" ]]; then + return 1 + fi + return 0 + fi + unset discardme + if ! zparseopts -M -E -D -Adiscardme ${every_opts}; then + error "error parsing" + return 127 + fi unset discardme subcommand=$1 if [[ -z $subcommand ]]; then @@ -1723,14 +1749,13 @@ main() { _warning "steghide not installed. Cannot bury your key" return 1 fi - encode_key ${CMD2} ${CMD3} - ;; + encode_key $PARAM[1] $PARAM[2] ;; exhume) if [ "$STEGHIDE" = 0 ]; then _warning "steghide not installed. Cannot exhume your key" return 1 fi - decode_key ${CMD2} + decode_key $PARAM[1] ;; resize) check_priv @@ -1740,8 +1765,9 @@ main() { 'source') return 0 ;; install) check_priv ; install_tomb ;; askpass) ask_password ${CMD2} ${CMD3} ;; - mktemp) safe_dir ${CMD2} ;; + mktemp) safe_dir $PARAM[1] ;; translate) generate_translatable_strings ;; + check) check_command $PARAM[1] ;; __default) cat <<EOF Tomb $VERSION - a strong and gentle undertaker for your secrets @@ -1770,8 +1796,9 @@ EOF # {{{ RUNTIME check_bin main $@ -if [[ $? != 0 ]]; then #this "if" seems useless, but avoid source tomb source from exiting - exit $? +ret=$? +if [[ $ret != 0 ]]; then #this "if" seems useless, but avoid source tomb source from exiting + exit $ret fi # }}} diff --git a/src/undertaker b/src/undertaker @@ -32,21 +32,21 @@ TRAPSTOP() die "STOP signal caught, undertaker aborting." # first of all source the tomb core functions which tomb > /dev/null if [[ $? != 0 ]]; then - print "$fg[red][!]$fg[white] Tomb command not found, operation aborted."; exit 1 + print "$fg[red][!]$fg[white] Tomb command not found, operation aborted." >&2; exit 1 fi key_found() { # $1 is "url" - if option_is_set --machine-parseable; then - print -n '[m]' + if option_is_set --batch; then + print -n '[m]' >&2 fi - print "$fg[white][found] $1" + print "$fg[white][found] $1" >&2 } function undertaker_scheme() { - zparseopts -D -print-path=print_path + zparseopts -D -path=print_path local scheme scheme=$1 @@ -60,7 +60,7 @@ function undertaker_scheme() { act "access to bluetooth protocol requested" which obexftp &> /dev/null if [[ $? != 0 ]]; then - error "obexftp not found, needed for bluetooth: operation aborted." + _warning "obexftp not found, needed for bluetooth: operation aborted." return 64 fi keytmp=`safe_dir undertaker` @@ -95,10 +95,10 @@ function undertaker_scheme() { file) if ! [[ -f $keypath ]]; then - error "Invalid path $keypath" + _warning "Invalid path $keypath" return 1 fi - if [[ -n $print_path ]]; then + if option_is_set --path; then key_found $scheme://$keypath; else < $keypath @@ -122,7 +122,7 @@ function undertaker_scheme() { #It implements automounting using udisks; udisks is a (recently) #new technology, so we can't rely on it being present if ! which udisks &> /dev/null; then - error 'udisks not found' + _warning 'udisks not found' exit 64 fi while true; do @@ -149,7 +149,7 @@ function undertaker_scheme() { *) if ! which undertaker-$scheme &> /dev/null; then - error "url protocol not recognized: $scheme" + _warning "url protocol not recognized: $scheme" return 64 fi undertaker-$scheme ${print_path[@]} ${scheme}://$keypath @@ -162,13 +162,14 @@ function main() { typeset -A opts zparseopts -M -E -D -Aopts -poll -path -batch if ! [ $1 ] ; then - error "an argument is missing, the undertaker is confused" - act "usage: undertaker [options] url://host:path/to/tomb.key" + print "[W] an argument is missing, the undertaker is confused" >&2 + print "usage: undertaker [options] url://host:path/to/tomb.key" >&2 exit 1; fi local -a tomb_opts if [[ -n ${(k)opts[--batch]} ]]; then - tomb_opts+='--batch' + tomb_opts+='--no-color' + tomb_opts+='--quiet' fi local -a under_opts if [[ -n ${(k)opts[--path]} ]]; then @@ -178,13 +179,14 @@ function main() { for a in ${(k)opts}; do backupopts[$a]=${opts[$a]} done - source tomb ${tomb_opts[@]} source + source tomb ${tomb_opts[@]} source + TOMBEXEC=undertaker for a in ${(k)backupopts}; do opts[$a]=${backupopts[$a]} done check_bin - notice "Undertaker will look for $1" + _success "Undertaker will look for $1" ARG1=${1} scheme=${ARG1%://*}