📄 wifisetup.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
#include <windows.h>
#include <eapol.h>
#include <wzcsapi.h>
#include <ntddndis.h>
#include "iptypes.h"
#include "nuiouser.h"
#include "iphlpapi.h"
#include <winsock2.h>
#include <ws2tcpip.h>
#include <wincrypt.h>
#include "zones.h"
// utility macro to convert a hexa digit into its value
#define HEX(c) ((c)<='9'?(c)-'0':(c)<='F'?(c)-'A'+0xA:(c)-'a'+0xA)
typedef HCERTSTORE (*PFN_CERTOPENSTORE)(LPCSTR lpszStoreProvider,
DWORD dwEncodingType,
HCRYPTPROV hCryptProv,
DWORD dwFlags,
const void *pvPara);
typedef PCCERT_CONTEXT (*PFN_CERTENUMCERTIFICATESINSTORE)(HCERTSTORE hCertStore, PCCERT_CONTEXT pPrevCertContext);
typedef BOOL (*PFN_CERTFREECERTIFICATECONTEXT)(PCCERT_CONTEXT pCertContext);
typedef BOOL (*PFN_CERTCLOSESTORE)(HCERTSTORE hCertStore, DWORD dwFlags);
//
// Check if there are any User certificates in the Cert Store. This is required
// if the connection specified is a 802.1x connection. If there are no certificates
// in the user store, the connection attemption will fail without a useful error
// message and in order to prevent that, we detect the presence of certificates
// before the connection attempt and notify the user using a MessageBox if
// no certs are present.
//
BOOL UserCertificatePresent()
{
HCERTSTORE hStore = NULL;
DWORD dwErr = 0;
PCCERT_CONTEXT pCertContext = NULL;
BOOL fRetVal = FALSE;
HINSTANCE hCryptDll = NULL;
PFN_CERTOPENSTORE pfnCertOpenStore = NULL;
PFN_CERTENUMCERTIFICATESINSTORE pfnCertEnumCertificatesInStore = NULL;
PFN_CERTFREECERTIFICATECONTEXT pfnCertFreeCertificateContext = NULL;
PFN_CERTCLOSESTORE pfnCertCloseStore = NULL;
hCryptDll = LoadLibrary(TEXT("crypt32.dll"));
if (NULL == hCryptDll)
{
DEBUGMSG(ZONE_ERROR, (TEXT("Ethman: UserCertificatePresent: Loadlibrary failed. Err = %d"), GetLastError()));
return TRUE;
}
pfnCertOpenStore = (PFN_CERTOPENSTORE)GetProcAddress(hCryptDll, TEXT("CertOpenStore"));
pfnCertEnumCertificatesInStore = (PFN_CERTENUMCERTIFICATESINSTORE)GetProcAddress(hCryptDll, TEXT("CertEnumCertificatesInStore"));
pfnCertFreeCertificateContext = (PFN_CERTFREECERTIFICATECONTEXT)GetProcAddress(hCryptDll, TEXT("CertFreeCertificateContext"));
pfnCertCloseStore = (PFN_CERTCLOSESTORE)GetProcAddress(hCryptDll, TEXT("CertCloseStore"));
if (NULL == pfnCertOpenStore ||
NULL == pfnCertEnumCertificatesInStore ||
NULL == pfnCertFreeCertificateContext ||
NULL == pfnCertCloseStore)
{
DEBUGMSG(ZONE_ERROR, (TEXT("Ethman: UserCertificatePresent: GetProcAddress failed. Err = %d"), GetLastError()));
goto Exit;
}
hStore = (*pfnCertOpenStore)(CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_CURRENT_USER, TEXT("MY"));
if (NULL == hStore)
{
dwErr = GetLastError();
DEBUGMSG(ZONE_ERROR, (TEXT("Ethman: IsUserCertificateAvailable: Failed to open cert store. Err = %d\r\n"), dwErr));
goto Exit;
}
pCertContext = (*pfnCertEnumCertificatesInStore)(hStore, NULL);
if (NULL != pCertContext)
{
fRetVal = TRUE;
DEBUGMSG(ZONE_VERBOSE, (TEXT("Ethman: IsUserCertificateAvailable: Found a user cert.\r\n")));
}
Exit:
if (NULL != pCertContext && NULL != pfnCertFreeCertificateContext)
{
(*pfnCertFreeCertificateContext)(pCertContext);
}
if (NULL != hStore && NULL != pfnCertCloseStore)
{
(*pfnCertCloseStore)(hStore, 0);
}
if (NULL != hCryptDll)
FreeLibrary(hCryptDll);
return fRetVal;
}
//
// find the first wireless network cards
//
BOOL GetFirstWirelessNetworkCard(LPTSTR *ppszDeviceName)
{
BOOL fRet = FALSE;
DWORD dwStatus;
LPTSTR pszDeviceName = NULL;
DWORD cbDeviceName = 0;
DWORD cchDeviceName = 0;
INTFS_KEY_TABLE IntfsTable;
IntfsTable.dwNumIntfs = 0;
IntfsTable.pIntfs = NULL;
if (NULL == ppszDeviceName)
{
DEBUGMSG(ZONE_ERROR, (L"Ethman: GetFirstWirelessNetworkCard:: Error INVALID PARAMETER\r\n"));
return fRet;
}
dwStatus = WZCEnumInterfaces(NULL, &IntfsTable);
if(dwStatus != ERROR_SUCCESS)
{
DEBUGMSG(ZONE_ERROR, (L"Ethman: GetFirstWirelessNetworkCard:: WZCEnumInterfaces() error 0x%08X\r\n", dwStatus));
goto Exit;
}
if(!IntfsTable.dwNumIntfs)
{
DEBUGMSG(ZONE_ERROR, (L"Ethman: GetFirstWirelessNetworkCard:: system has no wireless card.\r\n"));
goto Exit;
}
cchDeviceName = _tcslen(IntfsTable.pIntfs[0].wszGuid);
cbDeviceName = (cchDeviceName + 1) * sizeof(TCHAR);
pszDeviceName = (LPTSTR)LocalAlloc(LPTR, cbDeviceName);
if (NULL == pszDeviceName)
{
DEBUGMSG(ZONE_ERROR, (L"Ethman: GetFirstWirelessNetworkCard:: Error OUT_OF_MEMORY\r\n"));
goto Exit;
}
_tcsncpy(pszDeviceName, IntfsTable.pIntfs[0].wszGuid, cchDeviceName);
pszDeviceName[cchDeviceName] = TEXT('\0');
fRet = TRUE;
DEBUGMSG(ZONE_VERBOSE, (L"Ethman: GetFirstWirelessNetworkCard:: wireless card found: %s\r\n", pszDeviceName));
*ppszDeviceName = pszDeviceName;
pszDeviceName = NULL;
Exit:
// need to free memory allocated by WZC for us.
if (NULL != IntfsTable.pIntfs)
LocalFree(IntfsTable.pIntfs);
if (NULL != pszDeviceName)
LocalFree(pszDeviceName);
return fRet;
}
DWORD CheckConnectionStatus(LPTSTR pszDeviceName, BOOL *pfConnected, LPTSTR* ppszIpAddress, DWORD* pdwIpAddress)
{
DWORD dwRetVal = NO_ERROR;
PIP_ADAPTER_INFO pAdapterInfo = NULL;
PIP_ADAPTER_INFO pAdapterInfoHead = NULL;
ULONG ulBufferSize = 0;
TCHAR* pszAdapterName = NULL;
DWORD cdwAdapterName = 0;
DWORD cdwCurrAdapterName;
LPTSTR pszIPAddress = NULL;
DWORD cIpAddress = 0;
DWORD cbIpAddress = 0;
DWORD cRet = 0;
int errno = 0;
if (NULL == pszDeviceName ||
TEXT('\0') == pszDeviceName[0])
{
dwRetVal = ERROR_INVALID_PARAMETER;
goto exit;
}
if (NULL != pfConnected)
{
*pfConnected = FALSE;
}
// Get IP Adapters Info from IPhelper
dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulBufferSize);
if(dwRetVal == ERROR_BUFFER_OVERFLOW)
{
pAdapterInfo = (PIP_ADAPTER_INFO)LocalAlloc(LMEM_FIXED, ulBufferSize);
if(pAdapterInfo == NULL)
{
dwRetVal = ERROR_OUTOFMEMORY;
goto exit;
}
// Set a pointer to the head of the list
pAdapterInfoHead = pAdapterInfo;
dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulBufferSize);
if(dwRetVal != NO_ERROR)
{
goto exit;
}
}
else if(dwRetVal != NO_ERROR)
{
goto exit;
}
// If no adapter interface is present
if(ulBufferSize == 0)
{
dwRetVal = ERROR_INVALID_DATA;
goto exit;
}
// Check if the Public Interface Adapter is connected
do
{
cdwCurrAdapterName = strlen(pAdapterInfo->AdapterName)+1;
if(cdwCurrAdapterName > cdwAdapterName)
{
// Free the existing buffer (if it exists)
if(pszAdapterName)
{
LocalFree(pszAdapterName);
pszAdapterName = NULL;
}
// Allocate some memory for the adapter name string. Make this large enough so
// that we probably won't have to reallocate more later.
cdwAdapterName = cdwCurrAdapterName + 10;
pszAdapterName = (WCHAR*)LocalAlloc(LMEM_FIXED, cdwAdapterName*sizeof(TCHAR));
if(pszAdapterName == NULL)
{
dwRetVal = ERROR_OUTOFMEMORY;
goto exit;
}
}
errno = mbstowcs_s(&cdwCurrAdapterName, pszAdapterName, cdwCurrAdapterName, pAdapterInfo->AdapterName, cdwCurrAdapterName -1);
if (errno != 0 ||
cdwCurrAdapterName == 0)
{
dwRetVal = ERROR_INVALID_DATA;
goto exit;
}
if(_tcscmp(pszDeviceName, pszAdapterName) == 0)
{
// Verify that the IP address does not represent an invalid connection
if(strcmp(pAdapterInfo->IpAddressList.IpAddress.String, "0.0.0.0") == 0)
{
DEBUGMSG(ZONE_ERROR, (TEXT("Ethman: UpdateConnectionStatus: Not connected\r\n")));
if (NULL != pfConnected)
*pfConnected = FALSE;
}
else
{
*pfConnected = TRUE;
cIpAddress = 0;
errno = mbstowcs_s(&cIpAddress, NULL, 0, pAdapterInfo->IpAddressList.IpAddress.String, 0);
if (errno != 0 ||
cIpAddress == 0)
{
dwRetVal = ERROR_INVALID_DATA;
goto exit;
}
// mbstowcs_s returns size including terminating null
cbIpAddress = cIpAddress * sizeof(TCHAR);
pszIPAddress = LocalAlloc(LPTR, cbIpAddress);
if (pszIPAddress == NULL)
{
dwRetVal = ERROR_OUTOFMEMORY;
goto exit;
}
errno = mbstowcs_s(&cIpAddress, pszIPAddress, cIpAddress, pAdapterInfo->IpAddressList.IpAddress.String, cIpAddress -1);
if (errno != 0 ||
cIpAddress == 0)
{
dwRetVal = ERROR_INVALID_DATA;
goto exit;
}
DEBUGMSG(ZONE_VERBOSE, (TEXT("Ethman: UpdateConnectionStatus: Connected Adapter [%s] to IP: %s \r\n"), pszDeviceName, pszIPAddress));
if (NULL != ppszIpAddress)
{
*ppszIpAddress = pszIPAddress;
pszIPAddress = NULL;
}
if (NULL != pdwIpAddress)
{
*pdwIpAddress = inet_addr(pAdapterInfo->IpAddressList.IpAddress.String);
}
}
dwRetVal = NO_ERROR;
break;
}
pAdapterInfo = pAdapterInfo->Next;
}
while(pAdapterInfo != NULL);
exit:
if(pszAdapterName)
{
LocalFree(pszAdapterName);
}
if(pAdapterInfoHead)
{
LocalFree(pAdapterInfoHead);
}
if(pszIPAddress)
{
LocalFree(pszIPAddress);
}
return dwRetVal;
}
// encrypt WEP key material
// note: this is simply for the security (to protect from memory scanning)
void EncryptWepKMaterial(WZC_WLAN_CONFIG* pwzcConfig)
{
int i;
BYTE chFakeKeyMaterial[] = { 0x56, 0x09, 0x08, 0x98, 0x4D, 0x08, 0x11, 0x66, 0x42, 0x03, 0x01, 0x67, 0x66 };
for (i = 0; i < WZCCTL_MAX_WEPK_MATERIAL; i++)
pwzcConfig->KeyMaterial[i] ^= chFakeKeyMaterial[(7*i)%13];
}
// interpret key value then fill pwzcConfig1->KeyLength and KeyMaterial[]
// pwzcConfig1->Privacy should be initialized before calling.
// key is interpreted differently based on the pwzcConfig1->Privacy
// pwzcConfig1->Privacy could be one of these
// Ndis802_11WEPEnabled = WEP key
// Ndis802_11Encryption2Enabled = TKIP/WPA key
void InterpretEncryptionKeyValue(PWZC_WLAN_CONFIG pwzcConfig1,
WCHAR *szEncryptionKey,
BOOL* pfNeed8021X )
{
WCHAR *szEncryptionKeyValue;
UINT i;
char szEncryptionKeyValue8[64]; // longest key is 63
if(pwzcConfig1->Privacy == Ndis802_11WEPEnabled)
{
// WEP key : valid forms are
// -key 1/0x1234567890 [index=1,40-bit(10-digit hexa)]
// -key 4/zxcvb [index=4, 40-bit(5-char)
// -key 3/0x12345678901234567890123456 [index=3, 104-bit(26-digit hexa)
// -key 2/abcdefghij123 [index=2, 104-bit(13-char)
// -key auto [key comes from successful EAP]
if(!_wcsicmp(szEncryptionKey, L"auto"))
*pfNeed8021X = TRUE;
else
{
if((szEncryptionKey[0] < L'1') || (szEncryptionKey[0] > L'4') || (szEncryptionKey[1]!=L'/'))
{
DEBUGMSG(ZONE_ERROR, (TEXT("Ethman: InterpretEncryptionKeyValue: invalid key index\n")));
return;
}
pwzcConfig1->KeyIndex = szEncryptionKey[0] - L'1';
szEncryptionKeyValue = szEncryptionKey + 2;
pwzcConfig1->KeyLength = wcslen(szEncryptionKeyValue);
if((pwzcConfig1->KeyLength==5) || (pwzcConfig1->KeyLength==13))
{
for(i=0; i<pwzcConfig1->KeyLength; i++)
pwzcConfig1->KeyMaterial[i] = (UCHAR) szEncryptionKeyValue[i];
}
else
{
if((szEncryptionKeyValue[0]!=L'0') || (szEncryptionKeyValue[1]!=L'x'))
{
DEBUGMSG(ZONE_ERROR, (TEXT("Ethman: InterpretEncryptionKeyValue: invalid key value\n")));
return;
}
szEncryptionKeyValue += 2;
pwzcConfig1->KeyLength = wcslen(szEncryptionKeyValue);
if((pwzcConfig1->KeyLength!=10) && (pwzcConfig1->KeyLength!=26))
{
DEBUGMSG(ZONE_ERROR, (TEXT("Ethman: InterpretEncryptionKeyValue: invalid key value\n")));
return;
}
pwzcConfig1->KeyLength >>= 1;
for(i=0; i<pwzcConfig1->KeyLength; i++)
pwzcConfig1->KeyMaterial[i] = (HEX(szEncryptionKeyValue[2*i])<<4) | HEX(szEncryptionKeyValue[2*i+1]);
}
EncryptWepKMaterial(pwzcConfig1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -