Skip to content

Instantly share code, notes, and snippets.

@orangeblock
Last active May 13, 2023 16:52
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save orangeblock/15ee8e3cb304a4046082b422adaaf5fb to your computer and use it in GitHub Desktop.
GitHub webhook listener, using netcat and bash. `listen.sh` and `handler.sh` must be in the same directory. Start with `./listen.sh <port> <path-to-script> [<endpoint>]`. All files (including scripts) must be executable.
#!/bin/bash
# parse endpoint (only works for POST)
read request
url="${request#POST }"
url="${url% HTTP/*}"
# change this!!!
secret="top-secret"
endpoint=${2:-/}
hmac=
digest=
clen=
# parse http headers
while [ 1 ]; do
read header
[[ "$header" =~ 'X-Hub-Signature' ]] && hmac=$(echo $header | cut -d= -f2 | tr -d ' \n\r');
[[ "$header" =~ 'Content-Length' ]] && clen=$(echo $header | cut -d: -f2 | tr -d ' \n\r');
[[ "$header" == $'\r' ]] && break;
done
# read http payload
read -r -t 10 -n $clen payload
echo -e "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\nOK\r\n\r\n"
# calculate sha1-hmac digest
digest=$(echo -n $payload | openssl sha1 -hmac $secret | cut -d= -f2 | tr -d ' \n')
# $1 is a script to execute
# $2 is endpoint to check for (default /)
[[ ! -z "$1" ]] && [[ $url == $endpoint ]] && [[ $hmac == $digest ]] && $1 "$payload"
# do some logging
echo -e "$(date)\t$hmac\t$digest\t$endpoint\t$url" >> /var/log/webhook.log
#!/bin/bash
# Using temporary named pipes to simulate the -e option in netcat-traditional.
pipe=/tmp/pipe
function cleanup {
rm -f $pipe;
}
trap cleanup EXIT
[[ -e $pipe ]] || mkfifo $pipe;
while [ 1 ]; do
nc -l $1 0<$pipe | ./$(dirname "$0")/handler.sh $2 $3 1>$pipe;
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment