Made some formatting changes, added some additional debug statements, and updated the project file to adjust for the new directory structure.
This commit is contained in:
parent
f145a46ffe
commit
f6106fcd67
@ -59,7 +59,7 @@ AuthCacheEntry*
|
|||||||
CreateAuthTokenCacheEntry(
|
CreateAuthTokenCacheEntry(
|
||||||
IN const char *pCacheKey,
|
IN const char *pCacheKey,
|
||||||
IN const char *pGroupOrHostName,
|
IN const char *pGroupOrHostName,
|
||||||
IN CasaStatus status,
|
IN CasaStatus status,
|
||||||
IN unsigned char *pToken,
|
IN unsigned char *pToken,
|
||||||
IN int entryLifetime // seconds (0 == Lives forever)
|
IN int entryLifetime // seconds (0 == Lives forever)
|
||||||
)
|
)
|
||||||
@ -75,23 +75,23 @@ CreateAuthTokenCacheEntry(
|
|||||||
// L2
|
// L2
|
||||||
//=======================================================================--
|
//=======================================================================--
|
||||||
{
|
{
|
||||||
CasaStatus retStatus;
|
CasaStatus retStatus;
|
||||||
SSCS_KEYCHAIN_ID_T sessionKeyChain = {26, "SSCS_SESSION_KEY_CHAIN_ID"};
|
SSCS_KEYCHAIN_ID_T sessionKeyChain = {26, "SSCS_SESSION_KEY_CHAIN_ID"};
|
||||||
SSCS_SECRET_ID_T sharedId = {27, "CASA_AUTHENTICATION_TOKENS"};
|
SSCS_SECRET_ID_T sharedId = {27, "CASA_AUTHENTICATION_TOKENS"};
|
||||||
uint32_t tokenSize, entrySize, keySize;
|
uint32_t tokenSize, entrySize, keySize;
|
||||||
AuthCacheEntry *pEntry = NULL;
|
AuthCacheEntry *pEntry = NULL;
|
||||||
unsigned char *pKey;
|
unsigned char *pKey;
|
||||||
|
|
||||||
|
|
||||||
DbgTrace(1, "-CreateAuthTokenCacheEntry- Start\n", 0);
|
DbgTrace(1, "-CreateAuthTokenCacheEntry- Start\n", 0);
|
||||||
|
|
||||||
if (status == CASA_STATUS_SUCCESS)
|
if (status == CASA_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
tokenSize = (uint32_t)strlen(pToken);
|
tokenSize = (uint32_t)strlen(pToken);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tokenSize = 0;
|
tokenSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
entrySize = tokenSize + sizeof(AuthCacheEntry);
|
entrySize = tokenSize + sizeof(AuthCacheEntry);
|
||||||
@ -101,69 +101,68 @@ CreateAuthTokenCacheEntry(
|
|||||||
pEntry = (AuthCacheEntry*) malloc(entrySize);
|
pEntry = (AuthCacheEntry*) malloc(entrySize);
|
||||||
if (pEntry)
|
if (pEntry)
|
||||||
{
|
{
|
||||||
// Set the status
|
// Set the status
|
||||||
pEntry->status = status;
|
pEntry->status = status;
|
||||||
|
|
||||||
if (pEntry->status == CASA_STATUS_SUCCESS)
|
if (pEntry->status == CASA_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
memcpy(&pEntry->token[0], pToken, tokenSize);
|
memcpy(&pEntry->token[0], pToken, tokenSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
pEntry->token[tokenSize] = '\0';
|
pEntry->token[tokenSize] = '\0';
|
||||||
|
|
||||||
// Set the time when the entry was added to the cache
|
// Set the time when the entry was added to the cache
|
||||||
pEntry->creationTime = GetTickCount();
|
pEntry->creationTime = GetTickCount();
|
||||||
|
|
||||||
// First determine the time when the entry is due to expire
|
// First determine the time when the entry is due to expire
|
||||||
if (entryLifetime != 0)
|
if (entryLifetime != 0)
|
||||||
{
|
{
|
||||||
pEntry->expirationTime = pEntry->creationTime + (entryLifetime * 1000);
|
pEntry->expirationTime = pEntry->creationTime + (entryLifetime * 1000);
|
||||||
pEntry->doesNotExpire = FALSE;
|
pEntry->doesNotExpire = FALSE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// The entry does not expire
|
// The entry does not expire
|
||||||
pEntry->expirationTime = 0;
|
pEntry->expirationTime = 0;
|
||||||
pEntry->doesNotExpire = TRUE;
|
pEntry->doesNotExpire = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
keySize = (uint32_t)strlen(pCacheKey) + (uint32_t)strlen(pGroupOrHostName) + 2;
|
keySize = (uint32_t)strlen(pCacheKey) + (uint32_t)strlen(pGroupOrHostName) + 2;
|
||||||
|
|
||||||
pKey = malloc(keySize);
|
pKey = malloc(keySize);
|
||||||
|
|
||||||
if (pKey)
|
if (pKey)
|
||||||
{
|
{
|
||||||
strncpy(pKey, pCacheKey, keySize);
|
strncpy(pKey, pCacheKey, keySize);
|
||||||
strncat(pKey, "@", keySize);
|
strncat(pKey, "@", keySize);
|
||||||
strncat(pKey, pGroupOrHostName, keySize);
|
strncat(pKey, pGroupOrHostName, keySize);
|
||||||
|
|
||||||
retStatus = miCASAWriteBinaryKey(
|
retStatus = miCASAWriteBinaryKey(g_hCASAContext,
|
||||||
g_hCASAContext,
|
0,
|
||||||
0,
|
&sessionKeyChain,
|
||||||
&sessionKeyChain,
|
&sharedId,
|
||||||
&sharedId,
|
pKey,
|
||||||
pKey,
|
keySize,
|
||||||
keySize,
|
(uint8_t *)pEntry,
|
||||||
(uint8_t *)pEntry,
|
&entrySize,
|
||||||
&entrySize,
|
NULL,
|
||||||
NULL,
|
NULL);
|
||||||
NULL);
|
|
||||||
|
|
||||||
|
|
||||||
free(pKey);
|
free(pKey);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
||||||
CASA_FACILITY_AUTHTOKEN,
|
CASA_FACILITY_AUTHTOKEN,
|
||||||
CASA_STATUS_INSUFFICIENT_RESOURCES);
|
CASA_STATUS_INSUFFICIENT_RESOURCES);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
||||||
CASA_FACILITY_AUTHTOKEN,
|
CASA_FACILITY_AUTHTOKEN,
|
||||||
CASA_STATUS_INSUFFICIENT_RESOURCES);
|
CASA_STATUS_INSUFFICIENT_RESOURCES);
|
||||||
}
|
}
|
||||||
|
|
||||||
DbgTrace(1, "-CreateAuthTokenCacheEntry- End, pEntry = %08X\n", pEntry);
|
DbgTrace(1, "-CreateAuthTokenCacheEntry- End, pEntry = %08X\n", pEntry);
|
||||||
@ -176,7 +175,7 @@ CreateAuthTokenCacheEntry(
|
|||||||
AuthCacheEntry*
|
AuthCacheEntry*
|
||||||
CreateSessionTokenCacheEntry(
|
CreateSessionTokenCacheEntry(
|
||||||
IN const char *pCacheKey,
|
IN const char *pCacheKey,
|
||||||
IN CasaStatus status,
|
IN CasaStatus status,
|
||||||
IN unsigned char *pToken,
|
IN unsigned char *pToken,
|
||||||
IN int entryLifetime // seconds (0 == Lives forever)
|
IN int entryLifetime // seconds (0 == Lives forever)
|
||||||
)
|
)
|
||||||
@ -192,22 +191,22 @@ CreateSessionTokenCacheEntry(
|
|||||||
// L2
|
// L2
|
||||||
//=======================================================================--
|
//=======================================================================--
|
||||||
{
|
{
|
||||||
CasaStatus retStatus;
|
CasaStatus retStatus;
|
||||||
SSCS_KEYCHAIN_ID_T sessionKeyChain = {26, "SSCS_SESSION_KEY_CHAIN_ID"};
|
SSCS_KEYCHAIN_ID_T sessionKeyChain = {26, "SSCS_SESSION_KEY_CHAIN_ID"};
|
||||||
SSCS_SECRET_ID_T sharedId = {20, "CASA_SESSION_TOKENS"};
|
SSCS_SECRET_ID_T sharedId = {20, "CASA_SESSION_TOKENS"};
|
||||||
uint32_t tokenSize, entrySize;
|
uint32_t tokenSize, entrySize;
|
||||||
AuthCacheEntry *pEntry = NULL;
|
AuthCacheEntry *pEntry = NULL;
|
||||||
|
|
||||||
|
|
||||||
DbgTrace(1, "-CreateSessionTokenCacheEntry- Start\n", 0);
|
DbgTrace(1, "-CreateSessionTokenCacheEntry- Start\n", 0);
|
||||||
|
|
||||||
if (status == CASA_STATUS_SUCCESS)
|
if (status == CASA_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
tokenSize = (uint32_t)strlen(pToken);
|
tokenSize = (uint32_t)strlen(pToken);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tokenSize = 0;
|
tokenSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
entrySize = tokenSize + sizeof(AuthCacheEntry);
|
entrySize = tokenSize + sizeof(AuthCacheEntry);
|
||||||
@ -217,49 +216,48 @@ CreateSessionTokenCacheEntry(
|
|||||||
pEntry = (AuthCacheEntry*) malloc(entrySize);
|
pEntry = (AuthCacheEntry*) malloc(entrySize);
|
||||||
if (pEntry)
|
if (pEntry)
|
||||||
{
|
{
|
||||||
// Set the status
|
// Set the status
|
||||||
pEntry->status = status;
|
pEntry->status = status;
|
||||||
|
|
||||||
if (pEntry->status == CASA_STATUS_SUCCESS)
|
if (pEntry->status == CASA_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
memcpy(&pEntry->token[0], pToken, tokenSize);
|
memcpy(&pEntry->token[0], pToken, tokenSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
pEntry->token[tokenSize] = '\0';
|
pEntry->token[tokenSize] = '\0';
|
||||||
|
|
||||||
// Set the time when the entry was added to the cache
|
// Set the time when the entry was added to the cache
|
||||||
pEntry->creationTime = GetTickCount();
|
pEntry->creationTime = GetTickCount();
|
||||||
|
|
||||||
// First determine the time when the entry is due to expire
|
// First determine the time when the entry is due to expire
|
||||||
if (entryLifetime != 0)
|
if (entryLifetime != 0)
|
||||||
{
|
{
|
||||||
pEntry->expirationTime = pEntry->creationTime + (entryLifetime * 1000);
|
pEntry->expirationTime = pEntry->creationTime + (entryLifetime * 1000);
|
||||||
pEntry->doesNotExpire = FALSE;
|
pEntry->doesNotExpire = FALSE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// The entry does not expire
|
// The entry does not expire
|
||||||
pEntry->expirationTime = 0;
|
pEntry->expirationTime = 0;
|
||||||
pEntry->doesNotExpire = TRUE;
|
pEntry->doesNotExpire = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
retStatus = miCASAWriteBinaryKey(
|
retStatus = miCASAWriteBinaryKey(g_hCASAContext,
|
||||||
g_hCASAContext,
|
0,
|
||||||
0,
|
&sessionKeyChain,
|
||||||
&sessionKeyChain,
|
&sharedId,
|
||||||
&sharedId,
|
(char *)pCacheKey,
|
||||||
(char *)pCacheKey,
|
(uint32_t)strlen(pCacheKey) + 1,
|
||||||
(uint32_t)strlen(pCacheKey) + 1,
|
(uint8_t *)pEntry,
|
||||||
(uint8_t *)pEntry,
|
&entrySize,
|
||||||
&entrySize,
|
NULL,
|
||||||
NULL,
|
NULL);
|
||||||
NULL);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
||||||
CASA_FACILITY_AUTHTOKEN,
|
CASA_FACILITY_AUTHTOKEN,
|
||||||
CASA_STATUS_INSUFFICIENT_RESOURCES);
|
CASA_STATUS_INSUFFICIENT_RESOURCES);
|
||||||
}
|
}
|
||||||
|
|
||||||
DbgTrace(1, "-CreateSessionTokenCacheEntry- End, pEntry = %08X\n", pEntry);
|
DbgTrace(1, "-CreateSessionTokenCacheEntry- End, pEntry = %08X\n", pEntry);
|
||||||
@ -380,11 +378,11 @@ FindSessionTokenEntryInCache(
|
|||||||
// L2
|
// L2
|
||||||
//=======================================================================--
|
//=======================================================================--
|
||||||
{
|
{
|
||||||
CasaStatus retStatus;
|
CasaStatus retStatus;
|
||||||
SSCS_KEYCHAIN_ID_T sessionKeyChain = {26, "SSCS_SESSION_KEY_CHAIN_ID"};
|
SSCS_KEYCHAIN_ID_T sessionKeyChain = {26, "SSCS_SESSION_KEY_CHAIN_ID"};
|
||||||
SSCS_SECRET_ID_T sharedId = {20, "CASA_SESSION_TOKENS"};
|
SSCS_SECRET_ID_T sharedId = {20, "CASA_SESSION_TOKENS"};
|
||||||
uint32_t valueLength, bytesRequired;
|
uint32_t valueLength, bytesRequired;
|
||||||
AuthCacheEntry *pEntry = NULL;
|
AuthCacheEntry *pEntry = NULL;
|
||||||
|
|
||||||
|
|
||||||
DbgTrace(1, "-FindSessionTokenEntryInCache- Start\n", 0);
|
DbgTrace(1, "-FindSessionTokenEntryInCache- Start\n", 0);
|
||||||
@ -392,62 +390,59 @@ FindSessionTokenEntryInCache(
|
|||||||
valueLength = 0;
|
valueLength = 0;
|
||||||
bytesRequired = 0;
|
bytesRequired = 0;
|
||||||
|
|
||||||
retStatus = miCASAReadBinaryKey(
|
retStatus = miCASAReadBinaryKey(g_hCASAContext,
|
||||||
g_hCASAContext,
|
0,
|
||||||
0,
|
&sessionKeyChain,
|
||||||
&sessionKeyChain,
|
&sharedId,
|
||||||
&sharedId,
|
(char *)pCacheKey,
|
||||||
(char *)pCacheKey,
|
(uint32_t)strlen(pCacheKey) + 1,
|
||||||
(uint32_t)strlen(pCacheKey) + 1,
|
NULL,
|
||||||
NULL,
|
&valueLength,
|
||||||
&valueLength,
|
NULL,
|
||||||
NULL,
|
&bytesRequired,
|
||||||
&bytesRequired,
|
NULL);
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (retStatus == NSSCS_E_ENUM_BUFF_TOO_SHORT
|
if (retStatus == NSSCS_E_ENUM_BUFF_TOO_SHORT
|
||||||
&& bytesRequired != 0)
|
&& bytesRequired != 0)
|
||||||
{
|
{
|
||||||
pEntry = (AuthCacheEntry*) malloc(bytesRequired);
|
pEntry = (AuthCacheEntry*) malloc(bytesRequired);
|
||||||
|
|
||||||
if (pEntry)
|
if (pEntry)
|
||||||
{
|
{
|
||||||
valueLength = bytesRequired;
|
valueLength = bytesRequired;
|
||||||
bytesRequired = 0;
|
bytesRequired = 0;
|
||||||
|
|
||||||
retStatus = miCASAReadBinaryKey(
|
retStatus = miCASAReadBinaryKey(g_hCASAContext,
|
||||||
g_hCASAContext,
|
0,
|
||||||
0,
|
&sessionKeyChain,
|
||||||
&sessionKeyChain,
|
&sharedId,
|
||||||
&sharedId,
|
(char *)pCacheKey,
|
||||||
(char *)pCacheKey,
|
(uint32_t)strlen(pCacheKey) + 1,
|
||||||
(uint32_t)strlen(pCacheKey) + 1,
|
(uint8_t *)pEntry,
|
||||||
(uint8_t *)pEntry,
|
&valueLength,
|
||||||
&valueLength,
|
NULL,
|
||||||
NULL,
|
&bytesRequired,
|
||||||
&bytesRequired,
|
NULL);
|
||||||
NULL);
|
if (CASA_SUCCESS(retStatus))
|
||||||
|
{
|
||||||
|
if (pEntry->doesNotExpire == FALSE
|
||||||
|
&& CacheEntryLifetimeExpired(pEntry->creationTime, pEntry->expirationTime))
|
||||||
|
{
|
||||||
|
// Remove the entry ???
|
||||||
|
//miCASARemoveBinaryKey();
|
||||||
|
|
||||||
if (CASA_SUCCESS(retStatus))
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
||||||
{
|
CASA_FACILITY_AUTHTOKEN,
|
||||||
if (pEntry->doesNotExpire == FALSE
|
CASA_STATUS_UNSUCCESSFUL);
|
||||||
&& CacheEntryLifetimeExpired(pEntry->creationTime, pEntry->expirationTime))
|
}
|
||||||
{
|
}
|
||||||
// Remove the entry ???
|
|
||||||
//miCASARemoveBinaryKey();
|
|
||||||
|
|
||||||
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
if (!CASA_SUCCESS(retStatus))
|
||||||
CASA_FACILITY_AUTHTOKEN,
|
{
|
||||||
CASA_STATUS_UNSUCCESSFUL);
|
FreeAuthCacheEntry(pEntry);
|
||||||
}
|
pEntry = NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (!CASA_SUCCESS(retStatus))
|
|
||||||
{
|
|
||||||
FreeAuthCacheEntry(pEntry);
|
|
||||||
pEntry = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DbgTrace(1, "-FindSessionTokenEntryInCache- End, pEntry = %08X\n", pEntry);
|
DbgTrace(1, "-FindSessionTokenEntryInCache- End, pEntry = %08X\n", pEntry);
|
||||||
@ -473,12 +468,12 @@ FindAuthTokenEntryInCache(
|
|||||||
// L2
|
// L2
|
||||||
//=======================================================================--
|
//=======================================================================--
|
||||||
{
|
{
|
||||||
CasaStatus retStatus;
|
CasaStatus retStatus;
|
||||||
SSCS_KEYCHAIN_ID_T sessionKeyChain = {26, "SSCS_SESSION_KEY_CHAIN_ID"};
|
SSCS_KEYCHAIN_ID_T sessionKeyChain = {26, "SSCS_SESSION_KEY_CHAIN_ID"};
|
||||||
SSCS_SECRET_ID_T sharedId = {27, "CASA_AUTHENTICATION_TOKENS"};
|
SSCS_SECRET_ID_T sharedId = {27, "CASA_AUTHENTICATION_TOKENS"};
|
||||||
uint32_t valueLength, bytesRequired, keySize;
|
uint32_t valueLength, bytesRequired, keySize;
|
||||||
AuthCacheEntry *pEntry = NULL;
|
AuthCacheEntry *pEntry = NULL;
|
||||||
unsigned char *pKey;
|
unsigned char *pKey;
|
||||||
|
|
||||||
|
|
||||||
DbgTrace(1, "-FindAuthTokenEntryInCache- Start\n", 0);
|
DbgTrace(1, "-FindAuthTokenEntryInCache- Start\n", 0);
|
||||||
@ -486,75 +481,71 @@ FindAuthTokenEntryInCache(
|
|||||||
keySize = (uint32_t)strlen(pCacheKey) + (uint32_t)strlen(pGroupOrHostName) + 2;
|
keySize = (uint32_t)strlen(pCacheKey) + (uint32_t)strlen(pGroupOrHostName) + 2;
|
||||||
|
|
||||||
pKey = malloc(keySize);
|
pKey = malloc(keySize);
|
||||||
|
|
||||||
if (pKey)
|
if (pKey)
|
||||||
{
|
{
|
||||||
strncpy(pKey, pCacheKey, keySize);
|
strncpy(pKey, pCacheKey, keySize);
|
||||||
strncat(pKey, "@", keySize);
|
strncat(pKey, "@", keySize);
|
||||||
strncat(pKey, pGroupOrHostName, keySize);
|
strncat(pKey, pGroupOrHostName, keySize);
|
||||||
|
|
||||||
valueLength = 0;
|
valueLength = 0;
|
||||||
bytesRequired = 0;
|
bytesRequired = 0;
|
||||||
|
|
||||||
retStatus = miCASAReadBinaryKey(
|
retStatus = miCASAReadBinaryKey(g_hCASAContext,
|
||||||
g_hCASAContext,
|
0,
|
||||||
0,
|
&sessionKeyChain,
|
||||||
&sessionKeyChain,
|
&sharedId,
|
||||||
&sharedId,
|
pKey,
|
||||||
pKey,
|
keySize,
|
||||||
keySize,
|
NULL,
|
||||||
NULL,
|
&valueLength,
|
||||||
&valueLength,
|
NULL,
|
||||||
NULL,
|
&bytesRequired,
|
||||||
&bytesRequired,
|
NULL);
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (retStatus == NSSCS_E_ENUM_BUFF_TOO_SHORT
|
if (retStatus == NSSCS_E_ENUM_BUFF_TOO_SHORT
|
||||||
&& bytesRequired != 0)
|
&& bytesRequired != 0)
|
||||||
{
|
{
|
||||||
pEntry = (AuthCacheEntry*) malloc(bytesRequired);
|
pEntry = (AuthCacheEntry*) malloc(bytesRequired);
|
||||||
|
|
||||||
if (pEntry)
|
if (pEntry)
|
||||||
{
|
{
|
||||||
valueLength = bytesRequired;
|
valueLength = bytesRequired;
|
||||||
bytesRequired = 0;
|
bytesRequired = 0;
|
||||||
|
|
||||||
retStatus = miCASAReadBinaryKey(
|
retStatus = miCASAReadBinaryKey(g_hCASAContext,
|
||||||
g_hCASAContext,
|
0,
|
||||||
0,
|
&sessionKeyChain,
|
||||||
&sessionKeyChain,
|
&sharedId,
|
||||||
&sharedId,
|
pKey,
|
||||||
pKey,
|
keySize,
|
||||||
keySize,
|
(uint8_t *)pEntry,
|
||||||
(uint8_t *)pEntry,
|
&valueLength,
|
||||||
&valueLength,
|
NULL,
|
||||||
NULL,
|
&bytesRequired,
|
||||||
&bytesRequired,
|
NULL);
|
||||||
NULL);
|
if (CASA_SUCCESS(retStatus))
|
||||||
|
{
|
||||||
|
if (pEntry->doesNotExpire == FALSE
|
||||||
|
&& CacheEntryLifetimeExpired(pEntry->creationTime, pEntry->expirationTime))
|
||||||
|
{
|
||||||
|
// Remove the entry ???
|
||||||
|
//miCASARemoveBinaryKey();
|
||||||
|
|
||||||
if (CASA_SUCCESS(retStatus))
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
||||||
{
|
CASA_FACILITY_AUTHTOKEN,
|
||||||
if (pEntry->doesNotExpire == FALSE
|
CASA_STATUS_UNSUCCESSFUL);
|
||||||
&& CacheEntryLifetimeExpired(pEntry->creationTime, pEntry->expirationTime))
|
}
|
||||||
{
|
}
|
||||||
// Remove the entry ???
|
|
||||||
//miCASARemoveBinaryKey();
|
|
||||||
|
|
||||||
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
if (!CASA_SUCCESS(retStatus))
|
||||||
CASA_FACILITY_AUTHTOKEN,
|
{
|
||||||
CASA_STATUS_UNSUCCESSFUL);
|
FreeAuthCacheEntry(pEntry);
|
||||||
}
|
pEntry = NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!CASA_SUCCESS(retStatus))
|
free(pKey);
|
||||||
{
|
|
||||||
FreeAuthCacheEntry(pEntry);
|
|
||||||
pEntry = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
free(pKey);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DbgTrace(1, "-FindAuthTokenEntryInCache- End, pEntry = %08X\n", pEntry);
|
DbgTrace(1, "-FindAuthTokenEntryInCache- End, pEntry = %08X\n", pEntry);
|
||||||
@ -578,7 +569,7 @@ InitializeAuthCache()
|
|||||||
// L2
|
// L2
|
||||||
//=======================================================================--
|
//=======================================================================--
|
||||||
{
|
{
|
||||||
CasaStatus retStatus;
|
CasaStatus retStatus;
|
||||||
SSCS_SECRETSTORE_T ssId;
|
SSCS_SECRETSTORE_T ssId;
|
||||||
|
|
||||||
DbgTrace(1, "-InitializeAuthCache- Start\n", 0);
|
DbgTrace(1, "-InitializeAuthCache- Start\n", 0);
|
||||||
@ -586,21 +577,18 @@ InitializeAuthCache()
|
|||||||
ssId.version = NSSCS_VERSION_NUMBER;
|
ssId.version = NSSCS_VERSION_NUMBER;
|
||||||
strcpy((char *)ssId.ssName, (char *)SSCS_DEFAULT_SECRETSTORE_ID);
|
strcpy((char *)ssId.ssName, (char *)SSCS_DEFAULT_SECRETSTORE_ID);
|
||||||
|
|
||||||
g_hCASAContext = miCASAOpenSecretStoreCache(
|
g_hCASAContext = miCASAOpenSecretStoreCache(&ssId,
|
||||||
&ssId,
|
0,
|
||||||
0,
|
NULL);
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (!g_hCASAContext)
|
if (!g_hCASAContext)
|
||||||
{
|
{
|
||||||
retStatus = CasaStatusBuild(
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
||||||
CASA_SEVERITY_ERROR,
|
CASA_FACILITY_AUTHTOKEN,
|
||||||
CASA_FACILITY_AUTHTOKEN,
|
CASA_STATUS_UNSUCCESSFUL);
|
||||||
CASA_STATUS_UNSUCCESSFUL);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
retStatus = CASA_STATUS_SUCCESS;
|
retStatus = CASA_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
DbgTrace(1, "-InitializeAuthCache- End, retStatus = %08X\n", retStatus);
|
DbgTrace(1, "-InitializeAuthCache- End, retStatus = %08X\n", retStatus);
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
Name="VCLinkerTool"
|
Name="VCLinkerTool"
|
||||||
IgnoreImportLibrary="FALSE"
|
IgnoreImportLibrary="FALSE"
|
||||||
AdditionalOptions="/EXPORT:ObtainAuthToken"
|
AdditionalOptions="/EXPORT:ObtainAuthToken"
|
||||||
AdditionalDependencies="ws2_32.lib winhttp.lib libexpatml.lib micasa.lib"
|
AdditionalDependencies="ws2_32.lib winhttp.lib libexpatml.lib micasa.lib shlwapi.lib"
|
||||||
OutputFile="$(OutDir)/authtoken.dll"
|
OutputFile="$(OutDir)/authtoken.dll"
|
||||||
LinkIncremental="1"
|
LinkIncremental="1"
|
||||||
AdditionalLibraryDirectories=""\Program Files\Novell\CASA\lib";"..\..\..\..\Expat-2.0.0\StaticLibs""
|
AdditionalLibraryDirectories=""\Program Files\Novell\CASA\lib";"..\..\..\..\Expat-2.0.0\StaticLibs""
|
||||||
@ -93,7 +93,7 @@ copy $(SolutionDir)client\windows\authtoken.lib \"Program Files"\novel
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCLinkerTool"
|
Name="VCLinkerTool"
|
||||||
AdditionalOptions="/EXPORT:ObtainAuthToken"
|
AdditionalOptions="/EXPORT:ObtainAuthToken"
|
||||||
AdditionalDependencies="ws2_32.lib winhttp.lib libexpatml.lib micasa.lib"
|
AdditionalDependencies="ws2_32.lib winhttp.lib libexpatml.lib micasa.lib shlwapi.lib"
|
||||||
OutputFile="$(OutDir)/authtoken.dll"
|
OutputFile="$(OutDir)/authtoken.dll"
|
||||||
LinkIncremental="1"
|
LinkIncremental="1"
|
||||||
AdditionalLibraryDirectories=""\Program Files\Novell\CASA\lib";"..\..\..\Expat-2.0.0\StaticLibs""
|
AdditionalLibraryDirectories=""\Program Files\Novell\CASA\lib";"..\..\..\Expat-2.0.0\StaticLibs""
|
||||||
|
@ -664,7 +664,8 @@ GetConfigInterface(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DbgTrace(1, "-GetConfigInterface- Unable to open config file, errno = %d\n", errno);
|
DbgTrace(0, "-GetConfigInterface- Unable to open config file, errno = %d\n", errno);
|
||||||
|
DbgTrace(0, "-GetConfigInterface- Config file unable to open = %s\n", pFilePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -43,8 +43,8 @@ int DebugLevel = 0;
|
|||||||
//
|
//
|
||||||
// Operating parameter
|
// Operating parameter
|
||||||
//
|
//
|
||||||
bool secureRpcSetting = false;
|
bool secureRpcSetting = false;
|
||||||
bool g_bInitialized = FALSE;
|
bool g_bInitialized = FALSE;
|
||||||
|
|
||||||
//++=======================================================================
|
//++=======================================================================
|
||||||
static
|
static
|
||||||
@ -99,7 +99,7 @@ ObtainSessionToken(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Free the entry
|
// Free the entry
|
||||||
FreeAuthCacheEntry(pCacheEntry);
|
FreeAuthCacheEntry(pCacheEntry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -124,9 +124,9 @@ ObtainSessionToken(
|
|||||||
pCacheEntry = FindSessionTokenEntryInCache(pAuthContext->pContext);
|
pCacheEntry = FindSessionTokenEntryInCache(pAuthContext->pContext);
|
||||||
if (pCacheEntry == NULL)
|
if (pCacheEntry == NULL)
|
||||||
{
|
{
|
||||||
char *pReqMsg = NULL;
|
char *pReqMsg = NULL;
|
||||||
char *pRespMsg = NULL;
|
char *pRespMsg = NULL;
|
||||||
int respLen;
|
int respLen;
|
||||||
|
|
||||||
// Get authentication mechanism token
|
// Get authentication mechanism token
|
||||||
retStatus = GetAuthMechToken(pAuthContext, &pAuthMechToken);
|
retStatus = GetAuthMechToken(pAuthContext, &pAuthMechToken);
|
||||||
@ -140,82 +140,80 @@ ObtainSessionToken(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Authenticate to the ATS
|
// Authenticate to the ATS
|
||||||
pReqMsg = BuildAuthenticateMsg(pAuthContext, pAuthMechToken);
|
pReqMsg = BuildAuthenticateMsg(pAuthContext, pAuthMechToken);
|
||||||
if (pReqMsg)
|
if (pReqMsg)
|
||||||
{
|
{
|
||||||
// Issue rpc
|
// Issue rpc
|
||||||
retStatus = Rpc(pRpcSession,
|
retStatus = Rpc(pRpcSession,
|
||||||
"Authenticate",
|
"Authenticate",
|
||||||
secureRpcSetting,
|
secureRpcSetting,
|
||||||
pReqMsg,
|
pReqMsg,
|
||||||
&pRespMsg,
|
&pRespMsg,
|
||||||
&respLen);
|
&respLen);
|
||||||
if (CASA_SUCCESS(retStatus))
|
if (CASA_SUCCESS(retStatus))
|
||||||
{
|
{
|
||||||
AuthenticateResp *pAuthenticateResp;
|
AuthenticateResp *pAuthenticateResp;
|
||||||
|
|
||||||
// Create Authenticate response object
|
// Create Authenticate response object
|
||||||
retStatus = CreateAuthenticateResp(pRespMsg, respLen, &pAuthenticateResp);
|
retStatus = CreateAuthenticateResp(pRespMsg, respLen, &pAuthenticateResp);
|
||||||
if (CASA_SUCCESS(retStatus))
|
if (CASA_SUCCESS(retStatus))
|
||||||
{
|
{
|
||||||
// Return the auth token to the caller
|
// Return the auth token to the caller
|
||||||
pCacheEntry = CreateSessionTokenCacheEntry(
|
pCacheEntry = CreateSessionTokenCacheEntry(pAuthContext->pContext,
|
||||||
pAuthContext->pContext,
|
retStatus,
|
||||||
retStatus,
|
pAuthenticateResp->pToken,
|
||||||
pAuthenticateResp->pToken,
|
pAuthenticateResp->tokenLifetime);
|
||||||
pAuthenticateResp->tokenLifetime);
|
|
||||||
|
|
||||||
pAuthenticateResp->pToken = NULL; // To keep us from freeing the buffer
|
pAuthenticateResp->pToken = NULL; // To keep us from freeing the buffer
|
||||||
|
|
||||||
// Free the Authenticate response object
|
// Free the Authenticate response object
|
||||||
RelAuthenticateResp(pAuthenticateResp);
|
RelAuthenticateResp(pAuthenticateResp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DbgTrace(0, "-ObtainSessionToken- Authenticate Rpc failure, error = %08X\n", retStatus);
|
DbgTrace(0, "-ObtainSessionToken- Authenticate Rpc failure, error = %08X\n", retStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free resources that may be hanging around
|
// Free resources that may be hanging around
|
||||||
if (pRespMsg)
|
if (pRespMsg)
|
||||||
free(pRespMsg);
|
free(pRespMsg);
|
||||||
|
|
||||||
free(pReqMsg);
|
free(pReqMsg);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DbgTrace(0, "-ObtainSessionToken- Error building Authenticate msg\n", 0);
|
DbgTrace(0, "-ObtainSessionToken- Error building Authenticate msg\n", 0);
|
||||||
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
||||||
CASA_FACILITY_AUTHTOKEN,
|
CASA_FACILITY_AUTHTOKEN,
|
||||||
CASA_STATUS_INSUFFICIENT_RESOURCES);
|
CASA_STATUS_INSUFFICIENT_RESOURCES);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the entry to the cache if successful or if the reason that we failed
|
// Add the entry to the cache if successful or if the reason that we failed
|
||||||
// was because the server was unavailable.
|
// was because the server was unavailable.
|
||||||
if (CasaStatusCode(retStatus) == CASA_STATUS_AUTH_SERVER_UNAVAILABLE)
|
if (CasaStatusCode(retStatus) == CASA_STATUS_AUTH_SERVER_UNAVAILABLE)
|
||||||
{
|
{
|
||||||
pCacheEntry = CreateSessionTokenCacheEntry(
|
pCacheEntry = CreateSessionTokenCacheEntry(pAuthContext->pContext,
|
||||||
pAuthContext->pContext,
|
retStatus,
|
||||||
retStatus,
|
NULL,
|
||||||
NULL,
|
DEFAULT_RETRY_LIFETIME);
|
||||||
DEFAULT_RETRY_LIFETIME);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Release the cache entry if the resulting status is not successful
|
// Release the cache entry if the resulting status is not successful
|
||||||
if (!CASA_SUCCESS(retStatus))
|
if (!CASA_SUCCESS(retStatus))
|
||||||
{
|
{
|
||||||
FreeAuthCacheEntry(pCacheEntry);
|
FreeAuthCacheEntry(pCacheEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free up the buffer associated with the authentication mechanism token
|
// Free up the buffer associated with the authentication mechanism token
|
||||||
free(pAuthMechToken);
|
free(pAuthMechToken);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Free the entry
|
// Free the entry
|
||||||
FreeAuthCacheEntry(pCacheEntry);
|
FreeAuthCacheEntry(pCacheEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Advance to the next entry
|
// Advance to the next entry
|
||||||
@ -290,7 +288,7 @@ ObtainAuthTokenFromServer(
|
|||||||
char *pSessionToken = NULL;
|
char *pSessionToken = NULL;
|
||||||
|
|
||||||
// Request the auth parameters associated with this service
|
// Request the auth parameters associated with this service
|
||||||
pReqMsg = BuildGetAuthPolicyMsg(pServiceName, pHostName);
|
pReqMsg = BuildGetAuthPolicyMsg(pServiceName, "localhost"); // tbd - This will be changed in the future so that we can support services residing in a different host than the ATS
|
||||||
if (pReqMsg)
|
if (pReqMsg)
|
||||||
{
|
{
|
||||||
// Issue rpc
|
// Issue rpc
|
||||||
@ -318,7 +316,7 @@ ObtainAuthTokenFromServer(
|
|||||||
{
|
{
|
||||||
// Request auth token for the service
|
// Request auth token for the service
|
||||||
free(pReqMsg);
|
free(pReqMsg);
|
||||||
pReqMsg = BuildGetAuthTokenMsg(pServiceName, pHostName, pSessionToken);
|
pReqMsg = BuildGetAuthTokenMsg(pServiceName, "localhost", pSessionToken); // tbd - This will be changed in the future so that we can support services residing in a different host than the ATS
|
||||||
if (pReqMsg)
|
if (pReqMsg)
|
||||||
{
|
{
|
||||||
// Free the previous response msg buffer
|
// Free the previous response msg buffer
|
||||||
@ -473,7 +471,7 @@ ObtainAuthToken(
|
|||||||
CasaStatus retStatus = CASA_STATUS_SUCCESS;
|
CasaStatus retStatus = CASA_STATUS_SUCCESS;
|
||||||
AuthCacheEntry *pCacheEntry;
|
AuthCacheEntry *pCacheEntry;
|
||||||
char *pNormalizedHostName;
|
char *pNormalizedHostName;
|
||||||
unsigned char *pToken;
|
unsigned char *pToken;
|
||||||
HANDLE hUserMutex = NULL;
|
HANDLE hUserMutex = NULL;
|
||||||
|
|
||||||
|
|
||||||
@ -492,6 +490,10 @@ ObtainAuthToken(
|
|||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DbgTrace(1, "-ObtainAuthToken- ServiceName = %s\n", pServiceName);
|
||||||
|
DbgTrace(1, "-ObtainAuthToken- HostName = %s\n", pHostName);
|
||||||
|
DbgTrace(1, "-ObtainAuthToken- BufferLength = %d\n", *pAuthTokenBufLen);
|
||||||
|
|
||||||
// Make sure we are initialized
|
// Make sure we are initialized
|
||||||
// Obtain our synchronization mutex
|
// Obtain our synchronization mutex
|
||||||
AcquireInitializationMutex();
|
AcquireInitializationMutex();
|
||||||
@ -501,22 +503,22 @@ ObtainAuthToken(
|
|||||||
|
|
||||||
if (retStatus != CASA_STATUS_SUCCESS)
|
if (retStatus != CASA_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
DbgTrace(0, "-ObtainAuthToken- Error creating mutex for the user\n", 0);
|
DbgTrace(0, "-ObtainAuthToken- Error creating mutex for the user\n", 0);
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_bInitialized == FALSE)
|
if (g_bInitialized == FALSE)
|
||||||
{
|
{
|
||||||
retStatus = InitializeLibrary();
|
retStatus = InitializeLibrary();
|
||||||
|
|
||||||
if (retStatus == CASA_STATUS_SUCCESS)
|
if (retStatus == CASA_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
g_bInitialized = TRUE;
|
g_bInitialized = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Release our synchronization mutex
|
// Release our synchronization mutex
|
||||||
@ -533,37 +535,34 @@ ObtainAuthToken(
|
|||||||
pCacheEntry = FindAuthTokenEntryInCache(pServiceName, pNormalizedHostName);
|
pCacheEntry = FindAuthTokenEntryInCache(pServiceName, pNormalizedHostName);
|
||||||
if (pCacheEntry == NULL)
|
if (pCacheEntry == NULL)
|
||||||
{
|
{
|
||||||
// Initialize to retry in case of failure
|
// Initialize to retry in case of failure
|
||||||
int cacheEntryLifetime = DEFAULT_RETRY_LIFETIME;
|
int cacheEntryLifetime = DEFAULT_RETRY_LIFETIME;
|
||||||
|
|
||||||
// Cache entry created, now try to obtain auth token from the CASA Server
|
// Cache entry created, now try to obtain auth token from the CASA Server
|
||||||
retStatus = ObtainAuthTokenFromServer(pServiceName,
|
retStatus = ObtainAuthTokenFromServer(pServiceName,
|
||||||
pNormalizedHostName,
|
pNormalizedHostName,
|
||||||
&pToken,
|
&pToken,
|
||||||
&cacheEntryLifetime);
|
&cacheEntryLifetime);
|
||||||
|
|
||||||
// Add the entry to the cache if successful or if the reason that we failed
|
|
||||||
// was because the server was un-available.
|
|
||||||
if (CASA_SUCCESS(retStatus)
|
|
||||||
|| CasaStatusCode(retStatus) == CASA_STATUS_AUTH_SERVER_UNAVAILABLE)
|
|
||||||
{
|
|
||||||
pCacheEntry = CreateAuthTokenCacheEntry(
|
|
||||||
pServiceName,
|
|
||||||
pNormalizedHostName,
|
|
||||||
retStatus,
|
|
||||||
pToken,
|
|
||||||
cacheEntryLifetime);
|
|
||||||
|
|
||||||
if (pCacheEntry)
|
|
||||||
{
|
|
||||||
// Release the cache entry if the resulting status is not successful
|
|
||||||
if (!CASA_SUCCESS(retStatus))
|
|
||||||
{
|
|
||||||
FreeAuthCacheEntry(pCacheEntry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Add the entry to the cache if successful or if the reason that we failed
|
||||||
|
// was because the server was un-available.
|
||||||
|
if (CASA_SUCCESS(retStatus)
|
||||||
|
|| CasaStatusCode(retStatus) == CASA_STATUS_AUTH_SERVER_UNAVAILABLE)
|
||||||
|
{
|
||||||
|
pCacheEntry = CreateAuthTokenCacheEntry(pServiceName,
|
||||||
|
pNormalizedHostName,
|
||||||
|
retStatus,
|
||||||
|
pToken,
|
||||||
|
cacheEntryLifetime);
|
||||||
|
if (pCacheEntry)
|
||||||
|
{
|
||||||
|
// Release the cache entry if the resulting status is not successful
|
||||||
|
if (!CASA_SUCCESS(retStatus))
|
||||||
|
{
|
||||||
|
FreeAuthCacheEntry(pCacheEntry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -586,6 +585,7 @@ ObtainAuthToken(
|
|||||||
if (*pAuthTokenBufLen >= tokenLen)
|
if (*pAuthTokenBufLen >= tokenLen)
|
||||||
{
|
{
|
||||||
// Return the auth token to the caller
|
// Return the auth token to the caller
|
||||||
|
DbgTrace(0, "-ObtainAuthToken- Copying the token into the callers buffer\n", 0);
|
||||||
strcpy(pAuthTokenBuf, pCacheEntry->token);
|
strcpy(pAuthTokenBuf, pCacheEntry->token);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -620,7 +620,7 @@ exit:
|
|||||||
|
|
||||||
if (hUserMutex != NULL)
|
if (hUserMutex != NULL)
|
||||||
{
|
{
|
||||||
DestroyUserMutex(hUserMutex);
|
DestroyUserMutex(hUserMutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
DbgTrace(1, "-ObtainAuthToken- End, retStatus = %08X\n", retStatus);
|
DbgTrace(1, "-ObtainAuthToken- End, retStatus = %08X\n", retStatus);
|
||||||
@ -677,14 +677,11 @@ InitializeLibrary(void)
|
|||||||
|
|
||||||
// Initialize the host name normalization
|
// Initialize the host name normalization
|
||||||
retStatus = InitializeHostNameNormalization();
|
retStatus = InitializeHostNameNormalization();
|
||||||
|
|
||||||
|
|
||||||
if (CASA_SUCCESS(retStatus))
|
if (CASA_SUCCESS(retStatus))
|
||||||
{
|
{
|
||||||
retStatus = InitializeAuthCache();
|
retStatus = InitializeAuthCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DbgTrace(1, "-InitializeLibrary- End, retStatus = %08X\n", retStatus);
|
DbgTrace(1, "-InitializeLibrary- End, retStatus = %08X\n", retStatus);
|
||||||
|
|
||||||
return retStatus;
|
return retStatus;
|
||||||
|
Loading…
Reference in New Issue
Block a user