Last active
December 14, 2015 17:59
-
-
Save Naddiseo/5126508 to your computer and use it in GitHub Desktop.
A script for encrypting part of a file before committing to git. Useful for storing passwords encrypted on places like github, but having the plaintext available locally. Requirements: gpg, perl >=5.14
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl | |
#A script for encrypting part of a file before committing to git. | |
#Useful for storing passwords encrypted on places like github, but having the plaintext available locally. | |
# | |
#Requirements: gpg, perl >=5.14 | |
# | |
#Usage: | |
#- Create a gpg key for encrypting, passwordless. | |
#- Make sure crypt_pub.pl is executable and in $PATH | |
#- In your .git/config place: | |
#[filter "crypt_pub"] | |
# clean = crypt_pub.pl encrypt <KEY> | |
# smudge = crypt_pub.pl decrypt <KEY> | |
#[diff "crypt_pub"] | |
# command crypt_pub.pl diff <KEY> | |
# | |
#- In your source file that needs encrypting, in a comment at the end of the line place | |
# "$$ ENCRYPT N $$" where "N" is the number of non-whitespace tokens in the line where the password is, for example: | |
# "PASSWORD" : "THIS IS MY PASSWORD" # $$ ENCRYPT 3 $$ | |
# The above line can be tokenised into 3 tokens: (STRING COLON STRING), | |
# the "3" indicates that the 3rd token is a string that needs encrypting. | |
use 5.14.0; | |
use warnings; | |
use Data::Dumper; | |
my $cmd = shift; | |
my $key_r = shift; | |
my $op = $cmd eq 'encrypt' ? \&encrypt : ($cmd eq 'decrypt' ? \&decrypt : undef); | |
if (not defined $op) { | |
# call diff instead | |
my $file1 = $ARGV[0]; | |
my $file2 = $ARGV[3]; | |
open my $fh, ">out.txt" or die $!; | |
print $fh "$file1\n\n$file2"; | |
close $fh; | |
print STDERR "diff -u \"$file1\" \"$file2\" | cat"; | |
print `diff -u "$file1" "$file2" | cat`; | |
exit(0); | |
} | |
sub encrypt { | |
my $what = shift; | |
return `echo "$what" | gpg -ea -q --batch --no-tty -r $key_r`; | |
} | |
sub decrypt { | |
my $what = shift; | |
return `echo "$what" | gpg -d -q --batch --no-tty`; | |
} | |
sub tokenize_line { | |
my $line = shift; | |
my @tokens = (); | |
my $in_string = 0; | |
my $escape = 0; | |
my $is_white = 0; | |
my $q = ''; | |
my $buf = ''; | |
CHAR: for my $c (split //, $line) { | |
if ($in_string) { | |
if ($escape) { | |
$escape = 0; | |
} | |
elsif ($c eq '\\') { | |
$escape = 1; | |
} | |
elsif ($c eq $q) { | |
$in_string = 0; | |
$buf .= $q; | |
push @tokens, $buf; | |
$buf = ''; | |
next CHAR; | |
} | |
} | |
elsif ($is_white) { | |
if ($c !~ /\s/) { | |
push @tokens, $buf if length $buf; | |
$buf = ''; | |
$is_white = 0; | |
} | |
} | |
elsif ($c =~ /\s/) { | |
push @tokens, $buf if length $buf; | |
$buf = ''; | |
$is_white = 1; | |
} | |
if ($c eq '"' or $c eq "'") { | |
push @tokens, $buf if length $buf; | |
$buf = ''; | |
$in_string = 1; | |
$q = $c; | |
} | |
$buf .= $c; | |
} | |
push @tokens, $buf if length $buf; | |
return @tokens | |
} | |
LINE: for my $line (<>) { | |
unless ($line =~ /\$\$\s+ENCRYPT\s+(\d+)\s+\$\$/) { | |
print $line; | |
next LINE; | |
} | |
my $token_number = int $1; | |
my @tokens = tokenize_line $line; | |
my $i = 0; | |
TOK: for my $tok (@tokens) { | |
if ($tok !~ /^\s*$/) { | |
if (++$i == $token_number) { | |
if ($cmd eq 'decrypt') { | |
# we want to remove quotes surrounding the text | |
if ($tok =~ /^(["'])(.*?)\1(.*)$/) { | |
my ($q, $txt, $post) = ($1, $2, $3); | |
my $decrypted = $op->($txt); | |
$decrypted =~ s/\n$//; | |
print $decrypted; | |
print $post; | |
} | |
else { | |
print $tok; | |
} | |
} | |
else { | |
print "'"; | |
$tok =~ s/\n$//gm; | |
my $encrypted = $op->($tok); | |
$encrypted =~ s/\n$//; | |
$encrypted =~ s/\n/\\n/gm; | |
print $encrypted; | |
print "'"; | |
} | |
next TOK; | |
} | |
} | |
print $tok; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment