Tuesday, September 25, 2012

Avoiding the "javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated" with HttpClient

Please note: This article focuses on the Apache HttpClient library.

When developing a https application, your test server often doesn't have a (valid) SSL certificate. This will cause the following exception to be thrown when connecting your client to the test server: "javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated".
I will be discussing a way to fix this issue with the apache HttpClient, version 4.0.1

Bits and pieces
--------------------
You usually create your HttpClient like this:
client = new DefaultHttpClient();

We will need to tell the client to use a different TrustManager. A TrustManager is a class that checks if given credentials (or certificates) are valid. The scheme used by SSL is called X.509, and Java has a specific TrustManager for this scheme, called X509 TrustManager. First thing we will need to do is create such a TrustManager:
X509TrustManager tm = new X509TrustManager() {  
 public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException { }  
 public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException { }  
 public X509Certificate[] getAcceptedIssuers() {
 return null;
 }
};


As you can see, this code doesn't do much: if a certificate is invalid the TrustManager is supposed to throw a CertificateException in the checkXXX methods. Since we always want to accept all certificates, we never throw an exception.

Next we need to find a way to set this TrustManager in our HttpClient. The TrustManager is used by the SSL sockets. Sockets are created using a SocketFactory. For SSL sockets this is an SSLSocketFactory.

When creating a new SSLSocketFactory, you need to pass an SSLContext to the constructor. It is this SSLContext that will contain our newly created TrustManager.

First thing we need to do is get an SSLContext:SSLContext ctx = SSLContext.getInstance("TLS");

TLS is the successor to SSL, but they use the same SSLContext.
Then we initialize this context with our new TrustManager that we created above:ctx.init(null, new TrustManager[]{tm}, null);

We can then finally create our SSLSocketFactory:SSLSocketFactory ssf = new SSLSocketFactory(ctx);

Now we still need to register this SSLSocketFactory with our HttpClient. This is done in the SchemeRegistry of the ConnectionManager of the HttpClient:ClientConnectionManager ccm = base.getConnectionManager();
SchemeRegistry sr = ccm.getSchemeRegistry();
sr.register(new Scheme("https", ssf, 443));


We register a new Scheme, with the protocol https, our newly created SSLSocketFactory which contains our TrustManager and we tell the HttpClient that the default port for https is port 443.

Putting it all together:
===================
The following class takes a HttpClient and returns a new HttpClient that accepts any SSL certificate:
/* This code is public domain: you are free to use, link and/or modify it in any way you want, for all purposes including commercial applications.  */
public class WebClientDevWrapper { 
 public static HttpClient wrapClient(HttpClient base) {
 try { 

  SSLContext ctx = SSLContext.getInstance("TLS");
  X509TrustManager tm = new X509TrustManager() {  
   public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException { }  
   public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException { }  
   public X509Certificate[] getAcceptedIssuers() {
    return null;
   }
  }; 


  ctx.init(null, new TrustManager[]{tm}, null);
  SSLSocketFactory ssf = new SSLSocketFactory(ctx);
  ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
  ClientConnectionManager ccm = base.getConnectionManager();
  SchemeRegistry sr = ccm.getSchemeRegistry();
  sr.register(new Scheme("https", ssf, 443));
  return new DefaultHttpClient(ccm, base.getParams());
 } catch (Exception ex) {
  ex.printStackTrace();
  return null;
 }
      }
}


You can then do something like this in the code that creates the HttpClient:
this.client = new DefaultHttpClient();
if(dev) {
 this.client = WebClientDevWrapper.wrapClient(client);
}

- - - - - - - - - - - - - - - - - - - - - - - - - - - -  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Update:
In some exceptional cases, the method described above doesn't work. This is due to the Apache AllowAllHostnameVerifier still being to strict. In this case, you will need your own X509HostnameVerifier. Create it as follows:
X509HostnameVerifier verifier = new X509HostnameVerifier() {                  
 @Override               
 public void verify(String string, SSLSocket ssls) throws IOException {}                  
 @Override               
 public void verify(String string, X509Certificate xc) throws SSLException {}
 @Override               
 public void verify(String string, String[] strings, String[] strings1) throws SSLException {}
 @Override               
 public boolean verify(String string, SSLSession ssls) {
  return true;                
 }            
};


Then set it on your socket factory:
ssf.setHostnameVerifier(verifier);

