V0.92 user_key logging gebaseerd uitgaande FCLT_USERID header

svn path=/FcltISAPI/trunk/; revision=20247
This commit is contained in:
Jos Groot Lipman
2013-12-20 22:19:26 +00:00
parent c073ade075
commit 772bdcecfc

View File

@@ -2,14 +2,50 @@
#include <httpfilt.h>
#include "tchar.h"
#include "strsafe.h"
#include "time.h"
#define FCLT_ISAPI_VERSION "0.91"
#define FCLT_ISAPI_VERSION "0.92"
// http://believeinmiraclesx.wordpress.com/2013/11/19/isapi-filter-set-httponly-for-mulitple-cookies/
// http://stackoverflow.com/questions/17649213/how-to-set-multiple-cookies-in-isapi-filter
#define bufferSize 4096 // increase size if using many cookies
#define fclt_userid_cookie "userid"
#define FCLT_USERID "FCLT_USERID:"
class CMyContext
{
public:
CMyContext(HTTP_FILTER_CONTEXT* pFC)
: startTime( clock() )
{
userid[0] = 0;
CHAR szCookie[2048];
DWORD cbCookie = sizeof(szCookie) / sizeof(szCookie[0]);
pFC->GetServerVariable(pFC, "SERVER_SOFTWARE", szCookie, &cbCookie);
ie_version = 6;
if (strstr(szCookie, "7.0"))
ie_version = 7;
}
clock_t GetStartTime()
{
return startTime;
}
void get_userid(HTTP_FILTER_CONTEXT* pFC, HTTP_FILTER_SEND_RESPONSE* pResponseInfo)
{
DWORD dwUserid = sizeof(userid) / sizeof(userid[0]);
pResponseInfo->GetHeader(pFC,FCLT_USERID,userid,&dwUserid);
}
private:
clock_t startTime;
public:
int ie_version;
CHAR userid[32];
};
DWORD OnPreprocHeaders (HTTP_FILTER_CONTEXT* pFC,
HTTP_FILTER_PREPROC_HEADERS* pHeaderInfo)
@@ -24,36 +60,27 @@ DWORD OnPreprocHeaders (HTTP_FILTER_CONTEXT* pFC,
DWORD OnSendResponse (HTTP_FILTER_CONTEXT* pFC,
HTTP_FILTER_SEND_RESPONSE* pResponseInfo)
{
CMyContext* pContext = (CMyContext *)pFC->pFilterContext;
// Hard coded cookie length (2k bytes)
CHAR szCookie[2048];
DWORD cbCookie = sizeof(szCookie) / sizeof(szCookie[0]);
CHAR *szHeader = "Set-Cookie:";
// Bij IE6 moeten we de cookies stuk voor stuk vervangen met SetHeader
// Bij IE7 moeten we de cookies wissen via eenmalig SetHeader en toevoegen met AddHeader
CHAR *szHeader = "Set-Cookie:";
CHAR *szHttpOnly = "; HttpOnly";
if (pResponseInfo->GetHeader(pFC,szHeader,szCookie,&cbCookie))
{
/* http://msdn.microsoft.com/en-us/library/ms972826 ondersteunt maar <20><>n cookie
if (SUCCEEDED(StringCchCat(szCookie,
cbCookieOriginal,
szHttpOnly)))
{
if (!pResponseInfo->SetHeader(pFC,
szHeader,
szCookie))
{ // Fail securely - send no cookie!
pResponseInfo->SetHeader(pFC,szHeader,"");
}
}
else
{
pResponseInfo->SetHeader(pFC,szHeader,"");
}*/
// http://msdn.microsoft.com/en-us/library/ms972826 ondersteunt maar <20><>n cookie
// Met meerdere cookies
// ASPFIXATION=UWVAnJAYKAozuKPNBuKpCIINamAJZqMwRhut; path=/Facilitor5iWork/,userid=33083; path=/Facilitor5iWork/
// maar pas op met:
// fcltidxxxx; expires=Sun, 16-Dec-2012 21:54:34 GMT; path=/Facilitor5iWork/
// Daar zit wel een komma in maar toch is het maar <20><>n cookie
//pResponseInfo->SetHeader(pFC,szHeader,""); // alle standaard cookies wissen? Waarom?
if (pContext->ie_version == 7)
pResponseInfo->SetHeader(pFC,szHeader,""); // alle standaard cookies wissen
CHAR outCookie[2048];
DWORD cboutCookie = sizeof(outCookie) / sizeof(outCookie[0]);
char * token;
@@ -83,13 +110,19 @@ DWORD OnSendResponse (HTTP_FILTER_CONTEXT* pFC,
strcat_s (outCookie, cboutCookie, "; HttpOnly");
}
pResponseInfo->SetHeader(pFC, szHeader, outCookie); // 1-voor-1 terug
if (pContext->ie_version == 6)
pResponseInfo->SetHeader(pFC, szHeader, outCookie); // 1-voor-1 vervangen
else // ie7
pResponseInfo->AddHeader(pFC, szHeader, outCookie); // 1-voor-1 terug
memset(outCookie, 0, cboutCookie);
token = strtok_s (NULL, ",", &next_token);
}
}
pContext->get_userid(pFC, pResponseInfo);
pResponseInfo->SetHeader(pFC, FCLT_USERID, '\0'); // Niet meer nodig nu
// Altijd Server: Microsoft-IIS/6.0 verwijderen
pResponseInfo->SetHeader(pFC, "Server:", "FACILITOR");
@@ -101,43 +134,14 @@ DWORD OnSendResponse (HTTP_FILTER_CONTEXT* pFC,
return SF_STATUS_REQ_NEXT_NOTIFICATION;
}
char *getUserName(char buffer[])
{
char seps[] = ";= "; //cookies are separated by ; values by = then ignore spaces
char *token;
char *next_token = NULL;
token = strtok_s ( buffer, seps, &next_token );
while( token != NULL ){
/* While there are tokens in "buffer" */
if (!strcmp(token, fclt_userid_cookie))
{
token = strtok_s ( NULL, seps, &next_token );
if (strlen(token) < 32)
return token;
else
return "too_long_userid_cookie"; // safety
}
token = strtok_s( NULL, seps, &next_token );
}
return "-\0"; //this is the Anonymous user in the logfiles a "dash"
}
// Onderschept binnenkomende cookies en zoekt naar userid voor de logging
// Onderschept binnenkomende cookies en gebruikt eerder opgeslagen userid voor de logging
DWORD OnLog(HTTP_FILTER_CONTEXT* pFC, PHTTP_FILTER_LOG pLog)
{
char szBuffer[bufferSize-1] = "\0"; //NULL;
DWORD dwSize = bufferSize;
// Het was gemakkelijker geweest als we hier de uitgaande headers
// konden uitlezen naar helaas
// if (pResponseInfo->GetHeader(pFC,"FCLT_USER_ID:",szCookie,&cbCookie))
// Misschien uitlezen in OnSendResponse en dan bewaren (AllocMem)
// in HTTP_FILTER_CONTEXT::pFilterContext?
pFC->GetServerVariable(pFC, "HTTP_COOKIE", szBuffer, &dwSize);
if (strlen (szBuffer) > 0){
pLog->pszClientUserName = getUserName(szBuffer);
// OnSendResponse heeft de userid voor ons bewaard
CMyContext* pContext = (CMyContext *)pFC->pFilterContext;
if (pContext->userid[0])
{
pLog->pszClientUserName = pContext->userid;
}
return SF_STATUS_REQ_NEXT_NOTIFICATION;
@@ -148,13 +152,14 @@ BOOL WINAPI GetFilterVersion(
)
{
pVer->dwFilterVersion = HTTP_FILTER_REVISION;
strncpy_s( pVer->lpszFilterDesc, "HTTPOnlyFilter", SF_MAX_FILTER_DESC_LEN );
strncpy_s( pVer->lpszFilterDesc, "FACILITOR ISAPI Filter", SF_MAX_FILTER_DESC_LEN );
/* Notify me when headers have been processed */
pVer->dwFlags = SF_NOTIFY_ORDER_DEFAULT |
SF_NOTIFY_PREPROC_HEADERS | // Om version toe te voegen
SF_NOTIFY_SEND_RESPONSE | // Om cookies te manipuleren
SF_NOTIFY_LOG; // Om userid te loggen
SF_NOTIFY_LOG | // Om userid te loggen
SF_NOTIFY_END_OF_REQUEST; // Om geheugen vrij te geven
return TRUE;
};
@@ -164,19 +169,34 @@ DWORD WINAPI HttpFilterProc(
DWORD dwNotificationType,
LPVOID pvData) {
DWORD dwRet;
DWORD dwRet = SF_STATUS_REQ_NEXT_NOTIFICATION;
switch (dwNotificationType)
CMyContext* pContext = NULL;
switch (dwNotificationType)
{
case SF_NOTIFY_PREPROC_HEADERS:
{
// AllocMem wordt vanzelf opgeruimd aan einde sessie
CMyContext pContext(pFC);
pFC->pFilterContext = pFC->AllocMem(pFC, sizeof(CMyContext), 0);
memcpy(pFC->pFilterContext, &pContext, sizeof(CMyContext));
dwRet = OnPreprocHeaders( pFC, (PHTTP_FILTER_PREPROC_HEADERS) pvData );
break;
}
case SF_NOTIFY_SEND_RESPONSE:
dwRet = OnSendResponse( pFC, (PHTTP_FILTER_SEND_RESPONSE) pvData );
break;
case SF_NOTIFY_LOG:
dwRet = OnLog( pFC, (PHTTP_FILTER_LOG) pvData );
break;
case SF_NOTIFY_END_OF_REQUEST:
// time = clock() - pContext->GetStartTime();
//
// pContext wordt vanzelf opgeruimd
//
break;
default:
dwRet = SF_STATUS_REQ_NEXT_NOTIFICATION;
break;