From d5b036572ec5058817bf6e1e04a660407a1068a5 Mon Sep 17 00:00:00 2001
From: onefang
Date: Thu, 14 May 2020 10:48:05 +1000
Subject: Clean up the cleaning up.
Sanitize on input.
Use raw stuff internaly.
Escape on output.
---
src/sledjchisl/sledjchisl.c | 409 ++++++++++++++++++++++++++++----------------
1 file changed, 266 insertions(+), 143 deletions(-)
diff --git a/src/sledjchisl/sledjchisl.c b/src/sledjchisl/sledjchisl.c
index 3391ad3..07477db 100644
--- a/src/sledjchisl/sledjchisl.c
+++ b/src/sledjchisl/sledjchisl.c
@@ -488,6 +488,8 @@ qlist_t *dbRequests;
// A better idea, when we spawn tmux or spawn-fcgi, capture STDERR, full log everything to that, filtered log to the tmux console (STDOUT).
// Then we can use STDOUT / STDIN to run the console stuff.
+// TODO - escape anything that will turn the console into garbage.
+
// https://stackoverflow.com/questions/4842424/list-of-ansi-color-escape-sequences
char *logTypes[] =
{
@@ -633,7 +635,9 @@ int sendTmuxCmd(char *dest, char *cmd)
void waitTmuxText(char *dest, char *text)
{
int i;
- char *c = xmprintf("sleep 5; %s %s/%s capture-pane -t %s:'%s' -p | grep -E '%s' 2>&1 > /dev/null", Tcmd, scRun, Tsocket, Tconsole, dest, text);
+ // Using " for the grep pattern, coz ' might be used in a sim name.
+// TODO - should escape \ " ` in text.
+ char *c = xmprintf("sleep 5; %s %s/%s capture-pane -t %s:'%s' -p | grep -F \"%s\" 2>&1 > /dev/null", Tcmd, scRun, Tsocket, Tconsole, dest, text);
D("Waiting for '%s'.", text);
do
@@ -704,6 +708,25 @@ static int filterSims(struct dirtree *node)
return 0;
}
+// We particularly don't want \ " `
+char *cleanSimName(char *name)
+{
+ size_t l = strlen(name);
+ char *ret = xmalloc(l + 1);
+ int i, j = 0;
+
+ for (i = 0; i < l; i++)
+ {
+ char r = name[i];
+
+ if ((' ' == r) || (isalnum(r) != 0))
+ ret[j++] = r;
+ }
+ ret[j] = '\0';
+
+ return ret;
+}
+
simList *getSims()
{
simList *sims = xmalloc(sizeof(simList));
@@ -2244,7 +2267,7 @@ d(" %s = %s", qstrtrim_head(key), val);
return ret;
}
-void santize(qhashtbl_t *tbl, bool decode)
+void santize(qhashtbl_t *tbl)
{
qhashtbl_obj_t obj;
@@ -2254,36 +2277,12 @@ void santize(qhashtbl_t *tbl, bool decode)
{
char *n = obj.name, *o = (char *) obj.data;
- if (decode)
- qurl_decode(o);
-
-// if ((strcmp(n, "password") != 0) && (strcmp(n, "psswd") != 0))
- {
- // Poor mans Bobby Tables protection.
-// TODO - make this reversable, especially so these things can be used in aboutMe, and come out the other end unscathed.
-// qurl_encode doesn't handle \, but does the rest.
-// So that means don't qurl_decode it, and encode \\.
-// But then I have to qurl_decode everwhere.
- o = qstrreplace("tr", o, "'", "_");
- o = qstrreplace("tr", o, "\"", "_");
- o = qstrreplace("tr", o, ";", "_");
- o = qstrreplace("tr", o, "(", "_");
- o = qstrreplace("tr", o, ")", "_");
- }
-
+ qurl_decode(o);
tbl->putstr(tbl, n, o);
}
tbl->unlock(tbl);
}
-/*
-char *unsantize(char *str)
-{
- char *ret = qurl_decode(xstrdup(str));
- return ret;
-}
-*/
-
void outize(qgrow_t *reply, qhashtbl_t *tbl, char *label)
{
reply->addstrf(reply, "%s:
\n
\n", label);
@@ -2296,43 +2295,6 @@ void outize(qgrow_t *reply, qhashtbl_t *tbl, char *label)
reply->addstr(reply, "
\n");
}
-char *displayPrep(char *str)
-{
- char *ret = xstrdup(str), *t;
-
- qurl_decode(ret);
- t = qstrreplace("tn", ret, "<", "<");
- free(ret);
- ret = NULL;
- if (NULL != t)
- {
- ret = qstrreplace("tn", t, ">", ">");
- if (NULL == ret)
- ret = t;
- else
- free(t);
- }
-
- if (NULL == ret)
- ret = xstrdup(str);
-
- return ret;
-}
-
-char *encodeSlash(char *str)
-{
- char *ret = xstrdup(str), *t = qstrreplace("tn", str, "\\", "%5c");
-
- if (NULL != t)
- {
- free(ret);
- ret = t;
- }
-
- return ret;
-}
-
-
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie
enum cookieSame
{
@@ -2476,6 +2438,89 @@ static void HTMLheader(qgrow_t *reply, char *title)
HTMLdebug(reply);
}
+// TODO - maybe escape non printables as well?
+char *HTMLentities[] =
+{
+ "", "", "", "", "", "", "", "", "", // NUL SOH STX ETX EOT ENQ ACK BEL BS
+ "	", "
",
+ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", // VT FF CR SO SI DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US
+ " ", // Space
+ "!", """,
+ "#", "$",
+ "%", "&",
+ "'",
+ "(", ")",
+ "*",
+ "+",
+ ",",
+ "-",
+ ".",
+ "/",
+ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
+ ":", ";",
+ "<", "=", ">",
+ "?",
+ "@",
+ "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
+ "[", "\", "]",
+ "^",
+ "_",
+ "`",
+ "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
+ "{", "|", "}",
+ "~",
+ "", // DEL
+ " " // This is actually 160, not 128, but I hack around that.
+};
+static void HTMLescapeString(qgrow_t *reply, char *string)
+{
+ size_t l = strlen(string);
+ char *t = xmalloc(l * 10 + 1);
+ int i, j = 0;
+ boolean space = FALSE;
+
+ for (i = 0; i < l; i++)
+ {
+ int s = string[i];
+
+ // Alternate long line of spaces with space and .
+ if (' ' == s)
+ {
+ if (space)
+ {
+ s = 128;
+ space = FALSE;
+ }
+ else
+ space = TRUE;
+ }
+ else
+ {
+ space = FALSE;
+ if (128 == s) // The real 128 character.
+ {
+ t[j++] = ' ';
+ continue;
+ }
+ }
+
+ if (128 >= s)
+ {
+ char *r = HTMLentities[s];
+ size_t m = strlen(r);
+ int k;
+
+ for (k = 0; k < m; k++)
+ t[j++] = r[k];
+ }
+ else
+ t[j++] = ' ';
+ }
+ t[j] = '\0';
+ reply->addstr(reply, t);
+ free(t);
+}
+
static void HTMLtable(qgrow_t *reply, MYSQL *db, MYSQL_RES *result, char *caption, char *URL, char *id)
{
char *tbl = "";
@@ -2543,7 +2588,11 @@ static void HTMLtable(qgrow_t *reply, MYSQL *db, MYSQL_RES *result, char *captio
static void HTMLhidden(qgrow_t *reply, char *name, char *val)
{
if ((NULL != val) && ("" != val))
- reply->addstrf(reply, " \n", name, val);
+ {
+ reply->addstrf(reply, " addstr(reply, "\">\n");
+ }
}
static void HTMLform(qgrow_t *reply, char *action, char *token)
@@ -2596,7 +2645,11 @@ static void HTMLtextArea(qgrow_t *reply, char *name, char *title, int rows, int
if ("" != wrap)
reply->addstrf(reply, " wrap=\"%s\"", wrap);
if ((NULL != val) && ("" != val))
- reply->addstrf(reply, ">%s\n", val);
+ {
+ reply->addstr(reply, ">");
+ HTMLescapeString(reply, val);
+ reply->addstr(reply, "\n");
+ }
else
reply->addstrf(reply, ">\n");
}
@@ -2605,7 +2658,11 @@ static void HTMLtext(qgrow_t *reply, char *type, char *title, char *name, char *
{
reply->addstrf(reply, "