Skip to content

Commit fa8065e

Browse files
committed
SSL: Added SSL/TLS implementation for both HTTP and Binary Protocols
1 parent 9cf37f8 commit fa8065e

13 files changed

Lines changed: 537 additions & 12 deletions

File tree

client/src/main/java/com/orientechnologies/orient/client/remote/OStorageRemote.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ public class OStorageRemote extends OStorageAbstract implements OStorageProxy, O
9797
public static final String PARAM_DB_TYPE = "dbtype";
9898
private static final String DEFAULT_HOST = "localhost";
9999
private static final int DEFAULT_PORT = 2424;
100+
private static final int DEFAULT_SSL_PORT = 2434;
100101
private static final String ADDRESS_SEPARATOR = ";";
101102
private static final String DRIVER_NAME = "OrientDB Java";
102103
protected final List<String> serverURLs = new ArrayList<String>();
@@ -1798,8 +1799,10 @@ protected String addHost(String host) {
17981799
host = "127.0.0.1" + host.substring("localhost".length());
17991800

18001801
// REGISTER THE REMOTE SERVER+PORT
1801-
if (!host.contains(":"))
1802-
host += ":" + getDefaultPort();
1802+
if (!host.contains(":"))
1803+
host += ":" + (clientConfiguration.getValueAsBoolean(
1804+
OGlobalConfiguration.CLIENT_USE_SSL) ? getDefaultSSLPort() : getDefaultPort());
1805+
18031806

18041807
if (!serverURLs.contains(host))
18051808
serverURLs.add(host);
@@ -1814,7 +1817,11 @@ protected String getDefaultHost() {
18141817
protected int getDefaultPort() {
18151818
return DEFAULT_PORT;
18161819
}
1817-
1820+
1821+
protected int getDefaultSSLPort() {
1822+
return DEFAULT_SSL_PORT;
1823+
}
1824+
18181825
protected OChannelBinaryAsynchClient createNetworkConnection() throws IOException {
18191826
final String currentServerURL = getServerURL();
18201827

core/src/main/java/com/orientechnologies/orient/core/config/OGlobalConfiguration.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,9 @@ public void change(final Object iCurrentValue, final Object iNewValue) {
499499

500500
CLIENT_DB_RELEASE_WAIT_TIMEOUT("client.channel.dbReleaseWaitTimeout",
501501
"Delay in ms. after which data modification command will be resent if DB was frozen", Integer.class, 10000),
502+
503+
CLIENT_USE_SSL("client.ssl.enabled", "Use SSL for client connections", Boolean.class, false),
504+
502505

503506
// SERVER
504507
SERVER_CHANNEL_CLEAN_DELAY("server.channel.cleanDelay", "Time in ms of delay to check pending closed connections", Integer.class,
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
/*
2+
* Copyright 2014 Charles Baptiste (cbaptiste--at--blacksparkcorp.com)
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.orientechnologies.orient.enterprise.channel;
17+
18+
import java.io.IOException;
19+
import java.net.InetAddress;
20+
import java.net.ServerSocket;
21+
import java.net.Socket;
22+
import java.net.SocketException;
23+
import java.net.UnknownHostException;
24+
import java.security.NoSuchAlgorithmException;
25+
26+
import javax.net.SocketFactory;
27+
import javax.net.ssl.SSLContext;
28+
import javax.net.ssl.SSLServerSocket;
29+
30+
import com.orientechnologies.common.log.OLogManager;
31+
import com.orientechnologies.orient.core.config.OContextConfiguration;
32+
import com.orientechnologies.orient.core.config.OGlobalConfiguration;
33+
34+
public class OSocketFactory {
35+
36+
SocketFactory socketFactory;
37+
boolean useSSL = false;
38+
SSLContext context = null;
39+
OContextConfiguration config;
40+
41+
private OSocketFactory(OContextConfiguration iConfig) {
42+
config = iConfig;
43+
setUseSSL(iConfig.getValueAsBoolean(OGlobalConfiguration.CLIENT_USE_SSL));
44+
}
45+
46+
public static OSocketFactory instance(final OContextConfiguration iConfig) {
47+
return new OSocketFactory(iConfig);
48+
}
49+
50+
public static OSocketFactory instance(final OContextConfiguration iConfig,
51+
SSLContext context) {
52+
53+
OSocketFactory sFactory = instance(iConfig);
54+
sFactory.setSSLContent(context);
55+
return sFactory;
56+
}
57+
58+
private SocketFactory getBackingFactory() {
59+
if (socketFactory == null) {
60+
if (getUseSSL()) {
61+
socketFactory = getSSLContext().getSocketFactory();
62+
} else {
63+
socketFactory = SocketFactory.getDefault();
64+
}
65+
}
66+
return socketFactory;
67+
}
68+
69+
public void setSSLContent(SSLContext context) {
70+
this.context = context;
71+
synchronized(socketFactory) {
72+
socketFactory = null;
73+
}
74+
}
75+
76+
private SSLContext getSSLContext() {
77+
if (context == null) {
78+
try {
79+
context = SSLContext.getDefault();
80+
} catch (NoSuchAlgorithmException e) {
81+
OLogManager.instance().error(this,
82+
"Error creating ssl context", e);
83+
}
84+
}
85+
return context;
86+
}
87+
88+
public void setUseSSL(boolean useSSL) {
89+
this.useSSL = useSSL;
90+
}
91+
92+
public boolean getUseSSL() {
93+
return useSSL;
94+
}
95+
96+
private Socket configureSocket(Socket socket) throws SocketException {
97+
98+
// Add possible timeouts?
99+
return socket;
100+
}
101+
102+
public Socket createSocket() throws IOException {
103+
return configureSocket(getBackingFactory().createSocket());
104+
}
105+
106+
public Socket createSocket(String host, int port) throws IOException,
107+
UnknownHostException {
108+
return configureSocket(getBackingFactory().createSocket(host, port));
109+
}
110+
111+
public Socket createSocket(InetAddress host, int port) throws IOException {
112+
return configureSocket(getBackingFactory().createSocket(host, port));
113+
}
114+
115+
public Socket createSocket(String host, int port, InetAddress localHost,
116+
int localPort) throws IOException, UnknownHostException {
117+
return configureSocket(getBackingFactory().createSocket(host, port, localHost,
118+
localPort));
119+
}
120+
121+
public Socket createSocket(InetAddress address, int port,
122+
InetAddress localAddress, int localPort) throws IOException {
123+
return configureSocket(getBackingFactory().createSocket(address, port, localAddress,
124+
localPort));
125+
}
126+
127+
}

enterprise/src/main/java/com/orientechnologies/orient/enterprise/channel/binary/OChannelBinaryAsynchClient.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import com.orientechnologies.orient.core.config.OGlobalConfiguration;
2626
import com.orientechnologies.orient.core.exception.OStorageException;
2727
import com.orientechnologies.orient.core.serialization.OMemoryInputStream;
28+
import com.orientechnologies.orient.enterprise.channel.OSocketFactory;
2829

2930
import java.io.BufferedInputStream;
3031
import java.io.BufferedOutputStream;
@@ -35,7 +36,6 @@
3536
import java.lang.reflect.Constructor;
3637
import java.lang.reflect.InvocationTargetException;
3738
import java.net.InetSocketAddress;
38-
import java.net.Socket;
3939
import java.util.ArrayList;
4040
import java.util.List;
4141
import java.util.concurrent.TimeUnit;
@@ -60,8 +60,8 @@ public OChannelBinaryAsynchClient(final String remoteHost, final int remotePort,
6060

6161
public OChannelBinaryAsynchClient(final String remoteHost, final int remotePort, final OContextConfiguration iConfig,
6262
final int protocolVersion, final ORemoteServerEventListener asynchEventListener) throws IOException {
63-
super(new Socket(), iConfig);
64-
63+
super(OSocketFactory.instance(iConfig).createSocket(), iConfig);
64+
6565
maxUnreadResponses = OGlobalConfiguration.NETWORK_BINARY_READ_RESPONSE_MAX_TIMES.getValueAsInteger();
6666
serverURL = remoteHost + ":" + remotePort;
6767
socketTimeout = iConfig.getValueAsInteger(OGlobalConfiguration.NETWORK_SOCKET_TIMEOUT);

graphdb/config/orientdb-server-config.xml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,26 @@
4545

4646
</handlers>
4747
<network>
48+
<!-- <sockets>
49+
<socket implementation="com.orientechnologies.orient.server.network.OServerSSLSocketFactory" name="ssl">
50+
<parameters>
51+
<parameter value="true" name="network.ssl.clientAuth"/>
52+
<parameter value="bin/orientdb.ks" name="network.ssl.keyStore"/>
53+
<parameter value="password" name="network.ssl.keyStorePassword"/>
54+
<parameter value="bin/orientdb.ts" name="network.ssl.trustStore"/>
55+
<parameter value="password" name="network.ssl.trustStorePassword"/>
56+
</parameters>
57+
</socket>
58+
<socket implementation="com.orientechnologies.orient.server.network.OServerSSLSocketFactory" name="https">
59+
<parameters>
60+
<parameter value="false" name="network.ssl.clientAuth"/>
61+
<parameter value="bin/orientdb.ks" name="network.ssl.keyStore"/>
62+
<parameter value="password" name="network.ssl.keyStorePassword"/>
63+
<parameter value="bin/orientdb.ts" name="network.ssl.trustStore"/>
64+
<parameter value="password" name="network.ssl.trustStorePassword"/>
65+
</parameters>
66+
</socket>
67+
</sockets> -->
4868
<protocols>
4969
<!-- Default registered protocol. It reads commands using the HTTP protocol
5070
and write data locally -->
@@ -55,6 +75,8 @@
5575
</protocols>
5676
<listeners>
5777
<listener protocol="binary" ip-address="0.0.0.0" port-range="2424-2430"/>
78+
<!-- <listener protocol="binary" ip-address="0.0.0.0" port-range="2434-2440" socket="ssl"/> -->
79+
<!-- <listener protocol="http" ip-address="0.0.0.0" port-range="2480-2490" socket="https"> -->
5880
<listener protocol="http" ip-address="0.0.0.0" port-range="2480-2490">
5981
<parameters>
6082
<!-- Connection's custom parameters. If not specified the global configuration

graphdb/script/console.sh

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,10 @@ export JAVA
3636

3737
ORIENTDB_SETTINGS="-Dcache.level1.enabled=false -Dcache.level2.enabled=false -Djava.util.logging.config.file="$ORIENTDB_HOME/config/orientdb-client-log.properties" -Djava.awt.headless=true"
3838
#JAVA_OPTS=-Xmx1024m
39+
#KEYSTORE=$ORIENTDB_HOME/bin/orientdb-console.ks
40+
#KEYSTORE_PASS=password
41+
#TRUSTSTORE=$ORIENTDB_HOME/bin/orientdb-console.ts
42+
#TRUSTSTORE_PASS=password
43+
#SSL_OPTS="-Dclient.ssl.enabled=true -Djavax.net.ssl.keyStore=$KEYSTORE -Djavax.net.ssl.keyStorePassword=$KEYSTORE_PASS -Djavax.net.ssl.trustStore=$TRUSTSTORE -Djavax.net.ssl.trustStorePassword=$TRUSTSTORE_PASS"
3944

40-
$JAVA -client $JAVA_OPTS $ORIENTDB_SETTINGS -Dfile.encoding=utf-8 -Dorientdb.build.number="@BUILD@" -cp "$ORIENTDB_HOME/lib/orientdb-tools-@[email protected]:$ORIENTDB_HOME/lib/*" com.orientechnologies.orient.graph.console.OGremlinConsole $*
45+
$JAVA -client $JAVA_OPTS $ORIENTDB_SETTINGS $SSL_OPTS -Dfile.encoding=utf-8 -Dorientdb.build.number="@BUILD@" -cp "$ORIENTDB_HOME/lib/orientdb-tools-@[email protected]:$ORIENTDB_HOME/lib/*" com.orientechnologies.orient.graph.console.OGremlinConsole $*

server/src/main/java/com/orientechnologies/orient/server/OServer.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,13 @@
4444
import com.orientechnologies.orient.server.config.OServerNetworkListenerConfiguration;
4545
import com.orientechnologies.orient.server.config.OServerNetworkProtocolConfiguration;
4646
import com.orientechnologies.orient.server.config.OServerParameterConfiguration;
47+
import com.orientechnologies.orient.server.config.OServerSocketFactoryConfiguration;
4748
import com.orientechnologies.orient.server.config.OServerStorageConfiguration;
4849
import com.orientechnologies.orient.server.config.OServerUserConfiguration;
4950
import com.orientechnologies.orient.server.distributed.ODistributedServerManager;
5051
import com.orientechnologies.orient.server.handler.OConfigurableHooksManager;
5152
import com.orientechnologies.orient.server.network.OServerNetworkListener;
53+
import com.orientechnologies.orient.server.network.OServerSocketFactory;
5254
import com.orientechnologies.orient.server.network.protocol.ONetworkProtocol;
5355
import com.orientechnologies.orient.server.plugin.OServerPlugin;
5456
import com.orientechnologies.orient.server.plugin.OServerPluginInfo;
@@ -85,6 +87,7 @@ public class OServer {
8587
protected OContextConfiguration contextConfiguration;
8688
protected OServerShutdownHook shutdownHook;
8789
protected Map<String, Class<? extends ONetworkProtocol>> networkProtocols = new HashMap<String, Class<? extends ONetworkProtocol>>();
90+
protected Map<String, OServerSocketFactory> networkSocketFactories = new HashMap<String, OServerSocketFactory>();
8891
protected List<OServerNetworkListener> networkListeners = new ArrayList<OServerNetworkListener>();
8992
protected List<OServerLifecycleListener> lifecycleListeners = new ArrayList<OServerLifecycleListener>();
9093
protected OServerPluginManager pluginManager;
@@ -215,14 +218,29 @@ public OServer startup(final OServerConfiguration iConfiguration) throws Illegal
215218
public OServer activate() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
216219
for (OServerLifecycleListener l : lifecycleListeners)
217220
l.onBeforeActivate();
221+
222+
// REGISTER/CREATE SOCKET FACTORIES
223+
if (configuration.network.sockets != null) {
224+
for (OServerSocketFactoryConfiguration f : configuration.network.sockets) {
225+
Class<? extends OServerSocketFactory> fClass = (Class<? extends OServerSocketFactory>) Class.forName(f.implementation);
226+
OServerSocketFactory factory = fClass.newInstance();
227+
try {
228+
factory.config(f.name, f.parameters);
229+
networkSocketFactories.put(f.name, factory);
230+
}
231+
catch (OConfigurationException e) {
232+
OLogManager.instance().error(this, "Error creating socket factory", e);
233+
}
234+
}
235+
}
218236

219237
// REGISTER PROTOCOLS
220238
for (OServerNetworkProtocolConfiguration p : configuration.network.protocols)
221239
networkProtocols.put(p.name, (Class<? extends ONetworkProtocol>) Class.forName(p.implementation));
222240

223241
// STARTUP LISTENERS
224242
for (OServerNetworkListenerConfiguration l : configuration.network.listeners)
225-
networkListeners.add(new OServerNetworkListener(this, l.ipAddress, l.portRange, l.protocol, networkProtocols.get(l.protocol),
243+
networkListeners.add(new OServerNetworkListener(this, networkSocketFactories.get(l.socket), l.ipAddress, l.portRange, l.protocol, networkProtocols.get(l.protocol),
226244
l.parameters, l.commands));
227245

228246
registerPlugins();

server/src/main/java/com/orientechnologies/orient/server/config/OServerNetworkConfiguration.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@
2727

2828
@XmlRootElement(name = "network")
2929
public class OServerNetworkConfiguration {
30+
@XmlElementWrapper
31+
@XmlAnyElement
32+
@XmlElementRef(type = OServerSocketFactoryConfiguration.class)
33+
public List<OServerSocketFactoryConfiguration> sockets;
34+
3035
@XmlElementWrapper
3136
@XmlAnyElement
3237
@XmlElementRef(type = OServerNetworkProtocolConfiguration.class)

server/src/main/java/com/orientechnologies/orient/server/config/OServerNetworkListenerConfiguration.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
import javax.xml.bind.annotation.*;
1919

2020
@XmlRootElement(name = "listener")
21-
@XmlType(propOrder = { "commands", "parameters", "protocol", "portRange", "ipAddress" })
21+
@XmlType(propOrder = { "commands", "parameters", "protocol", "socket", "portRange", "ipAddress" })
2222
public class OServerNetworkListenerConfiguration {
2323

2424
@XmlAttribute(name = "ip-address", required = true)
@@ -29,6 +29,9 @@ public class OServerNetworkListenerConfiguration {
2929

3030
@XmlAttribute
3131
public String protocol = "binary";
32+
33+
@XmlAttribute
34+
public String socket = "default";
3235

3336
@XmlElementWrapper
3437
@XmlElementRef(type = OServerParameterConfiguration.class)
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright 2014 Charles Baptiste (cbaptiste--at--blacksparkcorp.com)
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.orientechnologies.orient.server.config;
17+
18+
import javax.xml.bind.annotation.XmlAttribute;
19+
import javax.xml.bind.annotation.XmlElementRef;
20+
import javax.xml.bind.annotation.XmlElementWrapper;
21+
import javax.xml.bind.annotation.XmlRootElement;
22+
import javax.xml.bind.annotation.XmlType;
23+
24+
@XmlRootElement(name = "socket")
25+
@XmlType(propOrder = { "parameters", "implementation", "name" })
26+
public class OServerSocketFactoryConfiguration {
27+
28+
public OServerSocketFactoryConfiguration() {
29+
}
30+
31+
public OServerSocketFactoryConfiguration(String name, String implementation) {
32+
this.name = name;
33+
this.implementation = implementation;
34+
}
35+
36+
@XmlAttribute(required = true)
37+
public String name;
38+
39+
@XmlAttribute(required = true)
40+
public String implementation;
41+
42+
@XmlElementWrapper
43+
@XmlElementRef(type = OServerParameterConfiguration.class)
44+
public OServerParameterConfiguration[] parameters;
45+
}

0 commit comments

Comments
 (0)