Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for git https credentials #23

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
*
!index.js
!ONVAULT
!package.json
!credentials
3 changes: 2 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
FROM mhart/alpine-node:0.10

RUN mkdir -p /vault /usr/src/app
RUN mkdir -p /vault /vault/store /usr/src/app

WORKDIR /usr/src/app
COPY package.json /usr/src/app/
RUN npm install
COPY . /usr/src/app/
RUN ln -s /usr/src/app/credentials /usr/bin/credentials

EXPOSE 3000
VOLUME /vault
Expand Down
46 changes: 41 additions & 5 deletions ONVAULT
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ log () {
echo -e "${GREEN}[Dockito Vault]${NC} $@"
}

# don't go through proxy for accessing vault
no_proxy_old="$no_proxy"
export no_proxy="$VAULT_HOST"

if ! curl -s "${VAULT_URI}/_ping"; then
COUNTER=0
echo 'Waiting 10s for dockito/vault to be ready...'
Expand All @@ -43,28 +47,60 @@ if curl -s "${VAULT_URI}/_ping"; then
cp -r ~/.ssh/* $tmp_ssh_vault
fi

log "Downloading private keys..."
log "Downloading private keys and git credentials ..."
curl -s "${VAULT_URI}/ssh.tgz" | tar -C ~/.ssh/ -zxf -
chown `whoami` ~/.ssh/*
chmod 600 ~/.ssh/*
chown -f `whoami` ~/.ssh/* || true
chmod -f 600 ~/.ssh/* || true

log "Using ssh key: $VAULT_SSH_KEY"
if [ ! -f ~/.ssh/$VAULT_SSH_KEY ]; then
log "Did not find ssh key: $VAULT_SSH_KEY"
else
log "Using ssh key: $VAULT_SSH_KEY"
fi
if [[ "$VAULT_SSH_KEY" != "id_rsa" ]]; then
# configure the ssh to any host to use this ssh key
echo -e "\nHost *\nIdentityFile ~/.ssh/$VAULT_SSH_KEY" >> ~/.ssh/config
fi

# download git credential store to temporary location
tmp_git_credential_store=`mktemp ~/.git-credentials-XXXXXX`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have removed the mktemp from the script to allow using it with Linux distros without this command.
Please take a look at c202988.

curl -s "${VAULT_URI}/git-credentials" > "$tmp_git_credential_store"

# check number of credentials (== non-blank lines) for seeing if something is wrong
credential_count=`cat "$tmp_git_credential_store" | sed '/^\s*$/d' | wc -l`
if [ $credential_count -eq 0 ]; then
log "Did not find any git https credentials"
else
log "Using $credential_count git https credential(s)"
fi

# configure git
git_config_old_credential_helper=`git config --global credential.helper` || true
git_config_old_core_askpass=`git config --global core.askpass` || true
git config --global credential.helper "store --file=$tmp_git_credential_store"
git config --global core.askpass true

# restore 'no_proxy' for executing the actual command
export no_proxy="$no_proxy_old"

log "Executing command: $@"
eval $@

log "Removing private keys..."
log "Removing private keys and git credentials..."
rm -rf ~/.ssh/*

# copying backup to ssh directory
if [[ -n "$ssh_backup_enabled" ]]; then
cp -r $tmp_ssh_vault/* ~/.ssh
rm -rf $tmp_ssh_vault
fi

rm $tmp_git_credential_store

# restoring old setting
git config --global credential.helper "$git_config_old_credential_helper"
git config --global core.askpass "$git_config_old_core_askpass"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to self: I need to test this "restoring" of the git config.


else
log "ERROR: Start the dockito/vault container before using ONVAULT!"
log "ex: docker run -d -p ${VAULT_HOST}:14242:3000 -v ~/.ssh:/vault/.ssh dockito/vault"
Expand Down
127 changes: 127 additions & 0 deletions credentials
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
#!/bin/sh

# allow overriding location of credential store
: ${CREDENTIALFILE:=/vault/store/git-credentials}

usage () {
echo "Usage:
$(basename $0) set URL
$(basename $0) remove URL
$(basename $0) list
$(basename $0) clear

Examples:
$(basename $0) set github.com
$(basename $0) set gitlab.com/foo/bar
$(basename $0) remove github.com
"
}

# parse arguments
while [ $# -ge 1 ]; do
case "$1" in
set|remove)
if [ $# -eq 2 ]; then
CMD="credentials_$1 $2"
shift
fi
break
;;
list|clear)
CMD="credentials_$1"
break
;;
-h|--help)
usage
exit 0
;;
*)
usage
exit 1
;;
esac

shift
done

if [ $# -ne 1 ] || [ -z "$CMD" ]; then
usage
exit 1
fi

# helper to url-encode username and password using javascript
# proper escaping for username & password, see: https://gist.github.com/pierrevalade/6025241
encodeurl () {
node <<EOF
var escape = function(str) {
return encodeURIComponent(str).replace(/[!*()']/g, function(character) {
return '%' + character.charCodeAt(0).toString(16);
});
};
console.log(escape('$1'))
EOF
}

mask_passwords () {
# replace passwords with ****** and discard non-matching lines
sed -n 's|^\(.*://.*:\)\(.*\)\(@.*\)$|\1******\3|p'
}

credentials_remove () {
# remove leading https://
URL="$( echo "$1" | sed -e 's#^.*://##' )"

# remove existing entry
matching=`grep "@$URL\$" "$CREDENTIALFILE" 2>/dev/null`
if [ -n "$matching" ]; then
tempfile=`mktemp -t git-credentials-XXXXXX`
grep -v "@$URL\$" "$CREDENTIALFILE" > "$tempfile"
mv "$tempfile" "$CREDENTIALFILE"
else
echo "No credentials for '$URL'"
exit 1
fi
}

credentials_set () {
# remove leading https://
URL="$( echo "$1" | sed -e 's#^.*://##' )"

# remove existing entry
matching=`grep "@$URL\$" "$CREDENTIALFILE" 2>/dev/null`
if [ -n "$matching" ]; then
echo "Removing existing entries:"
echo "$matching" | mask_passwords
read -p "Continue? [yN]: " CONFIRM
if ! [ "$CONFIRM" = "y" ]; then
exit 1
fi
credentials_remove $URL
echo ""
fi

echo "Adding credentials for 'https://$URL'."
read -p "Username: " USER
read -p "Password: " -s PASSWORD
echo ""

USER=`encodeurl "$USER"`
PASSWORD=`encodeurl "$PASSWORD"`

echo "https://$USER:$PASSWORD@$URL" >> "$CREDENTIALFILE"
chmod 600 "$CREDENTIALFILE"
}

credentials_list () {
if [ -f "$CREDENTIALFILE" ]; then
# mask passwords and sort by URL (which starts after the "@")
cat "$CREDENTIALFILE" | mask_passwords | sort -k 2 -t "@"
fi
}

credentials_clear () {
echo "" > "$CREDENTIALFILE"
}


$CMD
23 changes: 22 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ var express = require('express'),
fs = require('fs'),
exec = require('child_process').exec,
mime = require('mime'),
path = require('path');
path = require('path'),
touch = require("touch"),
mkdirp = require('mkdirp');


var host = process.env.HTTP_HOST || '0.0.0.0';
Expand All @@ -21,6 +23,7 @@ app.get('/_ping', function (req, res) {
Bundle containing all the user's private keys and ssh configuration
*/
app.get('/ssh.tgz', function (req, res) {
mkdirp("/vault/.ssh");
exec('mktemp -q /tmp/ssh.XXXXXX', function (err, stdout) {
var file = stdout.match(/(.+)/)[0];

Expand All @@ -33,11 +36,29 @@ app.get('/ssh.tgz', function (req, res) {

var filestream = fs.createReadStream(file);
filestream.pipe(res);
fs.unlink(file)
});
});
});


/**
Route to get the credenial store
*/
app.get('/git-credentials', function (req, res) {
var file = '/vault/store/git-credentials';
touch(file);
var filename = path.basename(file);
var mimetype = mime.lookup(file);

res.setHeader('Content-disposition', 'attachment; filename=' + filename);
res.setHeader('Content-type', mimetype);

var filestream = fs.createReadStream(file);
filestream.pipe(res);
});


/**
Route to get the ONVAULT utility to be used during build
*/
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
"license": "ISC",
"dependencies": {
"express": "^4.12.3",
"mime": "^1.3.4"
"mime": "^1.3.4",
"touch": "^1.0.0",
"mkdirp": "^0.5.1"
}
}