Java Server & SSL Socket Setup - Will this code work? - java

I am coding a web server in Java and so far everything is working nicely. However, since I am unable to obtain a SSL Certificate to test with, I do not have a way to test my server over https. Except for the following code, my server is written to respond to https requests the same way as it does with http requests. Would it work?
System.setProperty("javax.net.ssl.trustStore", trustStorePath);//The path to the trust store file
System.setProperty("javax.net.ssl.trustStorePassword", trustStorePassword);//The trust store password
try(SSLServerSocket socket = (SSLServerSocket) SSLServerSocketFactory.getDefault().createServerSocket(ssl_listen_port)) {
socket.setReuseAddress(true);
System.out.println("\tServer SSL socket created on port " + ssl_listen_port);
while(serverActive) {
//Omitted multithreading code for read-ability:
final SSLSocket s = (SSLSocket) socket.accept();
try {
s.startHandshake();
} catch(SSLHandshakeException e) {
System.err.println("Failed to initialize SSL handshake: " + e.getMessage());
continue;
}
//(The server then handles the remainder of the request as if it were http.)
}
} catch(BindException e) {
System.err.println(" /!\\\tUnable to bind to ssl port " + ssl_listen_port + ":\r\n/___\\\t" + e.getMessage());
} catch(Throwable e) {
e.printStackTrace();
}
I apologize in advance if this sort of question has already been asked or if I have done something wrong.

Related

Java Socket not using proxy from JAVA_TOOL_OPTIONS

How to make all Java connections to use proxy provided via JAVA_TOOL_OPTIONS environment variable?
The simple app I'm using as a test is taken from GitHub:
package to.noc.sslping;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import java.io.OutputStream;
public class SSLPing {
public static void main(String[] args) {
if (args.length != 2) {
System.out.println("Usage: java -jar SSLPing.jar <host> <port>");
System.exit(1);
}
try {
String hostname = args[0];
int port = Integer.parseInt(args[1]);
System.out.println("About to connect to '" + hostname + "' on port " + port);
SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket(hostname, port);
// Hostname verification is not done by default in Java with raw SSL connections.
// The next 3 lines enable it.
SSLParameters sslParams = new SSLParameters();
sslParams.setEndpointIdentificationAlgorithm("HTTPS");
sslsocket.setSSLParameters(sslParams);
// we only send 1 byte, so don't buffer
sslsocket.setTcpNoDelay(true);
// Write a test byte to trigger the SSL handshake
OutputStream out = sslsocket.getOutputStream();
out.write(1);
// If no exception happened, we connected successfully
System.out.println("Successfully connected");
} catch (Exception e) {
e.printStackTrace();
}
}
}
What I want is to be able to provide the PROXY settings via environment variables without having to configure it in the Java code.
I found that it is possible to provide some settings via the JAVA_TOOL_OPTIONS env.
JAVA_TOOL_OPTIONS="-Dhttp.proxyHost=161.xxx.xxx.xxx
-Dhttp.proxyPort=8080
-Dhttp.proxySet=true
-Dhttps.proxyHost=161.xxx.xxx.xxx
-Dhttps.proxyPort=8080
-Dhttps.proxySet=true"
It is correctly seen by the command
java -jar SSLPing.jar google.com 443
Picked up JAVA_TOOL_OPTIONS: -Dhttp.proxyHost=161.xxx.xxx.xxx
-Dhttp.proxyPort=8080
-Dhttp.proxySet=true
-Dhttps.proxyHost=161.xxx.xxx.xxx
-Dhttps.proxyPort=8080
-Dhttps.proxySet=true
About to connect to 'google.com' on port 443
Successfully connected
However when I need to reach a particular URL that requires the proxy, it fails to connect.
How do I make any socket to use the proxy from JAVA_TOOL_OPTIONS env?
How to check if the sockets are using the proxy?

Java Server Socket connection over different routers

