Xamarin Android - VpnService is blocking all apps - c#

An app I'm designing uses the VpnService, along with the VpnService.Builder, classes to generate a VPN in order to block traffic from specific apps. According to the documentation over at developer.android.com, all apps should be allowed through the VPN until Builder.AddAllowedApplication or Builder.AddDisallowedApplication is called.
When my VPN service starts up, for some reason, all apps are being disallowed which is strange. As soon as I disconnect from the VPN, all apps become available again. I need to to allow all, unless otherwise specified (which is what the documentation says should be happening). I start the VPN by calling the following:
private string _sTag = typeof(VpnService).Name;
private VpnServiceBinder _objBinder;
private ParcelFileDescriptor _objVpnInterface = null;
private PendingIntent _objPendingIntent = null;
...
if (_objVpnInterface == null)
{
Builder objVpnBuilder = new Builder(this);
objVpnBuilder.AddAddress("10.0.0.2", 32);
objVpnBuilder.AddRoute("0.0.0.0", 0);
// Form the interface
_objVpnInterface = objVpnBuilder.SetSession("Squelch").SetConfigureIntent(_objPendingIntent).Establish();
// Disallow instagram as a test
objVpnBuilder.AddDisallowedApplication("com.instagram.android");
// Set flag
_bVpnIsRunning = true;
}
So in the above instance, instagram should be the only blocked app, but all traffic appears to be blocked (can't use the chrome app, facebook, etc). Is there something I am missing in regards to this? Should I be specifying something before/after establishing the interface? Any help or direction would be greatly appreciated!
Note: In case it matters, I am targeting android 6.0 and higher. I can provide more source if required.

addDisallowedApplication:
By default, all applications are allowed access, except for those denied through this method. Denied applications will use networking as if the VPN wasn't running.
AddDisallowedApplication excludes the application from your VPNService and allows it to continue to use the "non-VPN" networking stack.
addAllowedApplication:
Adds an application that's allowed to access the VPN connection
Note: You can use an allowed or disallowed list, but not both at the same time.
So lets say we want to "block" any Chrome package from accessing the normal networking stack and redirect any Chrome apps from accessing the network via our "blocking" VPN, we can add all Chrome app package names to our VPNService implementation.
Note: there are 4(?) different Chrome apps, alpha, beta, etc.... so lets just block any package that has the name chrome in it, not really ideal, but for an example it works.
using (var pm = Application.Context.PackageManager)
{
var packageList = pm.GetInstalledPackages(0);
foreach (var package in packageList)
{
if (package.PackageName.Contains("chrome"))
{
Log.Debug(TAG, package.PackageName);
builder.AddAllowedApplication(package.PackageName);
}
}
}
After you .Establish() the VPN connection, all Chrome applications networking will be redirected to your VPNService and thus blocked.

Related

How to connect To Skype For Business using UCMA

I have a problem when I call LyncClient.Get() from a Windows Service project, knowing that it works well if I test on a console application.
var lyncClient = LyncClient.GetClient();
Dictionary<PublishableContactInformationType, object> statusData =
new Dictionary<PublishableContactInformationType, object>
{
{PublishableContactInformationType.LocationName, _position},
{PublishableContactInformationType.Availability, ContactAvailability.Busy}
};
The exception I get is:
Microsoft.Lync.Model.ClientNotFoundException: The host process is not running
at Microsoft.Lync.Model.LyncClient.EnsureOI ()
to Microsoft.Lync.Model.LyncClient.GetClient (Boolean sideBySideLync)
When doing research I read that in Windows service, we cannot get the Lync client by calling GetClient() because the service process and Lync process are in different sessions, that's why I'm trying to work with UCMA or UCWA but I do not understand how it works!
What I am trying to do in my application is to change the position of the skype user from a service. As it is not possible to do it with Lync Client SDK, I have to work with UCWA SDK but I can't find an example that i can follow him, A suggestion !
You are not talking about UCMA, you are talking about the Lync Client SDK.
You can think of the SDK's as such:
Lync Client SDK
This SDK allows you to remote control the standard "Lync Client". You can use this SDK to automate the Lync Client for a user to do whatever you can to do OR to extend the functionality of the Lync Client (kind-of limited). To use this SDK the Lync Client must be running in the user you wish to automate / extend. You can't really run it in a windows service context.
Also all Lync Client applications "share" the one Lync Client "session".
There is an option to run the Lync Client SDK in a "side by side" mode, but that mode is very very limited (i.e. no UI) and in most cases is not that useful.
UCMA
This SDK is a SIP endpoint SDK. It allows you to create and use two main type types of SIP endpoints:
User Endpoints
Trusted Application Endpoints
With sip endpoints you can do almost everything that a Lync Client SDK can do when automating the Lync Client (i.e. make calls, answer calls, set presence, subscribe to presence changes, etc, etc). There are some limitations, no video call support. Makes it harder to handle some situations.
UCMA allows you to create "trusted applications" that allow you to create sip endpoints used to extend S4B infrastructure. "trusted applications" / "trusted application endpoints" are "trusted" within S4B and are allowed to do things that you can't normally do with a simple UCMA application e.g. IVR
So it depends on what you are trying to do depends on what SDK you should use.
UCMA applications can be used in windows service applications.
UCWA is a web SDK version of UCMA (kind-of). The UCWA is a lot more limited than the UCMA SDK but UCWA works for Skype for Business Online whereas the UCMA doesn't directly work with Skype for Business Online. You can get UCMA working with Skype for Business Online using federation but that requires on-premise S4B setup federated to Skype for Business Online which is a lot of work.
Update:
To answer the comment question, location is part of the "presence". So what you need to do to set the location is to set the current presence with a location. For UCWA, see this MSDN link on setting the presence. Following the example, change which link you use to the "location" href and post something like:
{"location":"my new location"}
Why do you do it using a service? You could do it with a small console application that would be running in the background and invisible, and started at session startup.
This way you wouldn't need to know the user's login/password, you only need to poll in your code to wait for the Skype for Business client to be started (which I assume would be shortly after the session start)
Here is an example of what I mean :
class Program
{
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
[DllImport("Kernel32")]
private static extern IntPtr GetConsoleWindow();
const int SW_HIDE = 0;
static void Main(string[] args)
{
// Let's hide the console window first ...
IntPtr hwnd;
hwnd = GetConsoleWindow();
ShowWindow(hwnd, SW_HIDE);
// I recommend you start a separate thread from here, I removed it for the sake of simplicity
Boolean clientConnected = false;
while (!clientConnected)
{
try
{
LyncClient lyncClient = LyncClient.GetClient();
clientConnected = true;
// Do your stuff here...
}
catch (ClientNotFoundException ex)
{
// Client not found : the client is probably not running...
// There is nothing to do besides wait and expect to have the user starting his client...
clientConnected = false; // not needed, just to highlight the fact that we are not connected yet
}
// Don't forget to make your application sleep/do nothing on regular intervals to avoid taking 100% CPU time while you are polling
}
}
Of course users could manually kill the application by looking at their Task Manager, but most end users don't do that.

Using Static Wrapper Class

In my search for a WebSockets library, I came across this website that provides Delphi and C# versions in download section. It grabbed my attention especially because the client-side of my application is developed using Delphi, and I'm trying to develop the server-side using C#.
Looking at the Chat sample for C#, I realized that it uses a wrapper class (sgcWebSocketLib) around the unmanaged DLL written in Delphi. Here is an excerpt from sgcWebSocketLib.cs:
public sealed class sgcWebSocketLib
{
private static volatile sgcWebSocketLib instance;
private static object syncRoot = new Object();
private sgcWebSocketLib()
{
}
public static sgcWebSocketLib Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
instance = new sgcWebSocketLib();
}
}
return instance;
}
}
... //the rest is omitted
}
and the code from Start button in Chat server (a typical WinForms application):
private void btnStart_Click(object sender, EventArgs e)
{
string vOptions = "";
... //setting options according to UI values
sgcWebSocketLib.Instance.Server_LoadOptions(vOptions);
sgcWebSocketLib.Instance.Server_Start();
}
Now, here is the actual question: this Chat server uses a static property of sgcWebSocketLib class, and starts sending/receiving WebSocket stuff. Can I use the same approach in an ASP.Net application (WebForms or MVC)? Can I write the Chat server in ASP.Net using this wrapper class?
PS: I know there is SignalR and maybe others. But it has some limitations (IIS 8, Windows Server 2012 requirement for WebSocket) beside the unanswered communication problem with a Delphi VCL client.
Yes you can.
You will just have to pay attention to the Idle Time-out settings for your worker process (defaults to 20 minutes) as well as your Recycling settings (default is once every 29 hours). You may want to disable both settings if you want your application to never be recycled / go idle regardless of other parameters.
Recycling / idling will cause the worker process to shutdown, thus you'll lose any static variable and they'll have to be re instantiated when the process starts back up.
Check this answer for more info.
In IIS < 8 you won't be able of bind the WebSocket port to the same port than the web application (that is exactly what IIS8 can do)
Even with IIS8, the AppDomain is unable to recycle if there are WebSockets connected. So using the info that #Xeaz provided may be good idea. Usually I keep them in separate applications, since there is no point in mixing a connection oriented app (WebSockets), with a request-response one (regular HTTP). The only favorable point in doing that with IIS8 is the fact that both can share the port, but that is not really an issue aside of open/map an additional TCP port in the network, since cookies do not mind the port and WebSocket is not even affected by the SOP.
If the client is using the WebSocket protocol RFC6455 correctly, it should not matter which implementation is connecting to. I develop a websocket server for .NET/Mono 4.5 that works on Windows 7, take it a look if you go with the .NET server option.

