.Just follow the trace where socketFactory comes from and you will find ConnectionConfiguration.Builder .setSocketFactory(SocketFactory());
Not sure if I understand your remarks i.e. to getSocket() via the SocketFactory with extended class: follows are my inputs
Below is the extraction of the ProtocolProviderServiceJabbperImpl.java for atalk. Actually in the ConnectionConfiguration.Builder, I did not use .setSocketFactory. Even if I have and get a reference to the SocketFactory(). I see the abstract class SocketFactory does not keep a local copy of socket but return immediately to the caller in all its creatSocket() methods. Not sure how to extend this class under this case as I have not control on how XMPPTCPConnection calling createSocket().
=================
/**
- Connects xmpp connection and login. Returning the state whether is it final - Abort due to
- certificate cancel or keep trying cause only current address has failed or stop trying cause
- we succeeded.
-
-
@param address
- the address to connect to
-
@param serviceName
- the service name to use
-
@param userName
- the username to use
-
@param resource
- and the resource.
-
@param loginStrategy
- the login strategy to use
-
@return return the state how to continue the connect process.
-
@throws XMPPException
- if we cannot connect for some reason
*/
private ConnectState connectAndLogin(InetSocketAddress address, String serviceName,
String userName, String resource, JabberLoginStrategy loginStrategy)
throws XMPPException
{
XMPPTCPConnectionConfiguration.Builder config = XMPPTCPConnectionConfiguration.builder();
config.setServiceName(serviceName);
config.setResource(resource);
config.setHost(address.getAddress().getHostAddress());
config.setPort(address.getPort());
// config.setProxyInfo(proxy);
config.setCompressionEnabled(false);
// config.setReconnectionAllowed(false); // Not supported in Smack 4.1.8 ???
// if we have OperationSetPersistentPresence, skip sending initial presence during login;
// it is taken care by OperationSet
if (getOperationSet(OperationSetPersistentPresence.class) != null)
config.setSendPresence(false);
// user have the possibility to disable TLS but in this case, it will not be able to
// connect to a server which requires TLS
boolean tlsRequired = loginStrategy.isTlsRequired();
config.setSecurityMode(tlsRequired
? ConnectionConfiguration.SecurityMode.required
: ConnectionConfiguration.SecurityMode.ifpossible);
TLSUtils.setTLSOnly(config);
// Need to disable certain ReflectionDebuggerFactory.DEFAULT_DEBUGGERS loading for
// Android (that are only for windows)
SmackConfiguration.addDisabledSmackClass(
“org.jivesoftware.smackx.debugger.EnhancedDebugger”);
SmackConfiguration.addDisabledSmackClass(“org.jivesoftware.smack.debugger.LiteDebugger”);
config.setDebuggerEnabled(true);
// cmeng - disable interpreted xml printing - see no additional info included
// AbstractDebugger.printInterpreted = true;
if (connection != null) {
logger.error(“Connection is not null and is Connected:” + connection.isConnected(),
new Exception("Trace possible duplicate connections: "
- getAccountID().getAccountAddress()));
disconnectAndCleanConnection();
}
this.address = address;
CertificateService cvs = getCertificateVerificationService();
if (cvs != null) {
SSLContext sslContext;
try {
sslTrustManager = getTrustManager(cvs, serviceName);
sslContext = loginStrategy.createSslContext(cvs, sslTrustManager);
config.setCustomSSLContext(sslContext);
}
catch (GeneralSecurityException e) {
logger.error(“Error creating custom trust manager”, e);
throw new XMPPException.XMPPErrorException(
new XMPPError(XMPPError.Condition.service_unavailable));
}
}
else if (tlsRequired) {
throw new XMPPException.XMPPErrorException(
new XMPPError(XMPPError.Condition.service_unavailable));
}
// commented: atalk.org ejabberd XMPP Server supports SCRAMSHA1Mechanism
// SASLAuthentication.unregisterSASLMechanism(SCRAMSHA1Mechanism.class.getName());
XMPPTCPConnection.setUseStreamManagementDefault(true);
xmppConfig = config.build();
connection = new XMPPTCPConnection(xmppConfig);
// Allow longer timeout during login
// connection.setPacketReplyTimeout(
// ProtocolProviderServiceJabberImpl.SMACK_PACKET_REPLY_TIMEOUT);
try {
connection.connect();
}
catch (SmackException e) {
Throwable exception = e.getCause();
if ((exception instanceof SSLHandshakeException)
|| (exception instanceof CertificateException)) {
// javax.net.ssl.SSLHandshakeException:certification path not found :
// exception never throw, as it was masked off by JabberConnectionListener…
}
else {
String exMsg = e.getMessage();
logger.error("Encounter problem during login: " + exMsg);
throw new XMPPException.XMPPErrorException(
new XMPPError(Condition.internal_server_error, null, exMsg,
XMPPError.Type.CANCEL, null, null)
);
}
}
catch (IOException e) {
e.printStackTrace();
}
// Reset back to default
// connection.setPacketReplyTimeout(
// ProtocolProviderServiceJabberImpl.SMACK_PACKET_REPLY_DEFAULT_TIMEOUT);
setTrafficClass();
if (abortConnecting) {
abortConnecting = false;
disconnectAndCleanConnection();
return ConnectState.ABORT_CONNECTING;
}
registerServiceDiscoveryManager();
if (connectionListener == null) {
connectionListener = new JabberConnectionListener();
}
if (!connection.isSecureConnection() && tlsRequired) {
throw new XMPPException.XMPPErrorException(
new XMPPError(XMPPError.Condition.service_unavailable));
}
if (!connection.isConnected()) {
// connection is not connected, lets set state to our connection as failed seems
// there is some lag/problem with network and this way we will inform for it and
// later reconnect if needed as IllegalStateException that is thrown within
// addConnectionListener is not handled properly
disconnectAndCleanConnection();
logger.error(“Connection not established, server not found!”);
eventDuringLogin = null;
fireRegistrationStateChanged(getRegistrationState(),
RegistrationState.CONNECTION_FAILED,
RegistrationStateChangeEvent.REASON_SERVER_NOT_FOUND, null);
return ConnectState.ABORT_CONNECTING;
}
connection.addConnectionListener(connectionListener);
if (abortConnecting) {
abortConnecting = false;
disconnectAndCleanConnection();
return ConnectState.ABORT_CONNECTING;
}
fireRegistrationStateChanged(getRegistrationState(), RegistrationState.REGISTERING,
RegistrationStateChangeEvent.REASON_NOT_SPECIFIED, null);
if (!loginStrategy.login(connection, userName, resource)) {
disconnectAndCleanConnection();
eventDuringLogin = null;
fireRegistrationStateChanged(getRegistrationState(),
RegistrationState.CONNECTION_FAILED,
RegistrationStateChangeEvent.REASON_AUTHENTICATION_FAILED,
loginStrategy.getClass().getName() + " requests abort");
return ConnectState.ABORT_CONNECTING;
}
if (connection.isAuthenticated()) {
eventDuringLogin = null;
fireRegistrationStateChanged(getRegistrationState(), RegistrationState.REGISTERED,
RegistrationStateChangeEvent.REASON_NOT_SPECIFIED, null);
OperationSetPersistentPresenceJabberImpl opSet =
(OperationSetPersistentPresenceJabberImpl) getOperationSet(
OperationSetPersistentPresence.class);
try {
opSet.publishPresenceStatus(getJabberStatusEnum().getStatus(“Available”), “”);
}
catch (Exception e) {
logger.error(“Failed to publish presence status”);
}
return ConnectState.STOP_TRYING;
}
else {
disconnectAndCleanConnection();
eventDuringLogin = null;
fireRegistrationStateChanged(getRegistrationState(), RegistrationState.UNREGISTERED,
RegistrationStateChangeEvent.REASON_NOT_SPECIFIED, null);
return ConnectState.CONTINUE_TRYING;
}
}
=====================
If you have install the atalk.apk on an android phone; select Settings | SSL Certificate:
The last three items in the property page if each Jid i.e. TLS protocol; TLS cipher suite; and view certificate. These information are retrieved via the getSSLSocket()