I am currently developing a client and a server for a small game.
The client which connects to the server establishes the connection with this method:
// This method is called, passing on an ipv6 address and port number 6666
public void startConnection(String ip, int port) throws IOException {
try {
clientSocket = new Socket(ip, port);
out = new PrintWriter(clientSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
//some other code handling responses
} catch (IOException e) {
LOG.debug("Error when initializing connection", e);
throw new IOException();
}
}
The Server I built accepts connections using this method:
public void start(int port) {
try {
serverSocket = new ServerSocket(port); //port = 6666
//This part is used to handle multiple connections at once
while (b){
try {
map.add(new EchoClientHandler(serverSocket.accept())); //EchoClientHandler is a class used to send and receive data instructions
x = map.size() - 1;
System.out.println("Establishing connection from port " + port);
map.get(x).start();
System.out.println("Connection established");
} catch (SocketTimeoutException e) {
}
}
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Both methods work fine and establish a stable connection between the client and the server, but when i try and establish a connection from different routers or general internet connections (like via cellular data) it doesn't work.
Is there a way to establish connections without both the client and the server having to connect from the same router?
Edit:
Here is the error i get from the client, the server doesn't show anything:
18:03:24.288 [AWT-EventQueue-0] DEBUG dorusblanken.werwolfclient.Client - Error when initializing connection
java.net.SocketException: Network is unreachable: connect
"Network is unreachable" means there is no way to get to the destination network from the current network.
You mentioned that you are trying to establish a connection via the Internet. For that to work, the destination host (your server) must be connected to the Internet, it must have a public IP address, and the clients need to use the public IP address when connecting.
That is the simplest configuration. Most companies don't actually put their servers directly on the Internet. Instead, the public IP frequently belongs to a CDN or DDoS mitigation layer, which forwards connections to a load balancer, and the load balancer forwards connections to servers.

Apache Mina + SSL + Android not working

I'm developing an Android app using Apache Mina for network IO. Non-SSL connections (reading, writing) work fine, but as soon as I add an SSL filter things stop working.
I also tried pure SSL sockets and they work fine.
This is my Mina connection code (in a separate networking thread):
IoConnector connector = new NioSocketConnector();
connector.getSessionConfig().setReadBufferSize(2048);
SocketSessionConfig cfg = (SocketSessionConfig)connector.getSessionConfig();
cfg.setTcpNoDelay(true);
SslContextFactory f = new SslContextFactory();
f.setTrustManagerFactory(new BogusTrustManagerFactory());
f.setProtocol("SSL");
try {
filter = new SslFilter(f.newInstance(), true);
} catch (Exception e) {
Log.d(TAG, "Exception: ", e);
return;
}
filter.setUseClientMode(true);
connector.getFilterChain().addLast("sslFilter", filter);
connector.getFilterChain().addLast("logger", new LoggingFilter());
connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("ASCII"))));
connector.setHandler(new MinaClientHandler());
ConnectFuture future = connector.connect(new InetSocketAddress("10.0.1.9", 7072));
future.awaitUninterruptibly();
if (!future.isConnected())
{
Log.d(TAG, "not connected, return");
return;
}
IoSession session = future.getSession();
session.getConfig().setUseReadOperation(true);
session.getCloseFuture().awaitUninterruptibly();
//System.out.println(session.read().getMessage());
Log.d(TAG, "after writting");
connector.dispose();
In my IoHandlerAdapter I have the following override:
#Override
public void sessionOpened(IoSession session)
{
session.write(IoBuffer.wrap(data)); // byte array
}
Not my actual code, but it reproduces the problem.
On the server side I see that the connection is accepted an the handshake succeeds. But on the client side nothing is sent over the socket. I have tried the same code in a desktop Java application and it also works.
Also if I move the write call just after IoSession session = future.getSession(); the same thing happens.
Has anyone had similar issues? Are there known issues with Mina on Android? Am I missing some session config options?
Since normal SSL sockets work, that is a workaround, but I would rather not rewrite all my networking code.

vysper server login fail