Trying to use Launcher.LaunchUriAsync in a Share Target app win Win 8

I’m building an app that acts as a share target for URI’s; it takes the URI then URL for invokes the browser to our web site for sharing. I have the code working using the sharing target sample, however Launcher.LaunchUriAsync is always failing when I’m outside the debugger. It doesn’t throw though so I’m having a hard time figuring out what the error might be; maybe some security context.
Any ideas? The code itself is pretty short; I get success = false running directly from the shell and invoking via Win-C/Share. I’ve made sure the manifest has all three networking declarations set. Other thoughts?
if (this.shareOperation.Data.Contains(StandardDataFormats.Uri))
{
Uri uri = await this.shareOperation.Data.GetUriAsync();
if (uri != null)
{
Uri tempUri;
Uri.TryCreate("http://www.mysite.com/#/search?v=results&bk=1.0&q="+uri.ToString(), UriKind.Absolute, out tempUri);
bool success = await Windows.System.Launcher.LaunchUriAsync(tempUri);
if (success) {
contentValue.Text += "Success invoking browser" + ":URL="+tempUri.ToString()+ Environment.NewLine;
} else {
contentValue.Text += "Fail invoking browser" + ":URL=" + tempUri.ToString() + Environment.NewLine;
}
}
}
A sharing target shouldn't be launching another application. Share targets are meant to be hosted inside the sharing pane, and should provide a quick, in-context way for the user to share content with your app or service.
In your case, perhaps you should host a WebView and navigate that to your service's URL?
There are several conditions that needs to be met in order to successfully call LaunchUriAsync.
As seen here on MSDN you need to ensure the following:
The calling app must be visible to the user when the API is invoked.
Unless you are calling this API from a Classic Windows application, this API must be called from within an ASTA thread (also known as a UI thread).
You must specify the privateNetworkClientServer capability in the manifest in order to launch intranet URIs, for example a file:/// URI pointing to a network location.
You cannot use this method to launch a URI in the local zone. For example, apps cannot use the file:/// protocol to access files on the local computer. Instead, you must use the Storage APIs to access files.
I guess that one of the first two conditions is why your code fails. (At least that was my problem)

