gsasl-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

CVS gsasl/lib/digest-md5


From: gsasl-commit
Subject: CVS gsasl/lib/digest-md5
Date: Sun, 19 Dec 2004 18:38:19 +0100

Update of /home/cvs/gsasl/lib/digest-md5
In directory dopio:/tmp/cvs-serv2163

Modified Files:
        client.c 
Log Message:
Rewrite, unfinished but probably still an improvement.


--- /home/cvs/gsasl/lib/digest-md5/client.c     2004/12/19 02:14:34     1.14
+++ /home/cvs/gsasl/lib/digest-md5/client.c     2004/12/19 17:38:18     1.15
@@ -24,37 +24,42 @@
 # include "config.h"
 #endif
 
+/* Get specification. */
+#include "digest-md5.h"
+
 /* Get malloc, free. */
 #include <stdlib.h>
 
 /* Get memcpy, strlen. */
 #include <string.h>
 
-/* Get specification. */
-#include "digest-md5.h"
+/* Get tools. */
 #include "shared.h"
+
+#include "tokens.h"
 #include "parser.h"
+#include "validate.h"
+#include "printer.h"
+#include "free.h"
 
 /* Get digest_md5_encode, digest_md5_decode. */
 #include "session.h"
 
+#define CNONCE_ENTROPY_BYTES (CNONCE_ENTROPY_BITS / 8)
+
 struct _Gsasl_digest_md5_client_state
 {
   int step;
+  digest_md5_challenge challenge;
+  digest_md5_response response;
+  digest_md5_finish finish;
   char secret[MD5LEN];
-  char *nonce;
-  uint32_t nc;
-  char cnonce[2 * CNONCE_ENTROPY_BITS / 8 + 1];
-  Gsasl_qop qop;
-  Gsasl_cipher cipher;
-  char *authzid;
-  char *digesturi;
-  char response[RESPONSE_LENGTH + 1];
   uint32_t readseqnum, sendseqnum;
   char kic[MD5LEN];
   char kcc[MD5LEN];
   char kis[MD5LEN];
   char kcs[MD5LEN];
+
 };
 typedef struct _Gsasl_digest_md5_client_state _Gsasl_digest_md5_client_state;
 
