The user callback strcmp_otp may need to return an error rather than
just rejecting an OTP value.
response = 0: OTP accepted
response > 0: OTP mismatch
response < 0: internal failure (e.g. memory allocation), don't try again
I propose the patch below to allow this
The callback could potentially put details of the error in the
strcmp_handle, for use by user code
diff --git a/liboath/hotp.c b/liboath/hotp.c
index 00c5b20..6647ce6 100644
--- a/liboath/hotp.c
+++ b/liboath/hotp.c
@@ -192,8 +192,10 @@ oath_hotp_validate_callback (const char *secret,
if (rc != OATH_OK)
return rc;
- if (strcmp_otp (strcmp_handle, tmp_otp) == 0)
+ if ((rc = strcmp_otp (strcmp_handle, tmp_otp)) == 0)
return iter;
+ if (rc < 0)
+ return OATH_STRCMP_ERROR;
}
while (window - iter++ > 0);
diff --git a/liboath/oath.h.in b/liboath/oath.h.in
index a934828..050ee34 100644
--- a/liboath/oath.h.in
+++ b/liboath/oath.h.in
@@ -79,6 +79,7 @@
* @OATH_FILE_RENAME_ERROR: System error when renaming file
* @OATH_FILE_UNLINK_ERROR: System error when removing file
* @OATH_TIME_ERROR: System error for time manipulation
+ * @OATH_STRCMP_ERROR: A strcmp callback returned an error
*
* Return codes for OATH functions. All return codes are negative
* except for the successful code OATH_OK which are guaranteed to be
@@ -107,7 +108,8 @@ typedef enum
OATH_FILE_LOCK_ERROR = -15,
OATH_FILE_RENAME_ERROR = -16,
OATH_FILE_UNLINK_ERROR = -17,
- OATH_TIME_ERROR = -18
+ OATH_TIME_ERROR = -18,
+ OATH_STRCMP_ERROR = -19
} oath_rc;
/* Global */
@@ -163,7 +165,8 @@ oath_hotp_validate (const char *secret,
* test_otp OTP using the same hash, and then compare the results.
*
* Return value: 0 if and only if @test_otp is identical to the OTP to
- * be validated.
+ * be validated. Negative value if an internal failure occurs.
+ * Positive value if the test_otp simply doesn't match.
*
* Since: 1.6.0
**/
diff --git a/liboath/totp.c b/liboath/totp.c
index 70a92c8..d414622 100644
--- a/liboath/totp.c
+++ b/liboath/totp.c
@@ -302,12 +302,14 @@ oath_totp_validate2_callback (const char *secret,
if (rc != OATH_OK)
return rc;
- if (strcmp_otp (strcmp_handle, tmp_otp) == 0)
+ if ((rc = (strcmp_otp (strcmp_handle, tmp_otp)) == 0)
{
if (otp_pos)
*otp_pos = -iter;
return iter;
}
+ if (rc < 0)
+ return OATH_STRCMP_ERROR;
}
}
while (window - iter++ > 0);