Skip to content

Commit

Permalink
removed concept of empty passwords as "no passwords used",
Browse files Browse the repository at this point in the history
because we now start YaCy with a default password (yacy).
This has impact of all function that check the current state of
password-protection that included the empty password situation,
including the warnings to set a password in case that none is set (which
cannot be the case any more).
  • Loading branch information
Orbiter committed Oct 25, 2023
1 parent 2c60ff1 commit 4308aa5
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 79 deletions.
37 changes: 20 additions & 17 deletions htroot/ConfigAccounts_p.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#%env/templates/header.template%#
#%env/templates/submenuUseCaseAccount.template%#
<h2>User Administration</h2>

<!-- Page 1: Results -->
#(text)#
::
Expand All @@ -26,23 +26,28 @@ <h2>User Administration</h2>
::
<p class="error">Username already used (not allowed).</p>
#(/error)#
#(passwordNotSetWarning)#::<div class="error">No password is set for the administration account. Please define a password for the admin account.</div>#(/passwordNotSetWarning)#
#(changedfltpw)#::
<div class="alert alert-danger" role="alert">
<b>WARNING</b> This YaCy instance can be administered with the account "admin" and the default password "yacy".
Change the password as soon as possible!
</div>
#(/changedfltpw)#

<fieldset><legend>Admin Account</legend>
<form action="ConfigAccounts_p.html" method="post" accept-charset="UTF-8">
<input type="hidden" name="transactionToken" value="#[transactionToken]#"/>
<input type="hidden" name="transactionToken" value="#[transactionToken]#"/>
<fieldset>
<legend>
<input type="radio" name="access" id="access_localhost" value="localhost"#(localhost.checked)#:: checked="checked"#(/localhost.checked)# />
<label for="access_localhost">Access from localhost without account</label>
</legend>
Access to your peer from your own computer (localhost access) is granted with administrator rights. No need to configure an administration account.
<div class="alert alert-warning" role="alert">
This setting is convenient but less secure than using a qualified admin account.
Please use with care, notably when you browse untrusted and potentially malicious websites while running your YaCy peer on the same computer.
</div>
<div class="alert alert-warning" role="alert">
This setting is convenient but less secure than using a qualified admin account.
Please use with care, notably when you browse untrusted and potentially malicious websites while running your YaCy peer on the same computer.
</div>
</fieldset>

<fieldset>
<legend>
<input type="radio" name="access" id="access_account" value="account"#(account.checked)#:: checked="checked"#(/account.checked)# />
Expand All @@ -62,22 +67,22 @@ <h2>User Administration</h2>
</fieldset>
</form>
</fieldset>

<fieldset><legend>Access Rules</legend>
<form action="ConfigAccounts_p.html" method="post" accept-charset="UTF-8">
<input type="hidden" name="transactionToken" value="#[transactionToken]#"/>
<input type="hidden" name="transactionToken" value="#[transactionToken]#"/>
<dl class="userConfig">
<dt>Protection of all pages: if set to on, access to all pages need authorization; if off, only pages with "_p" extension are protected.</dt>
<dd><input type="checkbox" name="adminAccountAllPages" data-size="small"#(adminAccountAllPages.checked)#:: checked="checked"#(/adminAccountAllPages.checked)#></dd>
<script>$("[name='adminAccountAllPages']").bootstrapSwitch();
$("[name='adminAccountAllPages']").bootstrapSwitch('onText', 'ON');
$("[name='adminAccountAllPages']").bootstrapSwitch('offText', 'OFF');</script>
<dt></dt>
<dt></dt>
<dd><input type="submit" name="setAccess" value="Set Access Rules" class="btn btn-primary"/></dd>
</dl>
</form>
</fieldset>

<fieldset><legend>User Accounts</legend>
<form action="ConfigAccounts_p.html" method="post" accept-charset="UTF-8">
<input type="hidden" name="transactionToken" value="#[transactionToken]#"/>
Expand All @@ -98,7 +103,7 @@ <h2>User Administration</h2>
</dl>
</fieldset>
</form>

