diff --git a/README.md b/README.md index ddc0177..62cabb5 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,23 @@ Launch with `./http.sh`. Does not need root priviliges ~~- in fact, DO NOT run i To prevent running malicious scripts, by default only scripts with extension `.shs` can be run by the server, but this can be changed in the config. Also, cfg[index] ignores this. SHS stands for Shell Server. -Originally made for Junction Stupidhack 2020; Created by [redsPL](https://sakamoto.pl/), [selfisekai](https://selfisekai.rocks/) and [ptrcnull](https://ptrcnull.me/). +Originally made for Junction Stupidhack 2020; Created by [sdomi](https://sakamoto.pl/), [selfisekai](https://selfisekai.rocks/) and [ptrcnull](https://ptrcnull.me/). + +## Quick Start + +If you want to build a new webapp from scratch: + +``` +./http.sh init +./http.sh +``` + +If you're setting up HTTP.sh for an existing application: + +``` +git clone https://git.sakamoto.pl/laudom/ocw/ app # example repo :P +./http.sh +``` ## Dependencies @@ -13,8 +29,9 @@ Originally made for Junction Stupidhack 2020; Created by [redsPL](https://sakamo - [Ncat](https://nmap.org/ncat) - pkill - mktemp +- jq (probably not needed just yet, but it will be in 1.0) - dd (for accounts, multipart/form-data and websockets) -- sha1sum, sha256sum (for accounts and simple auth) +- sha1sum, sha256sum, base64 (for accounts and simple auth) - curl (for some demos) ## Known faults @@ -23,22 +40,21 @@ Originally made for Junction Stupidhack 2020; Created by [redsPL](https://sakamo - `$post_multipart` doesn't keep original names - could be fixed by parsing individual headers from the multipart request instead of skipping them all ## Directory structure (incomplete) +- app (or any other namespace name! - check cfg[namespace]) + - webroot/ - place your files **here** + - workers/ - workers live here + - config.sh - config - - master.sh: main config file, loaded with every request - - localhost:1337: example vhost file, loaded if `Host: ...` equals its name + - master.sh - main config file, loaded with every request + - localhost:1337 - example vhost file, loaded if `Host: ...` equals its name - src - server source files and modules (e.g. `ws.sh`) - response - files corresponding to specific HTTP status codes - listing.sh (code 210) is actually HTTP 200, but triggered in a directory with autoindex turned on and without a valid `index.shs` file -- templates - - section templates go here -- webroot - - place your files **here** -- secret - - users/passwords go here -- storage - - random data storage for shs apps +- templates - section templates go here +- secret - users, passwords and other Seecret data should be stored here +- storage - random data storage for your webapp ## Variables that we think are cool! diff --git a/config/master.sh b/config/master.sh index 22f36a9..da954dd 100644 --- a/config/master.sh +++ b/config/master.sh @@ -5,7 +5,9 @@ cfg[ip]=127.0.0.1 # IP address to bind to - use 0.0.0.0 to bind to all cfg[http]=true # enables/disables listening on HTTP cfg[port]=1337 # HTTP port -cfg[root]='webroot/' +cfg[namespace]='app' + +cfg[root]='webroot/' cfg[index]='index.shs' cfg[autoindex]=true @@ -18,16 +20,15 @@ cfg[ssl_cert]='' cfg[ssl_key]='' cfg[extension]='shs' -cfg[extra_headers]='server: HTTP.sh/0.92 (devel)' +cfg[extra_headers]='server: HTTP.sh/0.93 (devel)' -cfg[title]='HTTP.sh 0.92' +cfg[title]='HTTP.sh 0.93' cfg[php_enabled]=false # enable PHP script evalutaion (requires PHP) cfg[python_enabled]=false # enable Python script evalutaion (requires Python) -# by default, this log file is placed in the main directory - change it to /var/log/_name_ for production -cfg[log]='log' +cfg[log]='log' # filename # proxy functionality is very WiP cfg[proxy]=false -cfg[proxy_url]='http://example.com/' \ No newline at end of file +cfg[proxy_url]='http://example.com/' diff --git a/http.sh b/http.sh index 67f977c..072136a 100755 --- a/http.sh +++ b/http.sh @@ -1,18 +1,57 @@ #!/bin/bash trap ctrl_c INT +source config/master.sh function ctrl_c() { pkill -P $$ - echo -e "Killed all remaining processes.\nHave a great day!!" + echo -e "Killed all remaining processes.\nHave an awesome day!!" } +if [[ ! -f "$(pwd)/http.sh" ]]; then + echo -e "Please run HTTP.sh inside it's designated directory\nRunning the script from arbitrary locations isn't supported." + exit 1 +fi + +if [[ $1 == "init" ]]; then # will get replaced with proper parameter parsing in 1.0 + mkdir -p "${cfg[namespace]}/${cfg[root]}" "${cfg[namespace]}/workers/example" + touch "${cfg[namespace]}/config.sh" "${cfg[namespace]}/workers/example/control" + cat < "${cfg[namespace]}/config.sh" +# app config - loaded on server bootup +# your application-specific config goes here! + +# worker_add +# --- +# worker_add example 5 +LauraIsCute + + cat < "${cfg[namespace]}/workers/example/worker.sh" +#!/bin/bash +date +LauraIsCute + + cat < "${cfg[namespace]}/${cfg[root]}/index.shs" +#!/bin/bash +source templates/head.sh +echo "

Hello from HTTP.sh!


To get started with your app, check out $(pwd)/${cfg[namespace]}/ +
  • $(pwd)/${cfg[namespace]}/${cfg[root]} - your files go here
  • +
  • $(pwd)/${cfg[namespace]}/workers/ - worker directory, with an example one ready to go
  • +
  • $(pwd)/${cfg[namespace]}/config.sh - config for everything specific to your app AND workers
  • +
  • $(pwd)/config/master.sh - master server config
  • +
  • $(pwd)/src/ - HTTP.sh src, feel free to poke around :P
+ © sdomi, selfisekai, ptrcnull - 2020" +LauraIsCute + chmod +x "${cfg[namespace]}/workers/example/worker.sh" + + echo -e "Success..?\nTry running ./http.sh now" + exit 0 +fi + source src/worker.sh -if [[ -f "config/app.sh" ]]; then - source config/app.sh +if [[ -f "${cfg[namespace]}/config.sh" ]]; then + source "${cfg[namespace]}/config.sh" fi -source config/master.sh echo "HTTP.sh" if [[ ${cfg[http]} == true ]]; then @@ -29,4 +68,4 @@ if [[ ${cfg[ssl]} == true ]]; then fi fi -wait \ No newline at end of file +wait diff --git a/src/server.sh b/src/server.sh index 6fc659c..4e35247 100755 --- a/src/server.sh +++ b/src/server.sh @@ -83,7 +83,7 @@ while read param; do fi done -r[uri]=$(realpath ${cfg[root]}$(echo ${r[url]} | sed -E 's/\?(.*)$//')) +r[uri]=$(realpath "${cfg[namespace]}/${cfg[root]}$(echo ${r[url]} | sed -E 's/\?(.*)$//')") [[ -d "${r[uri]}/" ]] && pwd="${r[uri]}" || pwd=$(dirname "${r[uri]}") @@ -95,13 +95,13 @@ else r[proto]='https' fi -echo "$(date) - IP: ${r[ip]}, PROTO: ${r[proto]}, URL: ${r[url]}, GET_data: ${get_data[@]}, POST_data: ${post_data[@]}, POST_multipart: ${post_multipart[@]}" >> ${cfg[log]} +echo "$(date) - IP: ${r[ip]}, PROTO: ${r[proto]}, URL: ${r[url]}, GET_data: ${get_data[@]}, POST_data: ${post_data[@]}, POST_multipart: ${post_multipart[@]}" >> "${cfg[namespace]}/${cfg[log]}" if [[ ${r[status]} != 101 ]]; then if [[ -a ${r[uri]} && ! -r ${r[uri]} ]]; then r[status]=403 - elif [[ "$(echo -n ${r[uri]})" != "$(realpath ${cfg[root]})"* ]]; then + elif [[ "$(echo -n ${r[uri]})" != "$(realpath "${cfg[namespace]}/${cfg[root]}")"* ]]; then r[status]=403 elif [[ -f ${r[uri]} ]]; then r[status]=200 diff --git a/src/worker.sh b/src/worker.sh index 284a021..7108a69 100755 --- a/src/worker.sh +++ b/src/worker.sh @@ -4,15 +4,15 @@ # worker_add(name, interval) function worker_add() { - if [[ -x "workers/$1/worker.sh" ]]; then + if [[ -x "${cfg[namespace]}/workers/$1/worker.sh" ]]; then while true; do - workers/$1/worker.sh + "${cfg[namespace]}/workers/$1/worker.sh" sleep $2 - if [[ $(cat workers/$1/control) == "die" ]]; then - echo "" > workers/$1/control + if [[ $(cat "${cfg[namespace]}/workers/$1/control") == "die" ]]; then + echo "" > ${cfg[namespace]}/workers/$1/control while true; do - if [[ $(cat workers/$1/control) == "run" ]]; then - echo "" > workers/$1/control + if [[ $(cat "${cfg[namespace]}/workers/$1/control") == "run" ]]; then + echo "" > "${cfg[namespace]}/workers/$1/control" break fi sleep $2 @@ -26,10 +26,10 @@ function worker_add() { # worker_kill(name) function worker_kill() { - echo "die" > workers/$1/control + echo "die" > "${cfg[namespace]}/workers/$1/control" } # worker_resume(name) function worker_resume() { - echo "run" > workers/$1/control -} \ No newline at end of file + echo "run" > "${cfg[namespace]}/workers/$1/control" +} diff --git a/storage/pastes b/storage/.gitignore similarity index 100% rename from storage/pastes rename to storage/.gitignore diff --git a/storage/faves b/storage/faves deleted file mode 100644 index 7b71c6e..0000000 --- a/storage/faves +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/webroot/your_awesome_files_here b/webroot/your_awesome_files_here deleted file mode 100644 index e69de29..0000000 diff --git a/workers/example/control b/workers/example/control deleted file mode 100644 index 8b13789..0000000 --- a/workers/example/control +++ /dev/null @@ -1 +0,0 @@ - diff --git a/workers/example/worker.sh b/workers/example/worker.sh deleted file mode 100755 index 7d98e7e..0000000 --- a/workers/example/worker.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -date \ No newline at end of file