locked
[UWP][DesktopBridge] Can "uap4:LoopbackAccessRules" be used to allow TCP communication between UWP and Win32 executable? RRS feed

  • Question

  • For example, in the Desktop Bridge sample project:

    https://github.com/Microsoft/DesktopBridgeToUWP-Samples/tree/master/Samples/AppServiceBridgeSample_C%2B%2B

    Instead of using the AppService as shown in the sample, I would like to start a TCP listening server (Win32Process_CPP.exe) and connect to that TCP server from the UWP app.

    Such usage scenario is already possible but it requires end-users to use "CheckNetIsolation" command and add the app to the exempted list. I hope such manual changes can be skipped by somehow adding the "uap4:LoopbackAccessRules" extension.

    https://docs.microsoft.com/en-us/uwp/schemas/appxpackage/uapmanifestschema/element-uap4-loopbackaccessrules

    Is this possible? When should we actually use "uap4:LoopbackAccessRules"? Can someone please show an example of how "uap4:LoopbackAccessRules" is correctly used?

    Thanks.

    Sunday, January 7, 2018 2:44 AM

All replies

  • Hello choung.park,

    I am trying to consult for your this issue, it may be some time delay, appreciate your patience in advance.

    Best regards,

    Breeze


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, January 8, 2018 9:29 AM
  • Thank you. Looking forward to your answers!

    Best regards,
    Choung
    Tuesday, January 9, 2018 12:39 AM
  • Replacing the AppService in the sample with a TCP listener service shouldn't need any changes for network isolation. Loopback within the apppackage is allowed by default.

    If you want your listener service to be in a different app package then you'll need to deal with loopback restrictions. You can use the desktop bridge to package the service in its own appx and then enable loopback by that app's package family name.

    Per the documentation you linked, LoopbackAccessRules consist of a collection of Rules which have a Direction (in or out) and a PackageFamilyName (of the package the rule allows communication with).

    You'll end up with something like the following to allow XBoxApp to connect to your app or your app to connect to Calc:

            <uap4:Extension Category="windows.loopbackAccessRules">
              <uap4:LoopbackAccessRules>
                <uap4:Rule Direction="in" PackageFamilyName="Microsoft.XboxApp_36.36.12003.0_x64__8wekyb3d8bbwe" />
                <uap4:Rule Direction="out" PackageFamilyName="Microsoft.WindowsCalculator_10.1712.3351.0_x64__8wekyb3d8bbwe" />
              </uap4:LoopbackAccessRules>
            </uap4:Extension>

    LoopbackAccessRules: https://docs.microsoft.com/en-us/uwp/schemas/appxpackage/uapmanifestschema/element-uap4-loopbackaccessrules

    Rule: https://docs.microsoft.com/en-us/uwp/schemas/appxpackage/uapmanifestschema/element-uap4-rule

    The Package Family Name is computed from the Package name (in the appxmanifest) and other hashed information. You can find it in the Packaging tab of the Manifest editor in Visual Studio or in powershell with the get-appxpackage cmdlet (https://technet.microsoft.com/en-us/library/hh856044.aspx )

    Friday, January 19, 2018 12:39 AM
  • Thank you for your answer! But I couldn't make it work...

    > Replacing the AppService in the sample with a TCP listener service shouldn't need any changes for network isolation.
    > Loopback within the apppackage is allowed by default.

    Doesn't seems to be true. TCP listeners for localhost seem to be allowed only within an app (= single process). For example, I can setup a TCP localhost listener on MainPage and access it from another page on a different window created from ApplicationViewSwitcher.

    But for the AppService sample, there are two separate processes (UWP and CPP) and network isolation seems to be applied even though they are within the same package. I'm not sure if this is "by design" or just a bug...

    Anyhow, here are how I tested using the AppService CPP sample (please ignore the possible memory leaks... it's just a sample :-)):

    1. add the folliwing to AppServiceBridge.xaml.cs

    using System.Diagnostics;
    
    ...
    
    private async void SendRequest_Click(object sender, RoutedEventArgs e)
    {
    	...
    
    	TestTcp();
    }
    
    private async void TestTcp()
    {
    	Debug.WriteLine("FullName: " + Windows.ApplicationModel.Package.Current.Id.FullName);
    	Debug.WriteLine("FamilyName: " + Windows.ApplicationModel.Package.Current.Id.FamilyName);
    
    	try {
    
    		using(StreamSocket socket = new StreamSocket()) {
    
    			await socket.ConnectAsync((new HostName("127.0.0.1")), "50930");
    			Debug.WriteLine("Successfully connected!");
    			}
    		}
    	catch(Exception ex) {
    		Debug.WriteLine(ex.Message);
    		}
    }
    


    2. add the folliwing to Win32Process_CPP.cpp

    #include "stdafx.h"
    #pragma comment(lib, "Ws2_32.lib")
    
    ...
    
    DWORD WINAPI THREAD_AcceptLocal(void *pUserParam)
    {
    	SOCKET			SOCKET_accept;
    	SOCKADDR_IN		SOCKADDR_ipv4;
    	int				iSockAddrLen;
    
    	while(true) {
    
    		SOCKET_accept = ::accept(*((SOCKET *)pUserParam), (SOCKADDR *)&SOCKADDR_ipv4, &iSockAddrLen);
    		if(SOCKET_accept == INVALID_SOCKET) {
    			break;
    			}
    
    		closesocket(SOCKET_accept);
    		}
    
    	return 0;
    }
    
    void StartTcpServer()
    {
    	SOCKET			SOCKET_listen;
    	SOCKADDR_IN		SOCKADDR_ipv4;
    	WSADATA			wsaData;
    
    	WSAStartup(MAKEWORD(2, 2), &wsaData);
    
    	SOCKET_listen = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    	ZeroMemory(&SOCKADDR_ipv4, sizeof(SOCKADDR_IN));
    
    	SOCKADDR_ipv4.sin_family = AF_INET;
    	SOCKADDR_ipv4.sin_port = htons(50930);
    	SOCKADDR_ipv4.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
    
    	if((::bind(SOCKET_listen, (SOCKADDR *)&SOCKADDR_ipv4, sizeof(SOCKADDR_IN)) == 0)
    		&& (::listen(SOCKET_listen, SOMAXCONN) == 0)) {
    
    		CreateThread(NULL, 0, THREAD_AcceptLocal, &SOCKET_listen, 0, NULL);
    		}
    }
    
    /// <summary>
    /// Creates an app service thread
    /// </summary>
    int main(Platform::Array<Platform::String^>^ args)
    {
    	StartTcpServer();
    	
    	...
    	
    }
    

    3. Uncheck "Allow local network loopback" from UWP project [ Properties ] -> [ Debug ]

    4. Run and tap "Launch Background Process" to launch the CPP binary

    5. Tap "Send Request to Background Process"

    Instead of "Successfully connected!", I get "A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond." on Visual Studio "Output" pane.

    if I re-enable "Allow local network loopback" debug option, I get "Successfully connected!" as expected.


    So, I tried <uap4:Extension Category="windows.loopbackAccessRules">:

    In the Package.appxmanifest, I added

    <Package
    ...
    xmlns:uap4="http://schemas.microsoft.com/appx/manifest/uap/windows10/4"
    ...
    IgnorableNamespaces="uap uap4 mp rescap desktop"
    >
    
    ...
    
    <desktop:Extension Category="windows.fullTrustProcess" Executable="Win32Process_CPP.exe" />
    <uap4:Extension Category="windows.loopbackAccessRules">
      <uap4:LoopbackAccessRules>
        <uap4:Rule Direction="in" PackageFamilyName="Microsoft.AppServiceBridge_1.0.0.0_x64__8wekyb3d8bbwe" />
        <uap4:Rule Direction="out" PackageFamilyName="Microsoft.AppServiceBridge_1.0.0.0_x64__8wekyb3d8bbwe" />
      </uap4:LoopbackAccessRules>
    </uap4:Extension>
    
    ...

    I also tried using "Microsoft.AppServiceBridge_8wekyb3d8bbwe" for the PackageFamilyName and changing "<uap4:Extension Category="windows.loopbackAccessRules">" to "<uap4:Extension Category="windows.loopbackAccessRules" Executable="Win32Process_CPP.exe" EntryPoint="Windows.FullTrustApplication">".

    But nothing worked...

    Any suggestions?

    Friday, January 19, 2018 10:48 PM
  • The loopbackAccessRules are designed to help with connecting to other app packages, not to your own, where (in general) that's not necessary as loopback is allowed. It looks like your desktop app being full trust threw a curveball at how this works. I haven't tracked this all the way down, but the behavior suggests that since it's not running fully in the package's security context it's not being allowed as part of the package.

    Friday, January 26, 2018 1:09 AM
  • I'm simply trying to find a way to continuously communicate with the desktop executable from UWP. AppService can only provide message/event driven communication. We need stream based TCP like communication to reuse our existing codes and salvage legacy devices.

    We could ask end users to use CheckNetIsolation.exe and add the app to the exempt list, but such extra step shouldn't be necessary since the project already has the "FullTrust" permission and both executables are in the same app package...

    Friday, January 26, 2018 10:31 AM