diff --git a/flashterm/config.info b/flashterm/config.info
new file mode 100644
index 000000000..7865b466a
--- /dev/null
+++ b/flashterm/config.info
@@ -0,0 +1 @@
+telnetport=Port for telnet server,3,Default (23)
diff --git a/flashterm/flashterm.swf b/flashterm/flashterm.swf
new file mode 100644
index 000000000..0b65ea59b
Binary files /dev/null and b/flashterm/flashterm.swf differ
diff --git a/flashterm/global.js b/flashterm/global.js
new file mode 100644
index 000000000..4c27fbc3b
--- /dev/null
+++ b/flashterm/global.js
@@ -0,0 +1,9 @@
+function stormInit() {
+ showFlash();
+ var appendLinks = document.getElementsByTagName("a");
+ for (var i = 0; i < appendLinks.length; i++) {
+ if (appendLinks[i].rel == "append") {
+ appendLinks[i].href += this.location;
+ }
+ }
+}
diff --git a/flashterm/images/icon.gif b/flashterm/images/icon.gif
new file mode 100755
index 000000000..8a25c0378
Binary files /dev/null and b/flashterm/images/icon.gif differ
diff --git a/flashterm/index.cgi b/flashterm/index.cgi
new file mode 100755
index 000000000..b7210bed8
--- /dev/null
+++ b/flashterm/index.cgi
@@ -0,0 +1,79 @@
+#!/usr/local/bin/perl
+# Starts the flash policy server on port 843, then outputs an HTML page that
+# references the flash object
+
+BEGIN { push(@INC, ".."); };
+use WebminCore;
+use Socket;
+&init_config();
+
+&ui_print_header(undef, $text{'index_title'}, "", undef, 1, 1);
+
+# Work out host and port
+$host = $ENV{'HTTP_HOST'};
+$host =~ s/\:\d+$//;
+$telnetport = $config{'telnetport'} || 23;
+
+# Check for telnet
+&open_socket($host, $telnetport, TEST, \$err);
+$err && &error(&text('index_etelnet', $telnetport));
+close(TEST);
+
+# Start the policy file server on port 843
+$port = 843;
+$proto = getprotobyname('tcp');
+socket(MAIN, PF_INET, SOCK_STREAM, $proto) ||
+ &error(&text('index_esocket', "$!"));
+setsockopt(MAIN, SOL_SOCKET, SO_REUSEADDR, pack("l", 1));
+bind(MAIN, sockaddr_in($port, INADDR_ANY)) ||
+ &error(&text('index_eport', $port));
+listen(MAIN, SOMAXCONN);
+
+# Fork the process that will accept the connection
+$pid = fork();
+if (!$pid) {
+ $rmask = undef;
+ vec($rmask, fileno(MAIN), 1) = 1;
+ $sel = select($rmask, undef, undef, 10);
+ exit(1) if ($sel <= 0);
+ accept(SOCK, MAIN);
+ close(MAIN);
+ select(SOCK); $| = 1;
+ $header = "\000";
+ read(SOCK, $buf, length($header));
+ $buf eq $header || die "Invalid message $buf";
+ print SOCK <
+
+
+
+
+
+EOF
+ close(SOCK);
+ exit(0);
+ }
+close(MAIN);
+
+# Output HTML for the flash object
+print <
+
+
+
+EOF
+
+&ui_print_footer("/", $text{'index'});
diff --git a/flashterm/lang/en b/flashterm/lang/en
new file mode 100644
index 000000000..366ee54b0
--- /dev/null
+++ b/flashterm/lang/en
@@ -0,0 +1,4 @@
+index_title=FlashTerm
+index_esocket=Socket failed : $1
+index_eport=Port $1 is already in use, perhaps by another Flash policy server
+index_etelnet=This system is not running a Telnet server on port $1.
diff --git a/flashterm/module.info b/flashterm/module.info
new file mode 100644
index 000000000..25dd19631
--- /dev/null
+++ b/flashterm/module.info
@@ -0,0 +1,2 @@
+desc=FlashTerm
+version=1.0
diff --git a/flashterm/settings.cgi b/flashterm/settings.cgi
new file mode 100644
index 000000000..5e8af2c5b
--- /dev/null
+++ b/flashterm/settings.cgi
@@ -0,0 +1,28 @@
+#!/usr/local/bin/perl
+# Output the XML settings file
+
+BEGIN { push(@INC, ".."); };
+use WebminCore;
+$trust_unknown_referers = 1;
+&init_config();
+print "Content-type: text/plain\n\n";
+
+# Work out host and port
+$host = $ENV{'HTTP_HOST'};
+$host =~ s/\:\d+$//;
+$telnetport = $config{'telnetport'} || 23;
+
+print <
+EOF
+
+
diff --git a/flashterm/swfobject.js b/flashterm/swfobject.js
new file mode 100644
index 000000000..08fb27000
--- /dev/null
+++ b/flashterm/swfobject.js
@@ -0,0 +1,5 @@
+/* SWFObject v2.1
+ Copyright (c) 2007-2008 Geoff Stearns, Michael Williams, and Bobby van der Sluis
+ This software is released under the MIT License
+*/
+var swfobject=function(){var b="undefined",Q="object",n="Shockwave Flash",p="ShockwaveFlash.ShockwaveFlash",P="application/x-shockwave-flash",m="SWFObjectExprInst",j=window,K=document,T=navigator,o=[],N=[],i=[],d=[],J,Z=null,M=null,l=null,e=false,A=false;var h=function(){var v=typeof K.getElementById!=b&&typeof K.getElementsByTagName!=b&&typeof K.createElement!=b,AC=[0,0,0],x=null;if(typeof T.plugins!=b&&typeof T.plugins[n]==Q){x=T.plugins[n].description;if(x&&!(typeof T.mimeTypes!=b&&T.mimeTypes[P]&&!T.mimeTypes[P].enabledPlugin)){x=x.replace(/^.*\s+(\S+\s+\S+$)/,"$1");AC[0]=parseInt(x.replace(/^(.*)\..*$/,"$1"),10);AC[1]=parseInt(x.replace(/^.*\.(.*)\s.*$/,"$1"),10);AC[2]=/r/.test(x)?parseInt(x.replace(/^.*r(.*)$/,"$1"),10):0}}else{if(typeof j.ActiveXObject!=b){var y=null,AB=false;try{y=new ActiveXObject(p+".7")}catch(t){try{y=new ActiveXObject(p+".6");AC=[6,0,21];y.AllowScriptAccess="always"}catch(t){if(AC[0]==6){AB=true}}if(!AB){try{y=new ActiveXObject(p)}catch(t){}}}if(!AB&&y){try{x=y.GetVariable("$version");if(x){x=x.split(" ")[1].split(",");AC=[parseInt(x[0],10),parseInt(x[1],10),parseInt(x[2],10)]}}catch(t){}}}}var AD=T.userAgent.toLowerCase(),r=T.platform.toLowerCase(),AA=/webkit/.test(AD)?parseFloat(AD.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,q=false,z=r?/win/.test(r):/win/.test(AD),w=r?/mac/.test(r):/mac/.test(AD);/*@cc_on q=true;@if(@_win32)z=true;@elif(@_mac)w=true;@end@*/return{w3cdom:v,pv:AC,webkit:AA,ie:q,win:z,mac:w}}();var L=function(){if(!h.w3cdom){return }f(H);if(h.ie&&h.win){try{K.write("