I'm making a vysper xmpp server.
Here's my code:
public static void main(String[] args) throws Exception {
XMPPServer server = new XMPPServer("myserver.org");
StorageProviderRegistry providerRegistry = new MemoryStorageProviderRegistry();
AccountManagement accountManagement = (AccountManagement) providerRegistry.retrieve(AccountManagement.class);
Entity user = EntityImpl.parseUnchecked("user#myserver.org");
accountManagement.addUser(user, "password");
server.setStorageProviderRegistry(providerRegistry);
server.addEndpoint(new TCPEndpoint())
server.setTLSCertificateInfo(new File("keystore.jks"), "boguspw");
//server.setTLSCertificateInfo(new File("bogus_mina_tls.cert"), "boguspw");
server.start();
System.out.println("Vysper server is running...");
server.addModule(new EntityTimeModule());
server.addModule(new VcardTempModule());
server.addModule(new XmppPingModule());
server.addModule(new PrivateDataModule());
}
I've tried both certificate files. (keystore.jks,bogus_mina_tls.cert)
After I start the server, it connects to it, and tries to login but it can't login.
SmackConfiguration.setPacketReplyTimeout(5000);
config = new ConnectionConfiguration("myserver.org", port, "localhost");
config.setSelfSignedCertificateEnabled(true);
config.setSecurityMode(ConnectionConfiguration.SecurityMode.enabled);
config.setSASLAuthenticationEnabled(true);
// config.setKeystorePath("keystore.jks");
// config.setTruststorePath("keystore.jks");
config.setKeystorePath("bogus_mina_tls.cert");
config.setTruststorePath("bogus_mina_tls.cert");
config.setTruststorePassword("boguspw");
XMPPConnection.DEBUG_ENABLED = true;
connection = new XMPPConnection(config);
try {
connection.connect();
} catch (XMPPException e) {
System.out.println("Error connect");
e.printStackTrace();
}
System.out.println("Connected: " + connection.isConnected());
try {
System.out.println(connection.isAuthenticated());
connection.login("user", "password");
} catch (XMPPException e) {
System.out.println("Error login");
e.printStackTrace();
}
I catch this exception:
SASL authentication PLAIN failed: incorrect-encoding: at
org.jivesoftware.smack.SASLAuthentication.authenticate(SASLAuthentication.java:337)
at
org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:203)
at org.jivesoftware.smack.Connection.login(Connection.java:348) at
com.protocol7.vysper.intro.WorkingClient.init(WorkingClient.java:57)
at
com.protocol7.vysper.intro.WorkingClient.(WorkingClient.java:27)
at com.protocol7.vysper.intro.Runclient.main(Runclient.java:11)
I've seen these examples (1st, 2nd) but they don't work.
At first please note that the server certificate is not used for user authentication, it is used to provide secure communication channel between client and server.
From the log you can see that your authentication method is "SASL PLAIN", using a user and password.
On the server, you are setting username/password as:
accountManagement.addUser("user#myserver.org", "password");
but on the client you're using
connection.login("user", "password");
This doesn't fit with the error message you are posting, but I'd suggest you try again with correct user/password.

Java connection timeout exception (server is in virtual machine)

I'm havin this situation. I have server running in CentOS (CentOS is in my virtual machine VMware). In host (win7) I have java program that needs to make GET method to server on CentOS. I've manage connection between host and virtual machine and thing works from browser and java program in CentOS and from browser in host (win7) but not from java program in host which is what I need.
If I turn off virtual machine I still get timeout exception.
I've turn off firewall on win7 but i can't turn it off in CentOS because I don't have admin permission.
This is my java code for GET method (192.168.11.128 is IP of virtual machine) :
private static void getMethod(){
// Create a method instance.
GetMethod method = new GetMethod("http://192.168.11.128");
// Provide custom retry handler is necessary
method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
new DefaultHttpMethodRetryHandler(3, false));
try {
// Execute the method.
int statusCode = client.executeMethod(method);
if (statusCode != HttpStatus.SC_OK) {
System.err.println("Method failed: " + method.getStatusLine());
}
// Read the response body.
byte[] responseBody = method.getResponseBody();
// Deal with the response.
// Use caution: ensure correct character encoding and is not binary data
System.out.println(new String(responseBody));
} catch (HttpException e) {
System.err.println("Fatal protocol violation: " + e.getMessage());
e.printStackTrace();
} catch (IOException e) {
System.err.println("Fatal transport error: " + e.getMessage());
e.printStackTrace();
} finally {
// Release the connection.
method.releaseConnection();
}
}
Thanks for any help!

Categories