package com.juick.components.s2s; import com.juick.components.XMPPServer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xmlpull.mxp1.MXParser; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import java.io.*; import java.net.Socket; import java.nio.charset.Charset; import java.security.*; import java.security.cert.CertificateException; import java.util.UUID; /** * * @author ugnich */ public class Connection { protected static final Logger logger = LoggerFactory.getLogger(Connection.class); public String streamID; public long tsCreated = 0; public long tsLocalData = 0; public long bytesLocal = 0; public long packetsLocal = 0; XMPPServer xmpp; Socket socket; public static final String NS_DB = "jabber:server:dialback"; public static final String NS_TLS = "urn:ietf:params:xml:ns:xmpp-tls"; public static final String NS_STREAM = "http://etherx.jabber.org/streams"; XmlPullParser parser = new MXParser(); OutputStreamWriter writer; private boolean secured = false; SSLContext sc; private TrustManager[] trustAllCerts = new TrustManager[]{ new X509TrustManager() { public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) { } public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) { } public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } } }; public Connection(XMPPServer xmpp) throws XmlPullParserException, KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, UnrecoverableKeyException, KeyManagementException { this.xmpp = xmpp; tsCreated = System.currentTimeMillis(); parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); KeyStore ks = KeyStore.getInstance("JKS"); try (InputStream ksIs = new FileInputStream(xmpp.keystore)) { ks.load(ksIs, xmpp.keystorePassword.toCharArray()); KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory .getDefaultAlgorithm()); kmf.init(ks, xmpp.keystorePassword.toCharArray()); sc = SSLContext.getInstance("TLSv1.2"); sc.init(kmf.getKeyManagers(), trustAllCerts, new SecureRandom()); } catch (Exception e) { logger.warn("tls unavailable"); } } public void logParser() { if (streamID == null) { return; } String tag = "IN: <" + parser.getName(); for (int i = 0; i < parser.getAttributeCount(); i++) { tag += " " + parser.getAttributeName(i) + "=\"" + parser.getAttributeValue(i) + "\""; } tag += ">...\n"; logger.trace(tag); } public void sendStanza(String xml) throws IOException { if (streamID != null) { logger.trace("OUT: " + xml + "\n"); } writer.write(xml); writer.flush(); tsLocalData = System.currentTimeMillis(); bytesLocal += xml.length(); packetsLocal++; } public void closeConnection() { if (streamID != null) { logger.info(String.format("CLOSING STREAM %s", streamID)); } try { writer.write(""); } catch (Exception e) { } try { writer.close(); } catch (Exception e) { } try { socket.close(); } catch (Exception e) { } } static String generateDialbackKey(String to, String from, String id) throws Exception { Mac hmacSha256 = Mac.getInstance("hmacSHA256"); SecretKeySpec secret_key = new SecretKeySpec("$UppPerSeCCret4".getBytes(), "SHA-256"); hmacSha256.init(secret_key); byte key[] = hmacSha256.doFinal((to + " " + from + " " + id).getBytes()); StringBuilder hexkey = new StringBuilder(); for (int i = 0; i < key.length; i++) { hexkey.append(Integer.toHexString(0xFF & key[i])); } return hexkey.toString(); } public boolean isSecured() { return secured; } public void setSecured(boolean secured) { this.secured = secured; } public void restartParser() throws XmlPullParserException, IOException { parser = new MXParser(); parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); parser.setInput(new InputStreamReader(socket.getInputStream())); writer = new OutputStreamWriter(socket.getOutputStream(), Charset.forName("UTF-8")); streamID = UUID.randomUUID().toString(); } }