[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: |
Sat, 18 Dec 2004 23:57:22 +0100 |
Update of /home/cvs/gsasl/lib/digest-md5
In directory dopio:/tmp/cvs-serv30343
Modified Files:
test-parser.c parser.h parser.c
Log Message:
Add.
--- /home/cvs/gsasl/lib/digest-md5/test-parser.c 2004/12/17 03:41:49
1.1
+++ /home/cvs/gsasl/lib/digest-md5/test-parser.c 2004/12/18 22:57:21
1.2
@@ -27,34 +27,99 @@
int
main (int argc, char *argv[])
{
- digest_md5_finish tmp;
+ digest_md5_challenge c;
+ digest_md5_response r;
+ digest_md5_finish f;
int rc;
{
- char *token = "rspauth=\"4711\"";
+ char *token = "nonce=4711, foo=bar";
- rc = digest_md5_parse_finish (token, &tmp);
+ printf ("`%s': ", token);
+ rc = digest_md5_parse_challenge (token, &c);
if (rc == 0)
- printf ("`%s' -> `%s'? %s\n", token, tmp.rspauth,
- strcmp ("4711", tmp.rspauth) == 0 ? "ok" : "FAILURE");
+ printf ("nonce `%s': %s", c.nonce,
+ strcmp ("4711", c.nonce) == 0 ? "PASS" : "FAILURE");
else
- printf ("FAILURE\n");
+ printf ("FAILURE");
+ printf ("\n");
}
{
- char *token = "rspauth=\"4711\", foo=bar";
+ char *token = "bar=foo, foo=bar";
- rc = digest_md5_parse_finish (token, &tmp);
+ printf ("`%s': ", token);
+ rc = digest_md5_parse_challenge (token, &c);
if (rc == 0)
- printf ("FAILURE\n");
+ printf ("FAILURE");
else
- printf ("`%s' -> invalid? ok\n", token);
+ printf ("PASS");
+ printf ("\n");
+ }
+
+ {
+ char *token = "realm=foo, realm=bar, nonce=42";
+
+ printf ("`%s': ", token);
+ rc = digest_md5_parse_challenge (token, &c);
+ if (rc == 0)
+ {
+ if (c.nrealms == 2)
+ printf ("realms `%s', `%s' PASS", c.realms[0], c.realms[1]);
+ else
+ printf ("nrealms %d != 2", c.nrealms);
+ }
+ else
+ printf ("FAILURE");
+ printf ("\n");
+ }
+
+ /* Response */
+
+ {
+ char *token = "bar=foo, foo=bar";
+
+ printf ("response `%s': ", token);
+ rc = digest_md5_parse_response (token, &r);
+ if (rc == 0)
+ printf ("FAILURE");
+ else
+ printf ("PASS");
+ printf ("\n");
+ }
+
+ {
+ char *token = "username=jas, nonce=42, cnonce=4711, nc=00000001, "
+ "digest-uri=foo, response=apa";
+
+ printf ("response `%s': ", token);
+ rc = digest_md5_parse_response (token, &r);
+ if (rc == 0)
+ printf ("username `%s', nonce `%s', cnonce `%s',"
+ " nc %08lx, digest-uri `%s', response `%s': PASS",
+ r.username, r.nonce, r.cnonce, r.nc, r.digesturi, r.response);
+ else
+ printf ("FAILURE");
+ printf ("\n");
+ }
+
+ /* Auth-response, finish. */
+
+ {
+ char *token = "rspauth=\"4711\"";
+
+ rc = digest_md5_parse_finish (token, &f);
+ if (rc == 0)
+ printf ("`%s' -> `%s'? %s\n", token, f.rspauth,
+ strcmp ("4711", f.rspauth) == 0 ? "ok" : "FAILURE");
+ else
+ printf ("FAILURE\n");
}
{
- char *token = "rspauth=4711, foo=bar";
+ char *token = "bar=foo, foo=bar";
- rc = digest_md5_parse_finish (token, &tmp);
+ rc = digest_md5_parse_finish (token, &f);
if (rc == 0)
printf ("FAILURE\n");
else
--- /home/cvs/gsasl/lib/digest-md5/parser.h 2004/12/17 03:41:49 1.1
+++ /home/cvs/gsasl/lib/digest-md5/parser.h 2004/12/18 22:57:21 1.2
@@ -98,13 +98,13 @@
char *realm;
char *nonce;
char *cnonce;
- unsigned long noncecount;
+ unsigned long nc;
char *qop;
char *digesturi;
char *response;
unsigned long clientmaxbuf;
int utf8;
- int cipher;
+ char *cipher;
char *authzid;
};
typedef struct digest_md5_response digest_md5_response;
--- /home/cvs/gsasl/lib/digest-md5/parser.c 2004/12/17 03:41:49 1.1
+++ /home/cvs/gsasl/lib/digest-md5/parser.c 2004/12/18 22:57:21 1.2
@@ -118,8 +118,6 @@
return -1;
}
-#define MAXBUF_MIN 17
-#define MAXBUF_MAX 16777215
#define DEFAULT_CHARSET "utf-8"
#define DEFAULT_ALGORITHM "md5-sess"
@@ -157,6 +155,10 @@
memset (out, 0, sizeof (*out));
+ /* The size of a digest-challenge MUST be less than 2048 bytes. */
+ if (strlen (challenge) >= 2048)
+ return -1;
+
while (*challenge != '\0')
switch (digest_md5_getsubopt (&challenge, digest_challenge_opts, &value))
{
@@ -175,6 +177,9 @@
break;
case CHALLENGE_NONCE:
+ /* This directive is required and MUST appear exactly once; if
+ not present, or if multiple instances are present, the
+ client should abort the authentication exchange. */
if (out->nonce)
return -1;
out->nonce = strdup (value);
@@ -183,36 +188,56 @@
break;
case CHALLENGE_QOP:
- /* FIXME: sub-parse. */
+ /* The client MUST ignore unrecognized options; if the client
+ recognizes no option, it MUST abort the authentication
+ exchange. */
if (out->qop)
return -1;
+ /* FIXME: sub-parse. */
out->qop = strdup (value);
if (!out->qop)
return -1;
break;
case CHALLENGE_STALE:
+ /* This directive may appear at most once; if multiple
+ instances are present, the client MUST abort the
+ authentication exchange. */
if (out->stale)
return -1;
out->stale = 1;
break;
case CHALLENGE_MAXBUF:
+ /* This directive may appear at most once; if multiple
+ instances are present, or the value is out of range the
+ client MUST abort the authentication exchange. */
if (out->servermaxbuf)
return -1;
out->servermaxbuf = strtoul (value, NULL, 10);
- if (out->servermaxbuf < MAXBUF_MIN
- || out->servermaxbuf > MAXBUF_MAX)
+ /* FIXME: error handling. */
+ /* The value MUST be bigger than 16 (32 for Confidentiality
+ protection with the "aes-cbc" cipher) and smaller or equal
+ to 16777215 (i.e. 2**24-1). */
+ if (out->servermaxbuf <= 16 || out->servermaxbuf > 16777215)
return -1;
break;
case CHALLENGE_CHARSET:
+ /* This directive may appear at most once; if multiple
+ instances are present, the client MUST abort the
+ authentication exchange. */
+ if (out->utf8)
+ return -1;
if (strcmp (DEFAULT_CHARSET, value) != 0)
return -1;
out->utf8 = 1;
break;
case CHALLENGE_ALGORITHM:
+ /* This directive is required and MUST appear exactly once; if
+ not present, or if multiple instances are present, the
+ client SHOULD abort the authentication exchange. */
if (done_algorithm)
return -1;
if (strcmp (DEFAULT_ALGORITHM, value) != 0)
@@ -221,19 +246,33 @@
break;
case CHALLENGE_CIPHER:
- /* FIXME: sub-parse. */
if (out->ciphers)
return -1;
+ /* FIXME: sub-parse. */
out->ciphers = strdup (value);
if (!out->ciphers)
return -1;
break;
default:
- /* Unknown suboption, we MUST ignore it. */
+ /* The client MUST ignore any unrecognized directives. */
break;
}
+ /* Validate that we have the mandatory fields. */
+
+ /* This directive is required and MUST appear exactly once; if
+ not present, or if multiple instances are present, the
+ client should abort the authentication exchange. */
+ if (!out->nonce)
+ return -1;
+
+ /* This directive is required and MUST appear exactly once; if
+ not present, or if multiple instances are present, the
+ client SHOULD abort the authentication exchange. */
+ if (!done_algorithm)
+ return -1;
+
return 0;
}
@@ -278,17 +317,183 @@
memset (out, 0, sizeof (*out));
+ /* The size of a digest-response MUST be less than 4096 bytes. */
+ if (strlen (response) >= 4096)
+ return -1;
+
while (*response != '\0')
switch (digest_md5_getsubopt (&response, digest_response_opts, &value))
{
+ case RESPONSE_USERNAME:
+ /* This directive is required and MUST be present exactly
+ once; otherwise, authentication fails. */
+ if (out->username)
+ return -1;
+ out->username = strdup (value);
+ if (!out->username)
+ return -1;
+ break;
+
+ case RESPONSE_REALM:
+ /* This directive is required if the server provided any
+ realms in the "digest-challenge", in which case it may
+ appear exactly once and its value SHOULD be one of those
+ realms. */
+ if (out->realm)
+ return -1;
+ out->realm = strdup (value);
+ if (!out->realm)
+ return -1;
+ break;
+
+ case RESPONSE_NONCE:
+ /* This directive is required and MUST be present exactly
+ once; otherwise, authentication fails. */
+ if (out->nonce)
+ return -1;
+ out->nonce = strdup (value);
+ if (!out->nonce)
+ return -1;
+ break;
+
+ case RESPONSE_CNONCE:
+ /* This directive is required and MUST be present exactly once;
+ otherwise, authentication fails. */
+ if (out->cnonce)
+ return -1;
+ out->cnonce = strdup (value);
+ if (!out->cnonce)
+ return -1;
+ break;
+
+ case RESPONSE_NC:
+ /* This directive is required and MUST be present exactly
+ once; otherwise, authentication fails. */
+ if (out->nc)
+ return -1;
+ /* nc-value = 8LHEX */
+ if (strlen (value) != 8)
+ return -1;
+ out->nc = strtoul (value, NULL, 16);
+ /* FIXME: error handling. */
+ break;
+
+ case RESPONSE_QOP:
+ /* If present, it may appear exactly once and its value MUST
+ be one of the alternatives in qop-options. */
+ if (out->qop)
+ return -1;
+ /* FIXME: sub-parse. */
+ out->qop = strdup (value);
+ if (!out->qop)
+ return -1;
+ break;
+
+ case RESPONSE_DIGEST_URI:
+ /* This directive is required and MUST be present exactly
+ once; if multiple instances are present, the client MUST
+ abort the authentication exchange. */
+ if (out->digesturi)
+ return -1;
+ /* FIXME: sub-parse. */
+ out->digesturi = strdup (value);
+ if (!out->digesturi)
+ return -1;
+ break;
+
+ case RESPONSE_RESPONSE:
+ /* This directive is required and MUST be present exactly
+ once; otherwise, authentication fails. */
+ if (out->response)
+ return -1;
+ /* FIXME: sub-parse. */
+ out->response = strdup (value);
+ if (!out->response)
+ return -1;
+ break;
+
+ case RESPONSE_MAXBUF:
+ /* This directive may appear at most once; if multiple
+ instances are present, the server MUST abort the
+ authentication exchange. */
+ if (out->clientmaxbuf)
+ return -1;
+ out->clientmaxbuf = strtoul (value, NULL, 10);
+ /* FIXME: error handling. */
+ /* If the value is less or equal to 16 (<<32 for aes-cbc>>) or
+ bigger than 16777215 (i.e. 2**24-1), the server MUST abort
+ the authentication exchange. */
+ if (out->clientmaxbuf <= 16 || out->clientmaxbuf > 16777215)
+ return -1;
+ break;
+
+ case RESPONSE_CHARSET:
+ if (strcmp (DEFAULT_CHARSET, value) != 0)
+ return -1;
+ out->utf8 = 1;
+ break;
+
+ case RESPONSE_CIPHER:
+ if (out->cipher)
+ return -1;
+ /* FIXME: sub-parse. */
+ out->cipher = strdup (value);
+ if (!out->cipher)
+ return -1;
+ break;
+
+ case RESPONSE_AUTHZID:
+ /* This directive may appear at most once; if multiple
+ instances are present, the client MUST abort the
+ authentication exchange. FIXME NOT IN DRAFT */
+ if (out->authzid)
+ return -1;
+ /* The authzid MUST NOT be an empty string. */
+ if (strcmp (value, "") == 0)
+ return -1;
+ out->authzid = strdup (value);
+ if (!out->authzid)
+ return -1;
+ break;
default:
- /* Unknown suboption. Not clear if this should be ignored or
- treated as a failure. We do the latter for now. */
- return -1;
+ /* The client MUST ignore any unrecognized directives. */
break;
}
+ /* Validate that we have the mandatory fields. */
+
+ /* This directive is required and MUST be present exactly
+ once; otherwise, authentication fails. */
+ if (!out->username)
+ return -1;
+
+ /* This directive is required and MUST be present exactly
+ once; otherwise, authentication fails. */
+ if (!out->nonce)
+ return -1;
+
+ /* This directive is required and MUST be present exactly once;
+ otherwise, authentication fails. */
+ if (!out->cnonce)
+ return -1;
+
+ /* This directive is required and MUST be present exactly once;
+ otherwise, authentication fails. */
+ if (!out->nc)
+ return -1;
+
+ /* This directive is required and MUST be present exactly
+ once; if multiple instances are present, the client MUST
+ abort the authentication exchange. */
+ if (!out->digesturi)
+ return -1;
+
+ /* This directive is required and MUST be present exactly
+ once; otherwise, authentication fails. */
+ if (!out->response)
+ return -1;
+
return 0;
}
@@ -309,7 +514,11 @@
{
char *value;
- out->rspauth = NULL;
+ memset (out, 0, sizeof (*out));
+
+ /* The size of a response-auth MUST be less than 2048 bytes. */
+ if (strlen (finish) >= 2048)
+ return -1;
while (*finish != '\0')
switch (digest_md5_getsubopt (&finish, digest_responseauth_opts, &value))
@@ -321,12 +530,13 @@
break;
default:
- /* Unknown suboption. Not clear if this should be ignored or
- treated as a failure. We do the latter for now. */
- return -1;
+ /* The client MUST ignore any unrecognized directives. */
break;
}
+ if (!out->rspauth)
+ return -1;
+
return 0;
}
- CVS gsasl/lib/digest-md5, gsasl-commit, 2004/12/14
- CVS gsasl/lib/digest-md5, gsasl-commit, 2004/12/14
- CVS gsasl/lib/digest-md5, gsasl-commit, 2004/12/14
- CVS gsasl/lib/digest-md5, gsasl-commit, 2004/12/16
- CVS gsasl/lib/digest-md5, gsasl-commit, 2004/12/18
- CVS gsasl/lib/digest-md5, gsasl-commit, 2004/12/18
- CVS gsasl/lib/digest-md5,
gsasl-commit <=
- CVS gsasl/lib/digest-md5, gsasl-commit, 2004/12/18
- CVS gsasl/lib/digest-md5, gsasl-commit, 2004/12/18
- CVS gsasl/lib/digest-md5, gsasl-commit, 2004/12/18
- CVS gsasl/lib/digest-md5, gsasl-commit, 2004/12/18
- CVS gsasl/lib/digest-md5, gsasl-commit, 2004/12/18
- CVS gsasl/lib/digest-md5, gsasl-commit, 2004/12/18
- CVS gsasl/lib/digest-md5, gsasl-commit, 2004/12/18
- CVS gsasl/lib/digest-md5, gsasl-commit, 2004/12/18
- CVS gsasl/lib/digest-md5, gsasl-commit, 2004/12/18
- CVS gsasl/lib/digest-md5, gsasl-commit, 2004/12/18