diff options
author | onefang | 2020-03-19 21:56:38 +1000 |
---|---|---|
committer | onefang | 2020-03-19 21:56:38 +1000 |
commit | c7a86d69efc198736f613cf9ebdf77536c5e9b07 (patch) | |
tree | 73ff8b6431fdc766d77c669c179a44bc8b88897e /src/sledjchisl/sledjchisl.c | |
parent | Make HTML checkbox validation work. (diff) | |
download | opensim-SC-c7a86d69efc198736f613cf9ebdf77536c5e9b07.zip opensim-SC-c7a86d69efc198736f613cf9ebdf77536c5e9b07.tar.gz opensim-SC-c7a86d69efc198736f613cf9ebdf77536c5e9b07.tar.bz2 opensim-SC-c7a86d69efc198736f613cf9ebdf77536c5e9b07.tar.xz |
Plug a lot of leaks.
Still some left, mostly in the database code.
Some of the remaining leaks I think are in the third party libraries.
Diffstat (limited to '')
-rw-r--r-- | src/sledjchisl/sledjchisl.c | 460 |
1 files changed, 279 insertions, 181 deletions
diff --git a/src/sledjchisl/sledjchisl.c b/src/sledjchisl/sledjchisl.c index 6a971c8..11b5fb2 100644 --- a/src/sledjchisl/sledjchisl.c +++ b/src/sledjchisl/sledjchisl.c | |||
@@ -318,6 +318,7 @@ static void newValidFunc(char *name, char *title, fieldValidFunc func) | |||
318 | validFunc *vf = xmalloc(sizeof(validFunc)); | 318 | validFunc *vf = xmalloc(sizeof(validFunc)); |
319 | vf->name = name; vf->title = title; vf->func = func; | 319 | vf->name = name; vf->title = title; vf->func = func; |
320 | fieldValidFuncs->put(fieldValidFuncs, vf->name, vf, sizeof(validFunc)); | 320 | fieldValidFuncs->put(fieldValidFuncs, vf->name, vf, sizeof(validFunc)); |
321 | free(vf); | ||
321 | } | 322 | } |
322 | 323 | ||
323 | typedef void *(*pageFunction) (char *file, reqData *Rd, HTMLfile *thisFile); | 324 | typedef void *(*pageFunction) (char *file, reqData *Rd, HTMLfile *thisFile); |
@@ -333,6 +334,7 @@ static void newDynPage(char *name, pageFunction func) | |||
333 | dynPage *dp = xmalloc(sizeof(dynPage)); | 334 | dynPage *dp = xmalloc(sizeof(dynPage)); |
334 | dp->name = name; dp->func = func; | 335 | dp->name = name; dp->func = func; |
335 | dynPages->put(dynPages, dp->name, dp, sizeof(dynPage)); | 336 | dynPages->put(dynPages, dp->name, dp, sizeof(dynPage)); |
337 | free(dp); | ||
336 | } | 338 | } |
337 | 339 | ||
338 | typedef void *(*pageBuildFunction) (reqData *Rd, char *message); | 340 | typedef void *(*pageBuildFunction) (reqData *Rd, char *message); |
@@ -348,6 +350,7 @@ static void newBuildPage(char *name, pageBuildFunction func, pageBuildFunction e | |||
348 | buildPage *bp = xmalloc(sizeof(buildPage)); | 350 | buildPage *bp = xmalloc(sizeof(buildPage)); |
349 | bp->name = name; bp->func = func; bp->eFunc = eFunc; | 351 | bp->name = name; bp->func = func; bp->eFunc = eFunc; |
350 | buildPages->put(buildPages, bp->name, bp, sizeof(buildPage)); | 352 | buildPages->put(buildPages, bp->name, bp, sizeof(buildPage)); |
353 | free(bp); | ||
351 | } | 354 | } |
352 | 355 | ||
353 | 356 | ||
@@ -434,6 +437,10 @@ static void showSesh(qgrow_t *reply, sesh *shs) | |||
434 | 437 | ||
435 | 438 | ||
436 | char toybuf[4096]; | 439 | char toybuf[4096]; |
440 | lua_State *L; | ||
441 | qhashtbl_t *configs; | ||
442 | MYSQL *database, *dbconn; | ||
443 | gridStats *stats; | ||
437 | boolean isTmux = 0; | 444 | boolean isTmux = 0; |
438 | boolean isWeb = 0; | 445 | boolean isWeb = 0; |
439 | char *pwd = ""; | 446 | char *pwd = ""; |
@@ -460,6 +467,7 @@ int newbieTimeOut = 30; | |||
460 | float loadAverageInc = 0.5; | 467 | float loadAverageInc = 0.5; |
461 | int simTimeOut = 45; | 468 | int simTimeOut = 45; |
462 | qhashtbl_t *mimeTypes; | 469 | qhashtbl_t *mimeTypes; |
470 | qlist_t *dbRequests; | ||
463 | 471 | ||
464 | 472 | ||
465 | // TODO - log to file. The problem is we don't know where to log until after we have loaded the configs, and before that we are spewing log messages. | 473 | // TODO - log to file. The problem is we don't know where to log until after we have loaded the configs, and before that we are spewing log messages. |
@@ -941,6 +949,7 @@ d("Getting field metadata for %s", table); | |||
941 | fld->flags = fields[i].flags; | 949 | fld->flags = fields[i].flags; |
942 | fld->decimals = fields[i].decimals; | 950 | fld->decimals = fields[i].decimals; |
943 | ret->put(ret, fld->name, fld, sizeof(*fld)); | 951 | ret->put(ret, fld->name, fld, sizeof(*fld)); |
952 | free(fld); | ||
944 | } | 953 | } |
945 | tables->put(tables, table, ret, sizeof(*ret)); | 954 | tables->put(tables, table, ret, sizeof(*ret)); |
946 | } | 955 | } |
@@ -958,9 +967,11 @@ void dbFreeFields(qlisttbl_t *flds) | |||
958 | qlisttbl_obj_t obj; | 967 | qlisttbl_obj_t obj; |
959 | memset((void *) &obj, 0, sizeof(obj)); | 968 | memset((void *) &obj, 0, sizeof(obj)); |
960 | flds->lock(flds); | 969 | flds->lock(flds); |
970 | d("Freeing fields."); | ||
961 | while(flds->getnext(flds, &obj, NULL, false) == true) | 971 | while(flds->getnext(flds, &obj, NULL, false) == true) |
962 | { | 972 | { |
963 | dbField *fld = (dbField *) obj.data; | 973 | dbField *fld = (dbField *) obj.data; |
974 | d("Freeing field %s", fld->name); | ||
964 | free(fld->name); | 975 | free(fld->name); |
965 | } | 976 | } |
966 | flds->unlock(flds); | 977 | flds->unlock(flds); |
@@ -1014,6 +1025,7 @@ void dbDoSomething(dbRequest *req, boolean count, ...) | |||
1014 | } | 1025 | } |
1015 | if (0 == i) | 1026 | if (0 == i) |
1016 | { | 1027 | { |
1028 | free(select); | ||
1017 | if (count) | 1029 | if (count) |
1018 | select = xmprintf(",Count(*)"); | 1030 | select = xmprintf(",Count(*)"); |
1019 | else | 1031 | else |
@@ -1505,6 +1517,7 @@ d("Execute %s", req->sql); | |||
1505 | { | 1517 | { |
1506 | char *t = xmprintf("%d", (int) *((int *) req->outBind[i].buffer)); | 1518 | char *t = xmprintf("%d", (int) *((int *) req->outBind[i].buffer)); |
1507 | flds->putstr(flds, req->rows->fieldNames[i], t); | 1519 | flds->putstr(flds, req->rows->fieldNames[i], t); |
1520 | free(t); | ||
1508 | break; | 1521 | break; |
1509 | } | 1522 | } |
1510 | 1523 | ||
@@ -1512,6 +1525,7 @@ d("Execute %s", req->sql); | |||
1512 | { | 1525 | { |
1513 | char *t = xmprintf("%d", (int) *((int *) req->outBind[i].buffer)); | 1526 | char *t = xmprintf("%d", (int) *((int *) req->outBind[i].buffer)); |
1514 | flds->putstr(flds, req->rows->fieldNames[i], t); | 1527 | flds->putstr(flds, req->rows->fieldNames[i], t); |
1528 | free(t); | ||
1515 | break; | 1529 | break; |
1516 | } | 1530 | } |
1517 | 1531 | ||
@@ -1525,6 +1539,7 @@ d("Execute %s", req->sql); | |||
1525 | char *t = xmprintf("%d", (int) *((int *) (req->outBind[i].buffer))); | 1539 | char *t = xmprintf("%d", (int) *((int *) (req->outBind[i].buffer))); |
1526 | //d("Setting %i %s %s", i, fld->name, t); | 1540 | //d("Setting %i %s %s", i, fld->name, t); |
1527 | flds->putstr(flds, req->rows->fieldNames[i], t); | 1541 | flds->putstr(flds, req->rows->fieldNames[i], t); |
1542 | free(t); | ||
1528 | break; | 1543 | break; |
1529 | } | 1544 | } |
1530 | 1545 | ||
@@ -1532,6 +1547,7 @@ d("Execute %s", req->sql); | |||
1532 | { | 1547 | { |
1533 | char *t = xmprintf("%d", (int) *((int *) req->outBind[i].buffer)); | 1548 | char *t = xmprintf("%d", (int) *((int *) req->outBind[i].buffer)); |
1534 | flds->putstr(flds, req->rows->fieldNames[i], t); | 1549 | flds->putstr(flds, req->rows->fieldNames[i], t); |
1550 | free(t); | ||
1535 | break; | 1551 | break; |
1536 | } | 1552 | } |
1537 | 1553 | ||
@@ -1584,11 +1600,10 @@ d("Execute %s", req->sql); | |||
1584 | } | 1600 | } |
1585 | } | 1601 | } |
1586 | else | 1602 | else |
1587 | { | ||
1588 | D("Not setting data %s, coz it's NULL", fld->name); | 1603 | D("Not setting data %s, coz it's NULL", fld->name); |
1589 | } | ||
1590 | } | 1604 | } |
1591 | req->rows->rows->addlast(req->rows->rows, flds, sizeof(*flds)); | 1605 | req->rows->rows->addlast(req->rows->rows, flds, sizeof(qhashtbl_t)); |
1606 | free(flds); | ||
1592 | } | 1607 | } |
1593 | } | 1608 | } |
1594 | 1609 | ||
@@ -1618,22 +1633,22 @@ void dbPull(reqData *Rd, char *table, rowData *rows) | |||
1618 | 1633 | ||
1619 | memset((void*)&obj, 0, sizeof(obj)); | 1634 | memset((void*)&obj, 0, sizeof(obj)); |
1620 | me->lock(me); | 1635 | me->lock(me); |
1621 | while(me->getnext(me, &obj, true) == true) | 1636 | while(me->getnext(me, &obj, false) == true) |
1622 | { | 1637 | { |
1623 | where = xmprintf("%s.%s", table, obj.name); | 1638 | where = xmprintf("%s.%s", table, obj.name); |
1624 | Rd->database->putstr(Rd->database, where, (char *) obj.data); | 1639 | Rd->database->putstr(Rd->database, where, (char *) obj.data); |
1625 | me->remove(me, obj.name); | 1640 | // me->remove(me, obj.name); |
1626 | free(where); | 1641 | free(where); |
1627 | } | 1642 | } |
1628 | me->unlock(me); | 1643 | me->unlock(me); |
1629 | free(me); | 1644 | me->free(me); |
1630 | } | 1645 | } |
1631 | 1646 | ||
1632 | /* | ||
1633 | void dbFreeRequest(dbRequest *req) | 1647 | void dbFreeRequest(dbRequest *req) |
1634 | { | 1648 | { |
1635 | int i; | 1649 | int i; |
1636 | 1650 | ||
1651 | D("Cleaning up prepared database request %s - %s", req->table, req->where); | ||
1637 | if (NULL != req->outBind) | 1652 | if (NULL != req->outBind) |
1638 | { | 1653 | { |
1639 | for (i = 0; i < req->outCount; i++) | 1654 | for (i = 0; i < req->outCount; i++) |
@@ -1649,6 +1664,7 @@ void dbFreeRequest(dbRequest *req) | |||
1649 | { | 1664 | { |
1650 | for (i = 0; i < req->inCount; i++) | 1665 | for (i = 0; i < req->inCount; i++) |
1651 | { | 1666 | { |
1667 | // TODO - this leaks for some bizare reason. | ||
1652 | if (NULL != req->inBind[i].buffer) free(req->inBind[i].buffer); | 1668 | if (NULL != req->inBind[i].buffer) free(req->inBind[i].buffer); |
1653 | if (NULL != req->inBind[i].length) free(req->inBind[i].length); | 1669 | if (NULL != req->inBind[i].length) free(req->inBind[i].length); |
1654 | if (NULL != req->inBind[i].error) free(req->inBind[i].error); | 1670 | if (NULL != req->inBind[i].error) free(req->inBind[i].error); |
@@ -1659,9 +1675,13 @@ void dbFreeRequest(dbRequest *req) | |||
1659 | 1675 | ||
1660 | if (req->freeOutParams) free(req->outParams); | 1676 | if (req->freeOutParams) free(req->outParams); |
1661 | if (NULL != req->sql) free(req->sql); | 1677 | if (NULL != req->sql) free(req->sql); |
1662 | if (NULL != req->prep) mysql_stmt_close(req->prep); | 1678 | if (NULL != req->prep) |
1679 | { | ||
1680 | if (0 != mysql_stmt_close(req->prep)) | ||
1681 | C("Unable to close the prepared statement!"); | ||
1682 | free(req->prep); | ||
1683 | } | ||
1663 | } | 1684 | } |
1664 | */ | ||
1665 | 1685 | ||
1666 | my_ulonglong dbCount(MYSQL *db, char *table, char *where) | 1686 | my_ulonglong dbCount(MYSQL *db, char *table, char *where) |
1667 | { | 1687 | { |
@@ -1908,15 +1928,14 @@ gridStats *getStats(MYSQL *db, gridStats *stats) | |||
1908 | rgnSizes->inParams = szi; | 1928 | rgnSizes->inParams = szi; |
1909 | rgnSizes->outParams = szo; | 1929 | rgnSizes->outParams = szo; |
1910 | rgnSizes->where = "sizeX != 0"; | 1930 | rgnSizes->where = "sizeX != 0"; |
1931 | dbRequests->addfirst(dbRequests, rgnSizes, sizeof(*rgnSizes)); | ||
1911 | } | 1932 | } |
1912 | dbDoSomething(rgnSizes, FALSE); | 1933 | dbDoSomething(rgnSizes, FALSE); |
1913 | rowData *rows = rgnSizes->rows; | 1934 | rowData *rows = rgnSizes->rows; |
1914 | qlist_obj_t obj; | 1935 | |
1915 | memset((void*)&obj, 0, sizeof(obj)); // must be cleared before call | 1936 | qhashtbl_t *row; |
1916 | rows->rows->lock(rows->rows); | 1937 | while (NULL != (row = rows->rows->getat(rows->rows, 0, NULL, true))) |
1917 | while (rows->rows->getnext(rows->rows, &obj, false) == true) | ||
1918 | { | 1938 | { |
1919 | qhashtbl_t *row = (qhashtbl_t *) obj.data; | ||
1920 | my_ulonglong x = 0, y = 0; | 1939 | my_ulonglong x = 0, y = 0; |
1921 | 1940 | ||
1922 | tmp = row->getstr(row, "sizeX", false); | 1941 | tmp = row->getstr(row, "sizeX", false); |
@@ -1930,11 +1949,13 @@ gridStats *getStats(MYSQL *db, gridStats *stats) | |||
1930 | else | 1949 | else |
1931 | y = atoll(tmp); | 1950 | y = atoll(tmp); |
1932 | simSize += x * y; | 1951 | simSize += x * y; |
1933 | free(row); | 1952 | // TODO - I can't win. valgrind complains that either something is being freed twice, or not freed at all, no matter what I do. |
1953 | // This seems to keep the memory loss down to a minimum. | ||
1954 | row->free(row); | ||
1955 | rows->rows->removefirst(rows->rows); | ||
1934 | } | 1956 | } |
1935 | rows->rows->unlock(rows->rows); | ||
1936 | free(rows->rows); | ||
1937 | free(rows->fieldNames); | 1957 | free(rows->fieldNames); |
1958 | rows->rows->free(rows->rows); | ||
1938 | free(rows); | 1959 | free(rows); |
1939 | 1960 | ||
1940 | tmp = xmprintf("%lu", simSize); | 1961 | tmp = xmprintf("%lu", simSize); |
@@ -1986,7 +2007,7 @@ void santize(qhashtbl_t *tbl, bool decode) | |||
1986 | 2007 | ||
1987 | memset((void*)&obj, 0, sizeof(obj)); | 2008 | memset((void*)&obj, 0, sizeof(obj)); |
1988 | tbl->lock(tbl); | 2009 | tbl->lock(tbl); |
1989 | while(tbl->getnext(tbl, &obj, true) == true) | 2010 | while(tbl->getnext(tbl, &obj, false) == true) |
1990 | { | 2011 | { |
1991 | char *n = obj.name, *o = (char *) obj.data; | 2012 | char *n = obj.name, *o = (char *) obj.data; |
1992 | 2013 | ||
@@ -2004,7 +2025,6 @@ void santize(qhashtbl_t *tbl, bool decode) | |||
2004 | } | 2025 | } |
2005 | 2026 | ||
2006 | tbl->putstr(tbl, n, o); | 2027 | tbl->putstr(tbl, n, o); |
2007 | free(o); | ||
2008 | } | 2028 | } |
2009 | tbl->unlock(tbl); | 2029 | tbl->unlock(tbl); |
2010 | } | 2030 | } |
@@ -2033,7 +2053,7 @@ enum cookieSame | |||
2033 | typedef struct _cookie cookie; | 2053 | typedef struct _cookie cookie; |
2034 | struct _cookie | 2054 | struct _cookie |
2035 | { | 2055 | { |
2036 | char *cookie, *value, *domain, *path; | 2056 | char *value, *domain, *path; |
2037 | // char *expires; // Use maxAge instead, it's far simpler to figure out. | 2057 | // char *expires; // Use maxAge instead, it's far simpler to figure out. |
2038 | int maxAge; | 2058 | int maxAge; |
2039 | boolean secure, httpOnly; | 2059 | boolean secure, httpOnly; |
@@ -2043,23 +2063,30 @@ struct _cookie | |||
2043 | cookie *setCookie(reqData *Rd, char *cki, char *value) | 2063 | cookie *setCookie(reqData *Rd, char *cki, char *value) |
2044 | { | 2064 | { |
2045 | cookie *ret = xzalloc(sizeof(cookie)); | 2065 | cookie *ret = xzalloc(sizeof(cookie)); |
2066 | char *cook = xstrdup(cki); | ||
2046 | int l, i; | 2067 | int l, i; |
2047 | 2068 | ||
2048 | ret->cookie = xstrdup(cki); | ||
2049 | // Validate this, as there is a limited set of characters allowed. | 2069 | // Validate this, as there is a limited set of characters allowed. |
2050 | qstrreplace("tr", ret->cookie, "()<>@,;:\\\"/[]?={} \t", "_"); | 2070 | qstrreplace("tr", cook, "()<>@,;:\\\"/[]?={} \t", "_"); |
2051 | l = strlen(ret->cookie); | 2071 | l = strlen(cook); |
2052 | for (i = 0; i < l; i++) | 2072 | for (i = 0; i < l; i++) |
2053 | { | 2073 | { |
2054 | if (iscntrl(ret->cookie[i]) != 0) | 2074 | if (iscntrl(cook[i]) != 0) |
2055 | ret->cookie[i] = '_'; | 2075 | cook[i] = '_'; |
2056 | } | 2076 | } |
2057 | ret->value = qurl_encode(value, strlen(value)); | 2077 | l = strlen(value); |
2078 | if (0 != l) | ||
2079 | ret->value = qurl_encode(value, l); | ||
2080 | else | ||
2081 | ret->value = value; | ||
2058 | ret->httpOnly = TRUE; | 2082 | ret->httpOnly = TRUE; |
2059 | ret->site = CS_STRICT; | 2083 | ret->site = CS_STRICT; |
2060 | ret->secure = TRUE; | 2084 | ret->secure = TRUE; |
2061 | ret->path = xstrdup(getStrH(Rd->headers, "SCRIPT_NAME")); | 2085 | ret->path = getStrH(Rd->headers, "SCRIPT_NAME"); |
2062 | Rd->Rcookies->put(Rd->Rcookies, cki, ret, sizeof(*ret)); | 2086 | Rd->Rcookies->put(Rd->Rcookies, cook, ret, sizeof(cookie)); |
2087 | free(ret); | ||
2088 | ret = Rd->Rcookies->get(Rd->Rcookies, cook, NULL, false); | ||
2089 | free(cook); | ||
2063 | 2090 | ||
2064 | return ret; | 2091 | return ret; |
2065 | } | 2092 | } |
@@ -2388,6 +2415,7 @@ static void HTMLfooter(qgrow_t *reply) | |||
2388 | fragment *newFragment(enum fragmentType type, char *text, int len) | 2415 | fragment *newFragment(enum fragmentType type, char *text, int len) |
2389 | { | 2416 | { |
2390 | fragment *frg = xmalloc(sizeof(fragment)); | 2417 | fragment *frg = xmalloc(sizeof(fragment)); |
2418 | |||
2391 | frg->type = type; | 2419 | frg->type = type; |
2392 | frg->length = len; | 2420 | frg->length = len; |
2393 | frg->text = xmalloc(len + 1); | 2421 | frg->text = xmalloc(len + 1); |
@@ -2435,8 +2463,10 @@ qlist_t *fragize(char *mm, size_t length) | |||
2435 | i += 4; | 2463 | i += 4; |
2436 | } | 2464 | } |
2437 | frg0 = newFragment(FT_TEXT, &mm[k], m - k); | 2465 | frg0 = newFragment(FT_TEXT, &mm[k], m - k); |
2438 | fragments->addlast(fragments, frg0, sizeof(*frg0)); | 2466 | fragments->addlast(fragments, frg0, sizeof(fragment)); |
2439 | fragments->addlast(fragments, frg1, sizeof(*frg1)); | 2467 | fragments->addlast(fragments, frg1, sizeof(fragment)); |
2468 | free(frg0); | ||
2469 | free(frg1); | ||
2440 | k = i; | 2470 | k = i; |
2441 | break; | 2471 | break; |
2442 | } | 2472 | } |
@@ -2450,11 +2480,12 @@ qlist_t *fragize(char *mm, size_t length) | |||
2450 | } | 2480 | } |
2451 | frg0 = newFragment(FT_TEXT, &mm[k], length - k); | 2481 | frg0 = newFragment(FT_TEXT, &mm[k], length - k); |
2452 | fragments->addlast(fragments, frg0, sizeof(*frg0)); | 2482 | fragments->addlast(fragments, frg0, sizeof(*frg0)); |
2483 | free(frg0); | ||
2453 | 2484 | ||
2454 | return fragments; | 2485 | return fragments; |
2455 | } | 2486 | } |
2456 | 2487 | ||
2457 | void unfragize(qlist_t *fragments, reqData *Rd) | 2488 | void unfragize(qlist_t *fragments, reqData *Rd, boolean fre) |
2458 | { | 2489 | { |
2459 | qlist_obj_t lobj; | 2490 | qlist_obj_t lobj; |
2460 | memset((void *) &lobj, 0, sizeof(lobj)); | 2491 | memset((void *) &lobj, 0, sizeof(lobj)); |
@@ -2468,8 +2499,12 @@ void unfragize(qlist_t *fragments, reqData *Rd) | |||
2468 | continue; | 2499 | continue; |
2469 | } | 2500 | } |
2470 | HTMLfill(Rd, frg->type, frg->text, frg->length); | 2501 | HTMLfill(Rd, frg->type, frg->text, frg->length); |
2502 | if (fre) | ||
2503 | free(frg->text); | ||
2471 | } | 2504 | } |
2472 | fragments->unlock(fragments); | 2505 | fragments->unlock(fragments); |
2506 | if (fre) | ||
2507 | fragments->free(fragments); | ||
2473 | } | 2508 | } |
2474 | 2509 | ||
2475 | HTMLfile *checkHTMLcache(char *file) | 2510 | HTMLfile *checkHTMLcache(char *file) |
@@ -2876,6 +2911,7 @@ static void freeSesh(reqData *Rd, boolean linky, boolean wipe) | |||
2876 | } | 2911 | } |
2877 | else | 2912 | else |
2878 | shs->leaf[0] = '\0'; | 2913 | shs->leaf[0] = '\0'; |
2914 | free(file); | ||
2879 | } | 2915 | } |
2880 | 2916 | ||
2881 | static void setToken_n_munchie(reqData *Rd, boolean linky) | 2917 | static void setToken_n_munchie(reqData *Rd, boolean linky) |
@@ -2900,8 +2936,8 @@ static void setToken_n_munchie(reqData *Rd, boolean linky) | |||
2900 | 2936 | ||
2901 | if (!linky) | 2937 | if (!linky) |
2902 | { | 2938 | { |
2903 | cookie *ck = setCookie(Rd, "toke_n_munchie", shs->toke_n_munchie); | 2939 | setCookie(Rd, "toke_n_munchie", shs->toke_n_munchie); |
2904 | cookie *ckh = setCookie(Rd, "hashish", shs->hashish); | 2940 | setCookie(Rd, "hashish", shs->hashish); |
2905 | } | 2941 | } |
2906 | char *tnm0 = xmprintf( "toke_n_munchie = \n" | 2942 | char *tnm0 = xmprintf( "toke_n_munchie = \n" |
2907 | "{\n" | 2943 | "{\n" |
@@ -2953,6 +2989,8 @@ t("stuff %s = %s", obj.name, (char *) obj.data); | |||
2953 | // Set the mtime on the file. | 2989 | // Set the mtime on the file. |
2954 | futimens(fd, shs->timeStamp); | 2990 | futimens(fd, shs->timeStamp); |
2955 | xclose(fd); | 2991 | xclose(fd); |
2992 | free(tnm1); | ||
2993 | free(tnm0); | ||
2956 | free(file); | 2994 | free(file); |
2957 | } | 2995 | } |
2958 | 2996 | ||
@@ -3052,14 +3090,18 @@ d("New sesh"); | |||
3052 | } | 3090 | } |
3053 | else | 3091 | else |
3054 | { | 3092 | { |
3055 | qstrcpy(ret->salt, sizeof(ret->salt), qhex_encode(buf, sizeof(buf))); | 3093 | t0 = qhex_encode(buf, sizeof(buf)); |
3094 | qstrcpy(ret->salt, sizeof(ret->salt), t0); | ||
3095 | free(t0); | ||
3056 | //d("salt %s", ret->salt); | 3096 | //d("salt %s", ret->salt); |
3057 | numBytes = getrandom((void *)buf, sizeof(buf), GRND_NONBLOCK); | 3097 | numBytes = getrandom((void *)buf, sizeof(buf), GRND_NONBLOCK); |
3058 | if (-1 == numBytes) | 3098 | if (-1 == numBytes) |
3059 | perror_msg("Unable to generate a suitable random number."); | 3099 | perror_msg("Unable to generate a suitable random number."); |
3060 | else | 3100 | else |
3061 | { | 3101 | { |
3062 | qstrcpy(ret->seshID, sizeof(ret->seshID), qhex_encode(buf, sizeof(buf))); | 3102 | t0 = qhex_encode(buf, sizeof(buf)); |
3103 | qstrcpy(ret->seshID, sizeof(ret->seshID), t0); | ||
3104 | free(t0); | ||
3063 | //d("seshID %s", ret->seshID); | 3105 | //d("seshID %s", ret->seshID); |
3064 | 3106 | ||
3065 | ret->timeStamp[0].tv_nsec = UTIME_OMIT; | 3107 | ret->timeStamp[0].tv_nsec = UTIME_OMIT; |
@@ -3079,14 +3121,17 @@ d("New sesh"); | |||
3079 | qstrcpy(ret->munchie, sizeof(ret->munchie), munchie); | 3121 | qstrcpy(ret->munchie, sizeof(ret->munchie), munchie); |
3080 | //d("munchie %s", ret->munchie); | 3122 | //d("munchie %s", ret->munchie); |
3081 | t0 = xmprintf("%s%s", getStrH(Rd->stuff, "UUID"), munchie); | 3123 | t0 = xmprintf("%s%s", getStrH(Rd->stuff, "UUID"), munchie); |
3124 | free(munchie); | ||
3082 | toke_n_munchie = myHMAC(t0, FALSE); | 3125 | toke_n_munchie = myHMAC(t0, FALSE); |
3083 | free(t0); | 3126 | free(t0); |
3084 | qstrcpy(ret->toke_n_munchie, sizeof(ret->toke_n_munchie), toke_n_munchie); | 3127 | qstrcpy(ret->toke_n_munchie, sizeof(ret->toke_n_munchie), toke_n_munchie); |
3085 | //d("toke_n_munchie %s", ret->toke_n_munchie); | 3128 | //d("toke_n_munchie %s", ret->toke_n_munchie); |
3086 | hashish = myHMACkey(ret->salt, toke_n_munchie, FALSE); | 3129 | hashish = myHMACkey(ret->salt, toke_n_munchie, FALSE); |
3130 | free(toke_n_munchie); | ||
3087 | qstrcpy(ret->hashish, sizeof(ret->hashish), hashish); | 3131 | qstrcpy(ret->hashish, sizeof(ret->hashish), hashish); |
3088 | //d("hashish %s", ret->hashish); | 3132 | //d("hashish %s", ret->hashish); |
3089 | t0 = myHMACkey(getStrH(Rd->configs, "pepper"), hashish, TRUE); | 3133 | t0 = myHMACkey(getStrH(Rd->configs, "pepper"), hashish, TRUE); |
3134 | free(hashish); | ||
3090 | qstrcpy(ret->leaf, sizeof(ret->leaf), t0); | 3135 | qstrcpy(ret->leaf, sizeof(ret->leaf), t0); |
3091 | //d("leaf %s", ret->leaf); | 3136 | //d("leaf %s", ret->leaf); |
3092 | free(t0); | 3137 | free(t0); |
@@ -3182,9 +3227,7 @@ static int validateSesh(reqData *Rd, qhashtbl_t *data, char *name) | |||
3182 | return ret; | 3227 | return ret; |
3183 | } | 3228 | } |
3184 | 3229 | ||
3185 | char *toke_n_munchie = "", *munchie = "", *hashish = "", | 3230 | char *toke_n_munchie = "", *munchie = "", *hashish = "", *leaf = "", *timeStamp = "", *seshion = "", *seshID = "", *t0, *t1; |
3186 | *leaf, *timeStamp = "", *seshion = "", *seshID = "", | ||
3187 | *t0, *t1; | ||
3188 | 3231 | ||
3189 | // In this case the session stuff has to come from specific places. | 3232 | // In this case the session stuff has to come from specific places. |
3190 | hashish = getStrH(Rd->queries, "hashish"); | 3233 | hashish = getStrH(Rd->queries, "hashish"); |
@@ -3224,141 +3267,143 @@ static int validateSesh(reqData *Rd, qhashtbl_t *data, char *name) | |||
3224 | 3267 | ||
3225 | if (0 == ret) | 3268 | if (0 == ret) |
3226 | { | 3269 | { |
3270 | // This is apparently controversial, I added it coz some of the various security docs suggested it's a good idea. | ||
3271 | // https://security.stackexchange.com/questions/139952/why-arent-sessions-exclusive-to-an-ip-address?rq=1 | ||
3272 | // Includes various reasons why it's bad. | ||
3273 | // Another good reason why it is bad, TOR. | ||
3274 | // So should make this a user option, like Mantis does. | ||
3275 | if (strcmp(getStrH(Rd->headers, "REMOTE_ADDR"), getStrH(tnm, "IP")) != 0) | ||
3227 | { | 3276 | { |
3228 | { | 3277 | bitchSession(Rd, "Wrong IP for session.", "Session IP doesn't match."); |
3229 | // This is apparently controversial, I added it coz some of the various security docs suggested it's a good idea. | 3278 | ret++; |
3230 | // https://security.stackexchange.com/questions/139952/why-arent-sessions-exclusive-to-an-ip-address?rq=1 | 3279 | } |
3231 | // Includes various reasons why it's bad. | 3280 | else |
3232 | // Another good reason why it is bad, TOR. | 3281 | { |
3233 | // So should make this a user option, like Mantis does. | 3282 | timeStamp = xmprintf("%ld.%ld", (long) st.st_mtim.tv_sec, st.st_mtim.tv_nsec); |
3234 | if (strcmp(getStrH(Rd->headers, "REMOTE_ADDR"), getStrH(tnm, "IP")) != 0) | 3283 | //d("timeStamp %s", timeStamp); |
3284 | seshion = xmprintf("%s%s", tnm->getstr(tnm, "seshID", false), timeStamp); | ||
3285 | //d("sesh %s", seshion); | ||
3286 | t0 = myHMAC(seshion, FALSE); | ||
3287 | munchie = xmprintf("%s%s", t0, timeStamp); | ||
3288 | //d("munchie %s", munchie); | ||
3289 | free(t0); | ||
3290 | free(timeStamp); | ||
3291 | t1 = getStrH(Rd->body, "munchie"); | ||
3292 | if ('\0' != t1[0]) | ||
3293 | { | ||
3294 | if (strcmp(t1, munchie) != 0) | ||
3235 | { | 3295 | { |
3236 | bitchSession(Rd, "Wrong IP for session.", "Session IP doesn't match."); | 3296 | bitchSession(Rd, "Wrong munchie for session.", "HMAC(seshID + timeStamp) != munchie"); |
3237 | ret++; | 3297 | ret++; |
3238 | } | 3298 | } |
3239 | else | 3299 | else |
3240 | { | 3300 | { |
3241 | timeStamp = xmprintf("%ld.%ld", (long) st.st_mtim.tv_sec, st.st_mtim.tv_nsec); | 3301 | t0 = xmprintf("%s%s", getStrH(tnm, "UUID"), munchie); |
3242 | //d("timeStamp %s", timeStamp); | 3302 | t1 = myHMAC(t0, FALSE); |
3243 | seshion = xmprintf("%s%s", tnm->getstr(tnm, "seshID", false), timeStamp); | ||
3244 | //d("sesh %s", seshion); | ||
3245 | t0 = myHMAC(seshion, FALSE); | ||
3246 | munchie = xmprintf("%s%s", t0, timeStamp); | ||
3247 | //d("munchie %s", munchie); | ||
3248 | free(t0); | 3303 | free(t0); |
3249 | t1 = getStrH(Rd->body, "munchie"); | ||
3250 | if ('\0' != t1[0]) | ||
3251 | { | ||
3252 | if (strcmp(t1, munchie) != 0) | ||
3253 | { | ||
3254 | bitchSession(Rd, "Wrong munchie for session.", "HMAC(seshID + timeStamp) != munchie"); | ||
3255 | ret++; | ||
3256 | } | ||
3257 | else | ||
3258 | { | ||
3259 | t0 = xmprintf("%s%s", getStrH(tnm, "UUID"), munchie); | ||
3260 | t1 = myHMAC(t0, FALSE); | ||
3261 | free(t0); | ||
3262 | 3304 | ||
3263 | //d("toke_n_munchie %s", t1); | 3305 | //d("toke_n_munchie %s", t1); |
3264 | if (strcmp(t1, toke_n_munchie) != 0) | 3306 | if (strcmp(t1, toke_n_munchie) != 0) |
3265 | { | 3307 | { |
3266 | bitchSession(Rd, "Wrong toke_n_munchie for session.", "HMAC(UUID + munchie) != toke_n_munchie"); | 3308 | bitchSession(Rd, "Wrong toke_n_munchie for session.", "HMAC(UUID + munchie) != toke_n_munchie"); |
3267 | ret++; | 3309 | ret++; |
3268 | } | ||
3269 | free(t1); | ||
3270 | } | ||
3271 | } | 3310 | } |
3311 | free(t1); | ||
3312 | } | ||
3313 | } | ||
3272 | 3314 | ||
3273 | if (0 == ret) | 3315 | if (0 == ret) |
3274 | { | 3316 | { |
3275 | if (linky) | 3317 | if (linky) |
3276 | { | 3318 | { |
3277 | t0 = xmprintf("%s%s", getStrH(tnm, "UUID"), munchie); | 3319 | t0 = xmprintf("%s%s", getStrH(tnm, "UUID"), munchie); |
3278 | t1 = myHMAC(t0, FALSE); | 3320 | t1 = myHMAC(t0, FALSE); |
3279 | free(t0); | 3321 | free(t0); |
3280 | toke_n_munchie = t1; | 3322 | toke_n_munchie = t1; |
3281 | //d("toke_n_munchie %s", t1); | 3323 | //d("toke_n_munchie %s", t1); |
3282 | } | 3324 | } |
3283 | t1 = myHMACkey(getStrH(tnm, "salt"), toke_n_munchie, FALSE); | 3325 | t1 = myHMACkey(getStrH(tnm, "salt"), toke_n_munchie, FALSE); |
3284 | //d("hashish %s", t1); | 3326 | //d("hashish %s", t1); |
3285 | if (strcmp(t1, hashish) != 0) | 3327 | if (strcmp(t1, hashish) != 0) |
3286 | { | 3328 | { |
3287 | bitchSession(Rd, "Wrong hashish for session.", "HMAC(toke_n_munchie + salt) != hashish"); | 3329 | bitchSession(Rd, "Wrong hashish for session.", "HMAC(toke_n_munchie + salt) != hashish"); |
3288 | ret++; | 3330 | ret++; |
3289 | } | 3331 | } |
3332 | free(t1); | ||
3290 | 3333 | ||
3291 | if (now.tv_sec > st.st_mtim.tv_sec + idleTimeOut) | 3334 | if (now.tv_sec > st.st_mtim.tv_sec + idleTimeOut) |
3292 | { | 3335 | { |
3293 | W("Session idled out."); | 3336 | W("Session idled out."); |
3294 | Rd->vegOut = TRUE; | 3337 | Rd->vegOut = TRUE; |
3295 | } | 3338 | } |
3296 | else | 3339 | else |
3297 | { | 3340 | { |
3298 | if (now.tv_sec > st.st_mtim.tv_sec + seshTimeOut) | 3341 | if (now.tv_sec > st.st_mtim.tv_sec + seshTimeOut) |
3299 | { | 3342 | { |
3300 | W("Session timed out."); | 3343 | W("Session timed out."); |
3301 | Rd->vegOut = TRUE; | 3344 | Rd->vegOut = TRUE; |
3302 | } | 3345 | } |
3303 | else | 3346 | else |
3304 | { | 3347 | { |
3305 | W("Validated session."); | 3348 | W("Validated session."); |
3306 | sesh *shs = &Rd->shs; | 3349 | sesh *shs = &Rd->shs; |
3307 | 3350 | ||
3308 | qstrcpy(shs->leaf, sizeof(shs->leaf), leaf); | 3351 | qstrcpy(shs->leaf, sizeof(shs->leaf), leaf); |
3309 | if (linky) | 3352 | if (linky) |
3310 | { | 3353 | { |
3311 | W("Validated session linky."); | 3354 | W("Validated session linky."); |
3312 | addStrL(Rd->messages, "Congratulations, you have validated your new account. Now you can log onto the web site."); | 3355 | addStrL(Rd->messages, "Congratulations, you have validated your new account. Now you can log onto the web site."); |
3313 | addStrL(Rd->messages, "NOTE - you wont be able to log onto the grid until your new account has been approved."); | 3356 | addStrL(Rd->messages, "NOTE - you wont be able to log onto the grid until your new account has been approved."); |
3314 | Rd->lnk = xzalloc(sizeof(sesh)); | 3357 | Rd->lnk = xzalloc(sizeof(sesh)); |
3315 | qstrcpy(Rd->lnk->leaf, sizeof(Rd->lnk->leaf), leaf); | 3358 | qstrcpy(Rd->lnk->leaf, sizeof(Rd->lnk->leaf), leaf); |
3316 | Rd->chillOut = TRUE; | 3359 | Rd->chillOut = TRUE; |
3317 | freeSesh(Rd, linky, FALSE); | 3360 | freeSesh(Rd, linky, FALSE); |
3318 | qstrcpy(Rd->lnk->leaf, sizeof(Rd->lnk->leaf), ""); | 3361 | qstrcpy(Rd->lnk->leaf, sizeof(Rd->lnk->leaf), ""); |
3319 | Rd->func = (pageBuildFunction) loginPage; | 3362 | Rd->func = (pageBuildFunction) loginPage; |
3320 | Rd->doit = "logout"; | 3363 | Rd->doit = "logout"; |
3321 | // TODO - we might want to delete their old .lua session as well. Maybe? Don't think we have any suitable codes to find it. | 3364 | // TODO - we might want to delete their old .lua session as well. Maybe? Don't think we have any suitable codes to find it. |
3322 | } | 3365 | } |
3323 | else | 3366 | else |
3324 | { | 3367 | { |
3325 | qstrcpy(shs->sesh, sizeof(shs->sesh), seshion); | 3368 | qstrcpy(shs->sesh, sizeof(shs->sesh), seshion); |
3326 | qstrcpy(shs->toke_n_munchie, sizeof(shs->toke_n_munchie), toke_n_munchie); | 3369 | qstrcpy(shs->toke_n_munchie, sizeof(shs->toke_n_munchie), toke_n_munchie); |
3327 | qstrcpy(shs->hashish, sizeof(shs->hashish), hashish); | 3370 | qstrcpy(shs->hashish, sizeof(shs->hashish), hashish); |
3328 | qstrcpy(shs->munchie, sizeof(shs->munchie), munchie); | 3371 | qstrcpy(shs->munchie, sizeof(shs->munchie), munchie); |
3329 | qstrcpy(shs->salt, sizeof(shs->salt), tnm->getstr(tnm, "salt", false)); | 3372 | qstrcpy(shs->salt, sizeof(shs->salt), tnm->getstr(tnm, "salt", false)); |
3330 | qstrcpy(shs->seshID, sizeof(shs->seshID), tnm->getstr(tnm, "seshID", false)); | 3373 | qstrcpy(shs->seshID, sizeof(shs->seshID), tnm->getstr(tnm, "seshID", false)); |
3331 | shs->timeStamp[0].tv_nsec = UTIME_OMIT; | 3374 | shs->timeStamp[0].tv_nsec = UTIME_OMIT; |
3332 | shs->timeStamp[0].tv_sec = UTIME_OMIT; | 3375 | shs->timeStamp[0].tv_sec = UTIME_OMIT; |
3333 | memcpy(&shs->timeStamp[1], &st.st_mtim, sizeof(struct timespec)); | 3376 | memcpy(&shs->timeStamp[1], &st.st_mtim, sizeof(struct timespec)); |
3334 | t0 = tnm->getstr(tnm, "linky-hashish", false); | 3377 | t0 = tnm->getstr(tnm, "linky-hashish", false); |
3335 | if (NULL != t0) | 3378 | if (NULL != t0) |
3336 | Rd->stuff->putstr(Rd->stuff, "linky-hashish", t0); | 3379 | Rd->stuff->putstr(Rd->stuff, "linky-hashish", t0); |
3337 | } | 3380 | } |
3338 | } | 3381 | } |
3339 | 3382 | ||
3340 | qhashtbl_obj_t obj; | 3383 | qhashtbl_obj_t obj; |
3341 | 3384 | ||
3342 | memset((void*)&obj, 0, sizeof(obj)); | 3385 | memset((void*)&obj, 0, sizeof(obj)); |
3343 | tnm->lock(tnm); | 3386 | tnm->lock(tnm); |
3344 | while(tnm->getnext(tnm, &obj, false) == true) | 3387 | while(tnm->getnext(tnm, &obj, false) == true) |
3345 | { | 3388 | { |
3346 | char *n = obj.name; | 3389 | char *n = obj.name; |
3347 | 3390 | ||
3348 | if ((strcmp("salt", n) != 0) && (strcmp("seshID", n) != 0)) | 3391 | if ((strcmp("salt", n) != 0) && (strcmp("seshID", n) != 0)) |
3349 | { | 3392 | { |
3350 | t("Lua %s = %s", n, (char *) obj.data); | 3393 | t("Lua %s = %s", n, (char *) obj.data); |
3351 | Rd->stuff->putstr(Rd->stuff, obj.name, (char *) obj.data); | 3394 | Rd->stuff->putstr(Rd->stuff, obj.name, (char *) obj.data); |
3352 | } | ||
3353 | } | ||
3354 | tnm->unlock(tnm); | ||
3355 | Rd->database->putstr(Rd->database, "UserAccounts.PrincipalID", tnm->getstr(tnm, "UUID", true)); | ||
3356 | } | ||
3357 | } | 3395 | } |
3396 | } | ||
3397 | tnm->unlock(tnm); | ||
3398 | Rd->database->putstr(Rd->database, "UserAccounts.PrincipalID", tnm->getstr(tnm, "UUID", true)); | ||
3358 | } | 3399 | } |
3359 | } | 3400 | } |
3401 | free(munchie); | ||
3402 | free(seshion); | ||
3360 | } | 3403 | } |
3361 | } | 3404 | } |
3405 | free(leaf); | ||
3406 | tnm->free(tnm); | ||
3362 | } | 3407 | } |
3363 | 3408 | ||
3364 | return ret; | 3409 | return ret; |
@@ -3597,6 +3642,7 @@ static int validateName(reqData *Rd, qhashtbl_t *data, char *nm) | |||
3597 | acnts->inParams = szi; | 3642 | acnts->inParams = szi; |
3598 | acnts->outParams = szo; | 3643 | acnts->outParams = szo; |
3599 | acnts->where = "FirstName=? and LastName=?"; | 3644 | acnts->where = "FirstName=? and LastName=?"; |
3645 | dbRequests->addfirst(dbRequests, acnts, sizeof(*acnts)); | ||
3600 | } | 3646 | } |
3601 | dbDoSomething(acnts, FALSE, name, s); | 3647 | dbDoSomething(acnts, FALSE, name, s); |
3602 | rowData *rows = acnts->rows; | 3648 | rowData *rows = acnts->rows; |
@@ -3621,8 +3667,8 @@ static int validateName(reqData *Rd, qhashtbl_t *data, char *nm) | |||
3621 | } | 3667 | } |
3622 | else | 3668 | else |
3623 | { | 3669 | { |
3624 | W("More than one UserAccounts record with that name."); | 3670 | W("More than one UserAccounts record with that name."); |
3625 | ret++; | 3671 | ret++; |
3626 | } | 3672 | } |
3627 | bitch(Rd, "Login failed.", "Could not find user record."); | 3673 | bitch(Rd, "Login failed.", "Could not find user record."); |
3628 | } | 3674 | } |
@@ -3645,8 +3691,8 @@ static int validateName(reqData *Rd, qhashtbl_t *data, char *nm) | |||
3645 | Rd->database->putstr(Rd->database, "auth.passwordHash", getStrH(tnm, "passwordHash")); | 3691 | Rd->database->putstr(Rd->database, "auth.passwordHash", getStrH(tnm, "passwordHash")); |
3646 | tnm->free(tnm); | 3692 | tnm->free(tnm); |
3647 | } | 3693 | } |
3648 | Rd->stuff->putstr(Rd->stuff, "UUID", xstrdup(getStrH(Rd->database, "UserAccounts.PrincipalID"))); | 3694 | Rd->stuff->putstr(Rd->stuff, "UUID", getStrH(Rd->database, "UserAccounts.PrincipalID")); |
3649 | Rd->stuff->putstr(Rd->stuff, "level", xstrdup(getStrH(Rd->database, "UserAccounts.Userlevel"))); | 3695 | Rd->stuff->putstr(Rd->stuff, "level", getStrH(Rd->database, "UserAccounts.Userlevel")); |
3650 | if (s) {s--; *s = ' '; s++;} | 3696 | if (s) {s--; *s = ' '; s++;} |
3651 | Rd->stuff->putstr(Rd->stuff, "name", xstrdup(name)); | 3697 | Rd->stuff->putstr(Rd->stuff, "name", xstrdup(name)); |
3652 | if (s) {s--; *s = '\0'; s++;} | 3698 | if (s) {s--; *s = '\0'; s++;} |
@@ -3696,12 +3742,14 @@ static int validateName(reqData *Rd, qhashtbl_t *data, char *nm) | |||
3696 | Rd->stuff->putstr(Rd->stuff, "name", xstrdup(name)); | 3742 | Rd->stuff->putstr(Rd->stuff, "name", xstrdup(name)); |
3697 | } | 3743 | } |
3698 | } | 3744 | } |
3699 | free(rows->rows); | ||
3700 | free(rows->fieldNames); | 3745 | free(rows->fieldNames); |
3746 | rows->rows->free(rows->rows); | ||
3701 | free(rows); | 3747 | free(rows); |
3748 | tnm->free(tnm); | ||
3702 | if (s) {s--; *s = ' '; s++;} | 3749 | if (s) {s--; *s = ' '; s++;} |
3703 | } | 3750 | } |
3704 | } | 3751 | } |
3752 | free(name); | ||
3705 | 3753 | ||
3706 | badBoy(ret, Rd, data, "name", NULL); | 3754 | badBoy(ret, Rd, data, "name", NULL); |
3707 | return ret; | 3755 | return ret; |
@@ -3733,6 +3781,7 @@ static int validatePassword(reqData *Rd, qhashtbl_t *data, char *name) | |||
3733 | auth->inParams = szi; | 3781 | auth->inParams = szi; |
3734 | auth->outParams = szo; | 3782 | auth->outParams = szo; |
3735 | auth->where = "UUID=?"; | 3783 | auth->where = "UUID=?"; |
3784 | dbRequests->addfirst(dbRequests, auth, sizeof(*auth)); | ||
3736 | } | 3785 | } |
3737 | dbDoSomething(auth, FALSE, UUID); | 3786 | dbDoSomething(auth, FALSE, UUID); |
3738 | rowData *rows = auth->rows; | 3787 | rowData *rows = auth->rows; |
@@ -3776,11 +3825,15 @@ static int validatePassword(reqData *Rd, qhashtbl_t *data, char *name) | |||
3776 | ret++; | 3825 | ret++; |
3777 | } | 3826 | } |
3778 | Rd->stuff->putstr(Rd->stuff, "passwordHash", md5ascii); | 3827 | Rd->stuff->putstr(Rd->stuff, "passwordHash", md5ascii); |
3779 | free(md5ascii); | ||
3780 | } | 3828 | } |
3829 | free(md5ascii); | ||
3781 | free(where); | 3830 | free(where); |
3782 | } | 3831 | } |
3832 | free(me); | ||
3783 | } | 3833 | } |
3834 | free(rows->fieldNames); | ||
3835 | rows->rows->free(rows->rows); | ||
3836 | free(rows); | ||
3784 | } | 3837 | } |
3785 | } | 3838 | } |
3786 | else if (create) | 3839 | else if (create) |
@@ -3827,6 +3880,7 @@ static int validatePassword(reqData *Rd, qhashtbl_t *data, char *name) | |||
3827 | } | 3880 | } |
3828 | else | 3881 | else |
3829 | { | 3882 | { |
3883 | free(salt); | ||
3830 | salt = qhex_encode(md5hash, 16); | 3884 | salt = qhex_encode(md5hash, 16); |
3831 | hash = xmprintf("%s:%s", salt, getStrH(Rd->stuff, "passwordSalt")); | 3885 | hash = xmprintf("%s:%s", salt, getStrH(Rd->stuff, "passwordSalt")); |
3832 | if (!qhashmd5((void *) hash, strlen(hash), md5hash)) | 3886 | if (!qhashmd5((void *) hash, strlen(hash), md5hash)) |
@@ -3836,10 +3890,13 @@ static int validatePassword(reqData *Rd, qhashtbl_t *data, char *name) | |||
3836 | } | 3890 | } |
3837 | else | 3891 | else |
3838 | { | 3892 | { |
3893 | free(hash); | ||
3839 | hash = qhex_encode(md5hash, 16); | 3894 | hash = qhex_encode(md5hash, 16); |
3840 | Rd->stuff->putstr(Rd->stuff, "passwordHash", hash); | 3895 | Rd->stuff->putstr(Rd->stuff, "passwordHash", hash); |
3841 | Rd->chillOut = TRUE; | 3896 | Rd->chillOut = TRUE; |
3842 | } | 3897 | } |
3898 | free(hash); | ||
3899 | free(salt); | ||
3843 | } | 3900 | } |
3844 | } | 3901 | } |
3845 | } | 3902 | } |
@@ -3866,7 +3923,7 @@ static int validatePassword(reqData *Rd, qhashtbl_t *data, char *name) | |||
3866 | { | 3923 | { |
3867 | pswd = qhex_encode(md5hash, 16); | 3924 | pswd = qhex_encode(md5hash, 16); |
3868 | hash = xmprintf("%s:%s", pswd, Osalt); | 3925 | hash = xmprintf("%s:%s", pswd, Osalt); |
3869 | 3926 | free(pswd); | |
3870 | if (!qhashmd5((void *) hash, strlen(hash), md5hash)) | 3927 | if (!qhashmd5((void *) hash, strlen(hash), md5hash)) |
3871 | { | 3928 | { |
3872 | bitch(Rd, "Internal session error.", "Confirm - qhashmd5(passwordSalt) failed."); | 3929 | bitch(Rd, "Internal session error.", "Confirm - qhashmd5(passwordSalt) failed."); |
@@ -3874,12 +3931,14 @@ static int validatePassword(reqData *Rd, qhashtbl_t *data, char *name) | |||
3874 | } | 3931 | } |
3875 | else | 3932 | else |
3876 | { | 3933 | { |
3934 | free(hash); | ||
3877 | hash = qhex_encode(md5hash, 16); | 3935 | hash = qhex_encode(md5hash, 16); |
3878 | if (strcmp(hash, Ohash) != 0) | 3936 | if (strcmp(hash, Ohash) != 0) |
3879 | { | 3937 | { |
3880 | bitch(Rd, "Passwords are not the same.", ""); | 3938 | bitch(Rd, "Passwords are not the same.", ""); |
3881 | ret++; | 3939 | ret++; |
3882 | } | 3940 | } |
3941 | free(hash); | ||
3883 | } | 3942 | } |
3884 | } | 3943 | } |
3885 | } | 3944 | } |
@@ -3920,6 +3979,7 @@ static int validateUUID(reqData *Rd, qhashtbl_t *data, char *name) | |||
3920 | uuids->inParams = szi; | 3979 | uuids->inParams = szi; |
3921 | uuids->outParams = szo; | 3980 | uuids->outParams = szo; |
3922 | uuids->where = "PrincipalID=?"; | 3981 | uuids->where = "PrincipalID=?"; |
3982 | dbRequests->addfirst(dbRequests, uuids, sizeof(*uuids)); | ||
3923 | } | 3983 | } |
3924 | 3984 | ||
3925 | if ((strcmp("cancel", Rd->doit) == 0) || (strcmp("logout", Rd->doit) == 0)) | 3985 | if ((strcmp("cancel", Rd->doit) == 0) || (strcmp("logout", Rd->doit) == 0)) |
@@ -4017,13 +4077,14 @@ static int validateUUID(reqData *Rd, qhashtbl_t *data, char *name) | |||
4017 | 4077 | ||
4018 | void loginPage(reqData *Rd, char *message) | 4078 | void loginPage(reqData *Rd, char *message) |
4019 | { | 4079 | { |
4020 | char *name = xstrdup(getStrH(Rd->stuff, "name")); | 4080 | char *name = xstrdup(getStrH(Rd->stuff, "name")), *linky = checkLinky(Rd); |
4021 | 4081 | ||
4022 | Rd->stuff->remove(Rd->stuff, "UUID"); | 4082 | Rd->stuff->remove(Rd->stuff, "UUID"); |
4023 | HTMLheader(Rd->reply, "<!--#echo var=\"grid\" --> account manager"); | 4083 | HTMLheader(Rd->reply, "<!--#echo var=\"grid\" --> account manager"); |
4024 | HTMLdebug(Rd->reply); | 4084 | HTMLdebug(Rd->reply); |
4025 | Rd->reply->addstrf(Rd->reply, "<h1><!--#echo var=\"grid\" --> account manager</h1>\n"); | 4085 | Rd->reply->addstrf(Rd->reply, "<h1><!--#echo var=\"grid\" --> account manager</h1>\n"); |
4026 | Rd->reply->addstr(Rd->reply, checkLinky(Rd)); | 4086 | Rd->reply->addstr(Rd->reply, linky); |
4087 | free(linky); | ||
4027 | if (0 != Rd->errors->size(Rd->messages)) | 4088 | if (0 != Rd->errors->size(Rd->messages)) |
4028 | HTMLlist(Rd->reply, "messages -", Rd->messages); | 4089 | HTMLlist(Rd->reply, "messages -", Rd->messages); |
4029 | HTMLform(Rd->reply, "", Rd->shs.munchie); | 4090 | HTMLform(Rd->reply, "", Rd->shs.munchie); |
@@ -4044,7 +4105,7 @@ void loginPage(reqData *Rd, char *message) | |||
4044 | 4105 | ||
4045 | void accountCreationPage(reqData *Rd, char *message) | 4106 | void accountCreationPage(reqData *Rd, char *message) |
4046 | { | 4107 | { |
4047 | char *name = getStrH(Rd->body, "name"); | 4108 | char *name = getStrH(Rd->body, "name"), *linky = checkLinky(Rd); |
4048 | char *toke_n_munchie = getCookie(Rd->Rcookies, "toke_n_munchie"); | 4109 | char *toke_n_munchie = getCookie(Rd->Rcookies, "toke_n_munchie"); |
4049 | char *tmp = xmalloc(16), *t; | 4110 | char *tmp = xmalloc(16), *t; |
4050 | int i, d; | 4111 | int i, d; |
@@ -4058,7 +4119,8 @@ void accountCreationPage(reqData *Rd, char *message) | |||
4058 | HTMLdebug(Rd->reply); | 4119 | HTMLdebug(Rd->reply); |
4059 | Rd->reply->addstrf(Rd->reply, "<h1><!--#echo var=\"grid\" --> account manager</h1>\n"); | 4120 | Rd->reply->addstrf(Rd->reply, "<h1><!--#echo var=\"grid\" --> account manager</h1>\n"); |
4060 | Rd->reply->addstrf(Rd->reply, "<h2>Creating <!--#echo var=\"grid\" --> account for %s</h2>\n", name); | 4121 | Rd->reply->addstrf(Rd->reply, "<h2>Creating <!--#echo var=\"grid\" --> account for %s</h2>\n", name); |
4061 | Rd->reply->addstr(Rd->reply, checkLinky(Rd)); | 4122 | Rd->reply->addstr(Rd->reply, linky); |
4123 | free(linky); | ||
4062 | if (0 != Rd->errors->size(Rd->messages)) | 4124 | if (0 != Rd->errors->size(Rd->messages)) |
4063 | HTMLlist(Rd->reply, "messages -", Rd->messages); | 4125 | HTMLlist(Rd->reply, "messages -", Rd->messages); |
4064 | // TODO - set this to autocomplete="off". | 4126 | // TODO - set this to autocomplete="off". |
@@ -4124,14 +4186,15 @@ void accountCreationPage(reqData *Rd, char *message) | |||
4124 | 4186 | ||
4125 | void loggedOnPage(reqData *Rd, char *message) | 4187 | void loggedOnPage(reqData *Rd, char *message) |
4126 | { | 4188 | { |
4127 | char *name = getStrH(Rd->stuff, "name"); | 4189 | char *name = getStrH(Rd->stuff, "name"), *linky = checkLinky(Rd); |
4128 | char *toke_n_munchie = getCookie(Rd->Rcookies, "toke_n_munchie"); | 4190 | char *toke_n_munchie = getCookie(Rd->Rcookies, "toke_n_munchie"); |
4129 | 4191 | ||
4130 | HTMLheader(Rd->reply, "<!--#echo var=\"grid\" --> account manager"); | 4192 | HTMLheader(Rd->reply, "<!--#echo var=\"grid\" --> account manager"); |
4131 | HTMLdebug(Rd->reply); | 4193 | HTMLdebug(Rd->reply); |
4132 | Rd->reply->addstrf(Rd->reply, "<h1><!--#echo var=\"grid\" --> account manager</h1>\n"); | 4194 | Rd->reply->addstrf(Rd->reply, "<h1><!--#echo var=\"grid\" --> account manager</h1>\n"); |
4133 | Rd->reply->addstrf(Rd->reply, "<h2><!--#echo var=\"grid\" --> account for %s</h2>\n", name); | 4195 | Rd->reply->addstrf(Rd->reply, "<h2><!--#echo var=\"grid\" --> account for %s</h2>\n", name); |
4134 | Rd->reply->addstr(Rd->reply, checkLinky(Rd)); | 4196 | Rd->reply->addstr(Rd->reply, linky); |
4197 | free(linky); | ||
4135 | if (0 != Rd->errors->size(Rd->messages)) | 4198 | if (0 != Rd->errors->size(Rd->messages)) |
4136 | HTMLlist(Rd->reply, "messages -", Rd->messages); | 4199 | HTMLlist(Rd->reply, "messages -", Rd->messages); |
4137 | HTMLform(Rd->reply, "", Rd->shs.munchie); | 4200 | HTMLform(Rd->reply, "", Rd->shs.munchie); |
@@ -4163,14 +4226,15 @@ void loggedOnPage(reqData *Rd, char *message) | |||
4163 | void listPage(reqData *Rd, char *message) | 4226 | void listPage(reqData *Rd, char *message) |
4164 | { | 4227 | { |
4165 | // TODO - should check if the user is a god before allowing this. | 4228 | // TODO - should check if the user is a god before allowing this. |
4166 | char *name = getStrH(Rd->stuff, "name"); | 4229 | char *name = getStrH(Rd->stuff, "name"), *linky = checkLinky(Rd); |
4167 | char *toke_n_munchie = getCookie(Rd->Rcookies, "toke_n_munchie"); | 4230 | char *toke_n_munchie = getCookie(Rd->Rcookies, "toke_n_munchie"); |
4168 | 4231 | ||
4169 | HTMLheader(Rd->reply, "<!--#echo var=\"grid\" --> account manager"); | 4232 | HTMLheader(Rd->reply, "<!--#echo var=\"grid\" --> account manager"); |
4170 | HTMLdebug(Rd->reply); | 4233 | HTMLdebug(Rd->reply); |
4171 | Rd->reply->addstrf(Rd->reply, "<h1><!--#echo var=\"grid\" --> account manager</h1>\n"); | 4234 | Rd->reply->addstrf(Rd->reply, "<h1><!--#echo var=\"grid\" --> account manager</h1>\n"); |
4172 | Rd->reply->addstrf(Rd->reply, "<h1><!--#echo var=\"grid\" --> member accounts</h1>\n"); | 4235 | Rd->reply->addstrf(Rd->reply, "<h1><!--#echo var=\"grid\" --> member accounts</h1>\n"); |
4173 | Rd->reply->addstr(Rd->reply, checkLinky(Rd)); | 4236 | Rd->reply->addstr(Rd->reply, linky); |
4237 | free(linky); | ||
4174 | if (0 != Rd->errors->size(Rd->messages)) | 4238 | if (0 != Rd->errors->size(Rd->messages)) |
4175 | HTMLlist(Rd->reply, "messages -", Rd->messages); | 4239 | HTMLlist(Rd->reply, "messages -", Rd->messages); |
4176 | HTMLtable(Rd->reply, Rd->db, | 4240 | HTMLtable(Rd->reply, Rd->db, |
@@ -4368,24 +4432,59 @@ void account_html(char *file, reqData *Rd, HTMLfile *thisFile) | |||
4368 | } | 4432 | } |
4369 | 4433 | ||
4370 | 4434 | ||
4435 | static void cleanup(void) | ||
4436 | { | ||
4437 | C("Caught signal, cleaning up."); | ||
4438 | dbRequest *req = NULL; | ||
4439 | |||
4440 | while (NULL != (req = (dbRequest *) dbRequests->getat(dbRequests, 0, NULL, false))) | ||
4441 | { | ||
4442 | if (NULL != req->flds) | ||
4443 | dbFreeFields(req->flds); | ||
4444 | else | ||
4445 | D("No fields to clean up for %s - %s.", req->table, req->where); | ||
4446 | dbFreeRequest(req); | ||
4447 | dbRequests->removefirst(dbRequests); | ||
4448 | } | ||
4449 | if (fieldValidFuncs) fieldValidFuncs->free(fieldValidFuncs); | ||
4450 | if (dynPages) dynPages->free(dynPages); | ||
4451 | if (buildPages) buildPages->free(buildPages); | ||
4452 | if (HTMLfileCache) HTMLfileCache->free(HTMLfileCache); | ||
4453 | if (HTMLfileCache) mimeTypes->free(mimeTypes); | ||
4454 | if (dbRequests) dbRequests->free(dbRequests); | ||
4455 | if (database) mysql_close(database); | ||
4456 | mysql_library_end(); | ||
4457 | lua_close(L); | ||
4458 | if (stats) | ||
4459 | { | ||
4460 | if (stats->stats) stats->stats->free(stats->stats); | ||
4461 | free(stats); | ||
4462 | } | ||
4463 | if (configs) configs->free(configs); | ||
4464 | } | ||
4465 | |||
4371 | void sledjchisl_main(void) | 4466 | void sledjchisl_main(void) |
4372 | { | 4467 | { |
4373 | char *cmd = *toys.optargs; | 4468 | char *cmd = *toys.optargs; |
4374 | char *tmp; | 4469 | char *tmp; |
4375 | qhashtbl_t *configs = qhashtbl(0, 0); | ||
4376 | lua_State *L = luaL_newstate(); | ||
4377 | MYSQL *database = NULL, *dbconn = NULL; | 4470 | MYSQL *database = NULL, *dbconn = NULL; |
4378 | gridStats *stats = NULL; | 4471 | gridStats *stats = NULL; |
4379 | struct stat statbuf; | 4472 | struct stat statbuf; |
4380 | int status, result, i; | 4473 | int status, result, i; |
4381 | void *vd; | 4474 | void *vd; |
4382 | 4475 | ||
4476 | configs = qhashtbl(0, 0); | ||
4477 | L = luaL_newstate(); | ||
4478 | |||
4383 | I("libfcgi version: %s", FCGI_VERSION); | 4479 | I("libfcgi version: %s", FCGI_VERSION); |
4384 | I("Lua version: %s", LUA_RELEASE); | 4480 | I("Lua version: %s", LUA_RELEASE); |
4385 | I("LuaJIT version: %s", LUAJIT_VERSION); | 4481 | I("LuaJIT version: %s", LUAJIT_VERSION); |
4386 | I("MariaDB / MySQL client version: %s", mysql_get_client_info()); | 4482 | I("MariaDB / MySQL client version: %s", mysql_get_client_info()); |
4387 | I("toybox version: %s", TOYBOX_VERSION); | 4483 | I("toybox version: %s", TOYBOX_VERSION); |
4388 | 4484 | ||
4485 | dbRequests = qlist(0); | ||
4486 | sigatexit(cleanup); | ||
4487 | |||
4389 | pwd = getcwd(0, 0); | 4488 | pwd = getcwd(0, 0); |
4390 | 4489 | ||
4391 | if (-1 == fstat(STDIN_FILENO, &statbuf)) | 4490 | if (-1 == fstat(STDIN_FILENO, &statbuf)) |
@@ -4594,6 +4693,7 @@ jit library is loaded or the JIT compiler will not be activated. | |||
4594 | if ((! qfile_exist(scLog)) && (! qfile_mkdir(scLog, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP, true))) C("Unable to create path %s", scLog); | 4693 | if ((! qfile_exist(scLog)) && (! qfile_mkdir(scLog, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP, true))) C("Unable to create path %s", scLog); |
4595 | tmp = xmprintf("%s/sessions", scCache); | 4694 | tmp = xmprintf("%s/sessions", scCache); |
4596 | if ((! qfile_exist(tmp)) && (! qfile_mkdir(tmp, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP, true))) C("Unable to create path %s", tmp); | 4695 | if ((! qfile_exist(tmp)) && (! qfile_mkdir(tmp, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP, true))) C("Unable to create path %s", tmp); |
4696 | free(tmp); | ||
4597 | tmp = xmprintf("%s/users", scData); | 4697 | tmp = xmprintf("%s/users", scData); |
4598 | if ((! qfile_exist(tmp)) && (! qfile_mkdir(tmp, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP, true))) C("Unable to create path %s", tmp); | 4698 | if ((! qfile_exist(tmp)) && (! qfile_mkdir(tmp, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP, true))) C("Unable to create path %s", tmp); |
4599 | free(tmp); | 4699 | free(tmp); |
@@ -4632,6 +4732,7 @@ jit library is loaded or the JIT compiler will not be activated. | |||
4632 | // TODO - it looks like OpenSim invented their own half arsed backwards INI file include system. | 4732 | // TODO - it looks like OpenSim invented their own half arsed backwards INI file include system. |
4633 | // I doubt qlibc supports it, like it supports what seems to be the standard include system. | 4733 | // I doubt qlibc supports it, like it supports what seems to be the standard include system. |
4634 | // Not sure if we need to worry about it just yet. | 4734 | // Not sure if we need to worry about it just yet. |
4735 | // TODO - this leaks memory, but I suspect it's a bug in qLib. | ||
4635 | qlisttbl_t *qconfig = qconfig_parse_file(NULL, toybuf, '='); | 4736 | qlisttbl_t *qconfig = qconfig_parse_file(NULL, toybuf, '='); |
4636 | if (NULL == qconfig) | 4737 | if (NULL == qconfig) |
4637 | { | 4738 | { |
@@ -4688,10 +4789,10 @@ jit library is loaded or the JIT compiler will not be activated. | |||
4688 | else | 4789 | else |
4689 | { | 4790 | { |
4690 | dbconn = mysql_real_connect(database, | 4791 | dbconn = mysql_real_connect(database, |
4691 | configs->getstr(configs, "Data Source", true), | 4792 | getStrH(configs, "Data Source"), |
4692 | configs->getstr(configs, "User ID", true), | 4793 | getStrH(configs, "User ID"), |
4693 | configs->getstr(configs, "Password", true), | 4794 | getStrH(configs, "Password"), |
4694 | configs->getstr(configs, "Database", true), | 4795 | getStrH(configs, "Database"), |
4695 | // 3036, "/var/run/mysqld/mysqld.sock", | 4796 | // 3036, "/var/run/mysqld/mysqld.sock", |
4696 | 0, NULL, | 4797 | 0, NULL, |
4697 | CLIENT_FOUND_ROWS | CLIENT_LOCAL_FILES | CLIENT_MULTI_STATEMENTS | CLIENT_MULTI_RESULTS); | 4798 | CLIENT_FOUND_ROWS | CLIENT_LOCAL_FILES | CLIENT_MULTI_STATEMENTS | CLIENT_MULTI_RESULTS); |
@@ -4712,6 +4813,7 @@ jit library is loaded or the JIT compiler will not be activated. | |||
4712 | 4813 | ||
4713 | stats->stats->putstr(stats->stats, "uri", toybuf); | 4814 | stats->stats->putstr(stats->stats, "uri", toybuf); |
4714 | } | 4815 | } |
4816 | qconfig->free(qconfig); | ||
4715 | } | 4817 | } |
4716 | 4818 | ||
4717 | 4819 | ||
@@ -4779,6 +4881,7 @@ t("HEADERS"); | |||
4779 | { | 4881 | { |
4780 | char *k = xstrdup(*envp); | 4882 | char *k = xstrdup(*envp); |
4781 | char *v = strchr(k, '='); | 4883 | char *v = strchr(k, '='); |
4884 | |||
4782 | if (NULL != v) | 4885 | if (NULL != v) |
4783 | { | 4886 | { |
4784 | *v = '\0'; | 4887 | *v = '\0'; |
@@ -4787,6 +4890,7 @@ t("HEADERS"); | |||
4787 | if ((strcmp("HTTP_COOKIE", ky) == 0) || (strcmp("CONTENT_LENGTH", ky) == 0) || (strcmp("QUERY_STRING", ky) == 0)) | 4890 | if ((strcmp("HTTP_COOKIE", ky) == 0) || (strcmp("CONTENT_LENGTH", ky) == 0) || (strcmp("QUERY_STRING", ky) == 0)) |
4788 | d(" %s = %s", ky, v + 1); | 4891 | d(" %s = %s", ky, v + 1); |
4789 | } | 4892 | } |
4893 | free(k); | ||
4790 | } | 4894 | } |
4791 | 4895 | ||
4792 | // The FCGI paramaters sent from the server, are converted to environment variablse for the fcgi2 SDK. | 4896 | // The FCGI paramaters sent from the server, are converted to environment variablse for the fcgi2 SDK. |
@@ -4846,6 +4950,7 @@ t("QUERY"); | |||
4846 | Length = "0"; | 4950 | Length = "0"; |
4847 | t("BODY"); | 4951 | t("BODY"); |
4848 | Rd->body = toknize(Body, "=&"); | 4952 | Rd->body = toknize(Body, "=&"); |
4953 | free(Body); | ||
4849 | santize(Rd->body, TRUE); | 4954 | santize(Rd->body, TRUE); |
4850 | 4955 | ||
4851 | 4956 | ||
@@ -4902,8 +5007,9 @@ t("BODY"); | |||
4902 | // TODO - maybe cache this? | 5007 | // TODO - maybe cache this? |
4903 | qlist_t *fragments = fragize(finl, Rd->reply->datasize(Rd->reply)); | 5008 | qlist_t *fragments = fragize(finl, Rd->reply->datasize(Rd->reply)); |
4904 | Rd->reply->free(Rd->reply); | 5009 | Rd->reply->free(Rd->reply); |
4905 | Rd->reply = qgrow(QGROW_THREADSAFE); | 5010 | Rd->reply = qgrow(QGROW_THREADSAFE); |
4906 | unfragize(fragments, Rd); | 5011 | unfragize(fragments, Rd, TRUE); |
5012 | free(finl); | ||
4907 | goto sendReply; | 5013 | goto sendReply; |
4908 | } | 5014 | } |
4909 | 5015 | ||
@@ -4943,7 +5049,7 @@ goto sendReply; | |||
4943 | goto sendReply; | 5049 | goto sendReply; |
4944 | 5050 | ||
4945 | getStats(database, stats); | 5051 | getStats(database, stats); |
4946 | unfragize(thisFile->fragments, Rd); | 5052 | unfragize(thisFile->fragments, Rd, false); |
4947 | 5053 | ||
4948 | sendReply: | 5054 | sendReply: |
4949 | /* Send headers. | 5055 | /* Send headers. |
@@ -4969,7 +5075,7 @@ sendReply: | |||
4969 | while (Rd->Rcookies->getnext(Rd->Rcookies, &hobj, false) == true) | 5075 | while (Rd->Rcookies->getnext(Rd->Rcookies, &hobj, false) == true) |
4970 | { | 5076 | { |
4971 | cookie *ck = (cookie *) hobj.data; | 5077 | cookie *ck = (cookie *) hobj.data; |
4972 | FCGI_printf("Set-Cookie: %s=%s", ck->cookie, ck->value); | 5078 | FCGI_printf("Set-Cookie: %s=%s", hobj.name, ck->value); |
4973 | // if (NULL != ck->expires) FCGI_printf("; Expires=%s", ck->expires); | 5079 | // if (NULL != ck->expires) FCGI_printf("; Expires=%s", ck->expires); |
4974 | if (NULL != ck->domain) FCGI_printf("; Domain=%s", ck->domain); | 5080 | if (NULL != ck->domain) FCGI_printf("; Domain=%s", ck->domain); |
4975 | if (NULL != ck->path) FCGI_printf("; Path=%s", ck->path); | 5081 | if (NULL != ck->path) FCGI_printf("; Path=%s", ck->path); |
@@ -4981,7 +5087,6 @@ sendReply: | |||
4981 | if (CS_NONE == ck->site) FCGI_printf("; SameSite=None"); | 5087 | if (CS_NONE == ck->site) FCGI_printf("; SameSite=None"); |
4982 | FCGI_printf("\r\n"); | 5088 | FCGI_printf("\r\n"); |
4983 | free(ck->value); | 5089 | free(ck->value); |
4984 | free(ck->cookie); | ||
4985 | } | 5090 | } |
4986 | FCGI_printf("\r\n"); | 5091 | FCGI_printf("\r\n"); |
4987 | Rd->cookies->unlock(Rd->cookies); | 5092 | Rd->cookies->unlock(Rd->cookies); |
@@ -5028,6 +5133,7 @@ fcgiDone: | |||
5028 | double n = (now.tv_sec * 1000000000.0) + now.tv_nsec; | 5133 | double n = (now.tv_sec * 1000000000.0) + now.tv_nsec; |
5029 | double t = (Rd->then.tv_sec * 1000000000.0) + Rd->then.tv_nsec; | 5134 | double t = (Rd->then.tv_sec * 1000000000.0) + Rd->then.tv_nsec; |
5030 | I("Finished web request, took %lf seconds", (n - t) / 1000000000.0); | 5135 | I("Finished web request, took %lf seconds", (n - t) / 1000000000.0); |
5136 | free(Rd); | ||
5031 | } | 5137 | } |
5032 | 5138 | ||
5033 | FCGI_fprintf(FCGI_stderr, "Stopped SledjChisl web server.\n"); | 5139 | FCGI_fprintf(FCGI_stderr, "Stopped SledjChisl web server.\n"); |
@@ -5209,13 +5315,5 @@ finished: | |||
5209 | puts(""); | 5315 | puts(""); |
5210 | fflush(stdout); | 5316 | fflush(stdout); |
5211 | 5317 | ||
5212 | if (database) mysql_close(database); | 5318 | cleanup(); |
5213 | mysql_library_end(); | ||
5214 | lua_close(L); | ||
5215 | if (stats) | ||
5216 | { | ||
5217 | if (stats->stats) stats->stats->free(stats->stats); | ||
5218 | free(stats); | ||
5219 | } | ||
5220 | if (configs) configs->free(configs); | ||
5221 | } | 5319 | } |