Misc. COM Components AXGate

The topics in this page:

Requirements,
Overview,
AXGate profiles,
Using AXGate,
Object reference

Requirements

The AXGate ActiveX component is for Pocket PC 2003 (or later) and Pocket IE exclusively. No versions are planned for earlier Pocket PC versions. Actually the versions prior to Windows Mobile 2003 (also popular among the developers as Pocket PC 2003) do not allow this to be done.

Overview

The background: AXGate is a way to overcome the scripting limitations of Pocket Internet Explorer. While Microsoft has a fully working Internet Explorer for Windows CE - almost equivalent to the desktop version, the Pocket PC devices are distributed with the light version - Pocket Internet Explorer. Good or bad this is a fact and the developers face certain problems with it. Pocket IE has no zone manager, nor full-scale security as we know it from the desktop or full IE for CE.NET. It allows objects to be created on the pages but only components declared as safe for scripting and initialization (details can be found in MSDN - see IObjectSafety). Thus all the security is reduced to a single simple declaration implemented in the COM class itself and nothing more.

This makes impossible the usage of unsafe components. In theory a component developer can make his/her component declared as safe, but if it is not actually safe (for example if it implements FS access) this is unwise. The potential risk of such step is even bigger than on the desktop, because for the Pocket PC platform there are much less number of components available then for the desktop. For example for file access there are only 2 well-known components (at this moment - of course, there could be more at the time you read this). They are the File object from eVB and the Storages and Files set from ActiveX Pack1 Thus a malicious user will need to try only a few components and he will have quite a chance to harm the device. So, it is not a good idea to declare such components as safe if they are not naturally safe.

To overcome this AXGate provides way to create unsafe components and use them in the Javascript running in the opened page without compromising the device security. To do so AXGate uses a configuration that defines a set of profiles. Each profile may list one or more COM classes and/or a few internally supported pre-initialized objects (more info about them - see below). The security check is made when the script attempts to activate the profile. Further, if the profile passes the check no further checks are made when the script creates an object from the profile. So, the AXGate provides way to create the objects listed in the active profile - and no others, the security check is made on profile level, so that the user would not be overwhelmed by too many questions (if the profile configuration requires approval by the user). There are generally two type of profiles: The first type requires the user to allow/disallow access each time the profile is accessed, the second type is based on password that must be set by the script running on the page. Aside of that there are some additional options that allow combination of the features above with additional restrictions: protocol restriction (e.g. http, https, file and so on) or URL/site restrictions (e.g. only resources that are in certain par of a certain site).

As you may guess the password protected profiles are not safe enough without protocol restrictions at the least. If they are used and allowed on public WEB sites the passwords can be easily learned and used for security attacks. In contrast a restriction to certain site will make the password usage unprofitable as it will not work if used in pages on other sites/protocols. Read the recommendations in the AXGate profiles section of this page for suggestions and ideas on how to use AXGate correctly.

The profile based security checks allow something which can be perceived even as more comfortable than the behavior we have with the full scale security manager on the full Internet Explorer. For example the profile has name and a description. The description can be understandable for the end-user and if written well will allow almost all the users make the right decision instead of simply trusting a name of a vendor. The profiles cannot be updated online, therefore a permanent security compromise cannot be easily done by persuading the user even if he/she has configured a potentially dangerous profile on the device. 

In general - Where and how to use the AXGate? First there is a set of a few standard profiles. They are all configured in the most safe manner. We strongly recommend to use them only for the purposes they are designed for! Changing their area of application (i.e. changing their restriction settings) can produce a potential vulnerability. For example the "full access" profiles are configured to work only on the local file system, while the public profiles (profiles that allow usage from public WEB sites) are designed to allow access only to a single file or specific OLE storage file. This allows many operations to be performed in a closed sandbox - especially the public profiles. For example the OLE storage can be used to store many files, but still it is a file system into the main file system and would not allow the page write anything outside the storage file. Thus the maximum harm that can be done is corrupting the special storage file but not the entire system. All the predefined profiles are based on our products - mostly ActiveX Pack1 and NetStreams. However you can add other classes to some of the profiles or define new profiles for them. In various conversations with Pocket PC developers we discussed the need and seems that the primary target for AXGate should be corporate software or other specialized software. Very often it is convenient to have some small scripting applications do some simple jobs and sometimes it is convenient to combine or base them on HTML pages - local or from a specific site. These are most often information collection applications, simple queries and so on. In most cases usage of text files or flat files is enough and the major information processing is done later - on the desktop or by another PPC application that accesses the collected information. Of course, there are many other applications that may benefit of such a component - it is up to you!

