d34f2504803125515dc89955a60ad8366bca732e max Tue Jun 24 02:53:18 2025 -0700 captcha exceptions trigger error log line, and moving curl code into lib/curlWrap.c, refs #35790 diff --git src/hg/lib/cart.c src/hg/lib/cart.c index 7b5c6214570..ce298cca279 100644 --- src/hg/lib/cart.c +++ src/hg/lib/cart.c @@ -26,32 +26,31 @@ #endif /* GBROWSE */ #include "hgMaf.h" #include "hui.h" #include "geoMirror.h" #include "hubConnect.h" #include "trackHub.h" #include "cgiApoptosis.h" #include "customComposite.h" #include "regexHelper.h" #include "windowsToAscii.h" #include "jsonWrite.h" #include "verbose.h" #include "genark.h" #include "quickLift.h" #include "botDelay.h" - -#include +#include "curlWrap.h" static char *sessionVar = "hgsid"; /* Name of cgi variable session is stored in. */ static char *positionCgiName = "position"; DbConnector cartDefaultConnector = hConnectCart; DbDisconnect cartDefaultDisconnector = hDisconnectCart; static boolean cartDidContentType = FALSE; struct slPair *httpHeaders = NULL; // A list of headers to output before the content-type static void hashUpdateDynamicVal(struct hash *hash, char *name, void *val) /* Val is a dynamically allocated (freeMem-able) entity to put * in hash. Override existing hash item with that name if any. * Otherwise make new hash item. */ { @@ -1441,74 +1440,30 @@ else { char *url = genarkUrl(db); if (url != NULL) { cartSetString(cart, "genome", db); cartAddString(cart, "hubUrl", url); cartRemove(cart, "db"); } else if (!hDbIsActive(db)) errAbort("Can not find database '%s'", db); } } -// ------ libify this in the next release ---- -// -struct curlString { - char *ptr; - size_t len; -}; -void init_string(struct curlString *s) { - s->len = 0; - s->ptr = malloc(1); - s->ptr[0] = '\0'; -} - -size_t writefunc(void *ptr, size_t size, size_t nmemb, void *userData) { - struct curlString *s = (struct curlString *)userData; - size_t new_len = s->len + size * nmemb; - s->ptr = realloc(s->ptr, new_len + 1); - memcpy(s->ptr + s->len, ptr, size * nmemb); - s->ptr[new_len] = '\0'; - s->len = new_len; - return size * nmemb; -} - -char* curlPostUrl(char *url, char *data) -/* post data to URL and return as string. Must be freed. */ -{ -CURL *curl = curl_easy_init(); -if (!curl) - errAbort("Cannot init curl library"); - -struct curlString response; -init_string(&response); - -curl_easy_setopt(curl, CURLOPT_URL, url); -curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data); -curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc); -curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response); -curl_easy_perform(curl); -curl_easy_cleanup(curl); - -char *resp = cloneString(response.ptr); -free(response.ptr); -return resp; -} - boolean isValidToken(char *token) /* send https req to cloudflare, check if the token that we got from the captcha is really the one made by cloudflare */ { char *url = "https://challenges.cloudflare.com/turnstile/v0/siteverify"; char *secret = cfgVal("cloudFlareSecretKey"); if (!secret) errAbort("'cloudFlareSecretKey' must be set in hg.conf if cloudflare is activated in hg.conf"); char data[3000]; // cloudflare token is at most 2000 bytes safef(data, sizeof(data), "secret=%s&response=%s", secret, token); char *reply = curlPostUrl(url, data); boolean res = startsWith("{\"success\":true", reply); freez(&reply); return res; @@ -1552,32 +1507,35 @@ static boolean isUserAgentException() /* return true if HTTP user-agent is in list of exceptions in hg.conf */ { char *agent = cgiUserAgent(); if (!agent) return FALSE; struct slName *excStrs = cfgValsWithPrefix("noCaptchaAgent."); if (!excStrs) return FALSE; struct excReStr; for (struct slName *sl = excStrs; sl != NULL; sl = sl->next) { if (regexMatch(agent, sl->name)) + { + fprintf(stderr, "CAPTCHAPASS %s\n", agent); return TRUE; } + } return FALSE; } void forceUserIdOrCaptcha(struct cart* cart, char *userId, boolean userIdFound, boolean fromCommandLine) /* print captcha is user did not sent a valid hguid cookie or a valid * cloudflare token. Allow certain IPs and user-agents. */ { if (fromCommandLine || isEmpty(cfgOption(CLOUDFLARESITEKEY))) return; // no captcha for our own QA scripts running on a server with our IP address if (botException()) return; @@ -1598,35 +1556,36 @@ cartRemove(cart, "token"); return; } printCaptcha(); } void cartRemove(struct cart *cart, char *var); struct cart *cartNew(char *userId, char *sessionId, char **exclude, struct hash *oldVars) /* Load up cart from user & session id's. Exclude is a null-terminated list of * strings to not include */ { cgiApoptosisSetup(); -if (cfgOptionBooleanDefault("showEarlyErrors", TRUE)) +if (cfgOptionBooleanDefault("showEarlyErrors", FALSE)) errAbortSetDoContentType(TRUE); if (cfgOptionBooleanDefault("suppressVeryEarlyErrors", FALSE)) htmlSuppressErrors(); + setUdcCacheDir(); netSetTimeoutErrorMsg("A connection timeout means that either the server is offline or its firewall, the UCSC firewall or any router between the two blocks the connection."); struct cart *cart; struct sqlConnection *conn = cartDefaultConnector(); char *ex; boolean userIdFound = FALSE, sessionIdFound = FALSE; AllocVar(cart); cart->hash = newHash(12); cart->exclude = newHash(7); cart->userId = userId; cart->sessionId = sessionId; cart->userInfo = loadDb(conn, userDbTable(), userId, &userIdFound);