If we put everything together, the new code looks like this:
/* This code is public domain: you are free to use, link and/or modify it in any way you want, for all purposes including commercial applications.  */

public class WebClientDevWrapper {      
 public static HttpClient wrapClient(HttpClient base) {        
  try {             

   SSLContext ctx = SSLContext.getInstance("TLS");
   X509TrustManager tm = new X509TrustManager() {                  
    public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException {}
    public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException {}
    public X509Certificate[] getAcceptedIssuers() {                    
     return null;                
    }            
   };

            
   X509HostnameVerifier verifier = new X509HostnameVerifier() {                   

   @Override               
   public void verify(String string, SSLSocket ssls) throws IOException {}

   @Override               
   public void verify(String string, X509Certificate xc) throws SSLException {}

   @Override               
   public void verify(String string, String[] strings, String[] strings1) throws SSLException {}

   @Override               
   public boolean verify(String string, SSLSession ssls) {
    return true; 
   }            
  };             

  ctx.init(null, new TrustManager[]{tm}, null);            
  SSLSocketFactory ssf = new SSLSocketFactory(ctx);            
  ssf.setHostnameVerifier(verifier);            
  ClientConnectionManager ccm = base.getConnectionManager();    
  SchemeRegistry sr = ccm.getSchemeRegistry();            
  sr.register(new Scheme("https", ssf, 443));            
  return new DefaultHttpClient(ccm, base.getParams());         

 } catch (Exception ex) {            
  ex.printStackTrace();            
  return null;        
 }    
    }
}

You can then do something like this in the code that creates the HttpClient:
this.client = new DefaultHttpClient();
if(dev) {
 this.client = WebClientDevWrapper.wrapClient(client);
}

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Working Example implemented in one of my project:

package com.company.test;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;

import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;


