Copyright © 2011,2012 Mark G. Daniel
This program, comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it under the
conditions of the GNU GENERAL PUBLIC LICENSE, version 3, or any later version.
http://www.gnu.org/licenses/gpl.txt
DCL in a box provides an in-browser VT102 terminal emulation via a WASD WebSocket scripting application using the pseudo-terminal API. WebSocket makes the terminal input/output stream interface particularly straight-forward and allows a session logged-in via the Web to be maintained fairly simply.
Although at the time of first DCLinabox release (January 2012) the WebSocket Protocol had just been published (http://www.rfc-editor.org/rfc/rfc6455.txt) and mainstream browser support was fairly limited, the asynchronous, bidirectional data stream available using WebSocket will quickly make it an invaluable Web service building block with broad mainstream support.
This version of DCLinabox has been developed using mainstream releases; Chrome 23.0, Firefox 17.0, MSIE 10.0, Opera 12.10 and Safari 6.0.
Currently not all browsers fully support all HTTP semantics prior to WebSocket protocol upgrade. For example, of the above, only Firefox supports the standard HTTP request and proxy authentication mechanisms, which can be an issue if negotiating WebSockets through a proxy server requiring credentials.
Does this browser support WebSocket? NO!
DCLinabox is based on a JavaScript VT102 emulator from the ShellInABox project.
For all things VT ... vt100.net
Is a Free and Open Source project by Markus Gutschke <markus@shellinabox.com>.
http://code.google.com/p/shellinabox/
"Shell In A Box implements a web server that can export arbitrary command line tools to a web based terminal emulator. This emulator is accessible to any JavaScript and CSS enabled web browser and does not require any additional browser plugins. Most typically, login shells would be exported this way."
DCLinabox exports the DCL command-line in a similar way.
Installation
http://wasd.vsm.com.au/wasd/
$ SET DEFAULT WASD_ROOT:[000000] $ UNZIP "-V" location:DCLINABOXnnn.ZIP
$ SET DEFAULT WASD_ROOT:[SRC.DCLINABOX] $ @BUILD_DCLINABOX LINK
$ COPY WASD_EXE:DCLINABOX.EXE CGI_EXE:
By default all the required JavaScript, CSS and graphics are located in the
WASD runtime directory
WASD_ROOT:[RUNTIME.DCLINABOX]
Configuration
DCLinabox allows remote login from a Web browser to the server system. This could be a security issue and so the script disables itself by default. Logical name value DCLINABOX_ENABLE controls whether the application can be used. Define this system-wide using a value of "*" to simply allow experimentation. Alternatively provide one or more comma-separated, dotted-decimal IP address to specify one or more hosts allowed to use the script, and/or one or more comma-separated IP addresses and CIDR subnet mask to specify a range of hosts. IPv4 only! For example
$ DEFINE /SYSTEM DCLINABOX_ENABLE "*" $ DEFINE /SYSTEM DCLINABOX_ENABLE "192.168.1.2" $ DEFINE /SYSTEM DCLINABOX_ENABLE "192.168.1.2,192.168.1.3" $ DEFINE /SYSTEM DCLINABOX_ENABLE "192.168.1.0/24" $ DEFINE /SYSTEM DCLINABOX_ENABLE "192.168.1.0/24,192.168.2.2"
While the LNM$SYSTEM table is used in these examples, logical names may be defined in any table searched by LNM$FILE_DEV, including WASD_TABLE.
By default the WebSocket, and hence all traffic to and from the DCLinabox login and session, is only allowed over Secure Sockets Layer (wss:). This is the case even when the terminal page is accessed via standard (unencrypted) HTTP and implies the system must have a working SSL service. To allow access via unencrypted connections (CAUTION) add ws: somewhere in the logical name value and if the terminal page is accessed using standard HTTP the WebSocket will be established using the same service.
$ DEFINE /SYSTEM DCLINABOX_ENABLE "ws:,*" $ DEFINE /SYSTEM DCLINABOX_ENABLE "192.168.1.0/24,ws:,192.168.2.2"
An idle session is one not having terminal input for a given period. By default idle sessions are disconnected after two hours with a five minute warning. The logical name DCLINABOX_IDLE allows the number of minutes before client disconnection to be specified, the number of minutes warning (delivered in a browser alert), and the warning message (allowing language customisation). Each of these elements is delimited by a comma.
Define to -1 to to disable idle disconnection.
$ DEFINE /SYSTEM DCLINABOX_IDLE -1
To specify a four hour idle period with ten minute warning and local warning message (which may contain just one "%d" to substitute the minutes warning).
$ DEFINE /SYSTEM DCLINABOX_IDLE "240,10,WARNING - disconnection in %d minutes!"
The logical name DCLINABOX_ALERT results in an announcement being displayed in a browser alert dialog. This alert will be delivered at session establishment if it exists at the time, perhaps as a permanent announcement, otherwise will be alerted within a minute of it first being defined. If an ephemeral announcement it should be undefined when no longer relevant. For example
$ DEFINE /SYSTEM DCLINABOX_ALERT - "*** DCLinabox restart shortly - PLEASE LOG OFF ***"
By default the terminal title bar displays the DCLinabox host name, VMS node name and username. To display the process name in addition (periodically updated if changes) the executable image needs to be installed with WORLD privilege. System startup requires
$ INSTALL ADD CGI-BIN:[000000]DCLINABOX.EXE /AUTH=(WORLD)
and on executable image update
$ INSTALL REPLACE CGI-BIN:[000000]DCLINABOX.EXE
Also see Obfuscation.
Single Sign-On
By default, DCLinabox terminal sessions prompt for a username and password. For sites where WASD SYSUAF authentication is available, or where the authenticated remote user string is the equivalent of a VMS username, DCLinabox can use that browser-authenticated VMS username to establish a terminal session without further credential input (i.e. the terminal just displays the DCL prompt, ready to go).
This is obviously very powerful and should only be used with DUE CAUTION!
Note that the browser must support the authentication being used for its WebSocket capability as well as for general web access. For example, at the time of writing (December 2012) only Firefox 15.0 supports the standard HTTP BASIC authentication mechanism (username and password) for WebSocket, and Chrome 22.0, MSIE 10.0, Opera 12.10 and Safari 6.0 do not.
It is possible to selectively apply SSO authentication dependent on the browser in use. This allows suitable browsers to SSO while not disabling others from using DCLinabox via the logon prompt. For example the following applies it only to browsers with firefox or whatever in the agent identification.
["VMS credentials"=WASD_VMS_RW=id] if (websocket:) if (user-agent:*firefox* || user-agent:*whatever*) /*dclinabox* r+w,https: endif endif
The SSO functionality is enabled using the DCLINABOX_SSO logical name.
This logical name is multi-valued, allowing considerable granularity in establishing allowed use of the facility. Each value begins with the name of the realm associated with authentication of the VMS username. This is separated by an equate symbol and zero or more comma-separated usernames allowed to single sign-on and/or trailing wildcard. Preceding a username with a '!' (exclamation point) specifically disallows the matching username from SSO. All string matches are case-insensitive.
Account restrictions (e.g. times) are not evaluated. If a specific username matches it is permitted regardless of the account privileges. If a '**' (double asterisk) is specified any username is permitted regardless of the account privileges. If a '*' (single asterisk) is specified any non-privileged account is permitted to SSO. If '!*' (exclamation point then asterisk) is specified DCLinabox cannot be used except if permitted by SSO.
For example, the following authentication rule
["VMS credentials"=WASD_VMS_RW=id] if (websocket:) /*dclinabox* r+w,https:
would require the logical name defintion
$ DEFINE /SYSTEM DCLINABOX_SSO "WASD_VMS_RW=*"
to allow any such non-privileged authenticated user to create a logged-in terminal session, while the logical name definition
$ DEFINE /SYSTEM DCLINABOX_SSO "WASD_VMS_RW=REN,STIMPY"
would allow only users REN and STIMPY to do so. The logical name definition
$ DEFINE /SYSTEM DCLINABOX_SSO "WASD_VMS_RW=**"
would allow any account (privileged or non-privileged) to SSO, and
$ DEFINE /SYSTEM DCLINABOX_SSO "WASD_VMS_RW=REN,!STIMPY,*"
allows (perhaps privileged) REN but not STIMPY, and then any other non-privileged account.
If a matching authentication realm is not present, or a matching username in a matched realm is not found, or a disabling account status, then single sign-on does not occur and the terminal session just prompts for credentials as usual. Of course, even if the logical name does not allow SSO, the access to DCLinabox is still controlled by the web server authentication and authorisation.
The logical name DCLINABOX_ANNOUNCE allows an SSO session establishment announcement to be displayed in the terminal window. This multi-valued logical name appends carriage-control to each value displaying it as separate line.
$ DEFINE /SYSTEM DCLINABOX_ANNOUNCE "***** WARNING *****"," ","AUTHORISED USE ONLY!"
Single sign-on requires the executable image to be installed with privileges to allow UAI and persona services to be used. System startup requires
$ INSTALL ADD CGI-BIN:[000000]DCLINABOX.EXE /AUTH=(DETACH,SYSPRV,WORLD)
(WORLD only for terminal title management) and on executable image update
$ INSTALL REPLACE CGI-BIN:[000000]DCLINABOX.EXE
A DCLinabox session has user-selectable characteristics available via a right-click menu.
The DCLinabox terminal emulator infrastructure is designed to allow straight-forward application and site localisation.
DCLinabox operates in one of two modes;
The standalone terminal openDCLinabox() function will accept an optional host name (with optional scheme and/or port).
< ... onclick="openDCLinabox('the.host.name')" ... >
Configuration of some elements of DCLinabox behaviour is possible using JavaScript variables.
Variable | Purpose | Value |
---|---|---|
DCLinaboxAnother | the | button displayed on a standalone terminal can also be made available on an embedded terminaltrue or false(D) |
DCLinaboxConfig | specifies a JavaScript file name containing these variables | (string) name.JS |
DCLinaboxHeight | terminal height (number of lines) | (integer) 12 to 96 (24(D)) |
DCLinaboxHost | specifies the host to which the terminal connects | (string) host name or address |
DCLinaboxImmediate | a standlone terminal connects immediately but an embedded terminal must | with this setting overriding thistrue or false(D) |
DCLinaboxLogoutClose | detects the LOGOUT response and closes a standalone terminal window | true(D) or false |
DCLinaboxMessage | allows message text (and hence language) customisation | see below |
DCLinaboxResizeEmbedded | makes the resize dialog available on an embedded terminal | true or false(D) |
DCLinaboxResizeOptions | allows resize dialog options to be specified | array of WxH strings (see DCLINABOX.JS ) |
DCLinaboxScriptName | allows the DCLinabox script to have a different name | see below |
DCLinaboxScroll | terminal scrollback buffer | (integer) zero(D) to disable or number of lines |
DCLinaboxSecureAlways | always connect to the terminal system via SSL | true(D) or false |
DCLinaboxStyle | specifies a CSS file name containing site specifics | (string) name.CSS |
DCLinaboxTitle | by default a standalone terminal is named "DCLinabox: host node user [process]" with this providing a local alternative | (string) description |
DCLinaboxWidth | terminal width | (integer) 80(D) or 132 |
DCLinaboxWxH | terminal dimensions (width x height) | (string) e.g. 80x24, 132x24, 132x48 |
Common settings can be seen and are available for modification in the file CONFIGINABOX.JS for site-wide configuration, or the JavaScript variable can be assigned using a <script>..</script> element appended to the <head>..<head> section of an embedded terminal page or terminal launcher page to provide page-specific customisation. For example:
<script type="text/javascript"> DCLinaboxSecureAlways = true; DCLinaboxImmediate = true; DCLinaboxWidth = 132; DCLinaboxScroll = 200; </script>
By default DCLinabox connects to the same host and port used to access the HTML page containing the embedded terminal or launcher button/link. It is possible to have the terminal connect to a different host (which of course must have the /cgiplus-bin/dclinabox application available). This host specification can contain an optional, colon-delimited port number and the variable used to specify just an alternate port number. Add the DCLinaboxHost JavaScript variable to the embedded terminal or launcher page.
<script type="text/javascript">DCLinaboxHost="the.host.name"</script>
Alternatively, a host selection dialog can be generated on the embedded terminal or launcher page.
<span id="selectDCLinaboxHost"><script type="text/javascript"> selectDCLinaboxHost("one.host.name,two.host.name,three.host.name") </script></span>
Optionally, the host specification can include an equate symbol delimitted description.
<span id="selectDCLinaboxHost"><script type="text/javascript"> selectDCLinaboxHost("one.host.name=FIRST,two.host.name,three.host.name=3rd host name") </script></span>
DCLinabox supports terminal widths of 80 and 132 characters and page lengths from 12 to 96, defaulting to 80x24. Terminal width and height may be independently set using the appropriate configuration variables or jointly set using DCLinaboxWxH variable (which overrides the individual settings). In common with non-emulated terminals, a SET TERMINAL /INQURE is generally used to inform the terminal driver of these characteristics.
Customised and non English language messages are configurable. Carefully reproduce the default message object found in DCLINABOX.JS using desired equivalents and specify as for other configuration elements. One, some or all may be specified, with absent messages defaulted.
<script type="text/javascript"> DCLinaboxMessage = { NOTSUP : 'WebSocket stöds inte!', CONNEC : 'ANSLUTA', DISCON : 'KOPPLA', DISURE : 'KOPPLA: Är du säker?' }; </script>
The file
DCLINABOX.CSS
is available for style-sheet customisation of terminal elements (colour, border
size and style, font size, etc.) A local style file may be specified using the
JavaScript variable DCLinaboxStyle.
Bookmarklet
A Bookmarklet is a snippet of useful JavaScript often stored as the URL of a bookmark/favorite. DCLinabox provides for bookmarklet activation allowing standalone terminals to be activated simply by clicking such a bookmark (or link). The following application allows the essentials of a DCLinabox activation to be entered (with appropriate defaults) and the resulting link be added to the current browser's bookmarks.
With a public system it may be necessary to reduce nuisance-value access attempts and/or an attack vector with the executable having an alternate name. It just means the well-known /cgiplus-bin/dclinabox path will not exist and is akin to changing from the well-known SSH port number to reduce that obvious attack vector. Just use a less-than-obvious (or access-controlled) customised terminal page (or bookmarklet), with a different script executable file name, and add that script name to the <head>..</head> section of the HTML terminal file as with other per-terminal configuration variables.
<script type="text/javascript">DCLinaboxScriptName="anexample"</script>
The script accessed will then be /cgiplus-bin/anexample and the script file name CGI_EXE:ANEXAMPLE.EXE.
The logical names reflect the executable name and so in this case would be
ANEXAMPLE_ENABLE, etc.
Problems?
Many thanks to Markus Gutschke <markus@shellinabox.com> for the
original ShellInABox project and for making it Free and Open Source via
the GPL. Furthermore, the vt100.js implementation appears to be
particularly rigorous, so thanks again.