Skip to content

Commit

Permalink
added a warning message in ConfigBasic in case that the default password
Browse files Browse the repository at this point in the history
was not changed.
  • Loading branch information
Orbiter committed Oct 24, 2023
1 parent 7830268 commit 4da320b
Show file tree
Hide file tree
Showing 4 changed files with 218 additions and 198 deletions.
32 changes: 19 additions & 13 deletions htroot/ConfigBasic.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,16 @@ <h2>Basic Configuration</h2>
#(reconnect)#::
<p><strong>Your port has changed. Please wait 10 seconds.</strong></p>
#(/reconnect)#
#(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".
Open the <a href="ConfigAccounts_p.html" class="alert-link">User Administration</a> and change the password as soon as possible!
</div>
#(/changedfltpw)#
<p>
Your YaCy Peer needs some basic information to operate properly
</p>

<form action="ConfigBasic.html" method="post" accept-charset="UTF-8">
<input type="hidden" name="transactionToken" value="#[transactionToken]#"/>
<ol>
Expand All @@ -44,16 +50,16 @@ <h2>Basic Configuration</h2>
<input type="radio" name="language" value="hi" id="lang_hi" onchange="this.form.submit()" #(lang_hi)#::checked="checked"#(/lang_hi)# /><label for="lang_hi" #(active_hi)#::title="Click to generate translated pages"::class="label-success" title="Active : translated pages are available"#(/active_hi)#>&#2361;&#2367;&#2344;&#2381;&#2342;&#2368;</label>
<input type="radio" name="language" value="ja" id="lang_ja" onchange="this.form.submit()" #(lang_ja)#::checked="checked"#(/lang_ja)# /><label for="lang_ja" #(active_ja)#::title="Click to generate translated pages"::class="label-success" title="Active : translated pages are available"#(/active_ja)#>&#26085;&#26412;&#35486;</label>
<input type="radio" name="language" value="el" id="lang_el" onchange="this.form.submit()" #(lang_el)#::checked="checked"#(/lang_el)# /><label for="lang_el" #(active_el)#::title="Click to generate translated pages"::class="label-success" title="Active : translated pages are available"#(/active_el)#>Greek</label>
<input type="radio" name="language" value="it" id="lang_it" onchange="this.form.submit()" #(lang_it)#::checked="checked"#(/lang_it)# /><label for="lang_it" #(active_el)#::title="Click to generate translated pages"::class="label-success" title="Active : translated pages are available"#(/active_el)#>Italiano</label>
<input type="radio" name="language" value="es" id="lang_es" onchange="this.form.submit()" #(lang_es)#::checked="checked"#(/lang_es)# /><label for="lang_es" #(active_es)#::title="Click to generate translated pages"::class="label-success" title="Active : translated pages are available"#(/active_es)#>Español</label>
</fieldset>
<input type="radio" name="language" value="it" id="lang_it" onchange="this.form.submit()" #(lang_it)#::checked="checked"#(/lang_it)# /><label for="lang_it" #(active_el)#::title="Click to generate translated pages"::class="label-success" title="Active : translated pages are available"#(/active_el)#>Italiano</label>
<input type="radio" name="language" value="es" id="lang_es" onchange="this.form.submit()" #(lang_es)#::checked="checked"#(/lang_es)# /><label for="lang_es" #(active_es)#::title="Click to generate translated pages"::class="label-success" title="Active : translated pages are available"#(/active_es)#>Español</label>
</fieldset>
</li>
<!-- take care that no other items are changed, but also change the former if no js is enabled -->
<script type="text/javascript"> document.write('</form><form action="ConfigBasic.html" method="post" accept-charset="UTF-8"><input type="hidden" name="transactionToken" value="#[transactionToken]#"/>');</script>

#(setUseCase)#::
<li>
#(setUseCase)#::

