FCM/GCM App Server cannot connect to FCM/GCM CCS using SSLSocket and SMACK library - ssl

I'm writing a Firebase Cloud Messaing (FCM) App server program, and encountered a connection problem when I try to connect to FCM server via XMPP connection, using SMACK library. The program fails to be connected to the FCM server (fcm-xmpp.googleapis.com:5236).
Following an example,
https://github.com/carlosCharz/fcmxmppserverv2/blob/master/src/main/java/com/wedevol/xmpp/server/CcsClient.java,
I try to connect to the FCM server using SSL socket. The source codes are as follows.
XMPPTCPConnectionConfiguration.Builder configBuilder = XMPPTCPConnectionConfiguration.builder ();
configBuilder.setUsernameAndPassword (senderId, serverKey);
configBuilder.setServiceName (CCMServiceName);
configBuilder.setHost (CCMServer);
configBuilder.setPort (CCMServerPort);
configBuilder.setSocketFactory (SSLSocketFactory.getDefault ());
configBuilder.setSecurityMode (SecurityMode.ifpossible);
configBuilder.setSendPresence (true);
configBuilder.setDebuggerEnabled(true);
SASLAuthentication.unBlacklistSASLMechanism("PLAIN");
//Step 2. Generate a connection resource with CCM Server
connection = new XMPPTCPConnection (configBuilder.build ());
//Step 3. Connect
try {
systemLogStream.println ("Try to connect XMPP end-point: " + CCMServer );
connection.connect();
} catch (SmackException smackEx) {
systemLogStream.println ("SMACK Exception: " + smackEx.getMessage());
System.exit(999);
} catch (XMPPException xmppEx) {
systemLogStream.println ("XMPP Exception: ");
} catch (IOException ioEx) {
systemLogStream.println ("IO Exception: ");
}
However, it always fails to connect to FCM server generating following exception.
SMACK Exception: No response received within reply timeout. Timeout was 5000ms (~5s). Used filter: No filter used or filter was 'null'.
To figure out the reason, I captured tcpdumps and it looks like SSLSocket does not send Clienthello message which is the first step to TLS handshake. Following is the result from Wireshark.
Wireshark capture result
I hope that someone nice gives a comment or an advise how to resolve this problem.
Thank you.

Related

Ratchet PHP server establishes connection, but Kotlin never receives acknowledgement

