| 1874 | |
| 1875 | |
| 1876 | void CScriptWebServer::ProcessURL(ThreadData Data) |
| 1877 | { |
| 1878 | long httpOutLen; |
| 1879 | char *httpOut = 0; |
| 1880 | |
| 1881 | // Strip out any path-component to prevent information leakage. |
| 1882 | wxString filename = wxFileName(Data.parsedURL.File()).GetFullName(); |
| 1883 | |
| 1884 | Print(_("Processing request [original]: ") + filename + "\n"); |
| 1885 | |
| 1886 | if ( filename.Length() == 0 ) { |
| 1887 | filename = m_index; |
| 1888 | } |
| 1889 | |
| 1890 | CSession *session = CheckLoggedin(Data); |
| 1891 | |
| 1892 | session->m_vars["login_error"] = ""; |
| 1893 | if ( !session->m_logged_in ) { |
| 1894 | filename = "login.php"; |
| 1895 | |
| 1896 | // Refuse to consume `pass` if it's reachable via the original |
| 1897 | // (pre-POST-body-merge) URL query string. Passwords in URLs |
| 1898 | // leak into proxy logs / browser history / Referer headers, |
| 1899 | // and the GET-with-pass click-attack vector is exactly what |
| 1900 | // #872 exists to close. Note that `getOnlyParsedURL` is |
| 1901 | // always populated -- for GET requests it's identical to |
| 1902 | // `parsedURL`; for POST requests it's the pre-concat copy, |
| 1903 | // so `pass` only shows up there when an attacker put it |
| 1904 | // into a POST form's `action=...?pass=XYZ`. Either way, |
| 1905 | // presence means "don't trust this password attempt". |
| 1906 | wxString PwStr; |
| 1907 | if ( Data.getOnlyParsedURL.Param("pass").Length() ) { |
| 1908 | Print(_("Refusing to read `pass` from URL query string\n")); |
| 1909 | } else { |
| 1910 | PwStr = Data.parsedURL.Param("pass"); |
| 1911 | } |
| 1912 | if (webInterface->m_AdminPass.IsEmpty() && webInterface->m_GuestPass.IsEmpty()) { |
| 1913 | session->m_vars["login_error"] = "No password specified, login will not be allowed."; |
| 1914 | Print(_("No password specified, login will not be allowed.")); |
| 1915 | } else if ( PwStr.Length() ) { |
| 1916 | Print(_("Checking password\n")); |
| 1917 | session->m_logged_in = false; |
| 1918 | |
| 1919 | CMD4Hash PwHash; |
| 1920 | if (!PwHash.Decode(MD5Sum(PwStr).GetHash())) { |
| 1921 | Print(_("Password hash invalid\n")); |
| 1922 | session->m_vars["login_error"] = "Invalid password hash, please report at https://github.com/amule-org/amule/issues"; |
| 1923 | } else if ( PwHash == webInterface->m_AdminPass ) { |
| 1924 | session->m_logged_in = true; |
| 1925 | // m_vars is map<string, string> - so _() will not work here ! |
| 1926 | session->m_vars["guest_login"] = "0"; |
| 1927 | } else if ( PwHash == webInterface->m_GuestPass ) { |
| 1928 | session->m_logged_in = true; |
| 1929 | session->m_vars["guest_login"] = "1"; |
| 1930 | } else { |
| 1931 | session->m_vars["login_error"] = "Password incorrect, please try again."; |
| 1932 | } |
| 1933 |
no test coverage detected