Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Connect to Enterprise WiFi network issue



  • Hello!

    I want to connect to WiFi Enterprise network in my application. I have a Radius Server configured and using Windows WiFi Manager I can connect to this network.

    Code:

            QOAuth2AuthorizationCodeFlow oauth2;
            QOAuth2AuthorizationCodeFlow *serverReplyHandler = new QOAuthHttpServerReplyHandler(1812, this);
            oauth2.setReplyHandler(serverReplyHandler);
            connect(&oauth2, &QOAuth2AuthorizationCodeFlow::authorizeWithBrowser, &QDesktopServices::openUrl);
            connect(&oauth2, &QOAuth2AuthorizationCodeFlow::statusChanged, [=](QAbstractOAuth::Status status) {
                if (status == QAbstractOAuth::Status::Granted) {
                    qDebug() << "Granted";
                } else if (status == QAbstractOAuth::Status::RefreshingToken) {
                    qDebug() << "RefreshingToken";
                } else if (status == QAbstractOAuth::Status::NotAuthenticated) {
                    qDebug() << "NotAuthenticated";
                } else if (status == QAbstractOAuth::Status::TemporaryCredentialsReceived) {
                    qDebug() << "TemporaryCredentialsReceived";
                }
            });
            oauth2.setAuthorizationUrl(QUrl("192.168.0.X"));
            oauth2.setAccessTokenUrl(QUrl("192.168.0.X"));
            oauth2.setClientIdentifier("TestUser");
            oauth2.setClientIdentifierSharedKey("TestPassword");
            oauth2.grant();
    

    It displays the following issue:
    QOAuth2AuthorizationCodeFlow::buildAuthenticateUrl: 192.168.0.X?client_id=TestUser&redirect_uri=http://localhost:1812/&response_type=code&scope&state=YNC4svub ShellExecute '192.168.0.X?client_id=TestUser&redirect_uri=http://localhost:1812/&response_type=code&scope&state=YNC4svub' failed (error 2).

    I want to know how to make authentication with a Radius Server using my application? I think the problem is with setAuthorizationUrl and setAccessTokenUrl urls. Thanks in advance for your help.


  • Lifetime Qt Champion

    Hi,

    Isn't the connection to that server handled by the system ?



  • @sgaist

    I used Wlan API for personal WiFi networks. What do you mean by handled by the system? Thanks.



  • @sgaist

    I think you are right. I have found some Wlan API methods WlanSetProfileEapXmlUserData: https://docs.microsoft.com/en-us/windows/win32/api/wlanapi/nf-wlanapi-wlansetprofileeapxmluserdata, https://docs.microsoft.com/en-us/windows/win32/eaphost/peap-ms-chapv2-user-properties

    I will try these methods and reply later. Thanks.



  • I tried to set the Enterprise profile using WlanSetProfile function, it fails with 1206 error means bad profile. Also, I tried to use WlanSetProfileEapXmlUserData function, it fails with 1168 (ERROR_NOT_FOUND) error. It is strange, setting the profile to a personal network works well with WlanSetProfile function. Any ideas? Thanks.



  • After some investigation, I have found that <MsChapV2:LogonDomain>ias-domain</MsChapV2:LogonDomain> is optional and not needed for the profile. When previous connection to the Enterprise WiFi network was made by Windows WiFi Manager, it successfully sets the profile using WlanSetProfileEapXmlUserData method and connects. When removing the stored profile and try to set the profile again using WlanSetProfileEapXmlUserData method, it displays 1168 (ERROR_NOT_FOUND) error.

    First solution:
    So, I think something is missing, maybe I need to set WlanSetProfileEapUserData (function sets user credentials) before the WlanSetProfileEapXmlUserData (function sets xml profile, which contains also user credentials). Then, maybe Windows will verify this user credentials and sets the profile successfully. I will try it and reply later.



  • Also, I think it could be following:

    Second solution:

    1. WlanSetProfileEapUserData sets user credentials for profile;
    2. Use WlanSetProfileEapXmlUserData to set this xml profile without user credentials: https://docs.microsoft.com/en-us/windows/win32/nativewifi/wpa2-enterprise-with-peap-mschapv2-profile-sample

    The reason for the second approach, because this profile: https://docs.microsoft.com/en-us/windows/win32/eaphost/peap-ms-chapv2-user-properties contains only user credentials, but does not contains the network information, for example, authentication, encryption data. I will try my second solution.



  • From Microsoft docs, only one method should be used, WlanSetProfileEapUserData is equivalent to WlanSetProfileEapXmlUserData. So, I will use WlanSetProfileEapXmlUserData to set XML string. I think my XML string profile is wrong.



  • I tried WlanSetProfileEapUserData version instead of the function WlanSetProfileEapXmlUserData:

    Code:

    EAP_METHOD_TYPE type;
    DWORD dwUserDataSize = 0;
    LPBYTE pbUserData = nullptr;
    DWORD dwResult = WlanSetProfileEapUserData(hClient, &adapterGUID, wlanProfile, type, WLAN_SET_EAPHOST_DATA_ALL_USERS, dwUserDataSize, pbUserData, nullptr);
    

    But I get 1168, the same error. Here is my profile example:

    <?xml version="1.0"?>
    <WLANProfile xmlns="http://www.microsoft.com/networking/WLAN/profile/v1">
    	<name>Test</name>
    	<SSIDConfig>
    		<SSID>
    			<hex>436F62726154656B</hex>
    			<name>Test</name>
    		</SSID>
    	</SSIDConfig>
    	<connectionType>ESS</connectionType>
    	<connectionMode>auto</connectionMode>
    	<MSM>
    		<security>
    			<authEncryption>
    				<authentication>WPA2</authentication>
    				<encryption>AES</encryption>
    				<useOneX>true</useOneX>
    			</authEncryption>
    			<PMKCacheMode>enabled</PMKCacheMode>
    			<PMKCacheTTL>720</PMKCacheTTL>
    			<PMKCacheSize>128</PMKCacheSize>
    			<preAuthMode>disabled</preAuthMode>
    			<OneX xmlns="http://www.microsoft.com/networking/OneX/v1">
    				<authMode>user</authMode>
    				<EAPConfig><EapHostConfig xmlns="http://www.microsoft.com/provisioning/EapHostConfig"><EapMethod><Type xmlns="http://www.microsoft.com/provisioning/EapCommon">25</Type><VendorId xmlns="http://www.microsoft.com/provisioning/EapCommon">0</VendorId><VendorType xmlns="http://www.microsoft.com/provisioning/EapCommon">0</VendorType><AuthorId xmlns="http://www.microsoft.com/provisioning/EapCommon">0</AuthorId></EapMethod><Config xmlns="http://www.microsoft.com/provisioning/EapHostConfig"><Eap xmlns="http://www.microsoft.com/provisioning/BaseEapConnectionPropertiesV1"><Type>25</Type><EapType xmlns="http://www.microsoft.com/provisioning/MsPeapConnectionPropertiesV1"><ServerValidation><DisableUserPromptForServerValidation>false</DisableUserPromptForServerValidation><ServerNames></ServerNames><TrustedRootCA>50 13 a8 fc 50 2c 42 a8 e9 7a bb 6b 26 3f a9 6c 23 1e fd 6f </TrustedRootCA></ServerValidation><FastReconnect>true</FastReconnect><InnerEapOptional>false</InnerEapOptional><Eap xmlns="http://www.microsoft.com/provisioning/BaseEapConnectionPropertiesV1"><Type>26</Type><EapType xmlns="http://www.microsoft.com/provisioning/MsChapV2ConnectionPropertiesV1"><UseWinLogonCredentials>false</UseWinLogonCredentials></EapType></Eap><EnableQuarantineChecks>false</EnableQuarantineChecks><RequireCryptoBinding>false</RequireCryptoBinding><PeapExtensions><PerformServerValidation xmlns="http://www.microsoft.com/provisioning/MsPeapConnectionPropertiesV2">true</PerformServerValidation><AcceptServerName xmlns="http://www.microsoft.com/provisioning/MsPeapConnectionPropertiesV2">true</AcceptServerName><PeapExtensionsV2 xmlns="http://www.microsoft.com/provisioning/MsPeapConnectionPropertiesV2"><AllowPromptingWhenServerCANotFound xmlns="http://www.microsoft.com/provisioning/MsPeapConnectionPropertiesV3">true</AllowPromptingWhenServerCANotFound></PeapExtensionsV2></PeapExtensions></EapType></Eap></Config></EapHostConfig></EAPConfig>
    			</OneX>
    		</security>
    	</MSM>
    	<MacRandomization xmlns="http://www.microsoft.com/networking/WLAN/profile/v3">
    		<enableRandomization>false</enableRandomization>
    	</MacRandomization>
    </WLANProfile>
    

    So, WlanSetProfileEapXmlUserData and WlanSetProfileEapUserData failed with 1168 (ERROR_NOT_FOUND / ELEMENT_NOT_FOUND) error. Any ideas? Thanks.


  • Lifetime Qt Champion

    No I don't. You should bring that to the Microsoft developer network forum.



  • @SGaist

    Yes, I asked it on MSDN, but it seems that even Microsoft do not know what causing such issue :)


  • Lifetime Qt Champion

    Did you discover an "an unknown feature" ?

    Can you post the link to your thread over there ? It might become useful over time.



  • @SGaist

    Hello!

    Yes, of course: https://social.msdn.microsoft.com/Forums/en-US/1028091a-d39d-4f67-b802-625e39d7a2ae/connect-to-enteprise-wifi-network-issue?forum=windowsgeneraldevelopmentissues

    Also, I am still investigating this issue. There are three options:

    1. Using WlanSetProfileEapXmlUserData lead to 1168 error because the profile is always wrong.
    2. Using WlanSetProfileEapUserData also lead to 1168 error, but I think the reason, due to EAP_METHOD_TYPE struct, because from the MS docs: An EAP_METHOD_TYPE structure that contains the method for which the caller is supplying EAP user credentials.. But I can not provide the username and password to this struct because it only have eapType and dwAuthorId:
    typedef struct _EAP_METHOD_TYPE {
      EAP_TYPE eapType;
      DWORD    dwAuthorId;
    } EAP_METHOD_TYPE;
    

    Checking EAP_TYPE structure also does not have the ability to set username and password:

    typedef struct _EAP_TYPE {
      BYTE  type;
      DWORD dwVendorId;
      DWORD dwVendorType;
    } EAP_TYPE;
    

    But there is EapUsernamePasswordCredential structure (https://docs.microsoft.com/en-us/windows/win32/api/eaptypes/ns-eaptypes-eapusernamepasswordcredential), so I can set the user credentials, but WlanSetProfileEapUserData does not accept it and displays compilation errors, because the 4th parameter should be only EAP_METHOD_TYPE and not EapUsernamePasswordCredential:

    typedef struct _EapUsernamePasswordCredential {
      LPWSTR username;
      LPWSTR password;
    } EapUsernamePasswordCredential;
    

    So, the 3rd option is:
    3. Use WlanSetProfile to set Enterprise profile. It successfully sets the Enterprise profile, but it only accepts this profile without credentials. With credentials it lead to 1206 error code, which means: The profile invalid according to the schema / ERROR_BAD_PROFILE.
    I think the WlanSetProfile must work with combination of one more method to set the user credentials but it is missing.

    These 3 options are failed for me.



  • I figured it out! So, to resolve this issue you must do the following steps:

    1. Set the profile without credentials using WlanSetProfile (I used imported profile from netsh with some modifications)

    2. Then set the xml profile below with your username and password to WlanSetProfileEapXmlUserData:

    <?xml version="1.0" ?> 
     <EapHostUserCredentials xmlns="http://www.microsoft.com/provisioning/EapHostUserCredentials" 
       xmlns:eapCommon="http://www.microsoft.com/provisioning/EapCommon" 
       xmlns:baseEap="http://www.microsoft.com/provisioning/BaseEapMethodUserCredentials">
       <EapMethod>
         <eapCommon:Type>26</eapCommon:Type> 
         <eapCommon:AuthorId>0</eapCommon:AuthorId> 
       </EapMethod>
       <Credentials xmlns:eapUser="http://www.microsoft.com/provisioning/EapUserPropertiesV1" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xmlns:baseEap="http://www.microsoft.com/provisioning/BaseEapUserPropertiesV1" 
         xmlns:MsPeap="http://www.microsoft.com/provisioning/MsPeapUserPropertiesV1" 
         xmlns:MsChapV2="http://www.microsoft.com/provisioning/MsChapV2UserPropertiesV1">
         <baseEap:Eap>
           <baseEap:Type>26</baseEap:Type> 
           <MsChapV2:EapType>
             <MsChapV2:Username>test</MsChapV2:Username> 
             <MsChapV2:Password>test</MsChapV2:Password> 
           </MsChapV2:EapType>
         </baseEap:Eap>
       </Credentials>
     </EapHostUserCredentials>
    
    1. Then use WlanConnect function and callback function to verify the connection.

    It all good, but I get another issue:

    229377 ("The operation was cancelled.")

    It was the reason code that reports 229377 code, I think it returned such code because I opened the Windows WiFi Manager from the taskbar. The actual NotificationCode returns code 8 (wlan_notification_acm_scan_fail) and then 11 (wlan_notification_acm_connection_attempt_fail). I am still investigating this issue. Thanks.



  • Also, from MS docs:

    wlan_notification_acm_scan_fail:

    A scan for connectable networks failed.
    
    The pData member of the WLAN_NOTIFICATION_DATA structure points to a WLAN_REASON_CODE data type value that identifies the reason the WLAN operation failed.
    

    So, I checked the pData when this issue occurs and it returns the following reason:

    wlan_notification_acm_scan_fail
    "The operation was successful."
    

    But the network is not connected, it is strange.



  • Hello!
    I have fixed this issue. The problem was because the PerformServerValidation was set to true and it displayed the notification dialog to verify the certificate on Windows that's why it returned wlan_notification_acm_scan_fail "The operation was successful.".

    Setting the PerformServerValidation  to false fixed the issue (WlanSetProfile function).

    <PerformServerValidation xmlns=\"http://www.microsoft.com/provisioning/MsPeapConnectionPropertiesV2\">false</PerformServerValidation>
    

    Also, for WlanSetProfileEapXmlUserData function I provided this profile:

    <?xml version="1.0" ?>
    <EapHostUserCredentials
    xmlns="http://www.microsoft.com/provisioning/EapHostUserCredentials"
    xmlns:eapCommon="http://www.microsoft.com/provisioning/EapCommon"
    xmlns:baseEap="http://www.microsoft.com/provisioning/BaseEapMethodUserCredentials">
    <EapMethod>
    <eapCommon:Type>25</eapCommon:Type>
    <eapCommon:AuthorId>0</eapCommon:AuthorId>
    </EapMethod>
    <Credentials
    xmlns:eapUser="http://www.microsoft.com/provisioning/EapUserPropertiesV1"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:baseEap="http://www.microsoft.com/provisioning/BaseEapUserPropertiesV1"
    xmlns:MsPeap="http://www.microsoft.com/provisioning/MsPeapUserPropertiesV1"
    xmlns:MsChapV2="http://www.microsoft.com/provisioning/MsChapV2UserPropertiesV1">
    <baseEap:Eap>
    <baseEap:Type>25</baseEap:Type>
    <MsPeap:EapType>
    <baseEap:Eap>
    <baseEap:Type>26</baseEap:Type>
    <MsChapV2:EapType>
    <MsChapV2:Username>username</MsChapV2:Username>
    <MsChapV2:Password>password</MsChapV2:Password>
    </MsChapV2:EapType>
    </baseEap:Eap>
    </MsPeap:EapType>
    </baseEap:Eap>
    </Credentials>
    </EapHostUserCredentials>
    

    Now it connects successfully to Enterprise network. The issue is resolved. Thank you.


  • Lifetime Qt Champion

    Nice debugging !

    Thanks for the feedback and thorough description !



  • @Cobra91151 Hi, would you mind sharing the xml profile that you set as well? I'm not able to make the windows wifi popup not show. Thank you!


Log in to reply