<form action="ConfigAccounts_p.html" method="post" accept-charset="UTF-8">
<input type="hidden" name="transactionToken" value="#[transactionToken]#"/>
<fieldset><legend>Edit current user: #[username]#</legend>
Expand All @@ -118,11 +123,9 @@ <h2>User Administration</h2>
<dt><label for="address">Address</label>:</dt>
<dd><input type="text" id="address" name="address" value="#[address]#" /></dd>
<dt>Rights:</dt>
<dd>
#{rights}#
<dd>#{rights}#
<input type="checkbox" id="#[name]#" name="#[name]#"#(set)#:: checked="checked"#(/set)# /><label for="#[name]#">#[friendlyName]# right</label><br />
#{/rights}#
</dd>
#{/rights}#</dd>
<dt><label for="tlimit">Timelimit</label>:</dt>
<dd><input type="text" id="tlimit" name="timelimit" value="#[timelimit]#" /></dd>
<dt><label for="tused">Time used</label>:</dt>
Expand Down
31 changes: 13 additions & 18 deletions htroot/Status_p.inc
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,17 @@
<div>Processors: #[processors]#</div>
<div>Load: #[load]#</div>
<div>Threads: #[processesCurrentInclDaemon]#/#[processesCurrentOnlyDaemon]#, peak:#[processesPeak]#, total:#[processesTotal]#</div>

</dd>
<dt>Protection</dt>
<dd>#(protection)#
<strong>Password is missing.</strong>
<strong>Default password is not changed</strong>
<a href="ConfigAccounts_p.html">[Configure]</a>
::
password-protected
#(/protection)#

#(unrestrictedLocalAccess)#
::
<br />Unrestricted access from localhost.
#(/unrestrictedLocalAccess)#
<a href="ConfigAccounts_p.html">[Configure]</a>
</dd>

<dt>Address</dt>
<dd>Host: #[host]#:#[port]# #(extPortFormat)#::| (Binding to interface: #[extPort]#)#(/extPortFormat)# #(sslSupport)#::| SSL: <a href="ConfigBasic.html">enabled</a> (port <a href="Settings_p.html?page=ProxyAccess">#[sslPort]#</a>)#(/sslSupport)#<br />
#(peerAddress)#
Expand All @@ -38,12 +33,12 @@
Public Address: http://#[address]#<br/>
YaCy Address: http://#[peername]#.yacy
#(/peerAddress)#</dd>

#(portForwarding)#::
<dt>Port Forwarding Host</dt>
<dd>#[host]#:#[port]# (#(status)#broken::connected#(/status)#)</dd>
#(/portForwarding)#

<dt>Proxy</dt>
<dd>Transparent <a href="Settings_p.html?page=ProxyAccess">#(info_isTransparentProxy)#on::off#(/info_isTransparentProxy)#</a>&nbsp;&nbsp;
URL <a href="Settings_p.html?page=UrlProxyAccess">#(info_proxyURL)#on::off#(/info_proxyURL)#</a></dd>
Expand All @@ -56,7 +51,7 @@
Enabled <a href="Status.html?popup=false">[Disable]</a>
#(/popup)#
</dd>

<dt>Tray-Icon</dt>
<dd>
#(tray)#
Expand All @@ -67,21 +62,21 @@
<a href="ConfigProperties_p.html" onclick="alert('Set\ntray.icon.force = true\n\nWARNING:\nYou do this on your own risk. If you do this without YaCy running on a desktop-pc, this will possibly break startup. In this case, you will have to edit the configuration manually in DATA/SETTINGS/yacy.conf');">Experimental</a>
#(/tray)#
</dd>

<dt><a href="PerformanceMemory_p.html">Memory Usage</a></dt>
<dd><table border="0" cellspacing="0">
<tr><td>RAM used:</td><td align="right">#[usedMemory]#</td></tr>
<tr><td><a href="Performance_p.html">RAM max:</a></td><td align="right">#[maxMemory]#</td></tr>
<tr><td>DISK used:</td><td align="right">(approx.) #[usedDisk]#</td></tr>
<tr><td>DISK free:</td><td align="right">#[freeDisk]#</td></tr>
</table></dd>

<dt>Traffic [<a href="Status.html?ResetTraffic=">Reset</a>]</dt>
<dd>Proxy: #[trafficProxy]#<br/>Crawler: #[trafficCrawler]#</dd>

<dt><a href="Connections_p.html">Incoming Connections</a></dt>
<dd>Active: #[connectionsActive]# | Max: <a href="PerformanceQueues_p.html#ThreadPoolSettings">#[connectionsMax]#</a></dd>

<dt><a href="Crawler_p.html">Queues</a></dt>
<dd>
<a href="IndexCreateLoaderQueue_p.html">Loader Queue</a>:
Expand Down Expand Up @@ -110,7 +105,7 @@
</tr>
</table>
</dd>

<dt>Seed server</dt>
<dd>
#(seedServer)#
Expand All @@ -124,7 +119,7 @@
Last upload: #[lastUpload]# ago.
#(/seedServer)#
</dd>

