Code Monkey home page Code Monkey logo

transcrypt's Introduction

transcrypt

A script to configure transparent encryption of sensitive files stored in a Git repository. Files that you choose will be automatically encrypted when you commit them, and automatically decrypted when you check them out. The process will degrade gracefully, so even people without your encryption password can safely commit changes to the repository's non-encrypted files.

transcrypt protects your data when it's pushed to remotes that you may not directly control (e.g., GitHub, Dropbox clones, etc.), while still allowing you to work normally on your local working copy. You can conveniently store things like passwords and private keys within your repository and not have to share them with your entire team or complicate your workflow.

Tests

Overview

transcrypt is in the same vein as existing projects like git-crypt and git-encrypt, which follow Git's documentation regarding the use of clean/smudge filters for encryption. In comparison to those other projects, transcrypt makes substantial improvements in the areas of usability and safety.

  • transcrypt is just a Bash script and does not require compilation
  • transcrypt uses OpenSSL's symmetric cipher routines rather than implementing its own crypto
  • transcrypt does not have to remain installed after the initial repository configuration
  • transcrypt generates a unique salt for each encrypted file
  • transcrypt uses safety checks to avoid clobbering or duplicating configuration data
  • transcrypt facilitates setting up additional clones as well as rekeying
  • transcrypt adds an alias git ls-crypt to list all encrypted files

Salt Generation

The decryption -> encryption process on an unchanged file must be deterministic for everything to work transparently. To do that, the same salt must be used each time we encrypt the same file. Rather than use a static salt common to all files, transcrypt first has OpenSSL generate an HMAC-SHA256 cryptographic hash-based message authentication code for each decrypted file (keyed with a combination of the filename and transcrypt password), and then uses the last 16 bytes of that HMAC for the file's unique salt. When the content of the file changes, so does the salt. Since an HMAC has been proven to be a PRF, this method of salt selection does not leak information about the original contents, but is still deterministic.

Usage

The requirements to run transcrypt are minimal:

  • Bash
  • Git
  • OpenSSL
  • column and hexdump commands (on Ubuntu/Debian install bsdmainutils)
  • xxd command if using OpenSSL version 3 (on Ubuntu/Debian is included with vim)

...and optionally:

  • GnuPG - for secure configuration import/export

You also need access to the transcrypt script itself. You can add it directly to your repository, or just put it somewhere in your $PATH:

$ git clone https://github.com/elasticdog/transcrypt.git
$ cd transcrypt/
$ sudo ln -s ${PWD}/transcrypt /usr/local/bin/transcrypt

Installation via Packages

A number of packages are available for installing transcrypt directly on your system via its native package manager. Some of these packages also include man page documentation as well as shell auto-completion scripts.

...see the INSTALL document for more details.

Initialize an Unconfigured Repository

transcrypt will interactively prompt you for the required information, all you have to do run the script within a Git repository:

$ cd <path-to-your-repo>/
$ transcrypt

If you already know the values you want to use, you can specify them directly using the command line options. Run transcrypt --help for more details.

Designate a File to be Encrypted

Once a repository has been configured with transcrypt, you can designate for files to be encrypted by applying the "crypt" filter, diff, and merge to a pattern in the top-level .gitattributes config. If that pattern matches a file in your repository, the file will be transparently encrypted once you stage and commit it:

$ cd <path-to-your-repo>/
$ echo 'sensitive_file  filter=crypt diff=crypt merge=crypt' >> .gitattributes
$ git add .gitattributes sensitive_file
$ git commit -m 'Add encrypted version of a sensitive file'

The .gitattributes file should be committed and tracked along with everything else in your repository so clones will be aware of what is encrypted. Make sure you don't accidentally add a pattern that would encrypt this file :-)

For your reference, if you find the above description confusing, you'll find that this repository has been configured following these exact steps.

Listing the Currently Encrypted Files

For convenience, transcrypt also adds a Git alias to allow you to list all of the currently encrypted files in a repository:

