11 Commits

Author SHA1 Message Date
Andrew Ayer
f3890bed32 Update debian/changelog for 0.4.2-1~agwa1 2015-01-31 19:44:08 -08:00
Andrew Ayer
78fb6ab052 debian packaging: install additional docs 2015-01-31 19:42:45 -08:00
Andrew Ayer
1fc9664036 Merge tag '0.4.2' into debian
git-crypt 0.4.2

git-crypt 0.4.2 is a bugfix-only release that fixes the unlock (and lock)
commands under Git 2.2.2 and newer.  Due to an optimization introduced in
Git 2.2.2, 'git-crypt unlock' would not decrypt files in the working tree.

In addition, this version of git-crypt officially drops support for
versions of Git older than 1.7.2.
2015-01-31 19:41:21 -08:00
Andrew Ayer
1ca8f89602 Prepare for 0.4.2 release 2015-01-31 19:20:05 -08:00
Andrew Ayer
2fa2cffba6 Freshen Debian packaging 2015-01-27 21:36:55 -08:00
Andrew Ayer
5fd36a7ac5 Increase minimum supported Git version to 1.7.2
Previously, git-crypt claimed to support Git as old as 1.6.0 (albeit
with degraded operation).  However, this has not been true for some time,
since Git 1.6.0 does not support the --porcelain option to `git status`.

Since Git 1.7.2 was the first version of Git to support filters with
`git blame`, was released almost five years ago (in July 2010), and is
even in Debian Squeeze, it seems like a good minimum version to require.
2015-01-27 21:26:51 -08:00
Andrew Ayer
d5670c9552 Force Git to check out files by touching their mtimes
Starting with Git 2.2.2, `git checkout -f HEAD` no longer checks out
files if their mtimes haven't changed.  This causes files to remain
encrypted in the work tree after running `git-crypt unlock`, and to
remain decrypted after running `git-crypt lock`'.

To fix this, git-crypt now figures out what files are encrypted (by
checking `git check-attr` on every file output by `git ls-files`),
touches those files, and then runs `git checkout` on them.
2015-01-27 21:15:07 -08:00
Andrew Ayer
2d2053296f Fix placement of quotes in an error message 2015-01-27 21:06:29 -08:00
Andrew Ayer
216aa27009 Add helper function to get attribute name for a given key 2015-01-27 21:04:58 -08:00
Andrew Ayer
02c52ab21a Disable message about unimplemented ls-gpg-users command 2015-01-27 21:04:22 -08:00
Andrew Ayer
6b78ef0548 Add initial Debian packaging 2014-03-29 17:39:53 -07:00
19 changed files with 207 additions and 85 deletions

View File

@@ -2,10 +2,8 @@ DEPENDENCIES
To use git-crypt, you need:
* Git 1.6.0 or newer
* Git 1.7.2 or newer
* OpenSSL
* For decrypted git diff output, Git 1.6.1 or newer
* For decrypted git blame output, Git 1.7.2 or newer
To build git-crypt, you need a C++ compiler and OpenSSL development
headers.

View File

@@ -3,10 +3,8 @@ Dependencies
To use git-crypt, you need:
* Git 1.6.0 or newer
* Git 1.7.2 or newer
* OpenSSL
* For decrypted git diff output, Git 1.6.1 or newer
* For decrypted git blame output, Git 1.7.2 or newer
To build git-crypt, you need a C++ compiler and OpenSSL development
headers.

5
NEWS
View File

@@ -1,3 +1,8 @@
v0.4.2 (2015-01-31)
* Fix unlock and lock under Git 2.2.2 and higher.
* Drop support for versions of Git older than 1.7.2.
* Minor improvements to some help/error messages.
v0.4.1 (2015-01-08)
* Important usability fix to ensure that the .git-crypt directory
can't be encrypted by accident (see RELEASE_NOTES-0.4.1.md for

View File

