mirror of
https://github.com/AGWA/git-crypt.git
synced 2026-01-02 00:00:12 -08:00
Compare commits
11 Commits
0.4.1
...
debian/0.4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f3890bed32 | ||
|
|
78fb6ab052 | ||
|
|
1fc9664036 | ||
|
|
1ca8f89602 | ||
|
|
2fa2cffba6 | ||
|
|
5fd36a7ac5 | ||
|
|
d5670c9552 | ||
|
|
2d2053296f | ||
|
|
216aa27009 | ||
|
|
02c52ab21a | ||
|
|
6b78ef0548 |
4
INSTALL
4
INSTALL
@@ -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.
|
||||
|
||||
@@ -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
5
NEWS
@@ -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
|
||||
|
||||
5
NEWS.md
5
NEWS.md
@@ -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
2
README
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
156
commands.cpp
156
commands.cpp
@@ -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
12
debian/changelog
vendored
Normal 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
1
debian/compat
vendored
Normal file
@@ -0,0 +1 @@
|
||||
9
|
||||
24
debian/control
vendored
Normal file
24
debian/control
vendored
Normal 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
34
debian/copyright
vendored
Normal 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
5
debian/gbp.conf
vendored
Normal 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
8
debian/git-crypt.docs
vendored
Normal 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
1
debian/git-crypt.install
vendored
Normal file
@@ -0,0 +1 @@
|
||||
git-crypt usr/bin
|
||||
6
debian/rules
vendored
Executable file
6
debian/rules
vendored
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/make -f
|
||||
|
||||
%:
|
||||
dh $@
|
||||
|
||||
override_dh_auto_install:
|
||||
1
debian/source/format
vendored
Normal file
1
debian/source/format
vendored
Normal file
@@ -0,0 +1 @@
|
||||
3.0 (quilt)
|
||||
1
debian/source/options
vendored
Normal file
1
debian/source/options
vendored
Normal file
@@ -0,0 +1 @@
|
||||
single-debian-patch
|
||||
17
debian/source/patch-header
vendored
Normal file
17
debian/source/patch-header
vendored
Normal 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.
|
||||
@@ -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]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user