⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sspi_workbench.cpp

📁 sspi_workbench
💻 CPP
📖 第 1 页 / 共 3 页
字号:
#include "precomp.h"

#include "transport.h"
#include "model.h"
#include "tokdumpsrv.h"
#include "tokdumpsrv_i.c"
#include "MessageProtection.h"

enum AppStates {
    asChoosingSSP,
    asChoosingCreds,
    asChoosingCtxReq,
    asDoneNeedTx,
    asNotDoneNeedTx,
    asNeedToRx,
    asViewingRxToken,
    asAuthComplete,

    asComposingMsg,
    asViewingTxMessage,
    asViewingRxMessage,
    asSentMessage,
};

static bool          s_bServer             = false;
static AppStates     s_appState            = asChoosingSSP;

static MsgProtection s_msgProtection       = mpPlain;
static MsgProtection s_msgProtectionUponRx = mpPlain;
static DWORD         s_nMsgSequence        = 1;  // for sequence detection
static DWORD         s_grfCtxAttrs         = 0;

static Model*        s_pModel;  // SSPI model
static Transport*    s_pTx;     // network substrate (TCP)

static BYTE          s_msgBuf[4096 * 4]; // a big buffer eliminates buffer management worries
static DWORD         s_cbMsg;       // length of message
static DWORD         s_cbMsgBuf;    // length of message + security trailer (signature/encryption info)

static HWND          s_hwnd;
static HFONT         s_hfontNormal;
static HFONT         s_hfontHighlighted;
const wchar_t* const s_pszAppName          = L"SSPI Workbench";
const wchar_t* const s_pszINISectionClient = L"client_role";
const wchar_t* const s_pszINISectionServer = L"server_role";

static wchar_t s_szINIPath[_MAX_PATH];
inline const wchar_t* _getINIPath() { return s_szINIPath; }

static const int s_ctlGrp1[] = {
    IDC_GROUP_SELECT_SSP,
    IDB_SSP_OK,
    IDC_SPNEGO,
    IDC_PKGLIST,
    IDC_CHOOSE_SSP,
    IDC_SSP_DROPDOWN,
    IDC_STATIC_PROTOCOLS_TO_OFFER,
};

static const int s_ctlGrp2[] = {
    IDC_GROUP_CHOOSE_CREDS,
    IDB_ACQUIRE_CREDS,
    IDC_CRED_CUR_LOGON_SESSION,
    IDC_CRED_LOGON_SESSION,
    IDC_LOGON_SESSION_ID,
    IDC_CRED_EXPLICIT,
    IDC_AUTHORITY,
    IDC_PRINCIPAL,
    IDC_PASSWORD,
    IDC_STATIC_LOGONID,
    IDC_STATIC_AUTHORITY,
    IDC_STATIC_PRINCIPAL,
    IDC_STATIC_PASSWORD,
};

static const int s_ctlGrp3a[] = {
    IDC_STATIC_SPN,
    IDC_SPN,
    IDC_STATIC_CTX_REQ,
    IDC_MUTUAL_AUTHN,
    IDC_DELEGATE,
    IDC_PROMPT_FOR_CREDS,
};

static const int s_ctlGrp3b[] = {
    IDC_GROUP_AUTHENTICATE,
    IDB_INIT_SEC_CTX,
};

static const int s_ctlGrp4[] = {
    IDC_GROUP_PROTECT_MESSAGES,
    IDB_COMPOSE,
    IDB_SIGN,
    IDB_ENCRYPT,
    IDB_DECRYPT,
    IDB_VERIFY_SIG,
};

static const int s_ctlGrp5aClient[] = {
    IDC_STATIC_HOST,
    IDC_STATIC_PORT,
    IDC_HOST_ADDR,
    IDC_HOST_PORT,
};

static const int s_ctlGrp5aServer[] = {
    IDC_STATIC_PORT,
    IDC_HOST_PORT,
};

static const int s_ctlGrp5b[] = {
    IDC_GROUP_TXRX,
    IDB_TX,
    IDB_RX,
};

static const int s_ctlGrp6[] = {
    IDB_SIGN,
    IDB_ENCRYPT,
};

static const int s_ctlGrp7[] = {
    IDB_VERIFY_SIG,
    IDB_DECRYPT,
};

struct UIControlGroup {
    const int* m_begCtrls;
    const int* m_endCtrlsForHighlight;
    const int* m_endCtrls;
};

#define MAKE_UI_CONTROL_GROUP(g, n) {g, g + n, g + sizeof g / sizeof *g},

enum UIControlGroups {
    uicgChooseSSP,
    uicgChooseCred,
    uicgChooseCtxReq,
    uicgAuthenticate,
    uicgProtect,
    uicgClientHostInfo,
    uicgServerHostInfo,
    uicgTxRx,
    uicgProtectTx,
    uicgProtectRx,