@@ -1,6 +1,11 @@
News
====
######v0.4.2 (2015-01-31)
* Fix unlock and lock under Git 2.2.2 and higher.
* Drop support for versions of Git older than 1.7.2.
* Minor improvements to some help/error messages.
######v0.4.1 (2015-01-08)
* Important usability fix to ensure that the .git-crypt directory
can't be encrypted by accident (see

2
README
View File

@@ -66,7 +66,7 @@ encryption and decryption happen transparently.
CURRENT STATUS
The latest version of git-crypt is 0.4.1, released on 2015-01-08.
The latest version of git-crypt is 0.4.2, released on 2015-01-31.
git-crypt aims to be bug-free and reliable, meaning it shouldn't
crash, malfunction, or expose your confidential data. However,
it has not yet reached maturity, meaning it is not as documented,

View File

@@ -67,8 +67,8 @@ encryption and decryption happen transparently.
Current Status
--------------
The latest version of git-crypt is [0.4.1](RELEASE_NOTES-0.4.1.md), released on
2015-01-08. git-crypt aims to be bug-free and reliable, meaning it
The latest version of git-crypt is [0.4.2](NEWS.md), released on
2015-01-31. git-crypt aims to be bug-free and reliable, meaning it
shouldn't crash, malfunction, or expose your confidential data.
However, it has not yet reached maturity, meaning it is not as
documented, featureful, or easy-to-use as it should be. Additionally,

View File