<li>
<img src="env/grafics/ok.png" height="16" width="16" alt="ok" />&nbsp;Use Case: what do you want to do with YaCy:<br />
<fieldset>
#(switchError)#::<div class="alert alert-danger" role="alert"><p>Can not leave from Intranet Indexing : one or more remote Solr instances are attached and may contain private documents indexed.</p>
Expand All @@ -67,8 +73,8 @@ <h2>Basic Configuration</h2>
<table border="0">
<tr>
<td style="width: 256px;"><input type="radio" name="usecase" value="freeworld" id="usecaseFreeworld" #(freeworldChecked)#::checked="checked"#(/freeworldChecked)# /><label for="usecaseFreeworld">Community-based web search</label></td>
<td style="width: 256px;"><input type="radio" name="usecase" value="portal" id="usecasePortal" #(portalChecked)#::checked="checked"#(/portalChecked)# /><label for="usecasePortal">Search portal for your own web pages</label></td>
<td><input type="radio" name="usecase" value="intranet" id="usecaseIntranet" #(intranetChecked)#::checked="checked"#(/intranetChecked)# /><label for="usecaseIntranet">Intranet Indexing</label></td>
<td style="width: 256px;"><input type="radio" name="usecase" value="portal" id="usecasePortal" #(portalChecked)#::checked="checked"#(/portalChecked)# /><label for="usecasePortal">Search portal for your own web pages</label></td>
<td><input type="radio" name="usecase" value="intranet" id="usecaseIntranet" #(intranetChecked)#::checked="checked"#(/intranetChecked)# /><label for="usecaseIntranet">Intranet Indexing</label></td>
</tr>
<tr>
<td><label for="usecaseFreeworld"><img src="env/grafics/usecase_freeworld.png" alt="Usecase Freeworld" /></label></td>
Expand All @@ -85,7 +91,7 @@ <h2>Basic Configuration</h2>
</fieldset>
</li>
#(/setUseCase)#

<li>
#(statusName)#<img src="env/grafics/bad.png" height="16" width="16" alt="warning" />&nbsp;Your peer name has not been customized; please set your own peer name::<img src="env/grafics/ok.png" height="16" width="16" alt="ok" />&nbsp;You may change your peer name#(/statusName)#<br />
<fieldset>
Expand All @@ -97,7 +103,7 @@ <h2>Basic Configuration</h2>
</dl>
</fieldset>
</li>

<li>
#(statusPort)#<img src="env/grafics/bad.png" height="16" width="16" alt="warning" />&nbsp;Your peer cannot be reached from outside (which is not fatal, but would be good for the YaCy network); please open your firewall for this port and/or set a virtual server option in your router to allow connections on this port. Opening a router port is <i>not</i> a YaCy-specific task; you can see instruction videos everywhere in the internet, just search for <a href="http://www.youtube.com/results?search_query=Open+Ports+on+a+Router">Open Ports on a &lt;our-router-type&gt; Router</a> and add your router type as search term. However: if you fail to open a router port, you can nevertheless use YaCy with full functionality, the only function that is missing is on the side of the other YaCy users because they cannot see your peer.::<img src="env/grafics/ok.png" height="16" width="16" alt="ok" />&nbsp;Your peer can be reached by other peers#(/statusPort)#<br />
<fieldset>
Expand All @@ -118,9 +124,9 @@ <h2>Basic Configuration</h2>
</fieldset>
</li>
<fieldset>&nbsp;&nbsp;&nbsp;&nbsp;<input type="submit" name="set" value="Set Configuration" class="btn btn-primary"/></fieldset>

#(reconnect)#::<div class="alert alert-danger" role="alert">Your Browser will reload the YaCy UI with the new port in 5 seconds...</div>#(/reconnect)#

