From 698ae45a780bcc83d8dadc18aadfb049ec7c127c Mon Sep 17 00:00:00 2001 From: Tad Fisher Date: Sun, 19 Mar 2017 20:58:45 -0700 Subject: Fix HOTP URI parsing --- otp.bash | 26 +++++++++++++++----------- test/insert.t | 2 +- test/validate.t | 4 ++++ 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/ ' -- cgit v1.2.3