Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,35 @@ public void test30NoAutoGenerationWhenAutoConfigurationDisabled() throws Excepti
assertThat(usersAndPasswords.isEmpty(), is(true));
}

public void test40VerifyAutogeneratedCredentials() throws Exception {
public void test40NoAutogenerationWhenDaemonizedWithTty() throws Exception {
/* Windows issue awaits fix: https://github.com/elastic/elasticsearch/issues/49340 */
assumeTrue("expect command isn't on Windows", distribution.platform != Distribution.Platform.WINDOWS);
stopElasticsearch();
ServerUtils.enableSecurityAutoConfiguration(installation);
Shell.Result result = runElasticsearchStartCommand(null, true, true);
Map<String, String> usersAndPasswords = parseUsersAndPasswords(result.stdout);
assertThat(usersAndPasswords.isEmpty(), is(true));
}

public void test50NoAutogenerationWhenNotDaemonizedWithoutTty() throws Exception {
/* Windows issue awaits fix: https://github.com/elastic/elasticsearch/issues/49340 */
assumeTrue("expect command isn't on Windows", distribution.platform != Distribution.Platform.WINDOWS);
stopElasticsearch();
Shell.Result result = runElasticsearchStartCommand(null, false, false);
Map<String, String> usersAndPasswords = parseUsersAndPasswords(result.stdout);
assertThat(usersAndPasswords.isEmpty(), is(true));
}

public void test60NoAutogenerationWhenDaemonizedWithoutTty() throws Exception {
/* Windows issue awaits fix: https://github.com/elastic/elasticsearch/issues/49340 */
assumeTrue("expect command isn't on Windows", distribution.platform != Distribution.Platform.WINDOWS);
stopElasticsearch();
Shell.Result result = runElasticsearchStartCommand(null, true, false);
Map<String, String> usersAndPasswords = parseUsersAndPasswords(result.stdout);
assertThat(usersAndPasswords.isEmpty(), is(true));
}

public void test70VerifyAutogeneratedCredentials() throws Exception {
/* Windows issue awaits fix: https://github.com/elastic/elasticsearch/issues/49340 */
assumeTrue("expect command isn't on Windows", distribution.platform != Distribution.Platform.WINDOWS);
stopElasticsearch();
Expand All @@ -81,7 +109,7 @@ public void test40VerifyAutogeneratedCredentials() throws Exception {
}
}

public void test50PasswordAutogenerationOnlyOnce() throws Exception {
public void test80PasswordAutogenerationOnlyOnce() throws Exception {
/* Windows issue awaits fix: https://github.com/elastic/elasticsearch/issues/49340 */
assumeTrue("expect command isn't on Windows", distribution.platform != Distribution.Platform.WINDOWS);
stopElasticsearch();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -309,14 +309,15 @@ static void stop() throws IOException {
/**
* This method is invoked by {@link Elasticsearch#main(String[])} to startup elasticsearch.
*/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should isolate this, otherwise other forbidden uses can creep into bootstrap init.

@SuppressForbidden(reason = "Retain reference for System.out")
static void init(
final boolean foreground,
final Path pidFile,
final boolean quiet,
final Environment initialEnv) throws BootstrapException, NodeValidationException, UserException {
// force the class initializer for BootstrapInfo to run before
// the security manager is installed
BootstrapInfo.init();
BootstrapInfo.init(System.out);

INSTANCE = new Bootstrap();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import org.elasticsearch.core.SuppressForbidden;

import java.io.PrintStream;
import java.util.Dictionary;
import java.util.Enumeration;

Expand All @@ -19,6 +20,8 @@
@SuppressForbidden(reason = "exposes read-only view of system properties")
public final class BootstrapInfo {

private static PrintStream originalStandardOut;

/** no instantiation */
private BootstrapInfo() {}

Expand Down Expand Up @@ -46,6 +49,11 @@ public static boolean isSystemCallFilterInstalled() {
return Natives.isSystemCallFilterInstalled();
}

/**
* Returns a reference to the original System.out
*/
public static PrintStream getOriginalStandardOut() { return originalStandardOut; }

/**
* codebase location for untrusted scripts (provide some additional safety)
* <p>
Expand Down Expand Up @@ -110,7 +118,8 @@ public static Dictionary<Object,Object> getSystemProperties() {
return SYSTEM_PROPERTIES;
}

public static void init() {
public static void init(PrintStream originalStandardOut) {
BootstrapInfo.originalStandardOut = originalStandardOut;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.DocWriteRequest;
import org.elasticsearch.action.support.WriteRequest;
import org.elasticsearch.bootstrap.BootstrapInfo;
import org.elasticsearch.common.settings.SecureString;
import org.elasticsearch.index.engine.VersionConflictEngineException;
import org.elasticsearch.xpack.core.security.user.ElasticUser;
import org.elasticsearch.xpack.core.security.user.KibanaSystemUser;
import org.elasticsearch.xpack.security.authc.esnative.NativeUsersStore;
import org.elasticsearch.xpack.security.support.SecurityIndexManager;

import java.io.PrintStream;
import java.util.function.BiConsumer;

import static org.elasticsearch.xpack.security.tool.CommandUtils.generatePassword;
Expand All @@ -36,6 +38,13 @@ public GenerateInitialBuiltinUsersPasswordListener(NativeUsersStore nativeUsersS

@Override
public void accept(SecurityIndexManager.State previousState, SecurityIndexManager.State currentState) {
final PrintStream out = BootstrapInfo.getOriginalStandardOut();
// Check if it has been closed, try to write something so that we trigger PrintStream#ensureOpen
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if there is any other way to check if stdout is closed

out.println();
if (out.checkError()) {
outputOnError(new IllegalStateException("Stashed standard output stream is closed."));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really an illegal state? It just means that we’ve closed the streams, which is normal when not attached to a console.

return;
}
if (previousState.equals(SecurityIndexManager.State.UNRECOVERED_STATE)
&& currentState.equals(SecurityIndexManager.State.UNRECOVERED_STATE) == false
&& securityIndexManager.indexExists() == false) {
Expand All @@ -57,7 +66,7 @@ public void accept(SecurityIndexManager.State previousState, SecurityIndexManage
WriteRequest.RefreshPolicy.IMMEDIATE,
ActionListener.wrap(
r -> {
outputOnSuccess(elasticPassword, kibanaSystemPassword);
outputOnSuccess(elasticPassword, kibanaSystemPassword, out);
}, this::outputOnError
)
);
Expand All @@ -66,53 +75,41 @@ public void accept(SecurityIndexManager.State previousState, SecurityIndexManage
}
}

private void outputOnSuccess(SecureString elasticPassword, SecureString kibanaSystemPassword) {
LOGGER.info("");
LOGGER.info("-----------------------------------------------------------------");
LOGGER.info("");
LOGGER.info("");
LOGGER.info("");
LOGGER.info("Password for the elastic user is: " + elasticPassword);
LOGGER.info("");
LOGGER.info("");
LOGGER.info("");
LOGGER.info("Password for the kibana_system user is: " + kibanaSystemPassword);
LOGGER.info("");
LOGGER.info("");
LOGGER.info("Please note these down as they will not be shown again.");
LOGGER.info("");
LOGGER.info("You can use 'bin/elasticsearch-reset-elastic-password' at any time");
LOGGER.info("in order to reset the password for the elastic user.");
LOGGER.info("");
LOGGER.info("");
LOGGER.info("You can use 'bin/elasticsearch-reset-kibana-system-password' at any time");
LOGGER.info("in order to reset the password for the kibana_system user.");
LOGGER.info("");
LOGGER.info("");
LOGGER.info("");
LOGGER.info("-----------------------------------------------------------------");
LOGGER.info("");
private void outputOnSuccess(SecureString elasticPassword, SecureString kibanaSystemPassword, PrintStream out) {
out.println();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The stream could still have been closed, in which case we are not attached to a terminal. So we need to catch that case, and probably log a warning?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I'll check this first before even generating the passwords. If we can't show them, there is no need to even generate them

out.println("-----------------------------------------------------------------");
out.println();
out.println("Password for the elastic user is: " + elasticPassword);
out.println();
out.println("Password for the kibana_system user is: " + kibanaSystemPassword);
out.println();
out.println("Please note these down as they will not be shown again.");
out.println();
out.println();
out.println("You can use 'bin/elasticsearch-reset-elastic-password' at any time");
out.println("in order to reset the password for the elastic user.");
out.println();
out.println("You can use 'bin/elasticsearch-reset-kibana-system-password' at any time");
out.println("in order to reset the password for the kibana_system user.");
out.println();
out.println("-----------------------------------------------------------------");
out.println();
}

private void outputOnError(Exception e) {
if (e instanceof VersionConflictEngineException == false) {
LOGGER.info("");
LOGGER.info("-----------------------------------------------------------------");
LOGGER.info("");
LOGGER.info("");
LOGGER.info("");
LOGGER.info("Failed to set the password for the elastic and kibana-system users ");
LOGGER.info("automatically");
LOGGER.info("");
LOGGER.info("You can use 'bin/elasticsearch-reset-elastic-password'");
LOGGER.info("in order to set the password for the elastic user.");
LOGGER.info("");
LOGGER.info("");
LOGGER.info("You can use 'bin/elasticsearch-reset-kibana-system-password'");
LOGGER.info("in order to set the password for the kibana_system user.");
LOGGER.info("");
LOGGER.info("");
LOGGER.info("");
LOGGER.info("-----------------------------------------------------------------");
LOGGER.info("");
}
Expand Down