📄 casisapi.cpp
字号:
VARIANT vFalse;
VARIANT vMissing;
BSTR bResp;
size_t alloclen;
STACK_ALLOC_HEADER("URL",pURL);
if (pURL == NULL) {return SF_STATUS_REQ_ERROR;}
if (pExcludeFromStartOfURL && !strnicmp(pURL,pExcludeFromStartOfURL,strlen(pExcludeFromStartOfURL)))
pURL += strlen(pExcludeFromStartOfURL);
*(strstr(pURL,"?")) = '&';
alloclen = strlen(pValidateURL)+strlen(pAppParamName)+strlen(pAppCode)+strlen(pServiceParamName)+strlen(pHTTPS)+ strlen(pServerName)+strlen(pServerPort)+strlen(pURL)+13;
pValidateQuery = (char*)_alloca(alloclen);
if (pValidateQuery == NULL) {return SF_STATUS_REQ_ERROR;}
safestrcpy(pValidateQuery,pValidateURL,alloclen);
safestrcat(pValidateQuery,"?",alloclen);
safestrcat(pValidateQuery,pAppParamName,alloclen);
safestrcat(pValidateQuery,"=",alloclen);
safestrcat(pValidateQuery,pAppCode,alloclen);
safestrcat(pValidateQuery,"&",alloclen);
safestrcat(pValidateQuery,pServiceParamName,alloclen);
safestrcat(pValidateQuery,"=http",alloclen);
safestrcat(pValidateQuery,pHTTPS,alloclen);
safestrcat(pValidateQuery,"://",alloclen);
safestrcat(pValidateQuery,pServerName,alloclen);
if (pServerPort[0] != '\0')
{
safestrcat(pValidateQuery,":",alloclen);
safestrcat(pValidateQuery,pServerPort,alloclen);
}
safestrcat(pValidateQuery,pURL,alloclen);
len = strlen(pValidateQuery)*2+2;
pWBuf = (wchar_t*)_alloca((DWORD)len);
mbstowcs(pWBuf,pValidateQuery,len);
hr = CoCreateInstance(CLSID_ServerXMLHTTP40,NULL,CLSCTX_INPROC_SERVER,IID_IServerXMLHTTPRequest,(LPVOID*)&pRequest);
if (FAILED(hr)) {return SF_STATUS_REQ_ERROR;}
if (NULL == (bMethod=SysAllocString(L"GET")))
{
pRequest->Release();
return SF_STATUS_REQ_ERROR;
}
if (NULL == (bUrl=SysAllocString(pWBuf)))
{
pRequest->Release();
return SF_STATUS_REQ_ERROR;
}
vFalse.vt = VT_BOOL;
vFalse.boolVal = false;
vMissing.lVal = DISP_E_PARAMNOTFOUND;
vMissing.vt = VT_ERROR;
hr = pRequest->setTimeouts(resolveTimeout,connectTimeout,sendTimeout,receiveTimeout);
if (FAILED(hr))
{
pRequest->Release();
return SF_STATUS_REQ_ERROR;
}
hr = pRequest->open(bMethod,bUrl,vFalse,vMissing,vMissing);
if (FAILED(hr))
{
pRequest->Release();
return SF_STATUS_REQ_ERROR;
}
SysFreeString(bMethod);
SysFreeString(bUrl);
hr = pRequest->send(vMissing);
if (FAILED(hr))
{
pRequest->Release();
return SF_STATUS_REQ_ERROR;
}
hr = pRequest->get_responseText(&bResp);
if (FAILED(hr))
{
pRequest->Release();
return SF_STATUS_REQ_ERROR;
}
hr = pRequest->Release();
if (FAILED(hr)) {return SF_STATUS_REQ_ERROR;}
if (!wcsncmp(bResp,L"yes",3))
{
len = wcslen(bResp) + strlen(pRemoteAddr) + sizeof(long) + 3;
pCookie = (char*)_alloca(len);
wcstombs(pCookie,&bResp[bResp[4]==0x000a?5:4],len);
SysFreeString(bResp);
if (pCookie[strlen(pCookie)-1] == '\n') {pCookie[strlen(pCookie)-1] = '\0';}
if (pCookie[strlen(pCookie)-1] == '\r') {pCookie[strlen(pCookie)-1] = '\0';}
ReportValidation(pURL,pCookie);
time(&timer);
safestrcat(pCookie,"|",len);
safestrcat(pCookie,pRemoteAddr,len);
safestrcat(pCookie,"|",len);
hexEncode((BYTE*)&timer,sizeof(long),&pCookie[strlen(pCookie)]);
char *assign = "Set-Cookie: UITSAUTH=";
char *secure = "; secure\n";
size_t assignLen = strlen(assign);
size_t secureLen = strlen(secure);
size_t alloclen;
DWORD encryptionLen = encryptLength(pCookie);
alloclen = assignLen+(encryptionLen*2)+secureLen+2;
char *buf = (char*)_alloca(alloclen);
safestrcpy(buf,assign,alloclen);
safestrcat(buf,pCookie,alloclen);
if (encryptCookie(&buf[assignLen],encryptionLen))
{
safestrcat(buf,(bSecure)?secure:"\n",alloclen);
(*pCtxt->AddResponseHeaders)(pCtxt,buf,0);
*(strstr(pCookie,"|")) = '\0';
if (!(*pParms->SetHeader)(pCtxt,"user:",pCookie)) {dwLastError = GetLastError();}
authOkay = true;
}
}
}
if (!authOkay)
{
char* pCallbackURL;
char* pHeaders;
size_t alloclen;
if (bSecure && (*pHTTPS == '\0'))
{
char *pHeaders;
DWORD writeLen;
const char* pBoilerplate3 = "<html><body><h3>CAS Authentication Requires SSL</h3>\r\n</body></html>";
size_t alloclen = strlen(pHeaders1)+strlen(pHeaders2)+1;
pHeaders = (char*)_alloca(alloclen);
safestrcpy(pHeaders,pHeaders1,alloclen);
safestrcat(pHeaders,pHeaders2,alloclen);
pCtxt->AddResponseHeaders(pCtxt,pHeaders,0);
pCtxt->ServerSupportFunction(pCtxt,SF_REQ_SEND_RESPONSE_HEADER,
"200 OKAY",NULL,NULL);
writeLen = (DWORD)strlen(pBoilerplate3);
pCtxt->WriteClient(pCtxt,(LPVOID)pBoilerplate3,&writeLen,NULL);
return SF_STATUS_REQ_FINISHED;
}
STACK_ALLOC_HEADER("URL",pCallbackURL);
if (NULL == pCallbackURL)
return SF_STATUS_REQ_ERROR;
STACK_ALLOC_SERVER_VARIABLE("SERVER_PROTOCOL",pServerProtocol)
if (NULL == pServerProtocol)
return SF_STATUS_REQ_ERROR;
STACK_ALLOC_SERVER_VARIABLE("REQUEST_METHOD",pRequestMethod)
if (NULL == pRequestMethod)
return SF_STATUS_REQ_ERROR;
if (pExcludeFromStartOfURL && !strnicmp(pCallbackURL,pExcludeFromStartOfURL,strlen(pExcludeFromStartOfURL)))
pCallbackURL += strlen(pExcludeFromStartOfURL);
char *pBeginTicketParam;
//if pTicketParamSearchValue is already part of the URL
if (NULL != (pBeginTicketParam=strstr(pCallbackURL,pTicketParamSearchValue)))
{
char *s;
for (s=pBeginTicketParam; *s && (*s != '&'); s++) ;
if (*s == '&')
{
char *t;
for (t=pBeginTicketParam,++s; *t=*s; s++,t++) ;
}
else
pBeginTicketParam[-1] = '\0';
}
alloclen = strlen(pHeaders1a)+strlen(pLoginURL)+strlen(pAppParamName)+strlen(pAppCode)+strlen(pServiceParamName)+strlen(pHTTPS)+ strlen(pServerName)+1+strlen(pServerPort)+strlen(pCallbackURL)+17;
pHeaders = (char*)_alloca(alloclen);
safestrcpy(pHeaders,pHeaders1a,alloclen);
safestrcat(pHeaders,pLoginURL,alloclen);
safestrcat(pHeaders,"?",alloclen);
safestrcat(pHeaders,pAppParamName,alloclen);
safestrcat(pHeaders,"=",alloclen);
safestrcat(pHeaders,pAppCode,alloclen);
safestrcat(pHeaders,"&",alloclen);
safestrcat(pHeaders,pServiceParamName,alloclen);
safestrcat(pHeaders,"=http",alloclen);
safestrcat(pHeaders,pHTTPS,alloclen);
safestrcat(pHeaders,"://",alloclen);
safestrcat(pHeaders,pServerName,alloclen);
if (pServerPort[0] != '\0')
{
safestrcat(pHeaders,":",alloclen);
safestrcat(pHeaders,pServerPort,alloclen);
}
safestrcat(pHeaders,pCallbackURL,alloclen);
safestrcat(pHeaders,"\r\n\r\n",alloclen);
pCtxt->AddResponseHeaders(pCtxt,pHeaders,0);
pCtxt->ServerSupportFunction(pCtxt,SF_REQ_SEND_RESPONSE_HEADER,
(!stricmp(pRequestMethod,"POST") && !stricmp(pServerProtocol,"HTTP/1.1"))
? "307" : "302",
NULL,NULL);
ReportRedirect(pCallbackURL);
return SF_STATUS_REQ_FINISHED_KEEP_CONN;
}
}
}
return SF_STATUS_REQ_NEXT_NOTIFICATION;
}
static char* safestrcat(char* to,const char* from,size_t len)
{
if (strlen(to)+strlen(from) < len)
return strcat(to,from);
return NULL;
}
static char* safestrcpy(char* to,const char* from,size_t len)
{
if (strlen(from) < len)
return strcpy(to,from);
return NULL;
}
static int str2int(char* instr)
{
int val = 0;
for (; instr && *instr != '\0'; instr++)
{
val *= 10;
if ((*instr >= '0') && (*instr <= '9')) {
val += *instr - '0';
}
else {
return val;
}
}
return val;
}
static long str2long(char* instr)
{
long val = 0;
for (; instr && *instr != '\0'; instr++)
{
val *= 10;
if ((*instr >= '0') && (*instr <= '9')) {
val += *instr - '0';
}
else {
return val;
}
}
return val;
}
static void hexEncode(BYTE* inBytes,DWORD len,char* outBuf)
{
for (int i=0; i<(int)len; i++)
{
outBuf[i*2] = ((inBytes[i]/16) < 10) ? '0' + (inBytes[i]/16) : 'A' + (inBytes[i]/16) - 10;
outBuf[i*2+1] = ((inBytes[i]%16) < 10) ? '0' + (inBytes[i]%16) : 'A' + (inBytes[i]%16) - 10;
}
outBuf[len*2] = '\0';
}
static void hexEncodeInPlace(BYTE* inBytes,DWORD len)
{
size_t alloclen = len*2+1;
char *outBuf = (char*)_alloca(alloclen);
for (int i=0; i<(int)len; i++)
{
outBuf[i*2] = ((inBytes[i]/16) < 10) ? '0' + (inBytes[i]/16) : 'A' + (inBytes[i]/16) - 10;
outBuf[i*2+1] = ((inBytes[i]%16) < 10) ? '0' + (inBytes[i]%16) : 'A' + (inBytes[i]%16) - 10;
}
outBuf[len*2] = '\0';
safestrcpy((char*)inBytes,outBuf,alloclen);
}
static void hexDecode(char* inBuf,BYTE* outBuf)
{
int i;
for (i=0; i<(int)strlen(inBuf); i+=2)
{
outBuf[i/2] = ((inBuf[i] >= '0') && (inBuf[i] <= '9')) ? inBuf[i]-'0' : inBuf[i]-'A' + 10;
outBuf[i/2] *= 16;
outBuf[i/2] += ((inBuf[i+1] >= '0') && (inBuf[i+1] <= '9')) ? inBuf[i+1]-'0' : inBuf[i+1]-'A' + 10;
}
}
static bool InitEncryption()
{
HCRYPTHASH hHash;
if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,0))
if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,CRYPT_NEWKEYSET)) {return false;}
if (!CryptCreateHash(hProv,CALG_MD5,0,0,&hHash)) {return false;}
if (!CryptHashData(hHash,(BYTE *)pEncryptionPassword,(DWORD)strlen(pEncryptionPassword),0)) {return false;}
if (!CryptDeriveKey(hProv,CALG_RC2,hHash,CRYPT_EXPORTABLE,&hKey)) {return false;}
if (hHash) {CryptDestroyHash(hHash);}
return true;
}
static DWORD encryptLength(char* pPlainText)
{
DWORD dwCount = (DWORD)strlen(pPlainText) + 1;
// Get the length of the buffer we need
if (!CryptEncrypt(hKey, 0, true, 0, NULL, &dwCount,0)) {return 0;}
return dwCount;
}
static bool encryptCookie(char* pPlainText,DWORD encryptLen)
{
// Get the handle to the default provider.
DWORD dwCount = (DWORD)strlen(pPlainText) + 1;
DWORD dwBufLen = encryptLen;
// Encrypt the data.
if (!CryptEncrypt(hKey,0,true,0,(BYTE*)pPlainText,&dwCount,dwBufLen)) {return false;}
hexEncodeInPlace((BYTE*)pPlainText,dwCount);
return true;
}
static char* decryptCookie(char* pCypherText)
{
size_t alloclen = strlen(pCypherText);
DWORD dwLength = (DWORD)alloclen/2;
BYTE *pEncrypt = (BYTE*)_alloca(dwLength);
hexDecode(pCypherText,pEncrypt);
if (!CryptDecrypt(hKey,0,true,0,pEncrypt,&dwLength)) {return NULL;}
safestrcpy(pCypherText,(char*)pEncrypt,alloclen);
return pCypherText;
}
static bool AddEventSource()
{
HKEY hk;
DWORD dwData;
const char* keystr = "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\CasIsapi";
const char* dllfilespec = "%SystemRoot%\\system32\\inetsrv\\CasIsapi.dll";
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,keystr,0,KEY_READ,&hk) == ERROR_SUCCESS)
{
RegCloseKey(hk);
return true;
}
if (RegCreateKey(HKEY_LOCAL_MACHINE,keystr,&hk))
{
return false;
}
if (RegSetValueEx(hk,"EventMessageFile",0,REG_EXPAND_SZ,(const BYTE *)dllfilespec,(DWORD)strlen(dllfilespec) + 1))
{
RegCloseKey(hk);
return false;
}
dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_INFORMATION_TYPE;
if (RegSetValueEx(hk,"TypesSupported",0,REG_DWORD,(LPBYTE)&dwData,sizeof(DWORD)))
{
RegCloseKey(hk);
return false;
}
RegCloseKey(hk);
return true;
}
static void ReportInitError(char* szMsg)
{
HANDLE h;
char *ppszMsg[1];
ppszMsg[0] = szMsg;
h = RegisterEventSource(NULL,"CasIsapi");
if (h == NULL) return;
if (!ReportEvent(h,EVENTLOG_ERROR_TYPE,0,INIT_ERROR,NULL,1,0,(const char**)ppszMsg,NULL))
return;
DeregisterEventSource(h);
}
static void ReportInitSuccess()
{
HANDLE h;
h = RegisterEventSource(NULL,"CasIsapi");
if (h == NULL) return;
if (!ReportEvent(h,EVENTLOG_INFORMATION_TYPE,0,INIT_SUCCESS,NULL,0,0,NULL,NULL))
return;
DeregisterEventSource(h);
}
static void ReportRedirect(char* szMsg)
{
HANDLE h;
char *ppszMsg[1];
ppszMsg[0] = szMsg;
h = RegisterEventSource(NULL,"CasIsapi");
if (h == NULL) return;
if (!ReportEvent(h,EVENTLOG_INFORMATION_TYPE,0,REDIRECT_TO_LOGIN_SERVER,NULL,1,0,(const char**)ppszMsg,NULL))
return;
DeregisterEventSource(h);
}
static void ReportValidation(char* szMsg1,char* szMsg2)
{
HANDLE h;
char *ppszMsg[2];
ppszMsg[0] = szMsg1;
ppszMsg[1] = szMsg2;
h = RegisterEventSource(NULL,"CasIsapi");
if (h == NULL) return;
if (!ReportEvent(h,EVENTLOG_INFORMATION_TYPE,0,VALIDATION_FROM_LOGIN_SERVER,NULL,2,0,(const char**)ppszMsg,NULL))
return;
DeregisterEventSource(h);
}
static void ReportCookieAuthentication(char* szMsg1,char* szMsg2)
{
HANDLE h;
char *ppszMsg[2];
ppszMsg[0] = szMsg1;
ppszMsg[1] = szMsg2;
h = RegisterEventSource(NULL,"CasIsapi");
if (h == NULL) return;
if (!ReportEvent(h,EVENTLOG_INFORMATION_TYPE,0,AUTHENTICATION_THROUGH_COOKIE,NULL,2,0,(const char**)ppszMsg,NULL))
return;
DeregisterEventSource(h);
}
static void ReportApplyDecision(char* szMsg1,char* szMsg2,char* szMsg3)
{
HANDLE h;
char *ppszMsg[3];
ppszMsg[0] = szMsg1;
ppszMsg[1] = szMsg2;
ppszMsg[2] = szMsg3;
h = RegisterEventSource(NULL,"CasIsapi");
if (h == NULL) return;
if (!ReportEvent(h,EVENTLOG_INFORMATION_TYPE,0,ECHO_PATH_TRANSLATED,NULL,3,0,(const char**)ppszMsg,NULL))
return;
DeregisterEventSource(h);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -