Modified the folder name to be compatible with the make system for windows.
This commit is contained in:
		
							
								
								
									
										10
									
								
								auth_token/client/windows/authtoken.def
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								auth_token/client/windows/authtoken.def
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | |||||||
|  | LIBRARY         AUTHTOKEN | ||||||
|  | DESCRIPTION     'CASA Authentication Token Library.' | ||||||
|  |  | ||||||
|  |  | ||||||
|  | EXPORTS | ||||||
|  | ;                DllRegisterServer   PRIVATE | ||||||
|  | ;                DllUnregisterServer PRIVATE | ||||||
|  | ;                DllGetClassObject   PRIVATE | ||||||
|  |                 ObtainAuthToken     PRIVATE         | ||||||
|  | ;               DllCanUnloadNow     PRIVATE   | ||||||
							
								
								
									
										895
									
								
								auth_token/client/windows/cache.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										895
									
								
								auth_token/client/windows/cache.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,895 @@ | |||||||
|  | /*********************************************************************** | ||||||
|  |  *  | ||||||
|  |  *  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  g_authCacheListHead; | ||||||
|  |  | ||||||
|  | // Non-host specific key name | ||||||
|  | char  g_allHosts[] = "AllHosts"; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | //++======================================================================= | ||||||
|  | AuthCacheEntry* | ||||||
|  | CreateAuthCacheEntry( | ||||||
|  |    IN    char *pCacheKeyName, | ||||||
|  |    IN    char *pHostName) | ||||||
|  | // | ||||||
|  | //  Arguments:  | ||||||
|  | // | ||||||
|  | //  Returns:    | ||||||
|  | // | ||||||
|  | //  Abstract:   | ||||||
|  | // | ||||||
|  | //  Notes: | ||||||
|  | // | ||||||
|  | // L2 | ||||||
|  | //=======================================================================-- | ||||||
|  | { | ||||||
|  |    AuthCacheEntry *pEntry; | ||||||
|  |  | ||||||
|  |    DbgTrace(1, "-CreateAuthCacheEntry- Start\n", 0); | ||||||
|  |  | ||||||
|  |    // Use allHosts if a host name was not specified | ||||||
|  |    if (pHostName == NULL) | ||||||
|  |    { | ||||||
|  |       pHostName = g_allHosts; | ||||||
|  |    } | ||||||
|  |  | ||||||
|  |    // 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: | ||||||
|  | // | ||||||
|  | // L2 | ||||||
|  | //=======================================================================-- | ||||||
|  | { | ||||||
|  |    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: | ||||||
|  | // | ||||||
|  | // L2 | ||||||
|  | //=======================================================================-- | ||||||
|  | { | ||||||
|  |    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: | ||||||
|  | // | ||||||
|  | // L2 | ||||||
|  | //=======================================================================-- | ||||||
|  | { | ||||||
|  |    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. | ||||||
|  |  | ||||||
|  |    // Use allHosts if a host name was not specified | ||||||
|  |    if (pHostName == NULL) | ||||||
|  |    { | ||||||
|  |       pHostName = g_allHosts; | ||||||
|  |    } | ||||||
|  |  | ||||||
|  |    // First look through the entries in our in-memory cache | ||||||
|  |    pListEntry = g_authCacheListHead.Flink; | ||||||
|  |    while (pListEntry != &g_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(&g_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(&g_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: | ||||||
|  | // | ||||||
|  | // L2 | ||||||
|  | //=======================================================================-- | ||||||
|  | { | ||||||
|  |    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(&g_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: | ||||||
|  | // | ||||||
|  | // L2 | ||||||
|  | //=======================================================================-- | ||||||
|  | { | ||||||
|  |    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(&g_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; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | //++======================================================================= | ||||||
|  | //++======================================================================= | ||||||
|  | //++======================================================================= | ||||||
|  |  | ||||||
							
								
								
									
										132
									
								
								auth_token/client/windows/dllsup.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								auth_token/client/windows/dllsup.c
									
									
									
									
									
										Normal file
									
								
							| @@ -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); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //========================================================================= | ||||||
|  | //========================================================================= | ||||||
|  |  | ||||||
							
								
								
									
										549
									
								
								auth_token/client/windows/platform.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										549
									
								
								auth_token/client/windows/platform.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,549 @@ | |||||||
|  | /*********************************************************************** | ||||||
|  |  *  | ||||||
|  |  *  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: | ||||||
|  | // | ||||||
|  | // L2 | ||||||
|  | //=======================================================================-- | ||||||
|  | { | ||||||
|  |    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]; | ||||||
|  |  | ||||||
|  |             // 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 | ||||||
|  | AcquireUserMutex(void) | ||||||
|  | // | ||||||
|  | //  Arguments:  | ||||||
|  | // | ||||||
|  | //  Returns:    | ||||||
|  | // | ||||||
|  | //  Abstract:   | ||||||
|  | // | ||||||
|  | //  Notes: | ||||||
|  | // | ||||||
|  | // L2 | ||||||
|  | //=======================================================================-- | ||||||
|  | { | ||||||
|  |    DbgTrace(2, "-AcquireUserMutex- Start\n", 0); | ||||||
|  |  | ||||||
|  |    WaitForSingleObject(hUserMutex, INFINITE); | ||||||
|  |  | ||||||
|  |    DbgTrace(2, "-AcquireUserMutex- End\n", 0); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | //++======================================================================= | ||||||
|  | void | ||||||
|  | ReleaseUserMutex(void) | ||||||
|  | // | ||||||
|  | //  Arguments:  | ||||||
|  | // | ||||||
|  | //  Returns:    | ||||||
|  | // | ||||||
|  | //  Abstract:   | ||||||
|  | // | ||||||
|  | //  Notes: | ||||||
|  | // | ||||||
|  | // L2 | ||||||
|  | //=======================================================================-- | ||||||
|  | { | ||||||
|  |    DbgTrace(2, "-ReleaseUserMutex- Start\n", 0); | ||||||
|  |  | ||||||
|  |    if (ReleaseMutex(hUserMutex) == 0) | ||||||
|  |    { | ||||||
|  |       DbgTrace(0, "-ReleaseUserMutex- ReleaseMutex failed, error = %d\n", GetLastError()); | ||||||
|  |    } | ||||||
|  |  | ||||||
|  |    DbgTrace(2, "-ReleaseUserMutex- End\n", 0); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | //++======================================================================= | ||||||
|  | LIB_HANDLE | ||||||
|  | OpenLibrary( | ||||||
|  |    IN    char *pFileName) | ||||||
|  | // | ||||||
|  | //  Arguments:  | ||||||
|  | // | ||||||
|  | //  Returns:    | ||||||
|  | // | ||||||
|  | //  Abstract:   | ||||||
|  | // | ||||||
|  | //  Notes: | ||||||
|  | // | ||||||
|  | // L2 | ||||||
|  | //=======================================================================-- | ||||||
|  | { | ||||||
|  |    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: | ||||||
|  | // | ||||||
|  | // L2 | ||||||
|  | //=======================================================================-- | ||||||
|  | { | ||||||
|  |    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: | ||||||
|  | // | ||||||
|  | // L2 | ||||||
|  | //=======================================================================-- | ||||||
|  | { | ||||||
|  |    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: | ||||||
|  | // | ||||||
|  | // L2 | ||||||
|  | //=======================================================================-- | ||||||
|  | { | ||||||
|  |    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: | ||||||
|  | // | ||||||
|  | // L2 | ||||||
|  | //=======================================================================-- | ||||||
|  | { | ||||||
|  |    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; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | //++======================================================================= | ||||||
|  | //++======================================================================= | ||||||
|  | //++======================================================================= | ||||||
|  |  | ||||||
							
								
								
									
										112
									
								
								auth_token/client/windows/platform.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								auth_token/client/windows/platform.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,112 @@ | |||||||
|  | /*********************************************************************** | ||||||
|  |  *  | ||||||
|  |  *  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 || DebugLevel >= LEVEL)                \ | ||||||
|  | //   {                                                     \ | ||||||
|  | //      _snprintf(printBuff, sizeof(printBuff), X, Y);     \ | ||||||
|  | //      printf("AuthToken %s", printBuff);                 \ | ||||||
|  | //   }                                                     \ | ||||||
|  | //} | ||||||
|  | #define DbgTrace(LEVEL, X, Y) {                                \ | ||||||
|  | char formatBuff[128];                                          \ | ||||||
|  | char printBuff[256];                                           \ | ||||||
|  |    if (LEVEL == 0 || DebugLevel >= LEVEL)                      \ | ||||||
|  |    {                                                           \ | ||||||
|  |       strcpy(formatBuff, "AuthToken ");                        \ | ||||||
|  |       strncat(formatBuff, X, sizeof(formatBuff) - 10);         \ | ||||||
|  |       _snprintf(printBuff, sizeof(printBuff), formatBuff, Y);  \ | ||||||
|  |       OutputDebugString(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 ]=============================================== | ||||||
|  |  | ||||||
|  | //========================================================================= | ||||||
|  |  | ||||||
							
								
								
									
										498
									
								
								auth_token/client/windows/rpc.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										498
									
								
								auth_token/client/windows/rpc.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,498 @@ | |||||||
|  | /*********************************************************************** | ||||||
|  |  *  | ||||||
|  |  *  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 | ||||||
|  |  | ||||||
|  | #define MAX_RPC_RETRIES 3 | ||||||
|  |  | ||||||
|  | //===[ Function prototypes ]=============================================== | ||||||
|  |  | ||||||
|  | //===[ Global variables ]================================================== | ||||||
|  |  | ||||||
|  |  | ||||||
|  | //++======================================================================= | ||||||
|  | static | ||||||
|  | CasaStatus | ||||||
|  | CopyMultiToWideAlloc( | ||||||
|  |    IN    char *pMulti, | ||||||
|  |    IN    int multiSize, | ||||||
|  |    INOUT LPWSTR *ppWide, | ||||||
|  |    INOUT int *pWideSize) | ||||||
|  | // | ||||||
|  | //  Arguments:  | ||||||
|  | // | ||||||
|  | //  Returns:    | ||||||
|  | // | ||||||
|  | //  Abstract:   | ||||||
|  | // | ||||||
|  | //  Notes: | ||||||
|  | // | ||||||
|  | // L2 | ||||||
|  | //=======================================================================-- | ||||||
|  | { | ||||||
|  |    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: | ||||||
|  | // | ||||||
|  | // L2 | ||||||
|  | //=======================================================================-- | ||||||
|  | { | ||||||
|  |    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: | ||||||
|  | // | ||||||
|  | // L2 | ||||||
|  | //=======================================================================-- | ||||||
|  | { | ||||||
|  |    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); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | //++======================================================================= | ||||||
|  | static | ||||||
|  | CasaStatus | ||||||
|  | InternalRpc( | ||||||
|  |    IN    RpcSession *pSession, | ||||||
|  |    IN    char *pMethod, | ||||||
|  |    IN    bool secure, | ||||||
|  |    IN    char *pRequestData, | ||||||
|  |    INOUT char **ppResponseData, | ||||||
|  |    INOUT int *pResponseDataLen) | ||||||
|  | // | ||||||
|  | //  Arguments:  | ||||||
|  | // | ||||||
|  | //  Returns:    | ||||||
|  | // | ||||||
|  | //  Abstract:   | ||||||
|  | // | ||||||
|  | //  Notes: | ||||||
|  | // | ||||||
|  | // L2 | ||||||
|  | //=======================================================================-- | ||||||
|  | { | ||||||
|  |    CasaStatus  retStatus = CASA_STATUS_SUCCESS; | ||||||
|  |    char        rpcTarget[256]; | ||||||
|  |    LPWSTR      pWideRpcTarget; | ||||||
|  |    int         wideRpcTargetLen; | ||||||
|  |    WCHAR       sendHeaders[] = L"Content-Type: text/html"; | ||||||
|  |  | ||||||
|  |    DbgTrace(1, "-InternalRpc- Start\n", 0); | ||||||
|  |  | ||||||
|  |    // Initialize output parameter | ||||||
|  |    *ppResponseData = NULL; | ||||||
|  |  | ||||||
|  |    // Create rpc target string and convert it to a wide string | ||||||
|  |    sprintf(rpcTarget, "CasaAuthTokenSvc/%s", pMethod); | ||||||
|  |    retStatus = CopyMultiToWideAlloc(rpcTarget, | ||||||
|  |                                     (int) strlen(rpcTarget), | ||||||
|  |                                     &pWideRpcTarget, | ||||||
|  |                                     &wideRpcTargetLen); | ||||||
|  |    if (CASA_SUCCESS(retStatus)) | ||||||
|  |    { | ||||||
|  |       HINTERNET   hRequest; | ||||||
|  |  | ||||||
|  |       // 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, "-InternalRpc- Buffer allocation failure\n", 0); | ||||||
|  |                                     retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, | ||||||
|  |                                                                 CASA_FACILITY_AUTHTOKEN, | ||||||
|  |                                                                 CASA_STATUS_INSUFFICIENT_RESOURCES); | ||||||
|  |                                  } | ||||||
|  |                               } | ||||||
|  |                            } | ||||||
|  |                            else | ||||||
|  |                            { | ||||||
|  |                               DbgTrace(0, "-InternalRpc- 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, "-InternalRpc- Buffer allocation failure\n", 0); | ||||||
|  |                         retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, | ||||||
|  |                                                     CASA_FACILITY_AUTHTOKEN, | ||||||
|  |                                                     CASA_STATUS_INSUFFICIENT_RESOURCES); | ||||||
|  |                      } | ||||||
|  |                   } | ||||||
|  |                   else | ||||||
|  |                   { | ||||||
|  |                      DbgTrace(0, "-InternalRpc- HTTP request did not complete successfully, status = %S\n", httpCompStatus); | ||||||
|  |                      retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, | ||||||
|  |                                                  CASA_FACILITY_AUTHTOKEN, | ||||||
|  |                                                  CASA_STATUS_UNSUCCESSFUL); | ||||||
|  |                   } | ||||||
|  |                } | ||||||
|  |                else | ||||||
|  |                { | ||||||
|  |                   DbgTrace(0, "-InternalRpc- 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, "-InternalRpc- 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, "-InternalRpc- 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, "-InternalRpc- 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, "-InternalRpc- Error converting method name to wide string\n", 0); | ||||||
|  |    } | ||||||
|  |  | ||||||
|  |    DbgTrace(1, "-InternalRpc- End, retStatus = %d\n", retStatus); | ||||||
|  |  | ||||||
|  |    return retStatus; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | //++======================================================================= | ||||||
|  | CasaStatus | ||||||
|  | Rpc( | ||||||
|  |    IN    RpcSession *pSession, | ||||||
|  |    IN    char *pMethod, | ||||||
|  |    IN    bool secure, | ||||||
|  |    IN    char *pRequestData, | ||||||
|  |    INOUT char **ppResponseData, | ||||||
|  |    INOUT int *pResponseDataLen) | ||||||
|  | // | ||||||
|  | //  Arguments:  | ||||||
|  | // | ||||||
|  | //  Returns:    | ||||||
|  | // | ||||||
|  | //  Abstract:   | ||||||
|  | // | ||||||
|  | //  Notes: | ||||||
|  | // | ||||||
|  | // L2 | ||||||
|  | //=======================================================================-- | ||||||
|  | { | ||||||
|  |    CasaStatus  retStatus; | ||||||
|  |    int         retries = 0; | ||||||
|  |  | ||||||
|  |    DbgTrace(1, "-Rpc- Start\n", 0); | ||||||
|  |  | ||||||
|  |    // Retry the RPC as needed | ||||||
|  |    do | ||||||
|  |    { | ||||||
|  |       // Issue the RPC | ||||||
|  |       retStatus = InternalRpc(pSession, | ||||||
|  |                               pMethod, | ||||||
|  |                               secure, | ||||||
|  |                               pRequestData, | ||||||
|  |                               ppResponseData, | ||||||
|  |                               pResponseDataLen); | ||||||
|  |  | ||||||
|  |       // Account for this try | ||||||
|  |       retries ++; | ||||||
|  |  | ||||||
|  |    } while (CasaStatusCode(retStatus) == CASA_STATUS_AUTH_SERVER_UNAVAILABLE | ||||||
|  |             && retries < MAX_RPC_RETRIES); | ||||||
|  |  | ||||||
|  |    DbgTrace(1, "-Rpc- End, retStatus = %d\n", retStatus); | ||||||
|  |  | ||||||
|  |    return retStatus; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | //++======================================================================= | ||||||
|  | //++======================================================================= | ||||||
|  | //++======================================================================= | ||||||
|  |  | ||||||
		Reference in New Issue
	
	Block a user