</dl>
</fieldset>
</div>
10 changes: 3 additions & 7 deletions source/net/yacy/data/TransactionManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,18 +63,14 @@ public class TransactionManager {
*/
private static String getUserName(final RequestHeader header) {
String userName = header.getRemoteUser();
if (userName == null) userName = "admin"; // set a default to be able to create a transaction token
Switchboard sb = Switchboard.getSwitchboard();

if (sb != null) {
final String adminAccountBase64MD5 = sb.getConfig(SwitchboardConstants.ADMIN_ACCOUNT_B64MD5, "");
final String adminAccountUserName = sb.getConfig(SwitchboardConstants.ADMIN_ACCOUNT_USER_NAME, "admin");
if (adminAccountBase64MD5.equals(sb.emptyPasswordAdminAccount)) {
// admin users with empty passwords do not need to authentify, thus do not have
// this header present. We just consider the name is "admin"
userName = adminAccountUserName;
}

if (userName == null && header.accessFromLocalhost()) {
if (header.accessFromLocalhost()) {

if (sb.getConfigBool(SwitchboardConstants.ADMIN_ACCOUNT_FOR_LOCALHOST, false)) {
/* Unauthenticated local access as administrator can be enabled */
Expand Down Expand Up @@ -134,7 +130,7 @@ public static String getTransactionToken(final RequestHeader header, final Strin
/* Check this comes from an authenticated user */
final String userName = getUserName(header);
if (userName == null) {
throw new IllegalArgumentException("User is not authenticated");
throw new IllegalArgumentException("User is not authenticated");
}

/* Produce a token by signing a message with the server secret key :
Expand Down
7 changes: 4 additions & 3 deletions source/net/yacy/htroot/ConfigAccounts_p.java
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,10 @@ public static serverObjects respond(final RequestHeader header, final serverObje
}
}

if (env.getConfig(SwitchboardConstants.ADMIN_ACCOUNT_B64MD5, "").isEmpty() && !env.getConfigBool(SwitchboardConstants.ADMIN_ACCOUNT_FOR_LOCALHOST, false)) {
prop.put("passwordNotSetWarning", 1);
}
// set a warning in case that the default password was not changed
String currpw = sb.getConfig(SwitchboardConstants.ADMIN_ACCOUNT_B64MD5, "");
String dfltpw = SwitchboardConstants.ADMIN_ACCOUNT_B64MD5_DEFAULT;
prop.put("changedfltpw", currpw.equals(dfltpw) ? "1" : "0");

prop.put(SwitchboardConstants.ADMIN_ACCOUNT_All_PAGES + ".checked", sb.getConfigBool(SwitchboardConstants.ADMIN_ACCOUNT_All_PAGES, false) ? 1 : 0);
prop.put("localhost.checked", (localhostAccess) ? 1 : 0);
Expand Down
12 changes: 4 additions & 8 deletions source/net/yacy/htroot/Status.java
Original file line number Diff line number Diff line change
Expand Up @@ -131,14 +131,10 @@ public static serverObjects respond(
prop.put("privateStatusTable", "");
}

// password protection
if ( (sb.getConfig(SwitchboardConstants.ADMIN_ACCOUNT_B64MD5, "").isEmpty())
&& (!sb.getConfigBool(SwitchboardConstants.ADMIN_ACCOUNT_FOR_LOCALHOST, false)) ) {
prop.put("protection", "0"); // not protected
prop.put("urgentSetPassword", "1");
} else {
prop.put("protection", "1"); // protected
}
// password protection: set a warning in case that the default password was not changed
String currpw = sb.getConfig(SwitchboardConstants.ADMIN_ACCOUNT_B64MD5, "");
String dfltpw = SwitchboardConstants.ADMIN_ACCOUNT_B64MD5_DEFAULT;
prop.put("protection", currpw.equals(dfltpw) ? "0" : "1");

if ( sb.getConfigBool(SwitchboardConstants.ADMIN_ACCOUNT_FOR_LOCALHOST, false) ) {
prop.put("unrestrictedLocalAccess", 1);
Expand Down
5 changes: 1 addition & 4 deletions source/net/yacy/http/YaCySecurityHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,6 @@ protected RoleInfo prepareConstraintInfo(String pathInContext, Request request)
// Pages suffixed with "_p" are by the way always considered protected
protectedPage = protectedPage || (pathInContext.indexOf("_p.") > 0);

// ..except that the password for the admin account is empty
final String adminAccountBase64MD5 = sb.getConfig(SwitchboardConstants.ADMIN_ACCOUNT_B64MD5, "");
protectedPage = protectedPage && !adminAccountBase64MD5.equals(sb.emptyPasswordAdminAccount);

// check "/gsa" and "/solr" if not publicSearchpage
if (!protectedPage && !sb.getConfigBool(SwitchboardConstants.PUBLIC_SEARCHPAGE, true)) {
protectedPage = pathInContext.startsWith("/solr/") || pathInContext.startsWith("/gsa/");
Expand All @@ -98,6 +94,7 @@ protected RoleInfo prepareConstraintInfo(String pathInContext, Request request)
return null;
} else if (accessFromLocalhost) {
// last chance to authorize using the admin from localhost
final String adminAccountBase64MD5 = sb.getConfig(SwitchboardConstants.ADMIN_ACCOUNT_B64MD5, "");
final String credentials = request.getHeader(RequestHeader.AUTHORIZATION);
if (credentials != null && credentials.length() < 120 && credentials.startsWith("Basic ")) { // Basic credentials are short "Basic " + b64(user:pwd)
final String foruser = sb.getConfig(SwitchboardConstants.ADMIN_ACCOUNT_USER_NAME, "admin");
Expand Down
26 changes: 4 additions & 22 deletions source/net/yacy/search/Switchboard.java
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,6 @@ public final class Switchboard extends serverSwitch {
private boolean startupAction = true; // this is set to false after the first event
private static Switchboard sb;
public HashMap<String, Object[]> crawlJobsStatus = new HashMap<>();
public String emptyPasswordAdminAccount;

public Switchboard(final File dataPath, final File appPath, final String initPath, final String configPath) {
super(dataPath, appPath, initPath, configPath);
Expand Down Expand Up @@ -449,9 +448,6 @@ public void run() {
}
}.start();

// define the "non-password password"
this.emptyPasswordAdminAccount = this.encodeDigestAuth(this.getConfig(SwitchboardConstants.ADMIN_ACCOUNT_USER_NAME,"admin"), "");

// init the language detector
this.log.config("Loading language profiles");
try {
Expand Down Expand Up @@ -3907,13 +3903,10 @@ public void run() {
/**
* check authentication status for request access shall be granted if return value >= 2; these are the
* cases where an access is granted to protected pages:
* - a password is not configured: auth-level 2
* - access from localhost is granted and access comes from localhost: auth-level 3
* - a password is configured and access comes from localhost and the realm-value
* - access comes from localhost and the realm-value
* of a http-authentify String is equal to the stored base64MD5: auth-level 3
* - an empty password is configured an access comes from anywhere: auth-level 3
* This may be used in cluster installations where the cluster has an outside protection but inside is none needed.
* - a password is configured and access comes with matching http-authentify: auth-level 4
* - access comes with matching http-authentify: auth-level 4
*
* @param requestHeader
* - requestHeader.AUTHORIZATION = B64encode("adminname:password") or = B64encode("adminname:valueOf_Base64MD5cft")
Expand All @@ -3931,19 +3924,6 @@ public int adminAuthenticated(final RequestHeader requestHeader) {
return 4; // hard-authenticated, quick return
}

// authorization in case that there is no account stored
final String adminAccountUserName = this.getConfig(SwitchboardConstants.ADMIN_ACCOUNT_USER_NAME, "admin");
final String adminAccountBase64MD5 = this.getConfig(SwitchboardConstants.ADMIN_ACCOUNT_B64MD5, "");
if ( adminAccountBase64MD5.isEmpty() ) {
this.adminAuthenticationLastAccess = System.currentTimeMillis();
return 2; // no password stored; this should not happen for older peers
}

// authorization in case that administrators have stored an empty password; this authorizes all users as admin regardless of the give auth
if (adminAccountBase64MD5.equals(this.emptyPasswordAdminAccount)) {
return 3; // everyone is admin from everywhere
}

// authorization for localhost, only if flag is set to grant localhost access as admin
final boolean accessFromLocalhost = requestHeader.accessFromLocalhost();
if (accessFromLocalhost && this.getConfigBool(SwitchboardConstants.ADMIN_ACCOUNT_FOR_LOCALHOST, false)) {
Expand Down Expand Up @@ -3980,6 +3960,8 @@ public int adminAuthenticated(final RequestHeader requestHeader) {
}

// authorization by encoded password, only for localhost access
final String adminAccountUserName = this.getConfig(SwitchboardConstants.ADMIN_ACCOUNT_USER_NAME, "admin");
final String adminAccountBase64MD5 = this.getConfig(SwitchboardConstants.ADMIN_ACCOUNT_B64MD5, "");
final String pass = Base64Order.standardCoder.encodeString(adminAccountUserName + ":" + adminAccountBase64MD5);
if ( accessFromLocalhost && (pass.equals(realmValue)) ) { // assume realmValue as is in cfg
this.adminAuthenticationLastAccess = System.currentTimeMillis();
Expand Down

0 comments on commit 4308aa5

Please sign in to comment.