AXGate profiles

The AXGate keeps all its configuration in a single text file which must be located in the same directory where the DLL resides. It must be named AXGate.cfg. The sample file that comes with the component contains comments to remind you about the meaning of the settings - once you have read the documentation (note that using the change password sample will remove the comments). The configuration has two top level sections CONTROL which is reserved for future use and PROFILES which contains the profiles definitions. Each profile is defined in its own section. Here is a template section we will use for the description below it:

{ ProfileName:
  (int)Access=<AccessCode>
  (string)Password=<Password>
  (string)Name=<Display name>
  (string)Description=<Description>
  (string)Default=<Default object>
  (string)AllowedProtocols=<protocol1>
  ...
  (string)AllowedProtocols=<protocolN>
  (string)AllowedURL=<url1>
  ...
  (string)AllowedURL=<url1>
  { CLASSES:
    { ObjectName1:
       (string)Type=File
       (int)Create=<1|0>
       (int)Exclusive=<1|0>
       (int)ShareRead=<1|0>
       (string)File=<file full path>
    } ObjectName1;
    { ObjectName2:
	(string)Type=MemoryStream
    } ObjectName2;
    { ObjectName3:
      (string)Type=OLEStorage
      (int)Create=<1|0>
      (int)Exclusive=1
      (string)File=<file full path>
    } ObjectName3;
    (int)newObjects.utilctls.SFRecord=1
    (int){06C9B1B5-13E5-4661-AE98-DFAB98C67AF1}=1
    ........ and so on .........
  } CLASSES;
} ProfileName;

The ProfileName can be any string you want. It must not contain ":" or ";" characters and <CR>, <LF> characters. This name is used by the script when it requests profile activation through the Profile property.

The most important setting for a profile is Access. The current version supports the following values:

0 - Default (if Access is omitted). The profile can be used from any source, the user is asked for a permission to activate it.
1 - The profile can be used from any source, the access is granted if the PassCode property matches the Password setting in the profile.
2 - The profile is allowed only if the page has been downloaded through one of the protocols listed in an AllowedProtocol option. At least one such option should exist - otherwise the profile is unusable. The user is asked for a permission to activate the profile.
3 - Like previous (2) but PassCode property must match the Password setting.
4 - The profile is allowed if the page has been downloaded from URL "under" on of the URL specified in an AllowedURL option. This means that the page URL must begin with one of URL specified in the AllowedURL options. The user is asked for a permission to activate the profile.
5 - Like previous (4), but the PassCode property must match the Password setting.

The Password setting is meaningful only for profiles with Access set to 1, 3 or 5.

The Name specifies the display name of the profile. This name is shown to the user when he/she is asked for a permission to activate the profile or when the "Access denied" message is shown in case of a profile with password protection.

The Description allows you specify one line (can be quite long) of description that helps the user decide what to do - allow or deny profile activation. Used in profiles with Access set to 0, 2, 4 and not used in password protected profiles (Access set to 1, 3, and 5).

The Default setting is optional. If present it specifies one of the classes listed in the Classes section - the name of the class or the pre-initialized objects. It allows the CreateObject method proceed without parameters or with empty string parameter. If called this way it will return the default object.

The CLASSES section

The regular entries for COM classes are like this:

(int)<ProgID>=<1|0>
or
(int)<ClassID>=<1|0>

You can specify the ProgID of the class you want to list or/and its ClassID. If ClassID is specified it will allow CreatObject to accept the ClassID UID string (like this one for instance: {06C9B1B5-13E5-4661-AE98-DFAB98C67AF1} ). However most of the developers are used to ProgID strings instead of ClassID so ProgID-s should be used unless there is a specific reason to use ClassID.

The entry must be set to 1 in order to allow object creation. You can set it to 0 if you want to disable the object without removing the entry (for example if you want to disable it temporarily).

The special pre-initialized objects

Version 1.0.0.2 of AXGate supports 3 types of such objects. Each of them is specified in a section named after the name you want to use in CreateObject to obtain it. I.e. you will be able to obtain it when CreateObject is called with the section name you specified.

File

(string)Type=File
This is a SFStream object attached to a file explicitly specified by the setting:
(string)File=<file path>
File path must be full - for example: \My Documents\myfile.txt
If you want the file to be created if it does not exist yet instead of causing an error you can specify:
(int)Create=1
Also there are two more settings you can optionally put in the section:
(int)Exclusive=1
Will open/create the file with exclusive access - no other application or script will be able to open it while it is in use.
(int)ShareRead=1
If specified instead of Exclusive will allow other applications to read the file but not write it while you are using it.

