194 lines
3.4 KiB
C
194 lines
3.4 KiB
C
#include <err.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#ifdef __OpenBSD__
|
|
#include <unistd.h>
|
|
#else
|
|
#define pledge(a,b) 0
|
|
#endif
|
|
|
|
#include "xml.h"
|
|
|
|
static XMLParser x;
|
|
static char tag[256], inputname[256];
|
|
|
|
static char jschl_vc[256];
|
|
static char jschl_answer[256];
|
|
static char pass[256];
|
|
static char script[4096];
|
|
|
|
void
|
|
xmltagstart(struct xmlparser *x, const char *t, size_t tl)
|
|
{
|
|
if (!strcmp(t, "input") || !strcmp(t, "script"))
|
|
snprintf(tag, sizeof(tag), "%s", t);
|
|
}
|
|
|
|
void
|
|
xmltagend(struct xmlparser *x, const char *t, size_t tl, int st)
|
|
{
|
|
if (!strcmp(tag, "input"))
|
|
inputname[0] = tag[0] = '\0';
|
|
else if (!strcmp(tag, "script"))
|
|
tag[0] = '\0';
|
|
}
|
|
|
|
void
|
|
xmlattr(struct xmlparser *x, const char *t, size_t tl,
|
|
const char *a, size_t al, const char *v, size_t vl)
|
|
{
|
|
if (strcmp(tag, "input"))
|
|
return;
|
|
|
|
if (!strcmp(a, "name")) {
|
|
if (!strcmp(v, "jschl_vc") || !strcmp(v, "pass"))
|
|
snprintf(inputname, sizeof(inputname), "%s", v);
|
|
} else if (inputname[0] && !strcmp(a, "value")) {
|
|
if (!strcmp(inputname, "jschl_vc"))
|
|
snprintf(jschl_vc, sizeof(jschl_vc), "%s", v);
|
|
else if (!strcmp(inputname, "pass"))
|
|
snprintf(pass, sizeof(pass), "%s", v);
|
|
}
|
|
}
|
|
|
|
void
|
|
xmlcdata(struct xmlparser *x, const char *d, size_t dl)
|
|
{
|
|
char tmp[sizeof(script)];
|
|
|
|
if (strcmp(tag, "script"))
|
|
return;
|
|
|
|
snprintf(tmp, sizeof(tmp), "%s%s", script, d);
|
|
memcpy(script, tmp, sizeof(script));
|
|
}
|
|
|
|
int
|
|
calcvalue(char *script)
|
|
{
|
|
char *stopbreaking = "s,t,o,p,b,r,e,a,k,i,n,g,f, ";
|
|
char var[32] = "", key[32] = "", varkey[64] = "";
|
|
char *p, *s;
|
|
int op, pc, cv, nv, v = 0;
|
|
|
|
if (!(s = strstr(script, stopbreaking)))
|
|
return v;
|
|
s += strlen(stopbreaking);
|
|
|
|
for (p = s; *p; p++) {
|
|
if (*p == '=') {
|
|
*p = '\0';
|
|
snprintf(var, sizeof(var), "%s", s);
|
|
*p = '=';
|
|
break;
|
|
}
|
|
}
|
|
if (!var[0])
|
|
return v;
|
|
if (!(s = strchr(p, '"')))
|
|
return v;
|
|
s++;
|
|
|
|
for (p = s; *p; p++) {
|
|
if (*p == '"') {
|
|
*p = '\0';
|
|
snprintf(key, sizeof(key), "%s", s);
|
|
*p = '"';
|
|
break;
|
|
}
|
|
}
|
|
if (!key[0])
|
|
return v;
|
|
|
|
snprintf(varkey, sizeof(varkey), "%s.%s", var, key);
|
|
|
|
if (!(s = strchr(p, ':')))
|
|
return v;
|
|
s++;
|
|
|
|
op = '+';
|
|
while (1) {
|
|
// printf("op: %c\n", op);
|
|
|
|
pc = cv = nv = 0;
|
|
for (s = p; *s; s++) {
|
|
if (*s == ';') {
|
|
nv += cv;
|
|
// printf("nv: %d\n", nv);
|
|
break;
|
|
}
|
|
switch (*s) {
|
|
case '(':
|
|
nv += cv;
|
|
cv = 0;
|
|
break;
|
|
case '!':
|
|
case '+':
|
|
if (pc == '!')
|
|
cv++;
|
|
break;
|
|
case ')':
|
|
if (pc == ')')
|
|
break;
|
|
|
|
// printf(" cv: %d\n", cv);
|
|
nv *= 10;
|
|
|
|
break;
|
|
}
|
|
// printf(" %c\n", *s);
|
|
pc = *s;
|
|
}
|
|
|
|
switch (op) {
|
|
case '-': v -= nv; break;
|
|
case '+': v += nv; break;
|
|
case '*': v *= nv; break;
|
|
}
|
|
|
|
if (!(s = strstr(p, varkey)))
|
|
return v;
|
|
p = s + strlen(varkey);
|
|
op = *p;
|
|
}
|
|
|
|
return v;
|
|
}
|
|
|
|
int
|
|
main(int argc, char *argv[])
|
|
{
|
|
int value;
|
|
|
|
if (pledge("stdio", NULL) < 0)
|
|
err(1, "pledge");
|
|
|
|
if (argc != 2) {
|
|
fprintf(stderr, "%s <hostname>\n", argv[0]);
|
|
return 1;
|
|
}
|
|
|
|
x.xmlattr = xmlattr;
|
|
x.xmlcdata = xmlcdata;
|
|
x.xmltagstart = xmltagstart;
|
|
x.xmltagend = xmltagend;
|
|
x.getnext = getchar;
|
|
|
|
xml_parse(&x);
|
|
|
|
if (!(value = calcvalue(script)))
|
|
return 1;
|
|
value += strlen(argv[1]);
|
|
snprintf(jschl_answer, sizeof(jschl_answer), "%d", value);
|
|
|
|
printf("jschl_vc = %s\n", jschl_vc);
|
|
printf("pass = %s\n", pass);
|
|
printf("jschl_answer = %s\n", jschl_answer);
|
|
printf("\n");
|
|
printf("https://%s/cdn-cgi/l/chk_jschl?jschl_vc=%s&pass=%s&jschl_answer=%s\n",
|
|
argv[1], jschl_vc, pass, jschl_answer);
|
|
|
|
return 0;
|
|
}
|