Remote execution of client code from the server
When creating browser applications for Pick applications, people frequently ask how they can execute some code on the PC/client with instructions from the server. We do this all the time with terminal emulators in our “thick client” user interfaces. But what about doing this with a browser?
In various circles this kind of operation is typically called a Remote Procedure Call (RPC) or remote invocation. It’s easy to get a server to execute code, that’s the nature of Web Services, SaaS, SOA, etc. But getting the server to control a client, especially with a browser, is a different story because there are security concerns, and we often don’t know anything about the client-side environment.
In the Pick world, when we’re using something like AccuTerm or wIntegrate, we already have the application installed on the PC. The user has already given their permission – they know us, we know them, there is a trust relationship. So it’s easy to have the server execute random commands on the client – because we want that to happen. I’ve had discussions with Linux developers to get Linux emulators to do this and they cringe at the thought. They’re right to do so, except that for intranet applications we see RPC like this as a feature, while they think of the emulator as being used from outside a network, in which case RPC is a vulnerability. So don’t be surprised when people tell you “you can’t do that” when you have already been doing it for years.
It doesn’t matter if you are writing your browser UI with ASP.NET, DesignBais, PHP, or some other technology. It doesn’t matter if the executable is written with .NET or Java or some other language. The solutions are all similar. Note that I’m only discussing Windows here. While this can all be done with Mac and Linux, the techniques are the same but browser and OS restrictions and nuances make the solution different for each platform. So you can’t just ask every user to execute your C++ program, you need to know which platform the user has and then present them with OS-specific options. This can be done by checking the User-Agent on the server. Now that I’ve mentioned that aspect of the solution, let’s proceed with a Windows-centric discussion, knowing that it can be applied to other platforms as well.
Over the years browser security has been improved specifically to prevent a server from issuing commands to a client PC. The user has given their permission for the browser application to serve pages from random sites – they do not want to give random sites permission to execute code through this vehicle. Over the last 18 years or so, daily news has frequently lit up with alerts about browser security holes, vulnerabilities, hacks, intrusions, malware, trojans, and malicious attacks. These days current browsers are fairly well locked down. So you’re going to find that you can’t (easily) use the browser itself to execute code.
There are two approaches to executing code based on activity in the browser: user a browser plugin or execute a separate application which is installed on the client PC.
One way to execute client-side code is by using a custom browser addon which watches inbound pages for instructions. People load plugins all the time. If you’re a FireFox user you’ve probably installed a number of the hundreds of addons available – same for IE. Tools are available to create plugins for IE (I do this) and Firefox (I generally don’t do this). Browser-specific tools need to be maintained and can be difficult to implement. If you Google for “IE addon” you’ll probably see references to COM, and if you Google for “firefox execute program” you’ll see references to UniversalXPConnect and security permissions. Suffice to say, this is tough stuff.
Another way to execute code from within the browser is by embedding an invisible Silverlight or Flash plugin. This is easier because the first time it’s run it will ask the user for permission and should be transparent from then-forward. These tools are (largely) browser-independent. I recommend you Google for terms like “flash execute exe” (you’ll see references to fscommand) or “silverlight execute exe”. Another advantage of using Silverlight is that if you’re already a .NET developer then you don’t need a new skill-set to accomplish this task.
No matter how you execute “something” on the PC, we need “something” to execute. You generally don’t want to expose your client PCs to execute any random command-line. You want to do something neat but you don’t want to completely expose your users to vulnerabilities from elsewhere. So you should load your own executable to each client PC and then pass instructions for what that code is to do. The user must be involved in this process of installing an application. It’s a program like any other installed with a Setup or .MSI installer. You did this with your terminal emulator and this is no different. Unless you’re exploiting a browser-specific bug, you’re not going to install this without the user being prompted for their permission. It’s best to provide users with a link, get them to download the code, and then interact with it as discussed below.
And rather than having a custom application installed to each user PC for each application that comes up, it’s best to have a single executable which can do a number of things based on instructions coming into the browser. Use common self-update mechanisms to get that program to do new things.
Now about those “instructions”. To be clear, what I’m suggesting is that you have your BASIC code send text to the browser which is then passed on to your executable for processing. You aren’t sending commands to the browser for processing. The browser simply becomes the vehicle to convey messages.
On the server side you work the instructions into your normal code flow. For DesignBais and FlashCONNECT users, your normal BASIC template code accepts a request and then goes through a series of CASE checks to see what the browser wants to do at that moment. Now you just add some new “stuff” in response to the requests. The thing is that you don’t want this “stuff” to display on the user page or to confuse your other functionality.
If you’re using DesignBais it would be fairly easy to inject JavaScript into your pages when required. I’ve documented how that works here. If you’re not using DesignBais you do whatever you normally do to pass JavaScript in your responses.
Now what happens with that script? Well, if you have a plugin then you need to work out exactly how to interact with that plugin from client-side script. The JavaScript tells the plugin to do something, the plugin passes the message to the client PC executable, and the task is done. If a response needs to be sent back then the process goes in reverse: the application might write data to a file, the plugin scrapes that up and sends it back to the server as an Ajax request.
Another way to have client/server interaction is to not use the browser at all. This has the advantage of making it look like your app (DesignBais, .NET, FlashCONNECT, etc) is doing all sorts of cool things without anything being done in the browser. In the executable that you load to client systems, add a polling mechanism to check the server occasionally for instructions. This needs to be done frequently so that it acts in sync with the browser. When you get a browser request in your DBMS, execute some BASIC code that creates instructions for the specific user/client. Returned a page as-normal to the user, and simultaneously send a message to the client-side program. Your app acts on the instructions, and it “looks” like the browser did something. Rather than polling, technologies these days allow for Push operations from server to client. That eliminates excessive polling and keeps everything responsive. While I open here by suggesting polling (Pull) because it’s fairly well understood, that’s also a very poor solution in terms of performance, so I strongly recommend using Push.
Yeah, there’s a lot of know-how that goes into making any of that happen. I’m outlining the steps to take here, not paving the road coast-to-coast. 🙂 Feel free to post a comment here or to email for assistance if you are working on a project like this.