aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTad Fisher <tad@simple.com>2017-03-19 20:58:45 -0700
committerTad Fisher <tad@simple.com>2017-03-19 20:58:45 -0700
commit698ae45a780bcc83d8dadc18aadfb049ec7c127c (patch)
tree146beb2690007dd35aef6cf2e70eaf7bee59c96f
parentd29b61248c87ab29283eb4ccbd037869f0b4df28 (diff)
downloadpass-otp-698ae45a780bcc83d8dadc18aadfb049ec7c127c.tar.gz
pass-otp-698ae45a780bcc83d8dadc18aadfb049ec7c127c.zip
Fix HOTP URI parsing
-rwxr-xr-xotp.bash26
-rwxr-xr-xtest/insert.t2
-rwxr-xr-xtest/validate.t4
3 files changed, 20 insertions, 12 deletions
diff --git a/otp.bash b/otp.bash
index 539fc7e..b95e981 100755
--- a/otp.bash
+++ b/otp.bash
@@ -38,7 +38,7 @@ otp_parse_uri() {
uri="${uri//\`/%60}"
uri="${uri//\"/%22}"
- local pattern='^otpauth:\/\/(totp|hotp)(\/(([^:?]+)?(:([^:?]*))?))?(\?([^#&?]+))(&([^#&?]+))*$'
+ local pattern='^otpauth:\/\/(totp|hotp)(\/(([^:?]+)?(:([^:?]*))?))?\?(.+)$'
[[ "$uri" =~ $pattern ]] || die "Cannot parse OTP key URI: $uri"
otp_uri=${BASH_REMATCH[0]}
@@ -48,24 +48,28 @@ otp_parse_uri() {
otp_accountname=${BASH_REMATCH[6]}
[[ -z $otp_accountname ]] && otp_accountname=${BASH_REMATCH[4]} || otp_issuer=${BASH_REMATCH[4]}
- local parameters=(${BASH_REMATCH[@]:7})
- pattern='^([^?&=]+)(=(.+))$'
- for param in "${parameters[@]}"; do
+ local p=${BASH_REMATCH[7]}
+ local IFS=\&; local params=(${p[@]}); unset IFS
+
+ pattern='^(.+)=(.+)$'
+ for param in "${params[@]}"; do
if [[ "$param" =~ $pattern ]]; then
case ${BASH_REMATCH[1]} in
- secret) otp_secret=${BASH_REMATCH[3]} ;;
- digits) otp_digits=${BASH_REMATCH[3]} ;;
- algorithm) otp_algorithm=${BASH_REMATCH[3]} ;;
- period) otp_period=${BASH_REMATCH[3]} ;;
- counter) otp_counter=${BASH_REMATCH[3]} ;;
- issuer) otp_issuer=${BASH_REMATCH[3]} ;;
+ secret) otp_secret=${BASH_REMATCH[2]} ;;
+ digits) otp_digits=${BASH_REMATCH[2]} ;;
+ algorithm) otp_algorithm=${BASH_REMATCH[2]} ;;
+ period) otp_period=${BASH_REMATCH[2]} ;;
+ counter) otp_counter=${BASH_REMATCH[2]} ;;
+ issuer) otp_issuer=${BASH_REMATCH[2]} ;;
*) ;;
esac
fi
done
[[ -z "$otp_secret" ]] && die "Invalid key URI (missing secret): $otp_uri"
- [[ "$otp_type" == 'hotp' && -z "$otp_counter" ]] && die "Invalid key URI (missing counter): $otp_uri"
+
+ pattern='^[0-9]+$'
+ [[ "$otp_type" == 'hotp' ]] && [[ ! "$otp_counter" =~ $pattern ]] && die "Invalid key URI (missing counter): $otp_uri"
}
otp_build_uri() {
diff --git a/test/insert.t b/test/insert.t
index eb04898..228a8ec 100755
--- a/test/insert.t
+++ b/test/insert.t
@@ -67,7 +67,7 @@ test_expect_success 'Commits insert to git' '
test_pass_init &&
pass git init &&
"$PASS" otp insert totp -s AAAAAAAAAAAAAAAAAAAAA passfile &&
- git log --no-decorate -1 | grep "Add given OTP secret for passfile to store."
+ git log --no-decorate -1 | grep "Add OTP secret for passfile to store."
'
test_done
diff --git a/test/validate.t b/test/validate.t
index 9fbe66c..6d05fdf 100755
--- a/test/validate.t
+++ b/test/validate.t
@@ -12,6 +12,10 @@ test_expect_success 'Parses a complex TOTP URI' '
"$PASS" otp validate otpauth://totp/ACME%20Co:john.doe@email.com?secret=HXDMVJECJJWSRB3HWIZR4IFUGFTMXBOZ&issuer=ACME%20Co&algorithm=SHA1&digits=6&period=30
'
+test_expect_success 'Parses a basic HOTP URI' '
+ "$PASS" otp validate "otpauth://hotp/Example:alice@google.com?secret=JBSWY3DPEHPK3PXP&counter=10&issuer=Example"
+'
+
test_expect_success 'Fails for bogus URL' '
test_must_fail "$PASS" otp validate https://www.google.com/
'