From 0a50e7b02fb43d0b94262aa9c28469169542c187 Mon Sep 17 00:00:00 2001 From: Woody Gilk Date: Thu, 17 Mar 2011 00:35:16 -0500 Subject: [PATCH 01/35] Initial commit of gitcrypt --- README.md | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ gitcrypt | 56 +++++++++++++++++++++++ 2 files changed, 187 insertions(+) create mode 100644 README.md create mode 100755 gitcrypt diff --git a/README.md b/README.md new file mode 100644 index 0000000..26bc6e1 --- /dev/null +++ b/README.md @@ -0,0 +1,131 @@ +# Transparent Git Encryption + +The gitcrypt tool is inspired by [this document][1] written by [Ning Shang][2], +which was in turn inspired by [this post][1]. Without these two documents, +by people much smarter than me, gitcrypt would not exist. + +## Installation + +Clone git-encrypt somewhere on your local machine: + + $ git clone https://github.com/shadowhand/git-encrypt + $ cd git-encrypt + +The `gitcrypt` command must be executable: + + $ chmod 0755 gitcrypt + +And it must be accessible in your `$PATH`: + + $ sudo ln -s gitcrypt /usr/bin/gitcrypt + +## Configuration + +First, you will need to add a secret salt and secure passphrase to your git +configuration. The secret salt must be 16 **hexidecimal** chacaters and the +secure passphrase can be any characters of any length: + + $ git config gitcrypt.salt 0000000000000000 + $ git config gitcrypt.pass my-secret-phrase + +*It is possible to set these options globally using `git config --global`, but +more secure to create a separate salt and passphrase for every repository.* + +A quick way to generate a new salt is: + + $ head -c 10 < /dev/random | md5 | cut -c-16 + +## Usage + +For every repository that you want to use gitcrypt in, you will need a +[.gitattributes][4] file to define what files will be encrypted. Any file +[pattern format][5] can be used here. + +To encrypt all the files in the repo: + + * filter=encrypt diff=encrypt + [merge] + renormalize = true + +To encrypt only one file, you could do this: + + secret.txt filter=encrypt diff=encrypt + +Or to encrypt all ".secure" files: + + *.secure filter=encrypt diff=encrypt + +*Note: It is not recommended to add your `.gitattributes` file to the +repository itself. Instead, add `.gitattributes` to your `.gitignore` file +or use `.git/info/attributes` instead.* + +Next, you need to map the `encrypt` filter to `gitcrypt` using `git config`: + + $ git config filter.encrypt.smudge "gitcrypt smudge" + $ git config filter.encrypt.clean "gitcrypt clean" + $ git config diff.encrypt.textconv "gitcrypt diff" + +Or if you prefer to manually edit `.git/config`: + + [filter "encrypt"] + smudge = gitcrypt smudge + clean = gitcrypt clean + [diff "encrypt"] + textconv = gitcrypt diff + +Your repository is now set up! Any time you `git add` a file that matches the +filter pattern the `clean` filter is applied, automatically encrypting the file +before it is staged. Using `git diff` will work normally, as it automatically +decrypts file content as necessary. + +### Decryption and Clones + +To set up decryption from a clone, you will need to repeat most of these steps +on the other side. + +First, clone the repository, but **do not perform a checkout**: + + $ git clone -n git://github.com/johndoe/encrypted.get + $ cd encrypted + +If you do a `git status` now, it will show all your files as being deleted. +Do not fear, this is actually what we want right now, because we need to setup +gitcrypt before doing a checkout. Now we just repeat the configuration as it +was done for the original repo. + +Second, set your encryption salt and passphrase: + + $ git config gitcrypt.salt 0123456789abcdef + $ git config gitcrypt.pass "gosh, i am so insecure!" + +Third, edit `.gitattributes` or `.git/info/attributes`: + + * filter=encrypt diff=encrypt + [merge] + renormalize = true + +Fourth, map the `encrypt` filter: + + $ git config filter.encrypt.smudge "gitcrypt smudge" + $ git config filter.encrypt.clean "gitcrypt clean" + $ git config diff.encrypt.textconv "gitcrypt diff" + +Configuration is complete, now reset and checkout all the files: + + $ git reset HEAD + $ git ls-files --deleted | xargs git checkout -- + +All the files in the are now decrypted and ready to be edited. + +# Conclusion + +Enjoy your secure git repository! If you think gitcrypt is totally awesome, +you could [buy me a beer][wishes]. + +[1]: http://syncom.appspot.com/papers/git_encryption.txt "GIT transparent encryption" +[2]: http://syncom.appspot.com/ +[3]: http://git.661346.n2.nabble.com/Transparently-encrypt-repository-contents-with-GPG-td2470145.html "Web discussion: Transparently encrypt repository contents with GPG" +[4]: http://www.kernel.org/pub/software/scm/git/docs/gitattributes.html +[5]: http://www.kernel.org/pub/software/scm/git/docs/gitignore.html#_pattern_format + +[wishes]: http://www.amazon.com/gp/registry/wishlist/1474H3P2204L8 "Woody Gilk's Wish List on Amazon.com" diff --git a/gitcrypt b/gitcrypt new file mode 100755 index 0000000..c757bdf --- /dev/null +++ b/gitcrypt @@ -0,0 +1,56 @@ +#!/bin/bash + +VERSION=0.1.0 + +_clean() { + # Salt must be 16 characters or less to not fail + SALT=$(echo "$SALT" | cut -c-16) + + # Encrypt using OpenSSL + openssl enc -base64 -aes-256-ecb -S "$SALT" -k "$PASS" +} + +_smudge() { + if [ -z "$SALT" ] || [ -z "$PASS" ]; then + echo "Gitcrypt: secret salt and/or pass phrase have not been set" + exit 1 + fi + + # If decryption fails, use `cat` instead + openssl enc -d -base64 -aes-256-ecb -k "$PASS" 2> /dev/null || cat +} + +_diff() { + # If decryption fails, use `cat` instead + openssl enc -d -base64 -aes-256-ecb -k "$PASS" -in "$1" 2> /dev/null || cat "$1" +} + +case "$1" in + clean|smudge|diff) + # Need secret salt and secure passphrase + SALT=$(git config gitcrypt.salt) + if [ -z "$SALT" ]; then + echo "Gitcrypt: secret salt (gitcrypt.salt) has not been configured" + exit 1 + fi + + PASS=$(git config gitcrypt.pass) + if [ -z "$PASS" ]; then + echo "Gitcrypt: secure passphrase (gitcrypt.pass) has not been configured" + exit 1 + fi + + # Execute command + _$1 "$2" + ;; + version) + # Show version + echo "gitcrypt version $VERSION" + ;; + *) + # Not a valid option + echo "Gitcrypt: command does not exist: $1" + exit 1 + ;; +esac +exit 0 From 5f34886078cf8c4f4deb9a751185df9083e431a0 Mon Sep 17 00:00:00 2001 From: Woody Gilk Date: Thu, 17 Mar 2011 00:56:22 -0500 Subject: [PATCH 02/35] Added LICENSE file --- LICENSE.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 LICENSE.md diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..622d92d --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,19 @@ +Copyright (c) 2011 Woody Gilk + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. From 4c2dc16a3f332bc90918ff613034dd011c124401 Mon Sep 17 00:00:00 2001 From: Woody Gilk Date: Thu, 17 Mar 2011 09:21:01 -0500 Subject: [PATCH 03/35] Added gitcrypt.cipher configuration setting, allows using a custom cipher mode for encryption --- gitcrypt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/gitcrypt b/gitcrypt index c757bdf..f9a50e8 100755 --- a/gitcrypt +++ b/gitcrypt @@ -7,7 +7,7 @@ _clean() { SALT=$(echo "$SALT" | cut -c-16) # Encrypt using OpenSSL - openssl enc -base64 -aes-256-ecb -S "$SALT" -k "$PASS" + openssl enc -base64 -$CIPHER -S "$SALT" -k "$PASS" } _smudge() { @@ -17,12 +17,12 @@ _smudge() { fi # If decryption fails, use `cat` instead - openssl enc -d -base64 -aes-256-ecb -k "$PASS" 2> /dev/null || cat + openssl enc -d -base64 -$CIPHER -k "$PASS" 2> /dev/null || cat } _diff() { # If decryption fails, use `cat` instead - openssl enc -d -base64 -aes-256-ecb -k "$PASS" -in "$1" 2> /dev/null || cat "$1" + openssl enc -d -base64 -$CIPHER -k "$PASS" -in "$1" 2> /dev/null || cat "$1" } case "$1" in @@ -40,6 +40,10 @@ case "$1" in exit 1 fi + # Cipher + CIPHER=$(git config gitcrypt.cipher) + [ -z "$CIPHER" ] && CIPHER="aes-256-ecb" + # Execute command _$1 "$2" ;; From 80cb476608ee672ea02ac3fcd2caf07bb888be96 Mon Sep 17 00:00:00 2001 From: Woody Gilk Date: Thu, 17 Mar 2011 09:25:32 -0500 Subject: [PATCH 04/35] Remove $SALT truncation from _clean(), it will not apply to every cipher --- gitcrypt | 3 --- 1 file changed, 3 deletions(-) diff --git a/gitcrypt b/gitcrypt index f9a50e8..6955c84 100755 --- a/gitcrypt +++ b/gitcrypt @@ -3,9 +3,6 @@ VERSION=0.1.0 _clean() { - # Salt must be 16 characters or less to not fail - SALT=$(echo "$SALT" | cut -c-16) - # Encrypt using OpenSSL openssl enc -base64 -$CIPHER -S "$SALT" -k "$PASS" } From 43e8864c7087a78861093b1330312d8f7623f76c Mon Sep 17 00:00:00 2001 From: Woody Gilk Date: Thu, 17 Mar 2011 10:29:39 -0500 Subject: [PATCH 05/35] Breaking change! The default cipher has been changed from "aes-256-ecb" to "aes-256-cbc". Any existing repo using gitcrypt will run "git config gitcrypt.cipher aes-256-ecb" before continuing to use gitcrypt. An upgrade command will be added soon. Fixes #2 --- gitcrypt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitcrypt b/gitcrypt index 6955c84..f6e1953 100755 --- a/gitcrypt +++ b/gitcrypt @@ -39,7 +39,7 @@ case "$1" in # Cipher CIPHER=$(git config gitcrypt.cipher) - [ -z "$CIPHER" ] && CIPHER="aes-256-ecb" + [ -z "$CIPHER" ] && CIPHER="aes-256-ccb" # Execute command _$1 "$2" From ba92e9024fe440a9d3cc36fae7965af649907f59 Mon Sep 17 00:00:00 2001 From: Woody Gilk Date: Thu, 17 Mar 2011 10:36:44 -0500 Subject: [PATCH 06/35] Typo in 43e8864c7087a78861093b1330312d8f7623f76c --- gitcrypt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitcrypt b/gitcrypt index f6e1953..53fd6c5 100755 --- a/gitcrypt +++ b/gitcrypt @@ -39,7 +39,7 @@ case "$1" in # Cipher CIPHER=$(git config gitcrypt.cipher) - [ -z "$CIPHER" ] && CIPHER="aes-256-ccb" + [ -z "$CIPHER" ] && CIPHER="aes-256-cbc" # Execute command _$1 "$2" From be0b54bfaca9c774bca2dc65c2a394c20f4cdee8 Mon Sep 17 00:00:00 2001 From: Woody Gilk Date: Thu, 17 Mar 2011 10:38:26 -0500 Subject: [PATCH 07/35] Fixing incorrect link reference --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 26bc6e1..dbf449a 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Transparent Git Encryption The gitcrypt tool is inspired by [this document][1] written by [Ning Shang][2], -which was in turn inspired by [this post][1]. Without these two documents, +which was in turn inspired by [this post][3]. Without these two documents, by people much smarter than me, gitcrypt would not exist. ## Installation From 0b361439da25e8953c0e2cbe88c3dfcc54c791de Mon Sep 17 00:00:00 2001 From: Woody Gilk Date: Thu, 17 Mar 2011 10:39:06 -0500 Subject: [PATCH 08/35] Updated gitcrypt to version 0.2.0, added "gitcrypt init" command for interactive setup, updated README Fixes #1 --- README.md | 50 +++++++++++++++------------- gitcrypt | 97 ++++++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 109 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index dbf449a..e26bea5 100644 --- a/README.md +++ b/README.md @@ -21,25 +21,36 @@ And it must be accessible in your `$PATH`: ## Configuration -First, you will need to add a secret salt and secure passphrase to your git -configuration. The secret salt must be 16 **hexidecimal** chacaters and the -secure passphrase can be any characters of any length: +To quickly setup gitcrypt interactively, run `gitcrypt init` from the root +of your git repository. It will ask you for a passphrase, cipher mode, and +what files should be encrypted. + + $ cd my-repo + $ gitcrypt init + +Your repository is now set up! Any time you `git add` a file that matches the +filter pattern the `clean` filter is applied, automatically encrypting the file +before it is staged. Using `git diff` will work normally, as it automatically +decrypts file content as necessary. + +### Manual Configuration + +First, you will need to add a secure passphrase to your git configuration: - $ git config gitcrypt.salt 0000000000000000 $ git config gitcrypt.pass my-secret-phrase -*It is possible to set these options globally using `git config --global`, but -more secure to create a separate salt and passphrase for every repository.* +*It is possible to set this options globally using `git config --global`, but +more secure to create a separate passphrase for every repository.* -A quick way to generate a new salt is: +The default [encryption cipher][4] is `aes-256-cbc`, which should be suitable +for almost everyone. However, it is also possible to use a different cipher: - $ head -c 10 < /dev/random | md5 | cut -c-16 + $ git config gitcrypt.cipher aes-256-cbc -## Usage +**Do not use an `ecb` cipher unless you are 100% sure what you are doing!** -For every repository that you want to use gitcrypt in, you will need a -[.gitattributes][4] file to define what files will be encrypted. Any file -[pattern format][5] can be used here. +Next, you need to define what files will be automatically encrypted using the +[.gitattributes][5] file. Any file [pattern format][6] can be used here. To encrypt all the files in the repo: @@ -73,12 +84,7 @@ Or if you prefer to manually edit `.git/config`: [diff "encrypt"] textconv = gitcrypt diff -Your repository is now set up! Any time you `git add` a file that matches the -filter pattern the `clean` filter is applied, automatically encrypting the file -before it is staged. Using `git diff` will work normally, as it automatically -decrypts file content as necessary. - -### Decryption and Clones +## Decrypting Clones To set up decryption from a clone, you will need to repeat most of these steps on the other side. @@ -93,9 +99,8 @@ Do not fear, this is actually what we want right now, because we need to setup gitcrypt before doing a checkout. Now we just repeat the configuration as it was done for the original repo. -Second, set your encryption salt and passphrase: +Second, set your encryption passphrase: - $ git config gitcrypt.salt 0123456789abcdef $ git config gitcrypt.pass "gosh, i am so insecure!" Third, edit `.gitattributes` or `.git/info/attributes`: @@ -125,7 +130,8 @@ you could [buy me a beer][wishes]. [1]: http://syncom.appspot.com/papers/git_encryption.txt "GIT transparent encryption" [2]: http://syncom.appspot.com/ [3]: http://git.661346.n2.nabble.com/Transparently-encrypt-repository-contents-with-GPG-td2470145.html "Web discussion: Transparently encrypt repository contents with GPG" -[4]: http://www.kernel.org/pub/software/scm/git/docs/gitattributes.html -[5]: http://www.kernel.org/pub/software/scm/git/docs/gitignore.html#_pattern_format +[4]: http://en.wikipedia.org/wiki/Cipher +[5]: http://www.kernel.org/pub/software/scm/git/docs/gitattributes.html +[6]: http://www.kernel.org/pub/software/scm/git/docs/gitignore.html#_pattern_format [wishes]: http://www.amazon.com/gp/registry/wishlist/1474H3P2204L8 "Woody Gilk's Wish List on Amazon.com" diff --git a/gitcrypt b/gitcrypt index 53fd6c5..75f8f15 100755 --- a/gitcrypt +++ b/gitcrypt @@ -1,18 +1,85 @@ #!/bin/bash -VERSION=0.1.0 +readonly VERSION="0.2.0" +readonly DEFAULT_CIPHER="aes-256-cbc" + +init_config() { + local answer + while [ 1 ]; do + while [ -z "$PASS" ]; do + echo -n "Enter your passphrase: " + read PASS + done + + while [ 1 ]; do + echo -n "What encryption cipher do you want to use? [$DEFAULT_CIPHER] " + read CIPHER + [ -z "$CIPHER" ] && CIPHER="$DEFAULT_CIPHER" + + local exists + exists=$(openssl list-cipher-commands | grep "$CIPHER") + [ $? -eq 0 ] && break + + echo "Cipher '$CIPHER' is not available" + done + + echo -e "\nThis configuration will be stored:\n" + echo "pass: $PASS" + echo "cipher: $CIPHER" + echo -e -n "\nDoes this look right? [Y/n] " + read answer + + case "$answer" in + n*|N*) + # Reconfigure + unset -v PASS + unset -v CIPHER + ;; + *) + # Finished + break + ;; + esac + done + + echo -n "Do you want to use .git/info/attributes? [Y/n] " + read answer + + local attrs + case "$answer" in + n*|N*) + attrs=".gitattributes" + ;; + *) + attrs=".git/info/attributes" + ;; + esac + + local pattern + echo -n "What files do you want encrypted? [*] " + read pattern + [ -z "$pattern" ] && pattern="*" + + echo "$pattern filter=encrypt diff=encrypt" >> $attrs + echo "[merge]" >> $attrs + echo " renormalize = true" >> $attrs + + # Encryption + git config gitcrypt.pass "$PASS" + git config gitcrypt.cipher "$CIPHER" + + # Filters + git config filter.encrypt.smudge "gitcrypt smudge" + git config filter.encrypt.clean "gitcrypt clean" + git config diff.encrypt.textconv "gitcrypt diff" +} _clean() { # Encrypt using OpenSSL - openssl enc -base64 -$CIPHER -S "$SALT" -k "$PASS" + openssl enc -base64 -$CIPHER -salt -k "$PASS" } _smudge() { - if [ -z "$SALT" ] || [ -z "$PASS" ]; then - echo "Gitcrypt: secret salt and/or pass phrase have not been set" - exit 1 - fi - # If decryption fails, use `cat` instead openssl enc -d -base64 -$CIPHER -k "$PASS" 2> /dev/null || cat } @@ -24,26 +91,24 @@ _diff() { case "$1" in clean|smudge|diff) - # Need secret salt and secure passphrase - SALT=$(git config gitcrypt.salt) - if [ -z "$SALT" ]; then - echo "Gitcrypt: secret salt (gitcrypt.salt) has not been configured" - exit 1 - fi - + # Need a secure passphrase PASS=$(git config gitcrypt.pass) if [ -z "$PASS" ]; then echo "Gitcrypt: secure passphrase (gitcrypt.pass) has not been configured" exit 1 fi - # Cipher + # And a cipher mode CIPHER=$(git config gitcrypt.cipher) - [ -z "$CIPHER" ] && CIPHER="aes-256-cbc" + [ -z "$CIPHER" ] && CIPHER="$DEFAULT_CIPHER" # Execute command _$1 "$2" ;; + init) + # Run setup commands + init_config + ;; version) # Show version echo "gitcrypt version $VERSION" From 3e6a91282f7a1a398751b33b197e5f193620b15d Mon Sep 17 00:00:00 2001 From: Woody Gilk Date: Thu, 17 Mar 2011 11:24:17 -0500 Subject: [PATCH 09/35] Updated gitcrypt init to ask for salt, reverting random salt (impossible to sync two clones with random salt), fixes #2 --- README.md | 11 +++++++---- gitcrypt | 34 ++++++++++++++++++++++++++++++++-- 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index e26bea5..7c7a397 100644 --- a/README.md +++ b/README.md @@ -22,8 +22,8 @@ And it must be accessible in your `$PATH`: ## Configuration To quickly setup gitcrypt interactively, run `gitcrypt init` from the root -of your git repository. It will ask you for a passphrase, cipher mode, and -what files should be encrypted. +of your git repository. It will ask you for a passphrase, shared salt, +cipher mode, and what files should be encrypted. $ cd my-repo $ gitcrypt init @@ -35,8 +35,10 @@ decrypts file content as necessary. ### Manual Configuration -First, you will need to add a secure passphrase to your git configuration: +First, you will need to add a shared salt (16 hex characters) and a secure +passphrase to your git configuration: + $ git config gitcrypt.salt 0000000000000000 $ git config gitcrypt.pass my-secret-phrase *It is possible to set this options globally using `git config --global`, but @@ -99,8 +101,9 @@ Do not fear, this is actually what we want right now, because we need to setup gitcrypt before doing a checkout. Now we just repeat the configuration as it was done for the original repo. -Second, set your encryption passphrase: +Second, set your shared salt and encryption passphrase: + $ git config gitcrypt.salt abcdef0123456789 $ git config gitcrypt.pass "gosh, i am so insecure!" Third, edit `.gitattributes` or `.git/info/attributes`: diff --git a/gitcrypt b/gitcrypt index 75f8f15..f138a90 100755 --- a/gitcrypt +++ b/gitcrypt @@ -6,6 +6,26 @@ readonly DEFAULT_CIPHER="aes-256-cbc" init_config() { local answer while [ 1 ]; do + while [ -z "$SALT" ]; do + echo -n "Generate a random salt? [Y/n] " + read answer + + case "$answer" in + n*|N*) + echo -n "Shared salt as hex characters: " + read SALT + + if [ $(echo "$SALT" | grep '[^a-f0-9]' | wc -l) -ne 0 ]; then + echo "Error: non-hex characters in salt" + unset -v SALT + fi + ;; + *) + SALT=$(head -c 10 < /dev/random | md5 | cut -c-16) + ;; + esac + done + while [ -z "$PASS" ]; do echo -n "Enter your passphrase: " read PASS @@ -20,10 +40,11 @@ init_config() { exists=$(openssl list-cipher-commands | grep "$CIPHER") [ $? -eq 0 ] && break - echo "Cipher '$CIPHER' is not available" + echo "Error: Cipher '$CIPHER' is not available" done echo -e "\nThis configuration will be stored:\n" + echo "salt: $SALT" echo "pass: $PASS" echo "cipher: $CIPHER" echo -e -n "\nDoes this look right? [Y/n] " @@ -32,6 +53,7 @@ init_config() { case "$answer" in n*|N*) # Reconfigure + unset -v SALT unset -v PASS unset -v CIPHER ;; @@ -65,6 +87,7 @@ init_config() { echo " renormalize = true" >> $attrs # Encryption + git config gitcrypt.salt "$SALT" git config gitcrypt.pass "$PASS" git config gitcrypt.cipher "$CIPHER" @@ -76,7 +99,7 @@ init_config() { _clean() { # Encrypt using OpenSSL - openssl enc -base64 -$CIPHER -salt -k "$PASS" + openssl enc -base64 -$CIPHER -S "$SALT" -k "$PASS" } _smudge() { @@ -91,6 +114,13 @@ _diff() { case "$1" in clean|smudge|diff) + # Need a shared salt + SALT=$(git config gitcrypt.salt) + if [ -z "$SALT" ]; then + echo "Gitcrypt: shared salt (gitcrypt.salt) has not been configured" + exit 1 + fi + # Need a secure passphrase PASS=$(git config gitcrypt.pass) if [ -z "$PASS" ]; then From 49f52f4265425258e5fd10acb554679056112345 Mon Sep 17 00:00:00 2001 From: Woody Gilk Date: Thu, 17 Mar 2011 12:53:13 -0500 Subject: [PATCH 10/35] Reverted EBC to CBC mode change, see final comments on #2 for details. Updated README. --- README.md | 51 +++++++++++++++++++-------------------------------- gitcrypt | 2 +- 2 files changed, 20 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index 7c7a397..dce6b28 100644 --- a/README.md +++ b/README.md @@ -41,18 +41,21 @@ passphrase to your git configuration: $ git config gitcrypt.salt 0000000000000000 $ git config gitcrypt.pass my-secret-phrase -*It is possible to set this options globally using `git config --global`, but -more secure to create a separate passphrase for every repository.* +> It is possible to set these options globally using `git config --global`, +but more secure to create a separate passphrase for every repository. -The default [encryption cipher][4] is `aes-256-cbc`, which should be suitable +The default [encryption cipher][4] is `aes-256-ebc`, which should be suitable for almost everyone. However, it is also possible to use a different cipher: - $ git config gitcrypt.cipher aes-256-cbc + $ git config gitcrypt.cipher aes-256-ebc -**Do not use an `ecb` cipher unless you are 100% sure what you are doing!** +> An "ECB" mode is used because it encrypts in a format that provides usable +text diff, meaning that a single change will not cause the entire file to be +internally marked as changed. Because a static salt must be used, using "CBC" +would provide very little, if any, increased security over "ECB" mode. Next, you need to define what files will be automatically encrypted using the -[.gitattributes][5] file. Any file [pattern format][6] can be used here. +[.git/info/attributes][5] file. Any file [pattern format][6] can be used here. To encrypt all the files in the repo: @@ -68,11 +71,10 @@ Or to encrypt all ".secure" files: *.secure filter=encrypt diff=encrypt -*Note: It is not recommended to add your `.gitattributes` file to the -repository itself. Instead, add `.gitattributes` to your `.gitignore` file -or use `.git/info/attributes` instead.* +> If you want this mapping to be included in your repository, use a +`.gitattributes` file instead and **do not** encrypt it. -Next, you need to map the `encrypt` filter to `gitcrypt` using `git config`: +Next, you need to map the `encrypt` filter to `gitcrypt`: $ git config filter.encrypt.smudge "gitcrypt smudge" $ git config filter.encrypt.clean "gitcrypt clean" @@ -88,37 +90,22 @@ Or if you prefer to manually edit `.git/config`: ## Decrypting Clones -To set up decryption from a clone, you will need to repeat most of these steps -on the other side. +To set up decryption from a clone, you will need to repeat the same setup on +the new clone. First, clone the repository, but **do not perform a checkout**: $ git clone -n git://github.com/johndoe/encrypted.get $ cd encrypted -If you do a `git status` now, it will show all your files as being deleted. +> If you do a `git status` now, it will show all your files as being deleted. Do not fear, this is actually what we want right now, because we need to setup -gitcrypt before doing a checkout. Now we just repeat the configuration as it -was done for the original repo. +gitcrypt before doing a checkout. -Second, set your shared salt and encryption passphrase: +Now you can either run `gitcrypt init` or do the same manual configuration that +performed on the original repository. - $ git config gitcrypt.salt abcdef0123456789 - $ git config gitcrypt.pass "gosh, i am so insecure!" - -Third, edit `.gitattributes` or `.git/info/attributes`: - - * filter=encrypt diff=encrypt - [merge] - renormalize = true - -Fourth, map the `encrypt` filter: - - $ git config filter.encrypt.smudge "gitcrypt smudge" - $ git config filter.encrypt.clean "gitcrypt clean" - $ git config diff.encrypt.textconv "gitcrypt diff" - -Configuration is complete, now reset and checkout all the files: +Once configuration is complete, reset and checkout all the files: $ git reset HEAD $ git ls-files --deleted | xargs git checkout -- diff --git a/gitcrypt b/gitcrypt index f138a90..94294be 100755 --- a/gitcrypt +++ b/gitcrypt @@ -1,7 +1,7 @@ #!/bin/bash readonly VERSION="0.2.0" -readonly DEFAULT_CIPHER="aes-256-cbc" +readonly DEFAULT_CIPHER="aes-256-ebc" init_config() { local answer From f4bf37213e54740bff437d01b7a3ae9e730cea37 Mon Sep 17 00:00:00 2001 From: Woody Gilk Date: Thu, 17 Mar 2011 12:54:08 -0500 Subject: [PATCH 11/35] Updated version to 0.2.1 --- gitcrypt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitcrypt b/gitcrypt index 94294be..007e82d 100755 --- a/gitcrypt +++ b/gitcrypt @@ -1,6 +1,6 @@ #!/bin/bash -readonly VERSION="0.2.0" +readonly VERSION="0.2.1" readonly DEFAULT_CIPHER="aes-256-ebc" init_config() { From ffdd3ba692b9906ccc4c6f404501a46fb5d9aa43 Mon Sep 17 00:00:00 2001 From: Woody Gilk Date: Thu, 17 Mar 2011 13:14:43 -0500 Subject: [PATCH 12/35] Updated README, added note about controversy of using this technique --- README.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index dce6b28..b763203 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,9 @@ The gitcrypt tool is inspired by [this document][1] written by [Ning Shang][2], which was in turn inspired by [this post][3]. Without these two documents, by people much smarter than me, gitcrypt would not exist. +> There is [some controversy][4] over using this technique, so do your research +and understand the implications of using this tool before you go crazy with it. + ## Installation Clone git-encrypt somewhere on your local machine: @@ -44,7 +47,7 @@ passphrase to your git configuration: > It is possible to set these options globally using `git config --global`, but more secure to create a separate passphrase for every repository. -The default [encryption cipher][4] is `aes-256-ebc`, which should be suitable +The default [encryption cipher][5] is `aes-256-ebc`, which should be suitable for almost everyone. However, it is also possible to use a different cipher: $ git config gitcrypt.cipher aes-256-ebc @@ -55,7 +58,7 @@ internally marked as changed. Because a static salt must be used, using "CBC" would provide very little, if any, increased security over "ECB" mode. Next, you need to define what files will be automatically encrypted using the -[.git/info/attributes][5] file. Any file [pattern format][6] can be used here. +[.git/info/attributes][6] file. Any file [pattern format][7] can be used here. To encrypt all the files in the repo: @@ -120,8 +123,9 @@ you could [buy me a beer][wishes]. [1]: http://syncom.appspot.com/papers/git_encryption.txt "GIT transparent encryption" [2]: http://syncom.appspot.com/ [3]: http://git.661346.n2.nabble.com/Transparently-encrypt-repository-contents-with-GPG-td2470145.html "Web discussion: Transparently encrypt repository contents with GPG" -[4]: http://en.wikipedia.org/wiki/Cipher -[5]: http://www.kernel.org/pub/software/scm/git/docs/gitattributes.html -[6]: http://www.kernel.org/pub/software/scm/git/docs/gitignore.html#_pattern_format +[4]: http://article.gmane.org/gmane.comp.version-control.git/113221 "Junio Hamano does not recommend this technique" +[5]: http://en.wikipedia.org/wiki/Cipher +[6]: http://www.kernel.org/pub/software/scm/git/docs/gitattributes.html +[7]: http://www.kernel.org/pub/software/scm/git/docs/gitignore.html#_pattern_format [wishes]: http://www.amazon.com/gp/registry/wishlist/1474H3P2204L8 "Woody Gilk's Wish List on Amazon.com" From 6fcc337c9c6824454ec4d82ff8db7fc9acb49403 Mon Sep 17 00:00:00 2001 From: Woody Gilk Date: Thu, 17 Mar 2011 13:42:43 -0500 Subject: [PATCH 13/35] Added Pledgie to README --- README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b763203..5a0dc20 100644 --- a/README.md +++ b/README.md @@ -118,7 +118,9 @@ All the files in the are now decrypted and ready to be edited. # Conclusion Enjoy your secure git repository! If you think gitcrypt is totally awesome, -you could [buy me a beer][wishes]. +you could [buy me something][wishes] or donate using Pledgie: + +[![Support my open source development][pledgie]][donate] [1]: http://syncom.appspot.com/papers/git_encryption.txt "GIT transparent encryption" [2]: http://syncom.appspot.com/ @@ -128,4 +130,6 @@ you could [buy me a beer][wishes]. [6]: http://www.kernel.org/pub/software/scm/git/docs/gitattributes.html [7]: http://www.kernel.org/pub/software/scm/git/docs/gitignore.html#_pattern_format -[wishes]: http://www.amazon.com/gp/registry/wishlist/1474H3P2204L8 "Woody Gilk's Wish List on Amazon.com" +[wishes]: http://www.amazon.com/gp/registry/wishlist/1474H3P2204L8 +[donate]: http://www.pledgie.com/campaigns/14931 +[pledgie]: http://www.pledgie.com/campaigns/14931.png?skin=chrome From d53b45c07942b7a7e17a69feb8dcdc5020608330 Mon Sep 17 00:00:00 2001 From: Woody Gilk Date: Thu, 17 Mar 2011 13:45:39 -0500 Subject: [PATCH 14/35] Github breaks images in READMEs --- README.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/README.md b/README.md index 5a0dc20..fe7c6ce 100644 --- a/README.md +++ b/README.md @@ -118,9 +118,7 @@ All the files in the are now decrypted and ready to be edited. # Conclusion Enjoy your secure git repository! If you think gitcrypt is totally awesome, -you could [buy me something][wishes] or donate using Pledgie: - -[![Support my open source development][pledgie]][donate] +you could [buy me something][wishes] or [donate some money][donate]. [1]: http://syncom.appspot.com/papers/git_encryption.txt "GIT transparent encryption" [2]: http://syncom.appspot.com/ @@ -132,4 +130,3 @@ you could [buy me something][wishes] or donate using Pledgie: [wishes]: http://www.amazon.com/gp/registry/wishlist/1474H3P2204L8 [donate]: http://www.pledgie.com/campaigns/14931 -[pledgie]: http://www.pledgie.com/campaigns/14931.png?skin=chrome From ac9172698bc38a87ad7d2308aa579e566c104ddb Mon Sep 17 00:00:00 2001 From: Michel Weimerskirch Date: Sun, 1 May 2011 09:06:58 -0700 Subject: [PATCH 15/35] Fix default cipher Signed-off-by: Woody Gilk --- gitcrypt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) mode change 100755 => 100644 gitcrypt diff --git a/gitcrypt b/gitcrypt old mode 100755 new mode 100644 index 007e82d..ab7daf4 --- a/gitcrypt +++ b/gitcrypt @@ -1,7 +1,7 @@ #!/bin/bash readonly VERSION="0.2.1" -readonly DEFAULT_CIPHER="aes-256-ebc" +readonly DEFAULT_CIPHER="aes-256-ecb" init_config() { local answer From 1fffbfdd7cf109de5e6f8197a226ae9b73cfcc9b Mon Sep 17 00:00:00 2001 From: Woody Gilk Date: Sun, 15 May 2011 21:32:06 -0500 Subject: [PATCH 16/35] Fixes automatic salt generation on GNU *nix systems --- gitcrypt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gitcrypt b/gitcrypt index ab7daf4..730a831 100644 --- a/gitcrypt +++ b/gitcrypt @@ -21,7 +21,8 @@ init_config() { fi ;; *) - SALT=$(head -c 10 < /dev/random | md5 | cut -c-16) + local md5=$(which md5 2>/dev/null || which md5sum 2>/dev/null) + SALT=$(head -c 10 < /dev/random | $md5 | cut -c-16) ;; esac done From 3109f8e9d772b48930a533d69f54ae45aa3c8340 Mon Sep 17 00:00:00 2001 From: Woody Gilk Date: Sun, 15 May 2011 21:33:18 -0500 Subject: [PATCH 17/35] Bump version to 0.2.2 --- gitcrypt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitcrypt b/gitcrypt index 730a831..382c4c9 100644 --- a/gitcrypt +++ b/gitcrypt @@ -1,6 +1,6 @@ #!/bin/bash -readonly VERSION="0.2.1" +readonly VERSION="0.2.2" readonly DEFAULT_CIPHER="aes-256-ecb" init_config() { From 9d263a900f52e2e283b03d33004e32352f9f80f6 Mon Sep 17 00:00:00 2001 From: Maciej Mazur Date: Tue, 29 Nov 2011 00:14:07 +0100 Subject: [PATCH 18/35] Added pasword generation, fixes #8 Signed-off-by: Woody Gilk --- gitcrypt | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/gitcrypt b/gitcrypt index 382c4c9..6e9dbae 100644 --- a/gitcrypt +++ b/gitcrypt @@ -28,8 +28,18 @@ init_config() { done while [ -z "$PASS" ]; do - echo -n "Enter your passphrase: " - read PASS + echo -n "Generate a random password? [Y/n]" + read answer + + case "$answer" in + n*|N*) + echo -n "Enter your passphrase: " + read PASS + ;; + *) + PASS=$(cat /dev/urandom | tr -dc '!@#$%^&*()_A-Z-a-z-0-9' | head -c32) + ;; + esac done while [ 1 ]; do From 5df7028ef166e624589686aa6968109c5de06244 Mon Sep 17 00:00:00 2001 From: Woody Gilk Date: Fri, 2 Dec 2011 10:41:21 -0600 Subject: [PATCH 19/35] Changed mode of gitcrypt --- gitcrypt | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 gitcrypt diff --git a/gitcrypt b/gitcrypt old mode 100644 new mode 100755 From 1895f99eff20ac93a130a026f87d4df213fdb093 Mon Sep 17 00:00:00 2001 From: Woody Gilk Date: Tue, 20 Dec 2011 17:39:05 -0600 Subject: [PATCH 20/35] Reference `/usr/local/bin` instead of `/usr/bin`. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fe7c6ce..f18798b 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ The `gitcrypt` command must be executable: And it must be accessible in your `$PATH`: - $ sudo ln -s gitcrypt /usr/bin/gitcrypt + $ sudo ln -s gitcrypt /usr/local/bin/gitcrypt ## Configuration From 74ecd150982363b9743e2792440d9e871aeec2bc Mon Sep 17 00:00:00 2001 From: Woody Gilk Date: Wed, 28 Dec 2011 00:54:07 -0600 Subject: [PATCH 21/35] Updated README, refs https://gist.github.com/873637#gistcomment-71604 --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index fe7c6ce..cc8a1d5 100644 --- a/README.md +++ b/README.md @@ -110,8 +110,7 @@ performed on the original repository. Once configuration is complete, reset and checkout all the files: - $ git reset HEAD - $ git ls-files --deleted | xargs git checkout -- + $ git reset --hard HEAD All the files in the are now decrypted and ready to be edited. From b8e27f11903be02a69f467ed9601def91a468d26 Mon Sep 17 00:00:00 2001 From: Woody Gilk Date: Wed, 28 Dec 2011 00:54:33 -0600 Subject: [PATCH 22/35] Bump version to 0.2.3 --- gitcrypt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitcrypt b/gitcrypt index 6e9dbae..7b6b76c 100755 --- a/gitcrypt +++ b/gitcrypt @@ -1,6 +1,6 @@ #!/bin/bash -readonly VERSION="0.2.2" +readonly VERSION="0.2.3" readonly DEFAULT_CIPHER="aes-256-ecb" init_config() { From b39473e8b7cdee4b999d3b9277c15240cd80a9df Mon Sep 17 00:00:00 2001 From: Maciej Mazur Date: Tue, 29 Nov 2011 00:14:07 +0100 Subject: [PATCH 23/35] Added pasword generation, fixes #8 Signed-off-by: Woody Gilk --- gitcrypt | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/gitcrypt b/gitcrypt index 382c4c9..6e9dbae 100644 --- a/gitcrypt +++ b/gitcrypt @@ -28,8 +28,18 @@ init_config() { done while [ -z "$PASS" ]; do - echo -n "Enter your passphrase: " - read PASS + echo -n "Generate a random password? [Y/n]" + read answer + + case "$answer" in + n*|N*) + echo -n "Enter your passphrase: " + read PASS + ;; + *) + PASS=$(cat /dev/urandom | tr -dc '!@#$%^&*()_A-Z-a-z-0-9' | head -c32) + ;; + esac done while [ 1 ]; do From 6a47035e58096dfeaaa05cecb820e1330c0ca73f Mon Sep 17 00:00:00 2001 From: Woody Gilk Date: Fri, 2 Dec 2011 10:41:21 -0600 Subject: [PATCH 24/35] Changed mode of gitcrypt --- gitcrypt | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 gitcrypt diff --git a/gitcrypt b/gitcrypt old mode 100644 new mode 100755 From 50b0e02324147baf90f2f2dd45de6aa00a703d52 Mon Sep 17 00:00:00 2001 From: Woody Gilk Date: Wed, 28 Dec 2011 00:54:07 -0600 Subject: [PATCH 25/35] Updated README, refs https://gist.github.com/873637#gistcomment-71604 --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index f18798b..04e3210 100644 --- a/README.md +++ b/README.md @@ -110,8 +110,7 @@ performed on the original repository. Once configuration is complete, reset and checkout all the files: - $ git reset HEAD - $ git ls-files --deleted | xargs git checkout -- + $ git reset --hard HEAD All the files in the are now decrypted and ready to be edited. From 67930acfc3d2e83798aa96fe512d7dabc9f9079d Mon Sep 17 00:00:00 2001 From: Woody Gilk Date: Wed, 28 Dec 2011 00:54:33 -0600 Subject: [PATCH 26/35] Bump version to 0.2.3 --- gitcrypt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitcrypt b/gitcrypt index 6e9dbae..7b6b76c 100755 --- a/gitcrypt +++ b/gitcrypt @@ -1,6 +1,6 @@ #!/bin/bash -readonly VERSION="0.2.2" +readonly VERSION="0.2.3" readonly DEFAULT_CIPHER="aes-256-ecb" init_config() { From f57dd8ddbbe7ffa8aee2fc6081459e1dd7a5a09b Mon Sep 17 00:00:00 2001 From: Jay Taylor Date: Tue, 10 Apr 2012 12:03:47 -0700 Subject: [PATCH 27/35] Including an alternate (somewhat simplified) script. --- README.md | 29 ++++++++++ git-encrypt-init.sh | 125 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 154 insertions(+) create mode 100755 git-encrypt-init.sh diff --git a/README.md b/README.md index 04e3210..9280f3d 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,9 @@ by people much smarter than me, gitcrypt would not exist. > There is [some controversy][4] over using this technique, so do your research and understand the implications of using this tool before you go crazy with it. +## Requirements +Openssl must be installed and the binary must be available in your $PATH. + ## Installation Clone git-encrypt somewhere on your local machine: @@ -114,6 +117,32 @@ Once configuration is complete, reset and checkout all the files: All the files in the are now decrypted and ready to be edited. +# Alternate method: git-encrypt-init.sh + +Contributed by [Jay Taylor](https://jaytaylor.com "jaytaylor.com") + + +The git-encrypt-init.sh shell script automatically performs all prepartion, +setup and configuration for a local repository clone, prompting the user for +any required information (salt and password phrases.) This method of also +ensures that the git-encrypt scripts are automatically installed to +`~/.gitencrypt/`. One drawback to this approach is that it only supports having +1 password. + +One reason to use this alternate approach is because it makes decrypting cloned +repositories as simple as executing one script. + +## Usage + +Once you've cloned git-encrypt using the alternate script is straightforward: + + $ cd /path/to/your/repository + $ sh /path/to/git-encrypt/git-encrypt-init.sh + +Then you can add the files you would like to have encrypted to the +.gitattributes file contained in the root of your repository. + + # Conclusion Enjoy your secure git repository! If you think gitcrypt is totally awesome, diff --git a/git-encrypt-init.sh b/git-encrypt-init.sh new file mode 100755 index 0000000..31fd90e --- /dev/null +++ b/git-encrypt-init.sh @@ -0,0 +1,125 @@ +#!/usr/bin/env bash + +## +# @author Jay Taylor [@jtaylor] +# +# @date 2012-04-09 +# +# @description Initializes openssl encryption filter into the .git/config file +# of a cloned git repository. +# + + +localGitConfigFile='.git/config' + + +################################################################################ + +# Ensure that we are running in the root of a git repository. +if ! [ -r "$localGitConfigFile" ]; then + echo 'fatal: this script can only be run in the root of a git repository' 1>&2 + echo 'check your current directory (by running `pwd`), correct any issues you find, and then try again' 1>&2 + exit 1 +fi + + +# Define filter scripts and other static executable/reference file contents. +# NB: The semi-colons at the end of each line for the first 3 entries here are +# due to the use of `eval` below. +clean_filter_openssl='#!/usr/bin/env bash; +; +SALT_FIXED={{SALT}}; +#A1F1F8129C4FEBAB3513C174 # 24 or less hex characters; +PASS_FIXED={{PASSWORD}}; +; +openssl enc -base64 -aes-256-ecb -S $SALT_FIXED -k $PASS_FIXED' + +smudge_filter_openssl='#!/usr/bin/env bash; +; +# No salt is needed for decryption.; +PASS_FIXED={{PASSWORD}}; +; +# If decryption fails, use `cat` instead.; +# Error messages are redirected to /dev/null.; +openssl enc -d -base64 -aes-256-ecb -k $PASS_FIXED 2> /dev/null || cat' + +diff_filter_openssl='#!/usr/bin/env bash; +; +# No salt is needed for decryption.; +PASS_FIXED={{PASSWORD}}; +; +# Error messages are redirected to /dev/null.; +openssl enc -d -base64 -aes-256-ecb -k $PASS_FIXED -in "$1" 2> /dev/null || cat "$1"' + +gitattributes='*.md filter=openssl diff=openssl +sensitive.txt filter=openssl diff=openssl +[merge] + renormalize = true' + +gitconfig='[filter "openssl"] + smudge = ~/.gitencrypt/smudge_filter_openssl + clean = ~/.gitencrypt/clean_filter_openssl +[diff "openssl"] + textconv = ~/.gitencrypt/diff_filter_openssl' + + +# Initialize .gitencrypt directory in the users $HOME if not already there. + +if ! [ -d "$HOME/.gitencrypt" ]; then + echo 'info: initializing ~/.gitencrypt' + + # Prompt user for salt and password. + while [ -z "$salt" ]; do + echo 'Enter the salt phrase (16 hexadecimal characters):' + read salt + done + + while [ -z "$password" ]; do + echo 'Enter the encryption pass-phrase:' + read password + done + + mkdir "$HOME/.gitencrypt" + + for filter in clean_filter_openssl smudge_filter_openssl diff_filter_openssl; do + echo "info: generating filter script '$filter'" + filterScriptPath="$HOME/.gitencrypt/$filter" + + # This ugliness is due to `eval` not handling newlines very nicely. + # @see http://stackoverflow.com/a/3524860/293064 for more eval details. + echo -e $(eval "echo \$$filter") | tr ';' '\n' | sed "s/{{SALT}}/$salt/g + s/{{PASSWORD}}/$password/g + s/^ *\(.*\) *$/\1/g" > "$filterScriptPath" + + chmod a+x "$filterScriptPath" + done +fi + + +# Initialize .gitattributes file if it doesn't exist. + +if ! [ -e '.gitattributes' ]; then + echo "info: initializing file '.gitattributes'" + echo -n $gitattributes > .gitattributes +fi + + +# Initialize the .git/conf file for this repository clone if not already. + +checkForPreExistingConf=$(grep '^\[\(filter\|diff\) "openssl"]$' "$localGitConfigFile") + +if [ -n "$checkForPreExistingConf" ]; then + echo 'info: openssl filter/diff already configured for this clone' +else + cat <> "$localGitConfigFile" +$gitconfig +EOF + echo 'info: openssl filter/diff successfuly applied to this clone' +fi + + +# Reset the HEAD to re-check out all of the files [with the encryption filters.] + +echo 'info: re-checking out all of the files to ensure that the encryption filters are applied' +git reset --hard HEAD + From dcc8ad14a293c05337015fb79380d66a700a7118 Mon Sep 17 00:00:00 2001 From: Woody Gilk Date: Tue, 10 Apr 2012 14:21:30 -0500 Subject: [PATCH 28/35] Bump version to 0.3.0 --- gitcrypt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitcrypt b/gitcrypt index 7b6b76c..73149f4 100755 --- a/gitcrypt +++ b/gitcrypt @@ -1,6 +1,6 @@ #!/bin/bash -readonly VERSION="0.2.3" +readonly VERSION="0.3.0" readonly DEFAULT_CIPHER="aes-256-ecb" init_config() { From 6444c1eb6b978257e689879fb0e6f2aed2cc7872 Mon Sep 17 00:00:00 2001 From: Sundar Raman Date: Wed, 11 Apr 2012 15:07:40 -0400 Subject: [PATCH 29/35] Remove spacing between the key and value in git attributes The previous command "renormalize = true" caused the following to be dumped on the console with any gitcrypt enabled repo: is not a valid attribute name: .git/info/attributes:3 --- gitcrypt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitcrypt b/gitcrypt index 73149f4..c549229 100755 --- a/gitcrypt +++ b/gitcrypt @@ -95,7 +95,7 @@ init_config() { echo "$pattern filter=encrypt diff=encrypt" >> $attrs echo "[merge]" >> $attrs - echo " renormalize = true" >> $attrs + echo " renormalize=true" >> $attrs # Encryption git config gitcrypt.salt "$SALT" From 208b6af7429f3b2e940508923da83bbe0ee2e8be Mon Sep 17 00:00:00 2001 From: Veeresh Khanorkar Date: Mon, 23 Jul 2012 14:50:31 +0530 Subject: [PATCH 30/35] Added small check --- gitcrypt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/gitcrypt b/gitcrypt index c549229..67fa9ec 100755 --- a/gitcrypt +++ b/gitcrypt @@ -156,7 +156,11 @@ case "$1" in ;; *) # Not a valid option - echo "Gitcrypt: command does not exist: $1" + if [ -z "$1" ]; then + echo "Gitcrypt: available options: init, version" + else + echo "Gitcrypt: command does not exist: $1" + fi exit 1 ;; esac From 90d58bd4df1d97df3dc3c7849cb8936116ff504e Mon Sep 17 00:00:00 2001 From: Veeresh Khanorkar Date: Mon, 23 Jul 2012 14:50:46 +0530 Subject: [PATCH 31/35] Added Windows howto --- README.md | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/README.md b/README.md index 9280f3d..7f98a9d 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,49 @@ And it must be accessible in your `$PATH`: $ sudo ln -s gitcrypt /usr/local/bin/gitcrypt +### For Windows + +**Verified on PortableGit Only !** + +Copy the file gitcrypt to your PortableGit/bin location. In my environment PortableGit is +available at E:\PortableGit. + +> copy gitcrypt E:\PortableGit\bin + +Also make sure that PATH environment variable has E:\PortableGit\bin +available in it. + +> Path=C:\Python27\;C:\Python27\Scripts;E:\PortableGit\bin;E:\PortableGit\libexec\git-core;C:\windows\system32;C:\windows\;C:\window +> s\system32\WBEM;c:\windows\System32\WindowsPowerShell\v1.0\;c:\i386\~configs;C:\Users\VKHANORK\AppData\Roaming\Python\Scripts + +Setup gitcrypt: + +> E:\>mkdir TEST +> +> E:\>cd TEST +> +> E:\TEST>git init +> Initialized empty Git repository in E:/TEST/.git/ +> +> E:\TEST>git config core.autocrlf false +> +> E:\TEST>E:\PortableGit\bin\bash.exe E:\PortableGit\bin\gitcrypt init +> Generate a random salt? [Y/n] +> Generate a random password? [Y/n] +> What encryption cipher do you want to use? [aes-256-ecb] +> +> This configuration will be stored: +> +> salt: 5ecc05565042de81 +> pass: iLC#GkuzE1iOmUVItIQww8**oBDTfKE2 +> cipher: aes-256-ecb +> +> Does this look right? [Y/n] +> Do you want to use .git/info/attributes? [Y/n] +> What files do you want encrypted? [*] +> +> E:\TEST> + ## Configuration To quickly setup gitcrypt interactively, run `gitcrypt init` from the root From 2526c4e21defe5c2dda57566aa175574732d0645 Mon Sep 17 00:00:00 2001 From: Gandaman Date: Wed, 17 Oct 2012 21:37:04 +0200 Subject: [PATCH 32/35] Fix ln -s command (needs absolute path) in README Signed-off-by: Woody Gilk --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7f98a9d..a56217e 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ The `gitcrypt` command must be executable: And it must be accessible in your `$PATH`: - $ sudo ln -s gitcrypt /usr/local/bin/gitcrypt + $ sudo ln -s "$(pwd)/gitcrypt" /usr/local/bin/gitcrypt ### For Windows From 24f9d9eca8219f9cf8c4a8db5b414570e07531bf Mon Sep 17 00:00:00 2001 From: Lorin Hochstein Date: Wed, 20 Feb 2013 22:09:07 -0500 Subject: [PATCH 33/35] Fix an issue with tr on OS X The version of tr that ships with OS X can't handle certain binary inputs if the locale is set to a certain value. This sets the locale to C. --- gitcrypt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitcrypt b/gitcrypt index 67fa9ec..6957d60 100755 --- a/gitcrypt +++ b/gitcrypt @@ -37,7 +37,7 @@ init_config() { read PASS ;; *) - PASS=$(cat /dev/urandom | tr -dc '!@#$%^&*()_A-Z-a-z-0-9' | head -c32) + PASS=$(cat /dev/urandom | LC_ALL="C" tr -dc '!@#$%^&*()_A-Z-a-z-0-9' | head -c32) ;; esac done From 75ac9653b7300a8b9ed02e7eff788d111f0f0949 Mon Sep 17 00:00:00 2001 From: kris kechagia Date: Thu, 2 May 2013 17:11:19 +0200 Subject: [PATCH 34/35] Exit when directory doesn't contain a .git dir - this prevents the following error, when initializing in a non-git directory /usr/local/bin/gitcrypt: line 96: .git/info/attributes: No such file or directory /usr/local/bin/gitcrypt: line 97: .git/info/attributes: No such file or directory /usr/local/bin/gitcrypt: line 98: .git/info/attributes: No such file or directory error: could not lock config file .git/config: No such file or directory error: could not lock config file .git/config: No such file or directory error: could not lock config file .git/config: No such file or directory error: could not lock config file .git/config: No such file or directory error: could not lock config file .git/config: No such file or directory error: could not lock config file .git/config: No such file or directory --- gitcrypt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/gitcrypt b/gitcrypt index 6957d60..58022f9 100755 --- a/gitcrypt +++ b/gitcrypt @@ -5,6 +5,12 @@ readonly DEFAULT_CIPHER="aes-256-ecb" init_config() { local answer + + if [ ! -d ".git" ]; then + echo "Directory is not a git repository. Did you forget to run 'git init'?" + return 1 + fi + while [ 1 ]; do while [ -z "$SALT" ]; do echo -n "Generate a random salt? [Y/n] " From af47bc1d52cd633d2d6345ae34ffe0baf99f8190 Mon Sep 17 00:00:00 2001 From: Samoilenko Yuri Date: Mon, 2 Sep 2013 23:22:52 +0400 Subject: [PATCH 35/35] support for GIT_DIR environment var --- gitcrypt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/gitcrypt b/gitcrypt index 58022f9..4acd2a6 100755 --- a/gitcrypt +++ b/gitcrypt @@ -3,10 +3,12 @@ readonly VERSION="0.3.0" readonly DEFAULT_CIPHER="aes-256-ecb" +[ -z "$GIT_DIR" ] && GIT_DIR=".git" + init_config() { local answer - if [ ! -d ".git" ]; then + if [ ! -d "$GIT_DIR" ]; then echo "Directory is not a git repository. Did you forget to run 'git init'?" return 1 fi @@ -81,7 +83,7 @@ init_config() { esac done - echo -n "Do you want to use .git/info/attributes? [Y/n] " + echo -n "Do you want to use $GIT_DIR/info/attributes? [Y/n] " read answer local attrs @@ -90,7 +92,7 @@ init_config() { attrs=".gitattributes" ;; *) - attrs=".git/info/attributes" + attrs="$GIT_DIR/info/attributes" ;; esac