Wednesday, August 24, 2011

HowTo: Set up JInput API and Library for Java Development on Mac OS X or Linux Platform

Yod (August 24, 2011)

I came back from 2011 AUVSI convention (hosted in Washington DC) and found a lot of controllers for the unmanned vehicles to be very similar to the PC or console game controllers (read Real War Games: Video Game Controllers Hit the Battlefield). So, I decided to experiment with Logitech Dual Action Game Controller by using it as an optional controller to navigate my map/navigational tracking application that I wrote using Java on Mac OS X platform.

It took me couple of hours going through several game controller API for Java. After testing out 3 APIs, I decided to stick with JInput due to its stable development support (but poor documentation). It took me 20-30 minutes to figure out how to set JInput and write simple code to test my logitech controller, because the website provides very little information.






























Setting up JInput API

First, download the nightly build API from http://java.net/projects/jinput/downloads

Then follow the 3 simple steps below:

1. set up classpath (e.g. /Users/Yod/Library)
2. move jinput.jar and jinput_test.jar into the directory pointed to by classpath
3. extract the jar file jinput.jar and jinput_test.jar
There should be a net/ directory inside the classpath (e.g. /Users/Yod/Library/net)

Note for developers using Eclipse IDE:
Add the API jar files (jinput and jinput_test) to your project
1. Click [project (top bar)] --> select [properties] --> click [Java Build Path]
2. Click [Add External JARs...] and browse to the directory containing the jar files
3. Select the jar file and click [Open]
4. Click [Ok], when you're done.

You should now be able to compile your java source code using Eclipse IDE. However, you still cannot run the application until you set up the link to the library. If you run the app, you will encounter a Link Error similar to the one below.

[JInput LinkError in Apple OSX development environment]
JInput version: 2.0.6-b1241
java.lang.UnsatisfiedLinkError: no jinput-osx in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1758)
at java.lang.Runtime.loadLibrary0(Runtime.java:823)
at java.lang.System.loadLibrary(System.java:1045)
at net.java.games.input.OSXEnvironmentPlugin$1.run(OSXEnvironmentPlugin.java:78)
at java.security.AccessController.doPrivileged(Native Method)
at net.java.games.input.OSXEnvironmentPlugin.loadLibrary(OSXEnvironmentPlugin.java:70)
at net.java.games.input.OSXEnvironmentPlugin.(OSXEnvironmentPlugin.java:110)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:169)
at net.java.games.input.DefaultControllerEnvironment.getControllers(DefaultControllerEnvironment.java:159)
at USBControllerTest.main(USBControllerTest.java:8)
[Timestamp] net.java.games.input.ControllerEnvironment log
INFO: net.java.games.input.OSXEnvironmentPlugin is not supported

5. To set up the link, simply put "libjinput-osx.jnilib" file in the application working directory, which is the same location of your main app class file. This will allow you to run the code from CLI. However to run the code from Eclipse, you'll need to link the native jinput osx library to your Eclipse project.

Click [project (top bar)] -->select [properties]
In the middle of the window, "JARS and class folders on the build path:"
- Click [JRE System Library] --> click "Native Library Location" --> click "Edit..."
- Browse to the directory that contains "libjinput-osx.jnilib" file and click [Ok]








Source Code (To Test the USB Game Controller)

import net.java.games.input.*;

public class USBControllerTest {

public static void main(String[] args) {
System.out.println("JInput version: " + Version.getVersion());
ControllerEnvironment ce = ControllerEnvironment.getDefaultEnvironment();
Controller[] cs = ce.getControllers();
for (int i = 0; i < cs.length; i++)
System.out.println(i + ". " + cs[i].getName() + ", " + cs[i].getType() );
}

}

Output

macOSX:bin yod$ java USBControllerTest

JInput version: 2.0.6-b1241
0. Apple Internal Keyboard / Trackpad, Keyboard
1. Apple Internal Keyboard / Trackpad, Mouse
2. Apple Internal Keyboard / Trackpad, Mouse
3. Logitech Dual Action, Stick
4. PS/2+USB Mouse, Mouse


Tuesday, August 23, 2011

How to Delete All Your Gmail Messages in Your Inbox

Yod (Aug 23, 2011)

I need to reclaim my Gmail account, because my Android phone (contact info, etc.) ties to this account. In addition, I don't want to create another Gmail account.

Since I have over 30K+ messages in my Gmail account (see figure 1), there is no way that I'm going to manually delete 50 messages per page and do it on a page by page basis. This will take me months to clean out my inbox.

Luckily, there are 2 other options. Option 1 is to write a short Java program using Gmail API to clean out my inbox. Fortunately, I don't need any sorting done. I just want is to delete everything, so writing a program is not really necessary. Option 2 is to create Gmail filter, which will only take me 2-3 minutes to do. I went with option 2, which was extremely easy and does exactly what I needed. Follow the process below and you can clean out any bulk emails in your inbox.











Figure 1

The process below creates 2 filters (remove both read and unread messages into trash bin). It should take no more than 5 minutes to perform the steps below.

Step 1: Create filter to remove your read email
Click on the "Create Filter" link next to [Search Mail] text box











Step 2: Create filter for all read emails
Type "is:read" in the [Has the words] text box











Step 3: Click [Next step] under the filter criteria.
Then click [Ok] when the pop window appears.










Step 4: Select where you want to move your read email.
If you want to move it into trash can, select [Delete it] check box, then check the "Apply filter to ### conversation below" box, and then click [Create filter] to finish creating a filter.

Depending on the amount of messages you have, this could take from a few seconds to several minutes. Once done, all your read email messages should now appear in your email trash.














Step 5: If you also want to remove all unread email, repeat Step 1-4.
Type "is:unread" for step 2.

You should have these 2 filters.









Step 6: Delete these 2 filters.
If you don't delete these filters, all your future email will automatically go into your email trash.


Now that you reclaim your Gmail account, you should look at any new email and decide if you want to continue receiving them or stop them by either cancel the email subscription or create filter to have them automatically go into a specific label.

Friday, February 25, 2011

Providing Value to Your Customers Not Bullshit!

My drive home from work is typically listening to either Stanford's Entrepreneur Corner (EC) podcast (on my USB memory stick), Success Magazine's CD, or National Public Radio (NPR). As I continue driving home on the freeway in my little hybrid vehicle, I heard something about stop focusing on money but instead focus on value. Rather than thinking about how much money my startup company will bring, think about the value my startup will provide to my customers. And what my customers are willing to pay for it. Instead of thinking about how much I should be getting pay for my current position, think about what value I bring to my employer. What does my employer willing to pay for the value I bring to the table? After 30 minutes into this audio CD about value from Success Magazine's CD, I realized that customer is everything! Customer is the key to success. Give the customers (my employers, people that use my products) what they want with the best of my ability and nothing else really matter. My value speaks for itself and that should be the baseline for my compensation. By giving your customer your very best, your customers will appreciate you for it and should be willing to compensate your hard work. It is your duty to maintain this high standard of workmanship and quality of products you delivered. If you fail to maintain the consistency, your customers could and most likely will turn on you by either give you bad rating and leave you for some one else better.

Friday, February 20, 2009

mcrypt tool - part 1 - the installation