$ git ls-crypt
sensitive_file

Alternatively, you can use the --list command line option:

$ transcrypt --list
sensitive_file

You can also use this to verify your .gitattributes patterns when designating new files to be encrypted, as the alias will list pattern matches as long as everything has been staged (via git add).

After committing things, but before you push to a remote repository, you can validate that files are encrypted as expected by viewing them in their raw form:

$ git show HEAD:<path-to-file> --no-textconv

The <path-to-file> in the above command must be relative to the top-level of the repository. Alternatively, you can use the --show-raw command line option and provide a path relative to your current directory:

$ transcrypt --show-raw sensitive_file

Initialize a Clone of a Configured Repository

If you have just cloned a repository containing files that are encrypted, you'll want to configure transcrypt with the same cipher and password as the origin repository. The owner of the origin repository can dump the credentials for you by running the --display command line option:

$ transcrypt --display
The current repository was configured using transcrypt v0.2.0
and has the following configuration:

  CONTEXT:  default
  CIPHER:   aes-256-cbc
  PASSWORD: correct horse battery staple

Copy and paste the following command to initialize a cloned repository:

  transcrypt -c aes-256-cbc -p 'correct horse battery staple'

Once transcrypt has stored the matching credentials, it will force a checkout of any exising encrypted files in order to decrypt them.

Rekeying

Periodically, you may want to change the encryption cipher or password used to encrypt the files in your repository. You can do that easily with transcrypt's rekey option:

$ transcrypt --rekey

As a warning, rekeying will remove your ability to see historical diffs of the encrypted files in plain text. Changes made with the new key will still be visible, and you can always see the historical diffs in encrypted form by disabling the text conversion filters:

$ git log --patch --no-textconv

After rekeying, all clones of your repository should flush their transcrypt credentials, fetch and merge the new encrypted files via Git, and then re-configure transcrypt with the new credentials.

$ transcrypt --flush-credentials
$ git fetch origin
$ git merge origin/main
$ transcrypt -c aes-256-cbc -p 'the-new-password'

Command Line Options

Completion scripts for both Bash and Zsh are included in the contrib/ directory.

transcrypt [option...]

  -c, --cipher=CIPHER
         the symmetric cipher to utilize for encryption;
         defaults to aes-256-cbc

  -p, --password=PASSWORD
         the password to derive the key from;
         defaults to 30 random base64 characters

  --set-openssl-path=PATH_TO_OPENSSL
         use OpenSSL at this path; defaults to 'openssl' in $PATH

  -y, --yes
         assume yes and accept defaults for non-specified options

  -d, --display
         display the current repository's cipher and password

  -r, --rekey
         re-encrypt all encrypted files using new credentials

  -f, --flush-credentials
         remove the locally cached encryption credentials and  re-encrypt
         any files that had been previously decrypted

  -F, --force
         ignore whether the git directory is clean, proceed with the
         possibility that uncommitted changes are overwritten

  -u, --uninstall
         remove  all  transcrypt  configuration  from  the repository and
         leave files in the current working copy decrypted

   --upgrade
         uninstall and re-install transcrypt configuration in the repository
         to apply the newest scripts and .gitattributes configuration

  -l, --list
         list all of the transparently encrypted files in the repository,
         relative to the top-level directory

  -s, --show-raw=FILE
         show  the  raw file as stored in the git commit object; use this
         to check if files are encrypted as expected

  -e, --export-gpg=RECIPIENT
         export  the  repository's cipher and password to a file encrypted
         for a gpg recipient

  -i, --import-gpg=FILE
         import the password and cipher from a gpg encrypted file

  -C, --context=CONTEXT_NAME
         name for a context  with a different passphrase  and cipher from
         the  'default' context;   use this  advanced option  to  encrypt
         different files with different passphrases

  --list-contexts
         list all contexts configured in the  repository,  and warn about
         incompletely configured contexts

  -v, --version
         print the version information

  -h, --help
         view this help message

Caveats

Overhead

