diff options
author | Joel Sherrill <joel.sherrill@OARcorp.com> | 2003-04-11 16:34:49 +0000 |
---|---|---|
committer | Joel Sherrill <joel.sherrill@OARcorp.com> | 2003-04-11 16:34:49 +0000 |
commit | 2e7f00fce6696c380a93ea939bf233760f499640 (patch) | |
tree | 4054b7b0d7a6722c69691523b63159feb4ce06b0 /cpukit/httpd/websda.c | |
parent | 2002-04-10 Mike Siers <mikes@poliac.com> (diff) | |
download | rtems-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.c | 244 |
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 */ +} + +/******************************************************************************/ |