I was searching on the Internet for an encryption/decryption tool that will work with PHP and ran into mcrypt tool (http://mcrypt.sourceforge.net/). Being that this tool can be run from command line interface (CLI), I can call it from PHP, Java, PERL, shell or any languages that will allow me to do a system call. And because of that I'm really excited and started doing more reading on mcrypt. But reading alone is no fun. I have to try this tool out myself and see how good it really is. I downloaded the source code and build the executable on my development workstation, which has Linux OE (OpenSuSE). Below is the configuration/installation note I wrote down while doing mcrypt installation.

Installation Note:
1. Download mcrypt and libmcrypt from http://sourceforge.net/projects/mcrypt. The mcrypt requires libmcrypt, so get both source.

2. Build the libmcrypt (which comes in a source code format) using the standard build tool: configure, make, make test, make install, make clean. I didn't get any error during this build. Next step is to check the path link to libmcrypt. A simple whereis shows me that libmcrypt is in /usr/local/lib directory.

3. Next build the mcrypt tool (which also comes in a source code format). This part is a bit tricky, since you need to tell configure in mcrypt where to look for libmcrypt. Below is the entire processes I went through to install mcrypt. Which took me from midnight to about 1AM in the morning.

Installing mcrypt function for later encryption decryption project.

Run the following command in mcrypt directory.

./configure --with-libmcrypt-prefix=/usr/local

First attempt, fail.

The 1st issue was linking the LD_LIBRARY_PATH to libmcrypt (which was installed right before mcrypt), so that the configure in mcrypt can find it. To fixed the problem, simply add /usr/local/lib to /etc/ld.so.conf file, since the default lib directory for libmcrypt is /usr/local/lib.

The second attempt at installing the mcrypt resulted in ...

Again... failure. Another error appears: "You need at least libmhash 0.8.15 to compile this program. http://mhash.sf.net/"
So I went to http://mhash.sourceforge.net/ and download the source code and compile them on my Linux box using the standard procedure configure, make, make check, make install, and make clean. Then I do a whereis for libmhash to ensure it's successfully installed, which shows it's successfully installed at /usr/local/lib. One great feature about the libmhash is the large cryptography algorithm supported, which shows during the make check portion (see snippet):

testing CRC32 .
testing CRC32B .
testing MD5 .......
testing SHA1 ...
testing HAVAL256 ..
testing HAVAL224 .
testing HAVAL192 .
testing HAVAL160 .
testing HAVAL128 .
testing RIPEMD128 .........
testing RIPEMD160 .........
testing RIPEMD256 .........
testing RIPEMD320 .........
testing TIGER ........
testing TIGER160 .....
testing TIGER128 ...
testing GOST ..
testing MD4 .......
testing SHA256 ....
testing SHA224 ...
testing SHA512 ...
testing SHA384 ...
testing WHIRLPOOL .........
testing SNEFRU128 ......
testing SNEFRU256 ...
testing MD2 .......

PASS: hash_test.sh
MD5 HMAC-Test: Ok
PASS: hmac_test
KEYGEN-Test: Succeed
PASS: keygen_test

Testing save/restore for algorithm CRC32: Ok
Testing save/restore for algorithm MD5: Ok
Testing save/restore for algorithm SHA1: Ok
Testing save/restore for algorithm HAVAL256: Ok
Testing save/restore for algorithm RIPEMD160: Ok
Testing save/restore for algorithm TIGER: Ok
Testing save/restore for algorithm GOST: Ok
Testing save/restore for algorithm CRC32B: Ok
Testing save/restore for algorithm HAVAL224: Ok
Testing save/restore for algorithm HAVAL192: Ok
Testing save/restore for algorithm HAVAL160: Ok
Testing save/restore for algorithm HAVAL128: Ok
Testing save/restore for algorithm TIGER128: Ok
Testing save/restore for algorithm TIGER160: Ok
Testing save/restore for algorithm MD4: Ok
Testing save/restore for algorithm SHA256: Ok
Testing save/restore for algorithm ADLER32: Ok
Testing save/restore for algorithm SHA224: Ok
Testing save/restore for algorithm SHA512: Ok
Testing save/restore for algorithm SHA384: Ok
Testing save/restore for algorithm WHIRLPOOL: Ok
Testing save/restore for algorithm RIPEMD128: Ok
Testing save/restore for algorithm RIPEMD256: Ok
Testing save/restore for algorithm RIPEMD320: Ok
Testing save/restore for algorithm SNEFRU128: Ok
Testing save/restore for algorithm SNEFRU256: Ok
Testing save/restore for algorithm MD2: Ok
PASS: rest_test

Checking fragmentation capabilities of MD5: OK
Checking fragmentation capabilities of SHA1: OK
Checking fragmentation capabilities of HAVAL256: OK
Checking fragmentation capabilities of RIPEMD160: OK
Checking fragmentation capabilities of TIGER: OK
Checking fragmentation capabilities of HAVAL224: OK
Checking fragmentation capabilities of HAVAL192: OK
Checking fragmentation capabilities of HAVAL160: OK
Checking fragmentation capabilities of HAVAL128: OK
Checking fragmentation capabilities of TIGER128: OK
Checking fragmentation capabilities of TIGER160: OK
Checking fragmentation capabilities of MD4: OK
Checking fragmentation capabilities of SHA256: OK
Checking fragmentation capabilities of SHA224: OK
Checking fragmentation capabilities of SHA512: OK
Checking fragmentation capabilities of SHA384: OK
Checking fragmentation capabilities of WHIRLPOOL: OK
Checking fragmentation capabilities of RIPEMD128: OK
Checking fragmentation capabilities of RIPEMD256: OK
Checking fragmentation capabilities of RIPEMD320: OK
Checking fragmentation capabilities of SNEFRU128: OK
Checking fragmentation capabilities of SNEFRU256: OK
Checking fragmentation capabilities of MD2: OK

The third attempt at installing mcrypt resulted in ... SUCCESS!!!
This time everything works well. Continue with executing the following command in order: make, make check, make install, and finally make clean.

Output snippet of the make install

Making install in doc
make[1]: Entering directory `/home/jay/Download/PHP_Crypto/mcrypt-2.6.8/doc'
make[2]: Entering directory `/home/jay/Download/PHP_Crypto/mcrypt-2.6.8/doc'
make[2]: Nothing to be done for `install-exec-am'.
test -z "/usr/local/share/man/man1" || /bin/mkdir -p "/usr/local/share/man/man1"
/usr/bin/install -c -m 644 './mcrypt.1' '/usr/local/share/man/man1/mcrypt.1'
make[2]: Leaving directory `/home/jay/Download/PHP_Crypto/mcrypt-2.6.8/doc'
make[1]: Leaving directory `/home/jay/Download/PHP_Crypto/mcrypt-2.6.8/doc'
Making install in src
make[1]: Entering directory `/home/jay/Download/PHP_Crypto/mcrypt-2.6.8/src'
make[2]: Entering directory `/home/jay/Download/PHP_Crypto/mcrypt-2.6.8/src'
test -z "/usr/local/bin" || /bin/mkdir -p "/usr/local/bin"
/bin/sh ../libtool --mode=install /usr/bin/install -c 'mcrypt' '/usr/local/bin/mcrypt'
libtool: install: /usr/bin/install -c mcrypt /usr/local/bin/mcrypt
make[2]: Nothing to be done for `install-data-am'.
make[2]: Leaving directory `/home/jay/Download/PHP_Crypto/mcrypt-2.6.8/src'
make[1]: Leaving directory `/home/jay/Download/PHP_Crypto/mcrypt-2.6.8/src'
Making install in po
make[1]: Entering directory `/home/jay/Download/PHP_Crypto/mcrypt-2.6.8/po'
/bin/mkdir -p /usr/local/share
installing el.gmo as /usr/local/share/locale/el/LC_MESSAGES/mcrypt.mo
installing cs.gmo as /usr/local/share/locale/cs/LC_MESSAGES/mcrypt.mo
installing pl.gmo as /usr/local/share/locale/pl/LC_MESSAGES/mcrypt.mo
installing de.gmo as /usr/local/share/locale/de/LC_MESSAGES/mcrypt.mo
installing es_AR.gmo as /usr/local/share/locale/es_AR/LC_MESSAGES/mcrypt.mo
if test "mcrypt" = "gettext-tools"; then \
/bin/mkdir -p /usr/local/share/gettext/po; \
for file in Makefile.in.in remove-potcdate.sin quot.sed boldquot.sed en@quot.header en@boldquot.header insert-header.sin Rules-quot Makevars.template; do \
/usr/bin/install -c -m 644 ./$file \
/usr/local/share/gettext/po/$file; \
done; \
for file in Makevars; do \
rm -f /usr/local/share/gettext/po/$file; \
done; \
else \
: ; \
fi
make[1]: Leaving directory `/home/jay/Download/PHP_Crypto/mcrypt-2.6.8/po'
make[1]: Entering directory `/home/jay/Download/PHP_Crypto/mcrypt-2.6.8'
make[2]: Entering directory `/home/jay/Download/PHP_Crypto/mcrypt-2.6.8'
make install-exec-hook
make[3]: Entering directory `/home/jay/Download/PHP_Crypto/mcrypt-2.6.8'
/bin/rm -f /usr/local/bin/mdecrypt
ln -s mcrypt /usr/local/bin/mdecrypt
make[3]: Leaving directory `/home/jay/Download/PHP_Crypto/mcrypt-2.6.8'
make[2]: Nothing to be done for `install-data-am'.
make[2]: Leaving directory `/home/jay/Download/PHP_Crypto/mcrypt-2.6.8'
make[1]: Leaving directory `/home/jay/Download/PHP_Crypto/mcrypt-2.6.8'

Now to make they all come together and work with PHP, locate the PHP.ini file. One way to do this is using the following command

% php -r "phpinfo();" | grep Configuration

Output:
Configuration File (php.ini) Path => /etc/php5/cli
Loaded Configuration File => /etc/php5/cli/php.ini
Configuration

Add the path to libmcrypt to PHP.ini.

Done!

Friday, January 30, 2009

Quick Solution to String Encryption (MD5 and SHA)

For a fast solution to string encryption or verify MD5 hash, PHP provides a very simple function for encrypting string or displaying hash key in either SHA or MD5 algorithm.

As for encryption:
The pro is simplicity.
The con is you don't get to define the salt.

methods for encrypting string
$encrypted_MD5_Str = md5($string);
$encrypted_SHA_Str = sha1($string);

methods for displaying hash key
$filename = "test.gz";
echo "MD5 hash value is: ".md5_file($filename);
echo "SHA1 hash value is: ".sha1_file($filename);

dvd+rw-tools-7.1 - DVD Burner Utility for RHEL5

I had to work on building a kickstart to automate Red Hat Enterprise Linux (RHEL) 5 installation process for the lab these past few days. And it was quite a challenge, since it was my first time doing this. Also no one in my group seems to know anything about it. But everything dealing with RHEL always take on some sort of a challenge, especially when it comes to building sysadmin tools or create some sort of autonomous system task (w/o the help of cron). I won't go into detail about kickstart in this blog. I just want to let everybody know that after completed building kickstart configuration, I had to burn everything (config files, RPM packages, etc.) into a DVD and what do you know. RHEL doesn't by default come with a DVD burning utility. It has the cdrecorder tool for burning CD, CDR, CDRW but not DVD. So this is my lesson learned, and yes I did contacted Red Hat about this.

Anyway, I was able to find a solution using a tool called dvd+rw-tools-7.1 to burn DVD. The instruction about dvd+rw-tools found on the Internet didn't help me much, but being that I had a lot of experiences on Linux - it was easy to figure out what to do. Below is the note I took while installing and testing out the tool, which I (at this point) really like a lot.

--- Dev Journal ---
utility: dvd+rw-tools
server: RHEL 5

Step 1: untar the file using command "tar -zxvf dvd+rw-tools-7.1.tar.gz"

Step 2: cd to "dvd+rw-tools-7.1"

Step 3: run "make" command
You should see the same output as below.

$ make
make[1]: Entering directory
gcc -O2 -D_REENTRANT -c -o growisofs.o growisofs.c
g++ -O2 -fno-exceptions -D_REENTRANT -c -o growisofs_mmc.o growisofs_mmc.cpp
g++ -O2 -fno-exceptions -D_REENTRANT growisofs.o growisofs_mmc.o -lpthread -o growisofs
g++ -O2 -fno-exceptions -D_REENTRANT -c -o dvd+rw-format.o dvd+rw-format.cpp
g++ -O2 -fno-exceptions -D_REENTRANT dvd+rw-format.o -lpthread -o dvd+rw-format
g++ -O2 -fno-exceptions -D_REENTRANT -c -o dvd+rw-booktype.o dvd+rw-booktype.cpp
g++ -O2 -fno-exceptions -D_REENTRANT dvd+rw-booktype.o -lpthread -o dvd+rw-booktype
g++ -O2 -fno-exceptions -D_REENTRANT -c -o dvd+rw-mediainfo.o dvd+rw-mediainfo.cpp
g++ -O2 -fno-exceptions -D_REENTRANT dvd+rw-mediainfo.o -lpthread -o dvd+rw-mediainfo
g++ -O2 -fno-exceptions -D_REENTRANT -c -o dvd-ram-control.o dvd-ram-control.cpp
g++ -O2 -fno-exceptions -D_REENTRANT dvd-ram-control.o -lpthread -o dvd-ram-control
make[1]: Leaving directory

Step 4: Obtain root priviledge (using sudo) and run "make install" command
You should see the same output as below.

# make install
make[1]: Entering directory
[ -d /usr/local/bin ] || mkdir -p /usr/local/bin
install -o root -m 0755 growisofs dvd+rw-format dvd+rw-booktype dvd+rw-mediainfo dvd-ram-control /usr/local/bin
[ -d /usr/local/man/man1 ] || mkdir -p /usr/local/man/man1
install -o root -m 0644 growisofs.1 /usr/local/man/man1
[ -f rpl8 ] && install -o root -m 0755 rpl8 /usr/local/bin; :
[ -f btcflash ] && install -o root -m 0755 btcflash /usr/local/bin; :
make[1]: Leaving directory

Step 5: Exit out of root priviledge and verify the software is correctly installed using ls command.
You should see the same output as below..

$ ls /usr/local/bin
dvd-ram-control dvd+rw-booktype dvd+rw-format dvd+rw-mediainfo growisofs

Step 6: If you see the executable files above, the installation is a success.
Now... it's time to test out the dvd+rw-tools.

First, insert a blank DVD into the DVD drive and type the following command.

$ dvd+rw-mediainfo /dev/dvd

The above command will output information about your DVD drive and DVD media.
You should see something similar to the output below. The server hardware I'm working with is HP ProLiant Server.

$ dvd+rw-mediainfo /dev/dvd
INQUIRY: [TEAC ][DV-W28E-RW ][G.B1]
GET [CURRENT] CONFIGURATION:
Mounted Media: 1Bh, DVD+R
Media ID: CMC MAG/M01
Current Write Speed: 8.0x1385=11080KB/s
Write Speed #0: 8.0x1385=11080KB/s
Write Speed #1: 6.0x1385=8310KB/s
Write Speed #2: 4.0x1385=5540KB/s
Write Speed #3: 2.4x1385=3324KB/s
Speed Descriptor#0: 00/2295103 R@8.0x1385=11080KB/s W@8.0x1385=11080KB/s
Speed Descriptor#1: 00/2295103 R@6.0x1385=8310KB/s W@6.0x1385=8310KB/s
Speed Descriptor#2: 00/2295103 R@4.0x1385=5540KB/s W@4.0x1385=5540KB/s
Speed Descriptor#3: 00/2295103 R@2.4x1385=3324KB/s W@2.4x1385=3324KB/s
READ DVD STRUCTURE[#0h]:
Media Book Type: 00h, DVD-ROM book [revision 0]
Legacy lead-out at: 2295104*2KB=4700372992
READ DISC INFORMATION:dvd+rw-tools-7.1
Disc status: blank
Number of Sessions: 1
State of Last Session: empty
"Next" Track: 1
Number of Tracks: 1
READ TRACK INFORMATION[#1]:
Track State: blank
Track Start Address: 0*2KB
Next Writable Address: 0*2KB
Free Blocks: 2295104*2KB
Track Size: 2295104*2KB
READ CAPACITY: 0*2048=0

Step 7: Jump up and down for about 10 seconds! and then congrat
yourself for successfully installing dvd+rw-tools-7.1 on RHEL.

I know, I know, I'm easily excited...

If you don't want to test burn a DVD, you can stop the reading
here and simply remove the DVD from your DVD drive.
Otherwise, continue to step 8.

Step 8: Obtain root priviledge (using sudo) and run the following command
to create an ISO image.

# mkisofs -r -o test.iso /h/local/test/

You should see a bunch of status data looking similar to the output
snippet below. Don't do anything, until you see a command prompt.

32.26% done, estimate finish Fri Jan 30 16:21:08 2009
32.60% done, estimate finish Fri Jan 30 16:21:07 2009
32.93% done, estimate finish Fri Jan 30 16:21:05 2009
33.26% done, estimate finish Fri Jan 30 16:21:04 2009
33.59% done, estimate finish Fri Jan 30 16:21:02 2009
33.93% done, estimate finish Fri Jan 30 16:21:01 2009
...
99.78% done, estimate finish Fri Jan 30 16:21:28 2009
Total translation table size: 0
Total rockridge attributes bytes: 525542
Total directory bytes: 819200
Path table size(bytes): 390
Max brk space used 37e000
1503291 extents written (2936 MB)

Step 9: Run the following command to burn the ISO image to DVD.

growisofs -Z /dev/dvd=test.iso

Again, you should see a bunch of status data looking similar
to the output snippet below. Wait until you see a command prompt.

# growisofs -Z /dev/dvd=RHEL5_custom.iso
Executing 'builtin_dd if=RHEL5_custom.iso of=/dev/dvd obs=32k seek=0'
/dev/dvd: "Current Write Speed" is 8.2x1352KBps.
1572864/3078739968 ( 0.1%) @0.0x, remaining 195:38 RBU 100.0% UBU 2.0%
1572864/3078739968 ( 0.1%) @0.0x, remaining 293:27 RBU 100.0% UBU 100.0%
...
2975989760/3078739968 (96.7%) @6.0x, remaining 0:19 RBU 100.0% UBU 100.0%
3003678720/3078739968 (97.6%) @6.0x, remaining 0:13 RBU 100.0% UBU 100.0%
3029565440/3078739968 (98.4%) @5.6x, remaining 0:09 RBU 100.0% UBU 100.0%
3057287168/3078739968 (99.3%) @6.0x, remaining 0:03 RBU 64.0% UBU 100.0%
builtin_dd: 1503296*2KB out @ average 3.9x1352KBps
/dev/dvd: flushing cache
/dev/dvd: closing track
/dev/dvd: closing session

Step 10: Eject the DVD (using command "eject dvd" and then jump up and down again for
about 10 seconds! and congrat yourself for successfully burning dvd on RHEL.

Wednesday, January 28, 2009

PHP Cryptography

This is a follow up to my investigation in cryptography. If you read my previous Java Cryptography blog, then you already know that I build this PHP Encryption API to test against the Java Encryption API. If you just jump right into this blog, I'll make a long story short. I had to do some encryption/decryption testing. That's how this API got generated.

Here's what I learn. PHP provides a very powerful and easy to develop encryption mechanism using MD5, Standard DES, Extended DES, and Blowfish security algorithm. PHP has a built in encryption mechanism that will allow you to encrypt string using any of the previous mentioned algorithm and return a hash value (encrypted data). This makes the task of encrypting and comparing password very easy. Best way to learn is by downloading the source code and try it out. Man, the time already passed 11:30PM, and I have to get up early tomorrow and goto work. I'll cut this blog short and will tag information to it tomorrow night.

Source code (Encryption API): Encryption.php


<?php

/********************************
* A class for illustrating MD5, Standard DES, Extended DES, and Blowfish encryption process and comparing encryption data
*
* Encryption.php
*
* @version 0.1 27 January 2009
* @author Jay Suttiruttana
*
* Interpreter: PHP v5
* Development Platform: Linux 32 bits Kernel 2.6.22.19-0.1 / X86-64
*
* license: GNU LGPL
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*/

class Encryption{
//define method attributes
private $CRYPT_TYPE_MD5 = '$1$ABCDEFGH$'; //8 characters salt w/ $1$...$
private $CRYPT_TYPE_STD_DES = 'AB'; //2 characters salt
private $CRYPT_TYPE_EXT_DES = '12345678'; //8 character salt
private $CRYPT_TYPE_BLOWFISH = '$2$ABCDEFGHIJKLMNOP$'; //16 characters salt w/ $2$...$

//constructor
public function Encryption(){
}

//function encrypt password(username, password)
public function encryptPassword($uid, $pwd){
$completionFlag = false;
// TODO: create an insert to system db or write to flat file on user info

// SQL statement:
// insert $DB_MD5, $DB_DES_STD,$DB_DES_EXT, $DB_BLOWFISH to
// Client_Information where username = $uid;

$DB_PWD = crypt($pwd, $this->CRYPT_TYPE_MD5)."|".
crypt($pwd, $this->CRYPT_TYPE_STD_DES)."|".
crypt($pwd, $this->CRYPT_TYPE_EXT_DES)."|".
crypt($pwd, $this->CRYPT_TYPE_BLOWFISH);

//filename is the user ID.
if($this->generateUserPWDFile($uid, $DB_PWD)){
$completionFlag = true;
}
return $completionFlag;
}

//function authenticateUser_All(username, pasword)
//check all encryption.
public function authenticateUser_All($uid, $pwd){
$authenticateFlag = false;

//open password file for reading
$fileHandle = fopen($uid, 'r');
$data = fread($fileHandle, filesize($uid));
fclose($fileHandle);

//Parse string $data using regex with | as delimeter
//and assign value to homeULR, logoFile, and copyright
$pData = spliti ("\|", $data);
$DB_MD5 = $pData[0];
$DB_DES_STD = $pData[1];
$DB_DES_EXT = $pData[2];
$DB_BLOWFISH = $pData[3];

if (($this->validateMD5($pwd, $DB_MD5)) &&
($this->validateSTD_DES($pwd, $DB_DES_STD)) &&
($this->validateSTD_EXT($pwd, $DB_DES_EXT)) &&
($this->validateBlowfish($pwd, $DB_BLOWFISH))){
$authenticateFlag = true;
}
return $authenticateFlag;
}

//validate password with MD5 encryption
private function validateMD5($pwd, $cPwd){
$authenticateFlag = false;


if ($cPwd == crypt($pwd, $this->CRYPT_TYPE_MD5)){
$authenticateFlag = true;
}
return $authenticateFlag;
}


//validate password with Standard DES encryption
private function validateSTD_DES($pwd, $cPwd){
$authenticateFlag = false;

if ($cPwd == crypt($pwd, $this->CRYPT_TYPE_STD_DES)){
$authenticateFlag = true;
}
return $authenticateFlag;
}

//validate password with Extended DES encryption
private function validateSTD_EXT($pwd, $cPwd){
$authenticateFlag = false;

if ($cPwd == crypt($pwd, $this->CRYPT_TYPE_EXT_DES)){
$authenticateFlag = true;
}
return $authenticateFlag;
}

//validate password with Blowfish encryption
private function validateBlowfish($pwd, $cPwd){
$authenticateFlag = false;

if ($cPwd == crypt($pwd, $this->CRYPT_TYPE_BLOWFISH)){
$authenticateFlag = true;
}
return $authenticateFlag;
}

//write to file
private function generateUserPWDFile($filename, $value){
//create password file and write encrypted password to file
$fileHandle = fopen($filename, 'w') or die("can't open file");
fwrite($fileHandle, $value);
fclose($fileHandle);

return true;
}
}

?>


Source code for testing Encryption API: testEncryption.php


<?php
/**
* testEncryption.php
*
* Example 1: Test encryption. This will encrypt password and create a file.
* % php testEncryption.php jay test e
*
* Example 2: Test authentication. This will authenticate username & password.
* % php testEncryption.php jay test a
*
* @version 0.1 27 January 2009
* @author Jay Suttiruttana
*
* Interpreter: PHP v5
* Development Platform: Linux 32 bits Kernel 2.6.22.19-0.1 / X86-64
*
* license: GNU LGPL
*/

require_once("Encryption.php");

if (($argc != 4) || ($argc > 4)) {
print "Missing required information... {username} {password} {e/a}\n";
exit();
}
else {
$uid = $argv[1];
$pwd = $argv[2];
$test = $argv[3];
}

$enc = new Encryption();

switch ($test){
case 'e'://Test encrypted file creation
//comment out if/else logic below to test file creation
echo "Encrypting password for uid:".$uid."\n";
if($enc->encryptPassword($uid,$pwd)){
echo "success...\n";
}
else {
echo "fail...\n";
}
break;

case 'a'://Test authentication
//comment out if/else logic below to test authentication
echo "Authenticating user:".$uid."\n";
if($enc->authenticateUser_All($uid,$pwd)){
print "[access granted]\n";
}
else {
print "[access denied]\n";
}
break;
}

?>


Sample output:

First, I executed (e)ncryption for my password "test". This forces the API to create
a flat file containing encrypted password. Then I executed (a)uthentication to
authenticate my username and password, which resulted in "access granted". Then I
executed another authentication using uppercase "TEST", which resulted in "access
denied". Finanlly, I view the content of my password file using the cat command.

% php testEncryption.php jay test e
Encrypting password for uid:jay
success...

% php testEncryption.php jay test a
Authenticating user:jay
[access granted]

% php testEncryption.php jay TEST a
Authenticating user:jay
[access denied]

% cat jay
$1$ABCDEFGH$b1FW49h9UTi.E6xXyTsWl0|ABwOg1D2JDxIQ|126D8rSh5sjUE|*0