#include #include #include #include #ifdef __OpenBSD__ #include #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 \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; }