e5c786377cee95f737ff9d4bbada817e14f94aa4 angie Mon Dec 12 09:25:06 2016 -0800 Better cookies and validation for hgLogin: instead of sending gbMembers.idx as the login cookie and then never checking the value of the incoming cookie, use a salted hash. The salt is a secret text value specified by login.cookieSalt in hg.conf.private. For remote login, both hosts' hg.conf.private files must specify the same login.cookieSalt. In order to avoid logging out all users, for now the correct value of gbMembers.idx is accepted in place of the salted hash for local logins. For remote logins without login.cookieSalt, there is still no way to check the incoming cookie. For local logins without login.cookieSalt, the correct gbMembers.idx is accepted. refs #17327 diff --git src/hg/lib/cart.c src/hg/lib/cart.c index fbf6a4f..42e5da3 100644 --- src/hg/lib/cart.c +++ src/hg/lib/cart.c @@ -469,30 +469,35 @@ assert(hashNumEntries(hash) == 0); } #ifndef GBROWSE void cartLoadUserSession(struct sqlConnection *conn, char *sessionOwner, char *sessionName, struct cart *cart, struct hash *oldVars, char *actionVar) /* If permitted, load the contents of the given user's session, and then * reload the CGI settings (to support override of session settings). * If non-NULL, oldVars will contain values overloaded when reloading CGI. * If non-NULL, actionVar is a cartRemove wildcard string specifying the * CGI action variable that sent us here. */ { struct sqlResult *sr = NULL; char **row = NULL; +/* Validate login cookies if login is enabled -- must be called before wikiLinkUserName */ +if (loginSystemEnabled()) + { + loginValidateCookies(cart); + } char *userName = wikiLinkUserName(); char *encSessionName = cgiEncodeFull(sessionName); char *encSessionOwner = cgiEncodeFull(sessionOwner); char query[512]; if (isEmpty(sessionOwner)) errAbort("Please go back and enter a wiki user name for this session."); if (isEmpty(sessionName)) errAbort("Please go back and enter a session name to load."); sqlSafef(query, sizeof(query), "SELECT shared, contents FROM %s " "WHERE userName = '%s' AND sessionName = '%s';", namedSessionTable, encSessionOwner, encSessionName); sr = sqlGetResult(conn, query); if ((row = sqlNextRow(sr)) != NULL) @@ -1575,30 +1580,37 @@ cookieName, userIdKey, domain, cookieDate()); else printf("Set-Cookie: %s=%s; path=/; expires=%s\r\n", cookieName, userIdKey, cookieDate()); } if (geoMirrorEnabled()) { // This occurs after the user has manually choosen to go back to the original site; we store redirect value into a cookie so we // can use it in subsequent hgGateway requests before loading the user's cart char *redirect = cgiOptionalString("redirect"); if (redirect) { printf("Set-Cookie: redirect=%s; path=/; domain=%s; expires=%s\r\n", redirect, cgiServerName(), cookieDate()); } } +/* Validate login cookies if login is enabled */ +if (loginSystemEnabled()) + { + struct slName *newCookies = loginValidateCookies(cart), *sl; + for (sl = newCookies; sl != NULL; sl = sl->next) + printf("Set-Cookie: %s\r\n", sl->name); + } } struct cart *cartForSession(char *cookieName, char **exclude, struct hash *oldVars) /* This gets the cart without writing any HTTP lines at all to stdout. */ { char *hguid = getCookieId(cookieName); char *hgsid = getSessionId(); struct cart *cart = cartNew(hguid, hgsid, exclude, oldVars); cartExclude(cart, sessionVar); if (sameOk(cfgOption("signalsHandler"), "on")) /* most cgis call this routine */ initSigHandlers(hDumpStackEnabled()); char *httpProxy = cfgOption("httpProxy"); /* most cgis call this routine */ if (httpProxy) setenv("http_proxy", httpProxy, TRUE); /* net.c cannot see the cart, pass the value through env var */