Cybersecurity
DevOps Cloud (ADM)
IT Operations Cloud
ZENworks Handheld Management, Figuring out ConsoleOne Snapins:
Novell has had a number of tools, frameworks and what not over the years. Along the way we get told that this will be the be all, end all of tools. We had NWAdmin, a Win32 only application which was nice and quick. I still miss NWAdmin at times. But it had serious weaknesses and lack of features.
Then we had ConsoleOne, which started off pretty lousy, but as machines and Java Virtual Machines got faster, it really started to shine. This was a nice cross platform application (Cross platform at the core, and in theory. Not so much in reality when it came to snapins).
Next came iManager, a Tomcat based web application that was supposed to solve all our cross platform issues, being web based and all that jazz.
Now we are starting to see the evolution of the next approach, perhaps what we see in ZENworks Configuration Management's ZENworks Control Center. Perhaps we will see SUSE Linux's YAST expanded to handle the various things we need.
Prognostication on this type of thing is as successful as ground hogs in February.
Regardless there is a plethora of products with snapins or plugins in various formats for each of those various tools. Netmail for the longest time still required NWAdmin to administer.
Recently I was working on a ZENworks for Handhelds (Also known as ZENworks Handheld Management) project, version 7, and ran into some fun situations. The management tools are still ConsoleOne based. They have not been ported to iManager, nor have any of the ZENworks applications to be fair. Probably some day we will see ZENworks for Handhelds integrated into ZENworks Configuration Management, but not at the moment.
The thing is, I wanted to be able to use the tools that Zen for Handhelds provides via the ConsoleOne snapins, without necessarily running ConsoleOne just to launch them.
Unfortunately, like some other ConsoleOne snapins, while they should be Java based and in theory cross platform, much of the management of the Software Inventory is really still a Win32 executable. The snapins just call the executable with some parameters to run. You can tell, since you can just launch the executable on its own, and it does not connect to the database, and thus there is no data.
The kicker is, what are those parameters. But how do we figure out what to do next, to get the information we need.
Well, turns out since the ConsoleOne snapins are all Java based, it is pretty easy to decompile them and look at the Java source code. Alas there is a downside to doing this. All comments in the source code are lost, and boy would they ever be helpful for a task like this. Additionally all the variable names will be 'minified', that is basically short single letter names, because the original names are lost as they are compiled.
Again, having the real variable names would be really really helpful in figuring this out.
Step one is get the Java decompiler of your choice. I use jad.
You can read all about them at this link: http://www.faqs.org/docs/Linux-HOWTO/Java-Decompiler-HOWTO.html
Heck apparently you can even integrate the jad Java Decompiler into Eclipse! http://www.devx.com/Java/Article/22657
I was trying to find a link to download jad for this article, but I cannot find it any longer. There are lots of other ones available and the difference is probably minor between them. I had jad available on my machine left over from the time we had to look at the Vasco token plugins. We were at a client that had a couple of thousand Vasco tokens for secure logins via web portal (iChain at the front end). But they somehow lost the encrypted secrets in eDirectory and we had to find some way to get them back. By looking at the source code for the plugins we were able to find the core command that encrypted the secrets and were able to write a quick Java tool to put them all back en masse, instead of via the GUI interface and many clicks times several thousands tokens.
There is a download available for the ZENworks Handheld Managements snapins at http://download.novell.com/Download?buildid=471BGQYpWJU~
If you look in the Zip file that you download, you can get the Java files in the lib subdirectory or in the snapins directory. So store them somewhere, I used zfh\test as the output path.
The command for jad was:
jad -o zfh\test -sjava zfh/com/**/*.class
This extracts all the files it finds in the zfh directory and stores them in directories in the zfh\test subdirectory structure.
Look through the files, one by one, in this case, since it was Inventory related, I looked for files with Inventory in the name and pretty quickly found:
InventoryViewerUtil.java
If you look in the file you will see:
public static boolean execiViewer(JFrame jframe, ServiceObject serviceobject, String s, boolean flag)
{
boolean flag1 = false;
String s1 = "";
String s2 = "";
String s3 = SharedRes.getString("IVIEWER_ERROR_TITLE");
String s4 = "";
String s5 = "";
try
{
s1 = serviceobject.getDBLocation();
if(s1 == null || s1.length() <= 0)
{
s4 = SharedRes.getString("IVIEWER_ERROR_DB_LOCATION");
} else
{
s2 = serviceobject.getRemotePath();
if(s2 == null || s2.length() <= 0)
s4 = SharedRes.getString("IVIEWER_ERROR_REMOTE_PATH");
else
flag1 = true;
}
}
catch(SPIException spiexception)
{
spiexception.printStackTrace();
s4 = SharedRes.getString("IVIEWER_ERROR_SERVER_HISTORY");
}
if(flag1)
try
{
StringBuffer stringbuffer = new StringBuffer();
stringbuffer.append(System.getProperty("user.dir"));
stringbuffer.append("\\zfh\\");
stringbuffer.append("iViewer.exe");
stringbuffer.append(" \"");
stringbuffer.append("DataSourceID:");
stringbuffer.append(s1);
stringbuffer.append("\"");
stringbuffer.append(" \"");
stringbuffer.append("InstPathID:");
stringbuffer.append(s2);
stringbuffer.append("\"");
if(s != null && s.length() >= 0)
{
stringbuffer.append(" \"");
stringbuffer.append("GUIDID:");
stringbuffer.append(s);
stringbuffer.append("\"");
}
if(flag)
{
stringbuffer.append(" \"");
stringbuffer.append("ConfigureQueries:TRUE");
stringbuffer.append("\"");
}
String s6 = stringbuffer.toString();
Runtime.getRuntime().exec(s6);
}
catch(IOException ioexception)
{
ioexception.printStackTrace();
s4 = SharedRes.getString("IVIEWER_ERROR_EXEC_COMMAND");
s4 = s4 "\n";
s4 = s4 "\n";
s4 = s4 System.getProperty("user.dir");
s4 = s4 "\\zfh\\";
s4 = s4 "iViewer.exe";
flag1 = false;
}
if(!flag1)
{
NMsgBox nmsgbox = new NMsgBox(jframe, s3, s4, 3);
nmsgbox.show();
}
return flag1;
}
You can see the minified variable names, they start as s, and become s1, s2, s3, s4, s5, s6 and so on.
Here is where the real variable names would be really helpful. I am sure in the original source code s6 is very meaningful, like StartInventoryString or some such. But the good news is that the code is relatively readable, and you can see that the command Runtime.getRuntime().exec(s6); is probably the line that calls the command.
You can see in the line:
stringbuffer.append("iViewer.exe");
that it calls the executable iViewer.exe which is in the bin\zfh directory.
stringbuffer.append(" \"");
then it appends a quote mark (") but it needs to escape the quote as \" because the quote is itself enclosed in quotes.
stringbuffer.append("DataSourceID:");
Next we have the literal string DataSourceID:
stringbuffer.append(s1);
Then the value of s1, hmm, wonder what that could be, lets come back to that in a moment
stringbuffer.append("\"");
another quotation mark escaped as \"
stringbuffer.append(" \"");
a space and another quote (escaped as \" again)
stringbuffer.append("InstPathID:");
the literal string InstPathID:
stringbuffer.append(s2);
whatever is in the variable s2
stringbuffer.append("\"");
and another close quote mark, escaped as always.
So that looks something like:
iViewer.exe "DataSourceID:s1" "InstPathID:s2"
Thus all we need to do now is figure out what s1 and s2 should be.
Looking earlier in the code we see:
s1 = serviceobject.getDBLocation();
s2 = serviceobject.getRemotePath();
s1 is something to do with the Database location, and s2 is something to do with the remote path. Looking at the snapins in ConsoleOne we can see there are two values in the snapin that look interesting. One has to do with the Database, and looks like {SQL Server} ACMEZFHAPP\ZFHDevices in the snapin.
Then there is the path to the ZENworks files as well, which looks something like: \\acmezfhapp\zfh Those seem pretty darn likely to be the values we are looking for.
The end results would therefore look something like this:
iViewer.exe "DataSourceID:{SQL Server} ACMEZFHAPP\ZFHDevices" "InstPathID:\\acmezfhapp\zfh"
Well that was not too bad! I made a shortcut on the desktop with the above string as the target, and now I can start the ZENworks Handheld Management Inventory tool without needing to launch ConsoleOne. I still need much of the install for ConsoleOne (or at least the ZENworks Handheld Management snapins) but I do not need to actually launch it.
If you have more than one server in your system you would of course have to change the variables involved to match the server you are interested in controlling.
The nice thing about this approach is you can look at other ConsoleOne snapins and see what there is too see. Often there is something of interest involved in the magic it is doing in the background for you.