When you obtain the object the file is positioned in the beginning. If you want to append it the first thing you do should be ofile.Pos=ofile.Size - position at the end of the file.

MemoryStream

(string)Type=MemoryStream
This is a SFStream attached to a temporary in-memory file.
The file is lost when the page is closed. Can be useful when transferring data from other sources.

OLE Storage

(string)Type=OLEStorage
This is a SFStorage object attached to an OLE storage file explicitly specified by the setting:
(string)File=<file path>
File path must be full - for example: \My Documents\mystorage.stg
As like File you can use:
(int)Create=1
If you want the storage be created if it does not exist yet.
(int)Exclusive=1
Must be specified in order this to work because of the platform limitations.

The OLE storages are a kind of a virtual file system maintained in a file. So the storage looks like single file in the device's file system, but internally it may contain sub-storages (sub-directories), streams (files) in a tree-like structure as like the device's file system. There are certain limitations - for example the sub-elements names must be up to 31 characters long and no more, but in general it allows the data to be stored in any convenient way.

Using AXGate

The usage of the component is well illustrated in the samples packed with it. By default they are installed in My Documents\AXGate samples directory. You can download also the raw package which includes the samples as well.

A few words about the usage. In general there are two techniques depending on the profile(s) you intend to use. The profile with Access set to 0,2 and 4 require the user to permit the profile activation, while the others (1,3 and 5) expect the page to set the PassCode property before activating the profile.

The profile is activated by writing the profile name desired to the Profile property. When this is done before returning the control to the script 3 things may happen depending on the profile type - user is asked to permit the profile activation, PassCode is checked against the Password setting in the profile configuration or the access is implicitly denied if the profile requires the page to be fetched through a particular protocol or URL not matching the current page properties (the latter applies to the profiles with Access set to 2,3,4 and 5).

How to create the AXGate object?

You should use code like this:

...
<BODY>
...
<OBJECT 
  ID="axgate" 
  CLASSID="clsid:03797ADA-8CCF-4533-B623-2C5DE06B29C7"></OBJECT>
...

It is recommended to place this outside any form in order to make it easier to access the object. If the declaration is as in the above sample code you can refer to AXGate using the axgate variable (corresponds to the ID attribute) after the page is completely loaded. Note that you cannot refer to the AXGate object while the page loads but is not yet finished so it is convenient to use BODY's onLoad event to initialize AXGate with certain profile. Of course, if your page is constructed in manner that permits you perform the initialization later (when user clicks something for example) you can do this later - in response to some other event.

Below we will assume that the above <OBJECT ...> exists somewhere in the page and we will only list the other sample code involved. We also assume for the sample purposes that ID of AXGate is "axgate" - you can name it otherwise, of course.

A typical code for user acknowledged profile looks like this:

var creator;
function InitProfile() {
  axgate.Profile = "FullAccess"; // We want the FullAccess standard profile.
  creator = axgate.CreateObject();
  var o = creator.CreateObject("Someobject.ProgID");
  // use o for something
  .....
}

Above we use also the "Default" feature which allows us call CreateObject without parameters and receive the default object. In the "FullAccess" profile it is the Pack1Creator from ActiveX Pack1 which in turn provides access to any registered COM class in the system and also to composite objects. This special feature of ActiveX Pack1 is handy here but if we want to use some restricted profile like FileAccess for instance we may write this:

var SFMain;
function InitProfile() {
  axgate.PassCode = "<the actual pass code>";
  axgate.Profile = "FileAccess"; // We want the FileAccess standard profile.
  SFMain = axgate.CreateObject("newObjects.utilctls.SFMain");
  // Open a file for example
  var file = SFMain.OpenFile("\myfile.txt");
  // Write something in there
  file.WriteText("Some text ...",1);
  ..... etc. .....
}

By the way - the FileAccess profile is password protected so we need to set the PassCode property before activating it. After that point everything is the same with any profile - we use axgate.CreateObject("someID") to produce objects from the profile. Do not forget that the technique in FullAccess profile is an exception benefiting of the Pack1Creator object - in general ProgID-s are used as parameters.

