Update the GPL boilerplate with the new address of the FSF.
[freeradius.git] / src / modules / rlm_otp / cardops / cryptocard.c
index 9248d12..cf85fff 100644 (file)
@@ -14,9 +14,9 @@
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  *
- * Copyright 2005 TRI-D Systems, Inc.
+ * Copyright 2005,2006 TRI-D Systems, Inc.
  */
 
 #include <inttypes.h>
@@ -36,14 +36,20 @@ static struct {
   { "cryptocard-d8-rc", CRYPTOCARD_D8_RC },
   { "cryptocard-h7-rc", CRYPTOCARD_H7_RC },
   { "cryptocard-d7-rc", CRYPTOCARD_D7_RC },
+  { "cryptocard-hp-rc", CRYPTOCARD_HP_RC },
+  { "cryptocard-dp-rc", CRYPTOCARD_DP_RC },
   { "cryptocard-h8-es", CRYPTOCARD_H8_ES },
   { "cryptocard-d8-es", CRYPTOCARD_D8_ES },
   { "cryptocard-h7-es", CRYPTOCARD_H7_ES },
   { "cryptocard-d7-es", CRYPTOCARD_D7_ES },
+  { "cryptocard-hp-es", CRYPTOCARD_HP_ES },
+  { "cryptocard-dp-es", CRYPTOCARD_DP_ES },
   { "cryptocard-h8-rs", CRYPTOCARD_H8_RS },
   { "cryptocard-d8-rs", CRYPTOCARD_D8_RS },
   { "cryptocard-h7-rs", CRYPTOCARD_H7_RS },
   { "cryptocard-d7-rs", CRYPTOCARD_D7_RS },
+  { "cryptocard-hp-rs", CRYPTOCARD_HP_RS },
+  { "cryptocard-dp-rs", CRYPTOCARD_DP_RS },
 
   { NULL, 0 }                                  /* end of list */
 };
@@ -70,7 +76,7 @@ cryptocard_name2fm(const char *name, uint32_t *featuremask)
 
 /*
  * Convert an ASCII keystring to a keyblock.
- * Returns 0 on success, non-zero otherwise.
+ * Returns keylen on success, -1 otherwise.
  */
 static int
 cryptocard_keystring2keyblock(const char *keystring,
@@ -97,7 +103,7 @@ __attribute__ ((unused))
 #ifdef __GNUC__
 __attribute__ ((unused))
 #endif
-                      const otp_user_info_t *user_info,
+                      const otp_card_info_t *card_info,
 #ifdef __GNUC__
 __attribute__ ((unused))
 #endif
@@ -108,8 +114,8 @@ __attribute__ ((unused))
                       time_t when,
                       const char *log_prefix)
 {
-  otp_log(OTP_LOG_ERR, "%s: null state not supported for CRYPTOCard",
-          log_prefix);
+  otp_log(OTP_LOG_ERR, "%s: %s: null state not supported for CRYPTOCard",
+          log_prefix, __func__);
   return -1;
 }
 
@@ -120,12 +126,9 @@ __attribute__ ((unused))
  * (-2 rc is for early challenge, N/A for cryptocard.)
  */
 static int
-cryptocard_challenge(const otp_user_info_t *user_info,
-#ifdef __GNUC__
-__attribute__ ((unused))
-#endif
+cryptocard_challenge(const otp_card_info_t *card_info,
                      otp_user_state_t *user_state,
-                     char challenge[OTP_MAX_CHALLENGE_LEN + 1],
+                     unsigned char challenge[OTP_MAX_CHALLENGE_LEN],
 #ifdef __GNUC__
 __attribute__ ((unused))
 #endif
@@ -143,12 +146,9 @@ __attribute__ ((unused))
   unsigned char output[8];
   int i;
 
-  /* CRYPTOCard sync challenges are always 8 bytes. */
-  if (strlen(challenge) != 8)
-    return -1;
-
-  /* run x99 once on the challenge */
-  if (otp_x99_mac(challenge, 8, output, user_info->keyblock, log_prefix))
+  /* run x99 once on the previous challenge */
+  if (otp_x99_mac(challenge, user_state->clen, output, card_info->keyblock,
+                  log_prefix))
     return -1;
 
   /* convert the mac into the next challenge */
@@ -159,7 +159,7 @@ __attribute__ ((unused))
     output[i] |= 0x30;
   }
   (void) memcpy(challenge, output, 8);
-  challenge[8] = '\0';
+  user_state->clen = 8;
 
   return 0;
 }
@@ -183,34 +183,33 @@ __attribute__ ((unused))
  * 5. Truncate the response for 7 digit display modes.
  */
 static int