</ol>
</form>
<p><strong>What you should do next:</strong></p>
Expand Down
203 changes: 101 additions & 102 deletions source/net/yacy/data/TransactionManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,25 +42,25 @@
* These tokens should be designed to be hard to forge by an unauthenticated user.
*/
public class TransactionManager {

/** Parameter name of the transaction token */
public static final String TRANSACTION_TOKEN_PARAM = "transactionToken";

/** Secret signing key valid until next server restart */
/** Parameter name of the transaction token */
public static final String TRANSACTION_TOKEN_PARAM = "transactionToken";

/** Secret signing key valid until next server restart */
private static final String SIGNING_KEY = UUID.randomUUID().toString();

/** Random token seed valid until next server restart */
private static final String TOKEN_SEED = UUID.randomUUID().toString();
/**
* @param header
* current request header. Must not be null.
* @return the name of the currently authenticated user (administrator user
* name when the request comes from local host and unauthenticated local
* access as administrator is enabled), or null when no authenticated.
* @throws NullPointerException
* when header parameter is null.
*/

/**
* @param header
* current request header. Must not be null.
* @return the name of the currently authenticated user (administrator user
* name when the request comes from local host and unauthenticated local
* access as administrator is enabled), or null when no authenticated.
* @throws NullPointerException
* when header parameter is null.
*/
private static String getUserName(final RequestHeader header) {
String userName = header.getRemoteUser();
Switchboard sb = Switchboard.getSwitchboard();
Expand All @@ -70,85 +70,84 @@ private static String getUserName(final RequestHeader header) {
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 consoder the name is "admin"
// this header present. We just consider the name is "admin"
userName = adminAccountUserName;
}
if (userName == null && header.accessFromLocalhost()) {
if (sb.getConfigBool(SwitchboardConstants.ADMIN_ACCOUNT_FOR_LOCALHOST, false)) {
/* Unauthenticated local access as administrator can be enabled */
userName = adminAccountUserName;
} else {
/* authorization by encoded password, only for localhost access (used by bash scripts)*/
String pass = Base64Order.standardCoder.encodeString(adminAccountUserName + ":" + adminAccountBase64MD5);
/* get the authorization string from the header */
final String realmProp = (header.get(RequestHeader.AUTHORIZATION, "")).trim();
final String realmValue = realmProp.isEmpty() ? null : realmProp.substring(6); // take out "BASIC "
if (pass.equals(realmValue)) { // assume realmValue as is in cfg
userName = adminAccountUserName;
}
}
}

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

if (sb.getConfigBool(SwitchboardConstants.ADMIN_ACCOUNT_FOR_LOCALHOST, false)) {
/* Unauthenticated local access as administrator can be enabled */
userName = adminAccountUserName;
} else {
/* authorization by encoded password, only for localhost access (used by bash scripts)*/
String pass = Base64Order.standardCoder.encodeString(adminAccountUserName + ":" + adminAccountBase64MD5);

/* get the authorization string from the header */
final String realmProp = (header.get(RequestHeader.AUTHORIZATION, "")).trim();
final String realmValue = realmProp.isEmpty() ? null : realmProp.substring(6); // take out "BASIC "

if (pass.equals(realmValue)) { // assume realmValue as is in cfg
userName = adminAccountUserName;
}
}
}
}
return userName;

return userName;
}
/**
* Get a transaction token to be used later on a protected HTTP post method
* call on the same path with the currently authenticated user.
*
* @param header
* current request header
* @return a transaction token
* @throws IllegalArgumentException
* when header parameter is null or when the user is not authenticated.
*/

/**
* Get a transaction token to be used later on a protected HTTP post method
* call on the same path with the currently authenticated user.
*
* @param header
* current request header
* @return a transaction token
* @throws IllegalArgumentException
* when header parameter is null or when the user is not authenticated.
*/
public static String getTransactionToken(final RequestHeader header) {
if (header == null) {
throw new IllegalArgumentException("Missing required header parameter");
throw new IllegalArgumentException("Missing required header parameter");
}

return getTransactionToken(header, header.getPathInfo());
}
/**
* Get a transaction token to be used later on a protected HTTP post method
* call on the specified path with the currently authenticated user.
*
* @param header
* current request header
* @param path the relative path for which the token will be valid
* @return a transaction token for the specified path
* @throws IllegalArgumentException
* when a parameter is null or when the user is not authenticated.
*/

