How to run a Google Glass app in Infor Grid

Today I will detail the steps to run a Google Glass app in Infor Grid. This is part of my project to have M3 Picking Lists in Google Glass.
glass

For that, I will develop a very simple Glassware using the Google Mirror API Java Quick Start Project, and I will use the technique I learned in Hacking Infor Grid application development. The integration will be bi-directional: the Grid app will communicate to the Glass API on Google’s servers to insert cards in the timeline, and conversely when the user replies to a timeline card Google’s servers will send notifications to the Grid app provided it is located at a routable address with a valid SSL certificate.

This is a great demo of the integration capabilities of the Infor Grid. I worked a little bit here and there on evenings and week-ends over several months, and I distilled the resulting steps here and in a 15mn video so you can play along. You will need a pair of Google Glass.

STEP 1: Setup Eclipse with Maven

I will start with the instructions for the Google Mirror API Java Quick Start Project:
step1a

For the Prerequisites I need Java 1.6 and Apache Maven for the build process. I will download Eclipse IDE for Java Developers that has the Maven plugin integrated:step1

STEP 2: Setup the Glass Mirror API Java Quick Start Project

Then, I will download the Glass Mirror API Java Quick Start Project from the GitHub repository:
step2.1

Then, I will import it in Eclipse as an Existing Maven Project with the pom.xml:
step2.2

I will import the Infor Grid library grid-core.jar:
step2.3

Then, I will replace some of the source code to adapt it to the Infor Grid, using Eclipse File Search and Replace:
step2.4

I will replace the code for the Logger in all files (from/to):

import java.util.logging.Logger;
import com.lawson.grid.util.logging.GridLogger;
Logger LOG = Logger.getLogger
GridLogger LOG = GridLogger.getLogger
LOG.severe
LOG.error
LOG.fine
LOG.info
LOG.warning
LOG.warn

Then, I will add the context path to the URLs of all files (from/to):

href="/
href="
src="/static
src="static
url.setRawPath(
url.setRawPath(req.getContextPath() +
RegEx:
(getRequestURI\(\).*\()"/
$1httpRequest.getContextPath() + "/

For the subscription to notifications I will replace the callback URL in NewUserBootstrapper.java by a routable FQDN or IP address with a valid SSL certificate to handle the notification:

Subscription subscription = MirrorClient.insertSubscription(credential, WebUtil.buildUrl(req, "/notify").replace("m3app-2013.company.net", "11.22.33.44"), userId, "timeline");

Then, I will replace the code in NotifyServlet.java that processes the notification from the HTTP request body because apparently notificationReader.ready() always returns false in the Infor Grid and that throws IllegalArgumentException: no JSON input found. Here is the new code:

int lines = 0;
String line;
while ((line = notificationReader.readLine()) != null) {
	notificationString += line;
	...
}
notificationReader.close();

Then, I will setup the Project in the Google Developers Console with the Google Mirror API, the client ID and client secret credentials for OAuth 2.0, and the Consent screen:
step2.5a step2.5b step2.5c

Then, I will paste the client ID and secret in the oauth.properties of the project:
step2.6

Then, I will create and run a new Maven Build Configuration using goal war:war:
step2.7a

That will create a WAR file that I will use to deploy as a web application in my Grid application:
step2.7b

STEP 3: Setup the Infor Grid application

Then, create and install an Infor Grid application GoogleGlass based on the HelloWorld app:
step3.2b_i step3.2b_ii step3.2b_iii step3.2b_iv

STEP 4: Test

Then, launch the app:
step4.1a

Authenticate to the Google account associated with Glass, and click Accept to grant app permissions:
step4.1b

Use the app, insert cards in the timeline:
step4.2step4.5

You can also tap Glass to reply to a timecard:
step4.8

And the Grid app will receive the notification with a JSON string:
step4.12

Resulting video

Here is the video with hours of work distilled in 15mn (I recommend watching in full screen, HD, and 2x speed):

STEP 5: Summary

That was how to run a Google Glass app in Infor Grid. The main steps are:

  1. Setup Eclipse with Maven
  2. Setup the Glass Mirror API Quick Start Java project
  3. Setup the Infor Grid application
  4. Test

The integration is bi-directional: the Grid app adds cards to the Glass timeline, and when the user takes action on a card Google’s servers send a JSON notification to the Grid app.

The result is great to demo the integration capabilities of the Infor Grid, and it will be useful for my project to show M3 picking lists in Glass.

Future work

In future work, I will use the bi-directional communication for pickers in a warehouse to tap Glass to confirm picking lists, have Google’s servers send the JSON notification to the Grid app, and have the Grid app call an M3 API MHS850MI AddCOPick and AddCfmPickList to confirm picking.

That’s it. If you liked this, please give it a thumbs up, leave your comments, share around you, and contribute back by writing your own ideas. Thank you.

Hacking Infor Grid application development (part 5)

Here is the fifth part in the series Hacking Infor Grid application development. This time I will show you how to deploy a web application archive, WAR file. It is trivial and quick as the Infor Grid automatically deploys it.

Create the archive

Simply ZIP the contents of the web application into a WAR file:
1

File & folder structure

Move the WAR file into the webapps folder of the Grid application, and delete the rest of the webapps content (WEB-INF, JSP, etc.) so that there is only the WAR file left:

[...]
|
\---webapps
        HelloWorld.war

Deploy

Create the Grid application archive GAR and deploy it in the Grid as usual. The Infor Grid will automatically deploy the WAR file under webapps:
2

GitHub

I updated the GitHub repository with a Tag for part5.

Petition

Remember to join the campaign in asking Infor Product Development to release their Grid Development Tools and tutorials and to make their source code available so we can learn how to make good Grid applications.

Meanwhile, remember this is a hack with the intention to learn and progress.

Hacking Infor Grid application development (part 4)

Continuing the series Hacking Infor Grid application development, today I will show: how to decompile Java applications, how to write to the Grid application log files, how to read Grid application properties, how to secure the Java web application, and how to start playing with the HelloWorld app on GitHub. Remember this is currently a hack, it is at your own risk, there are limitations as discussed on part 1, and please join the campaign and sign the petition to Infor Product Development for making their source code available. The intention is to learn the internals of the applications we use every day, push their limits, and develop great software.

Decompile Java applications

First of all, check your licenses to determine if you are legally allowed to decompile the Java application you have in mind.

For this series I decompiled the Infor Grid core grid-core-1.11.27.jar to understand how to write to the Grid application log files and how to get Grid application properties. I also often decompile applications like M3_UI_Adapter (MNE), Event Hub, M3 Web Services, and Infor Process Automation to understand how they work, make enhancements, troubleshoot, and find bugs. All the JAR files are located in LifeCycle Manager at E:\Infor\LifeCycle\<host>\grid\<grid>\grids\<grid>\applications\. It is already common practice to decompile Infor Smart Office with RedGate Reflector (C#) to push the limits of Smart Office scripts and Smart Office SDK applications. I wish the source code of all applications were available.

For decompiling Java applications, I use the great Java Decompiler and its GUI. I simply drag and drop a JAR file and it automatically decompiles all files recursively:
1

Write to Grid application log files

To write to the Grid application log files, get the logger and log at the information, warning, error, debug, or trace levels:

import com.lawson.grid.util.logging.GridLogger;
[...]
private static final GridLogger log = GridLogger.getLogger(HelloWorld.class);
[...]
log.info("Yay, I'm writing to the log file :)");
log.warn("Hey, it feels hot in here!");
log.error("Ouch, that hurt :(");
log.debug("Useful data 48656C6C6F576F726C64");
log.trace("Wooohooo 01001000 01100101 01101100 01101100 01101111 00100000 01010111 01101111 01110010 01101100 01100100 00100001");

Set the log levels accordingly:

Check the result in the Grid application log file:
3

The log files are also directly in the log folder for use with a tail program or so:
5

Read Grid application properties

Declare Grid application properties in the application deployment descriptor GRID-INF\application.xml:

<property name="message">Hello Wrrrld!</property>

6

Then, read the properties with:

import com.lawson.grid.node.properties.GridProperties;
[...]
GridProperties p = ModuleContext.getCurrent().getProperties();
String message = p.getProperty("message");
log.info("The message is: " + message);

Re-deploy the application and check the application properties:
7

And here is the result:
4

Secure Java web application

To secure the Java web application in WEB-INF\web.xml:

<security-constraint>
    <web-resource-collection>
        <url-pattern>/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <role-name>grid-user</role-name>
    </auth-constraint>
</security-constraint>

Set the User and Role Mappings in the Grid Configuration Manager accordingly:8

Restart the application.

The Grid will now challenge for authentication:
9

HelloWorld app on GitHub

I published the HelloWorld Grid application source code on my GitHub repository so you can play along, learn, and contribute your code, and I added tags – part1, part2, part3, and part4 – so you can download the source code that corresponds to the desired part in this series:
10

Summary

That was an illustration of how to decompile Java applications, how to write to the Grid application log files, read Grid application properties, secure the Java web application, and start playing with the HelloWorld app on GitHub. Remember to play responsibly, know the limitations, sign the petition, and contribute your findings to the community.

That’s it! If you liked this, please click Like, write your comments, click Follow to subscribe to the blog, share around you, and author your own ideas. Thank you.

Hacking Infor Grid application development (part 3)

In the series Hacking Infor Grid application development, today I will illustrate how to add a JAR file to an Infor Grid application and a JAR file to a dynamic web application in that Grid application (which is trivial).

JAR for Grid application

First, create a simple Java library:

package net.company.your.library1;

public class HelloWorldLibrary1 {
	public static String getMessage() {
		return "Hello World sample library for my Grid application";
	}
}

Then, compile it with:

javac net\company\your\library1\HelloWorldLibrary1.java

Then, add it to a JAR file with:

jar cvf HelloWorldLibrary1.jar net\company\your\library\HelloWorldLibrary1.class

Then, call that library from the Grid application with:

[...]

import net.company.your.library1.*;

public class HelloWorld implements ApplicationEntryPointEx {

	public boolean startModule(ModuleContext paramModuleContext) {
		System.out.println(HelloWorldLibrary1.getMessage());
		return true;
	}

	[...]
}

Then, recompile that Grid application as usual with:

javac -cp grid-core-1.11.27.jar;. net\company\your\HelloWorld.java

Here’s the result in the command prompt:
1.1

Then, create a jars folder in the Grid application and add the JAR file to it:
1.3

The default folder for JAR files is jars. It seems other Infor Grid applications use folder lib instead. We can change the classpath in the Grid application’s properties, for instance the application M3UIAdapter has JAR files in a folder lib:
3.2b

Then, replace the Grid application:
1.2

Then, restart the Module in the Grid Management Pages:
b4

We can see the result in the logs:
1.4

JAR for dynamic web application

Now let’s create a second Java library for the dynamic web application of the Grid application; this is classic J2EE and trivial:

package net.company.your.library2;

public class HelloWorldLibrary2 {
	public static String getMessage() {
		return "Hello World sample library for my dynamic web application";
	}
}

Then, compile it and add it to a JAR file as shown above.

Then, let’s use that library from the servlet (or from a JSP):

[...]

import net.company.your.library2.*;

public class HelloWorldServlet extends HttpServlet {
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		[...]
		out.println(HelloWorldLibrary2.getMessage());
	}
}

Then, recompile the servlet as usual.

Here’s the result in the command prompt:
2.1

Then, create a lib folder in the WEB-INF folder of the dynamic web application:
2.3

Then, replace the servlet (or JSP):
2.2

And refresh the servlet (or JSP) to see the result:
2.4

Summary

That was how to add a JAR file to an Infor Grid application and a JAR file to a dynamic web application in that Grid application (which was trivial). Next time I will find out how to add a WAR file.

Also, remember this is a hack that currently has limitations due to our lack of knowledge of how to develop good applications for the Infor Grid, as discussed in part 1 of this series.

Also, remember to join the campaign and sign the petition to Infor Product Development for making their source code available.

That’s it! If you like this, please click the Like button, leave a comment below, subscribe to this blog, share around you, and write about your own ideas here. Thank you.

Hacking Infor Grid application development (part 2)

As a prolongation of my previous post on Hacking Infor Grid application development, this time I will show you how to add a simple HelloWorld servlet to your Infor Grid application.

HelloWorld servlet

Create a simple HelloWorld servlet:

package net.company.your;

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class HelloWorldServlet extends HttpServlet {
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html");
		PrintWriter out = response.getWriter();
		out.println("<html>");
		out.println("<body>");
		out.println("HelloWorld servlet! The time is " + new Date());
		out.println("</body>");
		out.println("</html>");
	}
}

Compile it with the Servlet API library that you can find in the LifeCycle Manager runtime:

E:\LifeCycle\<host>\grid\<grid>\runtimes\1.11.27\resources\servlet-api-2.5.jar
javac -cp servlet-api-2.5.jar WEB-INF\classes\net\company\your\HelloWorldServlet.java

1 2

Deployment descriptor

Create a simple deployment descriptor web.xml:

<?xml version="1.0" encoding="utf-8" ?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
	version="2.4">

	<display-name>HelloWorld Servlet</display-name>
	<description>My HelloWorld servlet</description>

	<servlet>
		<servlet-name>HelloWorldServlet</servlet-name>
		<servlet-class>net.company.your.HelloWorldServlet</servlet-class>
	</servlet>

	<servlet-mapping>
		<servlet-name>HelloWorldServlet</servlet-name>
		<url-pattern>/sup</url-pattern>
	</servlet-mapping>

</web-app>

File & folder structure

Set the following file & folder structure in a WEB-INF directory:

\---HelloWorld
    ...
    \---webapps
        \---HelloWorld
            ...
            \---WEB-INF
                |   web.xml
                |
                \---classes
                    \---net
                        \---company
                            \---your
                                    HelloWorldServlet.class

b3

With Eclipse

You can also use Eclipse to create the servlet and deployment descriptor and to compile:
e8

Deploy

You can create and deploy your servlet as a new application, or you can add WEB-INF to an existing application in LifeCycle Manager at:

E:\LifeCycle\<host>\grid\<grid>\grids\<grid>\applications\HelloWorld\webapps\HelloWorld\WEB-INF\

If you choose hot deployment, reload the Grid application module:

b4

 

 

Result

You can now test the result in a browser:
b5

And you can check the logs:
b6

Summary

That was how to add a simple servlet to your Infor Grid application. Next time, I will explore how to add JAR files and how to deploy a WAR file.

That’s it! Like + comment + subscribe + share.

Hacking Infor Grid application development

I just learned a technique to develop a custom application for the Infor Grid. The idea is to build a simple J2EE app using the Infor Grid as an application server. My understanding is that the Infor Grid is closed, and that this technique is currently unofficial, undocumented and unsupported. I will label this technique as a hack for now until we establish a recommended path.

History

In the past, official products such as Movex Workplace (MWP) and IBrix were built for IBM WebSphere Application Server (WAS), and software developers that needed custom J2EE applications unofficially deployed their code in that same WAS; it was a somewhat symbiotic relationship. With the switch to the Infor Grid, WAS is gone and replaced by a cloud of distributed servers with embedded Jetty – that is a leap forward for M3 – but there is no official solution for custom apps.

As a workaround, we continued to sideload our JSP and HTML files in the MNE folder of the Grid alongside Smart Office Scripts; that was a parasitic relationship subject to potential loss during upgrades. There is also the option to install our own separate application server like Microsoft IIS, but there are advantages to having a unified solution. I know of the Grid Development Tools for Eclipse and the Grid Application Developer Guide and tutorials, but to my knowledge they are internal to Infor products and not available for developing custom applications.

A former colleague of mine found an alternative workaround. He told me he had managed to create a GAR file for the Infor Grid, so now he has an application called “intentia” where he puts the JSP and HTML files instead of the MNE folder. He said it involved decompiling one of the Grid applications and then compiling it back with the new application name. I invited him to write a blog post about his solution, but he responded because it is unofficial he did not want to post it and wanted to remain anonymous. After a couple of email exchanges discussing a disclaimer, he accepted that I post his solution and acknowledge him for his contribution. So thank you, Jonathan Amiran of Intentia Israel.

Call for action

This is my call to Infor Product Development. If you are reading this, please jailbreak the Grid, release the tools and documentation and embrace the community. Help us reach a mutually beneficial relationship where great ideas can get out of anonymity and flourish. I understand there are risks involved in opening up a sensitive system to all sorts of inexperienced developers and misuse as that leads to you having to assume the role of support and troubleshooting until you can prove negligence on the part of the third-party developer. But don’t be closed. Share the good practices with us, certify us, or if it’s a risk, build a system that defends against byzantine failures from third-party developers.

For you readers, please call your Infor representatives and tell them the importance of being open and working together. Meanwhile, please understand the following hack has not yet been peer reviewed so it may be either favorable or damaging.

Find the Grid core

First, go to your LifeCycle Manager server and find the JAR file for the Grid core:

E:\LifeCycle\<host>\grid\<grid>\resources\grid-core-1.11.27.jar

b1

Create the application entry point

Then, create a simple Java class that implements ApplicationEntryPointEx:

package net.company.your;

import com.lawson.grid.node.application.ApplicationEntryPointEx;
import com.lawson.grid.node.application.ApplicationEntryPointEx.GlobalState;
import com.lawson.grid.node.application.ApplicationEntryPointEx.RemainingTaskCount;
import com.lawson.grid.node.application.ModuleContext;

public class HelloWorld implements ApplicationEntryPointEx {

	private boolean isInitialized = false;

	public boolean startModule(ModuleContext paramModuleContext) {
		return true;
	}

	public void onlineNotification() {
		this.isInitialized = true;
	}

	public void offlineNotification() {
		this.isInitialized = false;
	}

	public void stopModule() {
		this.isInitialized = false;
	}

	public ApplicationEntryPointEx.RemainingTaskCount getRemainingTaskCount() {
		return null;
	}

	public ApplicationEntryPointEx.GlobalState getGlobalState() {
		if (this.isInitialized) {
			return new ApplicationEntryPointEx.GlobalState(true, new String[] { "OK" });
		}
		return new ApplicationEntryPointEx.GlobalState(false, new String[] { "Initalizing" });
	}
}

And compile it with:

javac -cp grid-core-1.11.27.jar net\company\your\HelloWorld.java

Create the application deployment descriptor

Create the application deployment descriptor in a file GRID-INF\application.xml:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<application xmlns="http://schemas.lawson.com/grid/configuration_v3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" typeName="HelloWorld" version="10.1.0.1" xsi:schemaLocation="http://schemas.lawson.com/grid/configuration_v3 http://schemas.lawson.com/grid/configuration_v3">
	<description>HelloWorld Grid Example</description>
	<moduleDefinitions>
		<moduleDefinition typeName="HelloWorld" entryPointClass="net.company.your.HelloWorld" horizontallyScalable="false" verticallyScalable="false">
			<webApp name="HelloWorld" distributedSessions="false" sessionAffinity="true" />
		</moduleDefinition>
	</moduleDefinitions>
	<nodeTypes>
		<nodeType name="HelloWorld">
			<module typeName="HelloWorld" />
		</nodeType>
	</nodeTypes>
	<connectionDispatchers/>
	<properties>
		<propertyList name="grid.module.classpath">
			<value>classes</value>
			<value>jars/*</value>
		</propertyList>
		<property name="grid.jvm.maxHeapMB">64</property>
	</properties>
</application>

Add the resources

Add the static (HTML, images, CSS, JavaScript, etc.) and dynamic (JSP) resources in a webapps sub-folder, for example index.jsp:

<%@ page import="java.util.*" %>
<!DOCTYPE html>
<html>
   <body>Hello World! This is my first Grid application. The time is <%=new Date()%></body>
</html>

With the Infor Grid we don’t have a web server plugin to optimize serving static from dynamic content by URL path so I keep everything in the same folder.

Zip to a Grid archive

Create a file and folder structure like so:

+---classes
|   \---net
|       \---company
|           \---your
|                   HelloWorld.class
|
+---GRID-INF
|       application.xml
|
\---webapps
    \---HelloWorld
            image.png
            index.jsp
            script.js
            static.html
            style.css

ZIP the contents of the folder into a file and rename the file extension to .gar (make sure to ZIP the contents of the folder and not the folder itself or you will end up with an incorrect folder structure):

b1_

With Eclipse

You can also use Eclipse for this.

For that, create a new Java project, change the Default output folder from /bin to /classes, and add the grid-core as an external JAR:
b2

Create the file and folder structure as explained above:
b3_

ZIP the entire contents of the folder and change the file extension to .gar as explained above:
b4

Install the application

  1. Go to the Grid Management PagesAdvancedConfigurationConfiguration ManagerApplications and select Install New Application:
    b5
  2. Click Upload, browse to your GAR file, and click Upload:
    b6
  3. Select the hosts on which to deploy the app and click Finish:
    b7
  4. It will say “Operation completed.” Click Close:
    b8
  5. It will say “The application has no bindings defined”. Select Fix this problem:
    b9
  6. Enter Min 1 and Initial 1 and click Add Binding:
    b10
  7. It will say “The web application ‘HelloWorld’ of module ‘HelloWorld’ has no context root defined”. Select Fix this problem:
    b11
  8. Enter a Context Root Name and click Add:
    b12
  9. It will say “There are unsaved changes”. Click Save:
    b13
  10. Click Save to confirm the changes:
    b14
  11. The application is now deployed on the Infor Grid:
    b15

Result

Now we can try the application by going to /HelloWorld/:
18

My understanding of the Infor Grid is that applications run in a node, and that a node runs in its own JVM (probably to avoid collateral damage if the app crashes). We can confirm this by finding our app in the server’s Windows Task Manager:
b16

 

Updates

[UPDATED 2014-07-24]

At this point, you can update your files (JSP, HTML, JavaScript, etc) directly in the LifeCycle Manager deployment folder, refresh the browser, and the server will serve the new version of your files. This is the same type of updates we do with Smart Office scripts. If you do this, remember to backup your changes.

E:\LifeCycle\<host>\grid\<grid>\grids\<grid>\applications\HelloWorld\webapps\HelloWorld\

Limitations

Because of the distributed topology, fault tolerant, load balanced, scalable, and redundant nature of the Infor Grid, it is our responsibility as grid application developers to design them correctly. But we don’t yet know how to do that on the Infor Grid. Remember to call Infor about that. So keep it simple for now:

  • Make the application stateless until we find out how to store and share and synchronize state and make distributed sessions on the Grid.
  • Don’t make direct connections to any servers with network sockets until we find out how to abstract the communication with the Grid routers.
  • Don’t change any shared resources anywhere to avoid race conditions until we find out how to run critical sections on the Grid.
  • Don’t expect to do parallel programming since we don’t yet know how to communicate with multiple instances of the application.
  • Don’t persist data on disk as we don’t yet know how to abstract storage for failover and redundancy.

Summary

This was a hack to start developing simple applications on the Infor Grid. This technique is unofficial, undocumented and unsupported. It is our responsibility as developers to design applications correctly. Ask Infor to open up and support us.

That’s it! If you liked this, thank Jonathan, click Like, leave your comments below, subscribe to this blog, share with your peers, ask Infor to be open and embrace the community, and be responsible with your code. Thank YOU.

How to decrypt network traffic from Infor Grid

Here is a technique to intercept and decrypt the TLS (HTTPS) network traffic from the Infor Grid using Wireshark and the server’s private keys.

Why does it matter?

This technique is useful for troubleshooting products like M3 Web Services (MWS) and Infor Process Automation (IPA) which don’t log the HTTP requests and responses in their entirety. For instance, MWS Runtime can optionally dump the SOAP requests and SOAP responses but misses the HTTP request headers and HTTP response headers, and IPA only logs the HTTP response body but misses the HTTP request’s header and body and the HTTP response header, and neither MWS nor IPA let us hook to a proxy such as Fiddler. Sometimes it’s necessary to troubleshoot the HTTP requests and responses in their entirety. For example, I’m currently troubleshooting for a customer the case of a rogue white space somewhere in a request that’s throwing a syntax error down stream in a parser, and I need to chase the bug down by analyzing the hexadecimal values of the bytes, and for that I need un-encrypted traffic.

We could use Wireshark to intercept all network packets but if the traffic is encrypted with TLS (HTTPS) it’s unreadable. In public-key cryptography, a client and server initiate a TLS connection using asymmetric cryptography, and then switch to symmetric cryptography for the rest of the session. Fortunately, the Wireshark SSL dissector can decrypt traffic if we give it the server’s private keys. I had previously showed this technique a long time ago to decrypt Lawson Smart Office traffic and more recently to intercept un-encrypted IPA traffic. This time I update the technique for encrypted traffic of the Infor Grid.

Don’t get exited about hacking and don’t freak out about security because this technique is only available for those administrators that have access to the servers private keys and passwords.

Server’s private keys and passwords

First, we will need to find the Infor Grid’s private keys and passwords. I don’t do Grid installations so I don’t know where the keys are stored (if in the same path on any Grid, or if at a path defined by the installer), nor how the keys are generated (if automatically by the Grid, or if manually by the installer). In my case, I was testing on two different Grids and I found the keys in LifeCycle Manager (LCM) server at these two different paths:

D:\Infor\LifeCycle\<host>\grid\<grid>\grids\<grid>\secure\
E:\Infor\LifeCycle Manager\LCM-Server\grid\<grid>\keyStore\

This non-consistency tells me the path is defined by the installer.

Here is a screenshot:
b1

The paths contain many files of type *.ks and *.pw. The KS file type is a keystore encrypted with a password. The PW file type is the password in clear text; it looks encrypted but it’s just long random clear text. In my second Grid, there were about 50 pairs of files where the file names seem to follow a specific naming convention. That tells me the keys and passwords are generated automatically by the Grid.

Export and convert the private key

Now that we have the keystores and the passwords, we need to export the private key from the keystore and convert it to a format supported by Wireshark. For that, we can use the keytool of the JRE to export and OpenSSL to convert, or use KeyStore Explorer that will both export and convert.

Here’s with the keytool (export to PKCS12) and OpenSSL (convert to PEM):

keytool -importkeystore -srckeystore mykeystore.ks -destkeystore myexportedkey.p12 -deststoretype PKCS12
openssl pkcs12 -in myexportedkey.p12 -out myexportedkey.pem -nocerts -nodes -passin file:mykeystore.pw

b2

And here’s with the KeyStore Explorer (directly to PEM):
b3

Now we have a file with —–BEGIN PRIVATE KEY—–:
7

Import the private key in Wireshark

Now we import the key in Wireshark > Edit > Preferences > Protocols > SSL and set the Infor Grid server’s IP address, port and private key (PEM):
b4

Intercept and decrypt traffic

Now we are ready to intercept and decrypt traffic, for example we can go to the Grid Management Pages with HTTPS:
b5

Then we filter for ssl, see the decrypted traffic, the key exchange, and Follow SSL Stream:
b6

Summary

That was a technique to intercept and decrypt network traffic of the Infor Grid using Wireshark and the server’s private keys which is useful for troubleshooting purposes. This technique is only available to the administrators that have access to the servers.

If you know of a simpler technique please let me know.

That’s it. Please like, comment, subscribe, share. Thank you.