    uicgHostInfo, // mapped to uicgClientHostInfo or uicgClientHostInfo
};

static const UIControlGroup g_uiControlGroup[] = {
    MAKE_UI_CONTROL_GROUP(s_ctlGrp1,        1)
    MAKE_UI_CONTROL_GROUP(s_ctlGrp2,        1)
    MAKE_UI_CONTROL_GROUP(s_ctlGrp3a,       0)
    MAKE_UI_CONTROL_GROUP(s_ctlGrp3b,       1)
    MAKE_UI_CONTROL_GROUP(s_ctlGrp4,        1)
    MAKE_UI_CONTROL_GROUP(s_ctlGrp5aClient, 0)
    MAKE_UI_CONTROL_GROUP(s_ctlGrp5aServer, 0)
    MAKE_UI_CONTROL_GROUP(s_ctlGrp5b,       1)
    MAKE_UI_CONTROL_GROUP(s_ctlGrp6,        0)
    MAKE_UI_CONTROL_GROUP(s_ctlGrp7,        0)
};

void _err(const wchar_t* psz, bool bRecoverable = false, DWORD err = GetLastError()) {
    wchar_t szErr[256];
    if (!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
                       0, err, 0, szErr, sizeof szErr / sizeof *szErr, 0))
        wsprintf(szErr, L"Unknown Error: %x", err);
    wchar_t szMsg[512];
    wsprintf(szMsg, L"%s failed: %s\n\nWould you like to debug?", psz, szErr);
    if (IDYES == MessageBox(0, szMsg, s_pszAppName,
                MB_SETFOREGROUND | MB_ICONEXCLAMATION | MB_YESNOCANCEL)) {
        __asm int 3;        
    }
    else if (!bRecoverable)
        ExitProcess(err);
}

void _centerWindow(HWND hwnd) {
    RECT rc;
    GetWindowRect(hwnd, &rc);
    SetWindowPos(hwnd, 0,
                 (GetSystemMetrics(SM_CXSCREEN) - rc.right ) / 2,
                 (GetSystemMetrics(SM_CYSCREEN) - rc.bottom) / 2,
                 0, 0,
                 SWP_NOSIZE | SWP_NOZORDER);
}

void _manageAutoRadioButtonGroup(int nFirstInGroup, int nSelected) {
    int id = nFirstInGroup;
    HWND hwnd = GetDlgItem(s_hwnd, nFirstInGroup);
    for (;;) {
        Button_SetCheck(hwnd, id == nSelected ? BST_CHECKED : BST_UNCHECKED);
        hwnd = GetWindow(hwnd, GW_HWNDNEXT);
        if (GetWindowLong(hwnd, GWL_STYLE) & WS_GROUP)
            break;
        id = GetWindowLong(hwnd, GWL_ID);
    }
}

int _findSelectedAutoRadioButton(int nFirstInGroup) {
    int id = nFirstInGroup;
    HWND hwnd = GetDlgItem(s_hwnd, nFirstInGroup);
    for (;;) {
        if (BST_CHECKED == Button_GetCheck(hwnd))
            return id;
        hwnd = GetWindow(hwnd, GW_HWNDNEXT);
        if (GetWindowLong(hwnd, GWL_STYLE) & WS_GROUP)
            break;
        id = GetWindowLong(hwnd, GWL_ID);
    }
    return -1;
}

void _highlight(HWND hwnd, bool bHighlight) {
    SetWindowFont(hwnd, bHighlight ? s_hfontHighlighted : s_hfontNormal, FALSE);
    RECT rc;
    GetWindowRect(hwnd, &rc);
    MapWindowPoints(0, s_hwnd, (POINT*)&rc, 2);
    InvalidateRect(s_hwnd, &rc, TRUE);
}

void _activateControlGroup(UIControlGroups cg, bool bActivate) {
    if (uicgHostInfo == cg)
        cg = s_bServer ? uicgServerHostInfo : uicgClientHostInfo;
    const UIControlGroup& uicg = g_uiControlGroup[int(cg)];
    const int* const begin = uicg.m_begCtrls;
    const int* const endh  = uicg.m_endCtrlsForHighlight;
    const int* const end   = uicg.m_endCtrls;

    const BOOL bEnable = bActivate ? TRUE : FALSE;
    bool bHighlighting = true;
    for (const int* it = begin; end != it; ++it) {
        const HWND hwndCtrl = GetDlgItem(s_hwnd, *it);
        if (endh == it)
            bHighlighting = false;
        if (bHighlighting)
            _highlight(hwndCtrl, bActivate);
        EnableWindow(hwndCtrl, bEnable);
    }
}

void _activateControl(int id, bool bActivate) {
    EnableWindow(GetDlgItem(s_hwnd, id), bActivate ? TRUE : FALSE);
}