I have a ratchet server, that I try to access via Websocket. It is similar to the tutorial: logging when there is a new client or when it receives a message. The Ratchet server reports having successfully established a connection while the Kotlin client does not (the connection event in Kotlin is never fired). I am using the socket-io-java module v.2.0.1. The client shows a timeout after the specified timeout time, gets detached at the server and attaches again after a short while, just as it seems to think, the connection did not properly connect (because of a missing connection response?).
The successful connection confirmation gets reported to the client, if the client is a Websocket-Client in the JS-console of Chrome, but not to my Kotlin app. Even an Android emulator running on the same computer doesn´t get a response (So I think the problem is not wi-fi related).
The connection works fine with JS, completing the full handshake, but with an Android app it only reaches the server, but never the client again.
That´s my server code:
<?php
namespace agroSMS\Websockets;
use Ratchet\ConnectionInterface;
use Ratchet\MessageComponentInterface;
class SocketConnection implements MessageComponentInterface
{
protected \SplObjectStorage $clients;
public function __construct() {
$this->clients = new \SplObjectStorage;
}
function onOpen(ConnectionInterface $conn)
{
$this->clients->attach($conn);
error_log("New client attached");
}
function onClose(ConnectionInterface $conn)
{
$this->clients->detach($conn);
error_log("Client detached");
}
function onError(ConnectionInterface $conn, \Exception $e)
{
echo "An error has occurred: {$e->getMessage()}\n";
$conn->close();
}
function onMessage(ConnectionInterface $from, $msg)
{
error_log("Received message: $msg");
// TODO: Implement onMessage() method.
}
}
And the script that I run in the terminal:
<?php
use Ratchet\Server\IoServer;
use agroSMS\Websockets\SocketConnection;
use Ratchet\WebSocket\WsServer;
use Ratchet\Http\HttpServer;
require dirname(__DIR__) . '/vendor/autoload.php';
$server = IoServer::factory(
new HttpServer(
new WsServer(
new SocketConnection()
)
)
);
$server->run();
What I run in the browser for tests (returns "Connection established" in Chrome, but for some reason not in the Browser "Brave"):
var conn = new WebSocket('ws://<my-ip>:80');
conn.onopen = function(e) {
console.log("Connection established!");
};
conn.onmessage = function(e) {
console.log(e.data);
};
What my Kotlin-code looks like:
try {
val uri = URI.create("ws://<my-ip>:80")
val options = IO.Options.builder()
.setTimeout(60000)
.setTransports(arrayOf(WebSocket.NAME))
.build()
socket = IO.socket(uri, options)
socket.connect()
.on(Socket.EVENT_CONNECT) {
Log.d(TAG, "[INFO] Connection established")
socket.send(jsonObject)
}
.once(Socket.EVENT_CONNECT_ERROR) {
val itString = gson.toJson(it)
Log.d(TAG, itString)
}
}catch(e : Exception) {
Log.e(TAG, e.toString())
}
After a minute the Kotlin code logs a "timeout"-error, detaches from the server, and attaches again.
When I stop the script on the server, it then gives an error: "connection reset, websocket error" (which makes sense, but why doesn´t he get the connection in the first time?)
I also tried to "just" change the protocol to "wss" in the url, in case it might be the problem, even though my server doesn´t even work with SSL, but this just gave me another error:
[{"cause":{"bytesTransferred":0,"detailMessage":"Read timed out","stackTrace":[],"suppressedExceptions":[]},"detailMessage":"websocket error","stackTrace":[],"suppressedExceptions":[]}]
And the connection isn´t even established at the server. So this try has been more like a down-grade.
I went to the github page of socket.io-java-client to find a solution to my problem there and it turned out, the whole problem was, that I misunderstood a very important concept:
That socket.io uses Websockets doesn´t mean it is compatible with Websockets.
So speaking in clear words:
If you use socket.io at client side, you also need to use it at the server side and vice versa. Since socket.io sends a lot of meta data with its packets, a pure Websocket-server will accept their connection establishment, but his acknowledgement coming back will not be accepted by the socket.io client.
You have to go for either full socket.io or full pure Websockets.

When connecting to Pop3 server with Mailkit, connection fails every other time

I'm trying to write some code to retrieve the e-mails stored in the pop3 mailbox hosted at a third party email provider using Mailkit (version 2.1.0.3). When attempting to connect to the mailserver, the connection fails every other time with the error:
"An error occurred while attempting to establish an SSL or TLS
connection."
With inner exception
"Authentication failed because the remote party has closed the transport stream."
So the code above on the first attempt succeeds, and on the second attempt fails with the error mentioned above. This happens without fail, and always fails the second time I try. This leads me to believe there is something wrong with terminating the connection.
Here is the code I use to set up a connection.
using (var client = new Pop3Client())
{
await client.ConnectAsync("pop3.**.nl", 995, true); // FAILS HERE
await client.AuthenticateAsync("**username**", "**password**");
for (int i = 0; i < client.Count; i++)
{
...
}
await client.DeleteAllMessagesAsync();
await client.DisconnectAsync(true);
}
I already attempting resolving the issue using the following functions, however, none of them helped. However changing the SSL protocol to version SSL3 and SSL2 caused the error to appear at every connection attempt, instead of every other one.
client.ServerCertificateValidationCallback += (e, r, t, y) => true;
client.SslProtocols = SslProtocols.Tls12;
client.CheckCertificateRevocation = false;

How to setup websocket SSL connect using cpprestsdk?