-cryptocard_response(otp_user_info_t *user_info,
-                    const char challenge[OTP_MAX_CHALLENGE_LEN + 1],
-                    char response[OTP_MAX_RESPONSE_LEN + 1],
+cryptocard_response(otp_card_info_t *card_info,
+                    const unsigned char challenge[OTP_MAX_CHALLENGE_LEN],
+                    size_t len, char response[OTP_MAX_RESPONSE_LEN + 1],
                     const char *log_prefix)
 {
   unsigned char output[8];
-  char l_response[17];
   const char *conversion;
 
   /* Step 1, 2. */
-  if (otp_x99_mac(challenge, strlen(challenge), output,
-                  user_info->keyblock, log_prefix) !=0)
+  if (otp_x99_mac(challenge, len, output,
+                  card_info->keyblock, log_prefix) !=0)
     return 1;
 
   /* Setup for step 4. */
-  if (user_info->featuremask & OTP_CF_DD)
+  if (card_info->featuremask & OTP_CF_DD)
     conversion = otp_cc_dec_conversion;
   else
     conversion = otp_hex_conversion;
 
   /* Step 3, 4. */
-  otp_keyblock2keystring(l_response, output, conversion);
-  (void) memcpy(response, l_response, 8);
-  response[8] = '\0';
+  (void) otp_keyblock2keystring(response, output, 4, conversion);
 
   /* Step 5. */
-  if (user_info->featuremask & OTP_CF_R7)
+  if (card_info->featuremask & OTP_CF_R7)
     (void) memmove(&response[3], &response[4], 5);
+  else if (card_info->featuremask & OTP_CF_RP)
+    response[3] = '-';
 
   return 0;
 }
@@ -221,12 +220,7 @@ cryptocard_response(otp_user_info_t *user_info,
  * Returns 0 if succesful, -1 otherwise.
  */
 static int
-cryptocard_updatecsd(
-#ifdef __GNUC__
-__attribute__ ((unused))
-#endif
-                     const otp_user_info_t *user_info,
-                     otp_user_state_t *user_state,
+cryptocard_updatecsd(otp_user_state_t *user_state,
 #ifdef __GNUC__
 __attribute__ ((unused))
 #endif
@@ -236,11 +230,7 @@ __attribute__ ((unused))
 #endif
                      int twin,
                      int ewin,
-                     int auth_rc,
-#ifdef __GNUC__
-__attribute__ ((unused))
-#endif
-                     const char *log_prefix)
+                     int auth_rc)
 {
   if (auth_rc == OTP_RC_OK)
     user_state->rd[0] = '\0';                          /* reset */
@@ -263,7 +253,7 @@ cryptocard_isconsecutive(
 #ifdef __GNUC__
 __attribute__ ((unused))
 #endif
-                         const otp_user_info_t *user_info,
+                         const otp_card_info_t *card_info,
                          const otp_user_state_t *user_state,
                          int thisewin, const char *log_prefix)
 {
@@ -271,8 +261,8 @@ __attribute__ ((unused))
 
   /* extract the saved rwindow candidate position */
   if (sscanf(user_state->rd, "%" SCNx32, &nextewin) != 1) {
-    otp_log(OTP_LOG_ERR, "%s: %s: invalid rwindow data for [%s]", log_prefix,
-            __func__, user_info->username);
+    otp_log(OTP_LOG_ERR, "%s: %s: invalid rwindow data for [%s]",
+            log_prefix, __func__, card_info->username);
     return 0;
   }
   nextewin++;
@@ -291,7 +281,7 @@ cryptocard_maxtwin(
 #ifdef __GNUC__
 __attribute__ ((unused))
 #endif
-                    const otp_user_info_t *user_info,
+                    const otp_card_info_t *card_info,
 #ifdef __GNUC__
 __attribute__ ((unused))
 #endif
@@ -301,6 +291,19 @@ __attribute__ ((unused))
 }
 
 
+/* return human-readable challenge */
+static char *
+cryptocard_printchallenge(char s[OTP_MAX_CHALLENGE_LEN * 2 + 1],
+                          const unsigned char challenge[OTP_MAX_CHALLENGE_LEN],
+                          size_t len)
+{
+  /* cryptocard challenge is implicitly ASCII */
+  (void) memcpy(s, challenge, len);
+  s[len] = '\0';
+  return s;
+}
+
+
 /* cardops instance */
 static cardops_t cryptocard_cardops = {
   .prefix              = "cryptocard",
@@ -314,6 +317,7 @@ static cardops_t cryptocard_cardops = {
   .updatecsd           = cryptocard_updatecsd,
   .isconsecutive       = cryptocard_isconsecutive,
   .maxtwin             = cryptocard_maxtwin,
+  .printchallenge      = cryptocard_printchallenge,
 };