How can I configure network access for the Windows Phone emulator?

I'm trying to debug an application that is making a WebRequest synchronously, ie.:
HttpWebRequest req = WebRequest.Create(new Uri("http://www.stackoverflow.com/")) as HttpWebRequest;
IAsyncResult res = req.BeginGetResponse(callback => { }, req);
while (!res.IsCompleted)
{
System.Threading.Thread.Sleep(100);
}
// Doesn't matter what's here, as `res.IsCompleted` never returns true
This is just to check that some of the application logic is "right", but it's getting stuck, with the IAsyncResult never reporting itself as complete.
To check, things, I tried to use Internet Explorer on the emulator, but found that is unable to find any webpages (including the built in favourites), which makes me think that the emulator is trying to use a specific network interface on my laptop, but there doesn't seem to be any way to configure it, or which interface to use? I have a suspicion that it may be trying to use a VPN interface, or a virtual adaptor like the one for VirtualBox. So, how can I configure it? additionally, would you expect requests made by the emulator to show up in Fiddler?
For the record, NetworkInterface.GetIsNetworkAvailable() returns true;
UPDATE:
It appears that updating my graphics driver (and associated reboot) allowed the emulator to access the real network (or at least guess the right adapter); however, res.IsCompleted still doesn't report true (and Fiddler shows the request has completed), so I'm a little confuddled.
Are you using a proxy? The Windows Phone emulator is tied to the currently active Internet Connection, as well as the proxy settings. Make sure those are set up correctly. Also, there might be a firewall blocking Internet access for XDE - check the settings too.
I would recommend getting Fiddler. Attempt to configure it to capture emulator traffic and see what information you can get from there.

How to create a simple c# http monitor/blocker?

I was reading that question (How to create a simple proxy in C#?) that is near of my wishes.
I simply want develop a c# app that, by example, monitors Firefox, IE, etc and logs all navigated pages. Depending of the visited page, I want to block the site (like a parental filter).
Code snippets/samples are good, but if you can just tell me some direction of that classes to use I will be grateful. :-)
I’ll answer appropriate for a parent: ala "Parental Controls"
You can start out with a proxy server when the kids are less than about 10 years old. After that, they will figure out how to get around the proxy (or run their own client applications that bypass the proxy). In the early teen years, you can use raw sockets.
Type this program into Visual Studio (C#).
class Program
{
static void Main(string[] args)
{
try
{
byte[] input = BitConverter.GetBytes(1);
byte[] buffer = new byte[4096];
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP);
s.Bind(new IPEndPoint(IPAddress.Parse("192.168.1.91"), 0));
s.IOControl(IOControlCode.ReceiveAll, input, null);
int bytes = 0;
do
{
bytes = s.Receive(buffer);
if (bytes > 0)
{
Console.WriteLine(Encoding.ASCII.GetString(buffer, 0, bytes));
}
} while (bytes > 0);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
}
Note that this is just a “snippet”, lacking appropriate design and error checking. [Please do not use 'as-is' - you did request just a head start] Change the IP address to your machine. Run the program AS Administrator (use “runas” on the command line, or right-click “Run as Administrator”). Only administrators can create and use raw sockets on modern versions of windows. Sit back and watch the show.
All network traffic is delivered to your code (displayed on the screen, which will not look nice, with this program).
Your next step is to create some protocol filters. Learn about the various internet application protocols (assuming you don't already know), modify the program to examine the packets. Look for HTTP protocol, and save the appropriate data (like GET requests).
I personally have setup filters for AIM (AOL Instant Messenger), HTTP, MSN messenger (Windows Live Messenger), POP, and SMTP. Today, HTTP gets just about everything since the kids prefer the facebook wall to AIM nowadays.
As the kids reach their early-to-mid teenage years, you will want to back-off on the monitoring. Some say this is to enable the kids to “grow up”, but the real reason is that “you don’t wanna know”. I backed off to just collecting URLs of get requests, and username/passwords (for emergency situations) that are in clear text (pop, basic auth, etc.).
I don't know what happens in late teen years; I cannot image things getting much worse, but I am told that "I have not seen anything yet".
Like someone earlier said, this only works when run on the target machine (I run a copy on all of the machines in the house). Otherwise, for simple monitoring check your router - mine has some nice logging features.
My final comment is that this application should be written in C/C++ against the Win32 API directly, and installed as a service running with administrative rights on the machine. I don't think this type of code is appropriate for managed c#. You can attach a UI in C# for monitoring and control. You have to engineer the code so as to have zero noticeable effect on the system.
Your approach will depend on whether or not you are installing this application on the same box you are using to browse or on a separate proxy server.
If you are doing this on a separate server it will be easier to accomplish this in C# / managed code, as you will be simply writing a C# proxy server that client pc's will have point to. System.Net.Sockets namespace TcpListener and TcpClient will be your friend.
If, however, you are installing this on the same machine then take a look WinPcap and and SharpPCap and perhaps Fiddler for some ideas.
Hope that helps.

Categories