The method of using filters to selectively encrypt/decrypt files does add some overhead to Git by regularly forking OpenSSL processes and removing Git's ability to efficiently cache file changes. That said, it's not too different from tracking binary files, and when used as intended, transcrypt should not noticeably impact performance. There are much better options if your goal is to encrypt the entire repository.

Localhost

Note that the configuration and encryption information is stored in plain text within the repository's .git/config file. This prevents them from being transferred to remote clones, but they are not protected from inquisitive users on your local machine.

For safety, you may prefer to only have the credentials stored when actually updating encrypted files, and then flush them with --flush-credentials once you're done (make sure you have the credentials backed up elsewhere!). This will also revert any decrypted files back to their encrypted form in your local working copy.

Cipher Selection

Last up, regarding the default cipher choice of aes-256-cbc...there aren't any fantastic alternatives without pulling in outside dependencies. Ideally, we would use an authenticated cipher mode like id-aes256-GCM by default, but there are a couple of issues:

  1. I'd like to support OS X out of the box, and unfortunately they are the lowest common denominator when it comes to OpenSSL. For whatever reason, they still include OpenSSL 0.9.8y rather than a newer release. Unfortunately, GCM-based ciphers weren't added until OpenSSL 1.0.1 (back in early 2012).

  2. Even with newer versions of OpenSSL, the authenticated cipher modes don't work exactly right when utilizing the command line openssl enc.

I'm contemplating if transcrypt should append an HMAC to the aes-256-cbc ciphertext to provide authentication, or if we should live with the malleability issues as a known limitation. Essentially, malicious comitters without the transcrypt password could potentially manipulate the plaintext in limited ways (given that the attacker knows the original plaintext). Honestly, I'm not sure if the added complexity here would be worth it given transcrypt's use case.

Advanced

Contexts

Context names let you encrypt some files with different passwords for a different audience, such as super-users. The 'default' context applies unless you set a context name.

Add a context by reinitialising transcrypt with a context name then add a pattern with crypt-<CONTEXTNAME> attributes to .gitattributes. For example, to encrypt a file _top-secret in a "super" context:

# Initialise a new "super" context, and set a different password
$ transcrypt --context=super

# Add a pattern to .gitattributes with "crypt-super" values
$ echo >> .gitattributes \\
  'top-secret filter=crypt-super diff=crypt-super merge=crypt-super'

# Add and commit your top-secret and .gitattribute files
$ git add .gitattributes top-secret
$ git commit -m "Add top secret file for super-users only"

# List all contexts
$ transcrypt --list-contexts

# Display the cipher and password for the "super" context
$ transcrypt --context=super --display

License

transcrypt is provided under the terms of the MIT License.

Copyright © 2014-2020, Aaron Bull Schaefer.

Contributing

Linting and formatting

Please use:

  • the shellcheck tool to check for subtle bash scripting errors in the transcrypt file, and apply the recommendations when possible. E.g: shellcheck transcrypt
  • the shfmt tool to apply consistent formatting to the transcrypt file, e.g: shfmt -w transcrypt
  • the Prettier tool to apply consistent formatting to the README.md file, e.g: prettier --write README.md

Tests

Tests are written using bats-core version of "Bash Automated Testing System" and stored in the tests/ directory.

To run the tests:

  • install bats-core
  • run all tests with: bats tests/
  • run an individual test with e.g: bats tests/test_crypt.bats

transcrypt's People

Contributors

adrianduke avatar andreineculau avatar aramgutang avatar ataber avatar csimons avatar damaestro avatar dimitrov-adrian avatar dirkhas avatar elasticdog avatar erijo avatar fbartels avatar geneticgrabbag avatar jmurty avatar ljm42 avatar nivit avatar perplexes avatar ryancdotorg avatar ssiegel avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

transcrypt's Issues

Spaces in file name causing issue

Rekey fails when .gitattribute contains two star in path (**) and they are files with spaces in their name.

