📄 sspi_workbench.cpp
字号:
L"Replay_detect",
L"Sequence_detect",
L"Confidentiality",
L"Use_session_key",
L"Used_collected_creds",
L"Used_supplied_creds",
L"Allocated_memory",
L"Used_dce_style",
L"Datagram",
L"Connection",
L"Intermediate_return",
L"Call_level",
L"Extended_error",
L"Stream",
L"Integrity",
L"Identify",
L"Null_session",
L"Manual_cred_validation",
L"Reserved1",
L"Fragment_only",
};
const HWND hwndList = GetDlgItem(s_hwnd, IDC_CTX_ATTRS);
ComboBox_ResetContent(hwndList);
for (int i = 0; i < sizeof rgdesc / sizeof *rgdesc; ++i) {
if (s_grfCtxAttrs & (1 << i))
ComboBox_AddString(hwndList, rgdesc[i]);
}
ComboBox_SetCurSel(hwndList, 0);
}
void _persistCheckboxState(const wchar_t* pszINISection, const wchar_t* pszKey, int nControlID, bool bSave) {
if (bSave) {
WritePrivateProfileString(pszINISection, pszKey, (BST_CHECKED == Button_GetCheck(GetDlgItem(s_hwnd, nControlID))) ? L"1" : L"0", _getINIPath());
}
else {
wchar_t sz[10];
GetPrivateProfileString(pszINISection, pszKey, L"0", sz, sizeof sz / sizeof *sz, _getINIPath());
Button_SetCheck(GetDlgItem(s_hwnd, nControlID), _wtoi(sz) ? BST_CHECKED : BST_UNCHECKED);
}
}
AppStates _initSecurityCtx(bool bFirstTime = false) {
DWORD grfCtxRequirements = 0;
if (BST_CHECKED == Button_GetCheck(GetDlgItem(s_hwnd, IDC_MUTUAL_AUTHN)))
grfCtxRequirements |= ISC_REQ_MUTUAL_AUTH;
if (BST_CHECKED == Button_GetCheck(GetDlgItem(s_hwnd, IDC_DELEGATE)))
grfCtxRequirements |= ISC_REQ_DELEGATE;
if (BST_CHECKED == Button_GetCheck(GetDlgItem(s_hwnd, IDC_PROMPT_FOR_CREDS)))
grfCtxRequirements |= ISC_REQ_PROMPT_FOR_CREDS;
if (bFirstTime)
s_pModel->chooseContextRequirements(grfCtxRequirements);
wchar_t szSPN[256];
GetDlgItemText(s_hwnd, IDC_SPN, szSPN, sizeof szSPN / sizeof *szSPN);
void* pOutput;
DWORD cbOutput;
bool bContinueNeeded;
ULONG grfCtxAttrs;
if (bFirstTime) {
s_pModel->initializeSecurityContext(szSPN,
0, 0,
&pOutput, &cbOutput,
&bContinueNeeded, &grfCtxAttrs);
}
else {
s_pModel->initializeSecurityContext(szSPN,
s_msgBuf, s_cbMsgBuf,
&pOutput, &cbOutput,
&bContinueNeeded, &grfCtxAttrs);
}
_ASSERT(cbOutput < sizeof s_msgBuf);
WritePrivateProfileString(s_pszINISectionClient, L"server_principal_name", szSPN, _getINIPath());
_persistCheckboxState(s_pszINISectionClient, L"ctx_req_mutual", IDC_MUTUAL_AUTHN, true);
_persistCheckboxState(s_pszINISectionClient, L"ctx_req_delegate", IDC_DELEGATE, true);
_persistCheckboxState(s_pszINISectionClient, L"ctx_req_prompt", IDC_PROMPT_FOR_CREDS, true);
s_grfCtxAttrs = grfCtxAttrs;
_updateCtxAttrsViewer();
AppStates nextState;
if (pOutput) {
CopyMemory(s_msgBuf, pOutput, s_cbMsgBuf = cbOutput);
free(pOutput);
nextState = bContinueNeeded ? asNotDoneNeedTx : asDoneNeedTx;
}
else {
s_cbMsgBuf = 0;
nextState = asAuthComplete;
}
return nextState;
}
AppStates _acceptSecurityCtx() {
void* pOutput;
DWORD cbOutput;
bool bContinueNeeded;
ULONG grfCtxAttrs;
s_pModel->acceptSecurityContext(s_msgBuf, s_cbMsgBuf,
&pOutput, &cbOutput,
&bContinueNeeded, &grfCtxAttrs);
_ASSERT(cbOutput < sizeof s_msgBuf);
s_grfCtxAttrs = grfCtxAttrs;
if (!bContinueNeeded)
_updateCtxAttrsViewer();
AppStates nextState;
if (pOutput) {
CopyMemory(s_msgBuf, pOutput, s_cbMsgBuf = cbOutput);
free(pOutput);
nextState = bContinueNeeded ? asNotDoneNeedTx : asDoneNeedTx;
}
else {
s_cbMsgBuf = 0;
nextState = asAuthComplete;
}
return nextState;
}
bool _disp(MSG& msg) {
if (IsDialogMessage(s_hwnd, &msg)) {
if (WM_USER == msg.message)
return false;
}
else {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return true;
}
Transport* _getTransport() {
if (!s_pTx) {
BOOL bTranslated;
const WORD port = static_cast<WORD>(GetDlgItemInt(s_hwnd, IDC_HOST_PORT, &bTranslated, FALSE));
if (!bTranslated) {
MessageBox(s_hwnd, L"Please enter a valid port", s_pszAppName, MB_SETFOREGROUND | MB_ICONINFORMATION);
SetFocus(GetDlgItem(s_hwnd, IDC_HOST_PORT));
return false;
}
// create a transport object
if (s_bServer) {
ServerTransport* pServerTx = new ServerTransport(port, _err, _disp);
if (pServerTx->listenAndAcceptSingleConnection())
s_pTx = pServerTx;
{
wchar_t sz[20];
GetDlgItemText(s_hwnd, IDC_HOST_PORT, sz, sizeof sz / sizeof *sz);
WritePrivateProfileString(s_pszINISectionServer, L"host_port", sz, _getINIPath());
}
}
else {
char addr[40];
if (!GetDlgItemTextA(s_hwnd, IDC_HOST_ADDR, addr, sizeof addr / sizeof *addr))
return false;
ClientTransport* pClientTx = new ClientTransport(_err, _disp);
if (pClientTx->connect(addr, port))
s_pTx = pClientTx;
{
wchar_t sz[20];
GetDlgItemText(s_hwnd, IDC_HOST_ADDR, sz, sizeof sz / sizeof *sz);
WritePrivateProfileString(s_pszINISectionClient, L"host_addr", sz, _getINIPath());
GetDlgItemText(s_hwnd, IDC_HOST_PORT, sz, sizeof sz / sizeof *sz);
WritePrivateProfileString(s_pszINISectionClient, L"host_port", sz, _getINIPath());
}
}
}
if (s_pTx)
_activateControlGroup(uicgHostInfo, false);
return s_pTx;
}
wchar_t* _prettyPrintLine(wchar_t* psz, const BYTE* pbuf, int cb) {
const BYTE* p = pbuf;
for (int i = 0; i < 8; ++i) {
if (i < cb) {
wsprintf(psz, L"%02X ", *p);
psz += 3;
++p;
}
else {
*psz++ = L' ';
*psz++ = L' ';
*psz++ = L' ';
}
}
*psz++ = L' ';
for (; i < 16; ++i) {
if (i < cb) {
wsprintf(psz, L"%02X ", *p);
psz += 3;
++p;
}
else {
*psz++ = L' ';
*psz++ = L' ';
*psz++ = L' ';
}
}
*psz++ = L' ';
p = pbuf;
for (i = 0; i < cb; ++i) {
if (isprint(*p))
wsprintf(psz, L"%c", *p);
else *psz = L'.';
++psz;
++p;
if (15 == i)
break;
}
*psz++ = L'\r';
*psz++ = L'\n';
return psz;
}
wchar_t* _prettyPrint(const BYTE* pbuf, DWORD cb) {
_ASSERT(cb);
// 1 2 3 4 5 6
// 123456879012345687901234568790123456879012345687901234568790123456879012345687901234568790
// 00 11 22 33 44 55 66 77 00 11 22 33 44 55 66 77 1234567890123456
const int cBytesPerLine = 16;
const int cCharsPerLine = 68;
const int cWholeLines = cb / cBytesPerLine;
const int cRemainder = cb % cBytesPerLine;
const int cch = cCharsPerLine * (cWholeLines + 1);
wchar_t* psz = new wchar_t[cch+1];
psz[cch] = L'\0';
_wcsset(psz, L' ');
wchar_t* pszEnd = 0;
for (int i = 0; i < cWholeLines; ++i) {
pszEnd = _prettyPrintLine(psz + i * cCharsPerLine, pbuf + i * cBytesPerLine, 16);
}
if (cRemainder) {
pszEnd = _prettyPrintLine(psz + i * cCharsPerLine, pbuf + i * cBytesPerLine, cRemainder);
}
*pszEnd = L'\0';
return psz;
}
void _syncBufViewer() {
wchar_t szHeader[128];
switch (s_appState) {
case asComposingMsg:
return; // user is control of the viewer - don't mess with it
case asChoosingSSP:
case asChoosingCreds:
case asChoosingCtxReq:
case asNeedToRx:
case asAuthComplete:
case asSentMessage:
SetDlgItemText(s_hwnd, IDC_VIEWER, L"");
return; // nothing to view
case asDoneNeedTx:
case asNotDoneNeedTx:
lstrcpy(szHeader, L"Need to transmit the following authentication token");
break;
case asViewingRxToken:
lstrcpy(szHeader, L"Received the following authentication token");
break;
case asViewingTxMessage:
switch (s_msgProtection) {
case mpPlain: lstrcpy(szHeader, L"Ready to transmit the following cleartext message"); break;
case mpSigned: lstrcpy(szHeader, L"Ready to transmit the following signed message"); break;
case mpEncrypted: lstrcpy(szHeader, L"Ready to transmit the following encrypted message"); break;
}
break;
case asViewingRxMessage:
switch (s_msgProtectionUponRx) {
case mpEncrypted:
if (mpPlain == s_msgProtection)
lstrcpy(szHeader, L"Received and decrypted the following message");
else lstrcpy(szHeader, L"Received the following encrypted message");
break;
case mpSigned:
if (mpPlain == s_msgProtection)
lstrcpy(szHeader, L"Received and verified the following message");
else lstrcpy(szHeader, L"Received the following signed message");
break;
case mpPlain:
lstrcpy(szHeader, L"Received the following unprotected message");
break;
}
break;
}
wchar_t* pszMsg = 0;
wchar_t* pszTok = 0;
if (0 == s_cbMsg) {
// we're authenticating; the entire message is a token
pszMsg = _prettyPrint(s_msgBuf, s_cbMsgBuf);
}
else {
// only print out the message, not the trailing token
pszMsg = _prettyPrint(s_msgBuf, s_cbMsg);
}
_ASSERT(pszMsg);
if (0 == s_cbMsg || mpPlain == s_msgProtection) {
const wchar_t* const pszMsgType = (0 == s_cbMsg) ? L" Token " :
L"Message";
const wchar_t* pszFormat = L"%s:\r\n============================ %s =============================\r\n%s";
wchar_t* psz = new wchar_t[lstrlen(szHeader) + lstrlen(pszMsgType) + lstrlen(pszMsg) + lstrlen(pszFormat)];
wsprintf(psz, pszFormat, szHeader, pszMsgType, pszMsg);
SetDlgItemText(s_hwnd, IDC_VIEWER, psz);
delete [] psz;
}
else {
const wchar_t* const pszTokenType = (mpEncrypted == s_msgProtection) ? L" Trailer " :
L"Signature";
const BYTE* const pvToken = reinterpret_cast<BYTE*>(s_msgBuf) + s_cbMsg;
pszTok = _prettyPrint(pvToken, s_cbMsgBuf - s_cbMsg);
const wchar_t* pszFormat = L"%s:\r\n============================ Message =============================\r\n%s\r\n\r\n============================ %s =============================\r\n%s";
wchar_t* psz = new wchar_t[lstrlen(szHeader) + lstrlen(pszMsg) + lstrlen(pszTokenType) + lstrlen(pszTok) + lstrlen(pszFormat)];
wsprintf(psz, pszFormat, szHeader, pszMsg, pszTokenType, pszTok);
SetDlgItemText(s_hwnd, IDC_VIEWER, psz);
delete [] psz;
}
delete [] pszMsg;
delete [] pszTok;
}
void _clearMessage() {
ZeroMemory(s_msgBuf, sizeof s_msgBuf);
s_cbMsgBuf =
s_cbMsg = 0;
s_msgProtection =
s_msgProtectionUponRx = mpPlain;
}
bool _tx(bool bSequencedMessage = false) {
Transport* pTx = _getTransport();
if (pTx) {
if (!pTx->sendMessage(s_msgProtection, s_cbMsg, s_cbMsgBuf, s_msgBuf))
return false;
if (bSequencedMessage)
++s_nMsgSequence;
_clearMessage();
return true;
}
return false;
}
wchar_t* _dupString(const wchar_t* psz) {
const int cch = lstrlen(psz) + 1;
wchar_t* pszDup = new wchar_t[cch];
CopyMemory(pszDup, psz, cch * sizeof *psz);
return pszDup;
}
struct Mode {
Mode(const wchar_t* pszMode) {
BOOL bOk = GetWindowText(s_hwnd, m_szOldCaption, sizeof m_szOldCaption / sizeof *m_szOldCaption);
_ASSERT(bOk); bOk;
wchar_t sz[256];
wsprintf(sz, L"%s (%s)", m_szOldCaption, pszMode);
SetWindowText(s_hwnd, sz);
}
~Mode() {
SetWindowText(s_hwnd, m_szOldCaption);
}
wchar_t m_szOldCaption[256];
};
struct ReceiveMode : Mode {
ReceiveMode() : Mode(L"Receiving...") {
_activateControl(IDB_RX, false);
}
~ReceiveMode() {
_activateControl(IDB_RX, true);
}
};
bool _rx(bool bSequencedMessage = false) {
ReceiveMode mode;
Transport* pTx = _getTransport();
if (pTx) {
DWORD cbMsg, cbTotal;
void *pMsg;
MsgProtection msgProtection;
if (!pTx->recvMessage(&msgProtection, &cbMsg, &cbTotal, &pMsg))
return false;
if (bSequencedMessage)
++s_nMsgSequence;
_ASSERT(cbTotal < sizeof s_msgBuf);
CopyMemory(s_msgBuf, pMsg, s_cbMsgBuf = cbTotal);
s_cbMsg = cbMsg;
free(pMsg);
s_msgProtectionUponRx =
s_msgProtection = msgProtection;
return true;
}
return false;
}
void _readComposedMessage() {
char* pszBuf = reinterpret_cast<char*>(s_msgBuf);
HWND hwndViewer = GetDlgItem(s_hwnd, IDC_VIEWER);
int cch = GetWindowTextLengthA(hwndViewer);
if (cch) {
_ASSERT(cch + 1 < sizeof s_msgBuf);
GetWindowTextA(hwndViewer, pszBuf, sizeof s_msgBuf / sizeof *pszBuf);
}
else {
MessageBox(s_hwnd, L"Empty message, using default string (Hello world)", s_pszAppName, MB_SETFOREGROUND | MB_ICONINFORMATION);
lstrcpyA(pszBuf, "Hello world");
}
s_cbMsg = s_cbMsgBuf = lstrlenA(pszBuf);
}
bool _sign() {
_ASSERT(mpPlain == s_msgProtection);
bool bOk = false;
const DWORD cbMessage = s_cbMsgBuf;
void* pSignedMessage;
DWORD cbSignedMessage;
if (s_pModel->signMessage(s_msgBuf, cbMessage, s_nMsgSequence, &pSignedMessage, &cbSignedMessage)) {
_ASSERT(cbSignedMessage <= sizeof s_msgBuf);
CopyMemory(s_msgBuf, pSignedMessage, cbSignedMessage);
free(pSignedMessage);
s_cbMsg = cbMessage;
s_cbMsgBuf = cbSignedMessage;
s_msgProtection = mpSigned;
bOk = true;
}
return bOk;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -