MunichJS: Speech About Internationalization of HTML5 Apps and Using Encapsulator

Today there was a JavaScript meetup of MunichJS in Feldkirchen near Munich (Germany). MunichJS is a user group in Munich for developers that meets monthly to discuss topics on JavaScript and ECMAScript.

I was invited to give a speech there about the topic “Run Internationalized HTML5 App as Native Windows Program”.

MunichJS: Speech About Internationalization of HTML5 Apps and Using Encapsulator

In the first part of the speech I presented a HTML5 app that uses a JavaScript library to easily localize all strings in the HTML and in the JavaScript part of the application. At the end of the speech I used the Intel AppUp Encapsulator to generate a MSI file for this app. This way the application ran natively on a Windows operating system. Download the PowerPoint presentation.

The example project used in my presentation can be downloaded in my post Internationalization: How to Localize HTML5 Projects?.

Telephony Event Notifications of Polycom Phones Using PHP

All current Polycom phones like the Polycom SoundPoint IP, the Polycom VVX 500/1500 or the Polycom SpectraLink series support event notifications. This is a great feature where the phone is sending a POST request to a previously defined URL for various telephony events.

While developing a PHP server application that should handle some of these events, I came across the problem that there is no data in the PHP array $_POST although the script is called by the Polycom phone correctly.

After doing some investigation I found out that the data is not sent (for whatever reason) as “normal” POST key value pair, but just as raw POST data. Obviously PHP is therefore not able to add this raw POST data to the array $_POST.

Here is the way you can get the raw POST data anyway:

// Make sure that there really is some raw POST data available
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
	// Now we can read the raw POST data from PHP standard input
	$rawPostData = trim(file_get_contents('php://input'));
}

As a result you have the XML data that was sent by the Polycom phone in the variable $rawPostData.

Did you also have problems receiving Polycom event data?

Creating a Restricted SSH User for SSH Tunneling Only

Sometimes it is necessary to use SSH tunneling to access a web service on a specific port that is blocked by a firewall or router.

Of course, you could create just a new SSH user on your Linux server, but this user will be able to execute all server commands although they would not be necessary for SSH tunneling. In fact the only thing the user needs is to login and logout again – that’s enough! Therefore we don’t want the user to be able to do anything else for security reasons.

I will show in the following how you can create such a restricted SSH user on a Linux server (tested on Debian Linux) that can be used for SSH tunneling only.

First of all we create a new user (I just call him sshtunnel now) with rbash as shell:

useradd sshtunnel -m -d /home/sshtunnel -s /bin/rbash
passwd sshtunnel

Using rbash instead of bash will restrict the user already as he especially cannot change the directory and cannot set any environment variables. But the user can still execute most of the bash commands.

To prevent him from this, we use a small trick: we set the environment variable PATH for this user to nothing. This way the bash won’t find the commands to execute anymore. That’s easily done by adding this line to the end of the file .profile in the home directory of the user (in our example it is /home/sshtunnel/):

PATH=""

As we want to make sure the user is not able to change this again himself, we remove the write permissions from the user configuration files and from the home directory of the user itself:

chmod 555 /home/sshtunnel/
cd /home/sshtunnel/
chmod 444 .bash_logout .bashrc .profile

Now we’re done: you can setup your SSH tunnel for example with PuTTY just as normal and login with this newly created SSH user. You won’t be able to do anything else than login and logout anymore, but SSH tunneling will work fine!

Did you also need such a restricted SSH user already?

PHP Script for Accessing VirusTotal API Version 2.0

Recently VirusTotal updated its API to version 2.0. As the version 1.0 is now deprecated, I have also updated my PHP script for accessing this API:

Download PHP script for accessing VirusTotal API version 2.0

For a detailed description of this API implementation, please have a look on my post about VirusTotal API version 1.0.

Let me know if you have any questions or problems using this PHP API script.

Open Ports 135, 137 and 445 in AVM Fritz!Box Routers

Few days ago I got a new fiber glass internet connection here which works perfectly.

Together with the new connection type I also got a new free router from my local internet provider: an AVM Fritz!Box 7570 VDSL.

First of all I want to say that this is really a great product: it has a build-in VDSL modem, but also VoIP telecommunication ports (analog and ISDN), provides WLAN and even DECT for connecting your mobile phones.

I just had one problem: after this new router was up and running from within my network I could not access our web service operating on port 445 anymore. Thus no outgoing connection on port 445 was possible anymore.

Therefore I went to check the router settings, but could not find any option or at least a note about this port blocking. But searching the web afterwards turned out that I was not the only guy struggling with this issue.

Of course, port 445, the same as also the other mentioned ports 135 and 137, are normally reserved for NetBIOS respectively SMB communications which really would be a security issue if such services would be used outside of a secure local network. But anyway, even if a port number is normally used for a specific service, everybody is free to use it in a different way like us: We are using ports 444 and 445 for operating some internal SSL webpages as the default port 443 is already in use.

As I’m not the only one in my company using this internal SSL webpages and I definitely didn’t want to change our port usage just because of a new router, I needed to find a way to convince my Fritz!Box to allow outgoing connections on port 445.

After doing some research, I finally came up with following solution. Here is a step-by-step guide to get outgoing connections on ports 135, 137 and 445 working with an AVM Fritz!Box:

  1. save the settings of your Fritz!Box to a file (menu “System” / “Save Settings”).
  2. open this file with a simple text editor.
  3. replace all occurrences of filter_netbios = yes; with filter_netbios = no;. (If you have an older Fritz!Box model, the name of this config entry may be a little bit different. In this case just search for “netbios” and you should be able to find it easily.)
  4. add a new line NoChecks=yes somewhere on the top of the config file (I added it below the line starting with Language=). Without this line import won’t work, because the Fritz!Box would reject to load a manually changed config file.
  5. finally restore the setting by using your changed config file.

That’s it! After your changed config file is loaded, the Fritz!Box will reboot and now outgoing traffic on ports 135, 137  and 445 works fine again.

Of course, I understand that it is useful to block ports with a potential security risk by default, but I absolutely don’t understand why AVM does not provide a way (somewhere in the advanced settings) to change this from within their user interface. A router should never patronize a user: if the user wants to use a specific port for whatever reason, this has to be possible with every router!

Does your router also block some ports without being asked for?

Internationalization: How to Localize HTML5 Projects?

While working on a HTML5 project I came across the problem that I needed to localize it to different languages. Therefore obviously strings of HTML tags as well as JavaScript files need to be translated.

Although I think internationalization is something very important in a globally connected world, it looks like as this topic was completely forgotten for HTML5 development. I just found a proposal in the Common JS Wiki regarding that with no activity since more than a year!

After searching for while I found this post about Passive localization in JavaScript. Of course, I would prefer an officially standardized approach for the localization, but anyway, this JavaScript library is very helpful to use in the meantime until there is an an officially standardized solution.

In the following I will explain how I use this library, not only for JavaScript files, but also for translating the content of HTML tags.

HTML5 Test Page

First of all we need a small HTML5 test page like this:

<!doctype html>
<html class="no-js" lang="en">
<head>
	<meta charset="utf-8">
	<title>Internationalization Test</title>

	<link rel="localization" hreflang="de" href="lang/de.json" type="application/vnd.oftn.l10n+json"/>
	<link rel="stylesheet" href="css/style.css">
	<script type="text/javascript" src="js/i18n.js"></script>
	<script type="text/javascript" src="js/script.js"></script>
</head>
<body onload="loaded()">
	<h1 id="headertext">This is an Internationalization Test!</h1>
	<h2 id="subtitletext">With any subtitle.</h2>
	<a id="showinenglish" href="index.html?lang=en">Show in English</a>
	<a id="showingerman" href="index.html?lang=de">Show in German</a>
</body>
</html>

You can see that I assigned IDs to all major HTML tags. We will use them later on for doing the translation.

JavaScript Helper Functions

Before starting with the translation itself, we need some JavaScript helper functions first:

var _ = function (string) {
	return string.toLocaleString();
};

function localizeHTMLTag(tagId)
{
	tag = document.getElementById(tagId);
	tag.innerHTML = _(tag.innerHTML);
}

function getParameterValue(parameter)
{
	parameter = parameter.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
	var regexS = "[\\?&]" + parameter + "=([^&#]*)";
	var regex = new RegExp(regexS);
	var results = regex.exec(window.location.href);
	if(results == null)
		return "";
	else
		return results[1];
}

Here is a short explanation about what these helper functions are doing:

  • _(): that’s just a short form of the prototype string.toLocaleString().
  • localizeHTMLTag(tagId): this function gets the appropriate HTML element from the DOM tree based on the passed tag ID and directly does the translation afterwards.
  • getParameterValue(parameter): we’ll need this function to get a URL parameter value to change the language of the page upon user request.

Doing the Localization

We have all needed parts to do our localization which is really easy now:

function loaded()
{
	var lang = getParameterValue("lang");
	if (lang != "") String.locale = lang;

	alert(_("Localizing the document title..."));
	document.title = _(document.title);

	alert(_("Localizing other HTML tags..."));
	localizeHTMLTag("headertext");
	localizeHTMLTag("subtitletext");
	localizeHTMLTag("showinenglish");
	localizeHTMLTag("showingerman");

	alert(_("Localizing done!"));
}

There is just one function loaded(), which is called after the document is loaded (see the event in body tag of the HTML5 test page above). First we check if there is an URL parameter lang in case the user changed the page language with the links. Otherwise we don’t need to change the locale (the default browser locale of the user will be used automatically).

