summaryrefslogtreecommitdiffstats
path: root/cpukit/httpd/websda.c
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2003-04-11 16:34:49 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2003-04-11 16:34:49 +0000
commit2e7f00fce6696c380a93ea939bf233760f499640 (patch)
tree4054b7b0d7a6722c69691523b63159feb4ce06b0 /cpukit/httpd/websda.c
parent2002-04-10 Mike Siers <mikes@poliac.com> (diff)
downloadrtems-2e7f00fce6696c380a93ea939bf233760f499640.tar.bz2
2003-04-11 Joel Sherrill <joel@OARcorp.com>
* rtems_webserver/cgi.c, rtems_webserver/sockGen.c, rtems_webserver/umui.c, rtems_webserver/websSSL.c, rtems_webserver/websSSL.h, rtems_webserver/websda.c, rtems_webserver/websda.h: New files. Not included in previous commit.
Diffstat (limited to 'cpukit/httpd/websda.c')
-rw-r--r--cpukit/httpd/websda.c244
1 files changed, 244 insertions, 0 deletions
diff --git a/cpukit/httpd/websda.c b/cpukit/httpd/websda.c
new file mode 100644
index 0000000000..a4a95775b8
--- /dev/null
+++ b/cpukit/httpd/websda.c
@@ -0,0 +1,244 @@
+/*
+ * websda.c -- Digest Access Authentication routines
+ *
+ * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
+ *
+ * See the file "license.txt" for usage and redistribution license requirements
+ *
+ * $Id$
+ */
+
+/******************************** Description *********************************/
+
+/*
+ * Routines for generating DAA data. The module uses the
+ * "RSA Data Security, Inc. MD5 Message-Digest Algorithm" found in md5c.c
+ */
+
+/********************************* Includes ***********************************/
+
+#ifndef CE
+#include <time.h>
+#endif
+#include "websda.h"
+#include "md5.h"
+
+/******************************** Local Data **********************************/
+
+#define RANDOMKEY T("onceuponatimeinparadise")
+#define NONCE_SIZE 34
+#define HASH_SIZE 16
+
+/*********************************** Code *************************************/
+/*
+ * websMD5binary returns the MD5 hash
+ */
+
+char *websMD5binary(unsigned char *buf, int length)
+{
+ const char *hex = "0123456789abcdef";
+ MD5_CONTEXT md5ctx;
+ unsigned char hash[HASH_SIZE];
+ char *r, *strReturn;
+ char result[(HASH_SIZE * 2) + 1];
+ int i;
+
+/*
+ * Take the MD5 hash of the string argument.
+ */
+ MD5Init(&md5ctx);
+ MD5Update(&md5ctx, buf, (unsigned int)length);
+ MD5Final(hash, &md5ctx);
+
+/*
+ * Prepare the resulting hash string
+ */
+ for (i = 0, r = result; i < 16; i++) {
+ *r++ = hex[hash[i] >> 4];
+ *r++ = hex[hash[i] & 0xF];
+ }
+
+/*
+ * Zero terminate the hash string
+ */
+ *r = '\0';
+
+/*
+ * Allocate a new copy of the hash string
+ */
+ strReturn = balloc(B_L, sizeof(result));
+ strcpy(strReturn, result);
+
+ return strReturn;
+}
+
+/*****************************************************************************/
+/*
+ * Convenience call to websMD5binary
+ * (Performs char_t to char conversion and back)
+ */
+
+char_t *websMD5(char_t *string)
+{
+ char_t *strReturn;
+
+ a_assert(string && *string);
+
+ if (string && *string) {
+ char *strTemp, *strHash;
+ int nLen;
+/*
+ * Convert input char_t string to char string
+ */
+ nLen = gstrlen(string);
+ strTemp = ballocUniToAsc(string, nLen + 1);
+/*
+ * Execute the digest calculation
+ */
+ strHash = websMD5binary((unsigned char *)strTemp, nLen);
+/*
+ * Convert the returned char string digest to a char_t string
+ */
+ nLen = strlen(strHash);
+ strReturn = ballocAscToUni(strHash, nLen);
+/*
+ * Free up the temporary allocated resources
+ */
+ bfree(B_L, strTemp);
+ bfree(B_L, strHash);
+ } else {
+ strReturn = NULL;
+ }
+
+ return strReturn;
+}
+
+/******************************************************************************/
+/*
+ * Get a Nonce value for passing along to the client. This function
+ * composes the string "RANDOMKEY:timestamp:myrealm" and
+ * calculates the MD5 digest placing it in output.
+ */
+
+char_t *websCalcNonce(webs_t wp)
+{
+ char_t *nonce, *prenonce;
+ struct tm *newtime;
+ time_t longTime;
+
+ a_assert(wp);
+/*
+ * Get time as long integer.
+ */
+ time(&longTime);
+/*
+ * Convert to local time.
+ */
+ newtime = localtime(&longTime);
+/*
+ * Create prenonce string.
+ */
+ prenonce = NULL;
+#ifdef DIGEST_ACCESS_SUPPORT
+ fmtAlloc(&prenonce, 256, T("%s:%s:%s"), RANDOMKEY, gasctime(newtime),
+ wp->realm);
+#else
+ fmtAlloc(&prenonce, 256, T("%s:%s:%s"), RANDOMKEY, gasctime(newtime),
+ RANDOMKEY);
+#endif
+ a_assert(prenonce);
+/*
+ * Create the nonce
+ */
+ nonce = websMD5(prenonce);
+/*
+ * Cleanup
+ */
+ bfreeSafe(B_L, prenonce);
+
+ return nonce;
+}
+
+/******************************************************************************/
+/*
+ * Get an Opaque value for passing along to the client
+ */
+
+char_t *websCalcOpaque(webs_t wp)
+{
+ char_t *opaque;
+ a_assert(wp);
+/*
+ * Temporary stub!
+ */
+ opaque = bstrdup(B_L, T("5ccc069c403ebaf9f0171e9517f40e41"));
+
+ return opaque;
+}
+
+/******************************************************************************/
+/*
+ * Get a Digest value using the MD5 algorithm
+ */
+
+char_t *websCalcDigest(webs_t wp)
+{
+#ifdef DIGEST_ACCESS_SUPPORT
+ char_t *digest, *a1, *a1prime, *a2, *a2prime, *preDigest, *method;
+
+ a_assert(wp);
+ digest = NULL;
+
+/*
+ * Calculate first portion of digest H(A1)
+ */
+ a1 = NULL;
+ fmtAlloc(&a1, 255, T("%s:%s:%s"), wp->userName, wp->realm, wp->password);
+ a_assert(a1);
+ a1prime = websMD5(a1);
+ bfreeSafe(B_L, a1);
+/*
+ * Calculate second portion of digest H(A2)
+ */
+ method = websGetVar(wp, T("REQUEST_METHOD"), NULL);
+ a_assert(method);
+ a2 = NULL;
+ fmtAlloc(&a2, 255, T("%s:%s"), method, wp->uri);
+ a_assert(a2);
+ a2prime = websMD5(a2);
+ bfreeSafe(B_L, a2);
+/*
+ * Construct final digest KD(H(A1):nonce:H(A2))
+ */
+ a_assert(a1prime);
+ a_assert(a2prime);
+ a_assert(wp->nonce);
+
+ preDigest = NULL;
+ if (!wp->qop) {
+ fmtAlloc(&preDigest, 255, T("%s:%s:%s"), a1prime, wp->nonce, a2prime);
+ } else {
+ fmtAlloc(&preDigest, 255, T("%s:%s:%s:%s:%s:%s"),
+ a1prime,
+ wp->nonce,
+ wp->nc,
+ wp->cnonce,
+ wp->qop,
+ a2prime);
+ }
+
+ a_assert(preDigest);
+ digest = websMD5(preDigest);
+/*
+ * Now clean up
+ */
+ bfreeSafe(B_L, a1prime);
+ bfreeSafe(B_L, a2prime);
+ bfreeSafe(B_L, preDigest);
+ return digest;
+#else
+ return NULL;
+#endif /* DIGEST_ACCESS_SUPPORT */
+}
+
+/******************************************************************************/