c++windowsencryptionvpnras

C++: Disabling RequireCHAP and RequireMsCHAP2 in the Windows RAS API


I am writing a program that will set up a VPN on a user's computer. My sysadmin told me that the security page of the VPN must have these security settings checked, and no others.

I have used this code as a basis for my own. My version sets almost everything correctly, except that it cannot uncheck the 2 boxes titled Challenge Handshake Authentication Protocol (CHAP) and Microsoft CHAP Version 2 (MS-CHAP v2). Is it possible to programmatically uncheck those 2 checkboxes while leaving the Data Encryption dropdown list set as Require Encryption? Here is my code:

void createVPN()
{
    DWORD size = 0;
    RasGetEntryProperties(NULL, L"", NULL, &size, NULL, NULL);
    LPRASENTRY pras = (LPRASENTRY)malloc(size);
    memset(pras, 0, size);
    pras->dwSize = size;
    pras->dwType = RASET_Vpn;
    pras->dwRedialCount = 1;
    pras->dwRedialPause = 60;
    pras->dwfNetProtocols = RASNP_Ip;
    pras->dwEncryptionType = ET_Require;
    wcscpy_s(pras->szLocalPhoneNumber, L"meraki.companyname.com");
    wcscpy_s(pras->szDeviceType, RASDT_Vpn);
    pras->dwfOptions = RASEO_RemoteDefaultGateway;

    pras->dwVpnStrategy = VS_L2tpOnly;
    pras->dwfOptions2 |= RASEO2_UsePreSharedKey;
    pras->dwfOptions &= ~(RASEO_RequireCHAP | RASEO_RequireMsCHAP | RASEO_RequireMsCHAP2);//This should unset the CHAP flags, but it doesn't.

    RasSetEntryProperties(NULL, L"CompanyName Meraki VPN", pras, pras->dwSize, NULL, 0);

    RASCREDENTIALS ras_cre_psk = { 0 };
    ras_cre_psk.dwSize = sizeof(ras_cre_psk);
    ras_cre_psk.dwMask = RASCM_PreSharedKey;
    wcscpy_s(ras_cre_psk.szPassword, L"redacted");
    RasSetCredentials(NULL, L"CompanyName Meraki VPN", &ras_cre_psk, FALSE);

    free(pras);
}

I am thinking that by setting pras->dwEncryptionType to ET_Require, that prevents RASEO_RequireCHAP and the other CHAP flags from being unset, but in the Windows GUI, it is possible to uncheck them and leave Data Encryption set to Require Encryption. My sysadmin tells me that the connection will not work if either of the CHAP checkboxes are checked, or if Data Encryption is not set to Require Encryption. What can I do?


Solution

  • I have finally figured it out. You have to set the RASEO_RequirePAP switch. Here is the final version of the function:

    void createVPN()
    {
        DWORD size = 0;
        RasGetEntryProperties(NULL, L"", NULL, &size, NULL, NULL);
        RASENTRY rasEntry = {};
        rasEntry.dwSize = sizeof(rasEntry);
        rasEntry.dwType = RASET_Vpn;
        rasEntry.dwRedialCount = 1;
        rasEntry.dwRedialPause = 60;
        rasEntry.dwfNetProtocols = RASNP_Ip;
        rasEntry.dwEncryptionType = ET_Require;
        wcscpy_s(rasEntry.szLocalPhoneNumber, L"meraki.enoble.com");
        wcscpy_s(rasEntry.szDeviceType, RASDT_Vpn);
        rasEntry.dwfOptions = RASEO_RemoteDefaultGateway;
    
        rasEntry.dwVpnStrategy = VS_L2tpOnly;
        rasEntry.dwfOptions2 |= RASEO2_UsePreSharedKey;
        rasEntry.dwfOptions |= RASEO_RequirePAP;
    
        RasSetEntryProperties(NULL, L"Enoble Meraki VPN", &rasEntry, rasEntry.dwSize, NULL, 0);
    
        RASCREDENTIALS ras_cre_psk = { 0 };
        ras_cre_psk.dwSize = sizeof(ras_cre_psk);
        ras_cre_psk.dwMask = RASCM_PreSharedKey;
        wcscpy_s(ras_cre_psk.szPassword, L"passport2k");
        RasSetCredentials(NULL, L"Enoble Meraki VPN", &ras_cre_psk, FALSE);
    }
    

    I hope this helps somebody.