Unverified 提交 b876d231 authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov 提交者: GitHub

Merge pull request #1753 from katzyn/console

Add transparent key to Console tool that unlocks creation of new databases
......@@ -21,6 +21,8 @@ Change Log
<h2>Next Version (unreleased)</h2>
<ul>
<li>Issue #1751: making it easier to open console and create local databases
</li>
<li>Issue #1750: JOIN t ON t.col IN (SELECT ...) throws AssertionError
</li>
</ul>
......
......@@ -484,8 +484,9 @@ Auto-creation of databases can be disabled, see
<a href="features.html#database_only_if_exists">Opening a Database Only if it Already Exists</a>.
</p>
<p>
H2 Console does not allow creation of databases by default.
If H2 Console is launched with icon in the system tray its context menu can be used to create a new database.
H2 Console does not allow creation of databases by default unless a browser window is opened by Console during its
startup or from its icon in the system tray and remote access is not enabled.
A context menu of the tray icon can also be used to create a new database.
</p>
<h2 id="using_server">Using the Server</h2>
......
......@@ -281,6 +281,10 @@ public class WebApp {
if (b != null && b) {
return true;
}
String key = server.getKey();
if (key != null && key.equals(session.get("key"))) {
return true;
}
session.put("adminBack", file);
return false;
}
......@@ -937,7 +941,7 @@ public class WebApp {
prof.startCollecting();
Connection conn;
try {
conn = server.getConnection(driver, url, user, password);
conn = server.getConnection(driver, url, user, password, null);
} finally {
prof.stopCollecting();
profOpen = prof.getTop(3);
......@@ -998,7 +1002,7 @@ public class WebApp {
session.put("maxrows", "1000");
boolean isH2 = url.startsWith("jdbc:h2:");
try {
Connection conn = server.getConnection(driver, url, user, password);
Connection conn = server.getConnection(driver, url, user, password, (String) session.get("key"));
session.setConnection(conn);
session.put("url", url);
session.put("user", user);
......
......@@ -168,6 +168,8 @@ public class WebServer implements Service {
private ShutdownHandler shutdownHandler;
private Thread listenerThread;
private boolean ifExists = true;
private String key;
private boolean allowSecureCreation;
private boolean trace;
private TranslateThread translateThread;
private boolean allowChunked = true;
......@@ -266,6 +268,36 @@ public class WebServer implements Service {
return startDateTime;
}
/**
* Returns the key for privileged connections.
*
* @return key key, or null
*/
String getKey() {
return key;
}
/**
* Sets the key for privileged connections.
*
* @param key key, or null
*/
public void setKey(String key) {
if (!allowOthers) {
this.key = key;
}
}
/**
* @param allowSecureCreation
* whether creation of databases using the key should be allowed
*/
public void setAllowSecureCreation(boolean allowSecureCreation) {
if (!allowOthers) {
this.allowSecureCreation = allowSecureCreation;
}
}
@Override
public void init(String... args) {
// set the serverPropertiesDir, because it's used in loadProperties()
......@@ -325,6 +357,9 @@ public class WebServer implements Service {
for (String[] lang : LANGUAGES) {
languages.add(lang[0]);
}
if (allowOthers) {
key = null;
}
updateURL();
}
......@@ -336,8 +371,12 @@ public class WebServer implements Service {
private void updateURL() {
try {
url = (ssl ? "https" : "http") + "://" +
NetUtils.getLocalAddress() + ":" + port;
StringBuilder builder = new StringBuilder(ssl ? "https" : "http").append("://")
.append(NetUtils.getLocalAddress()).append(':').append(port);
if (key != null) {
builder.append("?key=").append(key);
}
url = builder.toString();
} catch (NoClassDefFoundError e) {
// Google App Engine does not allow java.net.InetAddress
}
......@@ -495,6 +534,9 @@ public class WebServer implements Service {
}
void setAllowOthers(boolean b) {
if (b) {
key = null;
}
allowOthers = b;
}
......@@ -718,10 +760,11 @@ public class WebServer implements Service {
* @param databaseUrl the database URL
* @param user the user name
* @param password the password
* @param userKey the key of privileged user
* @return the database connection
*/
Connection getConnection(String driver, String databaseUrl, String user,
String password) throws SQLException {
String password, String userKey) throws SQLException {
driver = driver.trim();
databaseUrl = databaseUrl.trim();
Properties p = new Properties();
......@@ -730,8 +773,10 @@ public class WebServer implements Service {
// encrypted H2 database with empty user password doesn't work
p.setProperty("password", password);
if (databaseUrl.startsWith("jdbc:h2:")) {
if (ifExists) {
databaseUrl += ";IFEXISTS=TRUE";
if (!allowSecureCreation || key == null || !key.equals(userKey)) {
if (ifExists) {
databaseUrl += ";IFEXISTS=TRUE";
}
}
}
return JdbcUtils.getConnection(driver, databaseUrl, p);
......
......@@ -78,6 +78,9 @@ class WebThread extends WebApp implements Runnable {
if (requestedFile.length() == 0) {
return "index.do";
}
if (requestedFile.charAt(0) == '?') {
return "index.do" + requestedFile;
}
return requestedFile;
}
......@@ -122,10 +125,12 @@ class WebThread extends WebApp implements Runnable {
attributes = new Properties();
int paramIndex = file.indexOf('?');
session = null;
String key = null;
if (paramIndex >= 0) {
String attrib = file.substring(paramIndex + 1);
parseAttributes(attrib);
String sessionId = attributes.getProperty("jsessionid");
key = attributes.getProperty("key");
file = file.substring(0, paramIndex);
session = server.getSession(sessionId);
}
......@@ -150,6 +155,9 @@ class WebThread extends WebApp implements Runnable {
message += "Content-Length: " + bytes.length + "\r\n";
} else {
if (session != null && file.endsWith(".jsp")) {
if (key != null) {
session.put("key", key);
}
String page = new String(bytes, StandardCharsets.UTF_8);
if (SysProperties.CONSOLE_STREAM) {
Iterator<String> it = (Iterator<String>) session.map.remove("chunks");
......
......@@ -9,6 +9,8 @@ import java.sql.Connection;
import java.sql.SQLException;
import org.h2.server.ShutdownHandler;
import org.h2.util.JdbcUtils;
import org.h2.util.MathUtils;
import org.h2.util.StringUtils;
import org.h2.util.Tool;
import org.h2.util.Utils;
......@@ -88,6 +90,7 @@ public class Console extends Tool implements ShutdownHandler {
boolean tcpShutdown = false, tcpShutdownForce = false;
String tcpPassword = "";
String tcpShutdownServer = "";
boolean ifExists = false, webAllowOthers = false;
for (int i = 0; args != null && i < args.length; i++) {
String arg = args[i];
if (arg == null) {
......@@ -109,6 +112,7 @@ public class Console extends Tool implements ShutdownHandler {
webStart = true;
} else if ("-webAllowOthers".equals(arg)) {
// no parameters
webAllowOthers = true;
} else if ("-webDaemon".equals(arg)) {
// no parameters
} else if ("-webSSL".equals(arg)) {
......@@ -168,6 +172,7 @@ public class Console extends Tool implements ShutdownHandler {
// no parameters
} else if ("-ifExists".equals(arg)) {
// no parameters
ifExists = true;
} else if ("-baseDir".equals(arg)) {
i++;
} else {
......@@ -196,7 +201,9 @@ public class Console extends Tool implements ShutdownHandler {
if (webStart) {
try {
web = Server.createWebServer(args);
String webKey = webAllowOthers ? null
: StringUtils.convertBytesToHex(MathUtils.secureRandomBytes(32));
web = Server.createWebServer(args, webKey, !ifExists);
web.setShutdownHandler(this);
web.start();
if (printStatus) {
......
......@@ -426,7 +426,24 @@ public class Server extends Tool implements Runnable, ShutdownHandler {
* @return the server
*/
public static Server createWebServer(String... args) throws SQLException {
return createWebServer(args, null, false);
}
/**
* Create a new web server, but does not start it yet.
*
* @param args
* the argument list
* @param key
* key, or null
* @param allowSecureCreation
* whether creation of databases using the key should be allowed
* @return the server
*/
static Server createWebServer(String[] args, String key, boolean allowSecureCreation) throws SQLException {
WebServer service = new WebServer();
service.setKey(key);
service.setAllowSecureCreation(allowSecureCreation);
Server server = new Server(service, args);
service.setShutdownHandler(server);
return server;
......@@ -492,7 +509,12 @@ public class Server extends Tool implements Runnable, ShutdownHandler {
try {
started = true;
service.start();
String name = service.getName() + " (" + service.getURL() + ")";
String url = service.getURL();
int idx = url.indexOf('?');
if (idx >= 0) {
url = url.substring(0, idx);
}
String name = service.getName() + " (" + url + ')';
Thread t = new Thread(this, name);
t.setDaemon(service.isDaemon());
t.start();
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论