https://git-scm.com/docs/gitignore
A trailing "/**" matches everything inside. For example, "abc/**" matches all files inside directory "abc", relative to the location of the .gitignore file, with infinite depth.

There was also a unicode character in the filename, but I don't think that was the problem. (à)
I'm on windows.

.gitattributes:
/private/** filter=crypt diff=crypt

file:
the file.txt

Error:

	Proceed with rekey? [y/N] y

touch: unknown option -- N
Try 'touch --help' for more information.
error: private/the: does not exist and --remove not passed
fatal: Unable to process path private/the
***  rekeyed files have been staged  ***
*** COMMIT THESE CHANGES RIGHT AWAY! ***

Overridden add/sub throws TypeError.

Objects with overridden +/- throw typeerror.

To reproduce:

import datetime
a = datetime.date.today()
b = datetime.date.today()
print(a - b) # throws typeerror in transpiled js

[Q] committing gpg keys

I love the simplicity of transcrypt, but I cannot wrap my head around the current integration with gpg in #10 .

transcrypt --export-gpg <recipient> ends up saving the credentials of this repo encrypted for recipient under .git/crypt/<recipient>.asc. For reasons unknown to me, transcrypt --import-gpg <recipient> will look for .git/crypt/<recipient> or .git/crypt/<recipient>.asc or for the file <recipient> itself.

Before GPG support, it is clear to me that sharing access to encrypted files is done by sharing the cipher and the password (hopefully via safe communication methods).

But after GPG support, it is unclear to me why sharing access is done by sharing (manually that is) an encrypted message, rather than having the message committed into the repo (implicit sharing; the recipient wouldn't need to store the message since it will always be available in the repo).

How do you imagine the use of the GPG support? What happens if everyone flushes their credentials and they didn't keep a copy of the encrypted message? Default once again to the cipher and password stored somewhere, in a safe location?

That's what I can't wrap my head around. As it is now, GPG support is merely a built-in secure transport of the cipher and password, while I see it as an alternative to cipher and password, because anyone with access to the git repo, and access to one of the secret keys that can decrypt a member's encrypted message, gains access to the encrypted files.

The latter increases the attack surface, but it is more convenient. The former, well, it seems at least, add only overhead (considerable one going from share a password to setup gpg&co) with little gain (as long as the cipher and password are transmitted to the right people via safe communication methods).

Thanks in advance for the explanations!

Suppress warnings for OpenSSL 1.1.1

Using OpenSSL 1.1.1 (in my case, in Git for Windows, which uses OpenSSL 1.1.1a 20 Nov 2018), the clean script constantly leads to git commands printing out the following warning:

*** WARNING : deprecated key derivation used.
Using -iter or -pbkdf2 would be better.

Diff problems when an empty file is marked for encryption

Steps to reproduce

  1. Create git repo
  2. Initialize Transcrypt
  3. Add Transcrypt rule to .gitattributes
    • empty-file filter=crypt diff=crypt
  4. Add/Commit the .gitattributes file
  5. Create the empty-file
    • touch empty-file
  6. Add the empty-file

At this point, if you run git diff there will be an empty diff, instead of no diff. If you run git diff --exit-code and then check the exit code echo $?, you'll see it exits with a 1 (indicating a difference), instead of a 0 (indicating no difference). If you reproduce these steps except for initializing transcrypt and configuring the rule for the empty file, git diff --exit-code will exit with a 0.

From the user's perspective there's no indication what the problem is and it interferes with the ability to run any commands that depend on a clean working tree, eg git rebase.

windows version?

Any chance of getting a windows executable? (Actually I'm running it from minGW and works great, but would be nice to have a native version)

Switch back to /dev/urandom from OpenSSL's PRNG?

Although transcrypt's usage of the random number generator is limited, I've been thinking of reverting commit 0c288b2 even though it was originally done for portability. I need to explore what using transcrypt in a Windows environment realistically looks like, and if switching back would break that functionality (or if it could be worked around easily).

See these for reference:

Windows issues, work-arounds and a minor change request

Hi.
I am using this on Windows 10 and after some issues, it is working. For it to work for others, I think my change should be put back into the tool.

First the two hints -

  • Set core.quotePath to false (git config --add core.quotePath false). Without this Danish (and similar) characters are escaped to \octal and that breaks further processing of those files
  • Next, to install transact on Windows without bash, I simply added it as a git alias and use the built-in bash interpretator in git. This is done with git config --add alias.transcrypt = !~/path/to/transcrypt/transcrypt. After this, I can install it with 'git transcrypt'.

And then the required fix in transcrypt itself.

The input file seperator (IFS) must be set to linefeed to avoid having the bash for statement split the input into words on space. Any files I have with spaces were not processed. So I added IFS=$'\n' before the "for secret_file in" loops (just before https://github.com/elasticdog/transcrypt/blob/master/transcrypt#L338)

Hope this change can get in.

PS. A great tool. Looking at using it for client-side encrypted backup.

Pull with rebase doesn't handle encrypted files

I'm not too sure how this could be fixed or if it's an issue with my setup, but if it's a small fix it'd be nice to have.

Happy to work on it if you can point me in the right direction :)


Steps to reproduce:

  • Hard reset your working copy to HEAD^ (make sure you don't lose any local changes!)
  • Make a change to encrypted file and commit
  • Pull with rebase from a remote repo

Expected behaviour:

  • Merge during rebase works as normal

Actual behaviour:

  • During rebase, the diff is done against an encrypted version of the file

mktemp without any arguments is invalid on <= macOS 10.10 Yosemite

The latest version of transcrypt calls mktemp without any arguments

tempfile=$(mktemp)

However on macOS Yosemite, and earlier, this is invalid syntax and will just cause usage information to be printed:

usage: mktemp [-d] [-q] [-t prefix] [-u] template ...
       mktemp [-d] [-q] [-u] -t prefix 

The newer man page for >= macOS 10.11 El Capitan says

     If no arguments are passed or if only the -d flag is passed mktemp behaves as if -t
     tmp was supplied.

So on the prior versions of macOS, it works to change tempfile=$(mktemp) to

tempfile=$(mktemp -t tmp)

However, that's not a drop-in fix because GNU mktemp will complain:

$ mktemp -t tmp
mktemp: too few X's in template ‘tmp’

So the invocation probably needs to be adjusted based on whether mktemp without args succeeds, in which case pass no args, otherwise pass -t tmp, to avoid breaking either way.

Encrypted files appearing as changed in git

Hey there.

I have a colleague who reports that their git status is never clean in the repos where we have encrypted files using transcrypt. We have compared versions of all the relevant software (transcrypt, git, openssl, OS...) and did not find any differences.

I am not sure why it is happening, but if you have any hints or advice on where to look to start tackling such an issue then I'm all ears!

I realise this is a bit vague and I don't have a way to reproduce the error so I understand if you aren't able to help but thought it was worth a shot.

GPG Support

It would be good to have GPG support that is one of the main benefits of git-crypt. Is there any chance of that?

Design contribution

Hi,

I am a graphic designer. I support the open source community with design contributions. I have made design contributions to different projects before. You can view my works from my profile. Would you like me to design a logo for TransCrypt?

Consider improving transcrypt's handling of large files

As @perost-l14 mentioned in these comments on #78 transcrypt currently does some things that hinder its use for encrypting many and/or large files.

This ticket is to draw out suggested improvements so they don't get lost in the broader discussion in #78.

In particular, as paraphrased by me (@jmurty):

  • encrypted files are Base64 encoded with the -a flag to openssl enc which takes up more space than binary data. This textual encoding may not be necessary since encrypted content isn't human-readable or diff-able as text.

  • adding -delta to encrypted file lines in .gitattributes disables git packing (delta compression) to avoid wasteful work when pushing encrypted files that aren't compressible. Example:

    *.jpg filter=crypt diff=crypt -delta
    

Would it make sense to update transcrypt to use binary data instead of base64, and set or recommend -delta in .gitattributes by default?

What would be the implications of doing these things, for both new transcrypt'ed repos and existing ones?

Object as map key

Python supports objects in map key, but js doesn't. The js map will end up having the string "[object Object]" as key instead.

If implementing this has negative performance implications, then a pragma would be nice.

Openssl 1.1.1 salt warnings / Git for Windows interoperability

In Git for Windows, currently in version 2.21.0 using Bash 4.4.23 and OpenSSL 1.1.1a, the salt generation in the clean script causes two issues:

a) The following warning is issued by OpenSSL everytime the openssl enc part of the clean script is called: hex string is too short, padding with zero bytes to length
b) salt generation differs between *nix and Windows due to line-endings.

Both issues have the same solution: make the salt consist of 16 hex characters not including any line-ending characters. Pull request on the way.

Spaces in directory names wreak havoc

I can't use transcrypt in a directory that has spaces in its name.

For example, I have a directory named Source Code (aliased as src) in my home folder, and if I try running transcrypt in ~/src/foo (aka /Users/jtilles/Source Code/foo) then I get an error that resembles the following:

$(git rev-parse --show-toplevel)/.git/crypt/smudge: /Users/jtilles/Source: No such file or directory
error: external filter $(git rev-parse --show-toplevel)/.git/crypt/smudge failed -1
error: external filter $(git rev-parse --show-toplevel)/.git/crypt/smudge failed

smudge issue

I keep getting:

error: external filter "$(git rev-parse --show-toplevel)"/.git/crypt/smudge failed 1
error: external filter "$(git rev-parse --show-toplevel)"/.git/crypt/smudge faile

While running git diff

My attributes file includes:

#pattern  filter=crypt diff=crypt
manifests/hosts/*.pp filter=crypt diff=crypt
data/*.yaml filter=crypt diff=crypt

error when running transcrypt on a fresh clone

(frank)[280] oti@core-dev:~/Software/tesf  [master]  $   transcrypt -c aes-256-cbc -p 'foo bar secret'

The following configuration will be saved:

  REPO:     /home/oti/Software/tesf
  CIPHER:   aes-256-cbc
  PASSWORD: foo bar secret

Does this look correct? [Y/n] 


error: external filter "$(git rev-parse --show-toplevel)"/.git/crypt/smudge failed 1
error: external filter "$(git rev-parse --show-toplevel)"/.git/crypt/smudge failed
The repository has been successfully configured by transcrypt.

This also happens when trying git diff:

(frank)[284] oti@core-dev:~/Software/tesf  [master]  $ git diff
error: external filter "$(git rev-parse --show-toplevel)"/.git/crypt/smudge failed 1
error: external filter "$(git rev-parse --show-toplevel)"/.git/crypt/smudge failed

OpenSSL 1.1.1c FIPS Causes Rewrite of Crypted Files

It seems that when I clone an existing repo and use transcrypt on it with correct information I end up rewriting all crypted files with an upgraded openssl.

transcrypt master and 9a8a1f4 tested
openssl-1.1.1c-2.fc30.x86_64 "OpenSSL 1.1.1c FIPS 28 May 2019"

git clone proto://server/my.git
cd my
transcrypt -c aes-256-cbc -p 'the-existing-phrase'

All git operations cause a rewrite of the crypted files. For example:

[damaestro@earth my]$ git status
*** WARNING : deprecated key derivation used.
Using -iter or -pbkdf2 would be better.
[...] repeated for every file
On branch transcrypt-test
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   path/to/crypted.py
[...] all files listed
no changes added to commit (use "git add" and/or "git commit -a")

The files are locally readable.

xkcd!

Indeed The example password indeed very secure, "correct horse battery staple"!

Multiple keys, same repo

Oh, hi there.

Is there any way to use multiple transcrypt keys in the same repo? i.e. encrypt some files with key A and some with key B.

I can try to write some code if you point me in the right direction. Let me know! Thanks.

transcrypt does not update built-in clean/smudge filters

As far as I can tell, there's no code path that updates the transcrypt scripts stored in .git/crypt, and these files are only updated on initialization.

This is problematic, as changes to these scripts are never propagated out to repositories with transcrypt already initialized.

In c8e4f72 the method for generating the salt was modified, and is not backwards compatible with the previous method. As a result, users who initialized a repository with transcrypt previous to this commit will be generating different salts, and thus be producing different output than those who initialized the repository after this commit.

For now, the work around is to have all users run transcrypt -u and rerun transcrypt, but this is a very tedious exercise to orchestrate across any organization of any size, and is prone to error.

transcrypt should have some facility to update these files automatically and transparently to users.

The most straightforward approach I can think of to fix this in transcrypt is to have it update these files every time it is run in a git repository, but that might be overkill.

A better solution might be to have these files be replaced with either symlinks or simple wrappers that call back out to transcrypt, and add this functionality in as a sub-module to the transcrypt program. This way these functions would always be tied in to the correct version expected by the current version of transcrypt.

Detection of clean repo is not reliable.

I'm using codefresh to build Docker images (including the .git directory), with an entrypoint script that configures the git repo for transcrypt with a password from the environment, to decrypt secret files at runtime.

transcrypt thinks the git repo is dirty:

# transcrypt -c "${TRANSCRYPT_CIPHER:-aes-256-cbc}" -p "$TRANSCRYPT_PASSWORD" -y
transcrypt: the repo is dirty; commit or stash your changes before running transcrypt

When I run the git diff-index command that transcrypt uses internally (minus the --quiet arg), it seems to return some odd results:

# git diff-index HEAD -- | tail                                                                                                   
:100644 100644 3d6e0e93c2bfef67162836b2f0b5ad24c526929e 0000000000000000000000000000000000000000 M      staticroot/apple-touch-icon-precomposed.png        
:100644 100644 9089ef7ffea1efe2de79b49b5e6a5856360de4d6 0000000000000000000000000000000000000000 M      staticroot/apple-touch-icon.png                    
:100644 100644 7b74f8caf013ba164ca9049f7bd4eea0555ff720 0000000000000000000000000000000000000000 M      staticroot/favicon.ico                             
:100644 100644 5d00a90141a920a278e2a8239e560b7ea395a1db 0000000000000000000000000000000000000000 M      staticroot/humans.txt                              
:100644 100644 214e4119653f9c6a4c48cd0ebb06a6754f00f62b 0000000000000000000000000000000000000000 M      staticroot/robots.txt                              

But the repo is clean, cloned and built by codefresh:

# git status                                                                                                                      
HEAD detached at 153c57c                                                                                                                                   
nothing to commit, working directory clean                                                                                                                 

Strangely, after running git status, transcrypt suddenly agrees that the repo is clean and agrees to configure the repo:

# git diff-index HEAD -- | tail                                                                                                   

# transcrypt -c "${TRANSCRYPT_CIPHER:-aes-256-cbc}" -p "$TRANSCRYPT_PASSWORD" -y
The repository has been successfully configured by transcrypt.                                                                                             

Is there something wrong with the way codefresh is cloning the repo before it builds the Docker image?

Is there a more reliable way transcrypt can detect a dirty repo (as reported by git status)?

Transcrypt version and help output not displayed outside git repositories

transcrypt --version and transcrypt --help should also work outside git repositories, as they're frequently used to test whether the script is installed correctly. They give no output, though.

Example terminal session:

➜  /tmp mkdir test
➜  /tmp cd testtest transcrypt --version
➜  test git init
Initialized empty Git repository in /tmp/test/.git/
➜  test git:(master) transcrypt --version
transcrypt 2.0.0

Same applies to transcrypt --help.

Expected behavior: version also displayed outside an initialized git repository.

Merging encrypted files with conflicts produces encrypted content in the "merged" file

When you merge branches containing transcrypt-encrypted files, if the files have conflicts the resulting "merged" file produced by Git for manual resolution ends up as a real mess, mostly or entirely full of the encrypted text which cannot be sensibly merged.

The root problem seems to be that git does not run the smudge/textconv filter on all the BASE, LOCAL, REMOTE conflicting versions of files before attempting a three-way merge, and instead attempts the merge using at least one – and maybe all – of the encrypted versions of these files. E.g. the encrypted content as available from git show :1:FILENAME and git show :2:FILENAME etc mid-merge.

I have not been able to find a workaround just within Git, and have instead added a custom "crypt" merge driver to handle this situation.

Here is a PR against our fork of Transcrypt as an example: ixc#1

This change isn't yet fully tested, and is written against a fairly old version of transcrypt.

Let me know if I should bring it up to date and submit a PR here directly to add the "crypt" merge driver to the latest version of transcrypt?

Files not being decrypted

Hi there,

I set up transcrypt on a repository (let's call it repo A) the other day and everything was working fine. I set up transcrypt on a new repository (repo B) yesterday and that seems to be working fine as well but now when I started working on the repo A again I noticed that my files are not being decrypted locally.
Things are still working fine on repo B.

I am not sure why this is happening but I am happy to give you more information if you guide me on where to look!

Edit: Is it possible that a rebase could cause this issue?

Unencrypted data left behind after credentials are flushed

Steps to reproduce:

  1. Clone transcrypt-enabled repo

  2. Run transcrypt with valid credentials

  3. Run git log -p (displaying all change sets, included encrypted ones)

  4. Run transcrypt -f (flushing the credentials)

  5. A. Run for object in $(cat .git/refs/notes/textconv/crypt); do git show $object; done (you'll see previously cached unencrypted data)

    or

    B. Run transcrypt with invalid credentials (encrypted data should NOT be available at this time)
    Run git log -p (you'll see previously cached unencrypted data)

I looked into this, and the reason this data is left unencrypted is due to the setting diff.crypt.cachetextconv=true. I image this has been done for efficiency/speed, but the result is unencrypted data left behind. I can think of two ways to handle this problem.

  1. Make cachetextconv=true optional, defaulting to false. This might be the simplest fix. Today this is hard-coded to true.
  2. Upon --flush, hunt down any cached data. This data can be found by inspecting <GIT_DIR>/refs/notes/textconv/crypt. That will contain a list of git objects that need to be removed. This is probably more difficult, but might be best because then caching could be used.

Avoid accidentally committing unencrypted files.

I use the GitUp client on OS X, and I just discovered that it does not execute attribute filters (git-up/GitUp#224).

If I'm not careful (or someone else using GitUp isn't careful), it is very easy to stage and commit an encrypted file from GitUp.

Could transcrypt automatically configure a pre/post-commit or pre-push hook to ensure that any files that should be encrypted, are always encrypted?

password leaks via proc info

Generally, at least on Linux, other users on a system are able to see the command line arguments given to a process. OpenSSL supports passing passwords via environment variables using -pass env:ENV_VAR_NAME which is not visible to other users besides root. I am not sure of a good fix.

One possible option which could generally apply to most other options would be to embed a short shell script within the git config an invoke it with something like this:

$(echo Zm9yIHcgaW4gaGVsbG8gd29ybGQKZG8KICAgICAgICBlY2hvICR3CmRvbmUK | openssl base64 -d | sh)

The main disadvantage being that it looks very shady.

Support for git archives

I just started using transcrypt recently and really like what it has to offer. One feature that I would really like to see is support for git archives. My particular use case is for Capistrano deployment to a remote server. Capistrano clones the git repository with the --mirror option to a local repo folder. It then calls "git update" to update the repo when needed. For deploying new releases it will use "git archive" on its local repo mirror and extract the output to a release directory. I would try to implement support for this myself but I am rather unfamiliar with the SSL encryption libraries and how Git filtering works.

Missing requirements

The transcrypt script needs the column command to run. On newer Ubuntu systems, this is provided by the bsdmainutils package. It should be added to the requirements list.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.