Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

370 lines
9.6 KiB

/* security/basic/pwcache.c -- Password Cache for Basic Authentication SPM. */
/* Jeff Hostetler, Spyglass, Inc., 1994. */
/* Copyright (C) 1994, Spyglass, Inc. All rights reserved. */
#include <win32.h>
#include <basic.h>
unsigned char gbEnableCache = TRUE;
//
// Hack for Lycos
//
#define XOR_MASK 0xAE
static unsigned char szLycosRealm[] = // realm name
{0xE3, 0xC7, 0xCD, 0xDC, 0xC1, 0xDD, 0xC1, 0xC8, 0xDA, 0xF1, 0xE2, 0xD7, 0xCD, 0xC1, 0xDD,
0xF1, 0xFF, 0xDB, 0xCB, 0xDC, 0xD7, 0xF1, 0xFD, 0xCB, 0xDC, 0xD8, 0xC7, 0xCD, 0xCB, 0 };
// "Microsoft_Lycos_Query_Service" masked with 0xAE
static unsigned char szLycosUserPass[] = // username:password
{0xD6, 0xC9, 0xD8, 0xCB, 0xD7, 0xC0, 0xC3, 0xD9, 0x94, 0xC1, 0xC6, 0xDC, 0xDF, 0xD4, 0xD4,
0xC2, 0xDE, 0 };
// "xgveynmw:ohrqzzlp" masked with 0xAE
//
// Decrypt a string by xor'ing with a constant
//
// On entry:
// pszString: pointer to string to be decrypted
//
// On exit:
// pszString: every character except the null terminator has been xor'ed with a constant
//
// Note:
// This encryption is only done so that finding the string in the .dll isn't trivial.
// The data will be sent plaintext over the wire, so there's no need to go crazy with
// and use real encryption.
//
static void DecryptString( unsigned char *pszString )
{
while ( *pszString ) {
*pszString ^= XOR_MASK;
pszString++;
}
}
//
// Decrypt Lycos related strings (does work only the first time it's called)
//
static void DecryptLycosStrings()
{
static BOOL bHaveDecrypted = FALSE;
if ( !bHaveDecrypted )
{
bHaveDecrypted = TRUE;
DecryptString( szLycosRealm );
DecryptString( szLycosUserPass );
}
}
/*****************************************************************/
static int pwci_TemplateMatch(unsigned char *template, unsigned char *filename)
{
/* code for this routine cloned from HTAA_templateMatch() */
unsigned char *p = template;
unsigned char *q = filename;
int m;
if (!template || !filename)
return 0;
for (; *p && *q && *p == *q; p++, q++) /* Find first mismatch */
; /* do nothing else */
if (!*p && !*q)
return 1; /* Equally long equal strings */
else if ('*' == *p)
{ /* Wildcard */
p++; /* Skip wildcard character */
m = strlen(q) - strlen(p); /* Amount to match to wildcard */
if (m < 0)
return 0; /* No match, filename too short */
else
{ /* Skip the matched characters and compare */
if (lstrcmp(p, q + m))
return 0; /* Tail mismatch */
else
return 1; /* Tail match */
}
} /* if wildcard */
else
return 0; /* Length or character mismatch */
}
/*****************************************************************/
static int pwci_MakeTemplate(F_UserInterface fpUI, void * pvOpaqueOS,
unsigned char ** pszTemplate, unsigned char *docname)
{
/* code for this routine cloned from HTAA_makeProtectionTemplate() */
unsigned char *template = NULL;
unsigned long k;
k = 0;
if (docname)
{
unsigned char *slash;
unsigned char *pchQuestion = strchr(docname, '?');
if ( pchQuestion )
*pchQuestion = '\0';
slash = strrchr(docname, '/');
if ( pchQuestion )
*pchQuestion = '?';
if (slash)
k = slash-docname+1;
}
template = spm_malloc(fpUI,pvOpaqueOS,k+2);
if (!template)
return 0;
if (k)
strncpy(template,docname,k);
template[k]='*';
template[k+1]=0;
*pszTemplate = template;
#ifdef DEBUG
{
unsigned char buf[1024];
sprintf(buf,"pwci_MakeTemplate: made template [%s] from [%s]",
template,docname);
(*fpUI)(pvOpaqueOS,UI_SERVICE_DEBUG_MESSAGE,buf,NULL);
}
#endif /* DEBUG */
return 1;
}
/*****************************************************************/
PWC * pwc_Create(F_UserInterface fpUI,
void * pvOpaqueOS)
{
return spm_calloc(fpUI,pvOpaqueOS,1,sizeof(PWC));
}
/*****************************************************************/
void pwc_Destroy(F_UserInterface fpUI,
void * pvOpaqueOS,
PWC * pwc)
{
/* Destroy cache */
PWCI * pwci_next;
PWCI * pwci;
if (pwc)
{
for (pwci=pwc->first; pwci; pwci=pwci_next)
{
pwci_next = pwci->next;
/* TODO: zeroize these strings before freeing them. */
if (pwci->szHost)
spm_free(fpUI,pvOpaqueOS,pwci->szHost);
if (pwci->szUriTemplate)
spm_free(fpUI,pvOpaqueOS,pwci->szUriTemplate);
if (pwci->szUserPass)
spm_free(fpUI,pvOpaqueOS,pwci->szUserPass);
if (pwci->szRealm)
spm_free(fpUI,pvOpaqueOS,pwci->szRealm);
spm_free(fpUI,pvOpaqueOS,pwci);
}
spm_free(fpUI,pvOpaqueOS,pwc);
}
return;
}
/*****************************************************************/
#if 0
/* DEADCODE -tr */
unsigned long pwc_CountCacheItems(PWC * pwc)
{
unsigned long k = 0;
PWCI * pwci;
if (pwc)
for (pwci=pwc->first; pwci; pwci=pwci->next)
k++;
return k;
}
#endif
/*****************************************************************/
unsigned char * pwc_Lookup(F_UserInterface fpUI,
void * pvOpaqueOS,
PWC * pwc,
unsigned char * szHost,
unsigned char * szUri,
unsigned char * szRealm)
{
PWCI * pwci;
if (!gbEnableCache) /* do nothing if Cache is Off */
return NULL;
/* upon cache-hit return "username:password" */
/* otherwise, return null */
/* Hack for Lycos */
DecryptLycosStrings();
/* Check for a NULL szRealm before compare cconner */
if ((szRealm) && (lstrcmpi(szLycosRealm,szRealm)==0)) /* realm must match magic lycos realm */
{
return szLycosUserPass;
}
if (!pwc || !pwc->first || !szHost || !szUri)
return NULL;
/* first we attempt the template match */
for (pwci=pwc->first; pwci; pwci=pwci->next)
{
/* note -- force DNS name to lower-case */
if ( (lstrcmpi(pwci->szHost,szHost)==0) /* if key 1 match */
&& (pwci_TemplateMatch(pwci->szUriTemplate,szUri))) /* and key 2 match */
{
#ifdef DEBUG
{
unsigned char buf[200];
sprintf(buf,"pwc_Lookup: Found template match [%s]",pwci->szUserPass);
(*fpUI)(pvOpaqueOS,UI_SERVICE_DEBUG_MESSAGE,buf,NULL);
}
#endif /* DEBUG */
return pwci->szUserPass;
}
}
/* second we see if host,realm can be found in cache
* (in case multiple uri trees are protected by same
* policy).
*/
if (szRealm && *szRealm)
{
for (pwci=pwc->first; pwci; pwci=pwci->next)
{
/* note -- force DNS name to lowercase,
and, what the hell, force Realm to lowercase
*/
if ( (lstrcmpi(pwci->szHost,szHost)==0) /* if key 1 match */
&& (lstrcmpi(pwci->szRealm,szRealm)==0)) /* and alternate key 2 match */
{
#ifdef DEBUG
{
unsigned char buf[200];
sprintf(buf,"pwc_Lookup: Found realm match [%s]",pwci->szUserPass);
(*fpUI)(pvOpaqueOS,UI_SERVICE_DEBUG_MESSAGE,buf,NULL);
}
#endif /* DEBUG */
return pwci->szUserPass;
}
}
}
return NULL;
}
/*****************************************************************/
void pwc_Store(F_UserInterface fpUI,
void * pvOpaqueOS,
PWC * pwc,
unsigned char * szHost,
unsigned char * szUri,
unsigned char * szUserPass,
unsigned char * szRealm)
{
unsigned long bResult;
PWCI * pwci;
if (!gbEnableCache) /* do nothing if Cache is Off */
return;
/* store "username:password" in password cache */
if (!pwc || !szHost || !szUri || !szUserPass)
return;
/* scan cache for matching key. if present, just update value.
* we have a unique cache entry for (host,template).
* we do not have a unique cache entry for (host,realm).
*/
for (pwci=pwc->first; pwci; pwci=pwci->next)
{
if ( (lstrcmpi(pwci->szHost,szHost)==0) /* if key 1 match */
&& (pwci_TemplateMatch(pwci->szUriTemplate,szUri))) /* and key 2 match */
{
#ifdef DEBUG
{
unsigned char buf[200];
sprintf(buf,"pwc_Store: Found template match [%s]",pwci->szUserPass);
(*fpUI)(pvOpaqueOS,UI_SERVICE_DEBUG_MESSAGE,buf,NULL);
}
#endif /* DEBUG */
/* replace cache value for this key */
bResult = spm_CloneString(fpUI,pvOpaqueOS,&pwci->szUserPass,szUserPass);
bResult = spm_CloneString(fpUI,pvOpaqueOS,&pwci->szRealm,szRealm);
return;
}
}
/* key not in cache. add item to cache. */
/* if out of memory, ignore item. */
pwci = spm_calloc(fpUI,pvOpaqueOS,1,sizeof(PWCI));
if ( pwci
&& spm_CloneString(fpUI,pvOpaqueOS,&pwci->szHost,szHost)
&& pwci_MakeTemplate(fpUI,pvOpaqueOS,&pwci->szUriTemplate,szUri)
&& spm_CloneString(fpUI,pvOpaqueOS,&pwci->szUserPass,szUserPass)
&& spm_CloneString(fpUI,pvOpaqueOS,&pwci->szRealm,szRealm))
{
pwci->next = pwc->first;
pwc->first = pwci;
return;
}
/* memory failure */
/* TODO zeroize these strings beforing freeing them. */
if (pwci)
{
if (pwci->szHost)
spm_free(fpUI,pvOpaqueOS,pwci->szHost);
if (pwci->szUriTemplate)
spm_free(fpUI,pvOpaqueOS,pwci->szUriTemplate);
if (pwci->szUserPass)
spm_free(fpUI,pvOpaqueOS,pwci->szUserPass);
if (pwci->szRealm)
spm_free(fpUI,pvOpaqueOS,pwci->szRealm);
spm_free(fpUI,pvOpaqueOS,pwci);
}
return;
}