You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@labs.apache.org by pq...@apache.org on 2009/03/15 03:42:49 UTC
svn commit: r754596 - /labs/orthrus/trunk/src/userdb.c
Author: pquerna
Date: Sun Mar 15 02:42:48 2009
New Revision: 754596
URL: http://svn.apache.org/viewvc?rev=754596&view=rev
Log:
More work on the verification code.
Modified:
labs/orthrus/trunk/src/userdb.c
Modified: labs/orthrus/trunk/src/userdb.c
URL: http://svn.apache.org/viewvc/labs/orthrus/trunk/src/userdb.c?rev=754596&r1=754595&r2=754596&view=diff
==============================================================================
--- labs/orthrus/trunk/src/userdb.c (original)
+++ labs/orthrus/trunk/src/userdb.c Sun Mar 15 02:42:48 2009
@@ -55,10 +55,14 @@
return ORTHRUS_SUCCESS;
}
-typedef struct orthrus_user_t {
- const char *username;
+typedef struct orthrus_challenge_t {
apr_uint32_t sequence;
const char *seed;
+} orthrus_challenge_t;
+
+typedef struct orthrus_user_t {
+ const char *username;
+ orthrus_challenge_t ch;
const char *lastreply;
} orthrus_user_t;
@@ -102,14 +106,14 @@
return orthrus_error_createf(APR_EGENERAL, "userdb corrupted at line %d", lineno);
}
- user->sequence = apr_strtoi64(v, NULL, 10);
+ user->ch.sequence = apr_strtoi64(v, NULL, 10);
v = apr_strtok(NULL, " ", &strtok_state);
if (!v) {
return orthrus_error_createf(APR_EGENERAL, "userdb corrupted at line %d", lineno);
}
- user->seed = apr_pstrdup(ort->pool, v);
+ user->ch.seed = apr_pstrdup(ort->pool, v);
v = apr_strtok(NULL, " ", &strtok_state);
if (!v) {
@@ -142,16 +146,116 @@
return rv;
}
- *challenge = apr_psprintf(pool, "otp-md5 %u %s", user->sequence, user->seed);
+ /* TODO: Configurable algorithms */
+ *challenge = apr_psprintf(pool, "otp-md5 %u %s", user->ch.sequence, user->ch.seed);
+
+ return ORTHRUS_SUCCESS;
+}
+
+static orthrus_error_t* decode_challenge(orthrus_t *ort,
+ const char *challenge,
+ orthrus_challenge_t *ch)
+{
+ char *strtok_state;
+ char *v;
+ char *p = apr_pstrdup(ort->pool, challenge);
+
+ /* len("otp-md5 1 a") = 11 */
+ if (strlen(p) < 11) {
+ return orthrus_error_create(APR_EGENERAL, "challenge string is too small.");
+ }
+
+ p += 4;
+
+ if (strncmp("md5 ", p, 4) != 0) {
+ return orthrus_error_create(APR_ENOTIMPL, "only md5 verification is supported.");
+ }
+
+ p += 4;
+
+ v = apr_strtok(p, " ", &strtok_state);
+
+ if (!v) {
+ return orthrus_error_create(APR_EGENERAL, "invalid challenge string when looking for sequence.");
+ }
+
+ ch->sequence = apr_strtoi64(v, NULL, 10);
+
+ v = apr_strtok(NULL, " ", &strtok_state);
+ if (!v) {
+ return orthrus_error_create(APR_EGENERAL,
+ "invalid challenge string when looking for seed.");
+ }
+
+ ch->seed = apr_pstrdup(ort->pool, v);
+
+ return ORTHRUS_SUCCESS;
+}
+
+static orthrus_error_t* decode_reply(orthrus_t *ort,
+ const char *reply,
+ orthrus_response_t **resp)
+{
+
+ /* TODO: Support Six word dictionary decoding.
+ * (note, its just a SHOULD from the RFC) */
+
+ /* RFC 2289 Section 6.0, "Form of Output":
+ * If a six-word encoded one-time password is valid, it is accepted.
+ * Otherwise, if the one-time password can be interpreted as hexadecimal, and
+ * with that decoding it is valid, then it is accepted.*/
+
+ *resp = apr_pcalloc(ort->pool, sizeof(orthrus_response_t));
return ORTHRUS_SUCCESS;
}
+/* RFC 2289 Section 7.0 "VERIFICATION OF ONE-TIME PASSWORDS":
+ * The server system has a database containing, for each user, the
+ * one-time password from the last successful authentication or the
+ * first OTP of a newly initialized sequence. To authenticate the user,
+ * the server decodes the one-time password received from the generator
+ * into a 64-bit key and then runs this key through the secure hash
+ * function once. If the result of this operation matches the stored
+ * previous OTP, the authentication is successful and the accepted
+ * one-time password is stored for future use.
+ */
+
orthrus_error_t* orthrus_userdb_verify(orthrus_t *ort,
const char *username,
const char *challenge,
const char *reply,
apr_pool_t *pool)
{
+ orthrus_error_t* rv;
+ orthrus_challenge_t ch;
+ orthrus_user_t *user;
+ orthrus_response_t *resp;
+
+ rv = userdb_get_user(ort, username, &user);
+ if (rv) {
+ return rv;
+ }
+
+ rv = decode_challenge(ort, challenge, &ch);
+ if (rv) {
+ return rv;
+ }
+
+
+ if (strcmp(ch.seed, user->ch.seed) != 0) {
+ return orthrus_error_create(APR_EGENERAL, "seed changed between challenge and verification.");
+ }
+
+ if (ch.sequence != user->ch.sequence) {
+ return orthrus_error_create(APR_EGENERAL, "sequence changed between challenge and verification.");
+ }
+
+ rv = decode_reply(ort, reply, &resp);
+
+ if (rv) {
+ return rv;
+ }
+
return orthrus_error_create(APR_ENOTIMPL, "userdb functionality is not complete");
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@labs.apache.org
For additional commands, e-mail: commits-help@labs.apache.org