@@ -49,6 +49,17 @@
#include <errno.h>
#include <vector>
static std::string attribute_name (const char* key_name)
{
if (key_name) {
// named key
return std::string("git-crypt-") + key_name;
} else {
// default key
return "git-crypt";
}
}
static void git_config (const std::string& name, const std::string& value)
{
std::vector<std::string> command;
@@ -99,31 +110,20 @@ static void configure_git_filters (const char* key_name)
static void unconfigure_git_filters (const char* key_name)
{
// unconfigure the git-crypt filters
if (key_name) {
// named key
git_unconfig(std::string("filter.git-crypt-") + key_name);
git_unconfig(std::string("diff.git-crypt-") + key_name);
} else {
// default key
git_unconfig("filter.git-crypt");
git_unconfig("diff.git-crypt");
}
git_unconfig("filter." + attribute_name(key_name));
git_unconfig("diff." + attribute_name(key_name));
}
static bool git_checkout_head (const std::string& top_dir)
static bool git_checkout (const std::vector<std::string>& paths)
{
std::vector<std::string> command;
command.push_back("git");
command.push_back("checkout");
command.push_back("-f");
command.push_back("HEAD");
command.push_back("--");
if (top_dir.empty()) {
command.push_back(".");
} else {
command.push_back(top_dir);
for (std::vector<std::string>::const_iterator path(paths.begin()); path != paths.end(); ++path) {
command.push_back(*path);
}
if (!successful_exit(exec_command(command))) {
@@ -256,18 +256,6 @@ static void get_git_status (std::ostream& output)
}
}
static bool check_if_head_exists ()
{
// git rev-parse HEAD
std::vector<std::string> command;
command.push_back("git");
command.push_back("rev-parse");
command.push_back("HEAD");
std::stringstream output;
return successful_exit(exec_command(command, output));
}
// returns filter and diff attributes as a pair
static std::pair<std::string, std::string> get_file_attributes (const std::string& filename)
{
@@ -368,6 +356,35 @@ static bool check_if_file_is_encrypted (const std::string& filename)
return check_if_blob_is_encrypted(object_id);
}
static void get_encrypted_files (std::vector<std::string>& files, const char* key_name)
{
// git ls-files -cz -- path_to_top
std::vector<std::string> command;
command.push_back("git");
command.push_back("ls-files");
command.push_back("-cz");
command.push_back("--");
const std::string path_to_top(get_path_to_top());
if (!path_to_top.empty()) {
command.push_back(path_to_top);
}
std::stringstream output;
if (!successful_exit(exec_command(command, output))) {
throw Error("'git ls-files' failed - is this a Git repository?");
}
while (output.peek() != -1) {
std::string filename;
std::getline(output, filename, '\0');
// TODO: get file attributes en masse for efficiency... unfortunately this requires machine-parseable output from git check-attr to be workable, and this is only supported in Git 1.8.5 and above (released 27 Nov 2013)
if (get_file_attributes(filename).first == attribute_name(key_name)) {
files.push_back(filename);
}
}
}
static void load_key (Key_file& key_file, const char* key_name, const char* key_path =0, const char* legacy_path =0)
{
if (legacy_path) {
@@ -781,25 +798,18 @@ void help_unlock (std::ostream& out)
}
int unlock (int argc, const char** argv)
{
// 0. Make sure working directory is clean (ignoring untracked files)
// We do this because we run 'git checkout -f HEAD' later and we don't
// want the user to lose any changes. 'git checkout -f HEAD' doesn't touch
// untracked files so it's safe to ignore those.
// 1. Make sure working directory is clean (ignoring untracked files)
// We do this because we check out files later, and we don't want the
// user to lose any changes. (TODO: only care if encrypted files are
// modified, since we only check out encrypted files)
// Running 'git status' also serves as a check that the Git repo is accessible.
std::stringstream status_output;
get_git_status(status_output);
// 1. Check to see if HEAD exists. See below why we do this.
bool head_exists = check_if_head_exists();
if (status_output.peek() != -1 && head_exists) {
// We only care that the working directory is dirty if HEAD exists.
// If HEAD doesn't exist, we won't be resetting to it (see below) so
// it doesn't matter that the working directory is dirty.
if (status_output.peek() != -1) {
std::clog << "Error: Working directory not clean." << std::endl;
std::clog << "Please commit your changes or 'git stash' them before running 'git-crypt' unlock." << std::endl;
std::clog << "Please commit your changes or 'git stash' them before running 'git-crypt unlock'." << std::endl;
return 1;
}
@@ -850,13 +860,14 @@ int unlock (int argc, const char** argv)
if (!decrypt_repo_keys(key_files, 0, gpg_secret_keys, repo_keys_path)) {
std::clog << "Error: no GPG secret key available to unlock this repository." << std::endl;
std::clog << "To unlock with a shared symmetric key instead, specify the path to the symmetric key as an argument to 'git-crypt unlock'." << std::endl;
std::clog << "To see a list of GPG keys authorized to unlock this repository, run 'git-crypt ls-collabs'." << std::endl;
// TODO std::clog << "To see a list of GPG keys authorized to unlock this repository, run 'git-crypt ls-gpg-users'." << std::endl;
return 1;
}
}
// 4. Install the key(s) and configure the git filters
std::vector<std::string> encrypted_files;
for (std::vector<Key_file>::iterator key_file(key_files.begin()); key_file != key_files.end(); ++key_file) {
std::string internal_key_path(get_internal_key_path(key_file->get_key_name()));
// TODO: croak if internal_key_path already exists???
@@ -867,18 +878,18 @@ int unlock (int argc, const char** argv)
}
configure_git_filters(key_file->get_key_name());
get_encrypted_files(encrypted_files, key_file->get_key_name());
}
// 5. Do a force checkout so any files that were previously checked out encrypted
// will now be checked out decrypted.
// If HEAD doesn't exist (perhaps because this repo doesn't have any files yet)
// just skip the checkout.
if (head_exists) {
if (!git_checkout_head(path_to_top)) {
std::clog << "Error: 'git checkout' failed" << std::endl;
std::clog << "git-crypt has been set up but existing encrypted files have not been decrypted" << std::endl;
return 1;
}
// 5. Check out the files that are currently encrypted.
// Git won't check out a file if its mtime hasn't changed, so touch every file first.
for (std::vector<std::string>::const_iterator file(encrypted_files.begin()); file != encrypted_files.end(); ++file) {
touch_file(*file);
}
if (!git_checkout(encrypted_files)) {
std::clog << "Error: 'git checkout' failed" << std::endl;
std::clog << "git-crypt has been set up but existing encrypted files have not been decrypted" << std::endl;
return 1;
}
return 0;
@@ -916,25 +927,18 @@ int lock (int argc, const char** argv)
return 2;
}
// 0. Make sure working directory is clean (ignoring untracked files)
// We do this because we run 'git checkout -f HEAD' later and we don't
// want the user to lose any changes. 'git checkout -f HEAD' doesn't touch
// untracked files so it's safe to ignore those.
// 1. Make sure working directory is clean (ignoring untracked files)
// We do this because we check out files later, and we don't want the
// user to lose any changes. (TODO: only care if encrypted files are
// modified, since we only check out encrypted files)
// Running 'git status' also serves as a check that the Git repo is accessible.
std::stringstream status_output;
get_git_status(status_output);
// 1. Check to see if HEAD exists. See below why we do this.
bool head_exists = check_if_head_exists();
if (status_output.peek() != -1 && head_exists) {
// We only care that the working directory is dirty if HEAD exists.
// If HEAD doesn't exist, we won't be resetting to it (see below) so
// it doesn't matter that the working directory is dirty.
if (status_output.peek() != -1) {
std::clog << "Error: Working directory not clean." << std::endl;
std::clog << "Please commit your changes or 'git stash' them before running 'git-crypt' lock." << std::endl;
std::clog << "Please commit your changes or 'git stash' them before running 'git-crypt lock'." << std::endl;
return 1;
}
@@ -944,6 +948,7 @@ int lock (int argc, const char** argv)
std::string path_to_top(get_path_to_top());
// 3. unconfigure the git filters and remove decrypted keys
std::vector<std::string> encrypted_files;
if (all_keys) {
// unconfigure for all keys
std::vector<std::string> dirents = get_directory_contents(get_internal_keys_path().c_str());
@@ -952,6 +957,7 @@ int lock (int argc, const char** argv)
const char* this_key_name = (*dirent == "default" ? 0 : dirent->c_str());
remove_file(get_internal_key_path(this_key_name));
unconfigure_git_filters(this_key_name);
get_encrypted_files(encrypted_files, this_key_name);
}
} else {
// just handle the given key
@@ -967,18 +973,18 @@ int lock (int argc, const char** argv)
remove_file(internal_key_path);
unconfigure_git_filters(key_name);
get_encrypted_files(encrypted_files, key_name);
}
// 4. Do a force checkout so any files that were previously checked out decrypted
// will now be checked out encrypted.
// If HEAD doesn't exist (perhaps because this repo doesn't have any files yet)
// just skip the checkout.
if (head_exists) {
if (!git_checkout_head(path_to_top)) {
std::clog << "Error: 'git checkout' failed" << std::endl;
std::clog << "git-crypt has been locked but up but existing decrypted files have not been encrypted" << std::endl;
return 1;
}
// 4. Check out the files that are currently decrypted but should be encrypted.
// Git won't check out a file if its mtime hasn't changed, so touch every file first.
for (std::vector<std::string>::const_iterator file(encrypted_files.begin()); file != encrypted_files.end(); ++file) {
touch_file(*file);
}
if (!git_checkout(encrypted_files)) {
std::clog << "Error: 'git checkout' failed" << std::endl;
std::clog << "git-crypt has been locked but up but existing decrypted files have not been encrypted" << std::endl;
return 1;
}
return 0;

12
debian/changelog vendored Normal file
View File

@@ -0,0 +1,12 @@
git-crypt (0.4.2-1~agwa1) unstable; urgency=low
* New upstream release.
* Various packaging improvements.
-- Andrew Ayer <agwa@andrewayer.name> Sat, 31 Jan 2015 19:43:06 -0800
git-crypt (0.3-1) unstable; urgency=low
* Initial release.
-- Andrew Ayer <agwa@andrewayer.name> Sat, 29 Mar 2014 12:38:14 -0700

1
debian/compat vendored Normal file
View File

@@ -0,0 +1 @@
9

24
debian/control vendored Normal file
View File

@@ -0,0 +1,24 @@
Source: git-crypt
Maintainer: Andrew Ayer <agwa@andrewayer.name>
Section: vcs
Priority: optional
Standards-Version: 3.9.4
Build-Depends: debhelper (>= 9), libssl-dev
Vcs-Git: https://www.agwa.name/git/git-crypt.git -b debian
Homepage: https://www.agwa.name/projects/git-crypt
Package: git-crypt
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, git (>= 1.7.2)
Recommends: gnupg
Enhances: git
Description: Transparent file encryption in git
git-crypt enables transparent encryption and decryption of files in a
git repository. Files which you choose to protect are encrypted when
committed, and decrypted when checked out. git-crypt lets you freely
share a repository containing a mix of public and private content.
git-crypt gracefully degrades, so developers without the secret key
can still clone and commit to a repository with encrypted files.
This lets you store your secret material (such as keys or passwords)
in the same repository as your code, without requiring you to lock down
your entire repository.

34
debian/copyright vendored Normal file
View File

@@ -0,0 +1,34 @@
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: git-crypt
Source: https://www.agwa.name/projects/git-crypt
Files: *
Copyright: Copyright 2014 Andrew Ayer <agwa@andrewayer.name>
License: GPL-3+ with OpenSSL exception
git-crypt 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.
.
git-crypt 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 git-crypt. If not, see <http://www.gnu.org/licenses/>.
.
On Debian systems, the full text of the GNU General Public
License version 3 can be found in the file
`/usr/share/common-licenses/GPL-3'.
.
Additional permission under GNU GPL version 3 section 7:
.
If you modify the Program, or any covered work, by linking or
combining it with the OpenSSL project's OpenSSL library (or a
modified version of that library), containing parts covered by the
terms of the OpenSSL or SSLeay licenses, the licensors of the Program
grant you additional permission to convey the resulting work.
Corresponding Source for a non-source form of such a combination
shall include the source code for the parts of OpenSSL used as well
as that of the covered work.

5
debian/gbp.conf vendored Normal file
View File

@@ -0,0 +1,5 @@
[DEFAULT]
pristine-tar = True
pristine-tar-commit = True
debian-branch = debian
upstream-tag = %(version)s

8
debian/git-crypt.docs vendored Normal file
View File

@@ -0,0 +1,8 @@
CONTRIBUTING.md
NEWS
NEWS.md
README
README.md
RELEASE_NOTES-0.4.1.md
RELEASE_NOTES-0.4.md
THANKS.md

1
debian/git-crypt.install vendored Normal file
View File

@@ -0,0 +1 @@
git-crypt usr/bin

6
debian/rules vendored Executable file
View File

@@ -0,0 +1,6 @@
#!/usr/bin/make -f
%:
dh $@
override_dh_auto_install:

1
debian/source/format vendored Normal file
View File

@@ -0,0 +1 @@
3.0 (quilt)

1
debian/source/options vendored Normal file
View File

@@ -0,0 +1 @@
single-debian-patch

17
debian/source/patch-header vendored Normal file
View File

@@ -0,0 +1,17 @@
Subject: Collected Debian patches for git-crypt
Author: Andrew Ayer <agwa@andrewayer.name>
Since I am also upstream for this package, there will normally not be
any patches to apply to the upstream source. However, occasionally
I'll pull up specific upstream commits prior to making an upstream
release. When this happens, this patch will collect all of those
modifications.
I use Git to maintain both the upstream source and the Debian
packages, and generating individual patches rather than using git
cherry-pick takes extra work for no gain. Since I'm also upstream,
there's no need to separate the patches for later upstream submission.
Hence, I take this approach with a unified patch when it's necessary.
For full commit history and separated commits, see the upstream Git
repository.

View File

@@ -31,7 +31,7 @@
#ifndef GIT_CRYPT_GIT_CRYPT_HPP
#define GIT_CRYPT_GIT_CRYPT_HPP
#define VERSION "0.4.1"
#define VERSION "0.4.2"
extern const char* argv0; // initialized in main() to argv[0]