aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTad Fisher <tadfisher@gmail.com>2022-02-12 19:15:05 -0800
committerTad Fisher <129148+tadfisher@users.noreply.github.com>2022-02-12 19:20:15 -0800
commit3ba564ca9f2c5d894a9ef7ef6b827d95e21d2104 (patch)
tree94c81fac802f67569bf52cd4661766294a02cec6
parent1b30683e9574965ff3bbff12f69e8eede9c99540 (diff)
Handle otpauth:// URIs with port numbers
-rwxr-xr-xotp.bash4
-rwxr-xr-xtest/code.t20
-rwxr-xr-xtest/insert.t8
-rwxr-xr-xtest/validate.t15
4 files changed, 44 insertions, 3 deletions
diff --git a/otp.bash b/otp.bash
index 041fb31..a0688d2 100755
--- a/otp.bash
+++ b/otp.bash
@@ -49,7 +49,7 @@ otp_parse_uri() {
uri="${uri//\`/%60}"
uri="${uri//\"/%22}"
- local pattern='^otpauth:\/\/(totp|hotp)(\/(([^:?]+)?(:([^:?]*))?))?\?(.+)$'
+ local pattern='^otpauth:\/\/(totp|hotp)(\/(([^:?]+)?(:([^:?]*))?)(:([0-9]+))?)?\?(.+)$'
[[ "$uri" =~ $pattern ]] || die "Cannot parse OTP key URI: $uri"
otp_uri=${BASH_REMATCH[0]}
@@ -60,7 +60,7 @@ otp_parse_uri() {
[[ -z $otp_accountname ]] && otp_accountname=$(urldecode "${BASH_REMATCH[4]}") || otp_issuer=$(urldecode "${BASH_REMATCH[4]}")
[[ -z $otp_accountname ]] && die "Invalid key URI (missing accountname): $otp_uri"
- local p=${BASH_REMATCH[7]}
+ local p=${BASH_REMATCH[9]}
local params
local IFS=\&; read -r -a params < <(echo "$p") ; unset IFS
diff --git a/test/code.t b/test/code.t
index 19b4754..1752d77 100755
--- a/test/code.t
+++ b/test/code.t
@@ -65,4 +65,24 @@ EOF
[[ $("$PASS" show passfile) == "$expected" ]]
'
+test_expect_success 'Generates TOTP code for URI with port number' '
+ uri="otpauth://totp/Example:alice@domain.com:443?secret=JBSWY3DPEHPK3PXP&issuer=Example"
+
+ test_pass_init &&
+ "$PASS" otp insert passfile <<< "$uri" &&
+ code=$("$PASS" otp passfile) &&
+ [[ ${#code} -eq 6 ]]
+'
+
+test_expect_success 'Generates HOTP code for URI with port number' '
+ uri="otpauth://hotp/Example:alice@google.com:443?secret=JBSWY3DPEHPK3PXP&counter=10&issuer=Example"
+ inc="otpauth://hotp/Example:alice@google.com:443?secret=JBSWY3DPEHPK3PXP&counter=11&issuer=Example"
+
+ test_pass_init &&
+ "$PASS" otp insert passfile <<< "$uri" &&
+ code=$("$PASS" otp passfile) &&
+ [[ ${#code} -eq 6 ]] &&
+ [[ $("$PASS" otp uri passfile) == "$inc" ]]
+'
+
test_done
diff --git a/test/insert.t b/test/insert.t
index 938a6dd..b9a3009 100755
--- a/test/insert.t
+++ b/test/insert.t
@@ -157,4 +157,12 @@ test_expect_success 'Allow multiple levels in path prefix' '
echo [[ $("$PASS" show totp/pass-test/Example/alice@google.com) == "$uri" ]]
'
+test_expect_success 'Insert TOTP URI with port number' '
+ uri="otpauth://totp/Example:alice@google.com:443?secret=JBSWY3DPEHPK3PXP&issuer=Example"
+
+ test_pass_init &&
+ "$PASS" otp insert passfile <<< "$uri" &&
+ [[ $("$PASS" show passfile) == "$uri" ]]
+'
+
test_done
diff --git a/test/validate.t b/test/validate.t
index 6d05fdf..13c6049 100755
--- a/test/validate.t
+++ b/test/validate.t
@@ -5,7 +5,8 @@ export test_description='Tests pass otp URI parsing'
. ./setup.sh
test_expect_success 'Parses a basic TOTP URI' '
- "$PASS" otp validate "otpauth://totp/Example:alice@google.com?secret=JBSWY3DPEHPK3PXP&issuer=Example"
+ "$PASS" otp validate "otpauth://totp/Example:alice@google.com?secret=JBSWY3DPEHPK3PXP&issuer=Example"
+ echo $otp_type
'
test_expect_success 'Parses a complex TOTP URI' '
@@ -28,4 +29,16 @@ test_expect_success 'Fails for missing counter' '
test_must_fail "$PASS" otp validate otpauth://hotp?secret=HXDMVJECJJWSRB3HWIZR4IFUGFTMXBOZ
'
+test_expect_success 'Parses TOTP URI with port number' '
+ "$PASS" otp validate "otpauth://totp/Example:alice@google.com:443?secret=JBSWY3DPEHPK3PXP&issuer=Example"
+'
+
+test_expect_success 'Parses a complex TOTP URI with port number' '
+ "$PASS" otp validate otpauth://totp/ACME%20Co:john.doe@email.com:443?secret=HXDMVJECJJWSRB3HWIZR4IFUGFTMXBOZ&issuer=ACME%20Co&algorithm=SHA1&digits=6&period=30
+'
+
+test_expect_success 'Parses a HOTP URI with port umber' '
+ "$PASS" otp validate "otpauth://hotp/Example:alice@google.com:443?secret=JBSWY3DPEHPK3PXP&counter=10&issuer=Example"
+'
+
test_done