--- /dev/null
+[Desktop Entry]
+Encoding=UTF-8
+Version=0.1
+Name=Secret Notes
+Exec=/opt/bin/secretnotes
+Type=Application
+Icon=secretnotes
+X-Window-Icon=secretnotes
--- /dev/null
+secretnotes (0.1-1) unstable; urgency=low
+
+ * Initial release
+
+ -- Janusz Sobczak <janusz.sobczak@gmail.com> Tue, 17 Nov 2009 11:29:21 +0200
--- /dev/null
+Source: secretnotes
+Section: user/utilities
+Priority: extra
+Maintainer: Janusz Sobczak
+ <janusz.sobczak@gmail.com>
+Build-Depends: debhelper (>= 5)
+Standards-Version: 3.7.2
+
+Package: secretnotes
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Description: The simplest way to protect your passwords, codes and PINs.
+ Secret Notes is a very easy to use notes application.
+ Notes are protected with a single password and strong encryption
+ is in place to keep your data safe.
+XB-Description-pl_PL: Najprostszy sposób na zapisanie haseł i PIN-ów.
+ Tajne Notatki to bardzo łatwy w użyciu notatnik.
+ Notatki są chronione pojedynczym hasłem i szyfrowane,
+ by Twoje dane były bezpieczne.
+XSBC-Bugtracker: https://garage.maemo.org/tracker/?group_id=1609
+XB-Maemo-Display-Name: Secret Notes
+XB-Maemo-Display-Name-pl_PL: Tajne Notatki
+XB-Maemo-Icon-26:
+ iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAMAAABg3Am1AAAAAXNSR0IArs4c
+ 6QAAAPNQTFRFMAqPFBQUHx8fKC0RKioqLTMQNDQ0NjY2OUIOPz8/R0dHSEhI
+ UVFRYWFhaGhob29veXl5goKCioqKj4+PkJCQmZmZn5+foKCgoqKimLkAq6ur
+ ra2tp8MmtbW1t7e3vb29v7+/xcXFx8fHycnJysrKy8vLzMzMz8/P0NDQ0dHR
+ 0tLS09PT1dXV1tbW19fX2NjY2dnZ2tra29vb3Nzc3d3d3t7e39/f4ODg4eHh
+ 4uLi4+Pj5OTk5eXl5ubm4+y45+fn6Ojo6enp6urq6+vr7Ozs7e3t7u7u7+/v
+ 8PDw8fHx8vLy8/Pz9PT09fX19fno+Pj4+fn5KknqrgAAAAF0Uk5TAEDm2GYA
+ AAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfaBQ0OMhC/oqtbAAAAGXRF
+ WHRDb21tZW50AENyZWF0ZWQgd2l0aCBHSU1QV4EOFwAAAWJJREFUSMftldlS
+ g0AQRdlkNMZ9xTXGuJuoASEoyDILaOLy/1+jzJBUTKoyzatlv1HVh3u77zAo
+ yh8tqyx4u67+lA5EyvYSAb9+REiQj/H2gpi3ZAKiER3uIpArIYDS1L64v0aC
+ kAsgSjMWJ8EtJ2ZKCAGb0j5OXgO3IZUQE1yS7J0x4vn7/HEmMFd0nDhpn2U0
+ 6a7LFcQMrWCQ54SeymcYbqn39pXjELClYQ4o/8wGIghZ1GXSdczqKkBAUQ7E
+ WTIJNaEHlrvSCNMAfsbCoEwWwQTAsooAoWCAz2AkqQEG+JYibIKBwstSGixD
+ t8QBB4fnkNhGh8MlUQQFihG0hySMVJgnLrDQcv1eDSQhHG01O0+PizCgcGTs
+ dRzfPQMlUTpywii+qkGG4MBG236OvSbEkxhhs+1h0m2sQAD+wa1uH9/dHO2s
+ Ac6fpU6W7G6dAiB3axVAV6c9Qf6Gv+pF+a+q9Q2T/S5Rnub5MAAAAABJRU5E
+ rkJggg==
--- /dev/null
+#!/usr/bin/make -f
+APPNAME := secretnotes
+builddir:
+ mkdir -p builddir
+
+builddir/Makefile: builddir
+ cd builddir && qmake-qt4 ../$(APPNAME).pro
+
+build: build-stamp
+
+build-stamp: builddir/Makefile
+ dh_testdir
+ # Add here commands to compile the package.
+ cd builddir && $(MAKE)
+ touch $@
+clean:
+ dh_testdir
+ dh_testroot
+ rm -f build-stamp
+ # Add here commands to clean up after the build process.
+ rm -rf builddir
+ dh_clean
+install: build
+ dh_testdir
+ dh_testroot
+ dh_clean -k
+ dh_installdirs
+
+ # Add here commands to install the package into debian/your_appname
+ cd builddir && $(MAKE) INSTALL_ROOT=$(CURDIR)/debian/$(APPNAME) install
+# Build architecture-independent files here.
+binary-indep: build install
+# We have nothing to do by default.
+
+# # Build architecture-dependent files here.
+binary-arch: build install
+ dh_testdir
+ dh_testroot
+ dh_installdocs
+ dh_installexamples
+ dh_installman
+ dh_link
+ dh_strip --dbg-package=secretnotes-dbg
+ dh_compress
+ dh_fixperms
+ dh_installdeb
+ dh_shlibdeps
+ dh_gencontrol
+ dh_md5sums
+ dh_builddeb
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install configure
--- /dev/null
+QMAKEVERSION = $$[QMAKE_VERSION]
+ISQT4 = $$find(QMAKEVERSION, ^[2-9])
+isEmpty( ISQT4 ) {
+error("Use the qmake include with Qt4.4 or greater, on Debian that is qmake-qt4");
+}
+
+TEMPLATE = subdirs
+SUBDIRS = src
+
--- /dev/null
+Note: see data/COPYING for license terms on the data files.
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
--- /dev/null
+/*
+ * This file is part of Secret Notes.
+ * Copyright (C) 2010 Janusz Sobczak
+ *
+ * Secret Notes is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Secret Notes is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Secret Notes. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <QtGui/QApplication>
+#include "mainwindow.h"
+#include <QTranslator>
+#include <QLocale>
+
+/* convert preprocesor variable to string */
+#define TOSTRING_(x) #x
+#define TOSTRING(x) TOSTRING_(x)
+
+int main(int argc, char *argv[])
+{
+ QApplication a(argc, argv);
+ QString translationDir;
+#if defined(PREFIX)
+ translationDir = QString(TOSTRING(PREFIX))+QString("/share/secretnotes");
+#endif
+ QTranslator translator;
+ translator.load(QString("secretnotes_")+QLocale::system().name(),
+ translationDir);
+
+ a.installTranslator(&translator);
+ MainWindow w;
+ w.show();
+ return a.exec();
+}
--- /dev/null
+/*
+ * This file is part of Secret Notes.
+ * Copyright (C) 2010 Janusz Sobczak
+ *
+ * Secret Notes is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Secret Notes is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Secret Notes. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <QDir>
+#include "mainwindow.h"
+#include "ui_mainwindow.h"
+#include <qmessagebox.h>
+#include <qtimer.h>
+#include <qfile.h>
+#include <qdatastream.h>
+#include <qinputdialog.h>
+#include <openssl/blowfish.h>
+#include <openssl/sha.h>
+#include "passworddialog.h"
+
+const char filename[] = "secretnotes.scn";
+
+MainWindow::MainWindow(QWidget *parent) :
+ QMainWindow(parent),
+ ui(new Ui::MainWindow),
+ password(NULL),
+ hasPasswordChanged(false),
+ hasReadFile(false)
+{
+ ui->setupUi(this);
+ enableTextEdit(false);
+ undoResetAction = ui->menuOptions->addAction(tr("Undo reset"));
+ connect(undoResetAction, SIGNAL(triggered()),this, SLOT(undoReset()));
+ enableUndoReset(false);
+
+ undoEditAction = ui->menuOptions->addAction(tr("Undo edit"));
+ connect(undoEditAction,SIGNAL(triggered()), this, SLOT(undoEdit()));
+ on_textEdit_undoAvailable(false);
+
+ /* the secret notes file is stored in user home directory */
+ filePath = QDir::fromNativeSeparators(QDir::homePath());
+
+ /* or in $HOME/DOCUMENTS */
+#if defined(DOCUMENTS)
+#define DOC_DIR_(x) #x
+#define DOC_DIR(x) DOC_DIR_(x)
+ QString doc(filePath + QString("/") + QString(DOC_DIR(DOCUMENTS)));
+ QDir dir(doc);
+ if (dir.exists())
+ filePath = doc;
+#endif
+ QTimer::singleShot(1, this, SLOT(readFile()));
+}
+
+MainWindow::~MainWindow()
+{
+ plaintext.fill(0);
+ undoText.fill(0);
+ delete ui;
+ if (password)
+ memset(password,0,passLength);
+ delete[] password;
+}
+
+void MainWindow::changeEvent(QEvent *e)
+{
+ QMainWindow::changeEvent(e);
+ switch (e->type()) {
+ case QEvent::LanguageChange:
+ ui->retranslateUi(this);
+ break;
+ default:
+ break;
+ }
+}
+
+void MainWindow::closeEvent(QCloseEvent *event)
+{
+ QFile file(filePath + QString("/") + filename);
+ QString text = ui->textEdit->toPlainText();
+
+ /* don't save the file if content hasn't changed */
+ if (((text == plaintext) && (!hasPasswordChanged)) ||
+ (!ui->textEdit->isEnabled()) ||
+ (text.length() < 1)) {
+ text.fill(0);
+ return;
+ }
+
+ QByteArray encoded;
+ if (!password)
+ askNewPassword();
+
+ /* has user provided a password */
+ if (!password) {
+ text.fill(0);
+ return;
+ }
+
+ encode(encoded, text);
+ text.fill(0);
+
+ if (encoded.length() < 1)
+ return;
+
+ if (!file.open(QIODevice::WriteOnly)) {
+ QMessageBox::warning(this, tr("File open failed"),
+ tr("Can't open %1").arg(filename),QMessageBox::Ok);
+ } else {
+ QDataStream stream(&file);
+ stream << QString("SECRETNOTES");
+ stream << (short int)1;
+ stream << encoded;
+ hasPasswordChanged = false;
+ }
+ text.fill(0);
+ encoded.fill(0);
+ event->accept();
+}
+
+void MainWindow::readFile()
+{
+ /* we want to call readFile only once */
+ if (hasReadFile)
+ return;
+ hasReadFile = true;
+
+ QFile file(filePath + QString("/") + filename);
+ if (!file.open(QIODevice::ReadOnly)) {
+ ui->textEdit->setPlainText("");
+ enableTextEdit(true);
+ askNewPassword();
+ QMessageBox::information(this,tr("Welcome"),
+ tr("Welcome to Secret Notes.\n"
+ "Your data will be saved automatically\n"
+ "when you close Secret Notes."));
+ } else {
+ QString decoded;
+ QString head;
+ short int version;
+ QByteArray text;
+ QDataStream stream(&file);
+ stream >> head;
+ stream >> version;
+ if ((head != QString("SECRETNOTES")) || (version != 1))
+ return;
+ stream >> text;
+ if (text.length() > 0) {
+ queryPassword(false);
+ if (!decode(decoded, text)) {
+ int i;
+ bool ok;
+ for (i=0; i<2; i++) {
+ queryPassword(true);
+ ok = decode(decoded, text);
+ if (ok)
+ break;
+ }
+ if (!ok)
+ return;
+ }
+ plaintext.fill(0);
+ plaintext = decoded;
+ ui->textEdit->setPlainText(plaintext);
+ enableTextEdit(true);
+ }
+ decoded.fill(0);
+ }
+}
+
+void MainWindow::queryPassword(bool retry)
+{
+ if (password && !retry)
+ return;
+ bool ok;
+ QString pass = QInputDialog::getText(this,
+ tr("Password"),
+ tr("Enter passphrase:"),
+ QLineEdit::PasswordEchoOnEdit,"", &ok);
+ if (ok) {
+ setPassword(pass);
+ pass.fill(0);
+ }
+}
+
+bool MainWindow::decode(QString &output, const QByteArray &input)
+{
+ int size = input.length();
+ int length = size - 8 - SHA_DIGEST_LENGTH;
+ if (length < 0)
+ return false;
+ if (!password)
+ return false;
+ char *out = new char[size+1];
+ out[size] = 0;
+
+ blowfish((unsigned char*)out, (unsigned char*)input.constData(), size, 0);
+
+ const char *text = out + 8 + SHA_DIGEST_LENGTH;
+ /* verify SHA checksum */
+ unsigned char *md =
+ SHA1((unsigned char *)text, length, NULL);
+ unsigned char *digest = (unsigned char *)out + 8;
+ for (int i=0; i<SHA_DIGEST_LENGTH; i++) {
+ if (md[i] != digest[i]) {
+ memset(out, 0, size);
+ delete[] out;
+ return false;
+ }
+ }
+
+ output = QString::fromUtf8(qUncompress(QByteArray(text, length)));
+ memset(out, 0, size);
+ delete[] out;
+ return true;
+}
+
+void MainWindow::encode(QByteArray &output, const QString &input)
+{
+ QByteArray bytes = qCompress(input.toUtf8());
+ int length = bytes.size();
+ int size = 8 + SHA_DIGEST_LENGTH + length;
+ QByteArray in;
+ char *out = new char[size];
+ int i;
+
+ in.reserve(size);
+ /* add 8 psuedo random bytes */
+ qsrand((uint)&bytes + size);
+ for(i=0; i<8; i++)
+ in.append((char)qrand());
+
+ /* add SHA checksum */
+ unsigned char *md = SHA1((unsigned char*)bytes.constData(), length, NULL);
+ for(i=0; i<SHA_DIGEST_LENGTH; i++)
+ in.append((char)md[i]);
+
+ /* add input text */
+ in.append(bytes);
+
+ blowfish((unsigned char*)out, (unsigned char*)in.constData(), size, 1);
+ output = QByteArray(out, size);
+ bytes.fill(0);
+ in.fill(0);
+ delete[] out;
+}
+
+void MainWindow::blowfish(unsigned char *output, const unsigned char *input,
+ int length, int enc)
+{
+ BF_KEY key;
+ unsigned char ivec[8];
+ int num = 0;
+
+ BF_set_key(&key, passLength, password);
+ BF_cfb64_encrypt(input, output, length, &key, ivec, &num, enc);
+ memset(&key, 0, sizeof(BF_KEY));
+}
+
+void MainWindow::on_actionChange_password_triggered()
+{
+ PasswordDialog dialog(this, (char*)password);
+ if (dialog.exec() == QDialog::Accepted) {
+ QString pass = dialog.getPassword();
+ setPassword(pass);
+ pass.fill(0);
+ }
+}
+
+void MainWindow::on_actionReset_secret_notes_triggered()
+{
+ if (QMessageBox::question(this, tr("Reset secret notes"),
+ tr("Do you want to reset Secret Notes?\n"
+ "This will destroy all contents!"),
+ QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) {
+ return;
+ }
+ if (password)
+ memset(password, 0, passLength);
+ delete[] password;
+ password = NULL;
+ if (plaintext.length() > 0) {
+ undoText.fill(0);
+ undoText = plaintext;
+ }
+
+ if (undoText.length() > 0)
+ enableUndoReset(true);
+ ui->textEdit->clear();
+ enableTextEdit(true);
+ askNewPassword();
+}
+
+void MainWindow::setPassword(const QString &text)
+{
+ int length = text.length();
+ if (length > 0) {
+ if (password)
+ memset(password, 0, passLength);
+ delete[] password;
+ password = new unsigned char[length+1];
+ int i;
+ for(i=0; i<length; i++)
+ password[i] = text.constData()[i].toAscii();
+ password[i] = 0;
+ passLength = length;
+ hasPasswordChanged = true;
+ }
+}
+
+void MainWindow::askNewPassword()
+{
+ int retries = 3;
+ PasswordDialog dialog(this);
+ dialog.hideOldPassword(true);
+ while (retries--) {
+ if (dialog.exec() == QDialog::Accepted) {
+ QString pass = dialog.getPassword();
+ setPassword(pass);
+ pass.fill(0);
+ return;
+ }
+ }
+}
+
+void MainWindow::enableTextEdit(bool ena)
+{
+ ui->textEdit->setEnabled(ena);
+ if (!ena) {
+ ui->textEdit->setPlainText(tr("Secret Notes disabled"));
+ }
+}
+
+void MainWindow::enableUndoReset(bool ena)
+{
+ undoResetAction->setVisible(ena);
+}
+
+void MainWindow::undoReset()
+{
+ plaintext.fill(0);
+ plaintext = undoText;
+ undoText.fill(0);
+ undoText = "";
+ ui->textEdit->setPlainText(plaintext);
+ enableUndoReset(false);
+ enableTextEdit(true);
+}
+
+void MainWindow::undoEdit()
+{
+ ui->textEdit->undo();
+}
+
+void MainWindow::on_textEdit_undoAvailable(bool b)
+{
+ undoEditAction->setVisible(b);
+}
--- /dev/null
+/*
+ * This file is part of Secret Notes.
+ * Copyright (C) 2010 Janusz Sobczak
+ *
+ * Secret Notes is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Secret Notes is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Secret Notes. If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QMainWindow>
+
+namespace Ui {
+ class MainWindow;
+}
+
+class MainWindow : public QMainWindow {
+ Q_OBJECT
+public:
+ MainWindow(QWidget *parent = 0);
+ ~MainWindow();
+
+protected:
+ void changeEvent(QEvent *e);
+ void closeEvent(QCloseEvent *);
+
+private:
+ Ui::MainWindow *ui;
+ void queryPassword(bool retry);
+ unsigned char* password;
+ int passLength;
+ bool hasPasswordChanged;
+ bool hasReadFile;
+ bool decode(QString& output, const QByteArray& input);
+ void encode(QByteArray& output, const QString& input);
+ void blowfish(unsigned char *output, const unsigned char *input,
+ int length, int enc);
+ void setPassword(const QString& text);
+ void askNewPassword();
+ QString plaintext;
+ QString undoText;
+ void enableTextEdit(bool);
+ void enableUndoReset(bool);
+ QAction *undoResetAction;
+ QAction *undoEditAction;
+ QString filePath;
+
+private slots:
+ void on_actionReset_secret_notes_triggered();
+ void on_actionChange_password_triggered();
+ void on_textEdit_undoAvailable(bool b);
+ void undoReset();
+ void undoEdit();
+ void readFile();
+};
+
+#endif // MAINWINDOW_H
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>600</width>
+ <height>400</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Secret Notes</string>
+ </property>
+ <widget class="QWidget" name="centralWidget">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QPlainTextEdit" name="textEdit">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="readOnly">
+ <bool>false</bool>
+ </property>
+ <property name="backgroundVisible">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QMenuBar" name="menuBar">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>600</width>
+ <height>25</height>
+ </rect>
+ </property>
+ <widget class="QMenu" name="menuOptions">
+ <property name="title">
+ <string>Options</string>
+ </property>
+ <addaction name="actionChange_password"/>
+ <addaction name="actionReset_secret_notes"/>
+ </widget>
+ <addaction name="menuOptions"/>
+ </widget>
+ <action name="actionChange_password">
+ <property name="text">
+ <string>Change password</string>
+ </property>
+ </action>
+ <action name="actionReset_secret_notes">
+ <property name="text">
+ <string>Reset secret notes</string>
+ </property>
+ </action>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <resources/>
+ <connections/>
+</ui>
--- /dev/null
+/*
+ * This file is part of Secret Notes.
+ * Copyright (C) 2010 Janusz Sobczak
+ *
+ * Secret Notes is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Secret Notes is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Secret Notes. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <qmessagebox.h>
+#include "passworddialog.h"
+#include "ui_passworddialog.h"
+#include <QPushButton>
+
+
+PasswordDialog::PasswordDialog(QWidget *parent, const char *password) :
+ QDialog(parent),
+ ui(new Ui::PasswordDialog),
+ oldPassword(password),
+ verifyOldPassword(true)
+{
+ ui->setupUi(this);
+ enableOKButton(false);
+}
+
+PasswordDialog::~PasswordDialog()
+{
+ oldPassword.fill(0);
+ delete ui;
+}
+
+void PasswordDialog::changeEvent(QEvent *e)
+{
+ QDialog::changeEvent(e);
+ switch (e->type()) {
+ case QEvent::LanguageChange:
+ ui->retranslateUi(this);
+ break;
+ default:
+ break;
+ }
+}
+
+void PasswordDialog::hideOldPassword(bool hide)
+{
+ ui->oldEdit->setVisible(!hide);
+ ui->oldLabel->setVisible(!hide);
+ verifyOldPassword = !hide;
+}
+
+QString PasswordDialog::getPassword()
+{
+ return ui->newEdit->text();
+}
+
+void PasswordDialog::on_oldEdit_textChanged(QString text)
+{
+ isOldPasswordCorrect = (text == oldPassword);
+ enableOKButton((!verifyOldPassword || isOldPasswordCorrect) &&
+ isNewPasswordCorrect);
+}
+
+void PasswordDialog::on_newEdit_textChanged(QString text)
+{
+ isNewPasswordCorrect = (text.length() > 0 &&
+ text == ui->newAgainEdit->text());
+ enableOKButton((!verifyOldPassword || isOldPasswordCorrect) &&
+ isNewPasswordCorrect);
+}
+
+
+void PasswordDialog::on_newAgainEdit_textChanged(QString text)
+{
+ isNewPasswordCorrect = (text.length() > 0 &&
+ text == ui->newEdit->text());
+ enableOKButton((!verifyOldPassword || isOldPasswordCorrect) &&
+ isNewPasswordCorrect);
+}
+
+void PasswordDialog::enableOKButton(bool ena)
+{
+ ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(ena);
+}
--- /dev/null
+/*
+ * This file is part of Secret Notes.
+ * Copyright (C) 2010 Janusz Sobczak
+ *
+ * Secret Notes is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Secret Notes is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Secret Notes. If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef PASSWORDDIALOG_H
+#define PASSWORDDIALOG_H
+
+#include <QDialog>
+
+namespace Ui {
+ class PasswordDialog;
+}
+
+class PasswordDialog : public QDialog {
+ Q_OBJECT
+public:
+ PasswordDialog(QWidget *parent = 0, const char *password = 0);
+ ~PasswordDialog();
+ void hideOldPassword(bool hide);
+ QString getPassword();
+
+protected:
+ void changeEvent(QEvent *e);
+
+private:
+ Ui::PasswordDialog *ui;
+ QString oldPassword;
+ bool verifyOldPassword;
+ bool isOldPasswordCorrect;
+ bool isNewPasswordCorrect;
+ void enableOKButton(bool ena);
+
+
+private slots:
+ void on_newAgainEdit_textChanged(QString );
+ void on_newEdit_textChanged(QString );
+ void on_oldEdit_textChanged(QString );
+};
+
+#endif // PASSWORDDIALOG_H
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>PasswordDialog</class>
+ <widget class="QDialog" name="PasswordDialog">
+ <property name="windowModality">
+ <enum>Qt::ApplicationModal</enum>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Set password</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="oldLabel">
+ <property name="text">
+ <string>Old password:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="oldEdit">
+ <property name="echoMode">
+ <enum>QLineEdit::PasswordEchoOnEdit</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>New password:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="newEdit">
+ <property name="echoMode">
+ <enum>QLineEdit::PasswordEchoOnEdit</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Repeat new password:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLineEdit" name="newAgainEdit">
+ <property name="echoMode">
+ <enum>QLineEdit::PasswordEchoOnEdit</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>145</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>PasswordDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>PasswordDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="pl_PL">
+<context>
+ <name>MainWindow</name>
+ <message>
+ <location filename="mainwindow.ui" line="14"/>
+ <source>Secret Notes</source>
+ <translation>Tajne notatki</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="44"/>
+ <source>Options</source>
+ <translation>Opcje</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="53"/>
+ <source>Change password</source>
+ <translation>Zmiana hasła</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="58"/>
+ <location filename="mainwindow.cpp" line="264"/>
+ <source>Reset secret notes</source>
+ <translation>Reset notatek</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="24"/>
+ <source>Undo reset</source>
+ <translation>Cofnij reset</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="28"/>
+ <source>Undo edit</source>
+ <translation>Cofnij edycję</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="99"/>
+ <source>File open failed</source>
+ <translation>Błąd otwarcia pliku</translation>
+ </message>
+ <message>
+ <source>Can't open secretnotes.txt</source>
+ <translation type="obsolete">Nie udało się otworzyć pliku secretnotes.txt</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="100"/>
+ <source>Can't open %1</source>
+ <translation>Nie można otworzyć %1</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="125"/>
+ <source>Welcome</source>
+ <translation>Powitanie</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="126"/>
+ <source>Welcome to Secret Notes.
+Your data will be saved automatically
+when you close Secret Notes.</source>
+ <translation>Zapraszamy do Tajnych Notatek.
+Twoje wpisy zostaną automatyczne zapisane
+podczas zamykania programu.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="169"/>
+ <source>Password</source>
+ <translation>Hasło</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="170"/>
+ <source>Enter passphrase:</source>
+ <translation>Podaj hasło:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="265"/>
+ <source>Do you want to reset Secret Notes?
+This will destroy all contents!</source>
+ <translation>Czy na pewno chcesz zresetować notatki?
+To skasuje wszystkie dane!</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="322"/>
+ <source>Secret Notes disabled</source>
+ <translation>Tajne Notatki nieaktywne</translation>
+ </message>
+</context>
+<context>
+ <name>PasswordDialog</name>
+ <message>
+ <location filename="passworddialog.ui" line="17"/>
+ <source>Set password</source>
+ <translation>Ustawienie hasła</translation>
+ </message>
+ <message>
+ <location filename="passworddialog.ui" line="25"/>
+ <source>Old password:</source>
+ <translation>Stare hasło:</translation>
+ </message>
+ <message>
+ <location filename="passworddialog.ui" line="39"/>
+ <source>New password:</source>
+ <translation>Nowe hasło:</translation>
+ </message>
+ <message>
+ <location filename="passworddialog.ui" line="53"/>
+ <source>Repeat new password:</source>
+ <translation>Powtórz nowe hasło:</translation>
+ </message>
+ <message>
+ <source>Bad password</source>
+ <translation type="obsolete">Niepoprawne hasło</translation>
+ </message>
+ <message>
+ <source>Incorrect old password.
+Password not changed.</source>
+ <translation type="obsolete">Nieprawidłowe stare hasło.
+Hasło niezmienione.</translation>
+ </message>
+ <message>
+ <source>New passwords don't match.
+Password not changed.</source>
+ <translation type="obsolete">Nowe hasło się nie zgadza.
+Hasło niezmienione.</translation>
+ </message>
+</context>
+</TS>
--- /dev/null
+# -------------------------------------------------
+# Project created by QtCreator 2010-05-10T11:29:23
+# -------------------------------------------------
+TARGET = secretnotes
+TEMPLATE = app
+CONFIG += link_pkgconfig
+PKGCONFIG += openssl
+SOURCES += main.cpp \
+ mainwindow.cpp \
+ passworddialog.cpp
+HEADERS += mainwindow.h \
+ passworddialog.h
+FORMS += mainwindow.ui \
+ passworddialog.ui
+TRANSLATIONS = secretnotes_pl.ts
+
+unix {
+ #VARIABLES
+ isEmpty(PREFIX) {
+ PREFIX = /opt/usr
+ }
+ BINDIR = $$PREFIX/bin
+ DATADIR =$$PREFIX/share
+ DOCUMENTS = MyDocs/.documents
+
+ DEFINES += DATADIR=\\\"$$DATADIR\\\" PKGDATADIR=\\\"$$PKGDATADIR\\\" PREFIX=$$PREFIX DOCUMENTS=$$DOCUMENTS
+
+ #MAKE INSTALL
+
+ INSTALLS += target desktop translations icon48
+
+ target.path =$$BINDIR
+
+ desktop.path = /usr/share/applications/hildon
+ desktop.files += ../data/$${TARGET}.desktop
+
+ translations.path = $${DATADIR}/secretnotes
+ translations.files += $${TARGET}_*.qm
+
+ icon48.path = /usr/share/icons/hicolor/48x48/apps
+ icon48.files = ../data/48x48/$${TARGET}.png
+}
+