//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1992 - 1996. // // File: ras.c // // Contents: // // Classes: // // Functions: // // History: 2-09-96 RichardW Created // //---------------------------------------------------------------------------- #include "msgina.h" #include #include #include #include #define NP_Nbf 0x1 #define NP_Ipx 0x2 #define NP_Ip 0x4 HANDLE hRasApi ; VOID WINAPI MyRasCallback( IN DWORD_PTR dwCallbackId, IN DWORD dwEventCode, IN LPWSTR pszEntry, IN LPVOID pEventArgs ) /* RasPhonebookDlg callback. 'DwCallbackId' is the ID provided in ** parameters to RasPhonebookDlg. 'DwEventCode' indicates the ** RASPBDEVENT_* event that has occurred. 'PszEntry' is the name of the ** entry on which the event occurred. 'PEventArgs' is the event-specific ** parameter block passed to us during RasPhonebookDlg callback. */ { RASNOUSERW* pInfo; PGLOBALS pGlobals; DebugLog((DEB_TRACE, "RasCallback: %#x, %#x, %ws, %#x\n", dwCallbackId, dwEventCode, pszEntry, pEventArgs )); /* Fill in information about the not yet logged on user. */ pInfo = (RASNOUSERW* )pEventArgs; pGlobals = (PGLOBALS) dwCallbackId; if (dwEventCode == RASPBDEVENT_NoUserEdit) { if (pInfo->szUserName[0]) { wcscpy( pGlobals->UserName, pInfo->szUserName ); } if (pInfo->szPassword[0]) { wcscpy( pGlobals->Password, pInfo->szPassword ); RtlInitUnicodeString( &pGlobals->PasswordString, pGlobals->Password ); pGlobals->Seed = 0; HidePassword( &pGlobals->Seed, &pGlobals->PasswordString ); } } else if (dwEventCode == RASPBDEVENT_NoUser) { ZeroMemory( pInfo, sizeof( RASNOUSERW ) ); pInfo->dwTimeoutMs = 2 * 60 * 1000; pInfo->dwSize = sizeof( RASNOUSERW ); wcsncpy( pInfo->szUserName, pGlobals->UserName, UNLEN ); wcsncpy( pInfo->szDomain, pGlobals->Domain, DNLEN ); RevealPassword( &pGlobals->PasswordString ); wcsncpy( pInfo->szPassword, pGlobals->Password, PWLEN ); HidePassword( &pGlobals->Seed, &pGlobals->PasswordString ); } if( pGlobals->SmartCardLogon && (NULL != pInfo)) { pInfo->dwFlags |= RASNOUSER_SmartCard; } } DWORD GetRasDialOutProtocols( void ) /* Returns a bit field containing NP_ flags for the installed ** PPP protocols. The term "installed" here includes enabling in RAS ** Setup. */ { // // Since after the connections checkin, RAS is always installed // and there is no way to uninstall it, all we need to check here // is if there are protocols installed that can be used by RAS to // dial out. By default any protocol installed is available for RAS // to dial out on. This can be overridden from the phonebook entry. // static const TCHAR c_szRegKeyIp[] = TEXT("SYSTEM\\CurrentControlSet\\Services\\Tcpip"); static const TCHAR c_szRegKeyIpx[] = TEXT("SYSTEM\\CurrentControlSet\\Services\\NwlnkIpx"); static const TCHAR c_szRegKeyNbf[] = TEXT("SYSTEM\\CurrentControlSet\\Services\\Nbf"); struct PROTOCOL_INFO { DWORD dwFlag; LPCTSTR pszRegkey; }; static const struct PROTOCOL_INFO c_aProtocolInfo[] = { { NP_Ip, c_szRegKeyIp, }, { NP_Ipx, c_szRegKeyIpx, }, { NP_Nbf, c_szRegKeyNbf, }, }; DWORD dwfInstalledProtocols = 0; DWORD dwNumProtocols = sizeof(c_aProtocolInfo)/sizeof(c_aProtocolInfo[0]); DWORD i; HKEY hkey; DebugLog(( DEB_TRACE, "GetRasDialOutProtocols...\n" )); for(i = 0; i < dwNumProtocols; i++) { if(0 == RegOpenKey(HKEY_LOCAL_MACHINE, c_aProtocolInfo[i].pszRegkey, &hkey)) { dwfInstalledProtocols |= c_aProtocolInfo[i].dwFlag; RegCloseKey(hkey); } } DebugLog(( DEB_TRACE, "GetRasDialOutProtocols: dwfInstalledProtocols=0x%x\n", dwfInstalledProtocols)); return dwfInstalledProtocols; } BOOL PopupRasPhonebookDlg( IN HWND hwndOwner, IN PGLOBALS pGlobals, OUT BOOL* pfTimedOut ) /* Popup the RAS common phonebook dialog to let user establish connection. ** 'HwndOwner' is the window to own the RAS dialog or NULL if none. '*PfTimedOut' is ** set TRUE if the dialog timed out, false otherwise. ** ** Returns true if user made a connection, false if not, i.e. an error ** occurred, RAS is not installed or user could not or chose not to ** connect. */ { BOOL fConnected; RASPBDLG info; DWORD Protocols; PUCHAR pvScData = NULL; struct EAPINFO { DWORD dwSizeofEapInfo; PBYTE pbEapInfo; DWORD dwSizeofPINInfo; PBYTE pbPINInfo; }; struct EAPINFO eapinfo; struct EAPINFO *pEapInfo = NULL; *pfTimedOut = FALSE; Protocols = GetRasDialOutProtocols(); if (Protocols == 0) { return( FALSE ); } if(pGlobals->SmartCardLogon) { PULONG pulScData; struct FLAT_UNICODE_STRING { USHORT Length; USHORT MaximumLength; BYTE abdata[1]; }; struct FLAT_UNICODE_STRING *pFlatUnicodeString; PWLX_SC_NOTIFICATION_INFO ScInfo = NULL ; // // Get the set of strings indicating the reader and CSP // to be used for the smart card. We will pass this info // down to RAS. // pWlxFuncs->WlxGetOption( pGlobals->hGlobalWlx, WLX_OPTION_SMART_CARD_INFO, (ULONG_PTR *) &ScInfo); if ( !ScInfo ) { return FALSE; } // // Validate the SC info against some common user // errors // if ( ( ScInfo->pszReader ) && ( ScInfo->pszCard == NULL ) ) { // // The card could not be read. Might not be // inserted correctly. // LocalFree(ScInfo); return FALSE; } if ( ( ScInfo->pszReader ) && ( ScInfo->pszCryptoProvider == NULL ) ) { // // Got a card, but the CSP for it could not be // found. // LocalFree(ScInfo); return FALSE; } pvScData = ScBuildLogonInfo(ScInfo->pszCard, ScInfo->pszReader, ScInfo->pszContainer, ScInfo->pszCryptoProvider ); LocalFree(ScInfo); if ( ! pvScData ) { return FALSE ; } pulScData = (PULONG) pvScData; ZeroMemory(&eapinfo, sizeof(struct EAPINFO)); eapinfo.dwSizeofEapInfo = *pulScData; eapinfo.pbEapInfo = (BYTE *) pvScData; eapinfo.dwSizeofPINInfo = sizeof(UNICODE_STRING) + (sizeof(TCHAR) * (1 + lstrlen(pGlobals->PasswordString.Buffer))); // // Flatten out the unicode string. // pFlatUnicodeString = LocalAlloc(LPTR, eapinfo.dwSizeofPINInfo); if(NULL == pFlatUnicodeString) { if(NULL != pvScData) { LocalFree(pvScData); } return (FALSE); } pFlatUnicodeString->Length = pGlobals->PasswordString.Length; pFlatUnicodeString->MaximumLength = pGlobals->PasswordString.MaximumLength; lstrcpy((LPTSTR) pFlatUnicodeString->abdata, (LPTSTR) pGlobals->PasswordString.Buffer); eapinfo.pbPINInfo = (BYTE *) pFlatUnicodeString; pEapInfo = &eapinfo; } ZeroMemory( &info, sizeof(info) ); info.dwSize = sizeof(info); info.hwndOwner = hwndOwner; info.dwFlags = RASPBDFLAG_NoUser; info.pCallback = MyRasCallback; info.dwCallbackId = (ULONG_PTR) pGlobals; info.reserved2 = (ULONG_PTR) pEapInfo; fConnected = RasPhonebookDlg( NULL, NULL, &info ); if (info.dwError == STATUS_TIMEOUT) *pfTimedOut = TRUE; if( (pEapInfo) && (pEapInfo->pbPINInfo)) { LocalFree(pEapInfo->pbPINInfo); } if(NULL != pvScData) { LocalFree(pvScData); } return fConnected; } BOOL IsRASServiceRunning() { BOOL bRet = FALSE; // assume the service is not running SC_HANDLE hServiceMgr; hServiceMgr = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); if (hServiceMgr != NULL) { SC_HANDLE hService = OpenService(hServiceMgr, TEXT("RASMAN"), SERVICE_QUERY_STATUS); if (hService != NULL) { SERVICE_STATUS status; if (QueryServiceStatus(hService, &status) && (status.dwCurrentState == SERVICE_RUNNING)) { // the RAS service is running bRet = TRUE; } CloseServiceHandle(hService); } CloseServiceHandle(hServiceMgr); } return bRet; } // we need to treat RAS connections made by the system luid as created by the user. // this allows us to "do the right thing" when a connection is made from the C-A-D dialog // before any user is logged in __inline BOOL IsEqualOrSystemLuid(PLUID pLuid, PLUID pUserLuid) { BOOL bRet = FALSE; static LUID luidSystem = SYSTEM_LUID; if (RtlEqualLuid(pLuid, pUserLuid) || RtlEqualLuid(pLuid, &luidSystem)) { // return true if pLuid matches the users luid or the system luid bRet = TRUE; } return bRet; } BOOL HangupRasConnections( PGLOBALS pGlobals ) { DWORD dwError; RASCONN rasconn; RASCONN* prc; DWORD cbSize; DWORD cConnections; HLOCAL pBuffToFree = NULL; if (!IsRASServiceRunning()) { return TRUE; } prc = &rasconn; prc->dwSize = sizeof(RASCONN); cbSize = sizeof(RASCONN); dwError = RasEnumConnections(prc, &cbSize, &cConnections); if (dwError == ERROR_BUFFER_TOO_SMALL) { pBuffToFree = LocalAlloc(LPTR, cbSize); prc = (RASCONN*)pBuffToFree; if (prc) { prc->dwSize = sizeof(RASCONN); dwError = RasEnumConnections(prc, &cbSize, &cConnections); } } if (dwError == ERROR_SUCCESS) { UINT i; for (i = 0; i < cConnections; i++) { if (IsEqualOrSystemLuid(&prc[i].luid, &pGlobals->LogonId)) { RasHangUp(prc[i].hrasconn); } } } if (pBuffToFree) { LocalFree(pBuffToFree); } return (dwError == ERROR_SUCCESS); }