void _enableComposeInViewer(bool bEnable, bool bSetFocus = false) {
    const HWND hwndViewer = GetDlgItem(s_hwnd, IDC_VIEWER);
    Edit_SetReadOnly(hwndViewer, bEnable ? FALSE : TRUE);
    if (bSetFocus)
        SetFocus(hwndViewer);
}

void _syncUIControlState() {

    switch (s_appState) {
    case asChoosingSSP:
        _activateControlGroup(uicgChooseSSP,      true);
        _activateControlGroup(uicgChooseCred,     false);
        _activateControlGroup(uicgChooseCtxReq,   false);
        _activateControlGroup(uicgAuthenticate,   false);
        _activateControlGroup(uicgProtect,        false);
        _activateControlGroup(uicgTxRx,           false);
        _activateControlGroup(uicgClientHostInfo, false);
        _activateControlGroup(uicgServerHostInfo, false);
        _activateControl(IDB_IMPERSONATE,         false);
        _activateControl(IDB_CLEAR,               false);
        switch (_findSelectedAutoRadioButton(IDC_SPNEGO)) {
        case IDC_SPNEGO:
            SetFocus(GetDlgItem(s_hwnd, IDC_PKGLIST));
            break;
        case IDC_CHOOSE_SSP:
            SetFocus(GetDlgItem(s_hwnd, IDC_SSP_DROPDOWN));
            break;
        }
       break;
    case asChoosingCreds:
        _activateControlGroup(uicgChooseSSP,    false);
        _activateControlGroup(uicgChooseCred,   true);
        switch (_findSelectedAutoRadioButton(IDC_CRED_CUR_LOGON_SESSION)) {
        case IDC_CRED_CUR_LOGON_SESSION:
            SetFocus(GetDlgItem(s_hwnd, IDC_CRED_CUR_LOGON_SESSION));
            break;
        case IDC_CRED_LOGON_SESSION:
            SetFocus(GetDlgItem(s_hwnd, IDC_LOGON_SESSION_ID));
            break;
        case IDC_CRED_EXPLICIT:
            SetFocus(GetDlgItem(s_hwnd, IDC_AUTHORITY));
            break;
        }
        break;
    case asChoosingCtxReq:
        _activateControlGroup(uicgChooseCred,   false);
        _activateControlGroup(uicgChooseCtxReq, true);
        _activateControlGroup(uicgAuthenticate, true);
        break;
    case asDoneNeedTx:
        _activateControlGroup(uicgChooseCtxReq, false);
        _activateControlGroup(uicgAuthenticate, false);
        _activateControlGroup(uicgTxRx,         true);
        _activateControl(IDB_RX,                false);
        _activateControl(IDB_TX,                true);
        if (!s_pTx)
            _activateControlGroup(uicgHostInfo, true);
        if (s_bServer)
            _activateControl(IDB_IMPERSONATE,   true);
        break;
    case asNotDoneNeedTx:
        _activateControlGroup(uicgChooseCtxReq, false);
        _activateControlGroup(uicgAuthenticate, false);
        _activateControlGroup(uicgTxRx,         true);
        _activateControl(IDB_RX,                false);
        _activateControl(IDB_TX,                true);
        if (!s_pTx)
            _activateControlGroup(uicgHostInfo, true);
        break;
    case asNeedToRx:
        _activateControlGroup(uicgChooseCred,   false);
        _activateControlGroup(uicgHostInfo,     false);
        _activateControl(IDB_TX,                false);
        _activateControl(IDB_RX,                true);
        if (!s_pTx)
            _activateControlGroup(uicgHostInfo, true);
        break;
    case asViewingRxToken:
        _activateControlGroup(uicgTxRx,         false);
        _activateControlGroup(uicgAuthenticate, true);
        break;
    case asAuthComplete:
        _activateControlGroup(uicgAuthenticate, false);
        _activateControlGroup(uicgProtect,      true);
        _activateControlGroup(uicgProtectTx,    false);
        _activateControlGroup(uicgProtectRx,    false);
        _activateControlGroup(uicgHostInfo,     false);
        if (s_bServer)
            _activateControl(IDB_IMPERSONATE,   true);
        _activateControl(IDB_CLEAR,             false);
        _activateControl(IDB_RX,                true);
        _activateControl(IDB_TX,                false);
        break;
    case asComposingMsg:
        _activateControlGroup(uicgProtectTx,    true);
        _activateControlGroup(uicgProtectRx,    false);
        _activateControl(IDB_RX,                false);
        _activateControl(IDB_TX,                true);
        _activateControl(IDB_COMPOSE,           true);
        _enableComposeInViewer(true, true);
        break;
    case asViewingTxMessage:
        _activateControl(IDB_COMPOSE,           false);
        _activateControl(IDB_SIGN,              mpPlain == s_msgProtection);
        _activateControl(IDB_ENCRYPT,           mpPlain == s_msgProtection);
        _enableComposeInViewer(false);
        break;
    case asViewingRxMessage:
        _activateControlGroup(uicgTxRx,         false);
        _activateControlGroup(uicgProtectTx,    false);
        _activateControlGroup(uicgProtectRx,    true);
        _activateControl(IDB_COMPOSE,           false);
        _activateControl(IDB_CLEAR,             true);
        _activateControl(IDB_VERIFY_SIG,        mpSigned    == s_msgProtection);
        _activateControl(IDB_DECRYPT,           mpEncrypted == s_msgProtection);
        break;
    case asSentMessage:
        _activateControlGroup(uicgProtectTx,    false);
        _activateControl(IDB_COMPOSE,           true);
        _activateControl(IDB_TX,                false);
        _activateControl(IDB_RX,                true);
        _enableComposeInViewer(false);
        break;
    }
}

bool _chooseSSP() {
    wchar_t sz[256];
    const wchar_t* pszSSP = 0;
    if (BST_CHECKED == Button_GetCheck(GetDlgItem(s_hwnd, IDC_SPNEGO))) {
        if (!GetDlgItemText(s_hwnd, IDC_PKGLIST, sz, sizeof sz / sizeof *sz)) {
            MessageBox(s_hwnd, L"In order to use SPNEGO, you must enter a comma separated list of SSPs, in order of preference. For example:\n\nKerberos,NTLM", s_pszAppName, MB_SETFOREGROUND | MB_ICONINFORMATION);
            return false;
        }
        s_pModel->chooseSPNEGO(sz);
        WritePrivateProfileString(s_pszINISectionClient, L"pkg_list", sz, _getINIPath());
        pszSSP = L"Negotiate";
    }
    else if (BST_CHECKED == Button_GetCheck(GetDlgItem(s_hwnd, IDC_CHOOSE_SSP))) {
        HWND hwndList = GetDlgItem(s_hwnd, IDC_SSP_DROPDOWN);
        int n = ComboBox_GetCurSel(hwndList);
        if (CB_ERR == n)
            return false;
        if (CB_ERR == ComboBox_GetLBText(hwndList, n, sz))
            return false;
        s_pModel->chooseSpecificSSP(sz);
        pszSSP = sz;
    }
    else return false;
    WritePrivateProfileString(s_pszINISectionClient, L"ssp", pszSSP, _getINIPath());
    return true;
}

AppStates _chooseCreds() {
    const wchar_t* const pszINISection = s_bServer ? s_pszINISectionServer : s_pszINISectionClient;
    const wchar_t* pszCredSource = L"0";
    if (BST_CHECKED == Button_GetCheck(GetDlgItem(s_hwnd, IDC_CRED_CUR_LOGON_SESSION))) {
        s_pModel->chooseCredentials();
    }
    else if (BST_CHECKED == Button_GetCheck(GetDlgItem(s_hwnd, IDC_CRED_LOGON_SESSION))) {
        wchar_t sz[40];
        if (!GetDlgItemText(s_hwnd, IDC_LOGON_SESSION_ID, sz, sizeof sz / sizeof *sz))
            return s_appState;
        const __int64 n = _wtoi64(sz);
        s_pModel->chooseCredentials(reinterpret_cast<const LUID*>(n));
        pszCredSource = L"1";
    }
    else if (BST_CHECKED == Button_GetCheck(GetDlgItem(s_hwnd, IDC_CRED_EXPLICIT))) {
        wchar_t szAuthority[256];
        wchar_t szPrincipal[256];
        wchar_t szPassword[256];
        GetDlgItemText(s_hwnd, IDC_AUTHORITY, szAuthority, sizeof szAuthority / sizeof *szAuthority);
        GetDlgItemText(s_hwnd, IDC_PRINCIPAL, szPrincipal, sizeof szPrincipal / sizeof *szPrincipal);
        GetDlgItemText(s_hwnd, IDC_PASSWORD,  szPassword,  sizeof szPassword  / sizeof *szPassword);
        s_pModel->chooseCredentials(szAuthority, szPrincipal, szPassword); 
        WritePrivateProfileString(pszINISection, L"alt_authority", szAuthority, _getINIPath());
        WritePrivateProfileString(pszINISection, L"alt_principal", szPrincipal, _getINIPath());
        WritePrivateProfileString(pszINISection, L"alt_password",  szPassword,  _getINIPath());
        pszCredSource = L"2";
    }
    else return s_appState;
    WritePrivateProfileString(pszINISection, L"cred_source", pszCredSource, _getINIPath());
    return s_bServer ? asNeedToRx : asChoosingCtxReq;
}
                
void _updateCtxAttrsViewer() {
    static const wchar_t*  rgdesc[] = {
        L"Delegate",
        L"Mutual_auth",

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -