Daily Archives: September 25, 2015

XMPP Client Server Setup and Programming

XMPP is a open XML technology for real-time communication. Applications are instant messaging, presence, media negotiation, whiteboarding, collaboration, lightweight middleware, content syndication, and generalized XML routing according to XMPP standards Foundation (XSF) .

Extensible Messaging and Presence Protocol (XMPP) is a communications protocol for message-oriented middleware based on XML (Extensible Markup Language). – wikipedia

XMPP Server

Some popular servers on XMPP are ejabbred ( written in erlang licensed by GPL2) and openfire ( written in Java licensed by Apache ). This article will show the installation steps for openfire on Ubuntu version 15 64 bit system

1.Install the tar from http://www.igniterealtime.org/downloads/index.jsp

Screenshot from 2015-09-25 15:12:02

2. Extract and move the folder to /opt

3. Goto bin and run  openfire server  with ./openfire start

Screenshot from 2015-09-24 12:46:12 (copy)

4. Gotot the web admin url http://localhost:9090/ .  For first time  the setup screen will appear

Screenshot from 2015-09-24 12:46:31

5.  Proceed with installation  .

Screenshot from 2015-09-24 12:46:12

It will show screens to select the mysql driver and database . Create a empty db name called openfiredb and add that to mysql url in setup screen of openfire

It will also request a administrator username and password I choose to give admin admin as the username and password alike .

6. change the interface inside of openfire.xml file in location /opt/openfire/conf

<network>
<interface>127.0.0.1</interface>
</network>

we can also review the mysql connection string

<database>
<defaultProvider>
<driver>com.mysql.jdbc.Driver</driver>
<serverURL>jdbc:mysql://127.0.0.1:3306/openfiredb?rewriteBatchedStatements=true</serverURL>
<username encrypted=”true”><<someval>></username>
<password encrypted=”true”> <<someval>></password>
<testSQL>select 1</testSQL>
<testBeforeUse>false</testBeforeUse>
<testAfterUse>false</testAfterUse>
<minConnections>5</minConnections>
<maxConnections>25</maxConnections>
<connectionTimeout>1.0</connectionTimeout>
</defaultProvider>
</database>

7. After the installation login to the server admin console with the admin username and password which is admin admin in our case

Screenshot from 2015-09-24 12:54:08

8.  Review the server settings etc from the admin web console

Screenshot from 2015-09-24 13:16:29

9. Incase the server setup did not go as planned we can reinstall the server again by dropping the database , creating a fresh empty database and modifying the following from true to false in openfire.xml file in location /opt/openfire/conf

<setup>true</setup>

Test the XMPP Server Installation using Spark client

1.Spark can also be downloaded from the same url as was used to download server . Choose your operating system for download

2.Register a spark client with the server

Screenshot from 2015-09-24 14:41:04

3. after registering the client presence should be indicated in the user summary by online status

Screenshot from 2015-09-25 12:55:13

4.Register another client with the same conf except username and password and perform messaging between them

Screenshot from 2015-09-24 14:45:57

XMPP Java Client

Source Code for a Simple Java Application using Smack4 communicating with XMPP servers


package testxmppsmack;

import java.io.IOException;

import org.jivesoftware.smack.ConnectionConfiguration.SecurityMode;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.chat.Chat;
import org.jivesoftware.smack.chat.ChatManager;
import org.jivesoftware.smack.chat.ChatMessageListener;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;

public class JabberSmackAPI {
 
 public static void main(String argsp[]){
 
 XMPPTCPConnectionConfiguration config = XMPPTCPConnectionConfiguration.builder()
 .setServiceName("machine")
 .setUsernameAndPassword("admin", "admin")
 .setCompressionEnabled(false)
 .setHost("127.0.0.1")
 .setPort(5222) 
 .setSecurityMode(SecurityMode.disabled)
/* .setSecurityMode(SecurityMode.required) keep this commented */ 
 .setSendPresence(true) 
 .build();
 
 // Create a connection to the the local XMPP server as defined in config above.
 XMPPTCPConnection con = new XMPPTCPConnection(config);
 
 // Connect to the server code is encapsulated in try/catch block for exception handling
 try {
 con.connect();
 System.out.println("Connected "+con.isConnected());
 } catch (SmackException | IOException | XMPPException e1) {
 // TODO Auto-generated catch block
 e1.printStackTrace();
 }
 
 //Login before performing other tasks like messaging etc 
 try {
 con.login("altanai", "aaa");
 System.out.println("Loggedin "+con.isAuthenticated());
 } catch (XMPPException | SmackException | IOException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 }
 
 
 // Start a new conversation with another account holder caled altanaibisht ( I created 2 user accounts one with my first name and another with fullname) 
 Chat chat = ChatManager.getInstanceFor(con).createChat("altanaibisht@localhost");
 
 try {
 chat.sendMessage("Did you try out the new code i send you last night ?");
 System.out.println("Chat Send ");
 } catch (NotConnectedException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 }

 // Disconnect from the server
 con.disconnect();


}
}


Some errors and their resolution while building and running the above code as Java Application are as follows :

1. Cannot instantiate XMPPConnection
Use XMPPTCPConnection instead of XMPPConnection in Smack 4.

2. Caused by: java.lang.ClassNotFoundException: org.xmlpull.v1.XmlPullParserFactory

need to have XPP3 (XML Pull Parser 3) in your classpath. Smack 4 does no longer bundle it (unlike Smack 3).

Download the xpp3 from http://www.extreme.indiana.edu/dist/java-repository/xpp3/distributions/

ref :http://stackoverflow.com/questions/24196588/smack-throws-java-lang-classnotfoundexception-org-xmlpull-v1-xmlpullparserfact

3. Exception in thread “main” java.lang.NoClassDefFoundError: de/measite/minidns/DNSCache

http://mvnrepository.com/artifact/de.measite.minidns/minidns/0.1.3

4.  For the jxmpp-util-cache-0.5.0-alpha2.jar

Install it from http://mvnrepository.com/artifact/org.jxmpp/jxmpp-util-cache/0.5.0-alpha2

5.Exception in thread “main” java.lang.NoClassDefFoundError: org/jxmpp/util/XmppStringUtils

http://mvnrepository.com/artifact/org.jxmpp/jxmpp-core/0.4.1

6. Exception in thread “main” java.lang.NoClassDefFoundError: org/apache/http/conn/ssl/StrictHostnameVerifier

http://www.java2s.com/Code/Jar/a/Downloadapachehttpcomponentshttpclientjar.htm

7.Exception in thread “main” java.lang.NoClassDefFoundError: org/xbill/DNS/Lookup

http://www.java2s.com/Code/Jar/d/Downloaddnsjava211jar.htm

8.org.jivesoftware.smack.SmackException$ConnectionException: The following addresses failed: ‘machine:5222’ failed because java.net.ConnectException: Connection refused

.setHost(“127.0.0.1”)
.setPort(5222)

9. org.jivesoftware.smack.SmackException: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

.setSecurityMode(SecurityMode.disabled)

Once the program build and runs succesfully connecting to the XMPP server ( which is running ofcourse ) , open a sapark client and test the application with it.

Screenshot from 2015-09-25 12:44:55

Summary

An alternative to XMPP messaging is the SIP for Instant Messaging and Presence Leveraging Extensions (SIMPLE) based on Session Initiation Protocol (SIP).

References :

1.XMPP.org
https://xmpp.org/

2.Getting started from Igniterealtime.org
https://www.igniterealtime.org/builds/smack/docs/latest/documentation/gettingstarted.html

3.IETF RFCs on XMPP ( 2004 ) –
RFC 3920 http://www.ietf.org/rfc/rfc3920.txt
RFC 3921 http://www.ietf.org/rfc/rfc3921.txt

4. Extensions on XMPP
http://xmpp.org/xmpp-protocols/xmpp-extensions/

5. XMPP API explanation by grepcode
http://grepcode.com/file/repo1.maven.org/maven2/org.igniterealtime.smack/smack-core/4.0.0-rc1/org/jivesoftware/smack/XMPPConnection.java

Wowza RTMP Authentication with Third party Token provider over Tiny Encryption Algorithm (TEA)

this article is focused on  Wowza RTMP Authentication with  Third party Token provider over Tiny Encryption Algorithm (TEA)  and  is a continuation of the previous post about setting up a basic RTMP Authentication module on Wowza Engine above version 4.

The task is divided into 3 parts .

  1. RTMP Encoder Application
  2. Wowza RTMP Auth module
  3. Third party Authentication Server

The component diagram is as follows :

Copy of Publisher App iOS

The detailed explanation of the components are :

1.Wowza RTMP Auth module

The Wowza Server receives a rtmp stream url in the format as :

rtmp://username:pass@wowzaip:1935/Application/stteamname

It considers the username and pass to be user credentials . RTMP auth Module invokes the getPassword() function inside of deployed application class  passing the username as parameter.  The username is then  encrypted using TEA ( Tiny Encryption algorithm)

TEA is a block cipher  which is based on symmetric ( private) key encryption . Input is a 64 bit of plain or cipher text with a 128 bit key resulting in output of cipher or plain text respectively.

The code for encryption  is


TEA.encrypt( username, sharedSecret );

The code to make a connection to third party auth server is


 url = new URL(serverTokenValidatorURL);
 
 URLConnection connection;
 connection = url.openConnection();
 connection.setDoOutput(true);

OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
 out.write("clientid=" + TEA.encrypt( username, sharedSecret ););
 out.close(); 

The sharedsecret is the common key which is with both the Auth server and wowza server . It must be atleast a 16 digit alphanumeric / special character based key . An example of shared secret is abcdefghijklmnop .The value can be stored as property in Application.xml file.

<Property>
<Name>secureTokenSharedSecret</Name>
<Value><![CDATA[abcdefghijklmnop]]></Value>
</Property>

<Property>
<Name>serverTokenValidatorURL</Name>
<Value>http://127.0.0.1:8080/TokenProvider/authentication/token</Value&gt;
</Property>

The values of serverTokenValidatorURL is the third party auth server listening for REST POST request .

The code for receiving the incoming  resulting json data is


	ObjectMapper mapper = new ObjectMapper();
	JsonNode node = mapper.readTree(connection.getInputStream()); 
	node = node.get("publisherToken") ;
	String token = node.asText();
        String token2 =TEA.decrypt(token, sharedSecret);

2.Third party Authentication Server

The 3rd party Auth server stores the passwords for users or performs oauth based authentication . It uses a shared secret key to decrypt the token based on TEA as explained in above section .

The code to decrypt the incoming clientId


TEA.decrypt(id, sharedSecret);

Add own custom logic to check files , databases etc for obtaining the password corresponding to the username as decrypted above.

The code to encrypt the password for the user if exists or send invalid response if non exists is


        try {

            String clientID = TEA.decrypt(id, sharedSecret);
            
            String token= findUserPassword(clientID);
            
             token = TEA.encrypt(token, sharedSecret); 
                        
            return "{\"publisherToken\":\""  + token+ "\"}";
            
        }catch (Exception ex) {

            return "{\"error\":\"Invalid Client\"}";
        }

The final callflow thus becomes :

Copy of Publisher App iOS (1)

Screenshots :

Screenshot_2015-09-16-20-22-37Screenshot_2015-09-17-18-36-23Screenshot_2015-09-16-20-22-42Screenshot_2015-09-16-20-23-30