Afterwards we can start doing our translation by directly translating a string with the function _() or by using our function localizeHTMLTag(tagId) to translate the content of a HTML tag. That’s it! :-)

What About More Languages?

If you want to add more or other languages, you just need to add a new localization link in the HTML head section together with a JSON file containing the translations for the new language.

Why not Using Short Variable Names?

The author of this JavaScript internationalization library suggests to use short variable strings instead of the default translations. Therefore I want to give an explanation why I’m not doing this in my example as he is, of course, right that using the default translations adds some overhead to the project. But using short variable names would have at least these two disadvantages, too:

  • your HTML5 page would no longer work without a translation, because otherwise only the short variable names would be displayed. In my example project it would just display the default translation (English) when no internationalization system is available.
  • I still hope that there will be a standardized way to do internationalization for HTML5 projects. Then probably you will need to have the default translation inside the HTML tags as the de facto standard for doing e. g. translation of PHP projects is to use gettext files (.po). That’s also the way the mentioned proposal suggests to do it. Therefore when I want to switch to such a way of internationalization somewhen in the future, I don’t like to copy all default translations back into the HTML tags.

Download Example Project

If you like, you can download the source of my example project.

Update

I’ve updated the example project as there was one comma too much in the JSON file which caused it to only work in Mozilla Firefox (not in Microsoft Internet Explorer and Google Chrome). That’s fixed now – thanks Margaret Wong for letting me know about that!

But please keep in mind that you have to upload the files to a webserver for testing as they probably won’t work in Internet Explorer and Chrome locally due to browser access restrictions. Anyway, the example project will work fine now when you upload it to a webserver.

What concept you’re using for localizing your HTML5 projects?

Using PHP to Access the Public VirusTotal API

Updated script for VirusTotal API Version 2.0!

As there is nowadays many spyware and malware out there, it is important to make sure that your own server stays clean.

Therefore I often use the great VirusTotal service to check suspicious files.

For a certain project I wanted to automate this to be able to check some files and URLs in defined time intervals automatically. This can be easily done with the public VirusTotal API.

Unfortunately the link to the PHP implementation provided on the VirusTotal website is down. Therefore I decided to do my own PHP implementation of this API.

You can download a copy of my implementation. The download contains also a small example script explaining how to use it. You’re free to use the implementation in your own projects. Of course, I’d be happy about a small backlink. :-)

In my API implementation not only the default API functions are implemented that are well documented and therefore not explained here, but there are also several helper functions to make life easier which I will explain in the following:

  • getScanID($result): returns the scan ID of a scan result that you can use to query a scan report later on.
  • displayResult($result): displays a scan or submission result in a user readable way.
  • getSubmissionDate($report): returns the submission date of a scan report.
  • getTotalNumberOfChecks($report): returns the total number of anti-virus checks of a scan report.
  • getNumberHits($report): returns the number of anti-virus hits (malware) of a scan report.
  • getReportPermalink($report, $withDate = TRUE): returns the permalink of the scan report. If $withDate == TRUE, permalink returns exactly the current scan report, otherwise it returns always the most recent scan report.

These helper functions should make it much easier to work with the API results as you don’t need to care about the details of the returned JSON object anymore. Therefore here again the download of my free API implementation.

Updated script for VirusTotal API Version 2.0!

Did you use the VirusTotal service already yourself?

Attending to the Event “The Future is Ultrabook”

Intel invited me to attend the event “The Future is Ultrabook” today.

The Future is Ultrabook

Beside interesting speeches about news of these next generation laptops and a panel discussion, it was great to meet other people of the industry. Unlike other events not only developers or ISVs (independent software vendors) attended to this event, but also OEMs (original equipment manufacturer), IHVs (independent hardware vendor) and, of course, a couple of Intel employees. It was exiting to talk with many of these folks.

By the way I won a Intel X25-M G2 160 GB SSD. :-)

Did you also attend to this event?

AppLab: Speech About “Black Belt and the Accelerator Program”

Today there was an AppLab of Intel about the Intel AppUp Developer Program in Milan (Italy) with about 80 attendees.

AppLab: Black Belt and the Accelerator Program

I was invited to give a speech there about the topic Black Belt and the Accelerator Program summarizing the reputation system of the AppUp Developer Program and explaining the opportunities of the Accelerator Program for developers. Download the PowerPoint presentation.

European Software Conference 2011: Speech About the Intel AppUp Developer Program

This weekend the yearly European Software Conference (ESWC) took place in London (Great Britain).

I gave a speech there about the “Intel AppUp Developer Program: the New App Store for Netbooks and Tablets” explaining the opportunities for developers when they submit their products in the AppUp Developer Program. In a short example I showed how an existent program can be prepared to be released inside the Intel AppUp app store. Download the PowerPoint presentation.

European Software Conference 2011: Intel AppUp

Did you attend the European Software Conference this year, too?