public class HttpsTestClient {
 public static void main(String[] args) throws KeyManagementException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException {
  SchemeRegistry registry = new SchemeRegistry();
  SSLSocketFactory socketFactory = new SSLSocketFactory(new TrustStrategy() {
   public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
    return true;
   }
  }, org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
 
  registry.register(new Scheme("https", 443, socketFactory));
  ThreadSafeClientConnManager mgr = new ThreadSafeClientConnManager(registry);
 
  DefaultHttpClient client = new DefaultHttpClient(mgr, new DefaultHttpClient().getParams());
       
     HttpPost post = new HttpPost("
https://host:7032/Xyz/service");
     try {
      String send = "< ?xml version=\"1.0\" encoding=\"UTF-8\"?> <msg> <head><Client>ComXCalFL</Client> <Region>QAYA</Region> <Source>E26XCALIBUR</Source><Destination>CCS01</Destination> <Origin>L0OG1-X-CAL ORDER DETAIL UPDATED</Origin> <Version>2.25</Version> <RoundTrip>MDU6MDAwMDAwMDM6MjAxMjA4MzE6MTE0OTE0MDA6ODIxMDAwMDA6TDBPRzowMg==</RoundTrip> <UserId>LRM 0B72</UserId> <ServerId>sbappre02-z04</ServerId> <TriggerDate>2012-08-31</TriggerDate><TriggerTime>11:49:14</TriggerTime> </head><body><OrderDetailUpdated> XML_PAYLOAD</OrderDetailUpdated></body></msg>";

     
      StringEntity strEnt = new StringEntity(send);
      post.setEntity(strEnt);
       HttpResponse response = client.execute( post);
       BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
       String line = "";
       while ((line = rd.readLine()) != null) {
         System.out.println(line);
       }

     } catch (IOException e) {
       e.printStackTrace();
     }
   }

}



Thursday, July 19, 2012

Apache JMeter

Apache J Meter

# - Remember to set JAVA_HOME to JDK 5+
Example:
Server 1:
JAVA_HOME=/app/weblogic/jdk1.6.0_33/bin

WEBLOGIC_HOME=/app/home/mradmin/Oracle/Middleware
APACHE_HOME=/app/cemp/apache-jmeter-2.7
PATH=/app/weblogic/jdk1.6.0_33/bin:/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/app/home/mradmin/bin:/app/cemp/apache-jmeter-2.7/bin/ApacheJMeter.jar:
export PATH
Server 2: [Same on Server 2]

# - [cemp@cempda01 bin]$ jmeter -n -r -t Usage\ Cache\ Users.jmx -LDEBUG -l results.jtl
Example #:

[cemp@cempda01 bin]$ jmeter -n -r -t UsageCacheUsers.jmx -LDEBUG -l results.jtl
Created the tree successfully using UsageCacheUsers.jmx

Configuring remote engine for cmpcol-dt-4d.ula.com.net
Using remote object: UnicastRef [liveRef: [endpoint:[10.255.156.129:49889](remote),objID:[71770134:138a12bc3d9:-7fff, 5263036063349195177]]]
Configuring remote engine for cempda01.cab.com.com
Using remote object: UnicastRef [liveRef: [endpoint:[147.191.113.124:34820](remote),objID:[584b8767:138a1409048:-7fff, -1613329581385448862]]]
Starting remote engines
Starting the test @ Fri Jul 20 05:29:06 UTC 2012 (1342762146778)
Remote engines have been started
Waiting for possible shutdown message on port 4445
Generate Summary Results + 916 in 31.3s = 29.3/s Avg: 34 Min: 21 Max: 176 Err: 0 (0.00%)
Generate Summary Results + 2631 in 89.0s = 29.6/s Avg: 35 Min: 20 Max: 134 Err: 0 (0.00%)
Generate Summary Results = 3547 in 120.3s = 29.5/s Avg: 35 Min: 20 Max: 176 Err: 0 (0.00%)
Tidying up remote @ Fri Jul 20 05:31:29 UTC 2012 (1342762289011)
... end of run
[cemp@cempda01 bin]$
# - Important Commands:
1. [cemp@cempda01 bin]$ netstat -tulpn // Check port - process id.
2. Microsoft Windows:  start rmiregistry 30031 // remember to JAVA_HOME before.
3. Solaris OS or Linux:  rmiregistry 30031 & // remember to set JAVA_HOME before.
By default, the registry runs on port 1099. To start the registry on a different port, specify the port number on the command line. Do not forget to unset your CLASSPATH environment variable.
To check that the RMI registry has started correctly, you can check that it is listening on its standard port (1099 unless you've specified otherwise) with a tool such as TCP View.






 
 
 

Wednesday, July 18, 2012

Mozilla Unresponsive Script

Any Solution ?

Warning: Unresponsible Script

A script on this page may be busy , or it may have stopped responding. You can stop the script now, or you can continue to see if the script will complete.
Script: http://s.ytimg.com/yt/jsbin/www-core-vf19FZ5Nr.js:219

Sunday, June 17, 2012

CVS Quick Reference

CVS Options
Use the following syntax to issue CVS Commands:
$ cvs [cvs-option] command [cmd-options] [args]

Replace cvs-options with one  or more of the following:
1. -a : Authenticate the data stream
2. --allow-root=directory : Set the repository root directory (used in server modes)
3. -d repository-path : Specify the repository path for the current command
4. -e editor : Use the specified editor in commit or import commands.
5. -f : Do not use the ~/.cvsrc file
6. -H or --help : Display help for CVS
7. --help-commands : Display a list of CVS Commands.
8. --help-options : Display a list of CVS Options.
9. --help-synonyms : Display a list of synonyms for CVS commands.
10. --H command or --help command : Display the options and help for the specified command.
11. -l : Do not log the current command to the history file.
12. -n : do not write to the repository or sandbox.
13. -q : Run in quiet mode.
14. -Q : Run in very quiet mode.
15. -r : Set files checked out to the sandbox read-only.
16. -s : variable=value : Set a user variable for use with one of the scripting files in CVSROOT
17. -t: Display messages that trance the execution of the command.
18. -v or --version : Display CVS version and copyright information.
19. -w : Set files checked out to the sandbox readable and writable.
20. -x : Encrypt all data that travels across the network.
21. -z # : Compress all network traffic using the specified gzip compression level.

Repository Access:
Repository path information is as follows:
[:method] [[[user][:password]@]hostname[:[port]]]/path 

Access method can be any of the following:
1. ext: Connection through external rsh or rsh-like program.
2. fork: Client / server mode on local computer.
3. gserver : Connection through the GSS-API and Kerberos 5
4. local : Local computer, no client / server mode.
5. pserver : Connection through password server.
6. kserver: Connection through kerberos 4.
7. server: Connection through internal rsh server key environment variables relating to repository access are
     CVS_RSH: Specifies rsh-like executable.
     CVSROOT: Specifies repository path.

Common CVS Tasks:
The following lists show the syntax to use in performing common CVS tasks. Remember that for any CVS command you can specify the repository path using the -d option. For example:
$ cvs -d repository_path checkout project
For brevity, the -d option is not shown in any of the example commands. However, it can be added to any of the commands.

Sandbox Commands:
Create a new sandbox: $ cvs checkout project
Remove a sandbox: $ cvs release directory
Check out files as of a specific tag name or revision: cvs checkout -r [tagname | revision] project
Check out files as of a specific date or time:  $ cvs checkout -D [date|time] project

Synchronization Commands:
Upload changes to the repository: $ cvs commit [filenames]
Force upload of unchanged files: $ cvs commit -f [filenames]
Download changes from the repository: $ cvs update [filenames]
Download changes and download new directories: $ cvs update -d [filenames]
Download changes. but not empty directories : $ cvs update -P [filenames]
Download changes, clear sticky revision, date, keyword mode or branch: $ cvs update -A [filenames]
Convert an existing sandbox to a specific tag name or revision: $ cvs update -r [tagname | revision] project
Convert an existing sandbox to a specific date or time: $ cvs update -D [date|time] project

File Commands:
Add new files or directories to the repository: $ cvs add [filenames]
Add new binary files to the repository: $ cvs add -kb [filenames]
Remove files or directories from the repository: $ cvs remove [filenames]

Branch Commands:
Create a branch from within a sandbox: $ cvs tag -b branchname [filenames]
Create a branch from anywhere using a tag name or revision: $ cvs rtag -r [tagname|revision] -b branchname project
Create a branch from anywhere using a date or time: $ cvs rtag -D [date|time] branchname project
Checkout a branch sandbox: $ cvs checkout -r branchname project
Convert an existing sandbox to a branch sandbox: $ cvs update -r branchname [filenames]

Tag Commands:
Tag files from within a sandbox: $ cvs tag tagname [filenames]
Tag files from anywhere using a tag name or revision: $ cvs rtag -r [existing_tagname | revision] new_tagname project
Tag files from anywhere using a date or time: $ cvs rtag -D [date|time] tagname project
Move a tag from within a sandbox: $ cvs tag -F tagname [filenames]
Move a tag from anywhere using a tag name or revision: $ cvs rtag -r [tagname_at_location|revision] -F tagname_to_more project
Move a tag form anywhere using a date or time: $ cvs rtag -D [date|time] -F tagname project
Delete a tag from within a sandbox: $ cvs tag -d tagname [filenames]
Delete a tag from anywhere: $cvs rtag -d tagname project

The -r [tagname|revision] option accepts a tag name or revision, but cannot have both tag name and revision. The -D [date|time] option accepts a date, a time, or both date and time.

CVSROOT: :ssh:adixit3034c@cmputl-po-3p:/opt/cm/cmsys/cvs/root
Server: cmputl-po-3p
Repository Folder: /opt/cm/cmsys/cvs/root

Username: adixit3034c

[Working]$ cvs -d adixit3034c@cmputl-po-3p:/opt/cm/cmsys/cvs/root checkout -P -r CFX_BR_EEPBill_DDPMediation_2_0_0_5 CFX_BR_EEPBill_DDPMediation

$ cd /data/Release_elements/current/US242513
$ tar -czvf CFX_BR_EEPBill_DDPMediation_2_0_0_5.tar.gz CFX_BR_EEPBill_DDPMediation_2_0_0_5

$ chmod 755 CFX_BR_EEPBill_DDPMediation_2_0_0_5 -R
$ cd /data/Release_elements/current/US242513/CFX_BR_EEPBill_DDPMediation_2_0_0_5/_EEPBill_DDPMediation/app

$ mvn clean install -Dmaven.test.skip=true

Location: http://cmputl-po-4p/cm_workareas/current/

Maven Important Command

Command 1. The install:install goal
In most cases, install:install goal doesn't need any configuration, it needs the project's POM and the artifact file to be installed during the install phase of the default build lifecycle. mvn install ::
install:install-file goal
The install:install-file goal is used primarily for installing artifacts to the local repository which were not built by Maven. The project's development team may or may not provide a POM for the artifact. Here's a list of some of the available parameters for the install-file goal:

$mvn install:install-file -Dfile=your-artifact-1.0.jar [-DpomFile=your-pom.xml] [-Dsources=src.jar] [-Djavadoc=apidocs.jar] [-DgroupId=org.some.group] [-DartifactId=your-artifact] [-Dversion=1.0] [-Dpackaging=jar] [-Dclassifier=sources] [-DgeneratePom=true] [-DcreateChecksum=true]

  • The groupId, artifactId, version and packaging of the file to install. These can be taken from the specified pomFile, and overridden or specified using the command line. When the pomFile contains a parent section, the parent's groupId can be considered if the groupId is not specified further for the current project or on the command line.
  • The optional classifier parameter can be used to install secondary artifacts for a project, like a javadoc or sources JAR. If a classifier is not given, Maven assumes the file is the main artifact for the project.

Command 2: The deploy:deploy Mojo
In most cases, this mojo is invoked when you call the deploy phase of the default build lifecycle.
To enable this mojo to function, you must include a valid section POM, which at the minimum provides a defining the remote repository location for your artifact. To separate snapshot artifacts from release artifacts, you can also specify a location. Finally, to deploy a project website, you must specify a section here as well. It's also important to note that this section can be inherited, allowing you to specify the deployment location one time for a set of related projects.
If your repository is secured, you may also want to configure your settings.xml file to define corresponding entries which provides authentication information. Server entries are matched to the different parts of the distributionManagement using their elements. For example, your project may have a distributionManagement section similar to the following:
[...]
 
   
      internal.repo
      MyCo Internal Repository
      Host to Company Repository
   

 

[...]
In this case, you can specify a server definition in your settings.xml to provide authentication information for both of these repositories at once. Your server section might look like this:
[...]
   
      internal.repo
      maven
      foobar
   

[...]
Please see the article about Password Encryption for instructions on how to avoid clear text passwords in the settings.xml.
Once you've configured your repository deployment information correctly deploying your project's artifact will only require invocation of the deploy phase of the build:
mvn deploy
The deploy:deploy-file Mojo
The deploy:deploy-file mojo is used primarily for deploying artifacts to which were not built by Maven. The project's development team may or may not provide a POM for the artifact, and in some cases you may want to deploy the artifact to an internal remote repository. The deploy-file mojo provides functionality covering all of these use cases, and offers a wide range of configurability for generating a POM on-the-fly. Additionally, you can specify what layout your repository uses. The full usage statement of the deploy-file mojo can be described as:
mvn deploy:deploy-file -Durl=file://C:\m2-repo -DrepositoryId=some.id -Dfile=your-artifact-1.0.jar [-DpomFile=your-pom.xml] [-DgroupId=org.some.group] [-DartifactId=your-artifact] [-Dversion=1.0] [-Dpackaging=jar] [-Dclassifier=test] [-DgeneratePom=true] [-DgeneratePom.description="My Project Description"] [-DrepositoryLayout=legacy] [-DuniqueVersion=false]
If the following required information is not specified in some way, the goal will fail:
•The artifact file to deploy
•The group, artifact, version and packaging of the file to deploy. These can be taken from the specified pomFile, and overriden or specified using the command line. When the pomFile contains a parent section, the parent's groupId can be considered if the groupId is not specified further for the current project or on the command line.
•The repository information: the url to deploy to and the repositoryId mapping to a server section in the settings.xml file. If you don't specify a repositoryId, Maven will try to extract authentication information using the id 'remote-repository'.


More about maven:
1. Plugins
2. Maven & Source Code








Saturday, June 2, 2012

J B O S S

EAP: Enterprise Application Platform

JBoss Developer Studio:
Configure Maven in JBoss Developer Studio:
Click Window→Preferences, expand JBoss T ools and select JBoss Maven Integration.

Add a repository [jboss-earlyaccess-repository] > 
Profile Id: jboss-ga-repository
Repository: ID: jboss-ga-repository; Name:jboss-ga-repository; URL: http://maven.repository.redhat.com/techpreview/all

Add early access repository[jboss-earlyaccess-repository]>
Profile Id:jboss-earlyaccess-repository
Repository: ID:jboss-earlyaccess-repository ; Name:jboss-earlyaccess-repository ; URL:http://maven.repository.redhat.com/earlyaccess/all/


First Time when we start JBOSS EAP Server, it will give following message:
- - - - - - - - - - - - - - - - - - - - - 
Welcome to EAP 6
The Enterprise Application Platform 6 is running.
However you have not yet added any users to be able to access the admin console.
To add a new user execute the add-user.sh script within the bin folder of your EAP 6 installation and enter the requested information.
By default the realm name used by EAP is "ManagementRealm" this is already selected by default.
After you have added the user follow this link to Try Again.
- - - - - - - - - - - - - - - - - - - - -