#!/usr/bin/nesla
/*
* CMS sample prog by Dan Cahill
* This is the Crappy Management system.
* It lets you browse the filesystem, execute shell commands, and edit files,
* and since there's no security, it lets everyone else do it, too... :-)
*
* build nesla.cgi and put it in /cgi-bin/
* make a .htaccess file, add these three lines,
*
* Options +ExecCGI
* AddHandler nes-script .ns
* Action nes-script /cgi-bin/nesla.cgi
* DirectoryIndex index.html index.ns index.php
*
* and that's about it..
*
* the most likely problem is file permissions, but you're on your own there.
*/
// This thing has serious limits that make its usefulness rather limited.
global MASTERPASSWORD="nesla";
if (typeof(_SERVER)!='table') exit;
function dologin() {
var user="nobody";
var pass=MASTERPASSWORD;
print("<HTML>
<TITLE>Nesla - Crappy Management system</TITLE>
<HEAD>
<STYLE TYPE=text/css>
A { color: #0000FF; text-decoration: none; }
A:HOVER { background-color: #E0E0FF; }
</STYLE>
</HEAD>
<BODY>
<CENTER>
<FORM ACTION='", _SERVER['PATH_INFO'], "' METHOD='POST' NAME='login'>
<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0>
<TR><TD><B> Username </B></TD><TD><INPUT SIZE=50 style='width:200px' NAME='username' VALUE='", user, "'></TD></TR>
<TR><TD><B> Password </B></TD><TD><INPUT SIZE=50 style='width:200px' NAME='password' VALUE='", pass, "' TYPE=password></TD></TR>
<TR><TD ALIGN=CENTER COLSPAN=2><input type='submit' value='login' name='submit'></TD></TR>
</TABLE>
</FORM>
</CENTER>
</BODY>
</HTML>
");
exit;
}
if (_POST['PASSWORD']!=null) {
_GET['DOWNLOAD']='';
if (_POST['PASSWORD']==MASTERPASSWORD) {
// printf("Set-Cookie: wminfo=%.2s:%.4s:%s:%s:%s; path=%s/; expires=%s\r\n");
// printf("Set-Cookie: wmpass=%s; path=%s/\r\n");
_HEADER['SET-COOKIE']="NESLACMS="+_POST['PASSWORD'];
print("<SCRIPT LANGUAGE=\"JavaScript\" TYPE=\"text/javascript\">\r\n<!--\r\nlocation.replace(\"", _SERVER['PATH_INFO'], "\");\r\n// -->\r\n</SCRIPT>\r\n");
print("<NOSCRIPT><META HTTP-EQUIV=\"Refresh\" CONTENT=\"1; URL=", _SERVER['PATH_INFO'], "\"></NOSCRIPT>\r\n");
} else {
print("bad pass");
}
exit;
}
if (_COOKIE['NESLACMS']==null) {
_GET['DOWNLOAD']='';
dologin();
}
global MASTERPASSWORD="********";
// if user is logged in, and download request exists, process that instead
if (_GET['DOWNLOAD']!=null) {
if (_GET['DOWNLOAD']!='') {
sendfile(_GET['DOWNLOAD']);
exit;
}
}
if (_SERVER['REQUEST_METHOD']=='POST') {
var opt=_POST['OPT'];
if (opt=='browse') {
// limit browsing to docroot
if (_SERVER['DOCUMENT_ROOT']==null) {
print("you have no docroot");
} else {
if (string.ncmp(_SERVER['DOCUMENT_ROOT'], _POST['PATH'], string.len(_SERVER['DOCUMENT_ROOT']))!=0) {
print("<B><font color=red>refusing to leave document root</font></B>");
parent=_SERVER['DOCUMENT_ROOT'];
_POST['PATH']=parent;
}
}
dir=dirlist(_POST['PATH']);
x=string.split(_POST['PATH'], "/");
for (i=0;;i++) {
if (x[i]==null) break;
}
parent="";
for (j=0;j<i-1;j++) {
if (x[j]=='') { continue; }
parent=parent+'/'+x[j];
}
if (parent=='') parent='/';
// limit browsing to docroot
if (_SERVER['DOCUMENT_ROOT']==null) {
print("you have no docroot");
} else {
if (string.ncmp(_SERVER['DOCUMENT_ROOT'], parent, string.len(_SERVER['DOCUMENT_ROOT']))!=0) {
parent=_SERVER['DOCUMENT_ROOT'];
_POST['PATH']=parent;
}
}
print("<TABLE BORDER=1 CELLPADDING=0 CELLSPACING=0 WIDTH=100%>\n");
for (i=0;;i++) {
var x=iname(dir, i);
if (typeof(dir[x])!='table') break;
if (string.cmp(x, '.')==0) {
} else if (string.cmp(x, '..')==0) {
print("<TR><TD COLSPAN=4 STYLE='border-style:solid'><IMG SRC=/icons/folder.open.png> <A HREF='javascript:newparent(\"", parent, "\");'>Parent Directory - ", parent, "</A></TD></TR>\n");
} else if (dir[x].type=='dir') {
print("<TR>");
print("<TD ALIGN=left NOWRAP STYLE='border-style:solid'> </TD>");
print("<TD ALIGN=left NOWRAP STYLE='border-style:solid' WIDTH=66%>dir - <A HREF='javascript:newparent(\"", _POST['PATH']+'/'+x, "\");'>", x, "/</A></TD>");
print("<TD ALIGN=right NOWRAP STYLE='border-style:solid'> </TD>");
print("<TD ALIGN=right NOWRAP STYLE='border-style:solid'>", time.sqldate(dir[x].mtime), " ", time.sqltime(dir[x].mtime), "</TD>");
print("</TR>\n");
}
}
for (i=0;;i++) {
var x=iname(dir, i);
if (typeof(dir[x])!='table') break;
if (string.cmp(x, '.')==0) {
} else if (string.cmp(x, '..')==0) {
} else if (dir[x].type=='dir') {
// hide htaccess files
} else if (string.cmp(x, '.htaccess')==0) {
} else {
print("<TR>");
print("<TD ALIGN=left NOWRAP STYLE='border-style:solid'><A HREF='javascript:nexthand(\"edit\", \"", _POST['PATH']+'/'+x, "\");'>edit</A></TD>");
// print("<TD ALIGN=left NOWRAP STYLE='border-style:solid'>file - <A HREF='", x, "'>", x, "</A></TD>");
// print("<TD ALIGN=left NOWRAP STYLE='border-style:solid' WIDTH=66%>file - <A HREF='javascript:download(\"", _POST['PATH']+'/'+x, "\");'>", x, "</A></TD>");
print("<TD ALIGN=left NOWRAP STYLE='border-style:solid' WIDTH=66%>file - <A HREF=\"", _SERVER['PATH_INFO'], "?download=", _POST['PATH']+'/'+x, "\" TARGET=\"_blank\">", x, "</A></TD>");
print("<TD ALIGN=right NOWRAP STYLE='border-style:solid'>", math.ceil(dir[x].size/1024), " KiB</TD>");
print("<TD ALIGN=right NOWRAP STYLE='border-style:solid'>", time.sqldate(dir[x].mtime), " ", time.sqltime(dir[x].mtime), "</TD>");
print("</TR>\n");
}
}
print("</TABLE>\n");
} else if (opt=='shell') {
print("\n");
system("cd "+_POST['PATH']+" && "+_POST['COMMAND']);
} else if (opt=='edit') {
system("chmod u+r "+_POST['FILE']);
x=file.read(_POST['FILE']);
if ((typeof(x)=='number')&&(x<0)) {
print("can't read file");
} else {
print(x);
}
} else if (opt=='save') {
if (_POST['ATTACHMENT1_SIZE']!=null) {
x=file.write(_POST['EDITNAME']+"-new", _POST['ATTACHMENT1']);
} else {
x=file.write(_POST['EDITNAME']+"-new", _POST['EDITWINDOW']);
}
_POST['EDITWINDOW']="";
if ((typeof(x)=='number')&&(x<0)) {
print("can't write file '", _POST['EDITNAME'], "'\n");
} else {
system("chmod 644 "+_POST['EDITNAME']+"-new");
print("Wrote '", _POST['EDITNAME'], "' (", x, " bytes).\n");
print("<SCRIPT LANGUAGE=\"JavaScript\" TYPE=\"text/javascript\">\r\n<!--\r\nlocation.replace(\"", _SERVER['PATH_INFO'], "\");\r\n// -->\r\n</SCRIPT>\r\n");
print("<NOSCRIPT><META HTTP-EQUIV=\"Refresh\" CONTENT=\"1; URL=", _SERVER['PATH_INFO'], "\"></NOSCRIPT>\r\n");
}
} else {
print("INVALID REQUEST");
print("<pre>");
printvar(_GLOBALS);
print("</pre>");
}
exit;
}
function printjs() {
print("<SCRIPT LANGUAGE=\"JavaScript\" TYPE=\"text/javascript\">\n<!--\n");
print(
"function newXMLHttpRequest() {\n",
" var xmlreq = false;\n",
"\n",
" if (window.XMLHttpRequest) {\n",
" xmlreq = new XMLHttpRequest();\n",
" } else if (window.ActiveXObject) {\n",
" try {\n",
" xmlreq = new ActiveXObject('Msxml2.XMLHTTP');\n",
" } catch (e1) {\n",
" try {\n",
" xmlreq = new ActiveXObject('Microsoft.XMLHTTP');\n",
" } catch (e2) {\n",
" // Unable to create an XMLHttpRequest with ActiveX\n",
" }\n",
" }\n",
" }\n",
" return xmlreq;\n",
"}\n"
);
print(
"function doresponse(opt, c) {\n",
" return function () {\n",
" if (c.readyState==4) {\n",
// " alert('HTTP status: '+c.status+'\\nHTTP return: '+c.responseText);\n",
" if (c.status==200) {\n",
" redraw(opt, c);\n",
" } else {\n",
" alert('HTTP status: '+c.status+'\\nHTTP return: '+c.responseText);\n",
" }\n",
" }\n",
" }\n",
"}\n"
);
print(
"function nexthand(opt, filename) {\n",
" var c = newXMLHttpRequest();\n",
" var handlerFunction = doresponse(opt, c);\n",
" var fdata='';\n",
"\n",
" fdata='opt='+opt;\n",
" if (opt=='edit') {\n",
" showpage(3);\n",
" document.editor.editname.value=filename;\n",
" document.editor.editwindow.innerText='';\n",
" fdata+='&file='+filename;\n",
" }\n",
" for (var i=0;i<document.shell.elements.length;i++) {\n",
// " alert(document.shell[i].name+'='+document.shell[i].value);\n",
" fdata+='&'+document.shell[i].name+'='+document.shell[i].value;\n",
" }\n",
" c.onreadystatechange = handlerFunction;\n",
" c.open('post', '", _SERVER['PATH_INFO'], "', true);\n",
" c.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');\n",
" c.setRequestHeader('Connection', 'close');\n",
" c.send(fdata);\n",
"}\n"
);
print("function redraw(opt, c) {\n");
print(" if (opt=='browse') {\n");
print(
// " r=c.responseXML.documentElement;\n"
" r=c.responseText;\n",
" document.getElementById('browsewindow').innerHTML=r;\n"
// " document.getElementById('browsewindow').innerText=r;\n"
);
print(" } else if (opt=='shell') {\n");
print(" r=c.responseText;\n");
print(" document.shell.shellwindow.value=r;\n");
print(" } else if (opt=='edit') {\n");
print(" r=c.responseText;\n");
print(" document.editor.editwindow.value=r;\n");
print(" }\n");
print("}\n");
print("// -->\n</SCRIPT>\n");
print("
<SCRIPT LANGUAGE=\"JavaScript\" TYPE=\"text/javascript\">
<!--
function showpage(page) {
for (var i=1;i<4;i++) {
if (i==page) {
document.getElementById('page'+i+'tab').style.borderBottom='solid 0px #000000';
document.getElementById('page'+i+'tab').bgColor='#FFFFFF';
document.getElementById('page'+i).style.display='block';
} else {
document.getElementById('page'+i+'tab').style.borderBottom='solid 1px #000000';
document.getElementById('page'+i+'tab').bgColor='#D0D0D0';
document.getElementById('page'+i).style.display='none';
}
}
}
function showdebug() {
if (document.getElementById('debug').style.display=='none') {
document.getElementById('debug').style.display='block';
} else {
document.getElementById('debug').style.display='none';
}
}
function doshell() {
showpage(2);
nexthand('shell');
return false;
}
function newparent(p) {
showpage(1);
document.shell.path.value=p;
nexthand('browse');
}
// -->
</SCRIPT>
");
return;
}
if (string.cmp(_SERVER['REQUEST_METHOD'], "POST")==0) {
var path=_POST['PATH'];
var command=_POST['COMMAND'];
} else {
var path=_filepath;
var command="ps auxw";
}
print("
<HTML>
<TITLE>Nesla - Crappy Management system</TITLE>
<HEAD>
<STYLE TYPE=text/css>
A { color: #0000FF; text-decoration: none; }
A:HOVER { background-color: #E0E0FF; }
</STYLE>
");
printjs();
print("
</HEAD>
<BODY>
<CENTER>
");
print("
<FORM ACTION='", _SERVER['PATH_INFO'], "' METHOD='POST' NAME='shell' onsubmit=\"return doshell();\">
<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0>
<TR><TD>Path </TD><TD><INPUT SIZE=50 NAME='path' VALUE='", path, "'></TD><TD VALIGN=BOTTOM ROWSPAN=2><input type='submit' value='run' name='submit'></TD></TR>
<TR><TD>Command</TD><TD><INPUT SIZE=50 NAME='command' VALUE='", command, "'></TD></TR>
</TABLE>
");
print("
<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 WIDTH=100%>
<TR><TD ALIGN=LEFT><TABLE BORDER=1 CELLPADDING=0 CELLSPACING=0 STYLE='border-style:solid'>
<TR>
<TD ID=page1tab NOWRAP STYLE='border-style:solid'> <A ACCESSKEY=1 HREF='javascript:showpage(1);'>FILE BROWSER</A> </TD>
<TD ID=page2tab NOWRAP STYLE='border-style:solid'> <A ACCESSKEY=2 HREF='javascript:showpage(2);'>SHELL</A> </TD>
<TD ID=page3tab NOWRAP STYLE='border-style:solid'> <A ACCESSKEY=3 HREF='javascript:showpage(3);'>TEXT EDITOR</A> </TD>
</TR></TABLE></TD></TR>
<TR><TD VALIGN=TOP STYLE='padding:3px'><HR>
<DIV ID=page1 STYLE='display: block'>
<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 WIDTH=100%>
<TR><TD COLSPAN=2><B> Browser window </B></TD></TR>
<TR><TD><SPAN ID='browsewindow'></SPAN></TD></TR>
<TR><TD ALIGN=CENTER COLSPAN=2>[<A HREF='javascript:nexthand(\"browse\");'> BROWSE FILES </A>]</TD></TR>
</TABLE>
</DIV>
<DIV ID=page2 STYLE='display: block'>
<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 WIDTH=100%>
<TR><TD COLSPAN=2><B> Shell window </B></TD></TR>
<TR><TD ALIGN=CENTER COLSPAN=2><TEXTAREA WRAP=PHYSICAL NAME=shellwindow ROWS=25 COLS=80 style='width:100%'></TEXTAREA></TD></TR>
<TR><TD ALIGN=CENTER COLSPAN=2>[<A HREF='javascript:nexthand(\"shell\");'> RUN COMMAND </A>]</TD></TR>
</TABLE>
</FORM>
</DIV>
<DIV ID=page3 STYLE='display: block'>
<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 WIDTH=100%>
<FORM ACTION='", _SERVER['PATH_INFO'], "' METHOD='POST' NAME='editor' ENCTYPE='multipart/form-data'>
<!--FORM ACTION='", _SERVER['PATH_INFO'], "' METHOD='POST' NAME='editor'-->
<INPUT TYPE=hidden NAME=path VALUE='", path, "'>
<INPUT TYPE=hidden NAME=opt VALUE='save'>
<TR><TD COLSPAN=2><B> Editor window </B></TD></TR>
<TR><TD STYLE='padding:0px'>
<TR><TD><B>Filename</B></TD><TD ALIGN=RIGHT><INPUT SIZE=100 NAME='editname' VALUE='", "'></TD></TR>
<TR><TD ALIGN=CENTER COLSPAN=2><TEXTAREA WRAP=OFF NAME=editwindow ROWS=25 COLS=80 style='width:100%'></TEXTAREA></TD></TR>
<TR><TD><B>Upload File</B></TD><TD ALIGN=RIGHT><INPUT SIZE=100 NAME=ATTACHMENT1 TYPE=FILE></TD></TR>
<TR><TD ALIGN=CENTER COLSPAN=2><input type='submit' value='Save' name='submit'></TD></TR>
</TD></TR>
</FORM>
</TABLE>
</DIV>
<HR>
</TD></TR>
</TABLE>
");
print("
<SCRIPT LANGUAGE=\"JavaScript\" TYPE=\"text/javascript\">
<!--
document.shell.command.focus();
showpage(1);
nexthand('browse');
// -->
</SCRIPT>
");
print("<A HREF='javascript:showdebug();'>DEBUG</A>\n");
print("</CENTER>\n");
print("<DIV ID=debug STYLE='display:none'><PRE><FONT SIZE=2>\n");
printvar(_GLOBALS);
print("</FONT></PRE></DIV>\n");
print("</BODY>\n</HTML>\n");