/**
* Get a transaction token to be used later on a protected HTTP post method
* call on the specified path with the currently authenticated user.
*
* @param header
* current request header
* @param path the relative path for which the token will be valid
* @return a transaction token for the specified path
* @throws IllegalArgumentException
* when a parameter is null or when the user is not authenticated.
*/
public static String getTransactionToken(final RequestHeader header, final String path) {
if (header == null) {
throw new IllegalArgumentException("Missing required header parameter");
throw new IllegalArgumentException("Missing required header parameter");
}

/* Check this comes from an authenticated user */
final String userName = getUserName(header);
if (userName == null) {
throw new IllegalArgumentException("User is not authenticated");
}

/* Produce a token by signing a message with the server secret key :
* The token is not unique per request and thus keeps the service stateless
* (no need to store tokens until they are consumed).
* On the other hand, it is supposed to remain hard enough to forge because the secret key and token seed
* are initialized with a random value at each server startup */
final String token = new HmacUtils(HmacAlgorithms.HMAC_SHA_1, SIGNING_KEY)
.hmacHex(TOKEN_SEED + userName + path);


if (userName == null) {
throw new IllegalArgumentException("User is not authenticated");
}

/* Produce a token by signing a message with the server secret key :
* The token is not unique per request and thus keeps the service stateless
* (no need to store tokens until they are consumed).
* On the other hand, it is supposed to remain hard enough to forge because the secret key and token seed
* are initialized with a random value at each server startup */
final String token = new HmacUtils(HmacAlgorithms.HMAC_SHA_1, SIGNING_KEY)
.hmacHex(TOKEN_SEED + userName + path);

return token;
}

/**
* Check the current request is a valid HTTP POST transaction : the current user is authenticated,
* and the request post parameters contain a valid transaction token.
Expand All @@ -159,34 +158,34 @@ public static String getTransactionToken(final RequestHeader header, final Strin
* @throws TemplateMissingParameterException when the transaction token is missing
* @throws BadTransactionException when a condition for valid transaction is not met.
*/
public static void checkPostTransaction(final RequestHeader header, final serverObjects post) {
public static void checkPostTransaction(final RequestHeader header, final serverObjects post) {
if (header == null)
throw new IllegalArgumentException("Missing required header parameters.");
throw new IllegalArgumentException("Missing required header parameters.");

if (header.accessFromLocalhost()) return; // this is one exception that we accept if basc authentication is gven

if (post == null) // non-local requests must use POST parameters
throw new IllegalArgumentException("Missing required post parameters.");
if (!HeaderFramework.METHOD_POST.equals(header.getMethod())) // non-local users must use POST protocol
throw new DisallowedMethodException("HTTP POST method is the only one authorized.");

if (!HeaderFramework.METHOD_POST.equals(header.getMethod())) // non-local users must use POST protocol
throw new DisallowedMethodException("HTTP POST method is the only one authorized.");

String userName = getUserName(header);
if (userName == null)
throw new BadTransactionException("User is not authenticated.");
final String transactionToken = post.get(TRANSACTION_TOKEN_PARAM);
if (transactionToken == null)
throw new TemplateMissingParameterException("Missing transaction token.");
final String token = new HmacUtils(HmacAlgorithms.HMAC_SHA_1, SIGNING_KEY)
.hmacHex(TOKEN_SEED + userName + header.getPathInfo());
/* Compare the server generated token with the one received in the post parameters,
* using a time constant function */
if(!MessageDigest.isEqual(token.getBytes(StandardCharsets.UTF_8), transactionToken.getBytes(StandardCharsets.UTF_8))) {
throw new BadTransactionException("Invalid transaction token.");
}
}
if (userName == null)
throw new BadTransactionException("User is not authenticated.");

final String transactionToken = post.get(TRANSACTION_TOKEN_PARAM);
if (transactionToken == null)
throw new TemplateMissingParameterException("Missing transaction token.");

final String token = new HmacUtils(HmacAlgorithms.HMAC_SHA_1, SIGNING_KEY)
.hmacHex(TOKEN_SEED + userName + header.getPathInfo());

/* Compare the server generated token with the one received in the post parameters,
* using a time constant function */
if(!MessageDigest.isEqual(token.getBytes(StandardCharsets.UTF_8), transactionToken.getBytes(StandardCharsets.UTF_8))) {
throw new BadTransactionException("Invalid transaction token.");
}
}

}
Loading

0 comments on commit 4da320b

Please sign in to comment.