From 9782bbd6f9d5f8be060c2533974408d02f350e3b Mon Sep 17 00:00:00 2001 From: Lukas Metzger Date: Sat, 6 Feb 2016 19:52:23 +0100 Subject: [PATCH] Initial commit: working client --- pdns-client | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++ pdns-keygen | 59 ++++++++++++++++++++++++++ 2 files changed, 176 insertions(+) create mode 100755 pdns-client create mode 100755 pdns-keygen diff --git a/pdns-client b/pdns-client new file mode 100755 index 0000000..a7fe5c9 --- /dev/null +++ b/pdns-client @@ -0,0 +1,117 @@ +#!/bin/bash + +SERVER="" +DOMAIN="" +ID="" +CONTENT="" +KEY="pdns.private.pem" + +exit_error() { + echo "ERROR: ${1}" >&2 + exit 1 +} + +check_dependencies() { + openssl version > /dev/null 2>&1 || exit_error "This script requires an openssl binary." + curl -V > /dev/null 2>&1 || exit_error "This script requires curl." + jq --version > /dev/null 2>&1 || exit_error "This script requires jq." +} + +print_help() { +cat << EOF +Usage: $0 [options] + +Options are: + -h Show this help message + -s SERVER Server where PDNS manager runs + -d DOMAIN Domain name to change + -i ID Id of permission + -c CONTENT Content to set + -k KEY Private key to sign with (default pdns.private.pem) +EOF + +exit 0 +} + +validate_arguments() { + if [[ ! "$SERVER" =~ ^https?://.+/$ ]] + then + exit_error "The server must be in form of https://dns.example.com/ with trailing slash" + fi + if [[ ! "$DOMAIN" =~ ^.+$ ]] + then + exit_error "The domain must be set" + fi + if [[ ! "$ID" =~ ^[0-9]+$ ]] + then + exit_error "The id must be a positive integer" + fi + if [[ ! "$CONTENT" =~ ^.+$ ]] + then + exit_error "The content cannot be empty" + fi + if [[ ! -f "$KEY" ]] + then + exit_error "$KEY is not a file" + fi + + openssl rsa -in "$KEY" -check -noout > /dev/null 2>&1 || exit_error "$KEY ist not a valid rsa private key" +} + +#main +while getopts "s:d:i:c:k:h" opt +do + case $opt in + s) + SERVER="$OPTARG" + ;; + d) + DOMAIN="$OPTARG" + ;; + i) + ID="$OPTARG" + ;; + c) + CONTENT="$OPTARG" + ;; + k) + KEY="$OPTARG" + ;; + h) + print_help + ;; + esac +done + +check_dependencies +validate_arguments + +#Get nonce for signing +read NONCE < <(echo "{}" |\ +jq -c .domain="\"$DOMAIN\"" |\ +jq -c .id="\"$ID\"" |\ +jq -c .content="\"$CONTENT\"" |\ +curl -s --data-binary @- "${SERVER}api/remote.php?getNonce" |\ +jq -r .nonce) + +if [ -z $NONCE ] +then + exit_error "Error when trying to get nonce" +fi + +#Sign request +SIGNATURE=$(echo -n "$DOMAIN$ID$CONTENT$NONCE" | openssl dgst -sha512 -sign $KEY | base64) + +#Send signed request to server +readarray result < <(echo "{}" |\ +jq -c .domain="\"$DOMAIN\"" |\ +jq -c .id="\"$ID\"" |\ +jq -c .content="\"$CONTENT\"" |\ +jq -c .signature="\"$SIGNATURE\"" |\ +curl -s --data-binary @- "${SERVER}api/remote.php?editRecord") + +if [ $(echo "${result[@]}" | jq -r .status) != "success" ] +then + echo "${result[@]}" | jq -r .error + exit 1 +fi diff --git a/pdns-keygen b/pdns-keygen new file mode 100755 index 0000000..7358358 --- /dev/null +++ b/pdns-keygen @@ -0,0 +1,59 @@ +#!/bin/bash + +umask 077 + +KEYNAME="pdns" +KEYSIZE=4096 + +exit_error() { + echo "ERROR: ${1}" >&2 + exit 1 +} + +check_old_key() { + if [ -f "$KEYNAME.private.pem" -o -f "$KEYNAME.public.pem" ] + then + exit_error "An old key is existing here, remove it first!" + fi +} + +check_dependencies() { + openssl version > /dev/null 2>&1 || exit_error "This script requires an openssl binary." +} + +print_help() { +cat << EOF +Usage: $0 [options] + +Options are: + -h Show this help message + -n NAME Set basename of key to NAME (default pdns) + -k SIZE Use SIZE as rsa keysize (default 4096) +EOF + +exit 0 +} + +#main +while getopts "n:s:h" opt +do + case $opt in + n) + KEYNAME=$OPTARG + ;; + s) + KEYSIZE=$OPTARG + ;; + h) + print_help + ;; + esac +done + +check_dependencies +check_old_key + +echo "Generating rsa key pair with $KEYSIZE bits" +openssl genrsa -out "$KEYNAME.private.pem" "$KEYSIZE" >/dev/null 2>&1 || exit_error "Key generation failed." +echo "Extracting public key" +openssl rsa -in "$KEYNAME.private.pem" -out "$KEYNAME.public.pem" -outform PEM -pubout >/dev/null 2>&1 || exit_error "Pubkey extraction failed."