A little discussion. In the first case when you attempt to set the Profile property a dialog will pop-up to ask the user for permission to access the profile, while in the second sample the PassCode and the Password will be compared silently and access provided if they match. Of course placing the password in the source of the page is not a good idea especially if the page is downloaded from a random site. This can be convenient and secure for pages in the local file system but is not wise for online pages. Note that the standard profiles follow these considerations (review the AXGate.cfg). Still a password protected profile can be used quite securely online if the password is not in the page source. You can provide a field user must fill or use cookies or something else. For example if it is in a field you can do this:

axgate.PassCode = document.forms[0].PassCode.value;

Where the ID of the field is "PassCode" too. Of course, in such cases you should init the profile not on load but later when the user clicks some button for instance to confirm that he/she have entered something in the password field.

Do not forget that the profiles with Access set to 2,3,4 and 5 allow you restrict their usage for certain protocols or URL only. This allows you find the balance between security and convenience. The standard profiles are good for many things but not for everything, of course. When creating yours consider how secure are they.

For example if may want to collect information in a file and use the latest entries on the device for some references. Assume that later (in the end of the day/week) you transfer the collected information to the desktop for further processing, but still you want to implement more then just simple forms - for example you want to allow the user to review whatever entries he/she have collected today, search through them etc. You can do this using a flat file and a SFRecord object. Then you will need a File pre-initialized object (see in the above section) and a few other objects to perform other supporting operations. If the only access to the local file system is through this File pre-initialized object everything you expose is that file where you collect the data. Well even in case of intrusion the attacker will only destroy the content of the file. Well, but if the user has been collecting this information for a few days it will be quite a loss, depending on what kind of attacks you may expect (based on popularity, the information and other considerations outside the pure programming) you can decide what way to use. In general password protection will be ok - as long as the application on the device consists of one or more pages in the local file system,. So a profile with Access=3 will do - limit the protocols to file only and usage of password is safe enough (if someone manages to access the files of your applications and thus steal the password then something elsewhere is very wrong and it has nothing to do with your application, nor with AXGate). But, suppose you want something more - for example allow the user connect to your corporate site online and run some additional pages over the local data. the purpose of this can be some statistics, analysis you publish for the users that do this or the reason can be even more complex - allow the user select and submit entry or entries from the locally stored data to the server. This page is to be more secured than the locally residing pages. You should look at profiles with Access set to 4 or 5 then. You can specify there the local URL and the online URL thus restricting the profile usage to these two locations only. But still password or user acknowledgment? If the application rarely requires the user to navigate from page to page user interaction will not be too disturbing, but if not a password usage may be more convenient. If you manage to implement the online pages to fill the password from a parameter or a cookie set by the local pages it will be better - i.e. if it is possible to avoid putting the password into the page source and even the URL parameters it is good and secure if something prevents such solution better go the other way - user interaction.

Can I create the AXGate object directly?

Yes you can use:

var axgate = new ActiveXObject("newObjects.sandbox.AXGate");

This will even work outside IE (in CE version of IIS for instance), but it will prevent AXGate from knowing where the page came from. So it will limit you to profiles with Access set to 0 and 1 only! If you use this technique in applications other than PIE consider what kind of profiles will be appropriate - for instance in IIS user acknowledgment will not be a good idea because a dialog will pop up every time a page is served.

Object reference

Threading model: both
ProgID: newObjects.sandbox.AXGate
ClassID: {03797ADA-8CCF-4533-B623-2C5DE06B29C7}

Profile (string) When written - the name of the profile you want to activate. When read - the currently active profile - empty string is returned if there is no active profile.

Please read carefully about the profiles above. The behavior of this property (especially when written) depends on the profile specifics. For example if you want to activate a profile protected by password you must set the PassCode property first. In case of non-password protected profile the user is asked to allow or disallow the access to the profile. Depending on the additional details in the profiles configuration some of them may be available for certain URL or protocols only.  

PassCode (string) A profile password. You set this when the next step will be attempt to activate a profile known to be protected by password (see the Profile property).
o = CreateObject(id); This method can be invoked only if a profile is already activated. If no profile has been activated the method will raise error.

If a profile is active the id parameter should match one of the classes listed in its CLASSES section (see above in the AXGate profiles section of the page). If there is a Default option specified in the profile definition the id can be an empty string. In such a case the default object specified by the Default option will be created.

The creation may succeed or fail. The COM classes specified in the profiles are from other DLL-s and they must be installed on the device if the particular profile will be used. Note that the errors returned by this method are not descriptive. This is mostly a precaution - descriptive errors will make it easier for malicious users to find weaknesses if a potentially risky profile is configured on the device. See more information in the AXGate profiles section of the page.

newObjects Copyright 2001-2006 newObjects [ ]