53bfcc23b47e1dab4dc8d0aa7bc2ca5c121ced2b angie Tue Jul 26 12:28:12 2016 -0700 hgLogin's links to itself and form posts to itself also need to use https, even if hgLogin was loaded via http (e.g. from a static page, bookmark, etc). refs #17778 diff --git src/hg/hgLogin/hgLogin.c src/hg/hgLogin/hgLogin.c index 85054df..37911b3 100644 --- src/hg/hgLogin/hgLogin.c +++ src/hg/hgLogin/hgLogin.c @@ -29,30 +29,32 @@ char msg[4096] = ""; char *incorrectUsernameOrPassword="The username or password you entered is incorrect."; char *incorrectUsername="The username you entered is incorrect."; /* The excludeVars are not saved to the cart. */ char *excludeVars[] = { "submit", "Submit", "debug", "fixMembers", "update", "hgLogin_password", "hgLogin_password2", "hgLogin_newPassword1", "hgLogin_newPassword2", NULL }; struct cart *cart; /* This holds cgi and other variables between clicks. */ char *database; /* Name of genome database - hg15, mm3, or the like. */ struct hash *oldCart; /* Old cart hash. */ char *errMsg; /* Error message to show user when form data rejected */ char brwName[64]; char brwAddr[256]; char signature[256]; char returnAddr[256]; +char *hgLoginUrl = NULL; + /* ---- Global helper functions ---- */ char *cookieNameForUserName() /* Return the cookie name used for logged in user name like 'wikidb_mw1_UserName' */ { if isEmpty(cfgOption(CFG_COOKIIENAME_USERNAME)) return cloneString("NULL_cookieNameUserName"); else return cloneString(cfgOption(CFG_COOKIIENAME_USERNAME)); } char *cookieNameForUserID() /* Return the cookie name used for logged in user ID like 'wikidb_mw1_UserID' */ { if isEmpty(cfgOption(CFG_COOKIIENAME_USERID)) return cloneString("NULL_cookieNameUserID"); @@ -347,38 +349,36 @@ char *returnURL = getReturnToURL(); hPrintf( "<script language=\"JavaScript\">\n" "<!-- " "\n" "window.setTimeout(afterDelay, %d);\n" "function afterDelay() {\n" "window.location =\"%s\";\n}" "\n//-->\n" "</script>", delay, returnURL); } static void redirectToLoginPage(char *paramStr) /* redirect to hgLogin page with given parameter string */ { -char *hgLoginHost = wikiLinkHost(); -char *cgiDir = cgiScriptDirUrl(); hPrintf("<script language=\"JavaScript\">\n" "<!-- \n" - "window.location =\"https://%s%shgLogin?%s\"" + "window.location =\"%s?%s\"" "//-->" "\n" - "</script>", hgLoginHost, cgiDir, paramStr); + "</script>", hgLoginUrl, paramStr); } void displayActMailSuccess() /* display Activate mail success box */ { char *returnURL = getReturnToURL(); hPrintf( "<div id=\"confirmationBox\" class=\"centeredContainer formBox\">" "\n" "<h2>%s</h2>", brwName); hPrintf( "<p id=\"confirmationMsg\" class=\"confirmationTxt\">A confirmation email has been sent to you. \n" "Please click the confirmation link in the email to activate your account.</p>" "\n" "<p><a href=\"%s\">Return</a></p>", returnURL); @@ -388,113 +388,112 @@ void sendActMailOut(char *email, char *subject, char *msg) /* send mail to email address */ { int result; result = mailViaPipe(email, subject, msg, returnAddr); if (result == -1) { hPrintf( "<h2>%s</h2>", brwName); hPrintf( "<p align=\"left\">" "</p>" "<h3>Error emailing to: %s</h3>" - "Click <a href=hgLogin?hgLogin.do.displayAccHelpPage=1>here</a> to return.<br>", email ); + "Click <a href=%s?hgLogin.do.displayAccHelpPage=1>here</a> to return.<br>", + hgLoginUrl, email ); } else redirectToLoginPage("hgLogin.do.displayActMailSuccess=1"); } void displayMailSuccess() /* display mail success confirmation box */ { char *sendMailTo = cartUsualString(cart, "hgLogin_sendMailTo", ""); hPrintf( "<div id=\"confirmationBox\" class=\"centeredContainer formBox\">" "<h2>%s</h2>", brwName); hPrintf( "<p id=\"confirmationMsg\" class=\"confirmationTxt\">All usernames on file (if any) for <B>%s</B> " "have been sent to that address.<BR><BR>" " If <B>%s</B> is not your registered email address, you will not receive an email." " If you can't find the message we sent you, please contact %s for help.</p>", sendMailTo, sendMailTo, returnAddr); -hPrintf( - "<p><a href=\"hgLogin?hgLogin.do.displayLoginPage=1\">Return to Login</a></p>"); +hPrintf("<p><a href=\"%s?hgLogin.do.displayLoginPage=1\">Return to Login</a></p>", + hgLoginUrl); cartRemove(cart, "hgLogin_helpWith"); cartRemove(cart, "hgLogin_email"); cartRemove(cart, "hgLogin_userName"); cartRemove(cart, "hgLogin_sendMailTo"); cartRemove(cart, "hgLogin_sendMailContain"); } void displayMailSuccessPwd() /* display mail success confirmation box */ { char *username = cgiUsualString("user",""); hPrintf( "<div id=\"confirmationBoxPwd\" class=\"centeredContainer formBox\">" "<h2>%s</h2>", brwName); char *contactAddr = returnAddr; if (sameString(returnAddr, "NOEMAIL")) contactAddr = "the administrator of this Genome Browser Mirror"; hPrintf( "<p id=\"confirmationMsgPwd\" class=\"confirmationTxt\">An email containing password reset information has been sent to the registered email address of <B>%s</B>.<BR><BR>" " If you do not receive an email, please contact %s for help.</p>", username, contactAddr); if (sameString(returnAddr, "NOEMAIL")) hPrintf("<p>If you still have questions, you can contact the Genome Browser team at " "genome-www@soe.ucsc.edu. As this is a mirror website not managed by UCSC, please " "specify the address of the mirror in your email.</p>"); -hPrintf( - "<p><a href=\"hgLogin?hgLogin.do.displayLoginPage=1\">Return to Login</a></p>"); +hPrintf("<p><a href=\"%s?hgLogin.do.displayLoginPage=1\">Return to Login</a></p>", + hgLoginUrl); cartRemove(cart, "hgLogin_helpWith"); cartRemove(cart, "hgLogin_email"); cartRemove(cart, "hgLogin_userName"); cartRemove(cart, "hgLogin_sendMailTo"); cartRemove(cart, "hgLogin_sendMailContain"); } void sendMailOut(char *email, char *subject, char *msg) /* send mail to email address */ { -char *hgLoginHost = wikiLinkHost(); char *obj = cartUsualString(cart, "hgLogin_helpWith", ""); -char *cgiDir = cgiScriptDirUrl(); int result; result = mailViaPipe(email, subject, msg, returnAddr); if (result == -1) { hPrintf( "<h2>%s</h2>", brwName); hPrintf( "<p align=\"left\">" "</p>" "<h3>Error emailing %s to: %s</h3>" - "Click <a href=hgLogin?hgLogin.do.displayAccHelpPage=1>here</a> to return.<br>", - obj, email ); + "Click <a href=%s?hgLogin.do.displayAccHelpPage=1>here</a> to return.<br>", + hgLoginUrl, obj, email ); } else { hPrintf("<script language=\"JavaScript\">\n" "<!-- \n" - "window.location =\"https://%s%shgLogin?hgLogin.do.displayMailSuccess=1\"" + "window.location =\"%s?hgLogin.do.displayMailSuccess=1\"" "//-->" "\n" - "</script>", hgLoginHost, cgiDir); + "</script>", hgLoginUrl); } } void mailUsername(char *email, char *users) /* send user name list to the email address */ { char subject[256]; char msg[4096]; char *remoteAddr=getenv("REMOTE_ADDR"); safef(subject, sizeof(subject),"Your user name at the %s", brwName); safef(msg, sizeof(msg), " Someone (probably you, from IP address %s) has requested user name(s) associated with this email address at the %s: \n\n %s\n\n%s\n%s", remoteAddr, brwName, users, signature, returnAddr); sendMailOut(email, subject, msg); @@ -515,54 +514,52 @@ while ((row = sqlNextRow(sr)) != NULL) { struct gbMembers *m = gbMembersLoad(row); if (numUser >= 1) safecat(userList, sizeof(userList), ", "); safecat(userList, sizeof(userList), m->userName); numUser += 1; } sqlFreeResult(&sr); mailUsername(email, userList); } void sendPwdMailOut(char *email, char *subject, char *msg, char *username) /* send password reset mail to user at registered email address */ { -char *hgLoginHost = wikiLinkHost(); -char *cgiDir = cgiScriptDirUrl(); char *obj = cartUsualString(cart, "hgLogin_helpWith", ""); int result; result = mailViaPipe(email, subject, msg, returnAddr); if (result == -1) { hPrintf( "<h2>%s</h2>", brwName); hPrintf( "<p align=\"left\">" "</p>" "<h3>Error emailing %s to: %s</h3>" - "Click <a href=hgLogin?hgLogin.do.displayAccHelpPage=1>here</a> to return.<br>", - obj, email ); + "Click <a href=%s?hgLogin.do.displayAccHelpPage=1>here</a> to return.<br>", + hgLoginUrl, obj, email ); } else { hPrintf("<script language=\"JavaScript\">\n" "<!-- \n" - "window.location =\"https://%s%shgLogin?hgLogin.do.displayMailSuccessPwd=1&user=%s\"" + "window.location =\"%s?hgLogin.do.displayMailSuccessPwd=1&user=%s\"" "//-->" "\n" - "</script>", hgLoginHost, cgiDir, username); + "</script>", hgLoginUrl, username); } } void sendNewPwdMail(char *username, char *email, char *password) /* send user new password */ { char subject[256]; char msg[4096]; char *remoteAddr=getenv("REMOTE_ADDR"); safef(subject, sizeof(subject),"New temporary password for your account at the %s", brwName); safef(msg, sizeof(msg), " Someone (probably you, from IP address %s) requested a new password for the %s (%s). A temporary password for user \"%s\" has been created and was set to \"%s\". If this was your intent, you will need to log in and choose a new password now. Your temporary password will expire in 7 days.\n\n If someone else made this request, or if you have remembered your password, and you no longer wish to change it, you may ignore this message and continue using your old password.\n\n%s\n%s", remoteAddr, brwName, brwAddr, username, password, signature, returnAddr); sendPwdMailOut(email, subject, msg, username); @@ -585,34 +582,34 @@ " } else {\n" " document.getElementById('usernameBox').style.display='inline';\n" " document.getElementById('emailAddrBox').style.display='none';\n" "}\n" "}\n" "//-->" "\n" "</script>" "\n"); hPrintf("<div id=\"accountHelpBox\" class=\"centeredContainer formBox\">" "\n" "<h2>%s</h2>" "\n", brwName); hPrintf("<h3>Having trouble signing in?</h3>" "\n" - "<form method=post action=\"hgLogin\" name=\"accountLoginForm\" id=\"acctHelpForm\">" + "<form method=post action=\"%s\" name=\"accountLoginForm\" id=\"acctHelpForm\">" "\n" "<p><span style='color:red;'>%s</span><p>" - "\n", errMsg ? errMsg : ""); + "\n", hgLoginUrl, errMsg ? errMsg : ""); hPrintf("<div class=\"inputGroup\">" "<div class=\"acctHelpSection\"><input name=\"hgLogin_helpWith\" type=\"radio\" value=\"password\" id=\"password\" onclick=\"toggle('showU');\">" "<label for=\"password\" class=\"radioLabel\">I forgot my <b>password</b>. Send me a new one.</label></div>" "<div class=\"acctHelpSection\"><input name=\"hgLogin_helpWith\" type=\"radio\" value=\"username\" id=\"username\" onclick=\"toggle('showE');\">" "<label for=\"username\" class=\"radioLabel\">I forgot my <b>username</b>. Please email it to me.</label></div>" "\n" "</div>" "\n"); hPrintf("<div class=\"inputGroup\" id=\"usernameBox\" style=\"display: none;\">" "<label for=\"emailUsername\">Username</label>" "<input type=\"text\" name=\"hgLogin_userName\" value=\"%s\" size=\"30\" id=\"emailUsername\">" "</div>" "\n" "<div class=\"inputGroup\" id=\"emailAddrBox\" style=\"display: none;\">" "<label for=\"emailPassword\">Email address</label>" @@ -664,37 +661,35 @@ { char query[256]; sqlSafef(query,sizeof(query), "UPDATE gbMembers SET lastUse=NOW(),newPassword='', newPasswordExpire='', passwordChangeRequired='N' WHERE userName='%s'", username); sqlUpdate(conn, query); cartRemove(cart, "hgLogin_changeRequired"); return; } void sendActivateMail(char *email, char *username, char *encToken) /* Send activation mail with token to user*/ { char subject[256]; char msg[4096]; char activateURL[256]; -char *hgLoginHost = wikiLinkHost(); char *remoteAddr=getenv("REMOTE_ADDR"); -char *cgiDir = cgiScriptDirUrl(); safef(activateURL, sizeof(activateURL), - "https://%s%shgLogin?hgLogin.do.activateAccount=1&user=%s&token=%s\n", - hgLoginHost, cgiDir, + "%s?hgLogin.do.activateAccount=1&user=%s&token=%s\n", + hgLoginUrl, cgiEncode(username), cgiEncode(encToken)); safef(subject, sizeof(subject),"%s account e-mail address confirmation", brwName); safef(msg, sizeof(msg), " Someone (probably you, from IP address %s) has requested an account %s with this e-mail address on the %s.\nTo confirm that this account really does belong to you on the %s, open this link in your browser:\n\n%s\n\nIf this is *not* you, do not follow the link. This confirmation code will expire in 7 days.\n\n%s\n%s", remoteAddr, username, brwName, brwName, activateURL, signature, returnAddr); sendActMailOut(email, subject, msg); } void setupNewAccount(struct sqlConnection *conn, char *email, char *username) /* Set up new user account and send activation mail to user */ { char query[256]; char *token = generateRandomPassword(); char *tokenMD5 = generateTokenMD5(token); @@ -710,61 +705,61 @@ void displayLoginPage(struct sqlConnection *conn) /* draw the account login page */ { char *username = cartUsualString(cart, "hgLogin_userName", ""); hPrintf("<div id=\"loginBox\" class=\"centeredContainer formBox\">" "\n" "<h2>%s</h2>" "\n", brwName); hPrintf( "<h3>Login</h3>" "\n"); if (errMsg && sameString(errMsg, "Your account has been activated.")) hPrintf("<span style='color:green;'>%s</span>\n", errMsg ? errMsg : ""); else hPrintf("<span style='color:red;'>%s</span>\n", errMsg ? errMsg : ""); -hPrintf("<form method=post action=\"hgLogin\" name=\"accountLoginForm\" id=\"accountLoginForm\">" +hPrintf("<form method=post action=\"%s\" name=\"accountLoginForm\" id=\"accountLoginForm\">" "\n" "<div class=\"inputGroup\">" "<label for=\"userName\">Username</label>" "<input type=text name=\"hgLogin_userName\" value=\"%s\" size=\"30\" id=\"userName\">" "</div>" "\n" "<div class=\"inputGroup\">" "<label for=\"password\">Password</label>" "<input type=password name=\"hgLogin_password\" value=\"\" size=\"30\" id=\"password\">" "</div>" "\n" "<div class=\"formControls\">" " <input type=\"submit\" name=\"hgLogin.do.displayLogin\" value=\"Login\" class=\"largeButton\">" " <a href=\"%s\">Cancel</a>" "</div>" - , username, getReturnToURL()); + , hgLoginUrl, username, getReturnToURL()); cartSaveSession(cart); hPrintf( "</form>" "\n" "\n" "<div id=\"helpBox\">" - "<a href=\"hgLogin?hgLogin.do.displayAccHelpPage=1\">Can't access your account?</a><br>" - "Need an account? <a href=\"hgLogin?hgLogin.do.signupPage=1\">Sign up</a>.<br>" + "<a href=\"%s?hgLogin.do.displayAccHelpPage=1\">Can't access your account?</a><br>" + "Need an account? <a href=\"%s?hgLogin.do.signupPage=1\">Sign up</a>.<br>" "</div><!-- END - helpBox -->" "</div><!-- END - loginBox -->" "\n" "\n" "</body>" - "</html>"); + "</html>", hgLoginUrl, hgLoginUrl); } void activateAccount(struct sqlConnection *conn) /* activate account */ { char query[256]; char *token = cgiUsualString("token", ""); char *username = cgiUsualString("user",""); sqlSafef(query,sizeof(query), "SELECT emailToken FROM gbMembers WHERE userName='%s'", username); char *emailToken = sqlQuickString(conn, query); if (sameString(emailToken, token)) { sqlSafef(query,sizeof(query), "UPDATE gbMembers SET lastUse=NOW(), dateActivated=NOW(), emailToken='', emailTokenExpires='', accountActivated='Y' WHERE userName='%s'", username); @@ -784,37 +779,37 @@ } /* -------- functions ---- */ void changePasswordPage(struct sqlConnection *conn) /* change password page */ { hPrintf("<div id=\"changePwBox\" class=\"centeredContainer formBox\">" "\n" "<h2>%s</h2>", brwName); hPrintf( "<h3>Change Password</h3>" "\n" "<p> <span style='color:red;'>%s</span> </p>" "\n" - "<form method=\"post\" action=\"hgLogin\" name=\"changePasswordForm\" id=\"changePasswordForm\">" + "<form method=\"post\" action=\"%s\" name=\"changePasswordForm\" id=\"changePasswordForm\">" "\n" "<div class=\"inputGroup\">" "<label for=\"userName\">Username</label>" "<input type=\"text\" name=\"hgLogin_userName\" size=\"30\" value=\"%s\" id=\"email\">" "</div>" - "\n", errMsg ? errMsg : "", + "\n", errMsg ? errMsg : "", hgLoginUrl, cartUsualString(cart, "hgLogin_userName", "")); hPrintf("<div class=\"inputGroup\">" "\n" "<label for=\"currentPw\">Current or Emailed Password</label>" "<input type=\"password\" name=\"hgLogin_password\" value=\"\" size=\"30\" id=\"currentPw\">" "</div>" "\n" "<div class=\"inputGroup\">" "<label for=\"newPw1\">New Password</label>" "<input type=\"password\" name=\"hgLogin_newPassword1\" value=\"\" size=\"30\" id=\"newPw\">" "</div>" "\n" "<div class=\"inputGroup\">" "<label for=\"newPw2\">Re-enter New Password</label>" "<input type=\"password\" name=\"hgLogin_newPassword2\" value=\"\" size=\"30\" id=\"newPw\">" @@ -915,36 +910,36 @@ "</p>" "<h3>Password has been changed.</h3>"); cartRemove(cart, "hgLogin_password"); cartRemove(cart, "hgLogin_newPassword1"); cartRemove(cart, "hgLogin_newPassword2"); returnToURL(150); } void signupPage(struct sqlConnection *conn) /* draw the signup page */ { hPrintf("<div id=\"signUpBox\" class=\"centeredContainer formBox\">" "<h2>%s</h2>", brwName); hPrintf( "<p>Signing up enables you to save multiple sessions and to share your sessions with others.</p>" - "Already have an account? <a href=\"hgLogin?hgLogin.do.displayLoginPage=1\">Login</a>.<br>" - "\n"); + "Already have an account? <a href=\"%s?hgLogin.do.displayLoginPage=1\">Login</a>.<br>" + "\n", hgLoginUrl); hPrintf("<h3>Sign Up</h3>" - "<form method=\"post\" action=\"hgLogin\" name=\"mainForm\">" + "<form method=\"post\" action=\"%s\" name=\"mainForm\">" "<span style='color:red;'>%s</span>" - "\n", errMsg ? errMsg : ""); + "\n", hgLoginUrl, errMsg ? errMsg : ""); hPrintf("<div class=\"inputGroup\">" "<label for=\"userName\">Username</label>" "<input type=text name=\"hgLogin_userName\" value=\"%s\" size=\"30\" id=\"userName\">" "</div>" "\n" "<div class=\"inputGroup\">" "<label for=\"emailAddr\">Email address</label>" "<input type=text name=\"hgLogin_email\" value=\"%s\" size=\"30\" id=\"emailAddr\">" "</div>" "\n" "<div class=\"inputGroup\">" "<label for=\"reenterEmail\">Re-enter Email address</label>" "<input type=text name=\"hgLogin_email2\" value=\"%s\" size=\"30\" id=\"emailCheck\">" "</div>" "\n", cartUsualString(cart, "hgLogin_userName", ""), cartUsualString(cart, "hgLogin_email", ""), @@ -1385,20 +1380,22 @@ " hgLogin <various CGI settings>\n" ); } int main(int argc, char *argv[]) /* Process command line. */ { long enteredMainTime = clock1000(); pushCarefulMemHandler(100000000); setUdcCacheDir(); cgiSpoof(&argc, argv); htmlSetStyleSheet("../style/userAccounts.css"); htmlSetStyle(htmlStyleUndecoratedLink); htmlSetBgColor(HG_CL_OUTSIDE); htmlSetFormClass("accountScreen"); +struct dyString *dy = dyStringCreate("https://%s%shgLogin", wikiLinkHost(), cgiScriptDirUrl()); +hgLoginUrl = dyStringCannibalize(&dy); oldCart = hashNew(10); cartHtmlShell("Login - UCSC Genome Browser", doMiddle, hUserCookie(), excludeVars, oldCart); cgiExitTime("hgLogin", enteredMainTime); return 0; }