Simon Josefsson <[email protected]> on Tue, 2013/01/08 21:32:
> Christian Hesse <[email protected]> writes:
> 
> > Hello everybody,
> >
> > some time ago support was added to handles multiple lines for a single
> > user. This works only if the (two factor) password is identical.
> >
> > The attached patch makes liboath try other configurations for the same
> > user if status is OATH_BAD_PASSWORD. Hope this is correct.
> 
> Hi.  Could you give an example two lines and what verification call is
> triggering this problem?  So that can be added to the regression tests.
> 
> Sorry that you just missed the 2.0.2 release, I'll try to get another
> released pulled together soon.

My patch was wrong, it gave some wrong return codes and did not apply against
git. Updated my patch and added the required checks. This compiles and works
(including tests) fine for me.
-- 
Schoene Gruesse
Chris
                         O< ascii ribbon campaign
                   stop html mail - www.asciiribbon.org
diff --git a/liboath/tests/expect.oath b/liboath/tests/expect.oath
index 530c5b5..73a584d 100644
--- a/liboath/tests/expect.oath
+++ b/liboath/tests/expect.oath
@@ -22,3 +22,5 @@ HOTP/E	fiveuser	-	22222222	5	746888	2006-12-07T00:00:00L
 HOTP/E	fiveuser	-	33333333
 HOTP/E	fiveuser	-	44444444	9	893841	2006-12-07T00:00:00L
 HOTP/E	fiveuser	-	55555555	7	730790	2006-12-07T00:00:00L
+HOTP	password	-	0815	2	898463	2006-12-07T00:00:00L
+HOTP	password	test	1630	3	989803	2006-12-07T00:00:00L
diff --git a/liboath/tests/tst_usersfile.c b/liboath/tests/tst_usersfile.c
index 2cc844e..5a40c8c 100644
--- a/liboath/tests/tst_usersfile.c
+++ b/liboath/tests/tst_usersfile.c
@@ -372,6 +372,25 @@ main (void)
       return 1;
     }
 
+  /* Test different tokens with different passwords for one user */
+  rc = oath_authenticate_usersfile (CREDS,
+				    "password", "898463", 5, NULL, &last_otp);
+  if (rc != OATH_OK)
+    {
+      printf ("oath_authenticate_usersfile[28]: %s (%d)\n",
+	      oath_strerror_name (rc), rc);
+      return 1;
+    }
+
+  rc = oath_authenticate_usersfile (CREDS,
+				    "password", "989803", 5, "test", &last_otp);
+  if (rc != OATH_OK)
+    {
+      printf ("oath_authenticate_usersfile[29]: %s (%d)\n",
+	      oath_strerror_name (rc), rc);
+      return 1;
+    }
+
   rc = oath_done ();
   if (rc != OATH_OK)
     {
diff --git a/liboath/tests/users.oath b/liboath/tests/users.oath
index c9cf617..095deab 100644
--- a/liboath/tests/users.oath
+++ b/liboath/tests/users.oath
@@ -22,3 +22,5 @@ HOTP/E	fiveuser	-	22222222
 HOTP/E	fiveuser	-	33333333
 HOTP/E	fiveuser	-	44444444
 HOTP/E	fiveuser	-	55555555
+HOTP	password	-	0815
+HOTP	password	test	1630
diff --git a/liboath/usersfile.c b/liboath/usersfile.c
index 462926d..2f3978d 100644
--- a/liboath/usersfile.c
+++ b/liboath/usersfile.c
@@ -85,6 +85,8 @@ parse_usersfile (const char *username,
 		 char **lineptr, size_t * n, uint64_t * new_moving_factor,
 		 size_t * skipped_users)
 {
+  int bad_password = 0;
+
   *skipped_users = 0;
 
   while (getline (lineptr, n, infh) != -1)
@@ -95,7 +97,7 @@ parse_usersfile (const char *username,
       char secret[32];
       size_t secret_length = sizeof (secret);
       uint64_t start_moving_factor = 0;
-      int rc;
+      int rc = 0;
       char *prev_otp = NULL;
 
       if (p == NULL)
@@ -119,14 +121,26 @@ parse_usersfile (const char *username,
 	  if (strcmp (p, "-") == 0)
 	    {
 	      if (*passwd != '\0')
-		return OATH_BAD_PASSWORD;
+	        {
+		  bad_password = 1;
+		  rc = OATH_BAD_PASSWORD;
+		}
 	    }
 	  else if (strcmp (p, "+") == 0)
 	    {
 	      /* Externally verified. */
 	    }
 	  else if (strcmp (p, passwd) != 0)
-	    return OATH_BAD_PASSWORD;
+	    {
+	      bad_password = 1;
+	      rc = OATH_BAD_PASSWORD;
+	    }
+	  if (rc == OATH_BAD_PASSWORD)
+	    {
+	      (*skipped_users)++;
+	      continue;
+	    }
+	  bad_password = 0;
 	}
 
       /* Read key. */
@@ -210,7 +224,10 @@ parse_usersfile (const char *username,
     }
 
   if (*skipped_users)
-    return OATH_INVALID_OTP;
+    if (bad_password)
+      return OATH_BAD_PASSWORD;
+    else
+      return OATH_INVALID_OTP;
 
   return OATH_UNKNOWN_USER;
 }

Reply via email to