@@ -62,31 +67,28 @@
 _gsasl_digest_md5_client_start (Gsasl_session * sctx, void **mech_data)
 {
   _Gsasl_digest_md5_client_state *state;
-  Gsasl_ctx *ctx;
+  char nonce[CNONCE_ENTROPY_BYTES];
+  char *p;
+  int rc;
+  size_t i;
+
+  rc = gsasl_nonce (nonce, CNONCE_ENTROPY_BYTES);
+  if (rc != GSASL_OK)
+    return rc;
+
+  rc = gsasl_base64_to (nonce, CNONCE_ENTROPY_BYTES, &p, NULL);
+  if (rc != GSASL_OK)
+    return rc;
 
-  ctx = gsasl_client_ctx_get (sctx);
-  if (ctx == NULL)
-    return GSASL_CANNOT_GET_CTX;
-
-  if (gsasl_client_callback_authentication_id_get (ctx) == NULL)
-    return GSASL_NEED_CLIENT_AUTHENTICATION_ID_CALLBACK;
-
-  if (gsasl_client_callback_password_get (ctx) == NULL)
-    return GSASL_NEED_CLIENT_PASSWORD_CALLBACK;
-
-  state = (_Gsasl_digest_md5_client_state *) malloc (sizeof (*state));
+  state = calloc (1, sizeof (*state));
   if (state == NULL)
-    return GSASL_MALLOC_ERROR;
+    {
+      free (p);
+      return GSASL_MALLOC_ERROR;
+    }
 
-  state->step = 0;
-  state->nonce = NULL;
-  state->nc = 1;
-  state->cipher = 0;
-  state->qop = GSASL_QOP_AUTH;
-  state->authzid = NULL;
-  state->digesturi = NULL;
-  state->readseqnum = 0;
-  state->sendseqnum = 0;
+  state->response.cnonce = p;
+  state->response.nc = 1;
 
   *mech_data = state;
 
@@ -98,690 +100,163 @@
                               void *mech_data,
                               const char *input,
                               size_t input_len,
-                              char **output2, size_t * output2_len)
+                              char **output, size_t * output_len)
 {
   _Gsasl_digest_md5_client_state *state = mech_data;
-  Gsasl_client_callback_authorization_id cb_authorization_id;
-  Gsasl_client_callback_authentication_id cb_authentication_id;
-  Gsasl_client_callback_password cb_password;
-  Gsasl_client_callback_service cb_service;
-  Gsasl_client_callback_qop cb_qop;
-  Gsasl_client_callback_maxbuf cb_maxbuf;
   char *subopts;
   char *value;
-  Gsasl_ctx *ctx;
   int outlen;
-  int res, i;
-  /* FIXME: Remove fixed size buffer. */
-  char output[BUFSIZ];
-  size_t outputlen = BUFSIZ - 1;
-  size_t *output_len = &outputlen;
-
-  *output2 = NULL;
-  *output2_len = 0;
-
-  ctx = gsasl_client_ctx_get (sctx);
-  if (ctx == NULL)
-    return GSASL_CANNOT_GET_CTX;
-
-  cb_qop = gsasl_client_callback_qop_get (ctx);
-  cb_authorization_id = gsasl_client_callback_authorization_id_get (ctx);
-  cb_maxbuf = gsasl_client_callback_maxbuf_get (ctx);
-
-  cb_authentication_id = gsasl_client_callback_authentication_id_get (ctx);
-  if (cb_authentication_id == NULL)
-    return GSASL_NEED_CLIENT_AUTHENTICATION_ID_CALLBACK;
-
-  cb_password = gsasl_client_callback_password_get (ctx);
-  if (cb_password == NULL)
-    return GSASL_NEED_CLIENT_PASSWORD_CALLBACK;
-
-  cb_service = gsasl_client_callback_service_get (ctx);
-  if (cb_service == NULL)
-    return GSASL_NEED_CLIENT_SERVICE_CALLBACK;
-
-  if (*output_len < 1)
-    return GSASL_TOO_SMALL_BUFFER;
-
-  strcpy (output, "");
-  outlen = 0;
-
-#if CLIENT_PRINT_OUTPUT
-  if (input && input_len > 0)
-    fprintf (stderr, "%s\n", input);
-#endif
+  int rc, res, i;
+
+  *output = NULL;
+  *output_len = 0;
 
   switch (state->step)
     {
     case 0:
       state->step++;
       if (input_len == 0)
-       {
-         *output_len = 0;
-         return GSASL_NEEDS_MORE;
-       }
+       return GSASL_NEEDS_MORE;
       /* fall through */
 
     case 1:
       {
-       char **realm = NULL;
-       size_t nrealm = 0;
-       long maxbuf = -1;
-       char *zinput = NULL;
-
-       if (input == NULL || input_len == 0)
+       if (digest_md5_parse_challenge (input, input_len,
+                                       &state->challenge) < 0)
          return GSASL_MECHANISM_PARSE_ERROR;
 
-       zinput = malloc (input_len + 1);
-       if (zinput == NULL)
-         return GSASL_MALLOC_ERROR;
-       memcpy (zinput, input, input_len);
-       zinput[input_len] = '\0';
-
-       gsasl_nonce (state->cnonce, CNONCE_ENTROPY_BITS / 8);
-       for (i = 0; i < CNONCE_ENTROPY_BITS / 8; i++)
-         {
-           state->cnonce[CNONCE_ENTROPY_BITS / 8 + i] =
-             HEXCHAR (state->cnonce[i]);
-           state->cnonce[i] = HEXCHAR (state->cnonce[i] >> 4);
-         }
-       state->cnonce[2 * CNONCE_ENTROPY_BITS / 8] = '\0';
-
-       subopts = zinput;
-       while (*subopts != '\0')
-         switch (digest_md5_getsubopt (&subopts, digest_challenge_opts,
-                                       &value))
-           {
-           case CHALLENGE_REALM:
-             if (nrealm == 0)
-               realm = (char **) malloc (sizeof (*realm));
-             else
-               realm = realloc (realm, (nrealm + 1) * sizeof (*realm));
-             if (realm == NULL)
-               {
-                 res = GSASL_MALLOC_ERROR;
-                 goto done;
-               }
-             realm[nrealm] = strdup (value);
-             nrealm++;
-             break;
-
-           case CHALLENGE_NONCE:
-             if (state->nonce != NULL)
-               {
-                 res = GSASL_MECHANISM_PARSE_ERROR;
-                 goto done;
-               }
-             state->nonce = strdup (value);
-             break;
-
-           case CHALLENGE_QOP:
-             {
-               char *subsubopts;
-               char *val;
-
-               state->qop = 0;
-               subsubopts = value;
-               while (*subsubopts != '\0')
-                 switch (digest_md5_getsubopt (&subsubopts, qop_opts, &val))
-                   {
-                   case QOP_AUTH_OPTION:
-                     state->qop |= GSASL_QOP_AUTH;
-                     break;
-
-                   case QOP_AUTH_INT_OPTION:
-                     state->qop |= GSASL_QOP_AUTH_INT;
-                     break;
-
-                   case QOP_AUTH_CONF_OPTION:
-                     state->qop |= GSASL_QOP_AUTH_CONF;
-                     break;
-
-                   default:
-                     /* Ignore unknown qop */
-                     break;
-                   }
-             }
-             break;
-
-           case CHALLENGE_STALE:
-             printf ("XXX stale: %s\n", value);
-             break;
-
-           case CHALLENGE_MAXBUF:
-             /* draft-ietf-sasl-rfc2831bis-02.txt:
-              * server_maxbuf ("maximal ciphertext buffer size")
-              * A number indicating the size of the largest buffer
-              * the server is able to receive when using "auth-int"
-              * or "auth-conf". The value MUST be bigger than 16 and
-              * smaller or equal to 16777215 (i.e.  2**24-1). If this
-              * directive is missing, the default value is
-              * 65536. This directive may appear at most once; if
-              * multiple instances are present, the client MUST abort
-              * the authentication exchange.
-              */
-             if (maxbuf != -1)
-               {
-                 res = GSASL_MECHANISM_PARSE_ERROR;
-                 goto done;
-               }
-             maxbuf = strtol (value, NULL, 10);
-             if (maxbuf < MAXBUF_MIN || maxbuf > MAXBUF_MAX)
-               {
-                 res = GSASL_MECHANISM_PARSE_ERROR;
-                 goto done;
-               }
-             break;
-
-           case CHALLENGE_CHARSET:
-             if (strcmp (DEFAULT_CHARSET, value) != 0)
-               {
-                 res = GSASL_MECHANISM_PARSE_ERROR;
-                 goto done;
-               }
-             break;
-
-           case CHALLENGE_ALGORITHM:
-             if (strcmp (DEFAULT_ALGORITHM, value) != 0)
-               {
-                 res = GSASL_MECHANISM_PARSE_ERROR;
-                 goto done;
-               }
-             break;
-
-           case CHALLENGE_CIPHER:
-             {
-               char *subsubopts;
-               char *val;
-
-               if (state->cipher)
-                 {
-                   res = GSASL_MECHANISM_PARSE_ERROR;
-                   goto done;
-                 }
-
-               subsubopts = value;
-               while (*subsubopts != '\0')
-                 switch (digest_md5_getsubopt (&subsubopts, cipher_opts, &val))
-                   {
-                   case CIPHER_DES_OPTION:
-                     state->cipher |= GSASL_CIPHER_DES;
-                     break;
-
-                   case CIPHER_3DES_OPTION:
-                     state->cipher |= GSASL_CIPHER_3DES;
-                     break;
-
-                   case CIPHER_RC4_OPTION:
-                     state->cipher |= GSASL_CIPHER_RC4;
-                     break;
-
-                   case CIPHER_RC4_40_OPTION:
-                     state->cipher |= GSASL_CIPHER_RC4_40;
-                     break;
-
-                   case CIPHER_RC4_56_OPTION:
-                     state->cipher |= GSASL_CIPHER_RC4_56;
-                     break;
-
-                   case CIPHER_AES_OPTION:
-                     state->cipher |= GSASL_CIPHER_AES;
-                     break;
-
-                   default:
-                     /* Ignoring unknown cipher. */
-                     break;
-                   }
-             }
-             break;
-
-           default:
-             /* Ignoring unknown parameter. */
-             break;
-           }
-       if (state->qop == 0 || state->nonce == NULL ||
-           (state->qop & GSASL_QOP_AUTH_CONF &&
-            !(state->cipher & GSASL_CIPHER_3DES)))
-         {
-           res = GSASL_MECHANISM_PARSE_ERROR;
-           goto done;
-         }
-
-       if (cb_qop)
-         state->qop = cb_qop (sctx, state->qop);
+       /* FIXME: How to let application know of remaining realms?
+          One idea, add a GSASL_REALM_COUNT property, and have the
+          GSASL_REALM be that many concatenated zero terminated realm
+          strings.  Slightly hackish, though.  Another cleaner
+          approach would be to add gsasl_property_set_array and
+          gsasl_property_get_array APIs, for those properties that
+          may be used multiple times. */
+       if (state->challenge.nrealms > 0)
+         gsasl_property_set (sctx, GSASL_REALM, state->challenge.realms[0]);
        else
-         state->qop = GSASL_QOP_AUTH;
+         gsasl_property_set (sctx, GSASL_REALM, NULL);
 
-       if (maxbuf == -1)
-         maxbuf = MAXBUF_DEFAULT;
+       /* Create response token. */
+       state->response.utf8 = 1;
 
-       if (cb_authorization_id)
-         {
-           size_t authzidlen;
+       state->response.qop = 2;
 
-           res = cb_authorization_id (sctx, NULL, &authzidlen);
-           if (res != GSASL_OK)
-             goto done;
-           state->authzid = (char *) malloc (authzidlen + 1);
-           if (state->authzid == NULL)
-             {
-               res = GSASL_MALLOC_ERROR;
-               goto done;

[557 lines skipped]





reply via email to

[Prev in Thread] Current Thread [Next in Thread]