[Top][All Lists]
[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]
- CVS gsasl/lib/digest-md5, (continued)
- CVS gsasl/lib/digest-md5, gsasl-commit, 2004/12/19
- CVS gsasl/lib/digest-md5, gsasl-commit, 2004/12/19
- CVS gsasl/lib/digest-md5, gsasl-commit, 2004/12/19
- CVS gsasl/lib/digest-md5, gsasl-commit, 2004/12/19
- CVS gsasl/lib/digest-md5, gsasl-commit, 2004/12/19
- CVS gsasl/lib/digest-md5, gsasl-commit, 2004/12/19
- CVS gsasl/lib/digest-md5, gsasl-commit, 2004/12/19
- CVS gsasl/lib/digest-md5, gsasl-commit, 2004/12/19
- CVS gsasl/lib/digest-md5, gsasl-commit, 2004/12/19
- CVS gsasl/lib/digest-md5, gsasl-commit, 2004/12/19
- CVS gsasl/lib/digest-md5,
gsasl-commit <=
- CVS gsasl/lib/digest-md5, gsasl-commit, 2004/12/19
- CVS gsasl/lib/digest-md5, gsasl-commit, 2004/12/19
- CVS gsasl/lib/digest-md5, gsasl-commit, 2004/12/19
- CVS gsasl/lib/digest-md5, gsasl-commit, 2004/12/19
- CVS gsasl/lib/digest-md5, gsasl-commit, 2004/12/19
- CVS gsasl/lib/digest-md5, gsasl-commit, 2004/12/19
- CVS gsasl/lib/digest-md5, gsasl-commit, 2004/12/19
- CVS gsasl/lib/digest-md5, gsasl-commit, 2004/12/19
- CVS gsasl/lib/digest-md5, gsasl-commit, 2004/12/19
- CVS gsasl/lib/digest-md5, gsasl-commit, 2004/12/19