cwinapiras

How to set l2tp preshared key?


I need to create RASENTRY for L2TP with pre-shared key set. So far, I can see that entry has somewhat correct flags, but no key is set, unfortunately.

Here is code:

int common_ras_manager_create_entry(const char* server_address, const char* username, const char* password, MY_VPN_CONNECTION_TYPE connection_type, const char* preshared_key)
{
    DWORD EntryInfoSize = 0;
    DWORD DeviceInfoSize = 0;
    DWORD Ret;
    LPRASENTRY lpRasEntry;
    LPBYTE lpDeviceInfo;

    // Get buffer sizing information for a default phonebook entry
    if ((Ret = RasGetEntryProperties(NULL, "", NULL, &EntryInfoSize, lpDeviceInfo, &DeviceInfoSize)) != 0)
    {
        if (Ret != ERROR_BUFFER_TOO_SMALL)
        {
            printf("RasGetEntryProperties sizing failed with error %d\n", Ret);
            return Ret;
        }
    }

    lpRasEntry = (LPRASENTRY) GlobalAlloc(GPTR, EntryInfoSize);

    if (DeviceInfoSize == 0)

        lpDeviceInfo = NULL;
    else
        lpDeviceInfo = (LPBYTE) GlobalAlloc(GPTR, DeviceInfoSize);

    // Get default phonebook entry
    lpRasEntry->dwSize = sizeof(RASENTRY);

    if ((Ret = RasGetEntryProperties(NULL, "", lpRasEntry, &EntryInfoSize, lpDeviceInfo, &DeviceInfoSize)) != 0)
    {
        printf("RasGetEntryProperties failed with error %d\n", Ret);
        return Ret;
    }

    // Validate new phonebook name "Testentry"
    if ((Ret = RasValidateEntryName(NULL, APP_NAME)) != ERROR_SUCCESS)
    {
        printf("RasValidateEntryName failed with error %d\n", Ret);
        if (Ret != ERROR_ALREADY_EXISTS)
            return Ret;
    }

    LPRASDEVINFO ras_devices;
    DWORD cb =sizeof(RASDEVINFO);
    DWORD cbDevices = 0;
    ras_devices = (LPRASDEVINFO)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cb);
    if (NULL == ras_devices)
    {
        printf("HeapAlloc failed.\n");
        return ERROR_OUTOFMEMORY;
    }



    ras_devices->dwSize = sizeof(RASDEVINFO);
    if ((Ret = RasEnumDevices(ras_devices, &cb, &cbDevices)) != ERROR_SUCCESS)
    {
        printf("RasEnumDevices failed with error %d\n", Ret);
        switch(Ret)
        {
            case ERROR_BUFFER_TOO_SMALL:
                printf("buffer too small");
                HeapFree(GetProcessHeap(), 0, (LPVOID)ras_devices);
                ras_devices = (LPRASDEVINFO)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cb);
                if (NULL == ras_devices)
                {
                    printf("HeapAlloc failed.\n");
                    return ERROR_OUTOFMEMORY;
                }

                ras_devices->dwSize = sizeof(RASDEVINFO);

                Ret = RasEnumDevices(ras_devices, &cb, &cbDevices);
                if (ERROR_SUCCESS == Ret)
                {
                    //fSuccess = TRUE;
                }
                else
                {
                    printf("RasEnumDevices failed again: Error = %d\n", Ret);
                    return Ret;
                    //goto done;
                }
                break;
            case ERROR_NOT_ENOUGH_MEMORY:
                printf("ERROR_NOT_ENOUGH_MEMORY");
                return Ret;
                break;
            case ERROR_INVALID_PARAMETER:
                printf("ERROR_INVALID_PARAMETER");
                return Ret;
                break;

            case ERROR_INVALID_USER_BUFFER:
                printf("ERROR_INVALID_USER_BUFFER");
                return Ret;
                break;


        }

    }

    DWORD dwVpnStrategy = 0;
    char device_name_mask[5];

    strcpy(device_name_mask, "");

    gboolean preshared_key_valid = 0;
    switch(connection_type)
    {
        case PPTP:
            strcpy(device_name_mask, "PPTP");
            dwVpnStrategy = VS_PptpOnly;
            break;
        case L2TP:
            if (preshared_key == 0 || strlen(preshared_key) == 0)
            {
                printf("CRITICAL: preshared key not set.");
                return 1;
            }
            else
            {
                preshared_key_valid = TRUE;
            }
            strcpy(device_name_mask, "L2TP");
            dwVpnStrategy = VS_L2tpOnly;
            break;
    }

    int i =0;
    for (i = 0; i < cbDevices; i++)
        {
            RASDEVINFO r = ras_devices[i];
            if (strstr(r.szDeviceName, device_name_mask))
            {
                break;
            }
        }

    //lpRasEntry->dwfOptions |= RASEO_SpecificIpAddr;
    //lpRasEntry->szLocalPhoneNumber = RASDT_Vpn;
    lpRasEntry->dwfNetProtocols |= RASNP_Ip;
    lpRasEntry->dwFramingProtocol = RASFP_Ppp;
    lstrcpy(lpRasEntry->szDeviceType, RASDT_Vpn);
    lstrcpy(lpRasEntry->szDeviceName, ras_devices[i].szDeviceName);
    lstrcpy(lpRasEntry->szLocalPhoneNumber, server_address);
    lpRasEntry->dwVpnStrategy = dwVpnStrategy; // VS_PptpOnly; VS_SstpOnly

    if (preshared_key_valid)
    {
        L2TP_CONFIG_DATA* data = GlobalAlloc(GPTR, sizeof(L2TP_CONFIG_DATA));
        lpRasEntry->dwfOptions2 |= RASEO2_UsePreSharedKey;
        data->dwOffsetKey = 16;
        memcpy((PBYTE)data + data->dwOffsetKey, preshared_key, strlen(preshared_key));
        data->dwAuthType =L2TP_IPSEC_AUTH_PRESHAREDKEY;

        RasSetCustomAuthData(NULL, APP_NAME, data, sizeof(L2TP_CONFIG_DATA));

    }


    if ((Ret = RasSetEntryProperties(NULL, APP_NAME, lpRasEntry, EntryInfoSize, lpDeviceInfo, DeviceInfoSize)) != 0)
    {
        printf("RasSetEntryProperties failed with error %d\n", Ret);
        return Ret;
    }

    //if ((Ret = RasSetCredentials(NULL, lpRasEntry.))
}

I cant find where is buffer to fill for pre-shared key.


Solution

  • Following code works fine.

    // l2tp
    if (preshared_key_valid)
    {
        RASCREDENTIALS ras_cre_psk = {0};
        ras_cre_psk.dwSize = sizeof(ras_cre_psk);
        ras_cre_psk.dwMask = 0x00000010; //RASCM_PreSharedKey;
        wcscpy(ras_cre_psk.szPassword, preshared_key);
        if ((Ret = RasSetCredentials(NULL, APP_NAME, &ras_cre_psk, FALSE)))
        {
            printf("RasSetCredentials failed with error %d\n", Ret);
            return Ret;
        }
    }