diff --git a/commands/chmod.json b/commands/chmod.json new file mode 100644 index 0000000..628da0b --- /dev/null +++ b/commands/chmod.json @@ -0,0 +1,66 @@ +{ + "name" : "chmod", + + "info" : { + "syntax" : "chmod <perms> <file|directory>", + "brief" : "Change the access permissions to a file or directory for one or more users or groups, for example chmod user1,user2,@group1,@group2+r" + }, + + "action" : function ( arg ) + { + var out = ''; + + if ( !arg.match ( /^\s*([^+|-]*)(\+|\-)((r|w)+)\s+(.+)\s*$/ )) + { + return "Usage: " + this.info.syntax + "
\n"; + } + + shell.auto_prompt_refresh = false; + + var userlist = RegExp.$1; + var resource = RegExp.$5; + var perm_string = RegExp.$3; + var perms = 0; + + // Unset R/W perms: 011. Unset R perms: 010. Unset W perms: 001 + // Set R/W perms: 111. Set R perms: 110. Set W perms: 101 + perms |= (( RegExp.$2 == '+' ) ? 4 : 0 ); + perms |= (( perm_string.match ( 'r' )) ? 2 : 0 ); + perms |= (( perm_string.match ( 'w' )) ? 1 : 0 ); + resource = shell.expandPath ( resource ); + + var users_php = window.location.href; + users_php = users_php.replace ( /\/([a-zA-Z\.]+)$/, '/modules/users/users.php' ); + params = 'action=chmod&resource=' + escape ( resource ) + '&perms=' + escape ( perms.toString() ); + + if ( userlist ) + { + params += '&userlist=' + escape ( userlist ); + } + + var http = new XMLHttpRequest(); + http.open ( "POST", users_php, true ); + http.setRequestHeader( "Content-type", "application/x-www-form-urlencoded" ); + http.setRequestHeader( "Content-length", params.length ); + http.setRequestHeader( "Connection", "close" ); + + http.onreadystatechange = function () + { + if ( http.readyState == 4 && http.status == 200 ) + { + if ( http.responseText.length > 0 ) + { + shell.cmdOut.innerHTML = http.responseText; + } + + shell.auto_prompt_refresh = true; + shell.refreshPrompt ( false, false ); + } + } + + http.send ( params ); + shell.cmdOut.innerHTML = ''; + return out; + } +} + diff --git a/commands/echo.json b/commands/echo.json index 2acfa33..89ad72c 100644 --- a/commands/echo.json +++ b/commands/echo.json @@ -9,6 +9,10 @@ "action" : function ( arg ) { var out = arg + "
\n"; + out = out.replace ( /(^|[^\\])"/g, '$1' ); + out = out.replace ( /(^|[^\\])'/g, '$1' ); + out = out.replace ( /\\"/g, '"' ); + out = out.replace ( /\\'/g, "'" ); return out; }, } diff --git a/commands/logout.json b/commands/logout.json index 19c55af..5eb8054 100644 --- a/commands/logout.json +++ b/commands/logout.json @@ -81,6 +81,22 @@ http.send ( params ); shell.path = shell.json.basepath; + + var json_config = window.location.href; + json_config = json_config.replace ( /\/([a-zA-Z_\.]+)$/, '/system/blash.json' ); + + var http2 = new XMLHttpRequest(); + http2.open ( "GET", json_config, true ); + + http2.onreadystatechange = function () + { + if ( http2.readyState == 4 && http2.status == 200 ) + { + shell.json = eval ( '(' + http2.responseText + ')' ); + } + } + + http2.send ( null ); return out; }, } diff --git a/commands/nano.json b/commands/nano.json index 3b66f9e..3c32612 100644 --- a/commands/nano.json +++ b/commands/nano.json @@ -118,8 +118,8 @@ if ( file.content.length > 0 ) { var content = file.content.replace ( //g, "\n" ); - content = content.replace ( '<', '<' ); - content = content.replace ( '>', '>' ); + content = content.replace ( /</g, '<' ); + content = content.replace ( />/g, '>' ); editor.value = content; has_content = true; } diff --git a/commands/su.json b/commands/su.json index 6fdf346..98d9267 100644 --- a/commands/su.json +++ b/commands/su.json @@ -135,6 +135,33 @@ shell.auto_prompt_focus = true; shell.auto_prompt_refresh = true; shell.refreshPrompt ( false, false ); + + blashrcIndex = -1; // Index of .blashrc file + + for ( var i in shell.files ) + { + if ( shell.files[i].path.match ( new RegExp ( '^' + shell.home + '/.blashrc$' ))) + { + blashrcIndex = i; + break; + } + } + + if ( blashrcIndex > 0 ) + { + var blashrc = shell.files[blashrcIndex].content.replace ( //g, ' ' ); + blashrc = eval ( '(' + blashrc + ')' ); + + if ( !blashrc ) + { + return false; + } + + for ( var i in blashrc ) + { + shell.json[i] = blashrc[i]; + } + } } } diff --git a/commands/whoami.json b/commands/whoami.json index 7ad70c0..f161e4e 100644 --- a/commands/whoami.json +++ b/commands/whoami.json @@ -15,7 +15,6 @@ return "guest
\n"; } - if ( arg ) { return "whoami: extra operand `" + arg + "'
\n"; diff --git a/modules/users/user_utils.php b/modules/users/user_utils.php index e088ec3..03efa68 100644 --- a/modules/users/user_utils.php +++ b/modules/users/user_utils.php @@ -34,6 +34,26 @@ function getUser () return "guest"; } +function userExists ( $user ) +{ + include 'userlist.php'; + + if ( !( $xml = new SimpleXMLElement ( $xmlcontent ))) + { + return "Unable to open the users XML file\n"; + } + + for ( $i = 0; $i < count ( $xml->user ); $i++ ) + { + if ( !strcmp ( $xml->user[$i]['name'], $user )) + { + return true; + } + } + + return false; +} + function getHome () { include 'userlist.php'; @@ -305,6 +325,147 @@ function __json_encode( $data ) { return $json; } +function __chmod ( $resource, $userlist, $perms ) +{ + include "../../system/files_json.php"; + $user = getUser(); + $file_index = -1; + + if ( !$files_json || strlen ( $files_json ) == 0 ) + { + return 'Error: Empty JSON file container'; + } + + $json = json_decode ( $files_json, true ); + + if ( !$json ) + { + return 'Error: Empty JSON file container'; + } + + for ( $i=0; $i < count ( $json ) && $file_index == -1; $i++ ) + { + if ( $json[$i]['path'] == $resource ) + { + $file_index = $i; + } + } + + if ( $file_index == -1 ) + { + return "chmod: No such file or directory"; + } + + $perm = json_decode ( getPerms ( $json[$file_index]['path'] ), true ); + + if ( !$perm['write'] ) + { + return "chmod: Permission denied"; + } + + if ( $userlist ) + { + $userlist = preg_split ( '/,\s*/', $userlist ); + } else { + $userlist = array(); + $userlist[0] = $user; + } + + $can = array(); + $perm = array(); + $perm['set'] = ( $perms & 0x4 ) ? true : false; + $perm['read'] = ( $perms & 0x2 ) ? true : false; + $perm['write'] = ( $perms & 0x1 ) ? true : false; + + foreach ( array ( 'read', 'write' ) as $action ) + { + if ( $perm['set'] ) + { + if ( $perm[$action] ) + { + if ( !$json[$file_index]['can_'.$action] ) + { + $json[$file_index]['can_'.$action] = join ( ", ", $userlist ); + } else { + $out = ''; + $can[$action] = preg_split ( '/,\s*/', $json[$file_index]['can_'.$action] ); + + for ( $i=0; $i < count ( $userlist ); $i++ ) + { + if ( !userExists ( $userlist[$i] ) && !preg_match ( '/^\s*@/', $userlist[$i] )) + { + continue; + } + + $user_found = false; + + for ( $j=0; $j < count ( $can[$action] ) && !$user_found; $j++ ) + { + if ( $userlist[$i] == $can[$action][$j] ) + { + $user_found = true; + } + } + + if ( !$user_found ) + { + if ( strlen ( $out ) == 0 ) + { + $out .= $userlist[$i]; + } else { + $out .= ', '.$userlist[$i]; + } + } + } + + if ( strlen ( $out ) > 0 ) + { + $json[$file_index]['can_'.$action] .= ', '.$out; + } + } + } + } else { + if ( $perm[$action] ) + { + if ( !$json[$file_index]['can_'.$action] ) + { + continue; + } else { + for ( $i=0; $i < count ( $userlist ); $i++ ) + { + if ( preg_match ( '/(,?\s*)'.$userlist[$i].'(,?)/', $json[$file_index]['can_'.$action], $matches )) + { + $replace = ''; + + if ( preg_match ( '/^\s*$/', $matches[1] ) || preg_match ( '/^\s*$/', $matches[2] )) + { + $replace = ''; + } else { + $replace = ", "; + } + + $json[$file_index]['can_'.$action] = preg_replace ( '/(,?\s*)'.$userlist[$i].'(,?)/', $replace, $json[$file_index]['can_'.$action] ); + } + } + + if ( strlen ( $json[$file_index]['can_'.$action] ) == 0 ) + { + unset ( $json[$file_index]['can_'.$action] ); + } + } + } + } + } + + if ( !( $fp = fopen ( "../../system/files_json.php", "w" ))) + { + return "Unable to write on directories file\n"; + } + + fwrite ( $fp, ""); + fclose ( $fp ); +} + function set_content ( $file, $content ) { $perms = json_decode ( getPerms ( $file ), true ); diff --git a/modules/users/userlist.php b/modules/users/userlist.php index 116089f..5b31f9c 100644 --- a/modules/users/userlist.php +++ b/modules/users/userlist.php @@ -3,7 +3,7 @@ $xmlcontent = << - + XML; diff --git a/modules/users/users.php b/modules/users/users.php index be6bcee..6879a44 100644 --- a/modules/users/users.php +++ b/modules/users/users.php @@ -71,6 +71,7 @@ switch ( $action ) $GLOBALS['sudo_cmd'] = true; print __mkdir ( '/home/'.$username, $perms )."
\n"; + set_content ( '/home/'.$username.'/.blashrc', file_get_contents ( '../../system/default_blashrc.json' )); $GLOBALS['sudo_cmd'] = false; print 'User "'.$username.'" successfully added, home directory set to "/home/'.$username."\"\n"; @@ -241,6 +242,19 @@ switch ( $action ) print __rm ( $file ); break; + case 'chmod': + $resource = $_REQUEST['resource']; + $perms = $_REQUEST['perms']; + $userlist = $_REQUEST['userlist']; + + if ( !( $resource && $perms )) + { + return false; + } + + print __chmod ( $resource, (( $userlist ) ? $userlist : null ), $perms ); + break; + case 'set_content': $file = $_REQUEST['file']; $content = $_REQUEST['content']; @@ -251,6 +265,12 @@ switch ( $action ) } print set_content ( $file, $content ); + + // If this was a sudo command, for example for creating .blashrc file, + // revoke sudo permissions now + if ( $GLOBALS['sudo_cmd'] == true ) + $GLOBALS['sudo_cmd'] = false; + break; default : diff --git a/system/blash.js b/system/blash.js index c4158c9..878b240 100644 --- a/system/blash.js +++ b/system/blash.js @@ -74,7 +74,7 @@ function blash () this.loadCommand = function ( cmd ) { var cmd_file = window.location.href; - cmd_file = cmd_file.replace ( /\/([a-zA-Z\.]+)$/, '/commands/' + cmd + ".json" ); + cmd_file = cmd_file.replace ( /\/([a-zA-Z_\.]+)$/, '/commands/' + cmd + ".json" ); var http = new XMLHttpRequest(); http.open ( "GET", cmd_file, true ); @@ -97,7 +97,7 @@ function blash () this.user = RegExp.$1; var params = 'action=getuser'; var users_php = window.location.href; - users_php = users_php.replace ( /\/([a-zA-Z\.]+)$/, '/modules/users/users.php' ); + users_php = users_php.replace ( /\/([a-zA-Z_\.]+)$/, '/modules/users/users.php' ); var xml = new XMLHttpRequest(); xml.open ( "POST", users_php, true ); @@ -148,7 +148,7 @@ function blash () this.prompt.focus(); var json_config = window.location.href; - json_config = json_config.replace ( /\/([a-zA-Z\.]+)$/, '/system/blash.json' ); + json_config = json_config.replace ( /\/([a-zA-Z_\.]+)$/, '/system/blash.json' ); var http = new XMLHttpRequest(); http.open ( "GET", json_config, true ); @@ -197,9 +197,9 @@ function blash () if ( shell.has_users ) { - shell.files_json = shell.files_json.replace ( /\/([a-zA-Z\.]+)$/, '/modules/users/files.php' ); + shell.files_json = shell.files_json.replace ( /\/([a-zA-Z_\.]+)$/, '/modules/users/files.php' ); } else { - shell.files_json = shell.files_json.replace ( /\/([a-zA-Z\.]+)$/, '/system/files.json' ); + shell.files_json = shell.files_json.replace ( /\/([a-zA-Z_\.]+)$/, '/system/files.json' ); } var http2 = new XMLHttpRequest(); @@ -233,6 +233,32 @@ function blash () } shell.files = tmp; + blashrcIndex = -1; // Index of .blashrc file + + for ( var i in shell.files ) + { + if ( shell.files[i].path.match ( new RegExp ( '^' + shell.home + '/.blashrc$' ))) + { + blashrcIndex = i; + break; + } + } + + if ( blashrcIndex > 0 ) + { + var blashrc = shell.files[blashrcIndex].content.replace ( //g, ' ' ); + blashrc = eval ( '(' + blashrc + ')' ); + + if ( !blashrc ) + { + return false; + } + + for ( var i in blashrc ) + { + shell.json[i] = blashrc[i]; + } + } } } diff --git a/system/blash.json b/system/blash.json index 8bcda31..3aec8c6 100644 --- a/system/blash.json +++ b/system/blash.json @@ -55,6 +55,7 @@ "commands" : [ "cat", "cd", + "chmod", "clear", "echo", "eval", diff --git a/system/default_blashrc.json b/system/default_blashrc.json new file mode 100644 index 0000000..f7e7427 --- /dev/null +++ b/system/default_blashrc.json @@ -0,0 +1,18 @@ +/** + * Sample configuration and contents + */ + +{ + "banner" : "Welcome back to blash

", + "machine" : "localhost", + + /** + * Macros for promptText: + * #{xxx} or #{xxxxxx} - use the specified HTML colour + * %n - username + * %m - machine name + * %W - current working directory + */ + "promptText" : "[#{800}%n#{888}@#{800}%m#{888} %W] $ " +} + diff --git a/system/files_json.php b/system/files_json.php index e61895b..d46a403 100644 --- a/system/files_json.php +++ b/system/files_json.php @@ -10,8 +10,6 @@ $files_json = <<
int main () {
printf ( 'loln' );
}"} +, {"path": "/root", "type": "directory", "can_write": "root", "can_read": "root"} ] JSON; -?> \ No newline at end of file +?>