apcgi

Web client for aps on trusted networks
git clone git://jacobedwards.org/apcgi
Log | Files | Refs | README

commit 5f50cc3cd8e5453e260539adf748618ae7100ca6
Author: Jacob R. Edwards <jacob@jacobedwards.org>
Date:   Sun, 18 Jun 2023 16:32:56 -0700

Add CGI script, Makefile, README, etc.

The Makefile won't work for everyone, but gives a good idea of what
you need to do to get it setup. The README explains most things
about the project, and the urldecode and urlencode programs are
included here for simplicity.

Diffstat:
AMakefile | 31+++++++++++++++++++++++++++++++
AREADME | 42++++++++++++++++++++++++++++++++++++++++++
Aap.cgi | 80+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aurldecode.c | 42++++++++++++++++++++++++++++++++++++++++++
Aurlencode.c | 33+++++++++++++++++++++++++++++++++
5 files changed, 228 insertions(+), 0 deletions(-)

diff --git a/Makefile b/Makefile @@ -0,0 +1,31 @@ +root = /var/www +files = /bin/sh /usr/bin/sed /usr/local/bin/apc /usr/lib/libc.so.* +script = ap.cgi +htdocs = ${root}/htdocs/${site} +cgiroot = ${htdocs}/cgi +cc = ${CC} + +all: urlencode urldecode + +urlencode urldecode: + ${cc} -o $@ $@.c + +clean: + rm -f urlencode urldecode + +install: urlencode urldecode + for file in ${files}; do \ + mkdir -p ${root}/"$$(dirname "$$file")" && \ + cp -av "$$file" ${root}/"$$file"; done + cp -a urlencode urldecode ${root}/usr/bin + mkdir -p ${htdocs}/man + man -T html aps > ${htdocs}/man/aps.1.html + install -o root -g www -m 755 ${script} ${cgiroot}/${script} + +uninstall: + # NOT POSIX + rm -f ${files:%=${root}/%} + rm -f ${cgiroot}/${script} + rm -f ${htdocs}/man/aps.1.html + +.PHONY: install uninstall clean diff --git a/README b/README @@ -0,0 +1,42 @@ +This is a CGI script intended to be used as a basic ap client for +a phone which would otherwise have to be programmed in something +like Java. I'm not sure it's even that useful to have an ap client +on a phone, but I made this anyway. + +Before using this, understand that I did not think about security +while writing this. For instance the player command (which allows +the execution of arbitrary programs as the server) would not be +something you'd want an untrusted entity to have access to. That, +and keep in mind what the license clearly states: + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR + DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE + INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR + ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA + OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +Also note that it doesn't do much to ensure text is encoded correctly +for either the HTML document or the audio player server. + +So with that out of the way here's how to get it running on OpenBSD +(and probably other operating systems using a similar process): + +- Setup httpd.conf(5) with 'location "/cgi/*" { fastcgi }' +- Copy the script to the cgi directory (ensuring it's executable by www) +- Copy /bin/sh(1), sed(1), and apc(1) to /var/www for access in + chrooted environment. (echo(1) is also used, but is built into + OpenBSD's sh(1)) +- If dynamically linked, also copy the required libraries (which + should only be libc) +- Start aps with apsock=/var/www/tmp/aps +- Start httpd(8) and slowcgi(8) + +I believe with that it should be setup; just point a web browser +at the script and there you have it. + +To drive the point home: It's very important you protect this script +in some way. For my use case, I just use pf(4). diff --git a/ap.cgi b/ap.cgi @@ -0,0 +1,80 @@ +#!/bin/sh +# Copyright 2023 Jacob R. Edwards <jacob@jacobedwards.org> +# The ap cgi script +# +# WARNING: The player command is dangerous, this script should be +# protected from malicious entities. +# +# Depends on /bin/sh(1), sed(1), echo(1) (unless built-in to sh(1)), +# and apc(1). If dynamically linked, you should only need libc. +# It also depends on urlencode and urldecode, but that's included +# in the project. +# +# If chrooted, you will need the programs and library listed above +# and the server socket must be accessable with the new root, such +# as at $CHROOT/tmp/aps + +nam='Web Audio Player Client' +css=../ap.css +man=/man/aps.1.html + +encode() { + echo -n "$1" | urlencode +} + +# name, command +button() { + echo '<a href="'"?command=$(encode "$2")"'"><button>'"$1"'</button></a>' +} + +# name, value, extra attributes +input() { + # put autofocus attribute in input to auto focus + # placeholder="'"${3:-list /jimi}"'"> + echo '<form action="'"$DOCUMENT_URI"'"> +<label for="command">'"$1"'</label> +<br> +<input type="search" name="command" value="'"$2"'" '${3:+"$3"}'> +<input type="submit" value="Execute"> +</form>' +} + +echo -n 'Content-Type: text/html + +' + +exec 2>&1 + +command="$(echo ${QUERY_STRING#command=} | sed 'y/+/ /' | urldecode)" + +echo '<!DOCTYPE HTML><head> + <title>'"$nam"'</title> + <link rel="stylesheet" type="text/css" href="'"$css"'"> +</head>' + +echo '<body><h1>'"$nam"'</h1> +<p>See the <a href="'"$man"'">manual</a> for available commands.</p>' + +input Command '' autofocus +input 'Last Command' "$command" 'placeholder="'"$command"'"' + +button Prev previous +button Toggle toggle +button Next next + +echo '<br>' +button Status status +button Player player +button Playing name + +echo '<br>' +button Next 'list 1' +button 'Next Ten' 'list ,10' +button 'List' list + +echo -n '<hr><pre>' + +echo "$command" | apc | + sed "s!.*!<a href='?command=play+\"&'>&</a>!" + +echo '</pre></body>' diff --git a/urldecode.c b/urldecode.c @@ -0,0 +1,42 @@ +/* + * Copyright 2021 Jacob R. Edwards + * Decode URI Percent Encoding (See RFC 2396, Section 2.4.1., "Escaped Encoding") + */ + +#include <stdio.h> +#include <stdlib.h> + +int +main(void) +{ + char *b; + size_t l; + size_t s; + char o[3]; + int p; + unsigned char c; + char *e; + + o[2] = 0; + b = NULL; + s = 0; + while ((l = getdelim(&b, &s, '%', stdin)) != -1) { + if (b[l - 1] == '%') { + --l; + if (fread(o, 1, 2, stdin) != 2) + goto badescape; + c = strtoul(o, &e, 16); + if (*e) { +badescape: + perror("bad escape"); + return 1; + } + p = 1; + } else + p = 0; + if (fwrite(b, 1, l, stdout) != l || (p && fputc(c, stdout) < 0)) + return 1; + } + + return 0; +} diff --git a/urlencode.c b/urlencode.c @@ -0,0 +1,33 @@ +/* + * Copyright 2021 Jacob R. Edwards + * Percent Encode URI (See RFC 2396, Sections 2., "Characters") + */ + +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +int +main(void) +{ + int i, il, ol; + unsigned char ib[1024], ob[sizeof(ib) * 3 + 1]; + + while ((il = read(0, ib, sizeof(ib))) > 0) { + ol = 0; + for (i = 0; i < il; ++i) { + if (ib[i] == ' ') { + ob[ol++] = '+'; + } else if (ib[i] <= 0x20 || strchr(":/?#[]@!$&'()*+,;=" "+%\x7F", ib[i])) { + if (sprintf(ob + ol, "%%%.2X", ib[i]) != 3) + return 1; + ol += 3; + } else + ob[ol++] = ib[i]; + } + if (write(1, ob, ol) != ol) + return 1; + } + + return il == -1; +}