diff --git a/auth_token/client/authmech.c b/auth_token/client/authmech.c
new file mode 100644
index 00000000..8f579bd6
--- /dev/null
+++ b/auth_token/client/authmech.c
@@ -0,0 +1,333 @@
+/***********************************************************************
+ * 
+ *  Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; version 2.1
+ *  of the License.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, Novell, Inc.
+ * 
+ *  To contact Novell about this file by physical or electronic mail, 
+ *  you may find current contact information at www.novell.com.
+ * 
+ *  Author: Juan Carlos Luciani <jluciani@novell.com>
+ *
+ ***********************************************************************/
+
+
+//===[ Include files ]=====================================================
+
+#include "internal.h"
+
+//===[ Type definitions ]==================================================
+
+//
+// AuthMechMod definition
+// 
+typedef struct _AuthMechMod
+{
+   LIST_ENTRY        listEntry;
+   char              *pAuthTypeName;
+   int               authTypeNameLen;
+   LIB_HANDLE        libHandle;
+   AuthTokenIf       *pAuthTokenIf;
+
+} AuthMechMod, *PAuthMechMod;
+
+
+//===[ Function prototypes ]===============================================
+
+//===[ Global variables ]==================================================
+
+// AuthMechModule List and syncronizing mutex
+static
+LIST_ENTRY  g_authMechModuleListHead = {&g_authMechModuleListHead,
+                                        &g_authMechModuleListHead};
+
+
+//++=======================================================================
+static
+CasaStatus
+GetAuthTokenIf(
+   IN       const char        *pAuthTypeName,
+   INOUT    AuthTokenIf   **ppAuthTokenIf)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+//  Environment:
+//
+// L2
+//=======================================================================--
+{
+   CasaStatus  retStatus;
+   ConfigIf    *pModuleConfigIf;
+
+
+   DbgTrace(2, "-GetAuthTokenIf- Start\n", 0);
+
+   // Get the configuration for the module
+   retStatus = GetConfigInterface(mechConfigFolder,
+                                  pAuthTypeName,
+                                  &pModuleConfigIf);
+   if (CASA_SUCCESS(retStatus)
+       && CasaStatusCode(retStatus) != CASA_STATUS_OBJECT_NOT_FOUND)
+   {
+      LIST_ENTRY     *pListEntry;
+      AuthMechMod    *pAuthMechMod = NULL;
+      int32_t        authTypeNameLen = (int32_t) strlen(pAuthTypeName);
+
+      // Look if we already have the module in our list
+      pListEntry = g_authMechModuleListHead.Flink;
+      while (pListEntry != &g_authMechModuleListHead)
+      {
+         // Get pointer to the current entry
+         pAuthMechMod = CONTAINING_RECORD(pListEntry, AuthMechMod, listEntry);
+
+         // Check if this is the module that we need
+         if (pAuthMechMod->authTypeNameLen == authTypeNameLen
+             && memcmp(pAuthTypeName, pAuthMechMod->pAuthTypeName, authTypeNameLen) == 0)
+         {
+            // This is the module that we need, stop looking.
+            break;
+         }
+         else
+         {
+            // This is not the module that we are looking for
+            pAuthMechMod = NULL;
+         }
+
+         // Advance to the next entry
+         pListEntry = pListEntry->Flink;
+      }
+
+      // Proceed based on whether or not a module was found
+      if (pAuthMechMod)
+      {
+         // Module found in our list, provide the caller with its AuthTokenIf
+         // instance after we have incremented its reference count.
+         pAuthMechMod->pAuthTokenIf->addReference(pAuthMechMod->pAuthTokenIf);
+         *ppAuthTokenIf = pAuthMechMod->pAuthTokenIf;
+
+         // Success
+         retStatus = CASA_STATUS_SUCCESS;
+      }
+      else
+      {
+         // Needed module not found in our list, create an entry.
+         pAuthMechMod = (AuthMechMod*) malloc(sizeof(*pAuthMechMod));
+         if (pAuthMechMod)
+         {
+            // Allocate buffer to contain the authentication type name within the module entry
+            pAuthMechMod->pAuthTypeName = (char*) malloc(authTypeNameLen + 1);
+            if (pAuthMechMod->pAuthTypeName)
+            {
+               char  *pLibraryName;
+
+               // Initialize the library handle field
+               pAuthMechMod->libHandle = NULL;
+
+               // Save the auth type name within the entry
+               strcpy(pAuthMechMod->pAuthTypeName, pAuthTypeName);
+               pAuthMechMod->authTypeNameLen = authTypeNameLen;
+
+               // Obtain the name of the library that we must load
+               pLibraryName = pModuleConfigIf->getEntryValue(pModuleConfigIf, "LibraryName");
+               if (pLibraryName)
+               {
+                  // Load the library
+                  pAuthMechMod->libHandle = OpenLibrary(pLibraryName);
+                  if (pAuthMechMod->libHandle)
+                  {
+                     PFN_GetAuthTokenIfRtn   pGetAuthTokenIfRtn;
+
+                     // Library has been loaded, now get a pointer to its GetAuthTokenInterface routine
+                     pGetAuthTokenIfRtn = (PFN_GetAuthTokenIfRtn) GetFunctionPtr(pAuthMechMod->libHandle,
+                                                                                 GET_AUTH_TOKEN_INTERFACE_RTN_SYMBOL);
+                     if (pGetAuthTokenIfRtn)
+                     {
+                        // Now, obtain the modules AuthTokenIf.
+                        retStatus = (pGetAuthTokenIfRtn)(pModuleConfigIf, &pAuthMechMod->pAuthTokenIf);
+                     }
+                     else
+                     {
+                        DbgTrace(0, "-GetAuthTokenIf- GetFunctionPtr\n", 0);
+                        retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                                    CASA_FACILITY_AUTHTOKEN,
+                                                    CASA_STATUS_LIBRARY_LOAD_FAILURE);
+                     }
+                  }
+                  else
+                  {
+                     DbgTrace(0, "-GetAuthTokenIf- OpenLibrary error\n", 0);
+                     retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                                 CASA_FACILITY_AUTHTOKEN,
+                                                 CASA_STATUS_UNSUCCESSFUL);
+                  }
+
+                  // Free the buffer holding the library name
+                  free(pLibraryName);
+               }
+               else
+               {
+                  DbgTrace(0, "-GetAuthTokenIf- Library name not configured\n", 0);
+                  retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                              CASA_FACILITY_AUTHTOKEN,
+                                              CASA_STATUS_CONFIGURATION_ERROR);
+               }
+
+               // Check if we were successful at obtaining the AuthTokenIf instance for the
+               // module.
+               if (CASA_SUCCESS(retStatus))
+               {
+                  // Insert the entry in the list, provide the caller with its AuthTokenIf
+                  // instance after we have incremented its reference count.
+                  InsertTailList(&g_authMechModuleListHead, &pAuthMechMod->listEntry);
+                  pAuthMechMod->pAuthTokenIf->addReference(pAuthMechMod->pAuthTokenIf);
+                  *ppAuthTokenIf = pAuthMechMod->pAuthTokenIf;
+               }
+               else
+               {
+                  // Failed, free resources.
+                  free(pAuthMechMod->pAuthTypeName);
+                  if (pAuthMechMod->libHandle)
+                     CloseLibrary(pAuthMechMod->libHandle);
+                  free(pAuthMechMod);
+               }
+            }
+            else
+            {
+               DbgTrace(0, "GetAuthTokenIf-GetAuthTokenIf- Unable to allocate buffer\n", 0);
+
+               // Free buffer allocated for entry
+               free(pAuthMechMod);
+
+               retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                           CASA_FACILITY_AUTHTOKEN,
+                                           CASA_STATUS_INSUFFICIENT_RESOURCES);
+            }
+         }
+         else
+         {
+            DbgTrace(0, "-GetAuthTokenIf- Unable to allocate buffer\n", 0);
+            retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                        CASA_FACILITY_AUTHTOKEN,
+                                        CASA_STATUS_INSUFFICIENT_RESOURCES);
+         }
+      }
+
+      // Release config interface instance
+      pModuleConfigIf->releaseReference(pModuleConfigIf);
+   }
+   else
+   {
+      DbgTrace(0, "-GetAuthTokenIf- Unable to obtain config interface\n", 0);
+      retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                  CASA_FACILITY_AUTHTOKEN,
+                                  CASA_STATUS_CONFIGURATION_ERROR);
+   }
+
+   DbgTrace(2, "-GetAuthTokenIf- End, retStatus = %08X\n", retStatus);
+
+   return retStatus;
+}
+
+
+//++=======================================================================
+CasaStatus
+GetAuthMechToken(
+   IN    AuthContext *pAuthContext,
+   INOUT char **ppAuthToken)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L0
+//=======================================================================--
+{
+   CasaStatus        retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                                 CASA_FACILITY_AUTHTOKEN,
+                                                 CASA_STATUS_UNSUCCESSFUL);
+   AuthTokenIf   *pAuthTokenIf;
+
+   DbgTrace(1, "-GetAuthMechToken- Start\n", 0);
+
+   // Initialize output parameter
+   *ppAuthToken = NULL;
+
+   // Obtain the appropriate token interface for the authentication type
+   retStatus = GetAuthTokenIf(pAuthContext->pMechanism,
+                                  &pAuthTokenIf);
+   if (CASA_SUCCESS(retStatus))
+   {
+      char  *pAuthToken = NULL;
+      int   authTokenBufLen = 0;
+
+      // We found a provider for the service, query it for the buffer size
+      // needed to obtain the authentication token.
+      retStatus = pAuthTokenIf->getAuthToken(pAuthTokenIf,
+                                                 pAuthContext->pContext,
+                                                 pAuthContext->pMechInfo,
+                                                 pAuthToken,
+                                                 &authTokenBufLen);
+      if (CasaStatusCode(retStatus) == CASA_STATUS_BUFFER_OVERFLOW)
+      {
+         // Allocate buffer to hold the authentication token
+         pAuthToken = (char*) malloc(authTokenBufLen);
+         if (pAuthToken)
+         {
+            // Request the token from the provider
+            retStatus = pAuthTokenIf->getAuthToken(pAuthTokenIf,
+                                                       pAuthContext->pContext,
+                                                       pAuthContext->pMechInfo,
+                                                       pAuthToken,
+                                                       &authTokenBufLen);
+            if (CASA_SUCCESS(retStatus))
+            {
+               // Return the buffer containing the token to the caller
+               *ppAuthToken = pAuthToken;
+            }
+            else
+            {
+               // Free the allocated buffer
+               free(pAuthToken);
+            }
+         }
+         else
+         {
+            DbgTrace(0, "-GetAuthMechToken- Buffer allocation failure\n", 0);
+         }
+      }
+
+      // Release token interface
+      pAuthTokenIf->releaseReference(pAuthTokenIf);
+   }
+   else
+   {
+      // No authentication token interface available for authentication type
+      DbgTrace(0, "-GetAuthMechToken- Failed to obtain auth mech token interface\n", 0);
+   }
+
+   DbgTrace(1, "-GetAuthMechToken- End, retStatus = %08X\n", retStatus);
+
+   return retStatus;
+}
+
diff --git a/auth_token/client/authmsg.c b/auth_token/client/authmsg.c
new file mode 100644
index 00000000..bc4a27d4
--- /dev/null
+++ b/auth_token/client/authmsg.c
@@ -0,0 +1,725 @@
+/***********************************************************************
+ * 
+ *  Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; version 2.1
+ *  of the License.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, Novell, Inc.
+ * 
+ *  To contact Novell about this file by physical or electronic mail, 
+ *  you may find current contact information at www.novell.com.
+ * 
+ *  Author: Juan Carlos Luciani <jluciani@novell.com>
+ *
+ ***********************************************************************/
+
+
+//===[ Include files ]=====================================================
+
+#include "internal.h"
+
+//===[ Type definitions ]==================================================
+
+//
+// Parse states
+//
+#define AWAITING_ROOT_ELEMENT_START             0x0
+#define AWAITING_ROOT_ELEMENT_END               0x1
+#define AWAITING_STATUS_ELEMENT_START           0x2
+#define AWAITING_STATUS_ELEMENT_END             0x3
+#define AWAITING_STATUS_DATA                    0x4
+#define AWAITING_DESCRIPTION_ELEMENT_START      0x5
+#define AWAITING_DESCRIPTION_ELEMENT_END        0x6
+#define AWAITING_DESCRIPTION_DATA               0x7
+#define AWAITING_SESSION_TOKEN_ELEMENT_START    0x8
+#define AWAITING_SESSION_TOKEN_ELEMENT_END      0x9
+#define AWAITING_SESSION_TOKEN_DATA             0xA
+#define AWAITING_LIFETIME_DATA                  0xB
+#define AWAITING_LIFETIME_ELEMENT_START         0xC
+#define AWAITING_LIFETIME_ELEMENT_END           0xD
+#define AWAITING_AUTH_TOKEN_ELEMENT_START       0xE
+#define AWAITING_AUTH_TOKEN_ELEMENT_END         0xF
+#define AWAITING_AUTH_TOKEN_DATA                0x10
+#define AWAITING_REALM_DATA                     0x12
+#define AWAITING_REALM_ELEMENT_END              0x13
+#define DONE_PARSING                            0x14
+
+//
+// Authentication Response Parse Structure
+//
+typedef struct _AuthRespParse
+{
+   XML_Parser           p;
+   int                  state;
+   int                  tokenDataProcessed;
+   AuthenticateResp     *pAuthenticateResp;
+   CasaStatus           status;
+
+} AuthRespParse, *PAuthRespParse;
+
+
+//===[ Function prototypes ]===============================================
+
+//===[ Global variables ]==================================================
+
+//++=======================================================================
+char*
+BuildAuthenticateMsg(
+   IN    AuthContext *pAuthContext,
+   IN    char *pAuthMechToken)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L0
+//=======================================================================--
+{
+   char  *pMsg = NULL;
+   int   bufferSize;
+
+   DbgTrace(1, "-BuildAuthenticateMsg- Start\n", 0);
+
+   /*
+   * The format of the authentication request message is as follows:
+   * 
+   * <?xml version="1.0" encoding="ISO-8859-1"?>
+   * <auth_req>
+   * <realm>realm value</realm>
+   * <auth_mech_token>authentication mechanism token data</auth_mech_token>
+   * </auth_req>
+   *
+   */
+
+   // Determine the buffer size necessary to hold the msg
+   bufferSize = strlen(XML_DECLARATION)
+                + 2  // crlf
+                + 1  // <
+                + strlen(AUTH_REQUEST_ELEMENT_NAME)
+                + 3  // >crlf
+                + 1  // <
+                + strlen(REALM_ELEMENT_NAME)
+                + 1  // >
+                + strlen(pAuthContext->pContext)
+                + 2  // </
+                + strlen(REALM_ELEMENT_NAME)
+                + 3  // >crlf
+                + 1  // <
+                + strlen(AUTH_MECH_TOKEN_ELEMENT_NAME)
+                + 1  // >
+                + strlen(pAuthMechToken)
+                + 2  // </
+                + strlen(AUTH_MECH_TOKEN_ELEMENT_NAME)
+                + 3  // >crlf
+                + 2  // </
+                + strlen(AUTH_REQUEST_ELEMENT_NAME)
+                + 2; // >null
+
+   // Allocate the msg buffer
+   pMsg = (char*) malloc(bufferSize);
+   if (pMsg)
+   {
+      // Now build the message
+      memset(pMsg, 0, bufferSize);
+      strcat(pMsg, XML_DECLARATION);
+      strcat(pMsg, "\r\n");
+      strcat(pMsg, "<");
+      strcat(pMsg, AUTH_REQUEST_ELEMENT_NAME);
+      strcat(pMsg, ">\r\n");
+      strcat(pMsg, "<");
+      strcat(pMsg, REALM_ELEMENT_NAME);
+      strcat(pMsg, ">");
+      strcat(pMsg, pAuthContext->pContext);
+      strcat(pMsg, "</");
+      strcat(pMsg, REALM_ELEMENT_NAME);
+      strcat(pMsg, ">\r\n");
+      strcat(pMsg, "<");
+      strcat(pMsg, AUTH_MECH_TOKEN_ELEMENT_NAME);
+      strcat(pMsg, ">");
+      strcat(pMsg, pAuthMechToken);
+      strcat(pMsg, "</");
+      strcat(pMsg, AUTH_MECH_TOKEN_ELEMENT_NAME);
+      strcat(pMsg, ">\r\n");
+      strcat(pMsg, "</");
+      strcat(pMsg, AUTH_REQUEST_ELEMENT_NAME);
+      strcat(pMsg, ">");
+   }
+   else
+   {
+      DbgTrace(0, "-BuildAuthenticateMsg- Buffer allocation error\n", 0);
+   }
+
+   DbgTrace(1, "-BuildAuthenticateMsg- End, pMsg = %08X\n", pMsg);
+
+   return pMsg;
+}
+
+
+//++=======================================================================
+static
+void XMLCALL
+AuthRespStartElementHandler(
+   IN    AuthRespParse *pAuthRespParse,
+   IN    const XML_Char *name,
+   IN    const XML_Char **atts)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L0
+//=======================================================================--
+{
+   DbgTrace(2, "-AuthRespStartElementHandler- Start\n", 0);
+
+   // Proceed based on the state
+   switch (pAuthRespParse->state)
+   {
+      case AWAITING_ROOT_ELEMENT_START:
+
+         // In this state, we are only expecting the Authentication
+         // Response Element.
+         if (strcmp(name, AUTH_RESPONSE_ELEMENT_NAME) == 0)
+         {
+            // Good, advance to the next state.
+            pAuthRespParse->state = AWAITING_STATUS_ELEMENT_START;
+         }
+         else
+         {
+            DbgTrace(0, "-AuthRespStartElementHandler- Un-expected start element\n", 0);
+            XML_StopParser(pAuthRespParse->p, XML_FALSE);
+         }
+         break;
+
+      case AWAITING_STATUS_ELEMENT_START:
+   
+         // In this state, we are only expecting the Status Element.
+         if (strcmp(name, STATUS_ELEMENT_NAME) == 0)
+         {
+            // Good, advance to the next state.
+            pAuthRespParse->state = AWAITING_DESCRIPTION_ELEMENT_START;
+         }
+         else
+         {
+            DbgTrace(0, "-AuthRespStartElementHandler- Un-expected start element\n", 0);
+            XML_StopParser(pAuthRespParse->p, XML_FALSE);
+         }
+         break;
+
+      case AWAITING_DESCRIPTION_ELEMENT_START:
+   
+         // In this state, we are only expecting the Description Element.
+         if (strcmp(name, DESCRIPTION_ELEMENT_NAME) == 0)
+         {
+            // Good, advance to the next state.
+            pAuthRespParse->state = AWAITING_DESCRIPTION_DATA;
+         }
+         else
+         {
+            DbgTrace(0, "-AuthRespStartElementHandler- Un-expected start element\n", 0);
+            XML_StopParser(pAuthRespParse->p, XML_FALSE);
+         }
+         break;
+
+      case AWAITING_SESSION_TOKEN_ELEMENT_START:
+   
+         // In this state, we are only expecting the Session Token Element.
+         if (strcmp(name, SESSION_TOKEN_ELEMENT_NAME) == 0)
+         {
+            // Good, advance to the next state.
+            pAuthRespParse->state = AWAITING_LIFETIME_ELEMENT_START;
+         }
+         else
+         {
+            DbgTrace(0, "-AuthRespStartElementHandler- Un-expected start element\n", 0);
+            XML_StopParser(pAuthRespParse->p, XML_FALSE);
+         }
+         break;
+   
+      case AWAITING_LIFETIME_ELEMENT_START:
+   
+         // In this state, we are only expecting the Lifetime Element.
+         if (strcmp(name, LIFETIME_ELEMENT_NAME) == 0)
+         {
+            // Good, advance to the next state.
+            pAuthRespParse->state = AWAITING_LIFETIME_DATA;
+         }
+         else
+         {
+            DbgTrace(0, "-AuthRespStartElementHandler- Un-expected start element\n", 0);
+            XML_StopParser(pAuthRespParse->p, XML_FALSE);
+         }
+         break;
+
+      default:
+         DbgTrace(0, "-AuthRespStartElementHandler- Un-expected state = %d\n", pAuthRespParse->state);
+         XML_StopParser(pAuthRespParse->p, XML_FALSE);
+         break;
+   }
+
+   DbgTrace(2, "-AuthRespStartElementHandler- End\n", 0);
+}
+
+
+//++=======================================================================
+static
+void XMLCALL
+AuthRespCharDataHandler(
+   IN    AuthRespParse *pAuthRespParse,
+   IN    const XML_Char *s,
+   IN    int len)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L0
+//=======================================================================--
+{
+   DbgTrace(2, "-AuthRespCharDataHandler- Start\n", 0);
+
+   // Just exit if being called to process LF and CR characters
+   if (len == 1
+       && ((*s == '\n') || (*s == '\r')))
+   {
+      goto exit;
+   }
+
+   // Proceed based on the state
+   switch (pAuthRespParse->state)
+   {
+      case AWAITING_DESCRIPTION_DATA:
+
+         // Ignore the status description data for now.
+
+         // Advanced to the next state
+         pAuthRespParse->state = AWAITING_DESCRIPTION_ELEMENT_END;
+         break;
+
+      case AWAITING_STATUS_DATA:
+
+         // Set the appropriate status in the AuthenticationResp based on the
+         // returned status.
+         if (strncmp(HTTP_OK_STATUS_CODE, s, len) == 0)
+         {
+            pAuthRespParse->status = CASA_STATUS_SUCCESS;
+         }
+         else if (strncmp(HTTP_UNAUTHORIZED_STATUS_CODE, s, len) == 0)
+         {
+            pAuthRespParse->status = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                                     CASA_FACILITY_AUTHTOKEN,
+                                                     CASA_STATUS_AUTHENTICATION_FAILURE);
+         }
+         else if (strncmp(HTTP_SERVER_ERROR_STATUS_CODE, s, len) == 0)
+         {
+            pAuthRespParse->status = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                                     CASA_FACILITY_AUTHTOKEN,
+                                                     CASA_STATUS_SERVER_ERROR);
+         }
+         else
+         {
+            DbgTrace(0, "-AuthRespCharDataHandler- Un-expected status\n", 0);
+            pAuthRespParse->status = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                                     CASA_FACILITY_AUTHTOKEN,
+                                                     CASA_STATUS_UNSUCCESSFUL);
+         }
+
+         // Advanced to the next state
+         pAuthRespParse->state = AWAITING_STATUS_ELEMENT_END;
+         break;
+
+      case AWAITING_LIFETIME_DATA:
+
+         // Convert the lifetime string to a numeric value
+         pAuthRespParse->pAuthenticateResp->tokenLifetime = dtoul(s, len);
+
+         // Advanced to the next state
+         pAuthRespParse->state = AWAITING_LIFETIME_ELEMENT_END;
+         break;
+                    
+      case AWAITING_SESSION_TOKEN_DATA:
+      case AWAITING_SESSION_TOKEN_ELEMENT_END:
+
+         // Check if we have already processed token data
+         if (pAuthRespParse->tokenDataProcessed == 0)
+         {
+            // Keep a copy of the session token (null terminated)
+            pAuthRespParse->pAuthenticateResp->pToken = (char*) malloc(len + 1);
+            if (pAuthRespParse->pAuthenticateResp->pToken)
+            {
+               memset(pAuthRespParse->pAuthenticateResp->pToken, 0, len + 1);
+               memcpy(pAuthRespParse->pAuthenticateResp->pToken, s, len);
+               pAuthRespParse->tokenDataProcessed = len;
+
+               // Advanced to the next state
+               pAuthRespParse->state = AWAITING_SESSION_TOKEN_ELEMENT_END;
+            }
+            else
+            {
+               DbgTrace(0, "-AuthRespCharDataHandler- Buffer allocation failure\n", 0);
+               pAuthRespParse->status = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                                        CASA_FACILITY_AUTHTOKEN,
+                                                        CASA_STATUS_INSUFFICIENT_RESOURCES);
+               XML_StopParser(pAuthRespParse->p, XML_FALSE);
+            }
+         }
+         else
+         {
+            char  *pNewBuf;
+
+            // We have already received token data, append this data to it.
+            pNewBuf = (char*) malloc(pAuthRespParse->tokenDataProcessed + len + 1);
+            if (pNewBuf)
+            {
+               memset(pNewBuf,
+                      0,
+                      pAuthRespParse->tokenDataProcessed + len + 1);
+               memcpy(pNewBuf,
+                      pAuthRespParse->pAuthenticateResp->pToken,
+                      pAuthRespParse->tokenDataProcessed);
+               memcpy(pNewBuf + pAuthRespParse->tokenDataProcessed, s, len);
+               pAuthRespParse->tokenDataProcessed += len;
+
+               // Swap the buffers
+               free(pAuthRespParse->pAuthenticateResp->pToken);
+               pAuthRespParse->pAuthenticateResp->pToken = pNewBuf;
+            }
+            else
+            {
+               DbgTrace(0, "-AuthRespCharDataHandler- Buffer allocation failure\n", 0);
+               pAuthRespParse->status = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                                        CASA_FACILITY_AUTHTOKEN,
+                                                        CASA_STATUS_INSUFFICIENT_RESOURCES);
+               XML_StopParser(pAuthRespParse->p, XML_FALSE);
+            }
+         }
+         break;
+
+      default:
+         DbgTrace(0, "-AuthRespCharDataHandler- Un-expected state = %d\n", pAuthRespParse->state);
+         XML_StopParser(pAuthRespParse->p, XML_FALSE);
+         break;
+   }
+
+exit:
+
+   DbgTrace(2, "-AuthRespCharDataHandler- End\n", 0);
+}
+
+
+//++=======================================================================
+static
+void XMLCALL
+AuthRespEndElementHandler(
+   IN    AuthRespParse *pAuthRespParse,
+   IN    const XML_Char *name)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L0
+//=======================================================================--
+{
+   DbgTrace(2, "-AuthRespEndElementHandler- Start\n", 0);
+
+   // Proceed based on the state
+   switch (pAuthRespParse->state)
+   {
+      case AWAITING_ROOT_ELEMENT_END:
+
+         // In this state, we are only expecting the Authentication
+         // Response Element.
+         if (strcmp(name, AUTH_RESPONSE_ELEMENT_NAME) == 0)
+         {
+            // Done.
+            pAuthRespParse->state = DONE_PARSING;
+         }
+         else
+         {
+            DbgTrace(0, "-AuthRespEndHandler- Un-expected end element\n", 0);
+            XML_StopParser(pAuthRespParse->p, XML_FALSE);
+         }
+         break;
+
+      case AWAITING_DESCRIPTION_ELEMENT_END:
+   
+         // In this state, we are only expecting the Description Element.
+         if (strcmp(name, DESCRIPTION_ELEMENT_NAME) == 0)
+         {
+            // Good, advance to the next state.
+            pAuthRespParse->state = AWAITING_STATUS_DATA;
+         }
+         else
+         {
+            DbgTrace(0, "-AuthRespEndElementHandler- Un-expected end element\n", 0);
+            XML_StopParser(pAuthRespParse->p, XML_FALSE);
+         }
+         break;
+
+      case AWAITING_STATUS_ELEMENT_END:
+   
+         // In this state, we are only expecting the Status Element.
+         if (strcmp(name, STATUS_ELEMENT_NAME) == 0)
+         {
+            // Good, advance to the next state based on the status code.
+            if (CASA_SUCCESS(pAuthRespParse->status))
+            {
+               // The request completed successfully
+               pAuthRespParse->state = AWAITING_SESSION_TOKEN_ELEMENT_START;
+            }
+            else
+            {
+               pAuthRespParse->state = AWAITING_ROOT_ELEMENT_END;
+            }
+         }
+         else
+         {
+            DbgTrace(0, "-AuthRespEndElementHandler- Un-expected start element\n", 0);
+            XML_StopParser(pAuthRespParse->p, XML_FALSE);
+         }
+         break;
+   
+      case AWAITING_LIFETIME_ELEMENT_END:
+   
+         // In this state, we are only expecting the Lifetime Element.
+         if (strcmp(name, LIFETIME_ELEMENT_NAME) == 0)
+         {
+            // Good, advance to the next state.
+            pAuthRespParse->state = AWAITING_SESSION_TOKEN_DATA;
+         }
+         else
+         {
+            DbgTrace(0, "-AuthRespEndElementHandler- Un-expected start element\n", 0);
+            XML_StopParser(pAuthRespParse->p, XML_FALSE);
+         }
+         break;
+   
+      case AWAITING_SESSION_TOKEN_ELEMENT_END:
+   
+         // In this state, we are only expecting the Session Token Element.
+         if (strcmp(name, SESSION_TOKEN_ELEMENT_NAME) == 0)
+         {
+            // Good, advance to the next state.
+            pAuthRespParse->state = AWAITING_ROOT_ELEMENT_END;
+         }
+         else
+         {
+            DbgTrace(0, "-AuthRespEndElementHandler- Un-expected start element\n", 0);
+            XML_StopParser(pAuthRespParse->p, XML_FALSE);
+         }
+         break;
+   
+      default:
+         DbgTrace(0, "-AuthRespEndElementHandler- Un-expected state = %d\n", pAuthRespParse->state);
+         XML_StopParser(pAuthRespParse->p, XML_FALSE);
+         break;
+   }
+
+   DbgTrace(2, "-AuthRespEndElementHandler- End\n", 0);
+}
+
+
+//++=======================================================================
+CasaStatus
+CreateAuthenticateResp(
+   IN    char *pRespMsg,
+   IN    int respLen,
+   INOUT AuthenticateResp **ppAuthenticateResp)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L0
+//=======================================================================--
+{
+   CasaStatus           retStatus = CASA_STATUS_SUCCESS;
+   AuthRespParse        authRespParse = {0};
+   AuthenticateResp     *pAuthenticateResp;
+
+   DbgTrace(1, "-CreateAuthenticateResp- Start\n", 0);
+
+   /*
+   * When an authentication request is processed successfully, the server replies to
+   * the client with a message with the following format:
+   * 
+   * <?xml version="1.0" encoding="ISO-8859-1"?>
+   * <auth_resp>
+   * <status><description>ok</description>200</status>
+   * <session_token><lifetime>lifetime value</lifetime>session token data</session_token>
+   * </auth_resp>
+   * 
+   * When an authentication request fails to be successfully processed, the server
+   * responds with an error and a error description string. The message format of
+   * an unsuccessful reply is as follows:
+   * 
+   * <?xml version="1.0" encoding="ISO-8859-1"?>
+   * <auth_resp>
+   * <status><description>status description</description>status code</status>
+   * </auth_resp>
+   * 
+   * Plase note that the protocol utilizes the status codes defined
+   * in the HTTP 1.1 Specification.
+   *
+   */
+
+   // Allocate AuthenticateResp object
+   pAuthenticateResp = malloc(sizeof(*pAuthenticateResp));
+   if (pAuthenticateResp)
+   {
+      XML_Parser  p;
+
+      // Initialize the AuthenticateResp object and set it in the
+      // authentication response parse oject.
+      memset(pAuthenticateResp, 0, sizeof(*pAuthenticateResp));
+      authRespParse.pAuthenticateResp = pAuthenticateResp;
+
+      // Create parser
+      p = XML_ParserCreate(NULL);
+      if (p)
+      {
+         // Keep track of the parser in our parse object
+         authRespParse.p = p;
+
+         // Initialize the status within the parse object
+         authRespParse.status = CASA_STATUS_SUCCESS;
+
+         // Set the start and end element handlers
+         XML_SetElementHandler(p,
+                               AuthRespStartElementHandler,
+                               AuthRespEndElementHandler);
+
+         // Set the character data handler
+         XML_SetCharacterDataHandler(p, AuthRespCharDataHandler);
+
+
+         // Set our user data
+         XML_SetUserData(p, &authRespParse);
+
+         // Parse the document
+         if (XML_Parse(p, pRespMsg, respLen, 1) == XML_STATUS_OK)
+         {
+            // Verify that the parse operation completed successfully
+            if (authRespParse.state == DONE_PARSING)
+            {
+               // The parse operation succeded, obtain the status returned
+               // by the server.
+               retStatus = authRespParse.status;
+            }
+            else
+            {
+               DbgTrace(0, "-CreateAuthenticateResp- Parse operation did not complete\n", 0);
+
+               // Check if a status has been recorded
+               if (authRespParse.status != CASA_STATUS_SUCCESS)
+               {
+                  retStatus = authRespParse.status;
+               }
+               else
+               {
+                  retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                              CASA_FACILITY_AUTHTOKEN,
+                                              CASA_STATUS_PROTOCOL_ERROR);
+               }
+            }
+         }
+         else
+         {
+            DbgTrace(0, "-CreateAuthenticateResp- Parse error %d\n", XML_GetErrorCode(p));
+            retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                        CASA_FACILITY_AUTHTOKEN,
+                                        CASA_STATUS_PROTOCOL_ERROR);
+         }
+
+         // Free the parser
+         XML_ParserFree(p);
+      }
+      else
+      {
+         DbgTrace(0, "-CreateAuthenticateResp- Parser creation error\n", 0);
+         retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                     CASA_FACILITY_AUTHTOKEN,
+                                     CASA_STATUS_INSUFFICIENT_RESOURCES);
+      }
+
+      // Return the AuthenticationResp object to the caller if necessary
+      if (CASA_SUCCESS(retStatus))
+      {
+         *ppAuthenticateResp = pAuthenticateResp;
+      }
+      else
+      {
+         free(pAuthenticateResp);
+      }
+   }
+   else
+   {
+      DbgTrace(0, "-CreateAuthenticateResp- Memory allocation error\n", 0);
+      retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                  CASA_FACILITY_AUTHTOKEN,
+                                  CASA_STATUS_INSUFFICIENT_RESOURCES);
+   }
+
+   DbgTrace(1, "-CreateAuthenticateResp- End, retStatus = %08X\n", retStatus);
+
+   return retStatus;
+}
+
+
+//++=======================================================================
+void
+RelAuthenticateResp(
+   IN    AuthenticateResp *pAuthenticateResp)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L0
+//=======================================================================--
+{
+   DbgTrace(1, "-RelAuthenticateResp- Start\n", 0);
+
+   // Free the resources associated with the object
+   if (pAuthenticateResp->pToken)
+      free(pAuthenticateResp->pToken);
+
+   free(pAuthenticateResp);
+
+   DbgTrace(1, "-RelAuthenticateResp- End\n", 0);
+}
+
diff --git a/auth_token/client/client.vcproj b/auth_token/client/client.vcproj
new file mode 100644
index 00000000..048b2283
--- /dev/null
+++ b/auth_token/client/client.vcproj
@@ -0,0 +1,206 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="client"
+	ProjectGUID="{7BD9A5DB-DE7D-40B7-A397-04182DC2F632}"
+	RootNamespace="client"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)client\win32\$(ConfigurationName)"
+			IntermediateDirectory="$(SolutionDir)client\win32\$(ConfigurationName)"
+			ConfigurationType="2"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/D &quot;XML_STATIC&quot;"
+				Optimization="0"
+				AdditionalIncludeDirectories=".;win32;..\..\include;..\..\..\Expat-2.0.0\source\lib"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="5"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="4"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				IgnoreImportLibrary="FALSE"
+				AdditionalOptions="/EXPORT:ObtainAuthToken"
+				AdditionalDependencies="ws2_32.lib winhttp.lib libexpatml.lib"
+				OutputFile="$(OutDir)/authtoken.dll"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="&quot;..\..\..\Expat-2.0.0\StaticLibs&quot;"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/client.pdb"
+				SubSystem="0"
+				ImportLibrary="$(OutDir)/$(TargetName).lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				CommandLine="mkdir \&quot;Program Files&quot;\novell\
+mkdir \&quot;Program Files&quot;\novell\casa
+mkdir \&quot;Program Files&quot;\novell\casa\lib\
+copy $(OutDir)\authtoken.dll \&quot;Program Files&quot;\novell\casa\lib\authtoken.dll
+copy $(OutDir)\authtoken.lib \&quot;Program Files&quot;\novell\casa\lib\authtoken.lib
+"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)client\win32\$(ConfigurationName)"
+			IntermediateDirectory="$(SolutionDir)client\win32\$(ConfigurationName)"
+			ConfigurationType="2"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/D &quot;XML_STATIC&quot;"
+				AdditionalIncludeDirectories=".;win32;..\..\include;..\..\..\Expat-2.0.0\source\lib"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+				RuntimeLibrary="4"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions="/EXPORT:ObtainAuthToken"
+				AdditionalDependencies="ws2_32.lib winhttp.lib libexpatml.lib"
+				OutputFile="$(OutDir)/authtoken.dll"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="&quot;..\..\..\Expat-2.0.0\StaticLibs&quot;"
+				GenerateDebugInformation="TRUE"
+				SubSystem="0"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				ImportLibrary="$(OutDir)/$(TargetName).lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				CommandLine="mkdir \&quot;Program Files&quot;\novell\
+mkdir \&quot;Program Files&quot;\novell\casa
+mkdir \&quot;Program Files&quot;\novell\casa\lib\
+copy $(OutDir)\authtoken.dll \&quot;Program Files&quot;\novell\casa\lib\authtoken.dll
+copy $(OutDir)\authtoken.lib \&quot;Program Files&quot;\novell\casa\lib\authtoken.lib
+"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+			<File
+				RelativePath=".\authmech.c">
+			</File>
+			<File
+				RelativePath=".\authmsg.c">
+			</File>
+			<File
+				RelativePath=".\win32\authtoken.def">
+			</File>
+			<File
+				RelativePath=".\win32\cache.c">
+			</File>
+			<File
+				RelativePath=".\config.c">
+			</File>
+			<File
+				RelativePath=".\win32\dllsup.c">
+			</File>
+			<File
+				RelativePath=".\engine.c">
+			</File>
+			<File
+				RelativePath=".\getpolicymsg.c">
+			</File>
+			<File
+				RelativePath=".\gettokenmsg.c">
+			</File>
+			<File
+				RelativePath=".\win32\platutils.c">
+			</File>
+			<File
+				RelativePath=".\win32\rpc.c">
+			</File>
+			<File
+				RelativePath=".\util.c">
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+			<File
+				RelativePath=".\internal.h">
+			</File>
+			<File
+				RelativePath=".\list_entry.h">
+			</File>
+			<File
+				RelativePath=".\mech_if.h">
+			</File>
+			<File
+				RelativePath=".\win32\platform.h">
+			</File>
+			<File
+				RelativePath=".\proto.h">
+			</File>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/auth_token/client/config.c b/auth_token/client/config.c
new file mode 100644
index 00000000..fa6c601b
--- /dev/null
+++ b/auth_token/client/config.c
@@ -0,0 +1,685 @@
+/***********************************************************************
+ * 
+ *  Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; version 2.1
+ *  of the License.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, Novell, Inc.
+ * 
+ *  To contact Novell about this file by physical or electronic mail, 
+ *  you may find current contact information at www.novell.com.
+ * 
+ *  Author: Juan Carlos Luciani <jluciani@novell.com>
+ *
+ ***********************************************************************/
+
+
+//===[ Include files ]=====================================================
+
+#include "internal.h"
+
+//===[ Type definitions ]==================================================
+
+//
+// Config Key object
+// 
+typedef struct _ConfigKey
+{
+   LIST_ENTRY  listEntry;
+   char        *pKeyName;
+   int         keyNameLen;
+   char        *pValue;
+   int         valueLen;
+
+} ConfigKey, *pConfigKey;
+
+//
+// Config Interface instance data
+// 
+typedef struct _ConfigIfInstance
+{
+   LIST_ENTRY     listEntry;
+   int            refCount;
+   char           *pConfigFolder;
+   int            configFolderLen;
+   char           *pConfigName;
+   int            configNameLen;
+   LIST_ENTRY     configKeyListHead;
+   ConfigIf       configIf;
+
+} ConfigIfInstance, *PConfigIfInstance;
+
+//===[ Function prototypes ]===============================================
+
+//===[ Global variables ]==================================================
+
+// ConfigIf variables
+static
+LIST_ENTRY        g_configIfListHead = {&g_configIfListHead, &g_configIfListHead};
+
+static
+int               g_numConfigIfObjs = 0;
+
+
+//++=======================================================================
+static void
+RemoveWhiteSpaceFromTheEnd(
+   IN       const char     *pInString)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L2
+//=======================================================================--
+{
+   char  *pLineEnd = (char*) pInString + strlen(pInString) - 1;
+
+
+   DbgTrace(3, "-RemoveWhiteSpaceFromTheEnd- Start\n", 0);
+
+   while (pLineEnd != pInString)
+   {
+      if (*pLineEnd == '\n'
+          || *pLineEnd == ' '
+          || *pLineEnd == '\t')
+      {
+         // Strike this character
+         *pLineEnd = '\0';
+         pLineEnd --;
+      }
+      else
+      {
+         // Found a non-white character
+         break;
+      }
+   }
+
+   DbgTrace(3, "-RemoveWhiteSpaceFromTheEnd- End\n", 0);
+}
+
+
+//++=======================================================================
+static char*
+SkipWhiteSpace(
+   IN       const char     *pInString)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L2
+//=======================================================================--
+{
+   char  *pOutString = (char*) pInString;
+
+   DbgTrace(3, "-SkipWhiteSpace- Start\n", 0);
+
+   while (*pOutString != '\0')
+   {
+      if (*pOutString == '\n'
+          || *pOutString == ' '
+          || *pOutString == '\t')
+      {
+         // Skip this character
+         pOutString ++;
+      }
+      else
+      {
+         // Found a non-white character
+         break;
+      }
+   }
+
+   DbgTrace(3, "-SkipWhiteSpace- End\n", 0);
+
+   return pOutString;
+}
+
+
+//++=======================================================================
+static char*
+SkipNonWhiteSpace(
+   IN       const char     *pInString)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L2
+//=======================================================================--
+{
+   char  *pOutString = (char*) pInString;
+
+   DbgTrace(3, "-SkipNonWhiteSpace- Start\n", 0);
+
+   while (*pOutString != '\0')
+   {
+      if (*pOutString == '\n'
+          || *pOutString == ' '
+          || *pOutString == '\t')
+      {
+         // Found a white character
+         break;
+      }
+      else
+      {
+         // Skip this character
+         pOutString ++;
+      }
+   }
+
+   DbgTrace(3, "-SkipNonWhiteSpace- End\n", 0);
+
+   return pOutString;
+}
+
+
+//++=======================================================================
+static void
+LowerCaseString(
+   IN       char        *pDestString,
+   IN       const char  *pSrcString)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L2
+//=======================================================================--
+{
+   int   i;
+
+   DbgTrace(3, "-LowerCaseString- Start\n", 0);
+
+   // Copy the string as lower case
+   for (i = 0; pSrcString[i] != '\0'; i++)
+   {
+      if (isalpha(pSrcString[i]))
+         pDestString[i] = tolower(pSrcString[i]);
+      else
+         pDestString[i] = pSrcString[i];
+   }
+
+   // Null terminate the destination string
+   pDestString[i] = '\0';
+
+   DbgTrace(3, "-LowerCaseString- End\n", 0);
+}
+
+
+//++=======================================================================
+int SSCS_CALL
+ConfigIf_AddReference(
+   IN       const void  *pIfInstance)
+//
+// Arguments:  
+//    pIfInstance -
+//       Pointer to interface object.
+//   
+// Returns:
+//    Interface reference count.
+//                           
+// Description:
+//    Increases interface reference count.
+//
+// L2
+//=======================================================================--
+{
+   int               refCount;
+   ConfigIfInstance  *pConfigIfInstance = CONTAINING_RECORD(pIfInstance, ConfigIfInstance, configIf);
+
+   DbgTrace(2, "-ConfigIf_AddReference- Start\n", 0);
+
+   // Increment the reference count on the object
+   pConfigIfInstance->refCount ++;
+   refCount = pConfigIfInstance->refCount;
+
+   DbgTrace(2, "-ConfigIf_AddReference- End, refCount = %08X\n", refCount);
+
+   return refCount;
+}
+
+
+//++=======================================================================
+void SSCS_CALL
+ConfigIf_ReleaseReference(
+   IN       const void  *pIfInstance)
+//
+// Arguments:  
+//    pIfInstance -
+//       Pointer to interface object.
+//   
+// Returns:
+//    Nothing.
+//                           
+// Description:
+//    Decreases interface reference count. The interface is deallocated if
+//    the reference count becomes zero.
+//
+// L2
+//=======================================================================--
+{
+   bool              freeObj = false;
+   ConfigIfInstance  *pConfigIfInstance = CONTAINING_RECORD(pIfInstance, ConfigIfInstance, configIf);
+
+   DbgTrace(2, "-ConfigIf_ReleaseReference- Start\n", 0);
+
+   // Decrement the reference count on the object and determine if it needs to
+   // be released.
+   pConfigIfInstance->refCount --;
+   if (pConfigIfInstance->refCount == 0)
+   {
+      // The object needs to be released, forget about it.
+      freeObj = true;
+      g_numConfigIfObjs --;
+      RemoveEntryList(&pConfigIfInstance->listEntry);
+   }
+
+   // Free object if necessary
+   if (freeObj)
+   {
+      // Free all of the config key objects associated with this configuration
+      // interface instance.
+      while (!IsListEmpty(&pConfigIfInstance->configKeyListHead))
+      {
+         LIST_ENTRY  *pListEntry;
+         ConfigKey   *pConfigKey;
+
+         // Get reference to entry at the head of the list
+         pListEntry = pConfigIfInstance->configKeyListHead.Flink;
+         pConfigKey = CONTAINING_RECORD(pListEntry, ConfigKey, listEntry);
+
+         // Free the buffers associated with the ConfigKey
+         free(pConfigKey->pKeyName);
+         free(pConfigKey->pValue);
+
+         // Remove the entry from the list
+         RemoveEntryList(&pConfigKey->listEntry);
+
+         // Finish freeing the ConfigKey
+         free(pConfigKey);
+      }
+
+      // Free the rest of the buffers associated with the interface instance data
+      free(pConfigIfInstance->pConfigFolder);
+      free(pConfigIfInstance->pConfigName);
+      free(pConfigIfInstance);
+   }
+
+   DbgTrace(2, "-ConfigIf_ReleaseReference- End\n", 0);
+}
+
+
+//++=======================================================================
+char* SSCS_CALL
+ConfigIf_GetEntryValue(
+   IN       const void  *pIfInstance,
+   IN       const char  *pKeyName)
+//
+// Arguments:  
+//    pIfInstance -
+//       Pointer to interface object.
+//   
+//    pKeyName -
+//       Pointer to NULL terminated string that contains the
+//       name of the key whose value is being requested.
+//               
+// Returns:
+//    Pointer to NULL terminated string with value being requested or NULL.
+//                           
+// Description:
+//    Gets value associated with a key for the configuration object.
+//
+// L2
+//=======================================================================--
+{
+   ConfigIfInstance  *pConfigIfInstance = CONTAINING_RECORD(pIfInstance, ConfigIfInstance, configIf);
+   char              *pValue = NULL;
+   LIST_ENTRY        *pListEntry;
+   ConfigKey         *pConfigKey;
+   int               keyNameLen = (int) strlen(pKeyName);
+   char              *pKeyNameLowercase;
+
+   DbgTrace(2, "-ConfigIf_GetEntryValue- Start\n", 0);
+
+   // Allocate enough space to hold lower case version of the key name
+   pKeyNameLowercase = (char*) malloc(keyNameLen + 1);
+   if (pKeyNameLowercase)
+   {
+      // Lower case the key name
+      LowerCaseString(pKeyNameLowercase, pKeyName);
+
+      // Try to find matching ConfigKey
+      pListEntry = pConfigIfInstance->configKeyListHead.Flink;
+      while (pListEntry != &pConfigIfInstance->configKeyListHead)
+      {
+         // Get pointer to the current entry
+         pConfigKey = CONTAINING_RECORD(pListEntry, ConfigKey, listEntry);
+
+         // Check if we have a match
+         if (pConfigKey->keyNameLen == keyNameLen
+             && memcmp(pKeyNameLowercase, pConfigKey->pKeyName, keyNameLen) == 0)
+         {
+            // We found it, return its value.
+            pValue = (char*) malloc(pConfigKey->valueLen + 1);
+            if (pValue)
+            {
+               strcpy(pValue, pConfigKey->pValue);
+            }
+            else
+            {
+               DbgTrace(0, "-ConfigIf_GetEntryValue- Buffer allocation failure\n", 0);
+            }
+            break;
+         }
+
+         // Advance to the next entry
+         pListEntry = pListEntry->Flink;
+      }
+
+      // Free the lower case version of the key name
+      free(pKeyNameLowercase);
+   }
+   else
+   {
+      DbgTrace(0, "-ConfigIf_GetEntryValue- Buffer allocation failure\n", 0);
+   }
+
+   DbgTrace(2, "-ConfigIf_GetEntryValue- End, pValue = %08X\n", (unsigned int) pValue);
+
+   return pValue;
+}
+
+
+
+//++=======================================================================
+CasaStatus
+GetConfigInterface(
+   IN       const char  *pConfigFolder,
+   IN       const char  *pConfigName,
+   INOUT    ConfigIf    **ppConfigIf)
+//
+// Arguments:  
+//    pConfigFolder -
+//       Pointer to NULL terminated string that contains the name of
+//       the folder containing the configuration file.
+//               
+//    pConfigName -
+//       Pointer to NULL terminated string containing the name of the
+//       configuration entry.
+//
+//    ppConfigIf -
+//       Pointer to variable that will receive pointer to ConfigIf
+//       instance.
+//   
+// Returns:
+//    Casa Status
+//                           
+// Description:
+//    Get configuration interface to specified configuration entry.
+//
+// L2
+//=======================================================================--
+{
+   int               configFolderLen = (int) strlen(pConfigFolder);
+   int               configNameLen = (int)strlen(pConfigName);
+   ConfigIfInstance  *pConfigIfInstance;
+   LIST_ENTRY        *pListEntry;
+   CasaStatus        retStatus = CasaStatusBuild(CASA_SEVERITY_INFORMATIONAL,
+                                                 CASA_FACILITY_AUTHTOKEN,
+                                                 CASA_STATUS_OBJECT_NOT_FOUND);
+
+   DbgTrace(2, "-GetConfigInterface- Start\n", 0);
+
+   // Check if we already have an entry in our list for the configuration
+   pListEntry = g_configIfListHead.Flink;
+   while (pListEntry != &g_configIfListHead)
+   {
+      // Get pointer to the current entry
+      pConfigIfInstance = CONTAINING_RECORD(pListEntry, ConfigIfInstance, listEntry);
+
+      // Check if we have a match
+      if (pConfigIfInstance->configFolderLen == configFolderLen
+          && pConfigIfInstance->configNameLen == configNameLen
+          && memcmp(pConfigFolder, pConfigIfInstance->pConfigFolder, configFolderLen) == 0
+          && memcmp(pConfigName, pConfigIfInstance->pConfigName, configNameLen) == 0)
+      {
+         // We found it, return the ConfigIf associated with the instance data
+         // after incrementing its reference count.
+         pConfigIfInstance->refCount ++;
+         *ppConfigIf = &pConfigIfInstance->configIf;
+
+         // Success
+         retStatus = CASA_STATUS_SUCCESS;
+         break;
+      }
+
+      // Advance to the next entry
+      pListEntry = pListEntry->Flink;
+   }
+
+   // Proceed to create interface instance data for the configuration if none was found
+   if (retStatus != CASA_STATUS_SUCCESS)
+   {
+      char  *pFilePath;
+
+      // Build a string containing the configuration file path
+      pFilePath = (char*) malloc(configFolderLen + 1 + configNameLen + sizeof(".conf"));
+      if (pFilePath)
+      {
+         FILE  *pConfigFile;
+
+         strcpy(pFilePath, pConfigFolder);
+         strcat(pFilePath, pathCharString);
+         strcat(pFilePath, pConfigName);
+         strcat(pFilePath, ".conf");
+
+         // Open the configuration file for reading
+         pConfigFile = fopen(pFilePath, "r");
+         if (pConfigFile)
+         {
+            // Opened the file, create a ConfigIfInstance object for it.
+            pConfigIfInstance = (ConfigIfInstance*) malloc(sizeof(*pConfigIfInstance));
+            if (pConfigIfInstance)
+            {
+               // Initialize the list head within the instance data
+               InitializeListHead(&pConfigIfInstance->configKeyListHead);
+
+               // Initialize the ConfigIf within the instance data
+               pConfigIfInstance->configIf.addReference = ConfigIf_AddReference;
+               pConfigIfInstance->configIf.releaseReference = ConfigIf_ReleaseReference;
+               pConfigIfInstance->configIf.getEntryValue = ConfigIf_GetEntryValue;
+
+               // Save the ConfigFolder and ConfigName information within the instance data
+               pConfigIfInstance->pConfigFolder = (char*) malloc(configFolderLen + 1);
+               if (pConfigIfInstance->pConfigFolder)
+               {
+                  strcpy(pConfigIfInstance->pConfigFolder, pConfigFolder);
+                  pConfigIfInstance->configFolderLen = configFolderLen;
+
+                  pConfigIfInstance->pConfigName = (char*) malloc(configNameLen + 1);
+                  if (pConfigIfInstance->pConfigName)
+                  {
+                     strcpy(pConfigIfInstance->pConfigName, pConfigName);
+                     pConfigIfInstance->configNameLen = configNameLen;
+
+                     // Add the instance data into our list and bump up its reference count
+                     // since we did that.
+                     InsertTailList(&g_configIfListHead, &pConfigIfInstance->listEntry);
+                     pConfigIfInstance->refCount = 1;
+
+                     // At this point we want to return success to the caller even if we
+                     // experience a read error.
+                     retStatus = CASA_STATUS_SUCCESS;
+
+                     // Return the ConfigIf associated with the instance data after
+                     // incrementing its reference count.
+                     pConfigIfInstance->refCount ++;
+                     *ppConfigIf = &pConfigIfInstance->configIf;
+
+                     // Now update the instance data with the information present in the file
+                     if (fseek(pConfigFile, 0, SEEK_SET) == 0)
+                     {
+                        char  line[512];
+
+                        while (fgets(line, sizeof(line), pConfigFile) != NULL)
+                        {
+                           int   lineLength;
+
+                           RemoveWhiteSpaceFromTheEnd(line);
+
+                           lineLength = (int) strlen(line);
+                           if (lineLength != 0)
+                           {
+                              char        *pKey;
+                              char        *pKeyEnd;
+                              char        *pValue;
+                              ConfigKey   *pConfigKey;
+
+                              // Attempt to find the key
+                              pKey = SkipWhiteSpace(line);
+
+                              // Make sure that we are not dealing with an empty line or a comment
+                              if (*pKey == '\0' || *pKey == '#')
+                                 continue;
+
+                              // Go past the key
+                              pKeyEnd = SkipNonWhiteSpace(pKey);
+
+                              // Protect against a malformed line
+                              if (*pKeyEnd == '\0')
+                              {
+                                 DbgTrace(0, "-GetConfigInterface- Key found without value\n", 0);
+                                 continue;
+                              }
+
+                              // Attempt to find the value
+                              pValue = SkipWhiteSpace(pKeyEnd);
+
+                              // Protect against a malformed line
+                              if (*pValue == '\0')
+                              {
+                                 DbgTrace(0, "-GetConfigInterface- Key found without value\n", 0);
+                                 continue;
+                              }
+
+                              // Delineate the key
+                              *pKeyEnd = '\0';
+
+                              // Create a ConfigKey object for this key/value pair
+                              pConfigKey = (ConfigKey*) malloc(sizeof(*pConfigKey));
+                              if (pConfigKey)
+                              {
+                                 pConfigKey->keyNameLen = (int) strlen(pKey);
+                                 pConfigKey->pKeyName = (char*) malloc(pConfigKey->keyNameLen + 1);
+                                 if (pConfigKey->pKeyName)
+                                 {
+                                    // Save the key name in lower case
+                                    LowerCaseString(pConfigKey->pKeyName, pKey);
+
+                                    pConfigKey->valueLen = (int) strlen(pValue);
+                                    pConfigKey->pValue = (char*) malloc(pConfigKey->valueLen + 1);
+                                    if (pConfigKey->pValue)
+                                    {
+                                       strcpy(pConfigKey->pValue, pValue);
+
+                                       // The entry is ready, now associate it with the instance data.
+                                       InsertTailList(&pConfigIfInstance->configKeyListHead, &pConfigKey->listEntry);
+                                    }
+                                    else
+                                    {
+                                       DbgTrace(0, "-GetConfigInterface- Buffer allocation failure\n", 0);
+                                       free(pConfigKey->pKeyName);
+                                       free(pConfigKey);
+                                    }
+                                 }
+                                 else
+                                 {
+                                    DbgTrace(0, "-GetConfigInterface- Buffer allocation failure\n", 0);
+                                    free(pConfigKey);
+                                 }
+                              }
+                              else
+                              {
+                                 DbgTrace(0, "-GetConfigInterface- Buffer allocation failure\n", 0);
+                              }
+                           }
+                        }
+                     }
+                     else
+                     {
+                        DbgTrace(0, "-GetConfigInterface- File seek error, errno = %d\n", errno);
+                     }
+                  }
+                  else
+                  {
+                     DbgTrace(0, "-GetConfigInterface- Buffer allocation failure\n", 0);
+
+                     // Free the buffers associated with the instance data
+                     free(pConfigIfInstance->pConfigFolder);
+                     free(pConfigIfInstance);
+                  }
+               }
+               else
+               {
+                  DbgTrace(0, "-GetConfigInterface- Buffer allocation failure\n", 0);
+
+                  // Free the buffer allocated for the instance data
+                  free(pConfigIfInstance);
+               }
+            }
+            else
+            {
+               DbgTrace(0, "-GetConfigInterface- Buffer allocation failure\n", 0);
+            }
+
+            // Close the file
+            fclose(pConfigFile);
+         }
+         else
+         {
+            DbgTrace(1, "-GetConfigInterface- Unable to open config file, errno = %d\n", errno);
+         }
+      }
+      else
+      {
+         DbgTrace(0, "-GetConfigInterface- Buffer allocation error\n", 0);
+      }
+   }
+
+   DbgTrace(2, "-GetConfigInterface- End, retStatus = %08X\n", retStatus);
+
+   return retStatus;
+}
+
+
+//++=======================================================================
+//++=======================================================================
+//++=======================================================================
+
diff --git a/auth_token/client/engine.c b/auth_token/client/engine.c
new file mode 100644
index 00000000..fcf28fec
--- /dev/null
+++ b/auth_token/client/engine.c
@@ -0,0 +1,626 @@
+/***********************************************************************
+ * 
+ *  Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; version 2.1
+ *  of the License.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, Novell, Inc.
+ * 
+ *  To contact Novell about this file by physical or electronic mail, 
+ *  you may find current contact information at www.novell.com.
+ * 
+ *  Author: Juan Carlos Luciani <jluciani@novell.com>
+ *
+ ***********************************************************************/
+
+
+//===[ Include files ]=====================================================
+
+#include "internal.h"
+
+//===[ Type definitions ]==================================================
+
+#define DEFAULT_RETRY_LIFETIME  5  // seconds
+
+//===[ Function prototypes ]===============================================
+
+//===[ Global variables ]==================================================
+
+//
+// Debug tracing level
+// 
+int   DebugLevel = 0;
+
+//
+// Operating parameter
+// 
+bool  secureRpcSetting = false;
+int   retryLifetime = DEFAULT_RETRY_LIFETIME;
+
+
+//++=======================================================================
+static
+CasaStatus
+ObtainSessionToken(
+   IN    RpcSession *pRpcSession,
+   IN    char *pHostName,
+   IN    AuthPolicy *pAuthPolicy,
+   INOUT char **ppSessionToken)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L0
+//=======================================================================--
+{
+   CasaStatus     retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                              CASA_FACILITY_AUTHTOKEN,
+                                              CASA_STATUS_UNSUCCESSFUL);
+   LIST_ENTRY     *pListEntry;
+   AuthCacheEntry *pCacheEntry = NULL;
+
+   DbgTrace(1, "-ObtainSessionToken- Start\n", 0);
+
+   // Initialize output parameter
+   *ppSessionToken = NULL;
+
+   // Look in our cache for an entry that matches one of the auth
+   // contexts specified in the AuthPolicy object.
+   pListEntry = pAuthPolicy->authContextListHead.Flink;
+   while (pListEntry != &pAuthPolicy->authContextListHead)
+   {
+      AuthContext *pAuthContext;
+
+      // Get pointer to AuthContext structure
+      pAuthContext = CONTAINING_RECORD(pListEntry, AuthContext, listEntry);
+
+      // Try to find a cache entry for the auth context
+      pCacheEntry = FindEntryInAuthCache(pAuthContext->pContext, pHostName);
+      if (pCacheEntry != NULL)
+      {
+         // Cache entry found, update the return status with the information
+         // saved in it and stop looking.
+         retStatus = pCacheEntry->status;
+         break;
+      }
+
+      // Advance to the next entry
+      pListEntry = pListEntry->Flink;
+   }
+
+   // If we did not find a cache entry that we can use, then Try to create one.
+   pListEntry = pAuthPolicy->authContextListHead.Flink;
+   while (!CASA_SUCCESS(retStatus)
+          && pListEntry != &pAuthPolicy->authContextListHead)
+   {
+      AuthContext *pAuthContext;
+      char        *pAuthMechToken;
+
+      // Get pointer to AuthContext structure
+      pAuthContext = CONTAINING_RECORD(pListEntry, AuthContext, listEntry);
+
+      // Get authentication mechanism token
+      retStatus = GetAuthMechToken(pAuthContext, &pAuthMechToken);
+      if (!CASA_SUCCESS(retStatus))
+      {
+         // We were not able to obtain an authentication mechanism token
+         // for the context.
+         //
+         // Advance to the next entry
+         pListEntry = pListEntry->Flink;
+         continue;
+      }
+
+      // Create a cache entry for the auth context
+      pCacheEntry = CreateAuthCacheEntry(pAuthContext->pContext,  pHostName);
+      if (pCacheEntry)
+      {
+         char  *pReqMsg = NULL;
+         char  *pRespMsg = NULL;
+         int   respLen;
+         int   cacheEntryLifetime = retryLifetime;   // Initialize to retry in case of failure
+
+         // Request auth token for the service
+         pReqMsg = BuildAuthenticateMsg(pAuthContext, pAuthMechToken);
+         if (pReqMsg)
+         {
+            // Issue rpc
+            retStatus = Rpc(pRpcSession,
+                            pAuthContext->pMechanism,
+                            secureRpcSetting,
+                            pReqMsg,
+                            &pRespMsg,
+                            &respLen);
+            if (CASA_SUCCESS(retStatus))
+            {
+               AuthenticateResp     *pAuthenticateResp;
+
+               // Create Authenticate response object
+               retStatus = CreateAuthenticateResp(pRespMsg, respLen, &pAuthenticateResp);
+               if (CASA_SUCCESS(retStatus))
+               {
+                  // Return the auth token to the caller
+                  pCacheEntry->pToken = pAuthenticateResp->pToken;
+                  pAuthenticateResp->pToken = NULL; // To keep us from freeing the buffer
+                  cacheEntryLifetime = pAuthenticateResp->tokenLifetime;
+
+                  // Free the Authenticate response object
+                  RelAuthenticateResp(pAuthenticateResp);
+               }
+            }
+            else
+            {
+               DbgTrace(0, "-ObtainSessionToken- Authenticate Rpc failure, error = %08X\n", retStatus);
+            }
+         }
+         else
+         {
+            DbgTrace(0, "-ObtainSessionToken- Error building Authenticate msg\n", 0);
+            retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                        CASA_FACILITY_AUTHTOKEN,
+                                        CASA_STATUS_INSUFFICIENT_RESOURCES);
+         }
+
+         // Add the entry to the cache if successful or if the reason that we failed
+         // was because the server was unavailable.
+         if (CASA_SUCCESS(retStatus)
+             || CasaStatusCode(retStatus) == CASA_STATUS_AUTH_SERVER_UNAVAILABLE)
+         {
+            pCacheEntry->status = retStatus;
+            AddEntryToAuthCache(pCacheEntry, cacheEntryLifetime);
+         }
+         else
+         {
+            // Free the entry
+            FreeAuthCacheEntry(pCacheEntry);
+         }
+      }
+      else
+      {
+         DbgTrace(0, "-ObtainSessionToken- Cache entry creation failure\n", 0);
+         retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                     CASA_FACILITY_AUTHTOKEN,
+                                     CASA_STATUS_INSUFFICIENT_RESOURCES);
+
+         // Stop trying after freeing up the buffer associated with
+         // the authentication mechanism token.
+         free(pAuthMechToken);
+         break;
+      }
+
+      // Free up the buffer associated with the authentication mechanism token
+      free(pAuthMechToken);
+
+      // Advance to the next entry
+      pListEntry = pListEntry->Flink;
+   }
+
+   // Return session token if successful
+   if (CASA_SUCCESS(retStatus))
+   {
+      // Allocate a buffer for the return token
+      *ppSessionToken = (char*) malloc(strlen(pCacheEntry->pToken) + 1);
+      if (*ppSessionToken)
+      {
+         // Copy the token onto the allocated buffer
+         strcpy(*ppSessionToken, pCacheEntry->pToken);
+      }
+      else
+      {
+         DbgTrace(0, "-ObtainSessionToken- Buffer allocation failure\n", 0);
+         retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                     CASA_FACILITY_AUTHTOKEN,
+                                     CASA_STATUS_INSUFFICIENT_RESOURCES);
+      }
+   }
+
+   DbgTrace(1, "-ObtainSessionToken- End, retStatus = %08X\n", retStatus);
+
+   return retStatus;
+}
+
+
+//++=======================================================================
+static
+CasaStatus
+ObtainAuthTokenFromServer(
+   IN    char *pServiceName,
+   IN    char *pHostName,
+   INOUT char **ppAuthToken,
+   INOUT int *pTokenLifetime)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L0
+//=======================================================================--
+{
+   CasaStatus  retStatus = CASA_STATUS_SUCCESS;
+   RpcSession  *pRpcSession;
+
+   DbgTrace(1, "-ObtainAuthTokenFromServer- Start\n", 0);
+
+   // Initialize output parameter
+   *ppAuthToken = NULL;
+
+   // Open Rpc Session to the auth service at the specified host
+   pRpcSession = OpenRpcSession(pHostName);
+   if (pRpcSession)
+   {
+      char                 *pReqMsg = NULL;
+      char                 *pRespMsg = NULL;
+      int                  respLen;
+      AuthPolicy           *pAuthPolicy = NULL;
+      GetAuthPolicyResp    *pGetAuthPolicyResp = NULL;
+      GetAuthTokenResp     *pGetAuthTokenResp = NULL;
+      char                 *pSessionToken = NULL;
+
+      // Request the auth parameters associated with this service
+      pReqMsg = BuildGetAuthPolicyMsg(pServiceName, pHostName);
+      if (pReqMsg)
+      {
+         // Issue rpc
+         retStatus = Rpc(pRpcSession,
+                         "GetAuthPolicy",
+                         secureRpcSetting,
+                         pReqMsg,
+                         &pRespMsg,
+                         &respLen);
+         if (CASA_SUCCESS(retStatus))
+         {
+            // Create GetAuthPolicy response object
+            retStatus = CreateGetAuthPolicyResp(pRespMsg, respLen, &pGetAuthPolicyResp);
+            if (CASA_SUCCESS(retStatus))
+            {
+               // Create the AuthPolicy object
+               retStatus = CreateAuthPolicy(pGetAuthPolicyResp->pPolicy,
+                                            pGetAuthPolicyResp->policyLen,
+                                            &pAuthPolicy);
+               if (CASA_SUCCESS(retStatus))
+               {
+                  // Now try to obtain a session token
+                  retStatus = ObtainSessionToken(pRpcSession, pHostName, pAuthPolicy, &pSessionToken);
+                  if (CASA_SUCCESS(retStatus))
+                  {
+                     // Request auth token for the service
+                     free(pReqMsg);
+                     pReqMsg = BuildGetAuthTokenMsg(pServiceName, pHostName, pSessionToken);
+                     if (pReqMsg)
+                     {
+                        // Free the previous response msg buffer
+                        free(pRespMsg);
+                        pRespMsg = NULL;
+
+                        // Issue rpc
+                        retStatus = Rpc(pRpcSession,
+                                        "GetAuthToken",
+                                        secureRpcSetting,
+                                        pReqMsg,
+                                        &pRespMsg,
+                                        &respLen);
+                        if (CASA_SUCCESS(retStatus))
+                        {
+                           // Create GetAuthPolicy response object
+                           retStatus = CreateGetAuthTokenResp(pRespMsg, respLen, &pGetAuthTokenResp);
+                           if (CASA_SUCCESS(retStatus))
+                           {
+                              // Return the auth token to the caller
+                              *ppAuthToken = pGetAuthTokenResp->pToken;
+                              pGetAuthTokenResp->pToken = NULL; // To keep us from freeing the buffer
+                              *pTokenLifetime = pGetAuthTokenResp->tokenLifetime;
+                           }
+                        }
+                        else
+                        {
+                           DbgTrace(0, "-ObtainAuthTokenFromServer- GetAuthToken Rpc failure, error = %08X\n", retStatus);
+                        }
+                     }
+                     else
+                     {
+                        DbgTrace(0, "-ObtainAuthTokenFromServer- Error building GetAuthToken msg\n", 0);
+                        retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                                    CASA_FACILITY_AUTHTOKEN,
+                                                    CASA_STATUS_INSUFFICIENT_RESOURCES);
+                     }
+                  }
+                  else
+                  {
+                     DbgTrace(1, "-ObtainAuthTokenFromServer- Failed to obtain session token, error = %08X\n", retStatus);
+                  }
+               }
+            }
+         }
+         else
+         {
+            DbgTrace(0, "-ObtainAuthTokenFromServer- GetAuthPolicy Rpc failure, error = %08X\n", retStatus);
+         }
+
+         // Free resources that may be hanging around
+         if (pReqMsg)
+            free(pReqMsg);
+
+         if (pRespMsg)
+            free(pRespMsg);
+
+         if (pSessionToken)
+            free(pSessionToken);
+
+         if (pGetAuthTokenResp)
+            RelGetAuthTokenResp(pGetAuthTokenResp);
+
+         if (pGetAuthPolicyResp)
+            RelGetAuthPolicyResp(pGetAuthPolicyResp);
+
+         if (pAuthPolicy)
+            RelAuthPolicy(pAuthPolicy);
+      }
+      else
+      {
+         DbgTrace(0, "-ObtainAuthTokenFromServer- Error building GetAuthPolicy msg\n", 0);
+         retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                     CASA_FACILITY_AUTHTOKEN,
+                                     CASA_STATUS_INSUFFICIENT_RESOURCES);
+      }
+
+      // Close the Rpc Session
+      CloseRpcSession(pRpcSession);
+   }
+   else
+   {
+      DbgTrace(0, "-ObtainAuthTokenFromServer- Error opening Rpc session\n", 0);
+      retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                  CASA_FACILITY_AUTHTOKEN,
+                                  CASA_STATUS_INSUFFICIENT_RESOURCES);
+   }
+
+   DbgTrace(1, "-ObtainAuthTokenFromServer- End, retStatus = %08X\n", retStatus);
+
+   return retStatus;
+}
+
+
+//++=======================================================================
+CasaStatus SSCS_CALL
+ObtainAuthToken(
+   IN    const char *pServiceAtHostName,
+   INOUT char *pAuthTokenBuf,
+   INOUT int *pAuthTokenBufLen)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L0
+//=======================================================================--
+{
+   CasaStatus  retStatus = CASA_STATUS_SUCCESS;
+   char        *pParseString;
+
+   DbgTrace(1, "-ObtainAuthToken- Start\n", 0);
+
+   // Verify the input parameters
+   if (pServiceAtHostName == NULL
+      || pAuthTokenBufLen == NULL
+      || (*pAuthTokenBufLen != 0 && pAuthTokenBuf == NULL))
+   {
+      DbgTrace(0, "-ObtainAuthToken- Invalid parameter\n", 0);
+      retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                  CASA_FACILITY_AUTHTOKEN,
+                                  CASA_STATUS_INVALID_PARAMETER);
+      goto exit;
+   }
+
+   // Allocate space to copy the service name string
+   pParseString = (char*) malloc(strlen(pServiceAtHostName) + 1);
+   if (pParseString)
+   {
+      char  *pServiceName, *pHostName;
+
+      // Space allocated, now copy the string onto it
+      // and parse it into its components.
+      strcpy(pParseString, pServiceAtHostName);
+      pServiceName = strtok(pParseString, "@");
+      pHostName = strtok(NULL, "@");
+      if (pHostName == NULL)
+      {
+         DbgTrace(0, "-ObtainAuthToken- Missing host name\n", 0);
+         retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                     CASA_FACILITY_AUTHTOKEN,
+                                     CASA_STATUS_INVALID_PARAMETER);
+      }
+      else
+      {
+         AuthCacheEntry *pCacheEntry;
+         char           *pNormalizedHostName;
+
+         printf("Obtaining auth token for Service = %s at Host = %s", pServiceName, pHostName);
+
+         // Normalize the host name
+         pNormalizedHostName = NormalizeHostName(pHostName);
+         if (pNormalizedHostName)
+         {
+            // Start user process synchronization
+            LockUserMutex();
+
+            // Try to find a cache entry for the service
+            pCacheEntry = FindEntryInAuthCache(pServiceName, pNormalizedHostName);
+            if (pCacheEntry == NULL)
+            {
+               // No entry found in the cache, create one.
+               pCacheEntry = CreateAuthCacheEntry(pServiceName, pNormalizedHostName);
+               if (pCacheEntry)
+               {
+                  int   cacheEntryLifetime = retryLifetime; // Initialize to retry in case of failure
+
+                  // Cache entry created, now try to obtain auth token from the CASA Server
+                  retStatus = ObtainAuthTokenFromServer(pServiceName,
+                                                        pNormalizedHostName,
+                                                        &pCacheEntry->pToken,
+                                                        &cacheEntryLifetime);
+
+                  // Add the entry to the cache if successful or if the reason that we failed
+                  // was because the server was un-available.
+                  if (CASA_SUCCESS(retStatus)
+                      || CasaStatusCode(retStatus) == CASA_STATUS_AUTH_SERVER_UNAVAILABLE)
+                  {
+                     pCacheEntry->status = retStatus;
+                     AddEntryToAuthCache(pCacheEntry, cacheEntryLifetime);
+                  }
+                  else
+                  {
+                     // Free the entry
+                     FreeAuthCacheEntry(pCacheEntry);
+                  }
+               }
+               else
+               {
+                  DbgTrace(0, "-ObtainAuthToken- Cache entry creation failure\n", 0);
+                  retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                              CASA_FACILITY_AUTHTOKEN,
+                                              CASA_STATUS_INSUFFICIENT_RESOURCES);
+               }
+            }
+            else
+            {
+               // Cache entry found, update the return status with the information saved in it.
+               retStatus = pCacheEntry->status;
+            }
+
+            // Try to return auth token if we have one to return
+            if (CASA_SUCCESS(retStatus))
+            {
+               int   tokenLen = (int) strlen(pCacheEntry->pToken) + 1;
+
+               // We have an authentication token, try to return it to the caller.
+               if (pAuthTokenBuf)
+               {
+                  // Verify that the supplied buffer is big enough
+                  if (*pAuthTokenBufLen >= tokenLen)
+                  {
+                     // Return the auth token to the caller
+                     strcpy(pAuthTokenBuf, pCacheEntry->pToken);
+                  }
+                  else
+                  {
+                     DbgTrace(0, "-ObtainAuthToken- The supplied buffer is not large enough", 0);
+                     retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                                 CASA_FACILITY_AUTHTOKEN,
+                                                 CASA_STATUS_BUFFER_OVERFLOW);
+                  }
+
+                  // Notify the caller about the token length
+                  *pAuthTokenBufLen = tokenLen;
+               }
+               else
+               {
+                  // The caller just wants the length of buffer that is required to
+                  // obtain the token.
+                  *pAuthTokenBufLen = tokenLen;
+               }
+            }
+
+            // Stop user process synchronization
+            FreeUserMutex();
+
+            // Free the space allocated for the normalized host name
+            free(pNormalizedHostName);
+         }
+         else
+         {
+            DbgTrace(0, "-ObtainAuthToken- Host name normalization failed\n", 0);
+            retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                        CASA_FACILITY_AUTHTOKEN,
+                                        CASA_STATUS_UNSUCCESSFUL);
+         }
+      }
+
+      // Free allocated space
+      free(pParseString);
+   }
+   else
+   {
+      DbgTrace(0, "-ObtainAuthToken- Buffer allocation error\n", 0);
+   }
+
+exit:
+
+   DbgTrace(1, "-ObtainAuthToken- End, retStatus = %08X\n", retStatus);
+
+   return retStatus;
+}
+
+
+//++=======================================================================
+int
+InitializeLibrary(void)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L0
+//=======================================================================--
+{
+   int   retStatus = -1;
+
+   DbgTrace(1, "-InitializeLibrary- Start\n", 0);
+
+   // Create user synchronization mutex
+   if (CreateUserMutex() == 0)
+   {
+      // Initialize the auth cache
+      if (CASA_SUCCESS(InitializeAuthCache()))
+      {
+         // Initialize the host name normalization
+         if (CASA_SUCCESS(InitializeHostNameNormalization()))
+         {
+            // Success
+            retStatus = 0;
+         }
+         else
+         {
+            DbgTrace(0, "-InitializeLibrary- Error initializing host name normalization\n", 0);
+         }
+      }
+      else
+      {
+         DbgTrace(0, "-InitializeLibrary- Error initializing the auth cache\n", 0);
+      }
+   }
+   else
+   {
+      DbgTrace(0, "-InitializeLibrary- Error creating mutex for the user\n", 0);
+   }
+
+   DbgTrace(1, "-InitializeLibrary- End, retStatus = %08X\n", retStatus);
+
+   return retStatus;
+}
+
diff --git a/auth_token/client/getpolicymsg.c b/auth_token/client/getpolicymsg.c
new file mode 100644
index 00000000..51a0821d
--- /dev/null
+++ b/auth_token/client/getpolicymsg.c
@@ -0,0 +1,1309 @@
+/***********************************************************************
+ * 
+ *  Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; version 2.1
+ *  of the License.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, Novell, Inc.
+ * 
+ *  To contact Novell about this file by physical or electronic mail, 
+ *  you may find current contact information at www.novell.com.
+ * 
+ *  Author: Juan Carlos Luciani <jluciani@novell.com>
+ *
+ ***********************************************************************/
+
+
+//===[ Include files ]=====================================================
+
+#include "internal.h"
+
+//===[ Type definitions ]==================================================
+
+//
+// Parse states
+//
+#define AWAITING_ROOT_ELEMENT_START             0x0
+#define AWAITING_ROOT_ELEMENT_END               0x1
+#define AWAITING_STATUS_ELEMENT_START           0x2
+#define AWAITING_STATUS_ELEMENT_END             0x3
+#define AWAITING_STATUS_DATA                    0x4
+#define AWAITING_DESCRIPTION_ELEMENT_START      0x5
+#define AWAITING_DESCRIPTION_ELEMENT_END        0x6
+#define AWAITING_DESCRIPTION_DATA               0x7
+#define AWAITING_SESSION_TOKEN_ELEMENT_START    0x8
+#define AWAITING_SESSION_TOKEN_ELEMENT_END      0x9
+#define AWAITING_SESSION_TOKEN_DATA             0xA
+#define AWAITING_LIFETIME_DATA                  0xB
+#define AWAITING_LIFETIME_ELEMENT_START         0xC
+#define AWAITING_LIFETIME_ELEMENT_END           0xD
+#define AWAITING_AUTH_TOKEN_ELEMENT_START       0xE
+#define AWAITING_AUTH_TOKEN_ELEMENT_END         0xF
+#define AWAITING_AUTH_TOKEN_DATA                0x10
+#define AWAITING_AUTH_POLICY_ELEMENT_START      0x11
+#define AWAITING_AUTH_POLICY_ELEMENT_END        0x12
+#define AWAITING_AUTH_POLICY_DATA               0x13
+#define AWAITING_AUTH_SOURCE_ELEMENT_START      0x14
+#define AWAITING_AUTH_SOURCE_ELEMENT_END        0x15
+#define AWAITING_AUTH_SOURCE_CHILD_START        0x16
+#define AWAITING_REALM_DATA                     0x17
+#define AWAITING_REALM_ELEMENT_END              0x18
+#define AWAITING_MECHANISM_DATA                 0x19
+#define AWAITING_MECHANISM_ELEMENT_END          0x1A
+#define AWAITING_MECHANISM_INFO_DATA            0x1B
+#define AWAITING_MECHANISM_INFO_ELEMENT_END     0x1C
+#define AWAITING_UNKNOWN_DATA                   0x1D
+#define AWAITING_UNKNOWN_ELEMENT_END            0x1E
+#define DONE_PARSING                            0x1F
+
+//
+// Authentication Policy Parse Structure
+//
+typedef struct _AuthPolicyParse
+{
+   XML_Parser              p;
+   int                     state;
+   AuthPolicy              *pAuthPolicy;
+   CasaStatus              status;
+
+} AuthPolicyParse, *PAuthPolicyParse;
+
+
+//
+// Get Authentication Policy Response Parse Structure
+//
+typedef struct _GetAuthPolicyRespParse
+{
+   XML_Parser              p;
+   int                     state;
+   GetAuthPolicyResp       *pGetAuthPolicyResp;
+   CasaStatus              status;
+
+} GetAuthPolicyRespParse, *PGetAuthPolicyRespParse;
+
+
+//===[ Function prototypes ]===============================================
+
+//===[ Global variables ]==================================================
+
+//++=======================================================================
+static
+void XMLCALL
+AuthPolicyStartElementHandler(
+   IN    AuthPolicyParse *pAuthPolicyParse,
+   IN    const XML_Char *name,
+   IN    const XML_Char **atts)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L0
+//=======================================================================--
+{
+   DbgTrace(2, "-AuthPolicyStartElementHandler- Start\n", 0);
+
+   // Proceed based on the state
+   switch (pAuthPolicyParse->state)
+   {
+      case AWAITING_ROOT_ELEMENT_START:
+
+         // In this state, we are only expecting the Authentication
+         // Policy Element.
+         if (strcmp(name, AUTH_POLICY_ELEMENT_NAME) == 0)
+         {
+            // Good, advance to the next state.
+            pAuthPolicyParse->state = AWAITING_AUTH_SOURCE_ELEMENT_START;
+         }
+         else
+         {
+            DbgTrace(0, "-AuthPolicyStartElementHandler- Un-expected start element\n", 0);
+            XML_StopParser(pAuthPolicyParse->p, XML_FALSE);
+         }
+         break;
+
+   case AWAITING_AUTH_SOURCE_ELEMENT_START:
+   case AWAITING_ROOT_ELEMENT_END:
+
+      // In this state, we are only expecting the Authentication
+      // Source Element.
+      if (strcmp(name, AUTH_SOURCE_ELEMENT_NAME) == 0)
+      {
+         AuthContext *pAuthContext;
+
+         // Create an authentication context structure
+         pAuthContext = (AuthContext*) malloc(sizeof(AuthContext));
+         if (pAuthContext)
+         {
+            // Initialize the allocated AuthContext structure and associate it
+            // with the AuthPolicy structure.
+            memset(pAuthContext, 0, sizeof(*pAuthContext));
+            InsertTailList(&pAuthPolicyParse->pAuthPolicy->authContextListHead, &pAuthContext->listEntry);
+         }
+         else
+         {
+            DbgTrace(0, "-AuthPolicyStartElementHandler- Buffer allocation error\n", 0);
+            XML_StopParser(pAuthPolicyParse->p, XML_FALSE);
+         }
+
+         // Good, advance to the next state.
+         pAuthPolicyParse->state = AWAITING_AUTH_SOURCE_CHILD_START;
+      }
+      else
+      {
+         DbgTrace(0, "-AuthPolicyStartElementHandler- Un-expected start element\n", 0);
+         XML_StopParser(pAuthPolicyParse->p, XML_FALSE);
+      }
+      break;
+
+      case AWAITING_AUTH_SOURCE_CHILD_START:
+
+         // Proceed based on the name of the element
+         if (strcmp(name, REALM_ELEMENT_NAME) == 0)
+         {
+            // Advance to the next state.
+            pAuthPolicyParse->state = AWAITING_REALM_DATA;
+         }
+         else if (strcmp(name, MECHANISM_ELEMENT_NAME) == 0)
+         {
+            // Advance to the next state.
+            pAuthPolicyParse->state = AWAITING_MECHANISM_DATA;
+         }
+         else if (strcmp(name, MECHANISM_INFO_ELEMENT_NAME) == 0)
+         {
+            // Advance to the next state.
+            pAuthPolicyParse->state = AWAITING_MECHANISM_INFO_DATA;
+         }
+         else if (strcmp(name, AUTH_SOURCE_ELEMENT_NAME) == 0)
+         {
+            // We are starting a new auth source entry, create an authentication
+            // context structure to hold its information.
+            AuthContext *pAuthContext;
+
+            // Create an authentication context structure
+            pAuthContext = (AuthContext*) malloc(sizeof(AuthContext));
+            if (pAuthContext)
+            {
+               // Initialize the allocated AuthContext structure and associate it
+               // with the AuthPolicy structure.
+               memset(pAuthContext, 0, sizeof(*pAuthContext));
+               InsertTailList(&pAuthPolicyParse->pAuthPolicy->authContextListHead, &pAuthContext->listEntry);
+            }
+            else
+            {
+               DbgTrace(0, "-AuthPolicyStartElementHandler- Buffer allocation error\n", 0);
+               XML_StopParser(pAuthPolicyParse->p, XML_FALSE);
+            }
+         }
+         else
+         {
+            // Advance to the next state.
+            pAuthPolicyParse->state = AWAITING_UNKNOWN_DATA;
+         }
+         break;
+   
+      default:
+         DbgTrace(0, "-AuthPolicyStartElementHandler- Un-expected state = %d\n", pAuthPolicyParse->state);
+         XML_StopParser(pAuthPolicyParse->p, XML_FALSE);
+         break;
+   }
+
+   DbgTrace(2, "-AuthPolicyStartElementHandler- End\n", 0);
+}
+
+
+//++=======================================================================
+static
+void XMLCALL
+AuthPolicyCharDataHandler(
+   IN    AuthPolicyParse *pAuthPolicyParse,
+   IN    const XML_Char *s,
+   IN    int len)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L0
+//=======================================================================--
+{
+   AuthContext *pAuthContext;
+
+   DbgTrace(2, "-AuthPolicyCharDataHandler- Start\n", 0);
+
+   // Just exit if being called to process LF and CR characters
+   if (len == 1
+       && ((*s == '\n') || (*s == '\r')))
+   {
+      goto exit;
+   }
+
+   // Proceed based on the state
+   switch (pAuthPolicyParse->state)
+   {
+      case AWAITING_REALM_DATA:
+
+         // Get access to the AuthContext at the tail of the list
+         pAuthContext = CONTAINING_RECORD(pAuthPolicyParse->pAuthPolicy->authContextListHead.Blink,
+                                          AuthContext,
+                                          listEntry);
+
+         // Keep a copy of the realm data (null terminated)
+         pAuthContext->pContext = (char*) malloc(len + 1);
+         if (pAuthContext->pContext)
+         {
+            memset(pAuthContext->pContext, 0, len + 1);
+            memcpy(pAuthContext->pContext, s, len);
+
+            // Advanced to the next state
+            pAuthPolicyParse->state = AWAITING_REALM_ELEMENT_END;
+         }
+         else
+         {
+            DbgTrace(0, "-AuthPolicyCharDataHandler- Buffer allocation failure\n", 0);
+            pAuthPolicyParse->status = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                                       CASA_FACILITY_AUTHTOKEN,
+                                                       CASA_STATUS_INSUFFICIENT_RESOURCES);
+            XML_StopParser(pAuthPolicyParse->p, XML_FALSE);
+         }
+         break;
+
+      case AWAITING_MECHANISM_DATA:
+
+         // Get access to the AuthContext at the tail of the list
+         pAuthContext = CONTAINING_RECORD(pAuthPolicyParse->pAuthPolicy->authContextListHead.Blink,
+                                          AuthContext,
+                                          listEntry);
+   
+         // Keep a copy of the mechanism data (null terminated)
+         pAuthContext->pMechanism = (char*) malloc(len + 1);
+         if (pAuthContext->pMechanism)
+         {
+            memset(pAuthContext->pMechanism, 0, len + 1);
+            memcpy(pAuthContext->pMechanism, s, len);
+   
+            // Advanced to the next state
+            pAuthPolicyParse->state = AWAITING_MECHANISM_ELEMENT_END;
+         }
+         else
+         {
+            DbgTrace(0, "-AuthPolicyCharDataHandler- Buffer allocation failure\n", 0);
+            pAuthPolicyParse->status = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                                       CASA_FACILITY_AUTHTOKEN,
+                                                       CASA_STATUS_INSUFFICIENT_RESOURCES);
+            XML_StopParser(pAuthPolicyParse->p, XML_FALSE);
+         }
+         break;
+
+      case AWAITING_MECHANISM_INFO_DATA:
+
+         // Get access to the AuthContext at the tail of the list
+         pAuthContext = CONTAINING_RECORD(pAuthPolicyParse->pAuthPolicy->authContextListHead.Blink,
+                                          AuthContext,
+                                          listEntry);
+   
+         // Keep a copy of the mechanism info data (null terminated)
+         pAuthContext->pMechInfo = (char*) malloc(len + 1);
+         if (pAuthContext->pMechInfo)
+         {
+            memset(pAuthContext->pMechInfo, 0, len + 1);
+            memcpy(pAuthContext->pMechInfo, s, len);
+   
+            // Advanced to the next state
+            pAuthPolicyParse->state = AWAITING_MECHANISM_INFO_ELEMENT_END;
+         }
+         else
+         {
+            DbgTrace(0, "-AuthPolicyCharDataHandler- Buffer allocation failure\n", 0);
+            pAuthPolicyParse->status = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                                       CASA_FACILITY_AUTHTOKEN,
+                                                       CASA_STATUS_INSUFFICIENT_RESOURCES);
+            XML_StopParser(pAuthPolicyParse->p, XML_FALSE);
+         }
+         break;
+
+      case AWAITING_UNKNOWN_DATA:
+
+         // Just advance the state
+         pAuthPolicyParse->state = AWAITING_UNKNOWN_ELEMENT_END;
+         break;
+
+      default:
+         DbgTrace(0, "-AuthPolicyCharDataHandler- Un-expected state = %d\n", pAuthPolicyParse->state);
+         XML_StopParser(pAuthPolicyParse->p, XML_FALSE);
+         break;
+   }
+
+exit:
+
+   DbgTrace(2, "-AuthPolicyCharDataHandler- End\n", 0);
+}
+
+
+//++=======================================================================
+static
+void XMLCALL
+AuthPolicyEndElementHandler(
+   IN    AuthPolicyParse *pAuthPolicyParse,
+   IN    const XML_Char *name)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L0
+//=======================================================================--
+{
+   AuthContext *pAuthContext;
+
+   DbgTrace(2, "-AuthPolicyEndElementHandler- Start\n", 0);
+
+   // Proceed based on the state
+   switch (pAuthPolicyParse->state)
+   {
+      case AWAITING_ROOT_ELEMENT_END:
+   
+         // In this state, we are only expecting the Authentication
+         // Policy Element.
+         if (strcmp(name, AUTH_POLICY_ELEMENT_NAME) == 0)
+         {
+            // Done.
+            pAuthPolicyParse->state = DONE_PARSING;
+         }
+         else
+         {
+            DbgTrace(0, "-AuthPolicyEndElementHandler- Un-expected end element\n", 0);
+            XML_StopParser(pAuthPolicyParse->p, XML_FALSE);
+         }
+         break;
+
+      case AWAITING_AUTH_SOURCE_CHILD_START:
+
+         // In this state, we are only expecting the Authentication
+         // Source Response Element.
+         if (strcmp(name, AUTH_SOURCE_ELEMENT_NAME) == 0)
+         {
+            // Good, advance to the next state.
+            pAuthPolicyParse->state = AWAITING_ROOT_ELEMENT_END;
+         }
+         else
+         {
+            DbgTrace(0, "-AuthPolicyEndHandler- Un-expected end element\n", 0);
+            XML_StopParser(pAuthPolicyParse->p, XML_FALSE);
+         }
+         break;
+
+      case AWAITING_REALM_ELEMENT_END:
+   
+         // In this state, we are only expecting the Realm Element.
+         if (strcmp(name, REALM_ELEMENT_NAME) == 0)
+         {
+            // Good, advance to the next state.
+            pAuthPolicyParse->state = AWAITING_AUTH_SOURCE_CHILD_START;
+         }
+         else
+         {
+            DbgTrace(0, "-AuthPolicyEndElementHandler- Un-expected end element\n", 0);
+            XML_StopParser(pAuthPolicyParse->p, XML_FALSE);
+         }
+         break;
+
+      case AWAITING_MECHANISM_ELEMENT_END:
+   
+         // In this state, we are only expecting the Mechanism Element.
+         if (strcmp(name, MECHANISM_ELEMENT_NAME) == 0)
+         {
+            // Good, advance to the next state.
+            pAuthPolicyParse->state = AWAITING_AUTH_SOURCE_CHILD_START;
+         }
+         else
+         {
+            DbgTrace(0, "-AuthPolicyEndElementHandler- Un-expected end element\n", 0);
+            XML_StopParser(pAuthPolicyParse->p, XML_FALSE);
+         }
+         break;
+
+      case AWAITING_MECHANISM_INFO_DATA:
+   
+         // Get access to the AuthContext at the tail of the list
+         pAuthContext = CONTAINING_RECORD(pAuthPolicyParse->pAuthPolicy->authContextListHead.Blink,
+                                          AuthContext,
+                                          listEntry);
+   
+         // There was no mechanism info data. Set it to an empty string.
+         pAuthContext->pMechInfo = (char*) malloc(1);
+         if (pAuthContext->pMechInfo)
+         {
+            *pAuthContext->pMechInfo = '\0';
+         }
+         else
+         {
+            DbgTrace(0, "-AuthPolicyEndElementHandler- Buffer allocation failure\n", 0);
+            pAuthPolicyParse->status = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                                       CASA_FACILITY_AUTHTOKEN,
+                                                       CASA_STATUS_INSUFFICIENT_RESOURCES);
+            XML_StopParser(pAuthPolicyParse->p, XML_FALSE);
+            break;
+         }
+         // Fall through
+
+      case AWAITING_MECHANISM_INFO_ELEMENT_END:
+   
+         // In this state, we are only expecting the Mechanism Info Element.
+         if (strcmp(name, MECHANISM_INFO_ELEMENT_NAME) == 0)
+         {
+            // Good, advance to the next state.
+            pAuthPolicyParse->state = AWAITING_AUTH_SOURCE_CHILD_START;
+         }
+         else
+         {
+            DbgTrace(0, "-AuthPolicyEndElementHandler- Un-expected end element\n", 0);
+            XML_StopParser(pAuthPolicyParse->p, XML_FALSE);
+         }
+         break;
+   
+      case AWAITING_UNKNOWN_ELEMENT_END:
+   
+         // Advance to the next state.
+         pAuthPolicyParse->state = AWAITING_AUTH_SOURCE_CHILD_START;
+         break;
+
+      default:
+         DbgTrace(0, "-AuthPolicyEndElementHandler- Un-expected state = %d\n", pAuthPolicyParse->state);
+         XML_StopParser(pAuthPolicyParse->p, XML_FALSE);
+         break;
+   }
+
+   DbgTrace(2, "-AuthPolicyEndElementHandler- End\n", 0);
+}
+
+
+//++=======================================================================
+CasaStatus
+CreateAuthPolicy(
+   IN    char *pEncodedData,
+   IN    int encodedDataLen,
+   INOUT AuthPolicy **ppAuthPolicy)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L0
+//=======================================================================--
+{
+   CasaStatus        retStatus;
+   AuthPolicy        *pAuthPolicy = NULL;
+   AuthPolicyParse   authPolicyParse = {0};
+   char              *pData = NULL;
+   int               dataLen = 0;
+
+   DbgTrace(1, "-CreateAuthPolicy- Start\n", 0);
+
+   // Initialize output parameter
+   *ppAuthPolicy = NULL;
+
+   // Decode the data
+   retStatus = DecodeData(pEncodedData,
+                          encodedDataLen,
+                          &pData,
+                          &dataLen);
+   if (CASA_SUCCESS(retStatus))
+   {
+      // Allocate space for the AuthPolicy structure
+      pAuthPolicy = (AuthPolicy*) malloc(sizeof(*pAuthPolicy));
+      if (pAuthPolicy)
+      {
+         XML_Parser  p;
+
+         // Initialize the list head within the structure
+         InitializeListHead(&pAuthPolicy->authContextListHead);
+
+         // Set the AuthPolicy object in the parse oject
+         authPolicyParse.pAuthPolicy = pAuthPolicy;
+
+         // Create parser
+         p = XML_ParserCreate(NULL);
+         if (p)
+         {
+            // Keep track of the parser in our parse object
+            authPolicyParse.p = p;
+
+            // Initialize the status within the parse object
+            authPolicyParse.status = CASA_STATUS_SUCCESS;
+
+            // Set the start and end element handlers
+            XML_SetElementHandler(p,
+                                  AuthPolicyStartElementHandler,
+                                  AuthPolicyEndElementHandler);
+
+            // Set the character data handler
+            XML_SetCharacterDataHandler(p, AuthPolicyCharDataHandler);
+
+            // Set our user data
+            XML_SetUserData(p, &authPolicyParse);
+
+            // Parse the document
+            if (XML_Parse(p, pData, dataLen, 1) == XML_STATUS_OK)
+            {
+               // Verify that the parse operation completed successfully
+               if (authPolicyParse.state == DONE_PARSING)
+               {
+                  // The parse operation succeded
+                  retStatus = CASA_STATUS_SUCCESS;
+               }
+               else
+               {
+                  DbgTrace(0, "-CreateAuthPolicy- Parse operation did not complete\n", 0);
+
+                  retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                              CASA_FACILITY_AUTHTOKEN,
+                                              CASA_STATUS_PROTOCOL_ERROR);
+               }
+            }
+            else
+            {
+               DbgTrace(0, "-CreateAuthPolicy- Parse error %d\n", XML_GetErrorCode(p));
+               retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                           CASA_FACILITY_AUTHTOKEN,
+                                           CASA_STATUS_PROTOCOL_ERROR);
+            }
+
+            // Free the parser
+            XML_ParserFree(p);
+         }
+         else
+         {
+            DbgTrace(0, "-CreateAuthPolicy- Parser creation error\n", 0);
+            retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                        CASA_FACILITY_AUTHTOKEN,
+                                        CASA_STATUS_INSUFFICIENT_RESOURCES);
+         }
+
+         // Return the AuthPolicy object to the caller if necessary
+         if (CASA_SUCCESS(retStatus))
+         {
+            *ppAuthPolicy = pAuthPolicy;
+         }
+      }
+      else
+      {
+         DbgTrace(0, "-CreateAuthPolicy- Buffer allocation error\n", 0);
+         retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                     CASA_FACILITY_AUTHTOKEN,
+                                     CASA_STATUS_INSUFFICIENT_RESOURCES);
+      }
+   }
+   else
+   {
+      DbgTrace(0, "-CreateAuthPolicy- Buffer allocation error\n", 0);
+      retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                  CASA_FACILITY_AUTHTOKEN,
+                                  CASA_STATUS_INSUFFICIENT_RESOURCES);
+   }
+
+   // Release allocated resources if not successful
+   if (!CASA_SUCCESS(retStatus)
+       && pAuthPolicy)
+      RelAuthPolicy(pAuthPolicy);
+
+   DbgTrace(1, "-CreateAuthPolicy- End, retStatus = %08X\n", retStatus);
+
+   return retStatus;
+}
+
+
+//++=======================================================================
+void
+RelAuthPolicy(
+   IN    AuthPolicy *pAuthPolicy)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L0
+//=======================================================================--
+{
+   LIST_ENTRY  *pListEntry;
+
+   DbgTrace(1, "-RelAuthPolicy- Start\n", 0);
+
+   // Free all of the associated AuthContexts
+   pListEntry = pAuthPolicy->authContextListHead.Flink;
+   while (pListEntry != &pAuthPolicy->authContextListHead)
+   {
+      AuthContext *pAuthContext;
+
+      // Get pointer to AuthContext structure
+      pAuthContext = CONTAINING_RECORD(pListEntry, AuthContext, listEntry);
+
+      // Free associated buffers
+      if (pAuthContext->pContext)
+         free(pAuthContext->pContext);
+         
+      if (pAuthContext->pMechanism)
+         free(pAuthContext->pMechanism);
+         
+      if (pAuthContext->pMechInfo)
+         free(pAuthContext->pMechInfo);
+
+      // Remove the entry from the list
+      RemoveEntryList(&pAuthContext->listEntry);
+
+      // Free the AuthContext
+      free(pAuthContext);
+
+      // Advance to the next entry
+      pListEntry = pAuthPolicy->authContextListHead.Flink;
+   }
+
+   // Free the AuthPolicy
+   free(pAuthPolicy);
+
+   DbgTrace(1, "-RelAuthPolicy- End\n", 0);
+}
+
+
+//++=======================================================================
+char*
+BuildGetAuthPolicyMsg(
+   IN    char *pServiceName,
+   IN    char *pHostName)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L0
+//=======================================================================--
+{
+   char  *pMsg = NULL;
+   int   bufferSize;
+
+   DbgTrace(1, "-BuildGetAuthPolicyMsg- Start\n", 0);
+
+   /*
+   * The format of the get authentication policy request message is as follows:
+   * 
+   * <?xml version="1.0" encoding="ISO-8859-1"?>
+   * <get_auth_policy_req>
+   * <service>service name<\service>
+   * <host>host name</host>
+   * </get_auth_policy_req>
+   *
+   */
+
+   // Determine the buffer size necessary to hold the msg
+   bufferSize = strlen(XML_DECLARATION)
+                + 2  // crlf
+                + 1  // <
+                + strlen(GET_AUTH_POLICY_REQUEST_ELEMENT_NAME)
+                + 3  // >crlf
+                + 1  // <
+                + strlen(SERVICE_ELEMENT_NAME)
+                + 1  // >
+                + strlen(pServiceName)
+                + 2  // </
+                + strlen(SERVICE_ELEMENT_NAME)
+                + 3  // >crlf
+                + 2  // </
+                + strlen(HOST_ELEMENT_NAME)
+                + 1  // >
+                + strlen(pHostName)
+                + 2  // </
+                + strlen(HOST_ELEMENT_NAME)
+                + 3  // >crlf
+                + 2  // </
+                + strlen(GET_AUTH_POLICY_REQUEST_ELEMENT_NAME)
+                + 2; // >null
+
+   // Allocate the msg buffer
+   pMsg = (char*) malloc(bufferSize);
+   if (pMsg)
+   {
+      // Now build the message
+      memset(pMsg, 0, bufferSize);
+      strcat(pMsg, XML_DECLARATION);
+      strcat(pMsg, "\r\n");
+      strcat(pMsg, "<");
+      strcat(pMsg, GET_AUTH_POLICY_REQUEST_ELEMENT_NAME);
+      strcat(pMsg, ">\r\n");
+      strcat(pMsg, "<");
+      strcat(pMsg, SERVICE_ELEMENT_NAME);
+      strcat(pMsg, ">");
+      strcat(pMsg, pServiceName);
+      strcat(pMsg, "</");
+      strcat(pMsg, SERVICE_ELEMENT_NAME);
+      strcat(pMsg, ">\r\n");
+      strcat(pMsg, "<");
+      strcat(pMsg, HOST_ELEMENT_NAME);
+      strcat(pMsg, ">");
+      strcat(pMsg, pHostName);
+      strcat(pMsg, "</");
+      strcat(pMsg, HOST_ELEMENT_NAME);
+      strcat(pMsg, ">\r\n");
+      strcat(pMsg, "</");
+      strcat(pMsg, GET_AUTH_POLICY_REQUEST_ELEMENT_NAME);
+      strcat(pMsg, ">");
+   }
+   else
+   {
+      DbgTrace(0, "-BuildGetAuthPolicyMsg- Buffer allocation error\n", 0);
+   }
+
+   DbgTrace(1, "-BuildGetAuthPolicyMsg- End, pMsg = %08X\n", pMsg);
+
+   return pMsg;
+}
+
+
+//++=======================================================================
+static
+void XMLCALL
+GetAuthPolicyRespStartElementHandler(
+   IN    GetAuthPolicyRespParse *pGetAuthPolicyRespParse,
+   IN    const XML_Char *name,
+   IN    const XML_Char **atts)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L0
+//=======================================================================--
+{
+   DbgTrace(2, "-GetAuthPolicyRespStartElementHandler- Start\n", 0);
+
+   // Proceed based on the state
+   switch (pGetAuthPolicyRespParse->state)
+   {
+      case AWAITING_ROOT_ELEMENT_START:
+
+         // In this state, we are only expecting the Get Authentication
+         // Policy Response Element.
+         if (strcmp(name, GET_AUTH_POLICY_RESPONSE_ELEMENT_NAME) == 0)
+         {
+            // Good, advance to the next state.
+            pGetAuthPolicyRespParse->state = AWAITING_STATUS_ELEMENT_START;
+         }
+         else
+         {
+            DbgTrace(0, "-GetAuthPolicyRespStartElementHandler- Un-expected start element\n", 0);
+            XML_StopParser(pGetAuthPolicyRespParse->p, XML_FALSE);
+         }
+         break;
+
+      case AWAITING_STATUS_ELEMENT_START:
+   
+         // In this state, we are only expecting the Status Element.
+         if (strcmp(name, STATUS_ELEMENT_NAME) == 0)
+         {
+            // Good, advance to the next state.
+            pGetAuthPolicyRespParse->state = AWAITING_DESCRIPTION_ELEMENT_START;
+         }
+         else
+         {
+            DbgTrace(0, "-GetAuthPolicyRespStartElementHandler- Un-expected start element\n", 0);
+            XML_StopParser(pGetAuthPolicyRespParse->p, XML_FALSE);
+         }
+         break;
+
+      case AWAITING_DESCRIPTION_ELEMENT_START:
+   
+         // In this state, we are only expecting the Description Element.
+         if (strcmp(name, DESCRIPTION_ELEMENT_NAME) == 0)
+         {
+            // Good, advance to the next state.
+            pGetAuthPolicyRespParse->state = AWAITING_DESCRIPTION_DATA;
+         }
+         else
+         {
+            DbgTrace(0, "-GetAuthPolicyRespStartElementHandler- Un-expected start element\n", 0);
+            XML_StopParser(pGetAuthPolicyRespParse->p, XML_FALSE);
+         }
+         break;
+
+      case AWAITING_AUTH_POLICY_ELEMENT_START:
+   
+         // In this state, we are only expecting the Authentication Policy Element.
+         if (strcmp(name, AUTH_POLICY_ELEMENT_NAME) == 0)
+         {
+            // Good, advance to the next state.
+            pGetAuthPolicyRespParse->state = AWAITING_AUTH_POLICY_DATA;
+         }
+         else
+         {
+            DbgTrace(0, "-GetAuthPolicyRespStartElementHandler- Un-expected start element\n", 0);
+            XML_StopParser(pGetAuthPolicyRespParse->p, XML_FALSE);
+         }
+         break;
+   
+      default:
+         DbgTrace(0, "-GetAuthPolicyRespStartElementHandler- Un-expected state = %d\n", pGetAuthPolicyRespParse->state);
+         XML_StopParser(pGetAuthPolicyRespParse->p, XML_FALSE);
+         break;
+   }
+
+   DbgTrace(2, "-GetAuthPolicyRespStartElementHandler- End\n", 0);
+}
+
+
+//++=======================================================================
+static
+void XMLCALL
+GetAuthPolicyRespCharDataHandler(
+   IN    GetAuthPolicyRespParse *pGetAuthPolicyRespParse,
+   IN    const XML_Char *s,
+   IN    int len)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L0
+//=======================================================================--
+{
+   DbgTrace(2, "-GetAuthPolicyRespCharDataHandler- Start\n", 0);
+
+   // Just exit if being called to process LF and CR characters
+   if (len == 1
+       && ((*s == '\n') || (*s == '\r')))
+   {
+      goto exit;
+   }
+
+   // Proceed based on the state
+   switch (pGetAuthPolicyRespParse->state)
+   {
+      case AWAITING_DESCRIPTION_DATA:
+
+         // Ignore the status description data for now.
+
+         // Advanced to the next state
+         pGetAuthPolicyRespParse->state = AWAITING_DESCRIPTION_ELEMENT_END;
+         break;
+
+      case AWAITING_STATUS_DATA:
+
+         // Set the appropriate status in the AuthenticationResp based on the
+         // returned status.
+         if (strncmp(HTTP_OK_STATUS_CODE, s, len) == 0)
+         {
+            pGetAuthPolicyRespParse->status = CASA_STATUS_SUCCESS;
+         }
+         else if (strncmp(HTTP_UNAUTHORIZED_STATUS_CODE, s, len) == 0)
+         {
+            pGetAuthPolicyRespParse->status = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                                             CASA_FACILITY_AUTHTOKEN,
+                                                             CASA_STATUS_AUTHENTICATION_FAILURE);
+         }
+         else if (strncmp(HTTP_SERVER_ERROR_STATUS_CODE, s, len) == 0)
+         {
+            pGetAuthPolicyRespParse->status = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                                             CASA_FACILITY_AUTHTOKEN,
+                                                             CASA_STATUS_SERVER_ERROR);
+         }
+         else
+         {
+            DbgTrace(0, "-GetAuthPolicyRespCharDataHandler- Un-expected status\n", 0);
+            pGetAuthPolicyRespParse->status = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                                             CASA_FACILITY_AUTHTOKEN,
+                                                             CASA_STATUS_UNSUCCESSFUL);
+         }
+
+         // Advanced to the next state
+         pGetAuthPolicyRespParse->state = AWAITING_STATUS_ELEMENT_END;
+         break;
+
+      case AWAITING_AUTH_POLICY_DATA:
+      case AWAITING_AUTH_POLICY_ELEMENT_END:
+
+         // Check if we have already processed policy data
+         if (pGetAuthPolicyRespParse->pGetAuthPolicyResp->policyLen == 0)
+         {
+            // Keep a copy of the policy (null terminated)
+            pGetAuthPolicyRespParse->pGetAuthPolicyResp->pPolicy = (char*) malloc(len + 1);
+            if (pGetAuthPolicyRespParse->pGetAuthPolicyResp->pPolicy)
+            {
+               memset(pGetAuthPolicyRespParse->pGetAuthPolicyResp->pPolicy, 0, len + 1);
+               memcpy(pGetAuthPolicyRespParse->pGetAuthPolicyResp->pPolicy, s, len);
+               pGetAuthPolicyRespParse->pGetAuthPolicyResp->policyLen = len;
+
+               // Advanced to the next state
+               pGetAuthPolicyRespParse->state = AWAITING_AUTH_POLICY_ELEMENT_END;
+            }
+            else
+            {
+               DbgTrace(0, "-GetAuthPolicyRespCharDataHandler- Buffer allocation failure\n", 0);
+               pGetAuthPolicyRespParse->status = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                                                CASA_FACILITY_AUTHTOKEN,
+                                                                CASA_STATUS_INSUFFICIENT_RESOURCES);
+               XML_StopParser(pGetAuthPolicyRespParse->p, XML_FALSE);
+            }
+         }
+         else
+         {
+            char  *pNewBuf;
+
+            // We have already received token data, append this data to it.
+            pNewBuf = (char*) malloc(pGetAuthPolicyRespParse->pGetAuthPolicyResp->policyLen + len + 1);
+            if (pNewBuf)
+            {
+               memset(pNewBuf,
+                      0,
+                      pGetAuthPolicyRespParse->pGetAuthPolicyResp->policyLen + len + 1);
+               memcpy(pNewBuf,
+                      pGetAuthPolicyRespParse->pGetAuthPolicyResp->pPolicy,
+                      pGetAuthPolicyRespParse->pGetAuthPolicyResp->policyLen);
+               memcpy(pNewBuf + pGetAuthPolicyRespParse->pGetAuthPolicyResp->policyLen, s, len);
+               pGetAuthPolicyRespParse->pGetAuthPolicyResp->policyLen += len;
+
+               // Swap the buffers
+               free(pGetAuthPolicyRespParse->pGetAuthPolicyResp->pPolicy);
+               pGetAuthPolicyRespParse->pGetAuthPolicyResp->pPolicy = pNewBuf;
+            }
+            else
+            {
+               DbgTrace(0, "-GetAuthPolicyRespCharDataHandler- Buffer allocation failure\n", 0);
+               pGetAuthPolicyRespParse->status = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                                                CASA_FACILITY_AUTHTOKEN,
+                                                                CASA_STATUS_INSUFFICIENT_RESOURCES);
+               XML_StopParser(pGetAuthPolicyRespParse->p, XML_FALSE);
+            }
+         }
+         break;
+
+      default:
+         DbgTrace(0, "-GetAuthPolicyRespCharDataHandler- Un-expected state = %d\n", pGetAuthPolicyRespParse->state);
+         XML_StopParser(pGetAuthPolicyRespParse->p, XML_FALSE);
+         break;
+   }
+
+exit:
+
+   DbgTrace(2, "-GetAuthPolicyRespCharDataHandler- End\n", 0);
+}
+
+
+//++=======================================================================
+static
+void XMLCALL
+GetAuthPolicyRespEndElementHandler(
+   IN    GetAuthPolicyRespParse *pGetAuthPolicyRespParse,
+   IN    const XML_Char *name)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L0
+//=======================================================================--
+{
+   DbgTrace(2, "-GetAuthPolicyRespEndElementHandler- Start\n", 0);
+
+   // Proceed based on the state
+   switch (pGetAuthPolicyRespParse->state)
+   {
+      case AWAITING_ROOT_ELEMENT_END:
+
+         // In this state, we are only expecting the Get Authentication
+         // Policy Response Element.
+         if (strcmp(name, GET_AUTH_POLICY_RESPONSE_ELEMENT_NAME) == 0)
+         {
+            // Done.
+            pGetAuthPolicyRespParse->state = DONE_PARSING;
+         }
+         else
+         {
+            DbgTrace(0, "-GetAuthPolicyRespEndHandler- Un-expected end element\n", 0);
+            XML_StopParser(pGetAuthPolicyRespParse->p, XML_FALSE);
+         }
+         break;
+
+      case AWAITING_DESCRIPTION_ELEMENT_END:
+   
+         // In this state, we are only expecting the Description Element.
+         if (strcmp(name, DESCRIPTION_ELEMENT_NAME) == 0)
+         {
+            // Good, advance to the next state.
+            pGetAuthPolicyRespParse->state = AWAITING_STATUS_DATA;
+         }
+         else
+         {
+            DbgTrace(0, "-GetAuthPolicyRespEndElementHandler- Un-expected end element\n", 0);
+            XML_StopParser(pGetAuthPolicyRespParse->p, XML_FALSE);
+         }
+         break;
+
+      case AWAITING_STATUS_ELEMENT_END:
+   
+         // In this state, we are only expecting the Status Element.
+         if (strcmp(name, STATUS_ELEMENT_NAME) == 0)
+         {
+            // Good, advance to the next state based on the status code.
+            if (CASA_SUCCESS(pGetAuthPolicyRespParse->status))
+            {
+               // The request completed successfully
+               pGetAuthPolicyRespParse->state = AWAITING_AUTH_POLICY_ELEMENT_START;
+            }
+            else
+            {
+               pGetAuthPolicyRespParse->state = AWAITING_ROOT_ELEMENT_END;
+            }
+         }
+         else
+         {
+            DbgTrace(0, "-GetAuthPolicyRespEndElementHandler- Un-expected start element\n", 0);
+            XML_StopParser(pGetAuthPolicyRespParse->p, XML_FALSE);
+         }
+         break;
+   
+      case AWAITING_AUTH_POLICY_ELEMENT_END:
+   
+         // In this state, we are only expecting the Authentication Policy Element.
+         if (strcmp(name, AUTH_POLICY_ELEMENT_NAME) == 0)
+         {
+            // Good, advance to the next state.
+            pGetAuthPolicyRespParse->state = AWAITING_ROOT_ELEMENT_END;
+         }
+         else
+         {
+            DbgTrace(0, "-GetAuthPolicyRespEndElementHandler- Un-expected start element\n", 0);
+            XML_StopParser(pGetAuthPolicyRespParse->p, XML_FALSE);
+         }
+         break;
+   
+      default:
+         DbgTrace(0, "-GetAuthPolicyRespEndElementHandler- Un-expected state = %d\n", pGetAuthPolicyRespParse->state);
+         XML_StopParser(pGetAuthPolicyRespParse->p, XML_FALSE);
+         break;
+   }
+
+   DbgTrace(2, "-GetAuthPolicyRespEndElementHandler- End\n", 0);
+}
+
+
+//++=======================================================================
+CasaStatus
+CreateGetAuthPolicyResp(
+   IN    char *pRespMsg,
+   IN    int respLen,
+   INOUT GetAuthPolicyResp **ppGetAuthPolicyResp)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L0
+//=======================================================================--
+{
+   CasaStatus              retStatus = CASA_STATUS_SUCCESS;
+   GetAuthPolicyRespParse  getAuthPolicyRespParse = {0};
+   GetAuthPolicyResp       *pGetAuthPolicyResp;
+
+   DbgTrace(1, "-CreateGetAuthPolicyResp- Start\n", 0);
+
+   /*
+   * When a get authentication policy request is processed successfully, the
+   * server replies to the client with a message with the following format:
+   * 
+   * <?xml version="1.0" encoding="ISO-8859-1"?>
+   * <get_auth_policy_resp>
+   * <status><description>ok</description>200</status>
+   * <auth_policy>authentication policy data</auth_policy>
+   * </get_auth_policy_resp>
+   * 
+   * When a get authentication policy request fails to be successfully processed,
+   * the server responds with an error and a error description string. The message
+   * format of an unsuccessful reply is as follows:
+   * 
+   * <?xml version="1.0" encoding="ISO-8859-1"?>
+   * <get_auth_policy_resp>
+   * <status><description>status description</description>status code</status>
+   * </get_auth_policy_resp>
+   * 
+   * Plase note that the protocol utilizes the status codes defined
+   * in the HTTP 1.1 Specification.
+   *
+   */
+
+   // Allocate GetAuthPolicyResp object
+   pGetAuthPolicyResp = malloc(sizeof(*pGetAuthPolicyResp));
+   if (pGetAuthPolicyResp)
+   {
+      XML_Parser  p;
+
+      // Initialize the GetAuthPolicyResp object and set it in the
+      // parse oject.
+      memset(pGetAuthPolicyResp, 0, sizeof(*pGetAuthPolicyResp));
+      getAuthPolicyRespParse.pGetAuthPolicyResp = pGetAuthPolicyResp;
+
+      // Create parser
+      p = XML_ParserCreate(NULL);
+      if (p)
+      {
+         // Keep track of the parser in our parse object
+         getAuthPolicyRespParse.p = p;
+
+         // Initialize the status within the parse object
+         getAuthPolicyRespParse.status = CASA_STATUS_SUCCESS;
+
+         // Set the start and end element handlers
+         XML_SetElementHandler(p,
+                               GetAuthPolicyRespStartElementHandler,
+                               GetAuthPolicyRespEndElementHandler);
+
+         // Set the character data handler
+         XML_SetCharacterDataHandler(p, GetAuthPolicyRespCharDataHandler);
+
+
+         // Set our user data
+         XML_SetUserData(p, &getAuthPolicyRespParse);
+
+         // Parse the document
+         if (XML_Parse(p, pRespMsg, respLen, 1) == XML_STATUS_OK)
+         {
+            // Verify that the parse operation completed successfully
+            if (getAuthPolicyRespParse.state == DONE_PARSING)
+            {
+               // The parse operation succeded, obtain the status returned
+               // by the server.
+               retStatus = getAuthPolicyRespParse.status;
+            }
+            else
+            {
+               DbgTrace(0, "-CreateGetAuthPolicyResp- Parse operation did not complete\n", 0);
+
+               // Check if a status has been recorded
+               if (getAuthPolicyRespParse.status != CASA_STATUS_SUCCESS)
+               {
+                  retStatus = getAuthPolicyRespParse.status;
+               }
+               else
+               {
+                  retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                              CASA_FACILITY_AUTHTOKEN,
+                                              CASA_STATUS_PROTOCOL_ERROR);
+               }
+            }
+         }
+         else
+         {
+            DbgTrace(0, "-CreateGetAuthPolicyResp- Parse error %d\n", XML_GetErrorCode(p));
+            retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                        CASA_FACILITY_AUTHTOKEN,
+                                        CASA_STATUS_PROTOCOL_ERROR);
+         }
+
+         // Free the parser
+         XML_ParserFree(p);
+      }
+      else
+      {
+         DbgTrace(0, "-CreateGetAuthPolicyResp- Parser creation error\n", 0);
+         retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                     CASA_FACILITY_AUTHTOKEN,
+                                     CASA_STATUS_INSUFFICIENT_RESOURCES);
+      }
+
+      // Return the AuthenticationResp object to the caller if necessary
+      if (CASA_SUCCESS(retStatus))
+      {
+         *ppGetAuthPolicyResp = pGetAuthPolicyResp;
+      }
+      else
+      {
+         free(pGetAuthPolicyResp);
+      }
+   }
+   else
+   {
+      DbgTrace(0, "-CreateGetAuthPolicyResp- Memory allocation error\n", 0);
+      retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                  CASA_FACILITY_AUTHTOKEN,
+                                  CASA_STATUS_INSUFFICIENT_RESOURCES);
+   }
+   DbgTrace(1, "-CreateGetAuthPolicyResp- End, retStatus = %08X\n", retStatus);
+
+   return retStatus;
+}
+
+
+//++=======================================================================
+void
+RelGetAuthPolicyResp(
+   IN    GetAuthPolicyResp *pGetAuthPolicyResp)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L0
+//=======================================================================--
+{
+   DbgTrace(1, "-RelGetAuthPolicyResp- Start\n", 0);
+
+   // Free the buffer holding the authentication policy
+   if (pGetAuthPolicyResp->pPolicy)
+      free(pGetAuthPolicyResp->pPolicy);
+
+   // Free the GetAuthPolicyResp
+   free(pGetAuthPolicyResp);
+
+   DbgTrace(1, "-RelGetAuthPolicyResp- End\n", 0);
+}
+
diff --git a/auth_token/client/gettokenmsg.c b/auth_token/client/gettokenmsg.c
new file mode 100644
index 00000000..438feee5
--- /dev/null
+++ b/auth_token/client/gettokenmsg.c
@@ -0,0 +1,736 @@
+/***********************************************************************
+ * 
+ *  Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; version 2.1
+ *  of the License.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, Novell, Inc.
+ * 
+ *  To contact Novell about this file by physical or electronic mail, 
+ *  you may find current contact information at www.novell.com.
+ * 
+ *  Author: Juan Carlos Luciani <jluciani@novell.com>
+ *
+ ***********************************************************************/
+
+
+//===[ Include files ]=====================================================
+
+#include "internal.h"
+
+//===[ Type definitions ]==================================================
+
+//
+// Parse states
+//
+#define AWAITING_ROOT_ELEMENT_START             0x0
+#define AWAITING_ROOT_ELEMENT_END               0x1
+#define AWAITING_STATUS_ELEMENT_START           0x2
+#define AWAITING_STATUS_ELEMENT_END             0x3
+#define AWAITING_STATUS_DATA                    0x4
+#define AWAITING_DESCRIPTION_ELEMENT_START      0x5
+#define AWAITING_DESCRIPTION_ELEMENT_END        0x6
+#define AWAITING_DESCRIPTION_DATA               0x7
+#define AWAITING_LIFETIME_DATA                  0x8
+#define AWAITING_LIFETIME_ELEMENT_START         0x9
+#define AWAITING_LIFETIME_ELEMENT_END           0xA
+#define AWAITING_AUTH_TOKEN_ELEMENT_START       0xB
+#define AWAITING_AUTH_TOKEN_ELEMENT_END         0xC
+#define AWAITING_AUTH_TOKEN_DATA                0xD
+#define DONE_PARSING                            0xE
+
+//
+// Get Authentication Token Response Parse Structure
+//
+typedef struct _GetAuthTokenRespParse
+{
+   XML_Parser              p;
+   int                     state;
+   int                     tokenDataProcessed;
+   GetAuthTokenResp        *pGetAuthTokenResp;
+   CasaStatus              status;
+
+} GetAuthTokenRespParse, *PGetAuthTokenRespParse;
+
+
+//===[ Function prototypes ]===============================================
+
+//===[ Global variables ]==================================================
+
+//++=======================================================================
+char*
+BuildGetAuthTokenMsg(
+   IN    char *pServiceName,
+   IN    char *pHostName,
+   IN    char *pSessionToken)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L0
+//=======================================================================--
+{
+   char  *pMsg = NULL;
+   int   bufferSize;
+
+   DbgTrace(1, "-BuildGetAuthTokenMsg- Start\n", 0);
+
+   /*
+   * The format of the get authentication token request message
+   * is as follows:
+   * 
+   * <?xml version="1.0" encoding="ISO-8859-1"?>
+   * <get_auth_token_req>
+   * <service>service name</service>
+   * <host>host name</host>
+   * <session_token>session token data</session_token>
+   * </get_auth_token_req>
+   *
+   */
+
+   // Determine the buffer size necessary to hold the msg
+   bufferSize = strlen(XML_DECLARATION)
+                + 2  // crlf
+                + 1  // <
+                + strlen(GET_AUTH_TOKEN_REQUEST_ELEMENT_NAME)
+                + 3  // >crlf
+                + 1  // <
+                + strlen(SERVICE_ELEMENT_NAME)
+                + 1  // >
+                + strlen(pServiceName)
+                + 2  // </
+                + strlen(SERVICE_ELEMENT_NAME)
+                + 3  // >crlf
+                + 2  // </
+                + strlen(HOST_ELEMENT_NAME)
+                + 1  // >
+                + strlen(pHostName)
+                + 2  // </
+                + strlen(HOST_ELEMENT_NAME)
+                + 3  // >crlf
+                + 2  // </
+                + strlen(SESSION_TOKEN_ELEMENT_NAME)
+                + 1  // >
+                + strlen(pSessionToken)
+                + 2  // </
+                + strlen(SESSION_TOKEN_ELEMENT_NAME)
+                + 3  // >crlf
+                + 2  // </
+                + strlen(GET_AUTH_TOKEN_REQUEST_ELEMENT_NAME)
+                + 2; // >null
+
+   // Allocate the msg buffer
+   pMsg = (char*) malloc(bufferSize);
+   if (pMsg)
+   {
+      // Now build the message
+      memset(pMsg, 0, bufferSize);
+      strcat(pMsg, XML_DECLARATION);
+      strcat(pMsg, "\r\n");
+      strcat(pMsg, "<");
+      strcat(pMsg, GET_AUTH_TOKEN_REQUEST_ELEMENT_NAME);
+      strcat(pMsg, ">\r\n");
+      strcat(pMsg, "<");
+      strcat(pMsg, SERVICE_ELEMENT_NAME);
+      strcat(pMsg, ">");
+      strcat(pMsg, pServiceName);
+      strcat(pMsg, "</");
+      strcat(pMsg, SERVICE_ELEMENT_NAME);
+      strcat(pMsg, ">\r\n");
+      strcat(pMsg, "<");
+      strcat(pMsg, HOST_ELEMENT_NAME);
+      strcat(pMsg, ">");
+      strcat(pMsg, pHostName);
+      strcat(pMsg, "</");
+      strcat(pMsg, HOST_ELEMENT_NAME);
+      strcat(pMsg, ">\r\n");
+      strcat(pMsg, "<");
+      strcat(pMsg, SESSION_TOKEN_ELEMENT_NAME);
+      strcat(pMsg, ">");
+      strcat(pMsg, pSessionToken);
+      strcat(pMsg, "</");
+      strcat(pMsg, SESSION_TOKEN_ELEMENT_NAME);
+      strcat(pMsg, ">\r\n");
+      strcat(pMsg, "</");
+      strcat(pMsg, GET_AUTH_TOKEN_REQUEST_ELEMENT_NAME);
+      strcat(pMsg, ">");
+   }
+   else
+   {
+      DbgTrace(0, "-BuildGetAuthTokenMsg- Buffer allocation error\n", 0);
+   }
+
+   DbgTrace(1, "-BuildGetAuthTokenMsg- End, pMsg = %08X\n", pMsg);
+
+   return pMsg;
+}
+
+
+//++=======================================================================
+static
+void XMLCALL
+GetAuthTokenRespStartElementHandler(
+   IN    GetAuthTokenRespParse *pGetAuthTokenRespParse,
+   IN    const XML_Char *name,
+   IN    const XML_Char **atts)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L0
+//=======================================================================--
+{
+   DbgTrace(2, "-GetAuthTokenRespStartElementHandler- Start\n", 0);
+
+   // Proceed based on the state
+   switch (pGetAuthTokenRespParse->state)
+   {
+      case AWAITING_ROOT_ELEMENT_START:
+
+         // In this state, we are only expecting the Get Authentication
+         // Token Response Element.
+         if (strcmp(name, GET_AUTH_TOKEN_RESPONSE_ELEMENT_NAME) == 0)
+         {
+            // Good, advance to the next state.
+            pGetAuthTokenRespParse->state = AWAITING_STATUS_ELEMENT_START;
+         }
+         else
+         {
+            DbgTrace(0, "-GetAuthTokenRespStartElementHandler- Un-expected start element\n", 0);
+            XML_StopParser(pGetAuthTokenRespParse->p, XML_FALSE);
+         }
+         break;
+
+      case AWAITING_STATUS_ELEMENT_START:
+   
+         // In this state, we are only expecting the Status Element.
+         if (strcmp(name, STATUS_ELEMENT_NAME) == 0)
+         {
+            // Good, advance to the next state.
+            pGetAuthTokenRespParse->state = AWAITING_DESCRIPTION_ELEMENT_START;
+         }
+         else
+         {
+            DbgTrace(0, "-GetAuthTokenRespStartElementHandler- Un-expected start element\n", 0);
+            XML_StopParser(pGetAuthTokenRespParse->p, XML_FALSE);
+         }
+         break;
+
+      case AWAITING_DESCRIPTION_ELEMENT_START:
+   
+         // In this state, we are only expecting the Description Element.
+         if (strcmp(name, DESCRIPTION_ELEMENT_NAME) == 0)
+         {
+            // Good, advance to the next state.
+            pGetAuthTokenRespParse->state = AWAITING_DESCRIPTION_DATA;
+         }
+         else
+         {
+            DbgTrace(0, "-GetAuthTokenRespStartElementHandler- Un-expected start element\n", 0);
+            XML_StopParser(pGetAuthTokenRespParse->p, XML_FALSE);
+         }
+         break;
+
+      case AWAITING_AUTH_TOKEN_ELEMENT_START:
+   
+         // In this state, we are only expecting the Authentication Token Element.
+         if (strcmp(name, AUTH_TOKEN_ELEMENT_NAME) == 0)
+         {
+            // Good, advance to the next state.
+            pGetAuthTokenRespParse->state = AWAITING_LIFETIME_ELEMENT_START;
+         }
+         else
+         {
+            DbgTrace(0, "-GetAuthTokenRespStartElementHandler- Un-expected start element\n", 0);
+            XML_StopParser(pGetAuthTokenRespParse->p, XML_FALSE);
+         }
+         break;
+   
+      case AWAITING_LIFETIME_ELEMENT_START:
+   
+         // In this state, we are only expecting the Lifetime Element.
+         if (strcmp(name, LIFETIME_ELEMENT_NAME) == 0)
+         {
+            // Good, advance to the next state.
+            pGetAuthTokenRespParse->state = AWAITING_LIFETIME_DATA;
+         }
+         else
+         {
+            DbgTrace(0, "-GetAuthTokenRespStartElementHandler- Un-expected start element\n", 0);
+            XML_StopParser(pGetAuthTokenRespParse->p, XML_FALSE);
+         }
+         break;
+
+      default:
+         DbgTrace(0, "-GetAuthTokenRespStartElementHandler- Un-expected state = %d\n", pGetAuthTokenRespParse->state);
+         XML_StopParser(pGetAuthTokenRespParse->p, XML_FALSE);
+         break;
+   }
+
+   DbgTrace(2, "-GetAuthTokenRespStartElementHandler- End\n", 0);
+}
+
+
+//++=======================================================================
+static
+void XMLCALL
+GetAuthTokenRespCharDataHandler(
+   IN    GetAuthTokenRespParse *pGetAuthTokenRespParse,
+   IN    const XML_Char *s,
+   IN    int len)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L0
+//=======================================================================--
+{
+   DbgTrace(2, "-GetAuthTokenRespCharDataHandler- Start\n", 0);
+
+   // Just exit if being called to process LF and CR characters
+   if (len == 1
+       && ((*s == '\n') || (*s == '\r')))
+   {
+      goto exit;
+   }
+
+   // Proceed based on the state
+   switch (pGetAuthTokenRespParse->state)
+   {
+      case AWAITING_DESCRIPTION_DATA:
+
+         // Ignore the status description data for now.
+
+         // Advanced to the next state
+         pGetAuthTokenRespParse->state = AWAITING_DESCRIPTION_ELEMENT_END;
+         break;
+
+      case AWAITING_STATUS_DATA:
+
+         // Set the appropriate status in the AuthenticationResp based on the
+         // returned status.
+         if (strncmp(HTTP_OK_STATUS_CODE, s, len) == 0)
+         {
+            pGetAuthTokenRespParse->status = CASA_STATUS_SUCCESS;
+         }
+         else if (strncmp(HTTP_UNAUTHORIZED_STATUS_CODE, s, len) == 0)
+         {
+            pGetAuthTokenRespParse->status = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                                             CASA_FACILITY_AUTHTOKEN,
+                                                             CASA_STATUS_AUTHENTICATION_FAILURE);
+         }
+         else if (strncmp(HTTP_SERVER_ERROR_STATUS_CODE, s, len) == 0)
+         {
+            pGetAuthTokenRespParse->status = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                                             CASA_FACILITY_AUTHTOKEN,
+                                                             CASA_STATUS_SERVER_ERROR);
+         }
+         else
+         {
+            DbgTrace(0, "-GetAuthTokenRespCharDataHandler- Un-expected status\n", 0);
+            pGetAuthTokenRespParse->status = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                                             CASA_FACILITY_AUTHTOKEN,
+                                                             CASA_STATUS_UNSUCCESSFUL);
+         }
+
+         // Advanced to the next state
+         pGetAuthTokenRespParse->state = AWAITING_STATUS_ELEMENT_END;
+         break;
+
+      case AWAITING_LIFETIME_DATA:
+
+         // Convert the lifetime string to a numeric value
+         pGetAuthTokenRespParse->pGetAuthTokenResp->tokenLifetime = dtoul(s, len);
+
+         // Advanced to the next state
+         pGetAuthTokenRespParse->state = AWAITING_LIFETIME_ELEMENT_END;
+         break;
+
+      case AWAITING_AUTH_TOKEN_DATA:
+      case AWAITING_AUTH_TOKEN_ELEMENT_END:
+
+         // Check if we have already processed token data
+         if (pGetAuthTokenRespParse->tokenDataProcessed == 0)
+         {
+            // Keep a copy of the authentication token (null terminated)
+            pGetAuthTokenRespParse->pGetAuthTokenResp->pToken = (char*) malloc(len + 1);
+            if (pGetAuthTokenRespParse->pGetAuthTokenResp->pToken)
+            {
+               memset(pGetAuthTokenRespParse->pGetAuthTokenResp->pToken, 0, len + 1);
+               memcpy(pGetAuthTokenRespParse->pGetAuthTokenResp->pToken, s, len);
+               pGetAuthTokenRespParse->tokenDataProcessed = len;
+
+               // Advanced to the next state
+               pGetAuthTokenRespParse->state = AWAITING_AUTH_TOKEN_ELEMENT_END;
+            }
+            else
+            {
+               DbgTrace(0, "-GetAuthTokenRespCharDataHandler- Buffer allocation failure\n", 0);
+               pGetAuthTokenRespParse->status = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                                                CASA_FACILITY_AUTHTOKEN,
+                                                                CASA_STATUS_INSUFFICIENT_RESOURCES);
+               XML_StopParser(pGetAuthTokenRespParse->p, XML_FALSE);
+            }
+         }
+         else
+         {
+            char  *pNewBuf;
+
+            // We have already received token data, append this data to it.
+            pNewBuf = (char*) malloc(pGetAuthTokenRespParse->tokenDataProcessed + len + 1);
+            if (pNewBuf)
+            {
+               memset(pNewBuf,
+                      0,
+                      pGetAuthTokenRespParse->tokenDataProcessed + len + 1);
+               memcpy(pNewBuf,
+                      pGetAuthTokenRespParse->pGetAuthTokenResp->pToken,
+                      pGetAuthTokenRespParse->tokenDataProcessed);
+               memcpy(pNewBuf + pGetAuthTokenRespParse->tokenDataProcessed, s, len);
+               pGetAuthTokenRespParse->tokenDataProcessed += len;
+
+               // Swap the buffers
+               free(pGetAuthTokenRespParse->pGetAuthTokenResp->pToken);
+               pGetAuthTokenRespParse->pGetAuthTokenResp->pToken = pNewBuf;
+            }
+            else
+            {
+               DbgTrace(0, "-GetAuthTokenRespCharDataHandler- Buffer allocation failure\n", 0);
+               pGetAuthTokenRespParse->status = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                                                CASA_FACILITY_AUTHTOKEN,
+                                                                CASA_STATUS_INSUFFICIENT_RESOURCES);
+               XML_StopParser(pGetAuthTokenRespParse->p, XML_FALSE);
+            }
+         }
+         break;
+
+      default:
+         DbgTrace(0, "-GetAuthTokenRespCharDataHandler- Un-expected state = %d\n", pGetAuthTokenRespParse->state);
+         XML_StopParser(pGetAuthTokenRespParse->p, XML_FALSE);
+         break;
+   }
+
+exit:
+
+   DbgTrace(2, "-GetAuthTokenRespCharDataHandler- End\n", 0);
+}
+
+
+//++=======================================================================
+static
+void XMLCALL
+GetAuthTokenRespEndElementHandler(
+   IN    GetAuthTokenRespParse *pGetAuthTokenRespParse,
+   IN    const XML_Char *name)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L0
+//=======================================================================--
+{
+   DbgTrace(2, "-GetAuthTokenRespEndElementHandler- Start\n", 0);
+
+   // Proceed based on the state
+   switch (pGetAuthTokenRespParse->state)
+   {
+      case AWAITING_ROOT_ELEMENT_END:
+
+         // In this state, we are only expecting the Get Authentication
+         // Token Response Element.
+         if (strcmp(name, GET_AUTH_TOKEN_RESPONSE_ELEMENT_NAME) == 0)
+         {
+            // Done.
+            pGetAuthTokenRespParse->state = DONE_PARSING;
+         }
+         else
+         {
+            DbgTrace(0, "-GetAuthTokenRespEndHandler- Un-expected end element\n", 0);
+            XML_StopParser(pGetAuthTokenRespParse->p, XML_FALSE);
+         }
+         break;
+
+      case AWAITING_DESCRIPTION_ELEMENT_END:
+   
+         // In this state, we are only expecting the Description Element.
+         if (strcmp(name, DESCRIPTION_ELEMENT_NAME) == 0)
+         {
+            // Good, advance to the next state.
+            pGetAuthTokenRespParse->state = AWAITING_STATUS_DATA;
+         }
+         else
+         {
+            DbgTrace(0, "-GetAuthTokenRespEndElementHandler- Un-expected end element\n", 0);
+            XML_StopParser(pGetAuthTokenRespParse->p, XML_FALSE);
+         }
+         break;
+
+      case AWAITING_STATUS_ELEMENT_END:
+   
+         // In this state, we are only expecting the Status Element.
+         if (strcmp(name, STATUS_ELEMENT_NAME) == 0)
+         {
+            // Good, advance to the next state based on the status code.
+            if (CASA_SUCCESS(pGetAuthTokenRespParse->status))
+            {
+               // The request completed successfully
+               pGetAuthTokenRespParse->state = AWAITING_AUTH_TOKEN_ELEMENT_START;
+            }
+            else
+            {
+               pGetAuthTokenRespParse->state = AWAITING_ROOT_ELEMENT_END;
+            }
+         }
+         else
+         {
+            DbgTrace(0, "-GetAuthTokenRespEndElementHandler- Un-expected start element\n", 0);
+            XML_StopParser(pGetAuthTokenRespParse->p, XML_FALSE);
+         }
+         break;
+   
+      case AWAITING_LIFETIME_ELEMENT_END:
+   
+         // In this state, we are only expecting the Lifetime Element.
+         if (strcmp(name, LIFETIME_ELEMENT_NAME) == 0)
+         {
+            // Good, advance to the next state.
+            pGetAuthTokenRespParse->state = AWAITING_AUTH_TOKEN_DATA;
+         }
+         else
+         {
+            DbgTrace(0, "-GetAuthTokenRespEndElementHandler- Un-expected start element\n", 0);
+            XML_StopParser(pGetAuthTokenRespParse->p, XML_FALSE);
+         }
+         break;
+   
+      case AWAITING_AUTH_TOKEN_ELEMENT_END:
+   
+         // In this state, we are only expecting the Authentication Token Element.
+         if (strcmp(name, AUTH_TOKEN_ELEMENT_NAME) == 0)
+         {
+            // Good, advance to the next state.
+            pGetAuthTokenRespParse->state = AWAITING_ROOT_ELEMENT_END;
+         }
+         else
+         {
+            DbgTrace(0, "-GetAuthTokenRespEndElementHandler- Un-expected start element\n", 0);
+            XML_StopParser(pGetAuthTokenRespParse->p, XML_FALSE);
+         }
+         break;
+   
+      default:
+         DbgTrace(0, "-GetAuthTokenRespEndElementHandler- Un-expected state = %d\n", pGetAuthTokenRespParse->state);
+         XML_StopParser(pGetAuthTokenRespParse->p, XML_FALSE);
+         break;
+   }
+
+   DbgTrace(2, "-GetAuthTokenRespEndElementHandler- End\n", 0);
+}
+
+
+//++=======================================================================
+CasaStatus
+CreateGetAuthTokenResp(
+   IN    char *pRespMsg,
+   IN    int respLen,
+   INOUT GetAuthTokenResp **ppGetAuthTokenResp)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L0
+//=======================================================================--
+{
+   CasaStatus              retStatus = CASA_STATUS_SUCCESS;
+   GetAuthTokenRespParse   getAuthTokenRespParse = {0};
+   GetAuthTokenResp        *pGetAuthTokenResp;
+
+   DbgTrace(1, "-CreateGetAuthTokenResp- Start\n", 0);
+
+   /*
+   * When a get authentication token request is processed successfully, the
+   * server replies to the client with a message with the following format:
+   * 
+   * <?xml version="1.0" encoding="ISO-8859-1"?>
+   * <get_auth_token_resp>
+   * <status><description>ok</description>200</status>
+   * <auth_token><lifetime>lifetime value</lifetime>session token data</auth_token>
+   * </get_auth_token_resp>
+   * 
+   * When a get authentication token request fails to be successfully processed,
+   * the server responds with an error and a error description string. The message
+   * format of an unsuccessful reply is as follows:
+   * 
+   * <?xml version="1.0" encoding="ISO-8859-1"?>
+   * <get_auth_token_resp>
+   * <status><description>status description</description>status code</status>
+   * </get_auth_token_resp>
+   * 
+   * Plase note that the protocol utilizes the status codes defined
+   * in the HTTP 1.1 Specification.
+   *
+   */
+
+   // Allocate GetAuthTokenResp object
+   pGetAuthTokenResp = malloc(sizeof(*pGetAuthTokenResp));
+   if (pGetAuthTokenResp)
+   {
+      XML_Parser  p;
+
+      // Initialize the GetAuthTokenResp object and set it in the
+      // parse oject.
+      memset(pGetAuthTokenResp, 0, sizeof(*pGetAuthTokenResp));
+      getAuthTokenRespParse.pGetAuthTokenResp = pGetAuthTokenResp;
+
+      // Create parser
+      p = XML_ParserCreate(NULL);
+      if (p)
+      {
+         // Keep track of the parser in our parse object
+         getAuthTokenRespParse.p = p;
+
+         // Initialize the status within the parse object
+         getAuthTokenRespParse.status = CASA_STATUS_SUCCESS;
+
+         // Set the start and end element handlers
+         XML_SetElementHandler(p,
+                               GetAuthTokenRespStartElementHandler,
+                               GetAuthTokenRespEndElementHandler);
+
+         // Set the character data handler
+         XML_SetCharacterDataHandler(p, GetAuthTokenRespCharDataHandler);
+
+
+         // Set our user data
+         XML_SetUserData(p, &getAuthTokenRespParse);
+
+         // Parse the document
+         if (XML_Parse(p, pRespMsg, respLen, 1) == XML_STATUS_OK)
+         {
+            // Verify that the parse operation completed successfully
+            if (getAuthTokenRespParse.state == DONE_PARSING)
+            {
+               // The parse operation succeded, obtain the status returned
+               // by the server.
+               retStatus = getAuthTokenRespParse.status;
+            }
+            else
+            {
+               DbgTrace(0, "-CreateGetAuthTokenResp- Parse operation did not complete\n", 0);
+
+               // Check if a status has been recorded
+               if (getAuthTokenRespParse.status != CASA_STATUS_SUCCESS)
+               {
+                  retStatus = getAuthTokenRespParse.status;
+               }
+               else
+               {
+                  retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                              CASA_FACILITY_AUTHTOKEN,
+                                              CASA_STATUS_PROTOCOL_ERROR);
+               }
+            }
+         }
+         else
+         {
+            DbgTrace(0, "-CreateGetAuthTokenResp- Parse error %d\n", XML_GetErrorCode(p));
+            retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                        CASA_FACILITY_AUTHTOKEN,
+                                        CASA_STATUS_PROTOCOL_ERROR);
+         }
+
+         // Free the parser
+         XML_ParserFree(p);
+      }
+      else
+      {
+         DbgTrace(0, "-CreateGetAuthTokenResp- Parser creation error\n", 0);
+         retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                     CASA_FACILITY_AUTHTOKEN,
+                                     CASA_STATUS_INSUFFICIENT_RESOURCES);
+      }
+
+      // Return the AuthenticationResp object to the caller if necessary
+      if (CASA_SUCCESS(retStatus))
+      {
+         *ppGetAuthTokenResp = pGetAuthTokenResp;
+      }
+      else
+      {
+         free(pGetAuthTokenResp);
+      }
+   }
+   else
+   {
+      DbgTrace(0, "-CreateGetAuthTokenResp- Memory allocation error\n", 0);
+      retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                  CASA_FACILITY_AUTHTOKEN,
+                                  CASA_STATUS_INSUFFICIENT_RESOURCES);
+   }
+   DbgTrace(1, "-CreateGetAuthTokenResp- End, retStatus = %08X\n", retStatus);
+
+   return retStatus;
+}
+
+
+//++=======================================================================
+void
+RelGetAuthTokenResp(
+   IN    GetAuthTokenResp *pGetAuthTokenResp)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L0
+//=======================================================================--
+{
+   DbgTrace(1, "-RelGetAuthTokenResp- Start\n", 0);
+
+   // Free the resources associated with the object
+   if (pGetAuthTokenResp->pToken)
+      free(pGetAuthTokenResp->pToken);
+
+   free(pGetAuthTokenResp);
+
+   DbgTrace(1, "-RelGetAuthTokenResp- End\n", 0);
+}
+
diff --git a/auth_token/client/internal.h b/auth_token/client/internal.h
new file mode 100644
index 00000000..c01bd9f0
--- /dev/null
+++ b/auth_token/client/internal.h
@@ -0,0 +1,345 @@
+/***********************************************************************
+ * 
+ *  Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; version 2.1
+ *  of the License.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, Novell, Inc.
+ * 
+ *  To contact Novell about this file by physical or electronic mail, 
+ *  you may find current contact information at www.novell.com.
+ * 
+ *  Author: Juan Carlos Luciani <jluciani@novell.com>
+ *
+ ***********************************************************************/
+
+#ifndef _INTERNAL_H_
+#define _INTERNAL_H_
+
+//===[ Include files ]=====================================================
+
+#include "platform.h"
+#include <expat.h>
+#include <micasa_types.h>
+#include <casa_status.h>
+#include <casa_auth_token.h>
+#include "list_entry.h"
+#include "mech_if.h"
+#include "proto.h"
+
+//===[ Type definitions ]==================================================
+
+//
+// Authentication Context structure
+// 
+typedef struct _AuthContext
+{
+   LIST_ENTRY  listEntry;
+   char        *pContext;
+   char        *pMechanism;
+   char        *pMechInfo;
+
+} AuthContext, *PAuthContext;
+
+//
+// Authentication Policy structure
+// 
+typedef struct _AuthPolicy
+{
+   LIST_ENTRY  authContextListHead;
+
+} AuthPolicy, *PAuthPolicy;
+
+//
+// Get Authentication Policy Response structure
+// 
+typedef struct _GetAuthPolicyResp
+{
+   char  *pPolicy;
+   int   policyLen;
+
+} GetAuthPolicyResp, *PGetAuthPolicyResp;
+
+//
+// Get Authentication Token Response structure
+// 
+typedef struct _GetAuthTokenResp
+{
+   char  *pToken;
+   int   tokenLifetime;
+
+} GetAuthTokenResp, *PGetAuthTokenResp;
+
+//
+// Authenticate Response structure
+//
+typedef struct _AuthenticateResp
+{
+   char  *pToken;
+   int   tokenLifetime;
+
+} AuthenticateResp, *PAuthenticateResp;
+
+
+//===[ Inlines functions   ]===============================================
+
+//===[ Function prototypes ]===============================================
+
+//===[ Global variables ]==================================================
+
+//===[ Global externals ]==================================================
+
+extern int  DebugLevel;
+
+extern char  mechConfigFolder[];
+
+extern char  pathCharString[];
+
+
+
+//===[ External prototypes ]===============================================
+
+//
+// Functions exported by engine.c
+// 
+
+extern
+int
+InitializeLibrary(void);
+
+//
+// Functions exported by authmech.c
+// 
+
+extern
+CasaStatus
+GetAuthMechToken(
+   IN    AuthContext *pAuthContext,
+   INOUT char **ppAuthMechToken);
+
+//
+// Functions exported by getpolicymsg.c
+// 
+
+extern
+CasaStatus
+CreateAuthPolicy(
+   IN    char *pEncodedData,
+   IN    int encodedDataLen,
+   INOUT AuthPolicy **ppAuthPolicy);
+
+extern
+void
+RelAuthPolicy(
+   IN    AuthPolicy *pAuthPolicy);
+
+extern
+char*
+BuildGetAuthPolicyMsg(
+   IN    char *pServiceName,
+   IN    char *pHostName);
+
+extern
+CasaStatus
+CreateGetAuthPolicyResp(
+   IN    char *pRespMsg,
+   IN    int respLen,
+   INOUT GetAuthPolicyResp **ppGetAuthPolicyResp);
+
+extern
+void
+RelGetAuthPolicyResp(
+   IN    GetAuthPolicyResp *pGetAuthPolicyResp);
+
+//
+// Functions exported by authmsg.c
+// 
+
+extern
+char*
+BuildAuthenticateMsg(
+   IN    AuthContext *pAuthContext,
+   IN    char *pAuthMechToken);
+
+extern
+CasaStatus
+CreateAuthenticateResp(
+   IN    char *pRespMsg,
+   IN    int respLen,
+   INOUT AuthenticateResp **ppAuthenticateResp);
+
+extern
+void
+RelAuthenticateResp(
+   IN    AuthenticateResp *pAuthenticateResp);
+
+//
+// Functions exported by gettokenmsg.c
+// 
+
+extern
+char*
+BuildGetAuthTokenMsg(
+   IN    char *pServiceName,
+   IN    char *pHostName,
+   IN    char *pSessionToken);
+
+extern
+CasaStatus
+CreateGetAuthTokenResp(
+   IN    char *pRespMsg,
+   IN    int respLen,
+   INOUT GetAuthTokenResp **ppGetAuthTokenResp);
+
+extern
+void
+RelGetAuthTokenResp(
+   IN    GetAuthTokenResp *pGetAuthTokenResp);
+
+//
+// Functions exported by cache.c
+//
+
+extern
+AuthCacheEntry*
+CreateAuthCacheEntry(
+   IN    char *pCacheKey,
+   IN    char *pHostName);
+
+extern
+void
+FreeAuthCacheEntry(
+   IN    AuthCacheEntry *pEntry);
+
+extern
+AuthCacheEntry*
+FindEntryInAuthCache(
+   IN    char *pCacheKey,
+   IN    char *pHostName);
+
+extern
+void
+AddEntryToAuthCache(
+   IN    AuthCacheEntry *pEntry,
+   IN    int entryLifetime);
+
+extern
+CasaStatus
+InitializeAuthCache(void);
+
+//
+// Functions exported by config.c
+//
+
+extern
+CasaStatus
+GetConfigInterface(
+   IN       const char  *pConfigFolder,
+   IN       const char  *pConfigName,
+   INOUT    ConfigIf    **ppConfigIf);
+
+//
+// Functions exported by platutils.c
+//
+
+extern
+CasaStatus
+CreateUserMutex(void);
+
+extern
+void
+LockUserMutex(void);
+
+extern
+void
+FreeUserMutex(void);
+
+extern
+LIB_HANDLE
+OpenLibrary(
+   IN    char *pFileName);
+
+extern
+void
+CloseLibrary(
+   IN    LIB_HANDLE libHandle);
+
+extern
+void*
+GetFunctionPtr(
+   IN    LIB_HANDLE libHandle,
+   IN    char *pFunctionName);
+
+extern
+char*
+NormalizeHostName(
+   IN    char *pHostName);
+
+extern
+CasaStatus
+InitializeHostNameNormalization(void);
+
+//
+// Functions exported by rpc.c
+//
+
+extern
+RpcSession*
+OpenRpcSession(
+   IN    char *pHostName);
+
+extern
+void
+CloseRpcSession(
+   IN    RpcSession *pSession);
+
+extern
+CasaStatus
+Rpc(
+   IN    RpcSession *pSession,
+   IN    char *pMethod,
+   IN    bool secure,
+   IN    char *pRequestData,
+   INOUT char **ppResponseData,
+   INOUT int *pResponseDataLen);
+
+//
+// Defined in utils.c
+//
+
+extern
+CasaStatus
+EncodeData(
+   IN    const void *pData,
+   IN    const int32_t dataLen,
+   INOUT char **ppEncodedData,
+   INOUT int32_t *pEncodedDataLen);
+
+extern
+CasaStatus
+DecodeData(
+   IN    const char *pEncodedData,
+   IN    const int32_t encodedDataLen, // Does not include NULL terminator
+   INOUT void **ppData,
+   INOUT int32_t *pDataLen);
+
+extern
+int
+dtoul(
+   IN    char *cp,
+   IN    int len);
+
+
+//=========================================================================
+
+#endif // _INTERNAL_H_
+
diff --git a/auth_token/client/list_entry.h b/auth_token/client/list_entry.h
new file mode 100644
index 00000000..42aaa926
--- /dev/null
+++ b/auth_token/client/list_entry.h
@@ -0,0 +1,186 @@
+/***********************************************************************
+ * 
+ *  Copyright (C) 2005-2006 Novell, Inc. All Rights Reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; version 2.1
+ *  of the License.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, Novell, Inc.
+ * 
+ *  To contact Novell about this file by physical or electronic mail, 
+ *  you may find current contact information at www.novell.com.
+ * 
+ ***********************************************************************/
+
+#ifndef _LIST_ENTRY_H_
+#define _LIST_ENTRY_H_
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" 
+{
+#endif
+
+//===[ Include files ]=====================================================
+
+//#include <micasa_types.h>
+
+//===[ Type definitions ]==================================================
+
+#ifndef CSAPI
+#if defined(WIN32)
+#define CSAPI __stdcall
+#else
+#define CSAPI
+#endif
+#endif
+
+#ifndef IN
+#define IN
+#endif
+
+#ifndef OUT
+#define OUT
+#endif
+
+#ifndef INOUT
+#define INOUT
+#endif
+
+//
+// LIST_ENTRY Type
+// Doubly linked list structure
+//
+//typedef struct _LIST_ENTRY
+//{
+//   struct _LIST_ENTRY * volatile Flink;
+//   struct _LIST_ENTRY * volatile Blink;
+//} LIST_ENTRY, *PLIST_ENTRY;
+
+
+//===[ Inlines functions   ]===============================================
+
+//
+// Inline functions for operating on LIST_ENTRY double-linked lists
+//
+
+__inline static void InitializeListHead(
+   IN    PLIST_ENTRY       pListEntry )
+{
+   pListEntry->Flink = pListEntry->Blink = pListEntry;
+}
+
+__inline static void InsertEntryAfter(
+   IN    PLIST_ENTRY       pListEntry,
+   IN    PLIST_ENTRY       pAfterEntry )
+{
+   pListEntry->Flink = pAfterEntry->Flink;
+   pListEntry->Blink = pAfterEntry;
+   pListEntry->Flink->Blink = pAfterEntry->Flink = pListEntry;
+}
+
+__inline static void InsertEntryBefore(
+   IN    PLIST_ENTRY       pListEntry,
+   IN    PLIST_ENTRY       pBeforeEntry )
+{
+   pListEntry->Flink = pBeforeEntry;
+   pListEntry->Blink = pBeforeEntry->Blink;
+   pListEntry->Blink->Flink = pBeforeEntry->Blink = pListEntry;
+}
+
+__inline static void InsertHeadList(
+   IN    PLIST_ENTRY       pListHead,
+   IN    PLIST_ENTRY       pListEntry )
+{
+   pListEntry->Blink = pListHead;
+   pListEntry->Flink = pListHead->Flink;
+   pListEntry->Flink->Blink = pListHead->Flink = pListEntry;
+}
+
+__inline static void InsertTailList(
+   IN    PLIST_ENTRY       pListHead,
+   IN    PLIST_ENTRY       pListEntry )
+{
+   pListEntry->Flink = pListHead;
+   pListEntry->Blink = pListHead->Blink;
+   pListEntry->Blink->Flink = pListHead->Blink = pListEntry;
+}
+
+__inline static bool IsListEmpty(
+   IN    PLIST_ENTRY       pListHead )
+{
+   bool rc = false;
+   if(pListHead->Flink == pListHead)
+      rc = true;
+   return(rc);
+}
+
+__inline static void RemoveEntryList(
+   IN    PLIST_ENTRY       pListEntry )
+{
+   pListEntry->Flink->Blink = pListEntry->Blink;
+   pListEntry->Blink->Flink = pListEntry->Flink;
+   pListEntry->Flink = pListEntry->Blink = (PLIST_ENTRY) 0xbaadf00d;
+}
+
+__inline static PLIST_ENTRY RemoveHeadList(
+   IN    PLIST_ENTRY       pListHead )
+{
+   PLIST_ENTRY Entry = (PLIST_ENTRY)0;
+   if(pListHead->Flink != pListHead)
+   {
+      Entry = pListHead->Flink;
+      RemoveEntryList(Entry);
+   }
+   return(Entry);
+}
+
+__inline static PLIST_ENTRY RemoveTailList(
+   IN    PLIST_ENTRY       pListHead )
+{
+   PLIST_ENTRY Entry= (PLIST_ENTRY)0;
+   if(pListHead->Blink != pListHead)
+   {
+      Entry = pListHead->Blink;
+      RemoveEntryList(Entry);
+   }
+   return(Entry);
+}
+
+__inline static PLIST_ENTRY GetFirstListEntry(
+   IN    PLIST_ENTRY pList)
+{
+   PLIST_ENTRY Entry = (PLIST_ENTRY)0;
+   if(pList != pList->Flink)
+      Entry = pList->Flink;
+   return(Entry);
+}
+
+__inline static PLIST_ENTRY GetNextListEntry(
+   IN    PLIST_ENTRY pList,
+   IN    PLIST_ENTRY pEntry)
+{
+   PLIST_ENTRY Entry = (PLIST_ENTRY)0;
+   if(pList != pEntry->Flink)
+      Entry = pEntry->Flink;
+   return(Entry);
+}
+
+
+//=========================================================================
+
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif // #if defined(__cplusplus) || defined(c_plusplus)
+
+#endif // #ifndef _LIST_ENTRY_H_
+
+
diff --git a/auth_token/client/mech_if.h b/auth_token/client/mech_if.h
new file mode 100644
index 00000000..346cec6e
--- /dev/null
+++ b/auth_token/client/mech_if.h
@@ -0,0 +1,232 @@
+/***********************************************************************
+ * 
+ *  Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; version 2.1
+ *  of the License.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, Novell, Inc.
+ * 
+ *  To contact Novell about this file by physical or electronic mail, 
+ *  you may find current contact information at www.novell.com.
+ * 
+ *  Author: Juan Carlos Luciani <jluciani@novell.com>
+ *
+ ***********************************************************************/
+
+
+#ifndef _MECH_IF_H_
+#define _MECH_IF_H_
+
+
+//===[ Include files ]=====================================================
+
+//===[ Type definitions ]==================================================
+
+//===[ Function prototypes ]===============================================
+
+//===[ Global variables ]==================================================
+
+/**************************************************************************
+***************************************************************************
+**                                                                       **
+**    Definitions common to all interfaces                               **
+**                                                                       **
+***************************************************************************
+**************************************************************************/
+
+
+//++=======================================================================
+typedef
+int       
+(SSCS_CALL *PFN_AddReference)(
+   IN       const void  *pIfInstance);
+//
+// Arguments:  
+//    pIfInstance -
+//       Pointer to interface object.
+//   
+// Returns:
+//    Interface reference count.
+//                           
+// Description:
+//    Increases interface reference count.
+//=======================================================================--
+
+
+//++=======================================================================
+typedef
+void       
+(SSCS_CALL *PFN_ReleaseReference)(
+   IN       const void  *pIfInstance);
+//
+// Arguments:  
+//    pIfInstance -
+//       Pointer to interface object.
+//   
+// Returns:
+//    Nothing.
+//                           
+// Description:
+//    Decreases interface reference count. The interface is deallocated if
+//    the reference count becomes zero.
+//=======================================================================--
+
+
+
+/**************************************************************************
+***************************************************************************
+**                                                                       **
+**    Configuration Object Interface Definitions                         **
+**                                                                       **
+***************************************************************************
+**************************************************************************/
+
+
+//++=======================================================================
+typedef
+char*
+(SSCS_CALL *PFN_GetEntryValue)(
+   IN       const void  *pIfInstance,
+   IN       const char  *pKeyName);
+//
+// Arguments:  
+//    pIfInstance -
+//       Pointer to interface object.
+//   
+//    pKeyName -
+//       Pointer to NULL terminated string that contains the
+//       name of the key whose value is being requested.
+//               
+// Returns:
+//    Pointer to NULL terminated string with value being requested or NULL.
+//                           
+// Description:
+//    Gets value associated with a key for the configuration object.
+//=======================================================================--
+
+
+//
+// Config Interface Object
+// 
+typedef struct _ConfigIf
+{
+   PFN_AddReference                    addReference;
+   PFN_ReleaseReference                releaseReference;
+   PFN_GetEntryValue                   getEntryValue;
+
+} ConfigIf, *PConfigIf;
+
+
+
+/**************************************************************************
+***************************************************************************
+**                                                                       **
+**    Authentication Mechanism Token Interface Definitions               **
+**                                                                       **
+***************************************************************************
+**************************************************************************/
+
+
+//++=======================================================================
+typedef
+CasaStatus 
+(SSCS_CALL *PFN_GetAuthToken)(
+   IN       const void        *pIfInstance,
+   IN       const char        *pContext,
+   IN       const char        *pMechInfo,
+   INOUT    char              *pTokenBuf,
+   INOUT    int               *pTokenBufLen);
+//
+// Arguments:  
+//    pIfInstance -
+//       Pointer to interface object.
+//   
+//    pServiceConfigIf -
+//       Pointer to service config object to which the client is trying to
+//       authenticate.
+//               
+//    pContext -
+//       Pointer to null terminated string containing mechanism specific
+//       context information. Another name for context is Authentication
+//       Realm.
+//
+//    pMechInfo -
+//       Pointer to null terminated string containing mechanism specific
+//       information. This is information is provided by the server to
+//       aid the mechanism to generate an authentication token. For
+//       example, the mechanism information for a Kerberos mechanism
+//       may be the service principal name to which the user will be
+//       authenticating.
+//               
+//    pTokenBuf -
+//       Pointer to buffer that will receive the authentication
+//       token. The length of this buffer is specified by the
+//       pTokenBufLen parameter. Note that the the authentication
+//       token will be in the form of a NULL terminated string.
+//
+//    pTokenBufLen -
+//       Pointer to integer that contains the length of the
+//       buffer pointed at by pTokenBuf. Upon return of the
+//       function, the integer will contain the actual length
+//       of the authentication token if the function successfully
+//       completes or the buffer length required if the function
+//       fails because the buffer pointed at by pUserNameBuf is
+//       not large enough.
+//   
+// Returns:
+//    Casa Status
+//                           
+// Description:
+//    Get authentication token to authenticate user to specified service.
+//=======================================================================--
+
+
+//
+// AuthMechToken Interface Object
+// 
+typedef struct _AuthTokenIf
+{
+   PFN_AddReference                    addReference;
+   PFN_ReleaseReference                releaseReference;
+   PFN_GetAuthToken                    getAuthToken;
+
+} AuthTokenIf, *PAuthTokenIf;
+
+
+//++=======================================================================
+typedef
+CasaStatus
+(SSCS_CALL *PFN_GetAuthTokenIfRtn)(
+   IN       const ConfigIf    *pModuleConfigIf,
+   INOUT    AuthTokenIf       **ppAuthTokenIf);
+//
+// Arguments:  
+//    pModuleConfigIf -
+//       Pointer to configuration interface instance for the module.
+//               
+//    ppAuthTokenIf -
+//       Pointer to variable that will receive pointer to AuthTokenIf
+//       instance.
+//
+// Returns:
+//    Casa Status
+//                           
+// Description:
+//    Gets authentication token interface instance.
+//=======================================================================--
+
+#define GET_AUTH_TOKEN_INTERFACE_RTN_SYMBOL  "GetAuthTokenInterface"
+#define GET_AUTH_TOKEN_INTERFACE_RTN         GetAuthTokenInterface
+
+
+#endif // #ifndef _MECH_IF_H_
+
diff --git a/auth_token/client/mechanisms/krb5/Krb5Authenticate.conf b/auth_token/client/mechanisms/krb5/Krb5Authenticate.conf
new file mode 100644
index 00000000..df843e9f
--- /dev/null
+++ b/auth_token/client/mechanisms/krb5/Krb5Authenticate.conf
@@ -0,0 +1,12 @@
+#######################################################
+#                                                     #
+# CASA Authentication Token System configuration file #
+# for module:                                         #
+#                                                     #
+#     Krb5Authenticate                                #
+#                                                     #
+#######################################################
+
+LibraryName		\Program Files\novell\casa\lib\krb5mech.dll
+
+
diff --git a/auth_token/client/mechanisms/krb5/interface.c b/auth_token/client/mechanisms/krb5/interface.c
new file mode 100644
index 00000000..2fbdf3f4
--- /dev/null
+++ b/auth_token/client/mechanisms/krb5/interface.c
@@ -0,0 +1,207 @@
+/***********************************************************************
+ * 
+ *  Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; version 2.1
+ *  of the License.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, Novell, Inc.
+ * 
+ *  To contact Novell about this file by physical or electronic mail, 
+ *  you may find current contact information at www.novell.com.
+ * 
+ *  Author: Juan Carlos Luciani <jluciani@novell.com>
+ *
+ ***********************************************************************/
+
+//===[ Include files ]=====================================================
+
+#include "internal.h"
+
+//===[ Type definitions ]==================================================
+
+//
+// Authentication Token Interface instance data
+// 
+typedef struct _AuthTokenIfInstance
+{
+   int            refCount;
+   AuthTokenIf    authTokenIf;
+
+} AuthTokenIfInstance, *PAuthTokenIfInstance;
+
+//===[ Function prototypes ]===============================================
+
+//===[ Global variables ]==================================================
+
+// AuthTokenIf variables
+static
+int   g_numAuthTokenIfObjs = 0;
+
+
+//++=======================================================================
+static
+int SSCS_CALL
+AuthTokenIf_AddReference(
+   IN       const void  *pIfInstance)
+//
+// Arguments:  
+//    pIfInstance -
+//       Pointer to interface object.
+//   
+// Returns:
+//    Interface reference count.
+//                           
+// Description:
+//    Increases interface reference count.
+//
+// L2
+//=======================================================================--
+{
+   int                  refCount;
+   AuthTokenIfInstance  *pAuthTokenIfInstance = CONTAINING_RECORD(pIfInstance, AuthTokenIfInstance, authTokenIf);
+
+   DbgTrace(2, "-AuthTokenIf_AddReference- Start\n", 0);
+
+   // Increment the reference count on the object
+   pAuthTokenIfInstance->refCount ++;
+   refCount = pAuthTokenIfInstance->refCount;
+
+   DbgTrace(2, "-AuthTokenIf_AddReference- End, refCount = %08X\n", refCount);
+
+   return refCount;
+}
+
+
+//++=======================================================================
+static
+void SSCS_CALL
+AuthTokenIf_ReleaseReference(
+   IN       const void  *pIfInstance)
+//
+// Arguments:  
+//    pIfInstance -
+//       Pointer to interface object.
+//   
+// Returns:
+//    Nothing.
+//                           
+// Description:
+//    Decreases interface reference count. The interface is deallocated if
+//    the reference count becomes zero.
+//
+// L2
+//=======================================================================--
+{
+   bool                 freeObj = false;
+   AuthTokenIfInstance  *pAuthTokenIfInstance = CONTAINING_RECORD(pIfInstance, AuthTokenIfInstance, authTokenIf);
+
+   DbgTrace(2, "-AuthTokenIf_ReleaseReference- Start\n", 0);
+
+   // Decrement the reference count on the object and determine if it needs to
+   // be released.
+   pAuthTokenIfInstance->refCount --;
+   if (pAuthTokenIfInstance->refCount == 0)
+   {
+      // The object needs to be released, forget about it.
+      freeObj = true;
+      g_numAuthTokenIfObjs --;
+   }
+
+   // Free object if necessary
+   if (freeObj)
+      free(pAuthTokenIfInstance);
+
+   DbgTrace(2, "-AuthTokenIf_ReleaseReference- End\n", 0);
+}
+
+
+//++=======================================================================
+CasaStatus SSCS_CALL
+GET_AUTH_TOKEN_INTERFACE_RTN(
+   IN       const ConfigIf    *pModuleConfigIf,
+   INOUT    AuthTokenIf       **ppAuthTokenIf)
+//
+// Arguments:  
+//    pModuleConfigIf -
+//       Pointer to configuration interface instance for the module.
+//               
+//    ppAuthTokenIf -
+//       Pointer to variable that will receive pointer to AuthTokenIf
+//       instance.
+//
+// Returns:
+//    Casa Status
+//                           
+// Description:
+//    Gets authentication token interface instance.
+//
+// L2
+//=======================================================================--
+{
+   CasaStatus           retStatus;
+   AuthTokenIfInstance  *pAuthTokenIfInstance;
+
+
+   DbgTrace(1, "-GetAuthTokenInterface- Start\n", 0);
+
+   // Validate input parameters
+   if (pModuleConfigIf == NULL
+       || ppAuthTokenIf == NULL)
+   {
+      DbgTrace(0, "-GetAuthTokenInterface- Invalid input parameter\n", 0);
+
+      retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                  CASA_FACILITY_PWTOKEN,
+                                  CASA_STATUS_INVALID_PARAMETER);
+      goto exit;
+   }
+
+   // Allocate space for the interface instance
+   pAuthTokenIfInstance = malloc(sizeof(*pAuthTokenIfInstance));
+   if (pAuthTokenIfInstance)
+   {
+      // Initialize the interface instance data
+      pAuthTokenIfInstance->refCount = 1;
+      pAuthTokenIfInstance->authTokenIf.addReference = AuthTokenIf_AddReference;
+      pAuthTokenIfInstance->authTokenIf.releaseReference = AuthTokenIf_ReleaseReference;
+      pAuthTokenIfInstance->authTokenIf.getAuthToken = AuthTokenIf_GetAuthToken;
+
+      // Keep track of this object
+      g_numAuthTokenIfObjs ++;
+
+      // Return the interface to the caller
+      *ppAuthTokenIf = &pAuthTokenIfInstance->authTokenIf;
+
+      // Success
+      retStatus = CASA_STATUS_SUCCESS;
+   }
+   else
+   {
+      DbgTrace(0, "-GetAuthTokenInterface- Buffer allocation failure\n", 0);
+
+      retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                  CASA_FACILITY_PWTOKEN,
+                                  CASA_STATUS_INSUFFICIENT_RESOURCES);
+   }
+
+exit:
+
+   DbgTrace(1, "-GetAuthTokenInterface- End, retStatus = %08X\n", retStatus);
+
+   return retStatus;
+}
+
+
+//++=======================================================================
+//++=======================================================================
+//++=======================================================================
+
diff --git a/auth_token/client/mechanisms/krb5/internal.h b/auth_token/client/mechanisms/krb5/internal.h
new file mode 100644
index 00000000..c4eb41d0
--- /dev/null
+++ b/auth_token/client/mechanisms/krb5/internal.h
@@ -0,0 +1,105 @@
+/***********************************************************************
+ * 
+ *  Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; version 2.1
+ *  of the License.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, Novell, Inc.
+ * 
+ *  To contact Novell about this file by physical or electronic mail, 
+ *  you may find current contact information at www.novell.com.
+ * 
+ *  Author: Juan Carlos Luciani <jluciani@novell.com>
+ *
+ ***********************************************************************/
+
+#ifndef _INTERNAL_H_
+#define _INTERNAL_H_
+
+//===[ Include files ]=====================================================
+
+#include "platform.h"
+#include <micasa_types.h>
+#include <casa_status.h>
+#include "mech_if.h"
+
+//===[ Type definitions ]==================================================
+
+#ifndef CONTAINING_RECORD
+#define CONTAINING_RECORD(address, type, field) ((type *)(     \
+             (char*)(address) -                                \
+             (char*)(&((type *)0)->field)))
+#endif
+
+//
+// DbgTrace macro define
+//
+#define DbgTrace(LEVEL, X, Y) {                          \
+   if (LEVEL == 0)                                       \
+      printf(X, Y);                                      \
+   else if (DebugLevel >= LEVEL)                         \
+         printf(X, Y);                                   \
+}
+
+//===[ Inlines functions   ]===============================================
+
+//===[ Function prototypes ]===============================================
+
+//===[ Global variables ]==================================================
+
+//===[ Global externals ]==================================================
+
+extern int  DebugLevel;
+
+//===[ External prototypes ]===============================================
+
+//
+// Defined in get.c
+//
+
+extern
+CasaStatus SSCS_CALL
+AuthTokenIf_GetAuthToken(
+   IN       const void        *pIfInstance,
+   IN       const char        *pContext,
+   IN       const char        *pMechInfo,
+   INOUT    char              *pTokenBuf,
+   INOUT    int               *pTokenBufLen);
+
+extern
+int
+InitializeLibrary(void);
+
+//
+// Defined in utils.c
+//
+
+extern
+CasaStatus
+EncodeData(
+   IN    const void *pData,
+   IN    const int32_t dataLen,
+   INOUT char **ppEncodedData,
+   INOUT int32_t *pEncodedDataLen);
+
+extern
+CasaStatus
+DecodeData(
+   IN    const char *pEncodedData,
+   IN    const int32_t encodedDataLen, // Does not include NULL terminator
+   INOUT void **ppData,
+   INOUT int32_t *pDataLen);
+
+
+//=========================================================================
+
+#endif // _INTERNAL_H_
diff --git a/auth_token/client/mechanisms/krb5/krb5.vcproj b/auth_token/client/mechanisms/krb5/krb5.vcproj
new file mode 100644
index 00000000..4d0e49f2
--- /dev/null
+++ b/auth_token/client/mechanisms/krb5/krb5.vcproj
@@ -0,0 +1,180 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="krb5"
+	ProjectGUID="{5499F624-F371-4559-B4C2-A484BCE892FD}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)client\mechanisms\krb5\win32\$(ConfigurationName)"
+			IntermediateDirectory="$(SolutionDir)client\mechanisms\krb5\win32\$(ConfigurationName)"
+			ConfigurationType="2"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="-DSECURITY_WIN32"
+				Optimization="0"
+				AdditionalIncludeDirectories="win32;.;..\..;..\..\..\..\include"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="5"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="4"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions="/EXPORT:GetAuthTokenInterface"
+				AdditionalDependencies="secur32.lib"
+				OutputFile="$(OutDir)/krb5mech.dll"
+				LinkIncremental="1"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/pw.pdb"
+				SubSystem="0"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				CommandLine="mkdir \&quot;Program Files&quot;\novell\
+mkdir \&quot;Program Files&quot;\novell\casa
+mkdir \&quot;Program Files&quot;\novell\casa\lib\
+mkdir \&quot;Program Files&quot;\novell\casa\etc\
+mkdir \&quot;Program Files&quot;\novell\casa\etc\auth\
+mkdir \&quot;Program Files&quot;\novell\casa\etc\auth\mechanisms\
+copy Krb5Authenticate.conf \&quot;Program Files&quot;\novell\casa\etc\auth\mechanisms\Krb5Authenticate.conf
+copy $(OutDir)\krb5mech.dll \&quot;Program Files&quot;\novell\casa\lib\krb5mech.dll"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)client\mechanisms\krb5\win32\$(ConfigurationName)"
+			IntermediateDirectory="$(SolutionDir)client\mechanisms\krb5\win32\$(ConfigurationName)"
+			ConfigurationType="2"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="-DSECURITY_WIN32"
+				AdditionalIncludeDirectories="win32;.;..\..;..\..\..\..\include"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+				RuntimeLibrary="4"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions="/EXPORT:GetAuthTokenInterface"
+				AdditionalDependencies="secur32.lib"
+				OutputFile="$(OutDir)/krb5mech.dll"
+				LinkIncremental="1"
+				GenerateDebugInformation="TRUE"
+				SubSystem="0"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				CommandLine="mkdir \&quot;Program Files&quot;\novell\
+mkdir \&quot;Program Files&quot;\novell\casa
+mkdir \&quot;Program Files&quot;\novell\casa\lib\
+mkdir \&quot;Program Files&quot;\novell\casa\etc\
+mkdir \&quot;Program Files&quot;\novell\casa\etc\auth\
+mkdir \&quot;Program Files&quot;\novell\casa\etc\auth\mechanisms\
+copy Krb5Authenticate.conf \&quot;Program Files&quot;\novell\casa\etc\auth\mechanisms\Krb5Authenticate.conf
+copy $(OutDir)\krb5mech.dll \&quot;Program Files&quot;\novell\casa\lib\krb5mech.dll"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+			<File
+				RelativePath=".\win32\dllsup.c">
+			</File>
+			<File
+				RelativePath=".\win32\get.c">
+			</File>
+			<File
+				RelativePath=".\interface.c">
+			</File>
+			<File
+				RelativePath=".\Krb5Authenticate.conf">
+			</File>
+			<File
+				RelativePath=".\win32\krb5mech.def">
+			</File>
+			<File
+				RelativePath=".\win32\platutils.c">
+			</File>
+			<File
+				RelativePath=".\util.c">
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+			<File
+				RelativePath=".\internal.h">
+			</File>
+			<File
+				RelativePath=".\win32\platform.h">
+			</File>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/auth_token/client/mechanisms/krb5/util.c b/auth_token/client/mechanisms/krb5/util.c
new file mode 100644
index 00000000..634203f8
--- /dev/null
+++ b/auth_token/client/mechanisms/krb5/util.c
@@ -0,0 +1,282 @@
+/***********************************************************************
+ * 
+ *  Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; version 2.1
+ *  of the License.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, Novell, Inc.
+ * 
+ *  To contact Novell about this file by physical or electronic mail, 
+ *  you may find current contact information at www.novell.com.
+ * 
+ *  Author: Juan Carlos Luciani <jluciani@novell.com>
+ *
+ ***********************************************************************/
+
+//===[ Include files ]=====================================================
+
+#include "internal.h"
+
+//===[ Type definitions ]==================================================
+
+//===[ Function prototypes ]===============================================
+
+//===[ Global variables ]==================================================
+
+// Debug Level
+int   DebugLevel = 2;
+
+// Tables for Base64 encoding and decoding
+static const int8_t  g_Base64[] =
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+static const uint8_t g_Expand64[256] =
+{
+    /* ASCII table */
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,
+    52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,
+    64,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
+    15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64,
+    64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+    41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64,
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
+};
+
+
+//++=======================================================================
+CasaStatus
+EncodeData(
+   IN    const void *pData,
+   IN    const int32_t dataLen,
+   INOUT char **ppEncodedData,
+   INOUT int32_t *pEncodedDataLen)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Description:  
+//
+// L2
+//=======================================================================--
+{
+   CasaStatus  retStatus;
+   int         encodedSize;
+
+   char        *pTmp;
+
+   DbgTrace(3, "-EncodeData- Start\n", 0);
+
+   // Determine the encoded size and allocate a buffer to hold the encoded data
+   encodedSize = ((dataLen * 4 + 2) / 3) - (dataLen % 3 ) + 4;
+   pTmp = (char*) malloc(encodedSize);
+   *ppEncodedData = pTmp;
+   if (*ppEncodedData)
+   {
+      uint8_t  *pOut, *pIn;
+      int      i;
+
+      // Setup pointers to move through the buffers
+      pIn = (uint8_t*) pData;
+      pOut = (uint8_t*) *ppEncodedData;
+
+      // Perform the encoding
+      for (i = 0; i < dataLen - 2; i += 3)
+      {
+          *pOut++ = g_Base64[(pIn[i] >> 2) & 0x3F];
+          *pOut++ = g_Base64[((pIn[i] & 0x3) << 4) |
+                          ((int32_t)(pIn[i + 1] & 0xF0) >> 4)];
+          *pOut++ = g_Base64[((pIn[i + 1] & 0xF) << 2) |
+                          ((int32_t)(pIn[i + 2] & 0xC0) >> 6)];
+          *pOut++ = g_Base64[pIn[i + 2] & 0x3F];
+      }
+      if (i < dataLen)
+      {
+          *pOut++ = g_Base64[(pIn[i] >> 2) & 0x3F];
+          if (i == (dataLen - 1))
+          {
+              *pOut++ = g_Base64[((pIn[i] & 0x3) << 4)];
+              *pOut++ = '=';
+          }
+          else
+          {
+              *pOut++ = g_Base64[((pIn[i] & 0x3) << 4) |
+                              ((int32_t)(pIn[i + 1] & 0xF0) >> 4)];
+              *pOut++ = g_Base64[((pIn[i + 1] & 0xF) << 2)];
+          }
+          *pOut++ = '=';
+      }
+      *pOut++ = '\0';
+
+      // Return the encoded data length
+      *pEncodedDataLen = (int32_t)(pOut - (uint8_t*)*ppEncodedData); 
+
+      // Success
+      retStatus = CASA_STATUS_SUCCESS;
+   }
+   else
+   {
+      DbgTrace(0, "-EncodeData- Buffer allocation failure\n", 0);
+
+      retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                  CASA_FACILITY_PWTOKEN,
+                                  CASA_STATUS_INSUFFICIENT_RESOURCES);
+   }
+
+   DbgTrace(3, "-EncodeData- End, retStatus = %08X\n", retStatus);
+
+   return retStatus;
+}
+
+
+//++=======================================================================
+CasaStatus
+DecodeData(
+   IN    const char *pEncodedData,
+   IN    const int32_t encodedDataLen, // Does not include NULL terminator
+   INOUT void **ppData,
+   INOUT int32_t *pDataLen)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Description:  
+//
+// L2
+//=======================================================================--
+{
+   CasaStatus  retStatus;
+   int         i, j;
+   int         decodedSize;
+
+   DbgTrace(3, "-DecodeData- Start\n", 0);
+
+   // Determine the decoded size
+   for (i = 0, j = 0; i < encodedDataLen; i++)
+       if (g_Expand64[((uint8_t*) pEncodedData)[i]] < 64)
+           j++;
+   decodedSize = (j * 3 + 3) / 4;
+
+   // Allocate buffer to hold the decoded data
+   *ppData = malloc(decodedSize);
+   if (*ppData)
+   {
+      bool  endReached = false;
+      uint8_t  c0, c1, c2, c3;
+      uint8_t  *p, *q;
+
+      // Initialize parameters that will be used during the decode operation
+      c0 = c1 = c2 = c3 = 0;
+      p = (uint8_t*) pEncodedData;
+      q = (uint8_t*) *ppData;
+
+      // Decode the data
+      //
+      // Loop through the data, piecing back information. Any newlines, and/or
+      // carriage returns need to be skipped.
+      while (j > 4)
+      {
+          while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p)))
+              p++;
+          if (64 == g_Expand64[*p])
+          {
+              endReached = true;
+              break;
+          }
+          c0 = *(p++);
+
+          while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p)))
+              p++;
+          if (64 == g_Expand64[*p])
+          {
+              *(q++) = (uint8_t)(g_Expand64[c0] << 2);
+              j--;
+              endReached = true;
+              break;
+          }
+          c1 = *(p++);
+
+          while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p)))
+              p++;
+          if (64 == g_Expand64[*p])
+          {
+              *(q++) = (uint8_t)(g_Expand64[c0] << 2 | g_Expand64[c1] >> 4);
+              *(q++) = (uint8_t)(g_Expand64[c1] << 4);
+              j -= 2;
+              endReached = true;
+              break;
+          }
+          c2 = *(p++);
+
+          while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p)))
+              p++;
+          if (64 == g_Expand64[*p])
+          {
+              *(q++) = (uint8_t)(g_Expand64[c0] << 2 | g_Expand64[c1] >> 4);
+              *(q++) = (uint8_t)(g_Expand64[c1] << 4 | g_Expand64[c2] >> 2);
+              *(q++) = (uint8_t)(g_Expand64[c2] << 6);
+              j -= 3;
+              endReached = true;
+              break;
+          }
+          c3 = *(p++);
+
+          *(q++) = (uint8_t)(g_Expand64[c0] << 2 | g_Expand64[c1] >> 4);
+          *(q++) = (uint8_t)(g_Expand64[c1] << 4 | g_Expand64[c2] >> 2);
+          *(q++) = (uint8_t)(g_Expand64[c2] << 6 | g_Expand64[c3]);
+          j -= 4;
+      }
+      if (!endReached)
+      {
+          if (j > 1)
+              *(q++) = (uint8_t)(g_Expand64[*p] << 2 | g_Expand64[p[1]] >> 4);
+          if (j > 2)
+              *(q++) = (uint8_t)(g_Expand64[p[1]] << 4 | g_Expand64[p[2]] >> 2);
+          if (j > 3)
+              *(q++) = (uint8_t)(g_Expand64[p[2]] << 6 | g_Expand64[p[3]]);
+      }
+
+      // Return the length of the decoded data
+      *pDataLen = (int32_t)(q - (uint8_t*)*ppData);
+
+      // Success
+      retStatus = CASA_STATUS_SUCCESS;
+   }
+   else
+   {
+      DbgTrace(0, "-DecodeData- Buffer allocation failure\n", 0);
+
+      retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                  CASA_FACILITY_PWTOKEN,
+                                  CASA_STATUS_INSUFFICIENT_RESOURCES);
+   }
+
+   DbgTrace(3, "-DecodeData- End, retStatus = %08X\n", retStatus);
+
+   return retStatus;
+}
+
+
+//++=======================================================================
+//++=======================================================================
+//++=======================================================================
+
diff --git a/auth_token/client/mechanisms/krb5/win32/dllsup.c b/auth_token/client/mechanisms/krb5/win32/dllsup.c
new file mode 100644
index 00000000..8eecacef
--- /dev/null
+++ b/auth_token/client/mechanisms/krb5/win32/dllsup.c
@@ -0,0 +1,132 @@
+/***********************************************************************
+ * 
+ *  Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; version 2.1
+ *  of the License.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, Novell, Inc.
+ * 
+ *  To contact Novell about this file by physical or electronic mail, 
+ *  you may find current contact information at www.novell.com.
+ * 
+ *  Author: Juan Carlos Luciani <jluciani@novell.com>
+ *
+ ***********************************************************************/
+
+//===[ Include files ]=====================================================
+
+#include "internal.h"
+
+//===[ External data ]=====================================================
+
+//===[ Manifest constants ]================================================
+
+//===[ Type definitions ]==================================================
+
+//===[ Function prototypes ]===============================================
+
+//===[ Global variables ]==================================================
+
+UINT32 g_ulCount  = 0;
+UINT32 g_ulLock = 0;
+HANDLE g_hModule;
+
+
+//++=======================================================================
+BOOL APIENTRY DllMain(
+   HANDLE hModule,
+   DWORD  ul_reason_for_call,
+   LPVOID lpReserved   
+   )
+//=======================================================================--
+{
+   BOOL  retStatus = TRUE;
+
+   switch (ul_reason_for_call)
+   {
+      case DLL_PROCESS_ATTACH:
+      {
+         g_hModule = hModule;
+
+         // Initialize the library
+         if (InitializeLibrary() != 0)
+         {
+            // Failed to initialize the library
+            OutputDebugString("CASA_PW_MECH -DllMain- Library initialization failed\n");
+            retStatus = FALSE;
+         }
+         break;
+      }
+
+      case DLL_THREAD_ATTACH:
+      {
+         g_hModule = hModule;
+         break;
+      }
+
+      case DLL_THREAD_DETACH:
+         break;
+
+      case DLL_PROCESS_DETACH:
+      {
+         /* Don't uninitialize on windows
+         tbd
+         */
+         break;
+      }
+    }
+
+    return retStatus;
+}
+
+//++=======================================================================
+//
+// DllCanUnloadNow
+//
+// Synopsis
+//
+//
+STDAPI
+DllCanUnloadNow()
+//
+// Input Arguments
+//
+// Ouput Arguments
+//
+// Return Value
+//    S_OK    The DLL can be unloaded.
+//    S_FALSE The DLL cannot be unloaded now.
+//
+// Description
+//    An Exported Function.
+//    DLLs that support the OLE Component Object Model (COM) should implement
+//    and export DllCanUnloadNow.
+//    A call to DllCanUnloadNow determines whether the DLL from which it is
+//    exported is still in use. A DLL is no longer in use when it is not
+//    managing  any existing objects (the reference count on all of its objects
+//    is 0).
+//    DllCanUnloadNow returns S_FALSE if there are any existing references to
+//    objects that the DLL manages.
+//
+// Environment
+//
+// See Also
+//
+//=======================================================================--
+{
+   // tbd
+   return ((g_ulCount == 0 && g_ulLock == 0) ? S_OK : S_FALSE);
+}
+
+//=========================================================================
+//=========================================================================
+
diff --git a/auth_token/client/mechanisms/krb5/win32/get.c b/auth_token/client/mechanisms/krb5/win32/get.c
new file mode 100644
index 00000000..fa1cdb7d
--- /dev/null
+++ b/auth_token/client/mechanisms/krb5/win32/get.c
@@ -0,0 +1,266 @@
+/***********************************************************************
+ * 
+ *  Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; version 2.1
+ *  of the License.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, Novell, Inc.
+ * 
+ *  To contact Novell about this file by physical or electronic mail, 
+ *  you may find current contact information at www.novell.com.
+ * 
+ *  Author: Juan Carlos Luciani <jluciani@novell.com>
+ *
+ ***********************************************************************/
+
+
+//===[ Include files ]=====================================================
+
+#include "internal.h"
+
+//===[ Type definitions ]==================================================
+
+//===[ Function prototypes ]===============================================
+
+//===[ Global variables ]==================================================
+
+
+//++=======================================================================
+CasaStatus SSCS_CALL
+AuthTokenIf_GetAuthToken(
+   IN       const void  *pIfInstance,
+   IN       const char  *pContext,
+   IN       const char  *pMechInfo,
+   INOUT    char        *pTokenBuf,
+   INOUT    int         *pTokenBufLen)
+//
+// Arguments:  
+//    pIfInstance -
+//       Pointer to interface object.
+//   
+//    pServiceConfigIf -
+//       Pointer to service config object to which the client is trying to
+//       authenticate.
+//               
+//    pContext -
+//       Pointer to null terminated string containing mechanism specific
+//       context information. Another name for context is Authentication
+//       Realm.
+//
+//    pMechInfo -
+//       Pointer to null terminated string containing mechanism specific
+//       information. This is information is provided by the server to
+//       aid the mechanism to generate an authentication token. For
+//       example, the mechanism information for a Kerberos mechanism
+//       may be the service principal name to which the user will be
+//       authenticating.
+//               
+//    pTokenBuf -
+//       Pointer to buffer that will receive the authentication
+//       token. The length of this buffer is specified by the
+//       pTokenBufLen parameter. Note that the the authentication
+//       token will be in the form of a NULL terminated string.
+//
+//    pTokenBufLen -
+//       Pointer to integer that contains the length of the
+//       buffer pointed at by pTokenBuf. Upon return of the
+//       function, the integer will contain the actual length
+//       of the authentication token if the function successfully
+//       completes or the buffer length required if the function
+//       fails because the buffer pointed at by pUserNameBuf is
+//       not large enough.
+//   
+// Returns:
+//    Casa Status
+//                           
+// Description:
+//    Get authentication token to authenticate user to specified service.
+//
+// L0
+//=======================================================================--
+{
+   CasaStatus  retStatus;
+   char        *pKrbServiceName = pMechInfo;
+
+   SECURITY_STATUS   secStatus;
+   TimeStamp         expiry;
+   CredHandle        hCredentials = {0};
+
+   DbgTrace(1, "-AuthTokenIf_GetAuthToken- Start\n", 0);
+
+   // Validate input parameters
+   if (pIfInstance == NULL
+       || pContext == NULL
+       || pMechInfo == NULL
+       || pTokenBufLen == NULL
+       || (pTokenBuf == NULL && *pTokenBufLen != 0))
+   {
+      DbgTrace(0, "-AuthTokenIf_GetAuthToken- Invalid input parameter\n", 0);
+
+      retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                  CASA_FACILITY_KRB5TOKEN,
+                                  CASA_STATUS_INVALID_PARAMETER);
+      goto exit;
+   }
+
+   // Acquire a credential handle for the current user
+   secStatus = AcquireCredentialsHandle(NULL,                  // no principal name
+                                        "Kerberos",            // package name
+                                        SECPKG_CRED_OUTBOUND,
+                                        NULL,                  // no logon id
+                                        NULL,                  // no auth data
+                                        NULL,                  // no get key fn
+                                        NULL,                  // noget key arg
+                                        &hCredentials,
+                                        &expiry);
+   if (secStatus == SEC_E_OK)
+   {
+      CtxtHandle        hContext = {0};
+      SecBuffer         sendTok;
+      SecBufferDesc     outputDesc;
+      ULONG             retFlags;
+
+      // We acquired the credential, now initialize a security context
+      // so that we can authenticate the user to the specified service.
+      //
+      // First ready an output descriptor so that we can receive the
+      // token buffer.
+      outputDesc.cBuffers = 1;
+      outputDesc.pBuffers = &sendTok;
+      outputDesc.ulVersion = SECBUFFER_VERSION;
+
+      sendTok.BufferType = SECBUFFER_TOKEN;
+      sendTok.cbBuffer = 0;
+      sendTok.pvBuffer = NULL;
+
+      // Initialize the security context for the specified service
+      secStatus = InitializeSecurityContext(&hCredentials,
+                                            NULL,
+                                            pKrbServiceName,
+                                            ISC_REQ_ALLOCATE_MEMORY,
+                                            0,          // reserved
+                                            SECURITY_NATIVE_DREP,
+                                            NULL,
+                                            0,          // reserved
+                                            &hContext,
+                                            &outputDesc,
+                                            &retFlags,
+                                            &expiry);
+      if (secStatus == SEC_E_OK)
+      {
+         char  *pEncodedToken;
+         int   encodedTokenLen;
+
+         // The security context was initialized, now return it to the caller after base64 encoding it.
+         // The token has been assembled, now encode it.
+         retStatus = EncodeData(sendTok.pvBuffer,
+                                (const int) sendTok.cbBuffer,
+                                &pEncodedToken,
+                                &encodedTokenLen);
+         if (CASA_SUCCESS(retStatus))
+         {
+            // Verify that the caller provided a buffer that is big enough
+            if (encodedTokenLen > *pTokenBufLen)
+            {
+               // The buffer is not big enough
+               DbgTrace(1, "-AuthTokenIf_GetAuthToken- Insufficient buffer space provided\n", 0);
+
+               retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                           CASA_FACILITY_KRB5TOKEN,
+                                           CASA_STATUS_BUFFER_OVERFLOW);
+            }
+            else
+            {
+               // The buffer provided is large enough, copy the data.
+               memcpy((void*) pTokenBuf, pEncodedToken, encodedTokenLen);
+
+               // Success
+               retStatus = CASA_STATUS_SUCCESS;
+            }
+
+            // Return the actual size or the size required
+            *pTokenBufLen = encodedTokenLen;
+
+            // Free the buffer containing the encoded token
+            free(pEncodedToken);
+         }
+
+         // Delete the security context
+         DeleteSecurityContext(&hContext);
+      }
+      else
+      {
+         DbgTrace(1, "-AuthTokenIf_GetAuthToken- Failed to obtain the credentials handle, error = %08X\n", secStatus);
+
+         // tdb - Set retStatus based on secStatus
+         retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                     CASA_FACILITY_KRB5TOKEN,
+                                     CASA_STATUS_UNSUCCESSFUL);
+      }
+
+      // Free any buffer associated with the sendToken
+      if (sendTok.pvBuffer)
+         FreeContextBuffer(sendTok.pvBuffer);
+
+      // Free the credential handle obtained
+      FreeCredentialsHandle(&hCredentials);
+
+   }
+   else
+   {
+      DbgTrace(1, "-AuthTokenIf_GetAuthToken- Failed to obtain the credentials handle, error = %08X\n", secStatus);
+
+      // tdb - Set retStatus based on secStatus
+
+      retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                  CASA_FACILITY_KRB5TOKEN,
+                                  CASA_STATUS_NO_CREDENTIALS);
+   }
+         
+exit:
+
+   DbgTrace(1, "-AuthTokenIf_GetAuthToken- End, retStatus = %08X\n", retStatus);
+
+   return retStatus;
+}
+
+
+//++=======================================================================
+int
+InitializeLibrary(void)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L0
+//=======================================================================--
+{
+   int   retStatus = 0;
+
+   DbgTrace(1, "-InitializeLibrary- Start\n", 0);
+
+
+   DbgTrace(1, "-InitializeLibrary- End, retStatus = %08X\n", retStatus);
+
+   return retStatus;
+}
+
+
+//++=======================================================================
+//++=======================================================================
+//++=======================================================================
+
diff --git a/auth_token/client/mechanisms/krb5/win32/krb5mech.def b/auth_token/client/mechanisms/krb5/win32/krb5mech.def
new file mode 100644
index 00000000..1605afcf
--- /dev/null
+++ b/auth_token/client/mechanisms/krb5/win32/krb5mech.def
@@ -0,0 +1,10 @@
+LIBRARY         KRB5MECH
+DESCRIPTION     'CASA Kerberos V Authentication Mechanism Library.'
+
+
+EXPORTS
+;                DllRegisterServer   PRIVATE
+;                DllUnregisterServer PRIVATE
+;                DllGetClassObject   PRIVATE
+                GetAuthTokenInterface  PRIVATE        
+;               DllCanUnloadNow     PRIVATE  
\ No newline at end of file
diff --git a/auth_token/client/mechanisms/krb5/win32/platform.h b/auth_token/client/mechanisms/krb5/win32/platform.h
new file mode 100644
index 00000000..e6ea6f1d
--- /dev/null
+++ b/auth_token/client/mechanisms/krb5/win32/platform.h
@@ -0,0 +1,77 @@
+/***********************************************************************
+ * 
+ *  Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; version 2.1
+ *  of the License.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, Novell, Inc.
+ * 
+ *  To contact Novell about this file by physical or electronic mail, 
+ *  you may find current contact information at www.novell.com.
+ * 
+ *  Author: Juan Carlos Luciani <jluciani@novell.com>
+ *
+ ***********************************************************************/
+
+#ifndef _PLATFORM_H_
+#define _PLATFORM_H_
+
+//===[ Include files ]=====================================================
+
+#include <windows.h>
+#include <stdio.h>
+#include <winerror.h>
+#include <security.h>
+#include <sspi.h>
+
+//===[ Type definitions ]==================================================
+
+#ifndef CONTAINING_RECORD
+#define CONTAINING_RECORD(address, type, field) ((type *)(     \
+             (char*)(address) -                                \
+             (char*)(&((type *)0)->field)))
+#endif
+
+//
+// DbgTrace macro define
+//
+#define DbgTrace(LEVEL, X, Y) {                          \
+char printBuff[256];                                     \
+   if (LEVEL == 0)                                       \
+   {                                                     \
+      _snprintf(printBuff, sizeof(printBuff), X, Y);     \
+      printf("Krb5Mech %s", printBuff);                  \
+   }                                                     \
+   else if (DebugLevel >= LEVEL)                         \
+   {                                                     \
+      _snprintf(printBuff, sizeof(printBuff), X, Y);     \
+      printf("Krb5Mech %s", printBuff);                  \
+   }                                                     \
+}
+
+#define bool BOOLEAN
+#define true TRUE
+#define false FALSE
+
+//===[ Inlines functions   ]===============================================
+
+//===[ Function prototypes ]===============================================
+
+//===[ Global externals ]==================================================
+
+//===[ External prototypes ]===============================================
+
+
+//=========================================================================
+
+#endif // _PLATFORM_H_
+
diff --git a/auth_token/client/mechanisms/krb5/win32/platutils.c b/auth_token/client/mechanisms/krb5/win32/platutils.c
new file mode 100644
index 00000000..869b581c
--- /dev/null
+++ b/auth_token/client/mechanisms/krb5/win32/platutils.c
@@ -0,0 +1,35 @@
+/***********************************************************************
+ * 
+ *  Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; version 2.1
+ *  of the License.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, Novell, Inc.
+ * 
+ *  To contact Novell about this file by physical or electronic mail, 
+ *  you may find current contact information at www.novell.com.
+ * 
+ *  Author: Juan Carlos Luciani <jluciani@novell.com>
+ *
+ ***********************************************************************/
+
+//===[ Include files ]=====================================================
+
+#include "internal.h"
+
+//===[ Type definitions ]==================================================
+
+//===[ Function prototypes ]===============================================
+
+//===[ Global variables ]==================================================
+
+
diff --git a/auth_token/client/mechanisms/pwd/PwdAuthenticate.conf b/auth_token/client/mechanisms/pwd/PwdAuthenticate.conf
new file mode 100644
index 00000000..171f06e0
--- /dev/null
+++ b/auth_token/client/mechanisms/pwd/PwdAuthenticate.conf
@@ -0,0 +1,12 @@
+#######################################################
+#                                                     #
+# CASA Authentication Token System configuration file #
+# for module:                                         #
+#                                                     #
+#     PwdAuthenticate                                 #
+#                                                     #
+#######################################################
+
+LibraryName		\Program Files\novell\casa\lib\pwmech.dll
+
+
diff --git a/auth_token/client/mechanisms/pwd/get.c b/auth_token/client/mechanisms/pwd/get.c
new file mode 100644
index 00000000..47d1807c
--- /dev/null
+++ b/auth_token/client/mechanisms/pwd/get.c
@@ -0,0 +1,359 @@
+/***********************************************************************
+ * 
+ *  Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; version 2.1
+ *  of the License.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, Novell, Inc.
+ * 
+ *  To contact Novell about this file by physical or electronic mail, 
+ *  you may find current contact information at www.novell.com.
+ * 
+ *  Author: Juan Carlos Luciani <jluciani@novell.com>
+ *
+ ***********************************************************************/
+
+
+//===[ Include files ]=====================================================
+
+#include "internal.h"
+
+//===[ Type definitions ]==================================================
+
+//===[ Function prototypes ]===============================================
+
+//===[ Global variables ]==================================================
+
+
+//++=======================================================================
+static
+CasaStatus
+GetUserCredentials(
+   IN       const char *pRealm,
+   INOUT    char **ppUsername,
+   INOUT    char **ppPassword)
+//
+// Arguments:  
+//    pRealm -
+//       The realm to which the credentials apply.
+//   
+//    ppUsername -
+//       Pointer to variable that will receive buffer with the username.
+//               
+//    ppPassword -
+//       Pointer to variable that will receive buffer with the password.
+//   
+// Returns:
+//    Casa Status
+//                           
+// Description:
+//    Get authentication credentials for the specified realm.
+//
+// L0
+//=======================================================================--
+{
+   CasaStatus              retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                                       CASA_FACILITY_PWTOKEN,
+                                                       CASA_STATUS_UNSUCCESSFUL);
+   char                    *pUsername;
+   char                    *pPassword;
+   int                     rcode = NSSCS_E_OBJECT_NOT_FOUND;
+   int32_t                 credtype = SSCS_CRED_TYPE_BASIC_F;
+   SSCS_BASIC_CREDENTIAL   credential = {0};
+   SSCS_SECRET_ID_T        secretId = {0};
+   SSCS_SECRET_ID_T        sharedSecretId = {0};
+   
+   DbgTrace(1, "-GetUserCredentials- Start\n", 0);
+
+   // Initialize output parameters
+   *ppUsername = NULL;
+   *ppPassword = NULL;
+
+   // Get the length of the realm string into the secret id structure
+   // and verify thatr it is not too long.
+   secretId.len = sscs_Utf8Strlen(pRealm) + 1;
+   if (secretId.len <= NSSCS_MAX_SECRET_ID_LEN)
+   {
+      // Set the secret id in the structure
+      sscs_Utf8Strcpy(secretId.id, pRealm);
+
+      // Specify that we want the common name
+      credential.unFlags = USERNAME_TYPE_CN_F;
+
+      // Now try to get the credentials
+      rcode = miCASAGetCredential(0,
+                                  &secretId,          
+                                  NULL,
+                                  &credtype, //SSCS_CRED_TYPE_BASIC_F,     
+                                  &credential,           
+                                  NULL);
+      if (rcode != NSSCS_SUCCESS)
+      {
+         // There were no credentials for the realm, now try to obtain the
+         // desktop credentials.
+         secretId.len = sscs_Utf8Strlen("Desktop") + 1;
+         sscs_Utf8Strcpy(secretId.id, "Desktop");
+         rcode = miCASAGetCredential(0,
+                                     &secretId,          
+                                     NULL,
+                                     &credtype, //SSCS_CRED_TYPE_BASIC_F,     
+                                     &credential,           
+                                     NULL);
+      }
+   }
+   else
+   {
+      DbgTrace(0, "-GetUserCredentials- Realm name too long\n", 0);
+      retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                  CASA_FACILITY_PWTOKEN,
+                                  CASA_STATUS_UNSUCCESSFUL);
+   }
+
+   // Proceed based on the result of the operatiosn above
+   if (rcode == NSSCS_SUCCESS
+       && credential.username != NULL
+       && credential.password != NULL)
+   {
+      // Allocate a buffer to return the username
+      pUsername = (char*) malloc(strlen(credential.username) + 1);
+      if (pUsername)
+      {
+         // Copy the username into the buffer that we will be returning
+         strcpy(pUsername, credential.username);
+
+         // Allocate a buffer to return the password
+         pPassword = (char*) malloc(strlen(credential.password) + 1);
+         if (pPassword)
+         {
+            // Copy the password into the buffer that we will be returning
+            strcpy(pPassword, credential.password);
+
+            // Success
+            retStatus = CASA_STATUS_SUCCESS;
+         }
+         else
+         {
+            DbgTrace(0, "-GetUserCredentials- Buffer allocation error\n", 0);
+            retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                       CASA_FACILITY_PWTOKEN,
+                                       CASA_STATUS_INSUFFICIENT_RESOURCES);
+
+            // Free the buffer allocated for the username
+            free(pUsername);
+         }
+      }
+      else
+      {
+         DbgTrace(0, "-GetUserCredentials- Buffer allocation error\n", 0);
+         retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                    CASA_FACILITY_PWTOKEN,
+                                    CASA_STATUS_INSUFFICIENT_RESOURCES);
+      }
+   }
+
+   // Return the buffers to the caller if successful
+   if (CASA_SUCCESS(retStatus))
+   {
+      *ppUsername = pUsername;
+      *ppPassword = pPassword;
+   }
+
+   DbgTrace(1, "-GetUserCredentials- End, retStatus = %08X\n", retStatus);
+
+   return retStatus;
+}
+
+
+//++=======================================================================
+CasaStatus SSCS_CALL
+AuthTokenIf_GetAuthToken(
+   IN       const void  *pIfInstance,
+   IN       const char  *pContext,
+   IN       const char  *pMechInfo,
+   INOUT    char        *pTokenBuf,
+   INOUT    int         *pTokenBufLen)
+//
+// Arguments:  
+//    pIfInstance -
+//       Pointer to interface object.
+//   
+//    pServiceConfigIf -
+//       Pointer to service config object to which the client is trying to
+//       authenticate.
+//               
+//    pContext -
+//       Pointer to null terminated string containing mechanism specific
+//       context information. Another name for context is Authentication
+//       Realm.
+//
+//    pMechInfo -
+//       Pointer to null terminated string containing mechanism specific
+//       information. This is information is provided by the server to
+//       aid the mechanism to generate an authentication token. For
+//       example, the mechanism information for a Kerberos mechanism
+//       may be the service principal name to which the user will be
+//       authenticating.
+//               
+//    pTokenBuf -
+//       Pointer to buffer that will receive the authentication
+//       token. The length of this buffer is specified by the
+//       pTokenBufLen parameter. Note that the the authentication
+//       token will be in the form of a NULL terminated string.
+//
+//    pTokenBufLen -
+//       Pointer to integer that contains the length of the
+//       buffer pointed at by pTokenBuf. Upon return of the
+//       function, the integer will contain the actual length
+//       of the authentication token if the function successfully
+//       completes or the buffer length required if the function
+//       fails because the buffer pointed at by pUserNameBuf is
+//       not large enough.
+//   
+// Returns:
+//    Casa Status
+//                           
+// Description:
+//    Get authentication token to authenticate user to specified service.
+//
+// L0
+//=======================================================================--
+{
+   CasaStatus  retStatus;
+   char        *pUsername = NULL;
+   char        *pPassword = NULL;
+   char        *pToken;
+
+   DbgTrace(1, "-AuthTokenIf_GetAuthToken- Start\n", 0);
+
+   // Validate input parameters
+   if (pIfInstance == NULL
+       || pContext == NULL
+       || pMechInfo == NULL
+       || pTokenBufLen == NULL
+       || (pTokenBuf == NULL && *pTokenBufLen != 0))
+   {
+      DbgTrace(0, "-AuthTokenIf_GetAuthToken- Invalid input parameter\n", 0);
+
+      retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                  CASA_FACILITY_PWTOKEN,
+                                  CASA_STATUS_INVALID_PARAMETER);
+      goto exit;
+   }
+
+   // Get the user credentials
+   retStatus = GetUserCredentials(pContext, &pUsername, &pPassword);
+   if (CASA_SUCCESS(retStatus))
+   {
+      // Now construct the PW token with the following format:
+      // "username\r\n" + "password\r\n"
+      //
+      // First allocate a buffer large enough to hold the token
+      pToken = (char*) malloc(strlen(pUsername) + 2 + strlen(pPassword) + 2 + 1);
+      if (pToken)
+      {
+         char  *pEncodedToken;
+         int   encodedTokenLen;
+
+         // Now assemble the token
+         sprintf(pToken, "%s\r\n%s\r\n", pUsername, pPassword);
+
+         // The token has been assembled, now encode it.
+         retStatus = EncodeData(pToken,
+                                (const int) strlen(pToken),
+                                &pEncodedToken,
+                                &encodedTokenLen);
+         if (CASA_SUCCESS(retStatus))
+         {
+            // Verify that the caller provided a buffer that is big enough
+            if (encodedTokenLen > *pTokenBufLen)
+            {
+               // The buffer is not big enough
+               DbgTrace(1, "-AuthTokenIf_GetAuthToken- Insufficient buffer space provided\n", 0);
+
+               retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                           CASA_FACILITY_PWTOKEN,
+                                           CASA_STATUS_BUFFER_OVERFLOW);
+            }
+            else
+            {
+               // The buffer provided is large enough, copy the data.
+               memcpy((void*) pTokenBuf, pEncodedToken, encodedTokenLen);
+
+               // Success
+               retStatus = CASA_STATUS_SUCCESS;
+            }
+
+            // Return the actual size or the size required
+            *pTokenBufLen = encodedTokenLen;
+
+            // Free the buffer containing the encoded token
+            free(pEncodedToken);
+         }
+
+         // Free the buffer allocated for the token
+         free(pToken);
+      }
+      else
+      {
+         DbgTrace(0, "-AuthTokenIf_GetAuthToken- Buffer allocation error\n", 0);
+         retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                     CASA_FACILITY_PWTOKEN,
+                                     CASA_STATUS_INSUFFICIENT_RESOURCES);
+      }
+
+      // Free allocated buffers
+      free(pUsername);
+      free(pPassword);
+   }
+   else
+   {
+      DbgTrace(1, "-AuthTokenIf_GetAuthToken- Failed to obtain the user credentials\n", 0);
+   }
+
+exit:
+
+   DbgTrace(1, "-AuthTokenIf_GetAuthToken- End, retStatus = %08X\n", retStatus);
+
+   return retStatus;
+}
+
+
+//++=======================================================================
+int
+InitializeLibrary(void)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L0
+//=======================================================================--
+{
+   int   retStatus = 0;
+
+   DbgTrace(1, "-InitializeLibrary- Start\n", 0);
+
+
+   DbgTrace(1, "-InitializeLibrary- End, retStatus = %08X\n", retStatus);
+
+   return retStatus;
+}
+
+
+//++=======================================================================
+//++=======================================================================
+//++=======================================================================
+
diff --git a/auth_token/client/mechanisms/pwd/interface.c b/auth_token/client/mechanisms/pwd/interface.c
new file mode 100644
index 00000000..2fbdf3f4
--- /dev/null
+++ b/auth_token/client/mechanisms/pwd/interface.c
@@ -0,0 +1,207 @@
+/***********************************************************************
+ * 
+ *  Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; version 2.1
+ *  of the License.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, Novell, Inc.
+ * 
+ *  To contact Novell about this file by physical or electronic mail, 
+ *  you may find current contact information at www.novell.com.
+ * 
+ *  Author: Juan Carlos Luciani <jluciani@novell.com>
+ *
+ ***********************************************************************/
+
+//===[ Include files ]=====================================================
+
+#include "internal.h"
+
+//===[ Type definitions ]==================================================
+
+//
+// Authentication Token Interface instance data
+// 
+typedef struct _AuthTokenIfInstance
+{
+   int            refCount;
+   AuthTokenIf    authTokenIf;
+
+} AuthTokenIfInstance, *PAuthTokenIfInstance;
+
+//===[ Function prototypes ]===============================================
+
+//===[ Global variables ]==================================================
+
+// AuthTokenIf variables
+static
+int   g_numAuthTokenIfObjs = 0;
+
+
+//++=======================================================================
+static
+int SSCS_CALL
+AuthTokenIf_AddReference(
+   IN       const void  *pIfInstance)
+//
+// Arguments:  
+//    pIfInstance -
+//       Pointer to interface object.
+//   
+// Returns:
+//    Interface reference count.
+//                           
+// Description:
+//    Increases interface reference count.
+//
+// L2
+//=======================================================================--
+{
+   int                  refCount;
+   AuthTokenIfInstance  *pAuthTokenIfInstance = CONTAINING_RECORD(pIfInstance, AuthTokenIfInstance, authTokenIf);
+
+   DbgTrace(2, "-AuthTokenIf_AddReference- Start\n", 0);
+
+   // Increment the reference count on the object
+   pAuthTokenIfInstance->refCount ++;
+   refCount = pAuthTokenIfInstance->refCount;
+
+   DbgTrace(2, "-AuthTokenIf_AddReference- End, refCount = %08X\n", refCount);
+
+   return refCount;
+}
+
+
+//++=======================================================================
+static
+void SSCS_CALL
+AuthTokenIf_ReleaseReference(
+   IN       const void  *pIfInstance)
+//
+// Arguments:  
+//    pIfInstance -
+//       Pointer to interface object.
+//   
+// Returns:
+//    Nothing.
+//                           
+// Description:
+//    Decreases interface reference count. The interface is deallocated if
+//    the reference count becomes zero.
+//
+// L2
+//=======================================================================--
+{
+   bool                 freeObj = false;
+   AuthTokenIfInstance  *pAuthTokenIfInstance = CONTAINING_RECORD(pIfInstance, AuthTokenIfInstance, authTokenIf);
+
+   DbgTrace(2, "-AuthTokenIf_ReleaseReference- Start\n", 0);
+
+   // Decrement the reference count on the object and determine if it needs to
+   // be released.
+   pAuthTokenIfInstance->refCount --;
+   if (pAuthTokenIfInstance->refCount == 0)
+   {
+      // The object needs to be released, forget about it.
+      freeObj = true;
+      g_numAuthTokenIfObjs --;
+   }
+
+   // Free object if necessary
+   if (freeObj)
+      free(pAuthTokenIfInstance);
+
+   DbgTrace(2, "-AuthTokenIf_ReleaseReference- End\n", 0);
+}
+
+
+//++=======================================================================
+CasaStatus SSCS_CALL
+GET_AUTH_TOKEN_INTERFACE_RTN(
+   IN       const ConfigIf    *pModuleConfigIf,
+   INOUT    AuthTokenIf       **ppAuthTokenIf)
+//
+// Arguments:  
+//    pModuleConfigIf -
+//       Pointer to configuration interface instance for the module.
+//               
+//    ppAuthTokenIf -
+//       Pointer to variable that will receive pointer to AuthTokenIf
+//       instance.
+//
+// Returns:
+//    Casa Status
+//                           
+// Description:
+//    Gets authentication token interface instance.
+//
+// L2
+//=======================================================================--
+{
+   CasaStatus           retStatus;
+   AuthTokenIfInstance  *pAuthTokenIfInstance;
+
+
+   DbgTrace(1, "-GetAuthTokenInterface- Start\n", 0);
+
+   // Validate input parameters
+   if (pModuleConfigIf == NULL
+       || ppAuthTokenIf == NULL)
+   {
+      DbgTrace(0, "-GetAuthTokenInterface- Invalid input parameter\n", 0);
+
+      retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                  CASA_FACILITY_PWTOKEN,
+                                  CASA_STATUS_INVALID_PARAMETER);
+      goto exit;
+   }
+
+   // Allocate space for the interface instance
+   pAuthTokenIfInstance = malloc(sizeof(*pAuthTokenIfInstance));
+   if (pAuthTokenIfInstance)
+   {
+      // Initialize the interface instance data
+      pAuthTokenIfInstance->refCount = 1;
+      pAuthTokenIfInstance->authTokenIf.addReference = AuthTokenIf_AddReference;
+      pAuthTokenIfInstance->authTokenIf.releaseReference = AuthTokenIf_ReleaseReference;
+      pAuthTokenIfInstance->authTokenIf.getAuthToken = AuthTokenIf_GetAuthToken;
+
+      // Keep track of this object
+      g_numAuthTokenIfObjs ++;
+
+      // Return the interface to the caller
+      *ppAuthTokenIf = &pAuthTokenIfInstance->authTokenIf;
+
+      // Success
+      retStatus = CASA_STATUS_SUCCESS;
+   }
+   else
+   {
+      DbgTrace(0, "-GetAuthTokenInterface- Buffer allocation failure\n", 0);
+
+      retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                  CASA_FACILITY_PWTOKEN,
+                                  CASA_STATUS_INSUFFICIENT_RESOURCES);
+   }
+
+exit:
+
+   DbgTrace(1, "-GetAuthTokenInterface- End, retStatus = %08X\n", retStatus);
+
+   return retStatus;
+}
+
+
+//++=======================================================================
+//++=======================================================================
+//++=======================================================================
+
diff --git a/auth_token/client/mechanisms/pwd/internal.h b/auth_token/client/mechanisms/pwd/internal.h
new file mode 100644
index 00000000..3e077cfe
--- /dev/null
+++ b/auth_token/client/mechanisms/pwd/internal.h
@@ -0,0 +1,107 @@
+/***********************************************************************
+ * 
+ *  Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; version 2.1
+ *  of the License.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, Novell, Inc.
+ * 
+ *  To contact Novell about this file by physical or electronic mail, 
+ *  you may find current contact information at www.novell.com.
+ * 
+ *  Author: Juan Carlos Luciani <jluciani@novell.com>
+ *
+ ***********************************************************************/
+
+#ifndef _INTERNAL_H_
+#define _INTERNAL_H_
+
+//===[ Include files ]=====================================================
+
+#include "platform.h"
+#include <micasa_types.h>
+#include <micasa_mgmd.h>
+#include <sscs_utf8.h>
+#include <casa_status.h>
+#include "mech_if.h"
+
+//===[ Type definitions ]==================================================
+
+#ifndef CONTAINING_RECORD
+#define CONTAINING_RECORD(address, type, field) ((type *)(     \
+             (char*)(address) -                                \
+             (char*)(&((type *)0)->field)))
+#endif
+
+//
+// DbgTrace macro define
+//
+#define DbgTrace(LEVEL, X, Y) {                          \
+   if (LEVEL == 0)                                       \
+      printf(X, Y);                                      \
+   else if (DebugLevel >= LEVEL)                         \
+         printf(X, Y);                                   \
+}
+
+//===[ Inlines functions   ]===============================================
+
+//===[ Function prototypes ]===============================================
+
+//===[ Global variables ]==================================================
+
+//===[ Global externals ]==================================================
+
+extern int  DebugLevel;
+
+//===[ External prototypes ]===============================================
+
+//
+// Defined in get.c
+//
+
+extern
+CasaStatus SSCS_CALL
+AuthTokenIf_GetAuthToken(
+   IN       const void        *pIfInstance,
+   IN       const char        *pContext,
+   IN       const char        *pMechInfo,
+   INOUT    char              *pTokenBuf,
+   INOUT    int               *pTokenBufLen);
+
+extern
+int
+InitializeLibrary(void);
+
+//
+// Defined in utils.c
+//
+
+extern
+CasaStatus
+EncodeData(
+   IN    const void *pData,
+   IN    const int32_t dataLen,
+   INOUT char **ppEncodedData,
+   INOUT int32_t *pEncodedDataLen);
+
+extern
+CasaStatus
+DecodeData(
+   IN    const char *pEncodedData,
+   IN    const int32_t encodedDataLen, // Does not include NULL terminator
+   INOUT void **ppData,
+   INOUT int32_t *pDataLen);
+
+//=========================================================================
+
+#endif // _INTERNAL_H_
+
diff --git a/auth_token/client/mechanisms/pwd/pwd.vcproj b/auth_token/client/mechanisms/pwd/pwd.vcproj
new file mode 100644
index 00000000..fd5bf95f
--- /dev/null
+++ b/auth_token/client/mechanisms/pwd/pwd.vcproj
@@ -0,0 +1,182 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="pwd"
+	ProjectGUID="{5499F624-F371-4559-B4C2-A484BCE892FD}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)client\mechanisms\pw\win32\$(ConfigurationName)"
+			IntermediateDirectory="$(SolutionDir)client\mechanisms\pw\win32\$(ConfigurationName)"
+			ConfigurationType="2"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="win32;.;..\..;..\..\..\..\include"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="5"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="4"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions="/EXPORT:GetAuthTokenInterface"
+				AdditionalDependencies="micasa.lib"
+				OutputFile="$(OutDir)/pwmech.dll"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="C:\Program Files\novell\CASA\lib"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/pw.pdb"
+				SubSystem="0"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				CommandLine="mkdir \&quot;Program Files&quot;\novell\
+mkdir \&quot;Program Files&quot;\novell\casa
+mkdir \&quot;Program Files&quot;\novell\casa\lib\
+mkdir \&quot;Program Files&quot;\novell\casa\etc\
+mkdir \&quot;Program Files&quot;\novell\casa\etc\auth\
+mkdir \&quot;Program Files&quot;\novell\casa\etc\auth\mechanisms\
+copy PwdAuthenticate.conf \&quot;Program Files&quot;\novell\casa\etc\auth\mechanisms\PwdAuthenticate.conf
+copy $(OutDir)\pwmech.dll \&quot;Program Files&quot;\novell\casa\lib\pwmech.dll
+"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)client\mechanisms\pw\win32\$(ConfigurationName)"
+			IntermediateDirectory="$(SolutionDir)client\mechanisms\pw\win32\$(ConfigurationName)"
+			ConfigurationType="2"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="win32;.;..\..;..\..\..\..\include"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+				RuntimeLibrary="4"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions="/EXPORT:GetAuthTokenInterface"
+				AdditionalDependencies="micasa.lib"
+				OutputFile="$(OutDir)/pwmech.dll"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="C:\Program Files\novell\CASA\lib"
+				GenerateDebugInformation="TRUE"
+				SubSystem="0"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				CommandLine="mkdir \&quot;Program Files&quot;\novell\
+mkdir \&quot;Program Files&quot;\novell\casa
+mkdir \&quot;Program Files&quot;\novell\casa\lib\
+mkdir \&quot;Program Files&quot;\novell\casa\etc\
+mkdir \&quot;Program Files&quot;\novell\casa\etc\auth\
+mkdir \&quot;Program Files&quot;\novell\casa\etc\auth\mechanisms\
+copy PwdAuthenticate.conf \&quot;Program Files&quot;\novell\casa\etc\auth\mechanisms\PwdAuthenticate.conf
+copy $(OutDir)\pwmech.dll \&quot;Program Files&quot;\novell\casa\lib\pwmech.dll
+"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+			<File
+				RelativePath=".\win32\dllsup.c">
+			</File>
+			<File
+				RelativePath=".\get.c">
+			</File>
+			<File
+				RelativePath=".\interface.c">
+			</File>
+			<File
+				RelativePath=".\win32\platutils.c">
+			</File>
+			<File
+				RelativePath=".\PwdAuthenticate.conf">
+			</File>
+			<File
+				RelativePath=".\win32\pwmech.def">
+			</File>
+			<File
+				RelativePath=".\util.c">
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+			<File
+				RelativePath=".\internal.h">
+			</File>
+			<File
+				RelativePath=".\win32\platform.h">
+			</File>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/auth_token/client/mechanisms/pwd/util.c b/auth_token/client/mechanisms/pwd/util.c
new file mode 100644
index 00000000..634203f8
--- /dev/null
+++ b/auth_token/client/mechanisms/pwd/util.c
@@ -0,0 +1,282 @@
+/***********************************************************************
+ * 
+ *  Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; version 2.1
+ *  of the License.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, Novell, Inc.
+ * 
+ *  To contact Novell about this file by physical or electronic mail, 
+ *  you may find current contact information at www.novell.com.
+ * 
+ *  Author: Juan Carlos Luciani <jluciani@novell.com>
+ *
+ ***********************************************************************/
+
+//===[ Include files ]=====================================================
+
+#include "internal.h"
+
+//===[ Type definitions ]==================================================
+
+//===[ Function prototypes ]===============================================
+
+//===[ Global variables ]==================================================
+
+// Debug Level
+int   DebugLevel = 2;
+
+// Tables for Base64 encoding and decoding
+static const int8_t  g_Base64[] =
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+static const uint8_t g_Expand64[256] =
+{
+    /* ASCII table */
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,
+    52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,
+    64,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
+    15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64,
+    64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+    41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64,
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
+};
+
+
+//++=======================================================================
+CasaStatus
+EncodeData(
+   IN    const void *pData,
+   IN    const int32_t dataLen,
+   INOUT char **ppEncodedData,
+   INOUT int32_t *pEncodedDataLen)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Description:  
+//
+// L2
+//=======================================================================--
+{
+   CasaStatus  retStatus;
+   int         encodedSize;
+
+   char        *pTmp;
+
+   DbgTrace(3, "-EncodeData- Start\n", 0);
+
+   // Determine the encoded size and allocate a buffer to hold the encoded data
+   encodedSize = ((dataLen * 4 + 2) / 3) - (dataLen % 3 ) + 4;
+   pTmp = (char*) malloc(encodedSize);
+   *ppEncodedData = pTmp;
+   if (*ppEncodedData)
+   {
+      uint8_t  *pOut, *pIn;
+      int      i;
+
+      // Setup pointers to move through the buffers
+      pIn = (uint8_t*) pData;
+      pOut = (uint8_t*) *ppEncodedData;
+
+      // Perform the encoding
+      for (i = 0; i < dataLen - 2; i += 3)
+      {
+          *pOut++ = g_Base64[(pIn[i] >> 2) & 0x3F];
+          *pOut++ = g_Base64[((pIn[i] & 0x3) << 4) |
+                          ((int32_t)(pIn[i + 1] & 0xF0) >> 4)];
+          *pOut++ = g_Base64[((pIn[i + 1] & 0xF) << 2) |
+                          ((int32_t)(pIn[i + 2] & 0xC0) >> 6)];
+          *pOut++ = g_Base64[pIn[i + 2] & 0x3F];
+      }
+      if (i < dataLen)
+      {
+          *pOut++ = g_Base64[(pIn[i] >> 2) & 0x3F];
+          if (i == (dataLen - 1))
+          {
+              *pOut++ = g_Base64[((pIn[i] & 0x3) << 4)];
+              *pOut++ = '=';
+          }
+          else
+          {
+              *pOut++ = g_Base64[((pIn[i] & 0x3) << 4) |
+                              ((int32_t)(pIn[i + 1] & 0xF0) >> 4)];
+              *pOut++ = g_Base64[((pIn[i + 1] & 0xF) << 2)];
+          }
+          *pOut++ = '=';
+      }
+      *pOut++ = '\0';
+
+      // Return the encoded data length
+      *pEncodedDataLen = (int32_t)(pOut - (uint8_t*)*ppEncodedData); 
+
+      // Success
+      retStatus = CASA_STATUS_SUCCESS;
+   }
+   else
+   {
+      DbgTrace(0, "-EncodeData- Buffer allocation failure\n", 0);
+
+      retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                  CASA_FACILITY_PWTOKEN,
+                                  CASA_STATUS_INSUFFICIENT_RESOURCES);
+   }
+
+   DbgTrace(3, "-EncodeData- End, retStatus = %08X\n", retStatus);
+
+   return retStatus;
+}
+
+
+//++=======================================================================
+CasaStatus
+DecodeData(
+   IN    const char *pEncodedData,
+   IN    const int32_t encodedDataLen, // Does not include NULL terminator
+   INOUT void **ppData,
+   INOUT int32_t *pDataLen)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Description:  
+//
+// L2
+//=======================================================================--
+{
+   CasaStatus  retStatus;
+   int         i, j;
+   int         decodedSize;
+
+   DbgTrace(3, "-DecodeData- Start\n", 0);
+
+   // Determine the decoded size
+   for (i = 0, j = 0; i < encodedDataLen; i++)
+       if (g_Expand64[((uint8_t*) pEncodedData)[i]] < 64)
+           j++;
+   decodedSize = (j * 3 + 3) / 4;
+
+   // Allocate buffer to hold the decoded data
+   *ppData = malloc(decodedSize);
+   if (*ppData)
+   {
+      bool  endReached = false;
+      uint8_t  c0, c1, c2, c3;
+      uint8_t  *p, *q;
+
+      // Initialize parameters that will be used during the decode operation
+      c0 = c1 = c2 = c3 = 0;
+      p = (uint8_t*) pEncodedData;
+      q = (uint8_t*) *ppData;
+
+      // Decode the data
+      //
+      // Loop through the data, piecing back information. Any newlines, and/or
+      // carriage returns need to be skipped.
+      while (j > 4)
+      {
+          while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p)))
+              p++;
+          if (64 == g_Expand64[*p])
+          {
+              endReached = true;
+              break;
+          }
+          c0 = *(p++);
+
+          while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p)))
+              p++;
+          if (64 == g_Expand64[*p])
+          {
+              *(q++) = (uint8_t)(g_Expand64[c0] << 2);
+              j--;
+              endReached = true;
+              break;
+          }
+          c1 = *(p++);
+
+          while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p)))
+              p++;
+          if (64 == g_Expand64[*p])
+          {
+              *(q++) = (uint8_t)(g_Expand64[c0] << 2 | g_Expand64[c1] >> 4);
+              *(q++) = (uint8_t)(g_Expand64[c1] << 4);
+              j -= 2;
+              endReached = true;
+              break;
+          }
+          c2 = *(p++);
+
+          while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p)))
+              p++;
+          if (64 == g_Expand64[*p])
+          {
+              *(q++) = (uint8_t)(g_Expand64[c0] << 2 | g_Expand64[c1] >> 4);
+              *(q++) = (uint8_t)(g_Expand64[c1] << 4 | g_Expand64[c2] >> 2);
+              *(q++) = (uint8_t)(g_Expand64[c2] << 6);
+              j -= 3;
+              endReached = true;
+              break;
+          }
+          c3 = *(p++);
+
+          *(q++) = (uint8_t)(g_Expand64[c0] << 2 | g_Expand64[c1] >> 4);
+          *(q++) = (uint8_t)(g_Expand64[c1] << 4 | g_Expand64[c2] >> 2);
+          *(q++) = (uint8_t)(g_Expand64[c2] << 6 | g_Expand64[c3]);
+          j -= 4;
+      }
+      if (!endReached)
+      {
+          if (j > 1)
+              *(q++) = (uint8_t)(g_Expand64[*p] << 2 | g_Expand64[p[1]] >> 4);
+          if (j > 2)
+              *(q++) = (uint8_t)(g_Expand64[p[1]] << 4 | g_Expand64[p[2]] >> 2);
+          if (j > 3)
+              *(q++) = (uint8_t)(g_Expand64[p[2]] << 6 | g_Expand64[p[3]]);
+      }
+
+      // Return the length of the decoded data
+      *pDataLen = (int32_t)(q - (uint8_t*)*ppData);
+
+      // Success
+      retStatus = CASA_STATUS_SUCCESS;
+   }
+   else
+   {
+      DbgTrace(0, "-DecodeData- Buffer allocation failure\n", 0);
+
+      retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                  CASA_FACILITY_PWTOKEN,
+                                  CASA_STATUS_INSUFFICIENT_RESOURCES);
+   }
+
+   DbgTrace(3, "-DecodeData- End, retStatus = %08X\n", retStatus);
+
+   return retStatus;
+}
+
+
+//++=======================================================================
+//++=======================================================================
+//++=======================================================================
+
diff --git a/auth_token/client/mechanisms/pwd/win32/dllsup.c b/auth_token/client/mechanisms/pwd/win32/dllsup.c
new file mode 100644
index 00000000..8eecacef
--- /dev/null
+++ b/auth_token/client/mechanisms/pwd/win32/dllsup.c
@@ -0,0 +1,132 @@
+/***********************************************************************
+ * 
+ *  Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; version 2.1
+ *  of the License.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, Novell, Inc.
+ * 
+ *  To contact Novell about this file by physical or electronic mail, 
+ *  you may find current contact information at www.novell.com.
+ * 
+ *  Author: Juan Carlos Luciani <jluciani@novell.com>
+ *
+ ***********************************************************************/
+
+//===[ Include files ]=====================================================
+
+#include "internal.h"
+
+//===[ External data ]=====================================================
+
+//===[ Manifest constants ]================================================
+
+//===[ Type definitions ]==================================================
+
+//===[ Function prototypes ]===============================================
+
+//===[ Global variables ]==================================================
+
+UINT32 g_ulCount  = 0;
+UINT32 g_ulLock = 0;
+HANDLE g_hModule;
+
+
+//++=======================================================================
+BOOL APIENTRY DllMain(
+   HANDLE hModule,
+   DWORD  ul_reason_for_call,
+   LPVOID lpReserved   
+   )
+//=======================================================================--
+{
+   BOOL  retStatus = TRUE;
+
+   switch (ul_reason_for_call)
+   {
+      case DLL_PROCESS_ATTACH:
+      {
+         g_hModule = hModule;
+
+         // Initialize the library
+         if (InitializeLibrary() != 0)
+         {
+            // Failed to initialize the library
+            OutputDebugString("CASA_PW_MECH -DllMain- Library initialization failed\n");
+            retStatus = FALSE;
+         }
+         break;
+      }
+
+      case DLL_THREAD_ATTACH:
+      {
+         g_hModule = hModule;
+         break;
+      }
+
+      case DLL_THREAD_DETACH:
+         break;
+
+      case DLL_PROCESS_DETACH:
+      {
+         /* Don't uninitialize on windows
+         tbd
+         */
+         break;
+      }
+    }
+
+    return retStatus;
+}
+
+//++=======================================================================
+//
+// DllCanUnloadNow
+//
+// Synopsis
+//
+//
+STDAPI
+DllCanUnloadNow()
+//
+// Input Arguments
+//
+// Ouput Arguments
+//
+// Return Value
+//    S_OK    The DLL can be unloaded.
+//    S_FALSE The DLL cannot be unloaded now.
+//
+// Description
+//    An Exported Function.
+//    DLLs that support the OLE Component Object Model (COM) should implement
+//    and export DllCanUnloadNow.
+//    A call to DllCanUnloadNow determines whether the DLL from which it is
+//    exported is still in use. A DLL is no longer in use when it is not
+//    managing  any existing objects (the reference count on all of its objects
+//    is 0).
+//    DllCanUnloadNow returns S_FALSE if there are any existing references to
+//    objects that the DLL manages.
+//
+// Environment
+//
+// See Also
+//
+//=======================================================================--
+{
+   // tbd
+   return ((g_ulCount == 0 && g_ulLock == 0) ? S_OK : S_FALSE);
+}
+
+//=========================================================================
+//=========================================================================
+
diff --git a/auth_token/client/mechanisms/pwd/win32/platform.h b/auth_token/client/mechanisms/pwd/win32/platform.h
new file mode 100644
index 00000000..1f551693
--- /dev/null
+++ b/auth_token/client/mechanisms/pwd/win32/platform.h
@@ -0,0 +1,75 @@
+/***********************************************************************
+ * 
+ *  Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; version 2.1
+ *  of the License.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, Novell, Inc.
+ * 
+ *  To contact Novell about this file by physical or electronic mail, 
+ *  you may find current contact information at www.novell.com.
+ * 
+ *  Author: Juan Carlos Luciani <jluciani@novell.com>
+ *
+ ***********************************************************************/
+
+#ifndef _PLATFORM_H_
+#define _PLATFORM_H_
+
+//===[ Include files ]=====================================================
+
+#include <windows.h>
+#include <stdio.h>
+#include <winerror.h>
+
+//===[ Type definitions ]==================================================
+
+#ifndef CONTAINING_RECORD
+#define CONTAINING_RECORD(address, type, field) ((type *)(     \
+             (char*)(address) -                                \
+             (char*)(&((type *)0)->field)))
+#endif
+
+//
+// DbgTrace macro define
+//
+#define DbgTrace(LEVEL, X, Y) {                          \
+char printBuff[256];                                     \
+   if (LEVEL == 0)                                       \
+   {                                                     \
+      _snprintf(printBuff, sizeof(printBuff), X, Y);     \
+      printf("PwdMech %s", printBuff);                   \
+   }                                                     \
+   else if (DebugLevel >= LEVEL)                         \
+   {                                                     \
+      _snprintf(printBuff, sizeof(printBuff), X, Y);     \
+      printf("PwdMech %s", printBuff);                   \
+   }                                                     \
+}
+
+#define bool BOOLEAN
+#define true TRUE
+#define false FALSE
+
+//===[ Inlines functions   ]===============================================
+
+//===[ Function prototypes ]===============================================
+
+//===[ Global externals ]==================================================
+
+//===[ External prototypes ]===============================================
+
+
+//=========================================================================
+
+#endif // _PLATFORM_H_
+
diff --git a/auth_token/client/mechanisms/pwd/win32/platutils.c b/auth_token/client/mechanisms/pwd/win32/platutils.c
new file mode 100644
index 00000000..869b581c
--- /dev/null
+++ b/auth_token/client/mechanisms/pwd/win32/platutils.c
@@ -0,0 +1,35 @@
+/***********************************************************************
+ * 
+ *  Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; version 2.1
+ *  of the License.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, Novell, Inc.
+ * 
+ *  To contact Novell about this file by physical or electronic mail, 
+ *  you may find current contact information at www.novell.com.
+ * 
+ *  Author: Juan Carlos Luciani <jluciani@novell.com>
+ *
+ ***********************************************************************/
+
+//===[ Include files ]=====================================================
+
+#include "internal.h"
+
+//===[ Type definitions ]==================================================
+
+//===[ Function prototypes ]===============================================
+
+//===[ Global variables ]==================================================
+
+
diff --git a/auth_token/client/mechanisms/pwd/win32/pwmech.def b/auth_token/client/mechanisms/pwd/win32/pwmech.def
new file mode 100644
index 00000000..0557e401
--- /dev/null
+++ b/auth_token/client/mechanisms/pwd/win32/pwmech.def
@@ -0,0 +1,10 @@
+LIBRARY         PWMECH
+DESCRIPTION     'CASA PW Authentication Mechanism Library.'
+
+
+EXPORTS
+;                DllRegisterServer   PRIVATE
+;                DllUnregisterServer PRIVATE
+;                DllGetClassObject   PRIVATE
+                GetAuthTokenInterface  PRIVATE        
+;               DllCanUnloadNow     PRIVATE  
\ No newline at end of file
diff --git a/auth_token/client/proto.h b/auth_token/client/proto.h
new file mode 100644
index 00000000..7aebd81f
--- /dev/null
+++ b/auth_token/client/proto.h
@@ -0,0 +1,66 @@
+/***********************************************************************
+ * 
+ *  Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; version 2.1
+ *  of the License.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, Novell, Inc.
+ * 
+ *  To contact Novell about this file by physical or electronic mail, 
+ *  you may find current contact information at www.novell.com.
+ * 
+ *  Author: Juan Carlos Luciani <jluciani@novell.com>
+ *
+ ***********************************************************************/
+
+#ifndef _PROTO_H_
+#define _PROTO_H_
+
+//===[ Include files ]=====================================================
+
+
+//===[ Type definitions ]==================================================
+
+//
+// XML Constants for the documents exchanged between the CASA Client
+// and the CASA Server.
+// 
+#define XML_DECLARATION "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>"
+#define AUTH_REQUEST_ELEMENT_NAME "auth_req"
+#define AUTH_RESPONSE_ELEMENT_NAME "auth_resp"
+#define GET_AUTH_POLICY_REQUEST_ELEMENT_NAME "get_auth_policy_req"
+#define GET_AUTH_POLICY_RESPONSE_ELEMENT_NAME "get_auth_policy_resp"
+#define GET_AUTH_TOKEN_REQUEST_ELEMENT_NAME "get_auth_tok_req"
+#define GET_AUTH_TOKEN_RESPONSE_ELEMENT_NAME "get_auth_tok_resp"
+#define AUTH_MECH_TOKEN_ELEMENT_NAME "auth_mech_token"
+#define AUTH_TOKEN_ELEMENT_NAME "auth_token"
+#define AUTH_POLICY_ELEMENT_NAME "auth_policy"
+#define AUTH_SOURCE_ELEMENT_NAME "auth_source"
+#define STATUS_ELEMENT_NAME  "status"
+#define SESSION_TOKEN_ELEMENT_NAME "session_token"
+#define LIFETIME_ELEMENT_NAME "lifetime"
+#define DESCRIPTION_ELEMENT_NAME "description"
+#define SERVICE_ELEMENT_NAME "service"
+#define HOST_ELEMENT_NAME "host"
+#define REALM_ELEMENT_NAME "realm"
+#define MECHANISM_ELEMENT_NAME "mechanism"
+#define MECHANISM_INFO_ELEMENT_NAME "mechanism_info"
+
+//
+// HTTP Status Codes
+// 
+#define HTTP_OK_STATUS_CODE "200"
+#define HTTP_UNAUTHORIZED_STATUS_CODE "401"
+#define HTTP_SERVER_ERROR_STATUS_CODE "500"
+
+
+#endif // _PROTO_H_
diff --git a/auth_token/client/test/CASA_Auth.cpp b/auth_token/client/test/CASA_Auth.cpp
new file mode 100644
index 00000000..f8b7c363
--- /dev/null
+++ b/auth_token/client/test/CASA_Auth.cpp
@@ -0,0 +1,165 @@
+/***********************************************************************
+ * 
+ *  Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; version 2.1
+ *  of the License.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, Novell, Inc.
+ * 
+ *  To contact Novell about this file by physical or electronic mail, 
+ *  you may find current contact information at www.novell.com.
+ * 
+ *  Author: Juan Carlos Luciani <jluciani@novell.com>
+ *
+ ***********************************************************************/
+
+#include <windows.h>
+#include "casa_auth_token.h"
+
+int main(int argc, char* argv[])
+{
+   int   retStatus;
+   char  authToken[4096];
+   int   authTokenLen = sizeof(authToken);
+
+   // Now lets obtain a token for our service
+   retStatus = ObtainAuthToken("testService@137.65.132.44", authToken, &authTokenLen);
+   if (retStatus)
+      printf("ObtainAuthToken failed with status %d\n", retStatus);
+   else
+   {
+      char                 serverAddr[] = "137.65.132.44";
+      char                 *pServerAddress = serverAddr;
+      int                  serverPort = 4444;
+      SOCKET               sock;
+      struct sockaddr_in   localAddr = {0};
+      struct sockaddr_in   remoteAddr = {0};
+      struct linger        linger_opt = {1, 15};
+      struct hostent       *pLookupResult;
+      int                  winsockStartupResult;
+      WSADATA              winsockData;
+
+      //printf("ObtainAuthToken succedded, token = %s\n", authToken);
+      printf("ObtainAuthToken succedded, tokenlen = %d\n", authTokenLen);
+
+      // Send the token to the server
+      //
+      // First initialize winsock
+      if ((winsockStartupResult = WSAStartup(MAKEWORD(2,2), &winsockData)) == 0)
+      {
+         // Open socket
+         sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+         if (sock != INVALID_SOCKET)
+         {
+            // Setup the local address structure
+            localAddr.sin_family = AF_INET;
+            localAddr.sin_addr.s_addr = htonl(INADDR_ANY);
+
+            // Bind socket
+            if (!bind(sock, (const struct sockaddr*) &localAddr, sizeof(struct sockaddr_in)))
+            {
+               // Resolve the server address
+               pLookupResult = gethostbyname(pServerAddress);
+               if (pLookupResult)
+               {
+                  // Validate the address type returned
+                  if (pLookupResult->h_addrtype == AF_INET)
+                  {
+                     int   numAddressesFound = 0;
+
+                     // Determine how many addresses where returned
+                     while (pLookupResult->h_addr_list[numAddressesFound] != NULL)
+                     {
+                        //printf("ServerAddress = %08X\n", *((int*) pLookupResult->h_addr_list[numAddressesFound]));
+                        numAddressesFound ++;
+                     }
+                     //printf("Found %d addresses\n", numAddressesFound);
+
+
+                     // Setup the remote address structure with the lookup results
+                     remoteAddr.sin_family = AF_INET;
+                     remoteAddr.sin_port = htons(serverPort);
+                     remoteAddr.sin_addr.s_addr = *((int*) pLookupResult->h_addr_list[0]); // Short-cut
+                     //printf("ServerAddress = %08X\n", remoteAddr.sin_addr.s_addr);
+
+                     // Perform connect operation
+                     if (connect(sock,
+                                 (struct sockaddr*) &remoteAddr,
+                                 sizeof(struct sockaddr_in)) == SOCKET_ERROR)
+                     {
+                        printf("main()- Connection creation failed, error = %d\n", WSAGetLastError());
+                     }
+                     else
+                     {
+                        // Now the connection is setup, send the credentials to the server as one line.
+                        // using our cheesy protocol followed by a hello string.
+
+                        // Send the username to the server (including NULL terminator)
+                        //send(sock, userName, userNameBufLen, 0);
+
+                        // Send new line
+                        //send(sock, "\n", 1, MSG_NOSIGNAL);
+
+                        // Send the token to the server (including NULL terminator)
+                        send(sock, authToken, (int) strlen(authToken) + 1, 0);
+
+                        // Send new line
+                        //send(sock, "\n", 1, 0);
+
+                        // Send "hello"
+                        //send(sock, helloString, strlen(helloString) + 1, MSG_NOSIGNAL);
+
+                        // Send new line
+                        //send(sock, "\n", 1, 0);
+
+                        // Shutdown the connection
+                        shutdown(sock, 0);
+                     }
+                  }
+                  else
+                  {
+                     printf("main()- Unsupported address type returned %08X\n", pLookupResult->h_addrtype);
+                  }
+               }
+               else
+               {
+                  printf("main()- Lookup for %s failed\n", pServerAddress);
+               }
+            }
+            else
+            {
+               printf("main()- Unable to bind socket, error = %d", errno);
+            }
+
+            // Close the socket
+            setsockopt(sock, SOL_SOCKET, SO_LINGER, (const char*) &linger_opt, sizeof(linger_opt));
+            closesocket(sock);
+         }
+         else
+         {
+            printf("main()- Unable to open socket, error = %d\n", errno);
+         }
+
+         // Close winsock
+         WSACleanup();
+      }
+      else
+      {
+         printf("main()- WSAStartup failed, error = %d\n", winsockStartupResult);
+      }
+   }
+
+   printf("Enter to exit application\n");
+   getchar();
+   return 0;
+}
+
diff --git a/auth_token/client/test/test.vcproj b/auth_token/client/test/test.vcproj
new file mode 100644
index 00000000..642d2b56
--- /dev/null
+++ b/auth_token/client/test/test.vcproj
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="test"
+	ProjectGUID="{6034EBF1-0838-45C4-A538-A41A31EC8F46}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="Debug"
+			IntermediateDirectory="Debug"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\..\..\include"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="5"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="4"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="authtoken.lib ws2_32.lib"
+				OutputFile="$(OutDir)/test.exe"
+				LinkIncremental="2"
+				AdditionalLibraryDirectories="..\..\client\win32\Debug"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/test.pdb"
+				SubSystem="1"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				CommandLine="copy ..\win32\debug\authtoken.dll debug\authtoken.dll"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="Release"
+			IntermediateDirectory="Release"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\include"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+				RuntimeLibrary="4"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="authtoken.lib ws2_32.lib"
+				OutputFile="$(OutDir)/test.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="&quot;C:\Program Files\novell\CASA\lib&quot;"
+				GenerateDebugInformation="TRUE"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+			<File
+				RelativePath=".\CASA_Auth.cpp">
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+		</Filter>
+		<File
+			RelativePath=".\ReadMe.txt">
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/auth_token/client/util.c b/auth_token/client/util.c
new file mode 100644
index 00000000..4e887979
--- /dev/null
+++ b/auth_token/client/util.c
@@ -0,0 +1,321 @@
+/***********************************************************************
+ * 
+ *  Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; version 2.1
+ *  of the License.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, Novell, Inc.
+ * 
+ *  To contact Novell about this file by physical or electronic mail, 
+ *  you may find current contact information at www.novell.com.
+ * 
+ *  Author: Juan Carlos Luciani <jluciani@novell.com>
+ *
+ ***********************************************************************/
+
+//===[ Include files ]=====================================================
+
+#include "internal.h"
+
+//===[ Type definitions ]==================================================
+
+//===[ Function prototypes ]===============================================
+
+//===[ Global variables ]==================================================
+
+// Tables for Base64 encoding and decoding
+static const int8_t  g_Base64[] =
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+static const uint8_t g_Expand64[256] =
+{
+    /* ASCII table */
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,
+    52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,
+    64,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
+    15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64,
+    64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+    41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64,
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
+};
+
+
+//++=======================================================================
+CasaStatus
+EncodeData(
+   IN    const void *pData,
+   IN    const int32_t dataLen,
+   INOUT char **ppEncodedData,
+   INOUT int32_t *pEncodedDataLen)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Description:  
+//
+// L2
+//=======================================================================--
+{
+   CasaStatus  retStatus;
+   int         encodedSize;
+
+   char        *pTmp;
+
+   DbgTrace(3, "-EncodeData- Start\n", 0);
+
+   // Determine the encoded size and allocate a buffer to hold the encoded data
+   encodedSize = ((dataLen * 4 + 2) / 3) - (dataLen % 3 ) + 4;
+   pTmp = (char*) malloc(encodedSize);
+   *ppEncodedData = pTmp;
+   if (*ppEncodedData)
+   {
+      uint8_t  *pOut, *pIn;
+      int      i;
+
+      // Setup pointers to move through the buffers
+      pIn = (uint8_t*) pData;
+      pOut = (uint8_t*) *ppEncodedData;
+
+      // Perform the encoding
+      for (i = 0; i < dataLen - 2; i += 3)
+      {
+          *pOut++ = g_Base64[(pIn[i] >> 2) & 0x3F];
+          *pOut++ = g_Base64[((pIn[i] & 0x3) << 4) |
+                          ((int32_t)(pIn[i + 1] & 0xF0) >> 4)];
+          *pOut++ = g_Base64[((pIn[i + 1] & 0xF) << 2) |
+                          ((int32_t)(pIn[i + 2] & 0xC0) >> 6)];
+          *pOut++ = g_Base64[pIn[i + 2] & 0x3F];
+      }
+      if (i < dataLen)
+      {
+          *pOut++ = g_Base64[(pIn[i] >> 2) & 0x3F];
+          if (i == (dataLen - 1))
+          {
+              *pOut++ = g_Base64[((pIn[i] & 0x3) << 4)];
+              *pOut++ = '=';
+          }
+          else
+          {
+              *pOut++ = g_Base64[((pIn[i] & 0x3) << 4) |
+                              ((int32_t)(pIn[i + 1] & 0xF0) >> 4)];
+              *pOut++ = g_Base64[((pIn[i + 1] & 0xF) << 2)];
+          }
+          *pOut++ = '=';
+      }
+      *pOut++ = '\0';
+
+      // Return the encoded data length
+      *pEncodedDataLen = (int32_t)(pOut - (uint8_t*)*ppEncodedData); 
+
+      // Success
+      retStatus = CASA_STATUS_SUCCESS;
+   }
+   else
+   {
+      DbgTrace(0, "-EncodeData- Buffer allocation failure\n", 0);
+
+      retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                  CASA_FACILITY_AUTHTOKEN,
+                                  CASA_STATUS_INSUFFICIENT_RESOURCES);
+   }
+
+   DbgTrace(3, "-EncodeData- End, retStatus = %08X\n", retStatus);
+
+   return retStatus;
+}
+
+
+//++=======================================================================
+CasaStatus
+DecodeData(
+   IN    const char *pEncodedData,
+   IN    const int32_t encodedDataLen, // Does not include NULL terminator
+   INOUT void **ppData,
+   INOUT int32_t *pDataLen)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Description:  
+//
+// L2
+//=======================================================================--
+{
+   CasaStatus  retStatus;
+   int         i, j;
+   int         decodedSize;
+
+   DbgTrace(3, "-DecodeData- Start\n", 0);
+
+   // Determine the decoded size
+   for (i = 0, j = 0; i < encodedDataLen; i++)
+       if (g_Expand64[((uint8_t*) pEncodedData)[i]] < 64)
+           j++;
+   decodedSize = (j * 3 + 3) / 4;
+
+   // Allocate buffer to hold the decoded data
+   *ppData = malloc(decodedSize);
+   if (*ppData)
+   {
+      bool  endReached = false;
+      uint8_t  c0, c1, c2, c3;
+      uint8_t  *p, *q;
+
+      // Initialize parameters that will be used during the decode operation
+      c0 = c1 = c2 = c3 = 0;
+      p = (uint8_t*) pEncodedData;
+      q = (uint8_t*) *ppData;
+
+      // Decode the data
+      //
+      // Loop through the data, piecing back information. Any newlines, and/or
+      // carriage returns need to be skipped.
+      while (j > 4)
+      {
+          while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p)))
+              p++;
+          if (64 == g_Expand64[*p])
+          {
+              endReached = true;
+              break;
+          }
+          c0 = *(p++);
+
+          while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p)))
+              p++;
+          if (64 == g_Expand64[*p])
+          {
+              *(q++) = (uint8_t)(g_Expand64[c0] << 2);
+              j--;
+              endReached = true;
+              break;
+          }
+          c1 = *(p++);
+
+          while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p)))
+              p++;
+          if (64 == g_Expand64[*p])
+          {
+              *(q++) = (uint8_t)(g_Expand64[c0] << 2 | g_Expand64[c1] >> 4);
+              *(q++) = (uint8_t)(g_Expand64[c1] << 4);
+              j -= 2;
+              endReached = true;
+              break;
+          }
+          c2 = *(p++);
+
+          while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p)))
+              p++;
+          if (64 == g_Expand64[*p])
+          {
+              *(q++) = (uint8_t)(g_Expand64[c0] << 2 | g_Expand64[c1] >> 4);
+              *(q++) = (uint8_t)(g_Expand64[c1] << 4 | g_Expand64[c2] >> 2);
+              *(q++) = (uint8_t)(g_Expand64[c2] << 6);
+              j -= 3;
+              endReached = true;
+              break;
+          }
+          c3 = *(p++);
+
+          *(q++) = (uint8_t)(g_Expand64[c0] << 2 | g_Expand64[c1] >> 4);
+          *(q++) = (uint8_t)(g_Expand64[c1] << 4 | g_Expand64[c2] >> 2);
+          *(q++) = (uint8_t)(g_Expand64[c2] << 6 | g_Expand64[c3]);
+          j -= 4;
+      }
+      if (!endReached)
+      {
+          if (j > 1)
+              *(q++) = (uint8_t)(g_Expand64[*p] << 2 | g_Expand64[p[1]] >> 4);
+          if (j > 2)
+              *(q++) = (uint8_t)(g_Expand64[p[1]] << 4 | g_Expand64[p[2]] >> 2);
+          if (j > 3)
+              *(q++) = (uint8_t)(g_Expand64[p[2]] << 6 | g_Expand64[p[3]]);
+      }
+
+      // Return the length of the decoded data
+      *pDataLen = (int32_t)(q - (uint8_t*)*ppData);
+
+      // Success
+      retStatus = CASA_STATUS_SUCCESS;
+   }
+   else
+   {
+      DbgTrace(0, "-DecodeData- Buffer allocation failure\n", 0);
+
+      retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                  CASA_FACILITY_AUTHTOKEN,
+                                  CASA_STATUS_INSUFFICIENT_RESOURCES);
+   }
+
+   DbgTrace(3, "-DecodeData- End, retStatus = %08X\n", retStatus);
+
+   return retStatus;
+}
+
+
+//++=======================================================================
+int
+dtoul(
+   IN    char *cp,
+   IN    int len)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L0
+//=======================================================================--
+{
+   int   n = 0;
+   int   i;
+
+   DbgTrace(2, "-dtoul- Start\n", 0);
+
+   for (i = 0; i < len; i++, cp++)
+   {
+      // Verify that we are dealing with a valid digit
+      if (*cp >= '0' && *cp <= '9')
+      {
+         n = 10 * n + (*cp - '0');
+      }
+      else
+      {
+         DbgTrace(0, "-dtoul- Found invalid digit\n", 0);
+         break;
+      }
+   }
+      
+   DbgTrace(2, "-dtoul- End, result = %d\n", n);
+
+   return n;
+}
+
+
+//++=======================================================================
+//++=======================================================================
+//++=======================================================================
+
diff --git a/auth_token/client/win32/authtoken.def b/auth_token/client/win32/authtoken.def
new file mode 100644
index 00000000..1862e07e
--- /dev/null
+++ b/auth_token/client/win32/authtoken.def
@@ -0,0 +1,10 @@
+LIBRARY         AUTHTOKEN
+DESCRIPTION     'CASA Authentication Token Library.'
+
+
+EXPORTS
+;                DllRegisterServer   PRIVATE
+;                DllUnregisterServer PRIVATE
+;                DllGetClassObject   PRIVATE
+                ObtainAuthToken     PRIVATE        
+;               DllCanUnloadNow     PRIVATE  
\ No newline at end of file
diff --git a/auth_token/client/win32/cache.c b/auth_token/client/win32/cache.c
new file mode 100644
index 00000000..ea8e565d
--- /dev/null
+++ b/auth_token/client/win32/cache.c
@@ -0,0 +1,875 @@
+/***********************************************************************
+ * 
+ *  Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; version 2.1
+ *  of the License.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, Novell, Inc.
+ * 
+ *  To contact Novell about this file by physical or electronic mail, 
+ *  you may find current contact information at www.novell.com.
+ * 
+ *  Author: Juan Carlos Luciani <jluciani@novell.com>
+ *
+ ***********************************************************************/
+
+
+//===[ Include files ]=====================================================
+
+#include "internal.h"
+
+//===[ Type definitions ]==================================================
+
+//
+// Registry Key/Value defines used in the AuthCache
+//
+#define CASA_AUTH_CACHE_REG_KEY     "CASA_Auth_Cache"
+#define CREATION_TIME_REG_VALUE     "CreationTime"
+#define EXPIRATION_TIME_REG_VALUE   "ExpirationTime"
+#define STATUS_REG_VALUE            "Status"
+#define TOKEN_REG_VALUE             "Token"
+
+
+//===[ Function prototypes ]===============================================
+
+//===[ Global variables ]==================================================
+
+// In memory auth cache list head
+LIST_ENTRY  authCacheListHead;
+
+
+//++=======================================================================
+AuthCacheEntry*
+CreateAuthCacheEntry(
+   IN    char *pCacheKeyName,
+   IN    char *pHostName)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L1
+//=======================================================================--
+{
+   AuthCacheEntry *pEntry;
+
+   DbgTrace(1, "-CreateAuthCacheEntry- Start\n", 0);
+
+   // Allocate space for the entry
+   pEntry = (AuthCacheEntry*) malloc(sizeof(*pEntry));
+   if (pEntry)
+   {
+      // Zero the entry
+      memset(pEntry, 0, sizeof(*pEntry));
+
+      // Now allocate buffers to maintain copies of the CacheKeyName and host names
+      pEntry->pCacheKeyName = (char*) malloc(strlen(pCacheKeyName) + 1);
+      if (pEntry->pCacheKeyName)
+      {
+         pEntry->pHostName = (char*) malloc(strlen(pHostName) + 1);
+         if (pEntry->pHostName)
+         {
+            // Save the names within the entry
+            strcpy(pEntry->pCacheKeyName, pCacheKeyName);
+            strcpy(pEntry->pHostName, pHostName);
+         }
+         else
+         {
+            DbgTrace(0, "-CreateAuthCacheEntry- Unable to allocate buffer for host name\n", 0);
+
+            // Free allocated resources
+            free(pEntry->pCacheKeyName);
+            free(pEntry);
+
+            // Adjust return parameter
+            pEntry = NULL;
+         }
+      }
+      else
+      {
+         DbgTrace(0, "-CreateAuthCacheEntry- Unable to allocate buffer for the CacheKeyName\n", 0);
+
+         // Free allocated resources
+         free(pEntry);
+
+         // Adjust return parameter
+         pEntry = NULL;
+      }
+   }
+   else
+   {
+      DbgTrace(0, "-CreateAuthCacheEntry- Unable to allocate buffer for auth cache entry\n", 0);
+   }
+
+   DbgTrace(1, "-CreateAuthCacheEntry- End, pEntry = %08X\n", pEntry);
+
+   return pEntry;
+}
+
+
+//++=======================================================================
+void
+FreeAuthCacheEntry(
+   IN    AuthCacheEntry *pEntry)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L1
+//=======================================================================--
+{
+   DbgTrace(1, "-FreeAuthCacheEntry- Start\n", 0);
+
+   // Free resources associated with the entry
+   if (pEntry->pToken)
+      free(pEntry->pToken);
+
+   if (pEntry->pHostName)
+      free(pEntry->pHostName);
+
+   if (pEntry->pCacheKeyName)
+      free(pEntry->pCacheKeyName);
+
+   // Free the entry
+   free(pEntry);
+
+   DbgTrace(1, "-FreeAuthCacheEntry- End\n", 0);
+}
+
+
+//++=======================================================================
+static
+BOOL
+CacheEntryLifetimeExpired(
+   IN    DWORD creationTime,
+   IN    DWORD expirationTime)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L1
+//=======================================================================--
+{
+   DWORD currentTime = GetTickCount();
+   BOOL  expired = FALSE;
+
+   DbgTrace(2, "-CacheEntryLifetimeExpired- Start\n", 0);
+
+   // Check if the clock has wrapped
+   if (currentTime >= creationTime)
+   {
+      // The clock has not wrapped, check if the
+      // expiration time has wrapped.
+      if (expirationTime > creationTime)
+      {
+         // The expiration time also has not wrapped,
+         // do a straight compare against the current
+         // time.
+         if (currentTime >= expirationTime)
+         {
+            // It has expired
+            expired = TRUE;
+         }
+      }
+   }
+   else
+   {
+      // The clock has wrapped, check if the expiration
+      // time also wrapped.
+      if (expirationTime > creationTime)
+      {
+         // The expiration time did not wrap, therefore
+         // it has been exceeded since the clock wrapped.
+         expired = TRUE;
+      }
+      else
+      {
+         // The expiration time also wrapped, do a straight
+         // compare against the current time.
+         if (currentTime >= expirationTime)
+         {
+            // It has expired
+            expired = TRUE;
+         }
+      }
+   }
+
+   DbgTrace(2, "-CacheEntryLifetimeExpired- End, result = %08X\n", expired);
+
+   return expired;
+}
+
+
+//++=======================================================================
+AuthCacheEntry*
+FindEntryInAuthCache(
+   IN    char *pCacheKeyName,
+   IN    char *pHostName)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L1
+//=======================================================================--
+{
+   AuthCacheEntry *pEntry = NULL;
+   LIST_ENTRY     *pListEntry;
+
+   DbgTrace(1, "-FindEntryInAuthCache- Start\n", 0);
+
+   // Examine the cache, if entry found then check if it has expired
+   // in which case we would want to remove it from the cache.
+
+   // First look through the entries in our in-memory cache
+   pListEntry = authCacheListHead.Flink;
+   while (pListEntry != &authCacheListHead)
+   {
+      AuthCacheEntry *pWrkEntry;
+
+      // get a pointer to the entry
+      pWrkEntry = CONTAINING_RECORD(pListEntry, AuthCacheEntry, listEntry);
+
+      // Check if this is an entry for the appropriate host
+      if (strcmp(pHostName, pWrkEntry->pHostName) == 0)
+      {
+         // This is an entry for the appropriate host, now check if it is
+         // also for the appropriate CacheKeyName
+         if (strcmp(pCacheKeyName, pWrkEntry->pCacheKeyName) == 0)
+         {
+            // This entry is for the appropriate CacheKeyName, check if it
+            // has not expired.
+            if (CacheEntryLifetimeExpired(pWrkEntry->creationTime, pWrkEntry->expirationTime))
+            {
+               // The lifetime of the entry has expired, remove it from the in-memory cache
+               // and free it.
+               RemoveEntryList(&pWrkEntry->listEntry);
+               FreeAuthCacheEntry(pWrkEntry);
+            }
+            else
+            {
+               // This cache entry is still good, use it.
+               pEntry = pWrkEntry;
+            }
+
+            // No need to keep looking in the in-memory cache
+            break;
+
+         }
+      }
+
+      // Advance to the next entry
+      pListEntry = pListEntry->Flink;
+   }
+
+   // Look in the persistent cache if an entry was not found in the in-memory cache
+   if (pEntry == NULL)
+   {
+      LONG  status;
+      HKEY  hCASARegKey;
+
+      // Open CASA Auth Cache Key
+      status = RegOpenKeyExA(HKEY_CURRENT_USER,
+                             CASA_AUTH_CACHE_REG_KEY,
+                             0,
+                             KEY_ALL_ACCESS,
+                             &hCASARegKey);
+      if (status == ERROR_SUCCESS)
+      {
+         HKEY  hHostRegKey;
+
+         // CASA Auth Cache key opened, now try to open
+         // key for the host.
+         status = RegOpenKeyExA(hCASARegKey,
+                                pHostName,
+                                0,
+                                KEY_ALL_ACCESS,
+                                &hHostRegKey);
+         if (status == ERROR_SUCCESS)
+         {
+            HKEY  hCacheKeyNameRegKey;
+
+            // Host key opened, now try to open key
+            // for the CacheKeyName.
+            status = RegOpenKeyExA(hHostRegKey,
+                                   pCacheKeyName,
+                                   0,
+                                   KEY_ALL_ACCESS,
+                                   &hCacheKeyNameRegKey);
+            if (status == ERROR_SUCCESS)
+            {
+               DWORD creationTime;
+               DWORD expirationTime;
+               BOOL  deleteCacheKeyNameKey = TRUE;
+               DWORD variableSz;
+
+               // Key for the CacheKeyName key opened, now determine whether
+               // or not its lifetime has expired.
+               // 
+               // Read the creation time value
+               variableSz = sizeof(creationTime);
+               status = RegQueryValueExA(hCacheKeyNameRegKey,
+                                         CREATION_TIME_REG_VALUE,
+                                         NULL,
+                                         NULL,
+                                         (LPBYTE) &creationTime,
+                                         &variableSz);
+               if (status == ERROR_SUCCESS)
+               {
+                  // Read the expiration time
+                  variableSz = sizeof(expirationTime);
+                  status = RegQueryValueExA(hCacheKeyNameRegKey,
+                                            EXPIRATION_TIME_REG_VALUE,
+                                            NULL,
+                                            NULL,
+                                            (LPBYTE) &expirationTime,
+                                            &variableSz);
+                  if (status == ERROR_SUCCESS)
+                  {
+                     // Check if the extry lifetime has been exceeded
+                     if (CacheEntryLifetimeExpired(creationTime, expirationTime) == FALSE)
+                     {
+                        // Create a AuthCacheEntry
+                        pEntry = CreateAuthCacheEntry(pCacheKeyName, pHostName);
+                        if (pEntry)
+                        {
+                           BOOL  entryInitialized = FALSE;
+
+                           // Start setting up the AuthCacheEntry
+                           pEntry->creationTime = creationTime;
+                           pEntry->expirationTime = expirationTime;
+
+                           // Read the status
+                           variableSz = sizeof(pEntry->status);
+                           status = RegQueryValueExA(hCacheKeyNameRegKey,
+                                                     STATUS_REG_VALUE,
+                                                     NULL,
+                                                     NULL,
+                                                     (LPBYTE) &pEntry->status,
+                                                     &variableSz);
+                           if (status == ERROR_SUCCESS)
+                           {
+                              // Check if there is also an auth token associated with
+                              // this entry.
+                              if (pEntry->status == CASA_STATUS_SUCCESS)
+                              {
+                                 DWORD tokenSz = 0;
+
+                                 // There should be an auth token associated with this CacheKeyName,
+                                 // first determine what size buffer to allocate for it.
+                                 status = RegQueryValueExA(hCacheKeyNameRegKey,
+                                                           TOKEN_REG_VALUE,
+                                                           NULL,
+                                                           NULL,
+                                                           (LPBYTE) pEntry->pToken,
+                                                           &tokenSz);
+                                 if (status == ERROR_SUCCESS
+                                    || status == ERROR_MORE_DATA)
+                                 {
+                                    // Allocate buffer to hold the auth token
+                                    pEntry->pToken = (char*) malloc(tokenSz);
+                                    if (pEntry->pToken)
+                                    {
+                                       // Now read token into the allocated buffer
+                                       status = RegQueryValueExA(hCacheKeyNameRegKey,
+                                                                 TOKEN_REG_VALUE,
+                                                                 NULL,
+                                                                 NULL,
+                                                                 (LPBYTE) pEntry->pToken,
+                                                                 &tokenSz);
+                                       if (status == ERROR_SUCCESS)
+                                       {
+                                          // The cache entry has been properly initialized,
+                                          // add it to the in-memory cache.
+                                          entryInitialized = TRUE;
+                                          deleteCacheKeyNameKey = FALSE;
+                                          InsertHeadList(&authCacheListHead, &pEntry->listEntry);
+                                       }
+                                       else
+                                       {
+                                          DbgTrace(0, "-FindEntryInAuthCache- Error reading token, status = %d\n", status);
+                                       }
+                                    }
+                                    else
+                                    {
+                                       DbgTrace(0, "-FindEntryInAuthCache- Unable to allocate buffer for token\n", 0);
+                                    }
+                                 }
+                                 else
+                                 {
+                                    DbgTrace(0, "-FindEntryInAuthCache- Error reading token2, status = %d\n", status);
+                                 }
+                              }
+                              else
+                              {
+                                 // There is no auth token associated with this entry
+                                 //
+                                 // The cache entry has been properly initialized,
+                                 // add it to the in-memory cache.
+                                 entryInitialized = TRUE;
+                                 deleteCacheKeyNameKey = FALSE;
+                                 InsertHeadList(&authCacheListHead, &pEntry->listEntry);
+                              }
+                           }
+                           else
+                           {
+                              DbgTrace(0, "-FindEntryInAuthCache- Error reading status, status = %d\n", status);
+                           }
+
+                           // Free the auth cache entry if it was not successfully initialized
+                           if (entryInitialized == FALSE)
+                           {
+                              FreeAuthCacheEntry(pEntry);
+                              pEntry = NULL;
+                           }
+                        }
+                        else
+                        {
+                           DbgTrace(0, "-FindEntryInAuthCache- Error creating auth cache entry\n", 0);
+                        }
+                     }
+                  }
+                  else
+                  {
+                     DbgTrace(0, "-FindEntryInAuthCache- Error reading expiration time, status = %d\n", status);
+                  }
+               }
+               else
+               {
+                  DbgTrace(0, "-FindEntryInAuthCache- Error reading creation time, status = %d\n", status);
+               }
+
+               // Close CacheKeyName key
+               RegCloseKey(hCacheKeyNameRegKey);
+
+               // Delete the CacheKeyName key if necessary
+               if (deleteCacheKeyNameKey)
+               {
+                  RegDeleteKey(hHostRegKey, pCacheKeyName);
+               }
+            }
+
+            // Close host key
+            RegCloseKey(hHostRegKey);
+         }
+
+         // Close CASA_Auth_Cache key
+         RegCloseKey(hCASARegKey);
+      }
+      else
+      {
+         DbgTrace(0, "-FindEntryInAuthCache- Error opening CASA Auth Cache key, status = %d\n", status);
+      }
+   }
+
+   DbgTrace(1, "-FindEntryInAuthCache- End, pEntry = %08X\n", pEntry);
+
+   return pEntry;
+}
+
+
+//++=======================================================================
+void
+AddEntryToAuthCache(
+   IN    AuthCacheEntry *pEntry,
+   IN    int entryLifetime) // seconds
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L1
+//=======================================================================--
+{
+   LONG  status;
+   HKEY  hCASARegKey;
+
+   DbgTrace(1, "-AddEntryToAuthCache- Start\n", 0);
+
+   // Set the time when the entry was added to the cache
+   pEntry->creationTime = GetTickCount();
+
+   // First determine the time when the entry is due to expire
+   pEntry->expirationTime = pEntry->creationTime + (entryLifetime * 1000);
+
+   // Save the entry in our persistent cache (registry)
+   //
+   // Open CASA Auth Cache key
+   status = RegOpenKeyExA(HKEY_CURRENT_USER,
+                          CASA_AUTH_CACHE_REG_KEY,
+                          0,
+                          KEY_ALL_ACCESS,
+                          &hCASARegKey);
+   if (status == ERROR_SUCCESS)
+   {
+      HKEY  hHostRegKey;
+
+      // CASA_Auth_Cache key created or opened, now open or create key for the host.
+      status = RegCreateKeyExA(hCASARegKey,
+                               pEntry->pHostName,
+                               0,
+                               NULL,
+                               REG_OPTION_VOLATILE,
+                               KEY_ALL_ACCESS,
+                               NULL,
+                               &hHostRegKey,
+                               NULL);
+      if (status == ERROR_SUCCESS)
+      {
+         HKEY  hCacheKeyNameRegKey;
+
+         // Host key created or opened, now create key for the CacheKeyName.
+         status = RegCreateKeyExA(hHostRegKey,
+                                  pEntry->pCacheKeyName,
+                                  0,
+                                  NULL,
+                                  REG_OPTION_VOLATILE,
+                                  KEY_ALL_ACCESS,
+                                  NULL,
+                                  &hCacheKeyNameRegKey,
+                                  NULL);
+         if (status == ERROR_SUCCESS)
+         {
+            // Write entry values
+            status = RegSetValueExA(hCacheKeyNameRegKey,
+                                    CREATION_TIME_REG_VALUE,
+                                    0,
+                                    REG_DWORD,
+                                    (LPBYTE) &pEntry->creationTime,
+                                    sizeof(pEntry->creationTime));
+            if (status == ERROR_SUCCESS)
+            {
+               status = RegSetValueExA(hCacheKeyNameRegKey,
+                                       EXPIRATION_TIME_REG_VALUE,
+                                       0,
+                                       REG_DWORD,
+                                       (LPBYTE) &pEntry->expirationTime,
+                                       sizeof(pEntry->expirationTime));
+               if (status == ERROR_SUCCESS)
+               {
+                  status = RegSetValueExA(hCacheKeyNameRegKey,
+                                          STATUS_REG_VALUE,
+                                          0,
+                                          REG_DWORD,
+                                          (LPBYTE) &pEntry->status,
+                                          sizeof(pEntry->status));
+                  if (status == ERROR_SUCCESS)
+                  {
+                     // Check if there is also an auth token associated with this entry
+                     // this entry.
+                     if (pEntry->status == CASA_STATUS_SUCCESS)
+                     {
+                        status = RegSetValueExA(hCacheKeyNameRegKey,
+                                                TOKEN_REG_VALUE,
+                                                0,
+                                                REG_SZ,
+                                                (LPBYTE) pEntry->pToken,
+                                                (DWORD) strlen(pEntry->pToken) + 1);
+                        if (status != ERROR_SUCCESS)
+                        {
+                           DbgTrace(0, "-AddEntryToAuthCache- Error setting token, status = %d\n", status);
+                        }
+                     }
+                  }
+                  else
+                  {
+                     DbgTrace(0, "-AddEntryToAuthCache- Error setting status, status = %d\n", status);
+                  }
+               }
+               else
+               {
+                  DbgTrace(0, "-AddEntryToAuthCache- Error setting expiration time, status = %d\n", status);
+               }
+            }
+            else
+            {
+               DbgTrace(0, "-AddEntryToAuthCache- Error setting creation time, status = %d\n", status);
+            }
+
+            // Close CacheKeyName key
+            RegCloseKey(hCacheKeyNameRegKey);
+
+            // Delete the CacheKeyName key if not successful
+            if (status != ERROR_SUCCESS)
+            {
+               RegDeleteKey(hHostRegKey, pEntry->pCacheKeyName);
+            }
+         }
+         else
+         {
+            DbgTrace(0, "-AddEntryToAuthCache- Error creating key for CacheKeyName, status = %d\n", status);
+         }
+
+         // Close host key
+         RegCloseKey(hHostRegKey);
+      }
+      else
+      {
+         DbgTrace(0, "-AddEntryToAuthCache- Error creating key for host, status = %d\n", status);
+      }
+
+      // Close CASA_Auth_Cache key
+      RegCloseKey(hCASARegKey);
+   }
+   else
+   {
+      DbgTrace(0, "-AddEntryToAuthCache- Error opening CASA Auth Cache Key, status = %d\n", status);
+   }
+
+   // Either place the cache entry in our in-memory cache or
+   // free it depending on the status of the operations performed.
+   if (status == ERROR_SUCCESS)
+   {
+      // The entry was added to the cache, save it in
+      // our in-memory cache.
+      InsertHeadList(&authCacheListHead, &pEntry->listEntry);
+   }
+   else
+   {
+      // Not able to successfully add the entry to the cache,
+      // free the entry.
+      FreeAuthCacheEntry(pEntry);
+   }
+
+   DbgTrace(1, "-AddEntryToAuthCache- End\n", 0);
+}
+
+
+//++=======================================================================
+CasaStatus
+InitializeAuthCache(void)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L1
+//=======================================================================--
+{
+   CasaStatus                 retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                                          CASA_FACILITY_AUTHTOKEN,
+                                                          CASA_STATUS_UNSUCCESSFUL);
+   PSID                       pEveryoneSID;
+   SID_IDENTIFIER_AUTHORITY   SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
+
+   DbgTrace(1, "-InitializeAuthCache- Start\n", 0);
+
+   // Initialize the cache list head
+   InitializeListHead(&authCacheListHead);
+
+   // Lets create the CASA Auth Cache registry key in the
+   // user's hive and limit access to it.
+   //
+   // Create a well-known SID for the Everyone group.
+   if (AllocateAndInitializeSid(&SIDAuthWorld,
+                                1,
+                                SECURITY_WORLD_RID,
+                                0, 0, 0, 0, 0, 0, 0,
+                                &pEveryoneSID))
+   {
+      EXPLICIT_ACCESS            ea[3] = {0};
+      SID_IDENTIFIER_AUTHORITY   SIDAuthNT = SECURITY_NT_AUTHORITY;
+      PSID                       pAdminSID;
+
+      // Initialize an EXPLICIT_ACCESS structure for an ACE.
+      // The ACE will revoke Everyone access to the key.
+      ea[0].grfAccessPermissions = KEY_ALL_ACCESS;
+      ea[0].grfAccessMode = REVOKE_ACCESS;
+      ea[0].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT;
+      ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
+      ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
+      ea[0].Trustee.ptstrName  = (LPTSTR) pEveryoneSID;
+
+      // Create a SID for the BUILTIN\Administrators group.
+      if (AllocateAndInitializeSid(&SIDAuthNT,
+                                   2,
+                                   SECURITY_BUILTIN_DOMAIN_RID,
+                                   DOMAIN_ALIAS_RID_ADMINS,
+                                   0, 0, 0, 0, 0, 0,
+                                   &pAdminSID))
+      {
+         DWORD    status;
+         PACL     pACL;
+         HANDLE   hToken;
+
+         // Initialize an EXPLICIT_ACCESS structure for an ACE.
+         // The ACE will revoke the Administrators group access to the key.
+         ea[1].grfAccessPermissions = KEY_ALL_ACCESS;
+         ea[1].grfAccessMode = REVOKE_ACCESS;
+         ea[1].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT;
+         ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
+         ea[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
+         ea[1].Trustee.ptstrName  = (LPTSTR) pAdminSID;
+
+         // Create a SID for the interactive user, first get the process token
+         if (OpenProcessToken(GetCurrentProcess(),
+                              TOKEN_QUERY,
+                              &hToken))
+         {
+            char  tokenInformation[1024];
+            DWORD infoLength;
+
+            if (GetTokenInformation(hToken,
+                                    TokenUser,
+                                    tokenInformation,
+                                    sizeof(tokenInformation),
+                                    &infoLength))
+            {
+               TOKEN_USER  *pTokenUser = (TOKEN_USER*) tokenInformation;
+
+               // Initialize an EXPLICIT_ACCESS structure for an ACE.
+               // The ACE will grant the interactive user access to the key.
+               ea[2].grfAccessPermissions = KEY_ALL_ACCESS;
+               ea[2].grfAccessMode = SET_ACCESS;
+               ea[2].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT;
+               ea[2].Trustee.TrusteeForm = TRUSTEE_IS_SID;
+               ea[2].Trustee.TrusteeType = TRUSTEE_IS_USER;
+               ea[2].Trustee.ptstrName  = (LPTSTR) pTokenUser->User.Sid;
+
+               // Create a new ACL that contains the new ACEs.
+               status = SetEntriesInAcl(3, ea, NULL, &pACL);
+               if (status == ERROR_SUCCESS)
+               {
+                  PSECURITY_DESCRIPTOR pSD;
+
+                  // Allocate space for a security descriptor
+                  pSD = (SECURITY_DESCRIPTOR*) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); 
+                  if (pSD)
+                  {
+                     // Initialize a security descriptor
+                     if (InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) 
+                     {
+                        // Add the ACL to the security descriptor
+                        if (SetSecurityDescriptorDacl(pSD, 
+                                                      TRUE,     // bDaclPresent flag   
+                                                      pACL, 
+                                                      FALSE))   // not a default DACL 
+                        {
+                           SECURITY_ATTRIBUTES  sa;
+                           HKEY                 hCASARegKey;
+                           DWORD                disposition;
+
+                           // Initialize a security attributes structure
+                           sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+                           sa.lpSecurityDescriptor = pSD;
+                           sa.bInheritHandle = FALSE;
+
+                           // Now create the CASA Auth Cache registry key for this user
+                           // with the required access control restrictions.
+                           status = RegCreateKeyExA(HKEY_CURRENT_USER,
+                                                    CASA_AUTH_CACHE_REG_KEY,
+                                                    0,
+                                                    NULL,
+                                                    REG_OPTION_VOLATILE,
+                                                    KEY_ALL_ACCESS,
+                                                    &sa,
+                                                    &hCASARegKey,
+                                                    &disposition);
+                           if (status == ERROR_SUCCESS)
+                           {
+                              // Success
+                              retStatus = CASA_STATUS_SUCCESS;
+
+                              // Close CASA_Auth_Cache key
+                              RegCloseKey(hCASARegKey);
+                           }
+                           else
+                           {
+                              DbgTrace(0, "-InitializeAuthCache- Error creating CASA Key, status = %d\n", status);
+                           }
+                        }
+                        else
+                        {  
+                           DbgTrace(0, "-InitializeAuthCache- SetSecurityDescriptorDacl Error = %d\n", GetLastError());
+                        } 
+                     }
+                     else
+                     {  
+                        DbgTrace(0, "-InitializeAuthCache- InitializeSecurityDescriptor Error %d\n", GetLastError());
+                     } 
+
+                     // Free the space allocated for the security descriptor
+                     LocalFree(pSD);
+                  }
+                  else
+                  { 
+                     DbgTrace(0, "-InitializeAuthCache- Unable to allocate memory for SD\n", 0);
+                  } 
+
+                  // Free the ACL structure
+                  LocalFree(pACL);
+               }
+               else
+               {
+                  DbgTrace(0, "-InitializeAuthCache- SetEntriesInAcl Error %d\n", status);
+               }
+            }
+            else
+            {
+               DbgTrace(0, "-InitializeAuthCache- Error obtaining token information, error = %d\n", GetLastError());
+            }
+
+            // Release the process token handle
+            CloseHandle(hToken);
+         }
+         else
+         {
+            DbgTrace(0, "-InitializeAuthCache- Unable to obtain process token, error = %d\n", GetLastError());
+         }
+
+         // Free the SID for the administrator
+         FreeSid(pAdminSID);
+      }
+      else
+      {
+         DbgTrace(0, "-InitializeAuthCache- AllocateAndInitializeSid Error %d\n", GetLastError());
+      }
+
+      // Free the SID for everyone
+      FreeSid(pEveryoneSID);
+   }
+   else
+   {
+      DbgTrace(0, "-InitializeAuthCache- AllocateAndInitializeSid Error = %d\n", GetLastError());
+   }
+
+   DbgTrace(1, "-InitializeAuthCache- End, retStatus = %08X\n", retStatus);
+   
+   return retStatus;
+}
+
diff --git a/auth_token/client/win32/dllsup.c b/auth_token/client/win32/dllsup.c
new file mode 100644
index 00000000..f6d3da15
--- /dev/null
+++ b/auth_token/client/win32/dllsup.c
@@ -0,0 +1,132 @@
+/***********************************************************************
+ * 
+ *  Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; version 2.1
+ *  of the License.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, Novell, Inc.
+ * 
+ *  To contact Novell about this file by physical or electronic mail, 
+ *  you may find current contact information at www.novell.com.
+ * 
+ *  Author: Juan Carlos Luciani <jluciani@novell.com>
+ *
+ ***********************************************************************/
+
+//===[ Include files ]=====================================================
+
+#include "internal.h"
+
+//===[ External data ]=====================================================
+
+//===[ Manifest constants ]================================================
+
+//===[ Type definitions ]==================================================
+
+//===[ Function prototypes ]===============================================
+
+//===[ Global variables ]==================================================
+
+UINT32 g_ulCount  = 0;
+UINT32 g_ulLock = 0;
+HANDLE g_hModule;
+
+
+//++=======================================================================
+BOOL APIENTRY DllMain(
+   HANDLE hModule,
+   DWORD  ul_reason_for_call,
+   LPVOID lpReserved   
+   )
+//=======================================================================--
+{
+   BOOL  retStatus = TRUE;
+
+   switch (ul_reason_for_call)
+   {
+      case DLL_PROCESS_ATTACH:
+      {
+         g_hModule = hModule;
+
+         // Initialize the library
+         if (InitializeLibrary() != 0)
+         {
+            // Failed to initialize the library
+            OutputDebugString("CASAAUTH -DllMain- Library initialization failed\n");
+            retStatus = FALSE;
+         }
+         break;
+      }
+
+      case DLL_THREAD_ATTACH:
+      {
+         g_hModule = hModule;
+         break;
+      }
+
+      case DLL_THREAD_DETACH:
+         break;
+
+      case DLL_PROCESS_DETACH:
+      {
+         /* Don't uninitialize on windows
+         tbd
+         */
+         break;
+      }
+    }
+
+    return retStatus;
+}
+
+//++=======================================================================
+//
+// DllCanUnloadNow
+//
+// Synopsis
+//
+//
+STDAPI
+DllCanUnloadNow()
+//
+// Input Arguments
+//
+// Ouput Arguments
+//
+// Return Value
+//    S_OK    The DLL can be unloaded.
+//    S_FALSE The DLL cannot be unloaded now.
+//
+// Description
+//    An Exported Function.
+//    DLLs that support the OLE Component Object Model (COM) should implement
+//    and export DllCanUnloadNow.
+//    A call to DllCanUnloadNow determines whether the DLL from which it is
+//    exported is still in use. A DLL is no longer in use when it is not
+//    managing  any existing objects (the reference count on all of its objects
+//    is 0).
+//    DllCanUnloadNow returns S_FALSE if there are any existing references to
+//    objects that the DLL manages.
+//
+// Environment
+//
+// See Also
+//
+//=======================================================================--
+{
+   // tbd
+   return ((g_ulCount == 0 && g_ulLock == 0) ? S_OK : S_FALSE);
+}
+
+//=========================================================================
+//=========================================================================
+
diff --git a/auth_token/client/win32/platform.h b/auth_token/client/win32/platform.h
new file mode 100644
index 00000000..25d60544
--- /dev/null
+++ b/auth_token/client/win32/platform.h
@@ -0,0 +1,106 @@
+/***********************************************************************
+ * 
+ *  Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; version 2.1
+ *  of the License.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, Novell, Inc.
+ * 
+ *  To contact Novell about this file by physical or electronic mail, 
+ *  you may find current contact information at www.novell.com.
+ * 
+ *  Author: Juan Carlos Luciani <jluciani@novell.com>
+ *
+ ***********************************************************************/
+
+
+//===[ Include files ]=====================================================
+
+#include <winsock2.h>
+#include <windows.h>
+#include <stdio.h>
+#include <aclapi.h>
+#include <winerror.h>
+#include <ws2tcpip.h>
+#include <winhttp.h>
+
+//===[ Type definitions ]==================================================
+
+#ifndef CONTAINING_RECORD
+#define CONTAINING_RECORD(address, type, field) ((type *)(     \
+             (char*)(address) -                                \
+             (char*)(&((type *)0)->field)))
+#endif
+
+//
+// DbgTrace macro define
+//
+#define DbgTrace(LEVEL, X, Y) {                          \
+char printBuff[256];                                     \
+   if (LEVEL == 0)                                       \
+   {                                                     \
+      _snprintf(printBuff, sizeof(printBuff), X, Y);     \
+      printf("AuthToken %s", printBuff);                 \
+   }                                                     \
+   else if (DebugLevel >= LEVEL)                         \
+   {                                                     \
+      _snprintf(printBuff, sizeof(printBuff), X, Y);     \
+      printf("AuthToken %s", printBuff);                 \
+   }                                                     \
+}
+
+
+#define bool BOOLEAN
+#define true TRUE
+#define false FALSE
+
+//
+// Auth Cache Entry definition
+//
+typedef struct _AuthCacheEntry
+{
+   LIST_ENTRY  listEntry;
+   DWORD       creationTime;
+   DWORD       expirationTime;
+   char        *pHostName;
+   char        *pCacheKeyName;
+   char        *pToken;
+   int         status;
+    
+} AuthCacheEntry, *PAuthCacheEntry;
+
+//
+// Rpc Session definition
+//
+typedef struct _RpcSession
+{
+   HINTERNET   hSession;
+   HINTERNET   hConnection;
+
+} RpcSession, *PRpcSession;
+
+//
+// Other definitions
+//
+#define LIB_HANDLE HMODULE
+
+
+//===[ Inlines functions   ]===============================================
+
+//===[ Function prototypes ]===============================================
+
+//===[ Global externals ]==================================================
+
+//===[ External prototypes ]===============================================
+
+//=========================================================================
+
diff --git a/auth_token/client/win32/platutils.c b/auth_token/client/win32/platutils.c
new file mode 100644
index 00000000..1a6abb4d
--- /dev/null
+++ b/auth_token/client/win32/platutils.c
@@ -0,0 +1,544 @@
+/***********************************************************************
+ * 
+ *  Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; version 2.1
+ *  of the License.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, Novell, Inc.
+ * 
+ *  To contact Novell about this file by physical or electronic mail, 
+ *  you may find current contact information at www.novell.com.
+ * 
+ *  Author: Juan Carlos Luciani <jluciani@novell.com>
+ *
+ ***********************************************************************/
+
+//===[ Include files ]=====================================================
+
+#include "internal.h"
+
+//===[ Type definitions ]==================================================
+
+//
+// Normalized Host Name Cache Entry definition
+//
+typedef struct _NormalizedHostNameCacheEntry
+{
+   LIST_ENTRY  listEntry;
+   char        *pHostName;
+   char        *pNormalizedHostName;
+   int         buffLengthRequired;
+    
+} NormalizedHostNameCacheEntry, *PNormalizedHostNameCacheEntry;
+
+
+//===[ Function prototypes ]===============================================
+
+//===[ Global variables ]==================================================
+
+// Global synchronization mutex for the user
+static
+HANDLE   hUserMutex;
+
+// Normalized host name cache list head
+static
+LIST_ENTRY  normalizedHostNameCacheListHead;
+
+// Synchronization mutex for the normalized host name cache
+static
+HANDLE   hNormalizedHostNameCacheMutex;
+
+// Authentication mechanism configuration file folder
+char  mechConfigFolder[] = "\\Program Files\\Novell\\Casa\\Etc\\Auth\\Mechanisms";
+
+// Path separator
+char  pathCharString[] = "\\";
+
+
+//++=======================================================================
+CasaStatus
+CreateUserMutex(void)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L1
+//=======================================================================--
+{
+   CasaStatus  retStatus = CASA_STATUS_SUCCESS;
+   char        *pUsername = NULL;
+   DWORD       nameLength = 0;
+
+   DbgTrace(1, "-CreateUserMutex- Start\n", 0);
+
+   // Get the size of the buffer required to obtain the user name
+   GetUserName(pUsername, &nameLength);
+   if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
+   {
+      // Allocate buffer to hold the user name
+      pUsername = (char*) malloc(nameLength);
+      if (pUsername)
+      {
+         // Get the name of the user
+         if (GetUserName(pUsername, &nameLength))
+         {
+            SECURITY_ATTRIBUTES  mutexAttributes;
+            char                 mutexName[256];
+
+            //printf("\nUsername is %s", pUsername);
+
+            // Now lets create a global semaphore for the
+            // user and allow its handle to be inherited.
+            mutexAttributes.nLength = sizeof(mutexAttributes);
+            mutexAttributes.lpSecurityDescriptor = NULL;
+            mutexAttributes.bInheritHandle = TRUE;
+            if (sprintf(mutexName, "Global\\CASA_Auth_Mutex_%s", pUsername) != -1)
+            {
+               hUserMutex = CreateMutex(&mutexAttributes,
+                                        FALSE,
+                                        mutexName);
+               if (hUserMutex == NULL)
+               {
+                  DbgTrace(0, "-CreateUserMutex- CreteMutex failed, error = %d\n", GetLastError());
+                  retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                              CASA_FACILITY_AUTHTOKEN,
+                                              CASA_STATUS_UNSUCCESSFUL);
+               }
+            }
+            else
+            {
+               DbgTrace(0, "-CreateUserMutex- sprintf failed, error = %d\n", GetLastError());
+               retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                           CASA_FACILITY_AUTHTOKEN,
+                                           CASA_STATUS_UNSUCCESSFUL);
+            }
+         }
+         else
+         {
+            DbgTrace(0, "-CreateUserMutex- GetUserName failed, error = %d\n", GetLastError());
+            retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                        CASA_FACILITY_AUTHTOKEN,
+                                        CASA_STATUS_UNSUCCESSFUL);
+         }
+
+         // Free the buffer allocated to hold the user name
+         free(pUsername);
+      }
+      else
+      {
+         DbgTrace(0, "-CreateUserMutex- Buffer allocation error\n", 0);
+         retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                     CASA_FACILITY_AUTHTOKEN,
+                                     CASA_STATUS_INSUFFICIENT_RESOURCES);
+      }
+   }
+   else
+   {
+      DbgTrace(0, "-CreateUserMutex- Un-expected GetUserName error, error = %d\n", GetLastError());
+      retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                  CASA_FACILITY_AUTHTOKEN,
+                                  CASA_STATUS_UNSUCCESSFUL);
+   }
+
+   DbgTrace(1, "-CreateUserMutex- End, retStatus\n", retStatus);
+
+   return retStatus;
+}
+
+
+//++=======================================================================
+void
+LockUserMutex(void)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L1
+//=======================================================================--
+{
+   DbgTrace(2, "-LockUserMutex- Start\n", 0);
+
+   WaitForSingleObject(hUserMutex, INFINITE);
+
+   DbgTrace(2, "-LockUserMutex- End\n", 0);
+}
+
+
+//++=======================================================================
+void
+FreeUserMutex(void)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L1
+//=======================================================================--
+{
+   DbgTrace(2, "-FreeUserMutex- Start\n", 0);
+
+   if (ReleaseMutex(hUserMutex) == 0)
+   {
+      DbgTrace(0, "-FreeUserMutex- ReleaseMutex failed, error = %d\n", GetLastError());
+   }
+
+   DbgTrace(2, "-FreeUserMutex- End\n", 0);
+}
+
+
+//++=======================================================================
+LIB_HANDLE
+OpenLibrary(
+   IN    char *pFileName)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L0
+//=======================================================================--
+{
+   LIB_HANDLE  libHandle;
+
+
+   DbgTrace(1, "-OpenLibrary- Start\n", 0);
+
+   libHandle = LoadLibrary(pFileName);
+   if (libHandle == NULL)
+   {
+      DbgTrace(0, "-OpenLibrary- Not able to load library, error = %d\n", GetLastError());
+   }
+
+   DbgTrace(1, "-OpenLibrary- End, handle = %08X\n", libHandle);
+
+   return libHandle;
+}
+
+
+//++=======================================================================
+void
+CloseLibrary(
+   IN    LIB_HANDLE libHandle)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L0
+//=======================================================================--
+{
+   DbgTrace(1, "-CloseLibrary- Start\n", 0);
+
+   FreeLibrary(libHandle);
+
+   DbgTrace(1, "-CloseLibrary- End\n", 0);
+}
+
+
+//++=======================================================================
+void*
+GetFunctionPtr(
+   IN    LIB_HANDLE libHandle,
+   IN    char *pFunctionName)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L0
+//=======================================================================--
+{
+   void  *pFuncPtr;
+
+   DbgTrace(1, "-GetFunctionPtr- Start\n", 0);
+
+   pFuncPtr = GetProcAddress(libHandle, pFunctionName);
+   if (pFuncPtr == NULL)
+   {
+      DbgTrace(0, "-GetFunctionPtr- Not able to obtain func ptr, error = %d\n", GetLastError());
+   }
+
+   DbgTrace(1, "-GetFunctionPtr- End, pFuncPtr = %08X\n", pFuncPtr);
+
+   return pFuncPtr;
+}
+
+
+//++=======================================================================
+char*
+NormalizeHostName(
+   IN    char *pHostName)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L1
+//=======================================================================--
+{
+   char                          *pNormalizedName = NULL;
+   LIST_ENTRY                    *pListEntry;
+   NormalizedHostNameCacheEntry  *pEntry = NULL;
+
+   DbgTrace(1, "-NormalizeHostName- Start\n", 0);
+
+   // Obtain our synchronization mutex
+   WaitForSingleObject(hNormalizedHostNameCacheMutex, INFINITE);
+
+   // First try to find an entry in the normalized host name cache
+   // for the host name provided.
+   pListEntry = normalizedHostNameCacheListHead.Flink;
+   while (pListEntry != &normalizedHostNameCacheListHead)
+   {
+      // Get pointer to the entry
+      pEntry = CONTAINING_RECORD(pListEntry, NormalizedHostNameCacheEntry, listEntry);
+
+      // Check if the entry is for the host name
+      if (strcmp(pHostName, pEntry->pHostName) == 0)
+      {
+         // This entry corresponds to the given host name
+         break;
+      }
+      else
+      {
+         // The entry does not correspond to the given host name
+         pEntry = NULL;
+      }
+
+      // Advance to the next entry
+      pListEntry = pListEntry->Flink;
+   }
+
+   // Check if we found an entry in our cache for the given host name
+   if (pEntry)
+   {
+      // Entry found, obtain the normalized name from it.
+      pNormalizedName = (char*) malloc(pEntry->buffLengthRequired);
+      if (pNormalizedName)
+      {
+         // Copy the normalized name onto the allocated buffer
+         strcpy(pNormalizedName, pEntry->pNormalizedHostName);
+      }
+      else
+      {
+         DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0);
+      }
+   }
+   else
+   {
+      // An entry was not found in our cache, create one.
+      pEntry = (NormalizedHostNameCacheEntry*) malloc(sizeof(NormalizedHostNameCacheEntry));
+      if (pEntry)
+      {
+         // Zero the entry
+         memset(pEntry, 0, sizeof(*pEntry));
+
+         // Allocate a buffer to hold the host name in the entry
+         pEntry->pHostName = (char*) malloc(strlen(pHostName) + 1);
+         if (pEntry->pHostName)
+         {
+            struct hostent       *pLookupResult;
+            struct sockaddr_in   sockAddr = {0};
+
+            // Copy the host name given into the allocated buffer
+            strcpy(pEntry->pHostName, pHostName);
+
+            // Now try to resolve the normalized name
+            pLookupResult = gethostbyname(pHostName);
+            if (pLookupResult && pLookupResult->h_addrtype == AF_INET)
+            {
+               char  dnsHostName[NI_MAXHOST];
+
+               // Set up a sockaddr structure
+               sockAddr.sin_family = AF_INET;
+               sockAddr.sin_addr.S_un.S_addr = *((int*) pLookupResult->h_addr_list[0]);
+
+               // Now try to resolve the name using DNS
+               if (getnameinfo((const struct sockaddr*) &sockAddr,
+                               sizeof(sockAddr),
+                               dnsHostName,
+                               sizeof(dnsHostName),
+                               NULL,
+                               0,
+                               NI_NAMEREQD) == 0)
+               {
+                  // We resolved the address to a DNS name, use it as the normalized name.
+                  pEntry->buffLengthRequired = (int) strlen(dnsHostName) + 1;
+                  pEntry->pNormalizedHostName = (char*) malloc(pEntry->buffLengthRequired);
+                  if (pEntry->pNormalizedHostName)
+                  {
+                     // Copy the dns name
+                     strcpy(pEntry->pNormalizedHostName, dnsHostName);
+                  }
+                  else
+                  {
+                     DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0);
+                  }
+               }
+               else
+               {
+                  DbgTrace(0, "-NormalizeHostName- getnameInfo failed, error %d\n", WSAGetLastError());
+
+                  // Not able to resolve the name in DNS, just use the host name as
+                  // the normalized name.
+                  pEntry->buffLengthRequired = (int) strlen(pHostName) + 1;
+                  pEntry->pNormalizedHostName = (char*) malloc(pEntry->buffLengthRequired);
+                  if (pEntry->pNormalizedHostName)
+                  {
+                     // Copy the host name
+                     strcpy(pEntry->pNormalizedHostName, pHostName);
+                  }
+                  else
+                  {
+                     DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0);
+                  }
+               }
+            }
+            else
+            {
+               DbgTrace(0, "-NormalizeHostName- Name resolution failed, error = %d\n", WSAGetLastError());
+            }
+         }
+         else
+         {
+            DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0);
+
+            // Free the space allocated for the entry
+            free(pEntry);
+         }
+
+         // Proceed based on whether or not we normalized the name
+         if (pEntry->pNormalizedHostName)
+         {
+            // The name was normalized, save the entry in our cache.
+            InsertHeadList(&normalizedHostNameCacheListHead, &pEntry->listEntry);
+
+            // Return the normalized name present in the entry
+            pNormalizedName = (char*) malloc(pEntry->buffLengthRequired);
+            if (pNormalizedName)
+            {
+               // Copy the normalized name onto the allocated buffer
+               strcpy(pNormalizedName, pEntry->pNormalizedHostName);
+            }
+            else
+            {
+               DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0);
+            }
+         }
+         else
+         {
+            // The host name was not normalized, free allocated resources.
+            if (pEntry->pHostName)
+               free(pEntry->pHostName);
+            free(pEntry);
+         }
+      }
+      else
+      {
+         DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0);
+      }
+   }
+
+   // Release our synchronization mutex
+   if (ReleaseMutex(hNormalizedHostNameCacheMutex) == 0)
+   {
+      DbgTrace(0, "-NormalizeHostName- ReleaseMutex failed, error\n", 0);
+   }
+
+   DbgTrace(1, "-NormalizeHostName- End, pNormalizedName = %08X\n", pNormalizedName);
+
+   return pNormalizedName;
+}
+
+
+//++=======================================================================
+CasaStatus
+InitializeHostNameNormalization(void)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L1
+//=======================================================================--
+{
+   CasaStatus  retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                           CASA_FACILITY_AUTHTOKEN,
+                                           CASA_STATUS_UNSUCCESSFUL);
+   int         winsockStartupResult;
+   WSADATA     winsockData;
+
+   DbgTrace(1, "-InitializeHostNameNormalization- Start\n", 0);
+
+   // Initialize winsock
+   if ((winsockStartupResult = WSAStartup(MAKEWORD(2,2), &winsockData)) == 0)
+   {
+      // Initialize the cache list head
+      InitializeListHead(&normalizedHostNameCacheListHead);
+
+      // Create a cache mutex only applicable to the current process
+      hNormalizedHostNameCacheMutex = CreateMutex(NULL,
+                                                  FALSE,
+                                                  NULL);
+      if (hNormalizedHostNameCacheMutex != NULL)
+      {
+         retStatus = CASA_STATUS_SUCCESS;
+      }
+      else
+      {
+         DbgTrace(0, "-InitializeHostNameNormalization- CreateMutex failed, error = %d\n", GetLastError());
+      }
+   }
+   else
+   {
+      DbgTrace(0, "-InitializeHostNameNormalization- WSAStartup failed, error = %d\n", winsockStartupResult);
+   }
+
+   DbgTrace(1, "-InitializeHostNameNormalization- End, retStatus = %08X\n", retStatus);
+
+   return retStatus;
+}
+
diff --git a/auth_token/client/win32/rpc.c b/auth_token/client/win32/rpc.c
new file mode 100644
index 00000000..d64fc029
--- /dev/null
+++ b/auth_token/client/win32/rpc.c
@@ -0,0 +1,442 @@
+/***********************************************************************
+ * 
+ *  Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; version 2.1
+ *  of the License.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, Novell, Inc.
+ * 
+ *  To contact Novell about this file by physical or electronic mail, 
+ *  you may find current contact information at www.novell.com.
+ * 
+ *  Author: Juan Carlos Luciani <jluciani@novell.com>
+ *
+ ***********************************************************************/
+
+
+//===[ Include files ]=====================================================
+
+#include "internal.h"
+
+//===[ Type definitions ]==================================================
+
+#define INITIAL_RESPONSE_DATA_BUF_SIZE 1028
+#define INCREMENT_RESPONSE_DATA_BUF_SIZE 256
+
+//===[ Function prototypes ]===============================================
+
+//===[ Global variables ]==================================================
+
+
+//++=======================================================================
+static
+CasaStatus
+CopyMultiToWideAlloc(
+   IN    char *pMulti,
+   IN    int multiSize,
+   INOUT LPWSTR *ppWide,
+   INOUT int *pWideSize)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L0
+//=======================================================================--
+{
+   int      retStatus;
+   int      size, i;
+
+   DbgTrace(2, "-CopyMultiToWideAlloc- Start\n", 0);
+
+   size = (multiSize + 1) * sizeof(WCHAR);
+
+   if ((*ppWide = (PWCHAR) malloc(size)) != NULL)
+   {
+      for (i = 0; i < multiSize; i++)
+      {
+         *(*ppWide + i) = (unsigned char) *(pMulti + i);
+      }
+
+      *(*ppWide + i) = L'\0';
+
+      if (pWideSize)
+      {
+         *pWideSize = size - sizeof(WCHAR);
+      }
+
+      retStatus = CASA_STATUS_SUCCESS;
+   }
+   else
+   {
+      retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                  CASA_FACILITY_AUTHTOKEN,
+                                  CASA_STATUS_INSUFFICIENT_RESOURCES);
+   }
+
+   DbgTrace(2, "-CopyMultiToWideAlloc- End, retStatus = %08X\n", retStatus);
+
+   return retStatus;
+}
+
+
+//++=======================================================================
+RpcSession*
+OpenRpcSession(
+   IN    char *pHostName)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L0
+//=======================================================================--
+{
+   RpcSession  *pSession;
+
+   DbgTrace(1, "-OpenRpcSession- Start\n", 0);
+
+   // Allocate space for the session
+   pSession = (RpcSession*) malloc(sizeof(*pSession));
+   if (pSession)
+   {
+      // Zero the session structure
+      memset(pSession, 0, sizeof(*pSession));
+
+      // Open a Winhttp session
+      pSession->hSession = WinHttpOpen(L"CASA Client/1.0",
+                                       WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
+                                       WINHTTP_NO_PROXY_NAME,
+                                       WINHTTP_NO_PROXY_BYPASS,
+                                       0);
+      if (pSession->hSession)
+      {
+         LPWSTR   pWideHostName;
+         int      wideHostLen;
+
+         // Session opened, now convert the host name to Unicode so that
+         // we can open a connection.
+         if (CopyMultiToWideAlloc(pHostName,
+                                  (int) strlen(pHostName),
+                                  &pWideHostName,
+                                  &wideHostLen) == CASA_STATUS_SUCCESS)
+         {
+            // Now open connection
+            pSession->hConnection = WinHttpConnect(pSession->hSession,
+                                                   pWideHostName,
+                                                   8080, /*INTERNET_DEFAULT_HTTP_PORT,*/
+                                                   0);
+            if (pSession->hConnection == NULL)
+            {
+               DbgTrace(0, "-OpenRpcSession- Failed to open connection, error = %d\n", GetLastError());
+
+               // Free allocated resources
+               WinHttpCloseHandle(pSession->hSession);
+               free(pSession);
+               pSession = NULL;
+            }
+
+            // Free the host name wide string buffer
+            free(pWideHostName);
+         }
+         else
+         {
+            DbgTrace(0, "-OpenRpcSession- Error converting host name to wide string\n", 0);
+
+            // Free allocated resources
+            WinHttpCloseHandle(pSession->hSession);
+            free(pSession);
+            pSession = NULL;
+         }
+      }
+      else
+      {
+         DbgTrace(0, "-OpenRpcSession- Failed to open session, error = %d\n", GetLastError());
+      }
+   }
+   else
+   {
+      DbgTrace(0, "-OpenRpcSession- Failed to allocate buffer for rpc session\n", 0);
+   }
+
+   DbgTrace(2, "-OpenRpcSession- End, pSession = %08X\n", pSession);
+
+   return pSession;
+}
+
+
+//++=======================================================================
+void
+CloseRpcSession(
+   IN    RpcSession *pSession)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L0
+//=======================================================================--
+{
+   DbgTrace(1, "-CloseRpcSession- Start\n", 0);
+
+   // Close the connection handle
+   WinHttpCloseHandle(pSession->hConnection);
+
+   // Close the session handle
+   WinHttpCloseHandle(pSession->hSession);
+
+   // Free the space allocated for the session
+   free(pSession);
+
+   DbgTrace(1, "-CloseRpcSession- End\n", 0);
+}
+
+
+//++=======================================================================
+CasaStatus
+Rpc(
+   IN    RpcSession *pSession,
+   IN    char *pMethod,
+   IN    bool secure,
+   IN    char *pRequestData,
+   INOUT char **ppResponseData,
+   INOUT int *pResponseDataLen)
+//
+//  Arguments: 
+//
+//  Returns:   
+//
+//  Abstract:  
+//
+//  Notes:
+//
+// L0
+//=======================================================================--
+{
+   CasaStatus  retStatus = CASA_STATUS_SUCCESS;
+   char        rpcTarget[256];
+   LPWSTR      pWideRpcTarget;
+   int         wideRpcTargetLen;
+   WCHAR       sendHeaders[] = L"Content-Type: text/html";
+
+   DbgTrace(1, "-Rpc- Start\n", 0);
+
+   // Initialize output parameter
+   *ppResponseData = NULL;
+
+   // Create rpc target string and convert it to a wide string
+   sprintf(rpcTarget, "CasaAuthServer/%s", pMethod);
+   retStatus = CopyMultiToWideAlloc(rpcTarget,
+                                    (int) strlen(rpcTarget),
+                                    &pWideRpcTarget,
+                                    &wideRpcTargetLen);
+   if (CASA_SUCCESS(retStatus))
+   {
+      HINTERNET   hRequest;
+
+      // tbd - Add retry capability
+
+      // Open a request handle
+      hRequest = WinHttpOpenRequest(pSession->hConnection,
+                                    L"POST",
+                                    pWideRpcTarget,
+                                    NULL,
+                                    WINHTTP_NO_REFERER,
+                                    WINHTTP_DEFAULT_ACCEPT_TYPES,
+                                    secure? WINHTTP_FLAG_REFRESH | WINHTTP_FLAG_SECURE : WINHTTP_FLAG_REFRESH);
+      if (hRequest)
+      {
+         int   reqDataLen = (int) strlen(pRequestData);
+
+         // Send the request
+         if (WinHttpSendRequest(hRequest,
+                                sendHeaders,
+                                -1,
+                                pRequestData,
+                                reqDataLen,
+                                reqDataLen,
+                                0))
+         {
+            // Request sent, now await for the response.
+            if (WinHttpReceiveResponse(hRequest, NULL))
+            {
+               WCHAR httpCompStatus[4] = {0};
+               DWORD httpCompStatusLen = sizeof(httpCompStatus);
+
+               // Response received, make sure that it completed successfully.
+               if (WinHttpQueryHeaders(hRequest,
+                                       WINHTTP_QUERY_STATUS_CODE,
+                                       NULL,
+                                       &httpCompStatus,
+                                       &httpCompStatusLen,
+                                       WINHTTP_NO_HEADER_INDEX))
+               {
+                  // Check that the request completed successfully
+                  if (memcmp(httpCompStatus, L"200", sizeof(httpCompStatus)) == 0)
+                  {
+                     char  *pResponseData;
+                     int   responseDataBufSize = INITIAL_RESPONSE_DATA_BUF_SIZE;      
+                     int   responseDataRead = 0;
+
+                     // Now read the response data, to do so we need to allocate a buffer.
+                     pResponseData = (char*) malloc(INITIAL_RESPONSE_DATA_BUF_SIZE);
+                     if (pResponseData)
+                     {
+                        char     *pCurrLocation = pResponseData;
+                        DWORD    bytesRead;
+
+                        do
+                        {
+                           bytesRead = 0;
+                           if (WinHttpReadData(hRequest,
+                                               (LPVOID) pCurrLocation,
+                                               responseDataBufSize - responseDataRead,
+                                               &bytesRead))
+                           {
+                              pCurrLocation += bytesRead;
+                              responseDataRead += bytesRead;
+
+                              // Check if we need to allocate a larger buffer
+                              if (responseDataRead == responseDataBufSize)
+                              {
+                                 char  *pTmpBuf;
+
+                                 // We need to upgrade the receive buffer
+                                 pTmpBuf = (char*) malloc(responseDataBufSize + INCREMENT_RESPONSE_DATA_BUF_SIZE);
+                                 if (pTmpBuf)
+                                 {
+                                    memcpy(pTmpBuf, pResponseData, responseDataBufSize);
+                                    free(pResponseData);
+                                    pResponseData = pTmpBuf;
+                                    pCurrLocation = pResponseData + responseDataBufSize;
+                                    responseDataBufSize += INCREMENT_RESPONSE_DATA_BUF_SIZE;
+                                 }
+                                 else
+                                 {
+                                    DbgTrace(0, "-Rpc- Buffer allocation failure\n", 0);
+                                    retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                                                CASA_FACILITY_AUTHTOKEN,
+                                                                CASA_STATUS_INSUFFICIENT_RESOURCES);
+                                 }
+                              }
+                           }
+                           else
+                           {
+                              DbgTrace(0, "-Rpc- Failed reading response data, error = %d\n", GetLastError());
+                              retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                                          CASA_FACILITY_AUTHTOKEN,
+                                                          CASA_STATUS_UNSUCCESSFUL);
+                           }
+                        } while (CASA_SUCCESS(retStatus)
+                                 && bytesRead != 0);
+
+                        // Check if the response data was successfully received
+                        if (CASA_SUCCESS(retStatus))
+                        {
+                           // The response data was received, return it to the caller.
+                           *ppResponseData = pResponseData;
+                           *pResponseDataLen = responseDataRead; 
+                        }
+                        else
+                        {
+                           // Failed to receive the response data, free the allocated buffer.
+                           free(pResponseData);
+                        }
+                     }
+                     else
+                     {
+                        DbgTrace(0, "-Rpc- Buffer allocation failure\n", 0);
+                        retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                                    CASA_FACILITY_AUTHTOKEN,
+                                                    CASA_STATUS_INSUFFICIENT_RESOURCES);
+                     }
+                  }
+                  else
+                  {
+                     DbgTrace(0, "-Rpc- HTTP request did not complete successfully, status = %S\n", httpCompStatus);
+                     retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                                 CASA_FACILITY_AUTHTOKEN,
+                                                 CASA_STATUS_UNSUCCESSFUL);
+                  }
+               }
+               else
+               {
+                  DbgTrace(0, "-Rpc- Unable to obtain http request completion status, error = %d\n", GetLastError());
+                  retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                              CASA_FACILITY_AUTHTOKEN,
+                                              CASA_STATUS_UNSUCCESSFUL);
+               }
+            }
+            else
+            {
+               DbgTrace(0, "-Rpc- Unable to receive response, error = %d\n", GetLastError());
+               retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                           CASA_FACILITY_AUTHTOKEN,
+                                           CASA_STATUS_UNSUCCESSFUL);
+            }
+         }
+         else
+         {
+            int   error = GetLastError();
+
+            DbgTrace(0, "-Rpc- Unsuccessful send http request, error = %d\n", error);
+            if (error == ERROR_WINHTTP_CANNOT_CONNECT)
+            {
+               retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                           CASA_FACILITY_AUTHTOKEN,
+                                           CASA_STATUS_AUTH_SERVER_UNAVAILABLE);
+            }
+            else
+            {
+               retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                           CASA_FACILITY_AUTHTOKEN,
+                                           CASA_STATUS_UNSUCCESSFUL);
+            }
+         }
+
+         // Close the request handle
+         WinHttpCloseHandle(hRequest);
+      }
+      else
+      {
+         DbgTrace(0, "-Rpc- Unable to open http request, error = %d\n", GetLastError());
+         retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
+                                     CASA_FACILITY_AUTHTOKEN,
+                                     CASA_STATUS_UNSUCCESSFUL);
+      }
+
+      // Free the rpc target wide string buffer
+      free(pWideRpcTarget);
+   }
+   else
+   {
+      DbgTrace(0, "-Rpc- Error converting method name to wide string\n", 0);
+   }
+
+   DbgTrace(1, "-Rpc- End, retStatus = %d\n", retStatus);
+
+   return retStatus;
+}
+
+