I tried to connect to a websocket server with SSL. But always failed on connection(...).
I am new to cpprestsdk, I can't find doc on how to set SSL information to websocket_client.
websocket_client_config config;
config.set_server_name("wss://host:port/v3/api");
websocket_client client(config);
auto fileStream = std::make_sharedconcurrency::streams::ostream();
pplx::task requestTask = fstream::open_ostream(U("results2.html"))
.then([&](ostream outFile)
{
*fileStream = outFile;
// Create http_client to send the request.
uri wsuri(U("wss://host:port/v3/api"));
client.connect(wsuri).wait();
websocket_outgoing_message msg;
msg.set_utf8_message(obj.serialize());
client.send(msg).wait();
printf("send success: %s\n", obj.serialize().c_str());
return client.receive().get();
})
it throws "Error exception:set_fail_handler: 8: TLS handshake failed".
Documentation for cpprestsdk can be found here
C++ REST SDK WebSocket client. Although this doesn't show all the necessary information related to cpprestsdk it will help you.
And also you can get an SSL test example here. I show a simple websocket client implemented using SSL or wss:// scheme
websocket_client client;
std::string body_str("hello");
try
{
client.connect(U("wss://echo.websocket.org/")).wait();
auto receive_task = client.receive().then([body_str](websocket_incoming_message ret_msg) {
VERIFY_ARE_EQUAL(ret_msg.length(), body_str.length());
auto ret_str = ret_msg.extract_string().get();
VERIFY_ARE_EQUAL(body_str.compare(ret_str), 0);
VERIFY_ARE_EQUAL(ret_msg.message_type(), websocket_message_type::text_message);
});
websocket_outgoing_message msg;
msg.set_utf8_message(body_str);
client.send(msg).wait();
receive_task.wait();
client.close().wait();
}
catch (const websocket_exception& e)
{
if (is_timeout(e.what()))
{
// Since this test depends on an outside server sometimes it sporadically can fail due to timeouts
// especially on our build machines.
return;
}
throw;
}
And further examples here to guide you get it successfully is found here
https://github.com/microsoft/cpprestsdk/wiki/Web-Socket

Web service Soap getting Read Timeout Exception

I am trying to create soap web service client by one client WSDL file by using Apache Axis 2 and tomcat 6.
I successfully generated client, but when I am calling methods to get data I am getting error.
WSDL location: https://staging2.myhcl.com/MedicalClaim/Service.svc?wsdl
Error:
Unable to sendViaPost to url[http://staging2.myhcl.com/MedicalClaim/Service.svc]
java.net.SocketTimeoutException: Read timed out
My doubt is mentioned below:
We are sending request with GET or POST methods that how we can know in SOAP web service?
When above mentioned error used to come?
Rather than Apache Axis 2, what other generating client can we use for this WSDL file?
You might need to check how much time it is taking at Skeleton end.I have done SOAP some time back and i have faced same issue.Below code might help you
private HttpURLConnection getConnection(String endPoint) {
try {
URL url = new URL(endPoint);
URLConnection connection = url.openConnection();
connection.setConnectTimeout(20000); // 20 sec connection timeout
connection.setReadTimeout(60000); // 60 sec read timeout
HttpURLConnection httpConnection = (HttpURLConnection) connection;
httpConnection.setRequestMethod("POST");
OutputStream out = httpConnection.getOutputStream();
return httpConnection;
} catch (MalformedURLException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
But ensure that your service(Skeleton) is not taking much time to process the request.You can use SoapUI to find out how much time it is taking to return the response.Accordingly you can set the timeout value.
Here comes answers of your doubts:
1.You can set POST/GET in HttpURLConnection object.
2.The error specified can come if the connection is idle for long and the Service is not returning any result.Use SoapUI to check the reply from Service.
3.wsdl2java and java2wsdl with Apache Axis2 is a good option for this purpose.Also xmlbeans has an inbuilt converter, which is quite handy to use.

How to test GCM server side without implementing client side?

I have created the server side for gcm using the code below:
Message message = new Message.Builder().timeToLive(30)
.delayWhileIdle(true).addData(MESSAGE_KEY, MESSAGE_VALUE).build();
MulticastResult result = null;
try
{
result = sender.send(message, devicesList, 1);
System.out.println(result.toString());
}
catch(Exception e)
{
e.printStackTrace();
}
It is working fine but the problem i am facing is that currently i can't implement the client side,so i don't have the registration id to test my code.
So anyone can please help me that is there any way to test my gcm server side implementation without implementing client side ??? Thanks ..!!!!