Commit cce44851 authored by Philip Rinn's avatar Philip Rinn

Imported Upstream version 1.0.1

parent fedd4c18
Makefile
debian/qtpass*
debian/files
build-stamp
qtpass
QtPass.*
qtpass.pro.user
qtpass.xcodeproj/project.xcworkspace/xcuserdata/*
qtpass.xcodeproj/xcuserdata/*
qtpass.xcworkspace/xcuserdata/*
.DS_Store
.qmake.stash
*.o
moc_*.cpp
qrc_*.cpp
ui_*.h
language: cpp
sudo: false
os:
- linux
- osx
compiler:
- gcc
- clang
addons:
apt:
packages:
- qt5-default
script:
- qmake -v
- qmake -Wall qtpass.pro
- make -j$(nproc)
notifications:
irc:
channels:
- "chat.freenode.net#IJhack"
on_success: change
on_failure: always
matrix:
allow_failures:
- os: osx
#FAQ
## Issues
### Can't save a password
* Is folder initialised? Easiest way is to use the [Users] button and make sure you can encrypt for someone (eg. yourself)
* Are you using git? If not, make sure it is switched off.
### I have an issue with GNOME keyring
* Disable GNOME keyring
* Create a `~/.gnupg/gpg-agent.conf` containing:
```
enable-ssh-support
write-env-file
use-standard-socket
default-cache-ttl 600
max-cache-ttl 7200
```
Also, the following is useful to add to your .bashrc if you are using Yubikey NEO on Ubuntu:
```
# OpenPGP applet support for YubiKey NEO
if [ ! -f /tmp/gpg-agent.env ]; then
killall gpg-agent;
eval $(gpg-agent --daemon --enable-ssh-support > /tmp/gpg-agent.env);
fi
. /tmp/gpg-agent.env
```
* More info: [issue 60](https://github.com/IJHack/qtpass/issues/60) and [issue 73](https://github.com/IJHack/qtpass/issues/73)
### Where can I ask for help?
* Create an [issue](https://github.com/IJHack/qtpass/) issues on github.
* Send an email to [help@qtpass.org](help@qtpass.org)
### Can I import from KeePass, LastPass or X?
* Yes, check [passwordstore.org/#migration](http://www.passwordstore.org/#migration) for more info.
### I don't like the design, what gives?
* It's all on github, clone, change and send a pull request.
* Open an issue and point out defects or better yet propose changes.
## How can I help improve QtPass?
###I would like to donate!
* Time:
* Fork, clone hack and send a pull request.
* Find an [issue](https://github.com/IJHack/qtpass/issues) to work on..
* Money:
IJhack takes donations in [bitcoin](https://blockchain.info/address/146dqz8zXn9iNZMv5s7JVqwZKjrmumHBfb)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDisplayName</key>
<string>QtPass @SHORT_VERSION@</string>
<key>CFBundleExecutable</key>
<string>@EXECUTABLE@</string>
<key>CFBundleGetInfoString</key>
<string>@SHORT_VERSION@</string>
<key>CFBundleIconFile</key>
<string>icon.icns</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>@SHORT_VERSION@</string>
<key>CFBundleSignature</key>
<string>@TYPEINFO@</string>
<key>NOTE</key>
<string>QtPass is a multi-platform GUI for pass</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2014-2015 IJhack
This program 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.</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
</dict>
</plist>
qtpass
QtPass [![Build Status](https://travis-ci.org/IJHack/qtpass.svg?branch=master)](https://travis-ci.org/IJHack/qtpass)
======
QtPass is a gui for [pass](http://www.passwordstore.org/)
QtPass is a GUI for [pass](http://www.passwordstore.org/), the standard unix password manager.
Features
--------
* Using pass or git and gpg2 directly
* Configurable shoulder surfing protection options
* Cross platform: Linux, BSD, OS X and Windows
* Per-folder user selection for multi recipient encryption
* Multiple profiles
Logo based on https://commons.wikimedia.org/wiki/File:Heart-padlock.svg by AnonMoos.
Security considerations
-----------------------
Using this program will not magically keep your passwords secure against
compromised computers even if you use it in combination with a smartcard.
It does protect future and changed passwords though against anyone with access to
your password store only but not your keys.
Used with a smartcard it also protects against anyone just monitoring/copying
......@@ -16,6 +27,7 @@ Once you plug in your smartcard and enter your PIN (or due to CVE-2015-3298
even without your PIN) all your passwords available to the machine can be
decrypted by it, if there is malicious software targeted specifically against
it installed (or at least one that knows how to use a smartcard).
To get better protection out of use with a smartcard even against a targeted
attack I can think of at least two options:
* The smartcard must require explicit confirmation for each decryption operation.
......@@ -28,23 +40,34 @@ attack I can think of at least two options:
Unfortunately I do not know of any WebDAV service with OTP support except ownCloud
(so you would have to run your own server).
Current state
-------------
* Using pass or directly with git and gpg2
* Configurable
* Cross platform
* Per-folder user selection
Known issues
------------
* Filtering (searching) breaks the tree/model sometimes
* Starting without a correctly set password-store folder give weird results in the tree view
* On Mac OS X only the gpgtools MacGPG2 version works with passphrase or PIN
Planned features
----------------
* Templates (username, url etc) in Add / Edit screen (configurable templates)
* Plugins based on field name, plugins follow same format as password files
* Re-encryption after users-change (optional of course)
* Colour coding folders (possibly disabling folders you can't decrypt)
* WebDAV (configuration) support
* Optional table view of decrypted folder contents
* Opening of (basic auth) urls in default browser? Possibly with helper plugin for filling out forms?
* Some other form of remote storage that allows for accountability / auditing (web API to retrieve the .gpg files?)
Instalation
-----------
Installation
------------
On most systems all you need is:
`qmake && make && make install`
On MacOsX:
`qmake && make && macdeployqt QtPass.app -dmg `
On Mac OS X:
`qmake && make && macdeployqt QtPass.app`
* Currently seems to only work with MacGPG2
Further reading
---------------
[Documentation](http://ijhack.github.io/qtpass/)
[Documentation](http://qtpass.org/)
[Source code](https://github.com/IJHack/qtpass)
{
"title": "QtPass",
"icon": "artwork/icon.icns",
"background": "artwork/icon.png",
"icon-size": 80,
"contents": [
{ "x": 64, "y": 64, "type": "file", "path": "QtPass.app" },
{ "x": 448, "y": 64, "type": "link", "path": "/Applications" },
{ "x": 64, "y": 448, "type": "file", "path": "README.rtf" },
{ "x": 448, "y": 448, "type": "file", "path": "LICENSE" }
]
}
No preview for this file type
debian/changelog
\ No newline at end of file
This diff is collapsed.
......@@ -3,8 +3,14 @@
#include <QDialog>
#include <QFileDialog>
#include "mainwindow.h"
#include <QTableWidgetItem>
#include <QCloseEvent>
namespace Ui {
struct UserInfo;
class Dialog;
}
......@@ -13,46 +19,97 @@ class Dialog : public QDialog
Q_OBJECT
public:
explicit Dialog(QWidget *parent = 0);
explicit Dialog(MainWindow *parent);
~Dialog();
void setPassPath(QString);
void setGitPath(QString);
void setGpgPath(QString);
void setStorePath(QString);
void setProfiles(QHash<QString, QString>, QString);
void usePass(bool);
void useClipboard(bool);
void useAutoclear(bool);
void setAutoclear(int);
void useAutoclearPanel(bool);
void setAutoclearPanel(int);
void hidePassword(bool);
void hideContent(bool);
void addGPGId(bool);
QString getPassPath();
QString getGitPath();
QString getGpgPath();
QString getStorePath();
QHash<QString,QString> getProfiles();
bool usePass();
bool useClipboard();
bool useAutoclear();
int getAutoclear();
bool useAutoclearPanel();
int getAutoclearPanel();
bool hidePassword();
bool hideContent();
bool addGPGId();
void wizard();
void genKey(QString, QDialog *);
bool useTrayIcon();
bool hideOnClose();
bool startMinimized();
void useTrayIcon(bool);
void hideOnClose(bool);
void startMinimized(bool);
void useGit(bool);
bool useGit();
QString getPwgenPath();
void setPwgenPath(QString);
void usePwgen(bool);
void useSymbols(bool);
void setPasswordLength(int);
void setPasswordChars(QString);
bool usePwgen();
bool useSymbols();
int getPasswordLength();
QString getPasswordChars();
bool useTemplate();
void useTemplate(bool);
QString getTemplate();
void setTemplate(QString);
void templateAllFields(bool);
bool templateAllFields();
bool autoPull();
void autoPull(bool);
bool autoPush();
void autoPush(bool);
protected:
void closeEvent(QCloseEvent *event);
private slots:
void on_radioButtonNative_clicked();
void on_radioButtonPass_clicked();
void on_toolButtonGit_clicked();
void on_toolButtonGpg_clicked();
void on_toolButtonPwgen_clicked();
void on_toolButtonPass_clicked();
void on_toolButtonStore_clicked();
void on_checkBoxClipboard_clicked();
void on_checkBoxAutoclear_clicked();
void on_checkBoxAutoclearPanel_clicked();
void on_addButton_clicked();
void on_deleteButton_clicked();
void on_checkBoxUseTrayIcon_clicked();
void on_checkBoxUseGit_clicked();
void on_checkBoxUsePwgen_clicked();
void on_checkBoxUseTemplate_clicked();
private:
QScopedPointer<Ui::Dialog> ui;
void setGroupBoxState();
QString selectExecutable();
QString selectFolder();
// QMessageBox::critical with hack to avoid crashes with
// Qt 5.4.1 when QApplication::exec was not yet called
void criticalMessage(const QString &title, const QString &text);
MainWindow *mainWindow;
};
#endif // DIALOG_H
This diff is collapsed.
start gpg4win\gpa.exe
#include "keygendialog.h"
#include "ui_keygendialog.h"
#include "progressindicator.h"
#include <QDebug>
#include <QMessageBox>
KeygenDialog::KeygenDialog(Dialog *parent) :
QDialog(parent),
ui(new Ui::KeygenDialog)
{
ui->setupUi(this);
dialog = parent;
}
KeygenDialog::~KeygenDialog()
{
delete ui;
}
void KeygenDialog::on_passphrase1_textChanged(const QString &arg1)
{
if (ui->passphrase1->text() == ui->passphrase2->text()) {
ui->buttonBox->setEnabled(true);
replace("Passphrase", arg1);
if (arg1 == "") {
no_protection(true);
} else {
no_protection(false);
}
} else {
ui->buttonBox->setEnabled(false);
}
}
void KeygenDialog::on_passphrase2_textChanged(const QString &arg1)
{
on_passphrase1_textChanged(arg1);
}
void KeygenDialog::on_checkBox_stateChanged(int arg1)
{
if (arg1) {
ui->plainTextEdit->setReadOnly(false);
ui->plainTextEdit->setEnabled(true);
} else {
ui->plainTextEdit->setReadOnly(true);
ui->plainTextEdit->setEnabled(false);
}
}
void KeygenDialog::on_email_textChanged(const QString &arg1)
{
replace("Name-Email", arg1);
}
void KeygenDialog::on_name_textChanged(const QString &arg1)
{
replace("Name-Real", arg1);
}
/**
* @brief KeygenDialog::replace
* @param key
* @param value
*/
void KeygenDialog::replace(QString key, QString value)
{
QStringList clear;
QString expert = ui->plainTextEdit->toPlainText();
QStringList lines = expert.split(QRegExp("[\r\n]"),QString::SkipEmptyParts);
foreach (QString line, lines) {
line.replace(QRegExp(key+":.*"), key + ": " + value);
if (key == "Passphrase") {
line.replace("%no-protection", "Passphrase: " + value);
}
clear.append(line);
}
ui->plainTextEdit->setPlainText(clear.join("\n"));
}
/**
* @brief KeygenDialog::no_protection
* @param enable
*/\
void KeygenDialog::no_protection(bool enable)
{
QStringList clear;
QString expert = ui->plainTextEdit->toPlainText();
QStringList lines = expert.split(QRegExp("[\r\n]"),QString::SkipEmptyParts);
foreach (QString line, lines) {
bool remove = false;
if (!enable) {
if (line.indexOf("%no-protection") == 0) {
remove = true;
}
} else {
if (line.indexOf("Passphrase") == 0) {
line = "%no-protection";
}
}
if (!remove) {
clear.append(line);
}
}
ui->plainTextEdit->setPlainText(clear.join("\n"));
}
/**
* @brief KeygenDialog::done
* @param r
*/
void KeygenDialog::done(int r)
{
if(QDialog::Accepted == r) // ok was pressed
{
ui->widget->setEnabled(false);
ui->buttonBox->setEnabled(false);
ui->checkBox->setEnabled(false);
ui->plainTextEdit->setEnabled(false);
QProgressIndicator* pi = new QProgressIndicator();
pi->startAnimation();
pi->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
ui->frame->hide();
ui->label->setText(QString("This operation can take some minutes.<br />") +
"We need to generate a lot of random bytes. It is a good idea to perform "
"some other action (type on the keyboard, move the mouse, utilize the "
"disks) during the prime generation; this gives the random number "
"generator a better chance to gain enough entropy.");
this->layout()->addWidget(pi);
this->show();
dialog->genKey(ui->plainTextEdit->toPlainText(), this);
}
else // cancel, close or exc was pressed
{
QDialog::done(r);
return;
}
}
void KeygenDialog::closeEvent(QCloseEvent *event) {
// TODO save window size or somethign
event->accept();
}
#ifndef KEYGENDIALOG_H
#define KEYGENDIALOG_H
#include <QDialog>
#include <QCloseEvent>
#include "dialog.h"
namespace Ui {
class KeygenDialog;
}
class KeygenDialog : public QDialog
{
Q_OBJECT
public:
explicit KeygenDialog(Dialog *parent = 0);
~KeygenDialog();
protected:
void closeEvent(QCloseEvent *event);
private slots:
void on_passphrase1_textChanged(const QString &arg1);
void on_passphrase2_textChanged(const QString &arg1);
void on_checkBox_stateChanged(int arg1);
void on_email_textChanged(const QString &arg1);
void on_name_textChanged(const QString &arg1);
private:
Ui::KeygenDialog *ui;
void replace(QString, QString);
void done(int r);
void no_protection(bool enable);
Dialog *dialog;
};
#endif // KEYGENDIALOG_H
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>KeygenDialog</class>
<widget class="QDialog" name="KeygenDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>606</width>
<height>480</height>
</rect>
</property>
<property name="windowTitle">
<string>Generate GnuPG keypair</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item>
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Generate a new key pair</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="1" column="0" colspan="2">
<widget class="QLabel" name="labelPassphrase">
<property name="text">
<string>Passphrase</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="labelEmail">
<property name="text">
<string>Email</string>
</property>
</widget>
</item>
<item row="2" column="2" colspan="3">
<widget class="QLineEdit" name="passphrase2">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item row="0" column="1" colspan="2">
<widget class="QLineEdit" name="email"/>
</item>
<item row="0" column="3">
<widget class="QLabel" name="labelName">
<property name="text">
<string>Name</string>
</property>
</widget>
</item>
<item row="1" column="2" colspan="3">
<widget class="QLineEdit" name="passphrase1">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QLineEdit" name="name"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QLabel" name="labelPassphraseInfo">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;There is no limit on the length of a passphrase, and it should be carefully chosen. From the perspective of security, the passphrase to unlock the private key is one of the weakest points in GnuPG (and other public-key encryption systems as well) since it is the only protection you have if another individual gets your private key. &lt;br/&gt;Ideally, the passphrase should not use words from a dictionary and should mix the case of alphabetic characters as well as use non-alphabetic characters.&lt;br/&gt;A good passphrase is crucial to the secure use of GnuPG.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBox">
<property name="text">
<string>Expert</string>
</property>
</widget>
</item>
<item>
<widget class="QPlainTextEdit" name="plainTextEdit">
<property name="enabled">
<bool>false</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
<property name="plainText">
<string># QtPass GPG key generator
#
# first test version please comment
#
%echo Generating a default key
Key-Type: default
Subkey-Type: default
Name-Real:
Name-Comment: QtPass
Name-Email:
Expire-Date: 0
%no-protection
# Do a commit here, so that we can later print &quot;done&quot; :-)
%commit
%echo done</string>
</property>
<property name="textInteractionFlags">
<set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
<property name="backgroundVisible">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelExpertInfo">
<property name="text">
<string>For expert options check out the &lt;a href=&quot;https://www.gnupg.org/documentation/manuals/gnupg/Unattended-GPG-key-generation.html&quot;&gt;GnuPG manual&lt;/a&gt;</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse</set>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">