I'm trying to get a java server set up for communicating to Google's Cloud Connection Server using the smack library. I have set up an app ID and API key through Google APIs and am trying to use the following code:
import javax.net.ssl.SSLSocketFactory;
import org.jivesoftware.smack.Connection;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.SASLAuthentication;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Packet;
public class CloudMessager {
public CloudMessager(){
ConnectionConfiguration config = new ConnectionConfiguration("gcm.googleapis.com", 5235);
SASLAuthentication.supportSASLMechanism("PLAIN", 0);
config.setSASLAuthenticationEnabled(true);
config.setSocketFactory(SSLSocketFactory.getDefault());
Connection connection = new XMPPConnection(config);
// Connect to the server
try {
connection.connect();
connection.login("SENDERID#gcm.googleapis.com", "APIKEY");
PacketListener myListener = new PacketListener() {
public void processPacket(Packet packet) {
}
};
// Register the listener.
connection.addPacketListener(myListener,null);
} catch (XMPPException e) {
e.printStackTrace();
}
}
}
Which gives me the following error:
SASL authentication PLAIN failed: text:
at org.jivesoftware.smack.SASLAuthentication.authenticate(SASLAuthentication.java:342)
at org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:221)
at org.jivesoftware.smack.Connection.login(Connection.java:366)
at org.umptyfratz.strongbox.CloudMessager.<init>(CloudMessager.java:25)
I'm at a bit of a loss to figure out where to go from here. Has anyone else successfully connected to CCS using the Java smack library?
Try to debug the connection with this option:
config.setDebuggerEnabled(true);
This'll open a new window with the data sent and received.
If you find something like "Project SENDERID not whitelisted." you have to register your project here.
(This is in the documentation's note too! http://developer.android.com/google/gcm/ccs.html )
Related
The intention is to stream the log during runtime on a specific host:port, so that the logs are accessible to users outside the running system, from browser.
As you can see, i have created a simple SocketHandler for java8 logging(java.util.logging), is there something that i have missed?
import java.net.MalformedURLException;
import java.net.URL;
import java.io.IOException;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import java.util.logging.SocketHandler;
import java.util.logging.XMLFormatter;
public class Main {
public static void main(String[] args) throws Exception {
Logger logger = Logger.getLogger("concrete.log");
SocketHandler handler = new SocketHandler("HOSTNAME", 19004);
LogRecord logRec = new LogRecord(Level.INFO, "Log recorded");
handler.publish(logRec);
handler.setFormatter(new XMLFormatter());
logger.addHandler(handler);
logger.info("socket handler info message");
}
}
When i run the code, i see the following exception, i have tried checking the system firewall settings on both local(mac/windows) and remote(Linux) and seen that the settings do not block 19004 port
Exception in thread "main" java.net.ConnectException: Connection refused (Connection refused)
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:476)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:218)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:200)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:394)
at java.net.Socket.connect(Socket.java:606)
at java.net.Socket.connect(Socket.java:555)
at java.net.Socket.<init>(Socket.java:451)
at java.net.Socket.<init>(Socket.java:228)
at java.util.logging.SocketHandler.connect(SocketHandler.java:167)
at java.util.logging.SocketHandler.<init>(SocketHandler.java:154)
at Main.main(Main.java:16)
UPDATE
As suggested by bosowski
When i create Socket to listen to a specific port, the log messages are getting printed on the console of the host. However, am unable to access hostname:port for the log to be streamed from the browser. Is there anything specific that needs to be performed after this step?
Please let me know
import java.io.*;
import java.net.*;
public class MyServer {
public static void main(String[] args)
{
try {
ServerSocket ss = new ServerSocket(19004);
Socket soc = ss.accept();
DataInputStream dis
= new DataInputStream(soc.getInputStream());
String str = (String)dis.readUTF();
System.out.println("message= " + str);
ss.close();
}
catch (Exception e) {
System.out.println(e);
}
}
}
SocketHandler does not open up a port to connect to, if that's what you're assuming. It tries to connect to the specified host and port, so you need to have a port that is listening on the host that you are trying to connect to.
https://docs.oracle.com/javase/8/docs/api/java/util/logging/SocketHandler.html#SocketHandler-java.lang.String-int-
<handler-name>.host specifies the target host name to connect to (no default).
<handler-name>.port specifies the target TCP port to use (no default).
If you do indeed have a listening TCP port on the hostname that you're trying to connect to, you can try running sudo nmap -F hostname to check if the port is indeed accessible from your machine.
I am currently trying to make a simple connection between a Java class and an Apache Hive server.
However, I have not been able to do it due to a javax.net.ssl.SSLPeerUnverifiedException error.
This is the Java code that I am executing:
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.logging.Logger;
public class Main {
public static void main(String[] args) {
Connection con = null;
try {
String conStr = "jdbc:hive2://{{domain}}:{{port}}/default;ssl=true;sslTrustStore=C:/DBVisualization/gateway.jks;trustStorePassword=Password1;transportMode=http;httpPath=/gateway/default/hive";
Class.forName("org.apache.hive.jdbc.HiveDriver");
con = DriverManager.getConnection(conStr, "user", "password");
if(con != null)
System.out.println("Connected");
} catch (Exception ex) {
Logger.getAnonymousLogger().severe("There was an error while connecting to Hive");
}
}
}
And this is the error I am getting:
Could not open client transport with JDBC Uri: jdbc:hive2:{{url}}:{{port}}/default;ssl=true;sslTrustStore=C:/DBVisualization/cacerts;trustStorePassword=changeit;transportMode=http;httpPath=/gateway/default/hive: Could not establish connection to jdbc:hive2://{{url}}:{{port}}/default;ssl=true;sslTrustStore=C:/DBVisualization/cacerts;trustStorePassword=changeit;transportMode=http;httpPath=/gateway/default/hive: javax.net.ssl.SSLPeerUnverifiedException: Certificate for <IP> doesn't match any of the subject alternative names: []
As you can see I am pointing to the file where the certificate is, I used that same certificate for set up a DB visualizer connection and it worked. I am just do not know if for Java a different certificate is required. What am I doing wrong?
Forgive me for the newb question, but I am confused and obviously not understanding the fundamentals or explanations of how to use a Websocket server hosted over HTTPS. Everything I find online leads me to have more questions than answers.
I have a Websocket server hosted on my HTTPS website using Java code.
This is my WebsocketServer.java file:
import org.java_websocket.WebSocket;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;
import java.net.InetSocketAddress;
import java.util.HashSet;
import java.util.Set;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class WebsocketServer extends WebSocketServer {
private static final Logger logger = LogManager.getLogger(WebsocketServer.class);
private static int TCP_PORT = 6868;
private static Set<WebSocket> conns;
public WebsocketServer() {
super(new InetSocketAddress(TCP_PORT));
conns = new HashSet<>();
}
#Override
public void onOpen(WebSocket conn, ClientHandshake handshake) {
conns.add(conn);
logger.info("New connection from " + conn.getRemoteSocketAddress().getAddress().getHostAddress());
logger.info("Size of connection list: " + conns.size());
}
#Override
public void onClose(WebSocket conn, int code, String reason, boolean remote) {
conns.remove(conn);
logger.info("Closed connection to " + conn.getRemoteSocketAddress().getAddress().getHostAddress());
}
#Override
public void onMessage(WebSocket conn, String message) {
logger.info("Message from client: {}", message);
// for (WebSocket sock : conns) {
// sock.send("SENDING BACK" + message);
// }
}
#Override
public void onError(WebSocket conn, Exception ex) {
// ex.printStackTrace();
try {
if (conn != null) {
conns.remove(conn);
// do some thing if required
}
logger.info("ERROR from {}", conn.getRemoteSocketAddress().getAddress().getHostAddress());
} catch (Exception e) {
logger.info("onError: WebSocketServer may already be running");
}
}
public Set<WebSocket> getConns() {
return conns;
}
}
Then I started the WebsocketServer like this:
WebsocketServer websocketServer;
// Start socket server
websocketServer = new WebsocketServer();
websocketServer.start();
And on the client side, I connect to it like this:
// APP_WEB_SOCKET is the url to my site: api.my_custom_domain.com
var connection = new WebSocket("wss://" + APP_WEB_SOCKET + ":6868");
QUESTIONS:
I keep reading that I need a certificate if I want to use wss over HTTPS, but cannot find any documents that explain what this means in a way that I can understand.
My app is hosted in AWS Elastic Beanstalk environment. Do I need to somehow add a certificate to the setup of the WebsocketServer in my Java code?
Example:
WebsocketServer websocketServer;
// Start socket server
websocketServer = new WebsocketServer();
// example guessing
websocketServer.cert = "SOMETHING";??
websocketServer.start();
Does the client code need to be changed at all?
Who needs the certificate?
If someone could please explain what I am missing or point me in the correct direction, I would really appreciate it.
Keep it easy.
Certs inside your application are complex - they are hard to manage and you will get problems to run your application in a modern cloud environment (start new environments, renew certs, scale your application, ...).
Simple conclusion: Dont implement any certs.
How-to get encrypted connections?
As Mike already pointed out in the comments: WebSockets are just upgraded HTTP(S) connections. A normal webserver (nginx, apache) takes care about the certs. It can be done in kubernetes (as ingress-controller) or with a "bare-metal" webserver.
Both of them should act as a reverse-proxy. This means: Your java-application doesn't know anything about certs. It has just unencrypted connections - like in your code on port 6868.
But the client will not use this port. 6868 is only internally reachable.
The client will call your reverse-proxy at the normal HTTPS port (=443). The reverse-proxy will forward the connection to your java-application.
Here some links for further information:
nginx reverse-proxy
nginx reverse-proxy for websocket
tutorial for java behind reverse-proxy
LetsEncrypt for automatic and free certs
I am running RServe from Server machine using cmd
Rserve.exe --RS-conf Rserv.conf --RS-port 12306
Rserv.conf file has following content:
pwdfile RserveAuth.txt
auth required
remote enable
plaintext disable
RserveAuth.txt has following contents:
Admin 123456
I am connecting to R Server from JAVA
import org.rosuda.REngine.REXPMismatchException;
import org.rosuda.REngine.REngineException;
import org.rosuda.REngine.Rserve.RConnection;
import org.rosuda.REngine.Rserve.RserveException;
import org.rosuda.REngine.REXP;
import org.rosuda.REngine.*;
public class ConnecttoR
{
...
...
public void connectR()
{
try
{
RConnection connection = new RConnection("172.16.33.242",12306); // Works if authentication is not required in Rserv.conf
}
catch (RserveException e) {
e.printStackTrace();
}
catch(REXPMismatchException e){
e.printStackTrace();
}
catch(REngineException e){
e.printStackTrace();
}
}
}
Connection to Rserve is open to all without username & Password. How shall I add security and allow connection only with valid credentials to access Rserve
As you have enabled the authentification after creating the connection as a first command you need to execute the login command. The Java library has a special wrapper for it.
See code below for example use case.
RConnection connection = new RConnection("127.0.0.1",12306);
connection.login("Admin", "123456");
REXP x = connection.eval("R.version.string");
System.out.println(x.asString());
Also, I would recommend using full path as the pwdfile value.
I am getting connection error on WebSphere admin client creation process.
I read many forums but cannot fix it.
"Exception creating Admin Client Connection: com.ibm.websphere.management.exception.ConnectorException: ADMC0016E: The system cannot create a SOAP connector to connect to host "111.xxxx.." at port 8879."
My dmgr port is 8879
Host name is "111.xxxx.."
Servers config files located c:\temp\soap.client.props, DummyClientTrustFile.jks, DummyClientKeyFile.jks
My code is below:
import java.util.Date;
import java.util.Properties;
import java.util.Set;
import javax.management.InstanceNotFoundException;
import javax.management.MalformedObjectNameException;
import javax.management.Notification;
import javax.management.NotificationListener;
import javax.management.ObjectName;
import com.ibm.websphere.management.AdminClient;
import com.ibm.websphere.management.AdminClientFactory;
import com.ibm.websphere.management.exception.ConnectorException;
public class AdminClientConnection
{
private AdminClient adminClient;
public static void main(String[] args)
{
AdminClientConnection aClient = new AdminClientConnection();
// Create an AdminClient
aClient.createAdminClient();
}
private void createAdminClient()
{
// Set up a Properties object for the JMX connector attributes
Properties clientProps = new Properties();
clientProps.setProperty(
AdminClient.CONNECTOR_TYPE, AdminClient.CONNECTOR_TYPE_SOAP);
clientProps.setProperty(AdminClient.CONNECTOR_HOST, "111.xxxx..");
clientProps.setProperty(AdminClient.CONNECTOR_PORT, "8879");
clientProps.setProperty(AdminClient.CONNECTOR_SECURITY_ENABLED, "true");
clientProps.setProperty(AdminClient.USERNAME, "usr");
clientProps.setProperty(AdminClient.PASSWORD, "pass");
clientProps.setProperty(AdminClient.CONNECTOR_SOAP_CONFIG, "c:/temp/soap.client.props");
clientProps.setProperty("javax.net.ssl.trustStore", "c:/temp/DummyClientTrustFile.jks");
clientProps.setProperty("javax.net.ssl.keyStore", "c:/temp/DummyClientKeyFile.jks");
clientProps.setProperty("javax.net.ssl.trustStorePassword", "WebAS");
clientProps.setProperty("javax.net.ssl.keyStorePassword", "WebAS");
// Get an AdminClient based on the connector properties
try
{
adminClient = AdminClientFactory.createAdminClient(clientProps);
}
catch (ConnectorException e)
{
System.out.println("Exception creating Admin Client Connection: " + e);
System.exit(-1);
}
System.out.println("Connected to Application Server");
}
}
Be sure that CONNECTOR_PORT is true, CONNECTOR_SECURITY_ENABLED is not neccassary. Be sure that soap.client.props and jks files are gathered from the connector host.