Tuesday, December 31, 2013

OpenConnect client for Cisco's AnyConnect SSL VPN

If we need to connect Cisco's AnyConnect SSL VPN from an AWS CentOS instance without using Cisco AnyConnect client, there's the OpenConnect as an alternative.

On CentOS 5.4, it's easy to install OpenConnect from enabled Red Hat Enterprise Linux / CentOS Linux Enable EPEL (Extra Packages for Enterprise Linux) repository.
If it is not, then install it:

rpm -ivh http://dl.fedoraproject.org/pub/epel/5/i386/epel-release-5-4.noarch.rpm

And then install openconnect: yum install openconnect
Then use it to connect VPN: openconnect -u auser cisco-vpn-server
But after enter the password, it throws an error: Failed to open tun device: No such device

Let's check the tun module:

[root@myhost ~]# modprobe tun
FATAL: Module tun not found.

[root@myhost ~]# cat /dev/net/tun
cat: /dev/net/tun: No such device

The module tun is /lib/modules/2.6.16-xenU/kernel/drivers/net/tun.ko. For some reason, if it's missed, so get it from http://s3.amazonaws.com/ec2-downloads/modules-2.6.16-ec2.tgz and unpack/copy entire folder lib/modules/2.6.16-xenU/kernel to /lib/modules/2.6.16-xenU

Then we need to reload modules:
[root@myhost ~]# depmod -ae 2.6.16-xenU
[root@myhost ~]# modprobe tun

Then connect VPN again, and it works: Connected tun0 as a.b.c.d, using SSL
Then just open another terminal and ssh to a server in the network.



Friday, December 13, 2013

Tynamo tapestry-security 0.5.1 and UNAUTHORIZED_URL bug

The Tynamo tapestry security 0.5.1 allows us to configure the URL path when unauthorized access happens. But it only works when we use annotation @RequiresRoles for each page, while it won't if we use Shiro createChain for global configuration, like
 configuration.add(factory.createChain("/admin/**").add(factory.roles(),User.Role.admin.name()).build());  
, the app displays:

HTTP ERROR 401
Problem accessing /admin/home. Reason:
Unauthorized
------------------------------------------------------------------------
/Powered by Jetty:///

instead of configured URL page.

The reason is the org.tynamo.security.shiro.authz.AuthorizationFilter.
getUnauthorizedUrl() overwrites the org.tynamo.security.shiro.AccessControlFilter.getUnauthorizedUrl() where the configured UNAUTHORIZED_URL passed in. The AuthorizationFilter.
getUnauthorizedUrl() returns value from class private variable unauthorizedUrl, so it's always null.

To fix it, just patch AuthorizationFilter by removing unauthorizedUrl, getUnauthorizedUrl(), setUnauthorizedUrl(.) as this.

Tuesday, December 10, 2013

Apache Shiro - Remember me and SerializationException: Unable to deserialze argument byte array

When implementing Tynamo tapestry security 0.5.1, I got exception when using Remember me

[WARN] mgt.DefaultSecurityManager Delegate RememberMeManager instance of type [$RememberMeManager_133e98f5ddc26344] threw an exception during getRememberedPrincipals().
org.apache.shiro.io.SerializationException: Unable to deserialze argument byte array.
at org.apache.shiro.io.DefaultSerializer.deserialize(DefaultSerializer.java:82)
at org.apache.shiro.mgt.AbstractRememberMeManager.deserialize(AbstractRememberMeManager.java:514)
at org.apache.shiro.mgt.AbstractRememberMeManager.convertBytesToPrincipals(AbstractRememberMeManager.java:431)

Caused by: java.io.StreamCorruptedException: invalid type code: EE
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1353)
at java.io.ObjectInputStream.readArray(ObjectInputStream.java:1639)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1320)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1950)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1874)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1756)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1326)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:348)
at java.util.HashSet.readObject(HashSet.java:291)
...
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:348)
at org.apache.shiro.io.DefaultSerializer.deserialize(DefaultSerializer.java:77)

The Tynamo tapestry security 0.5.1 is based on Apache Shiro 1.2.0

Google around and found it was resolved for 1.2.0 release. That's interesting.

So I tried to debug the ClassResolvingObjectInputStream and ClassUtils and still didn't know the reason why the ClassUtils.forName(..) can't load byte array class. Finally google around for deserialize byte array exception and got JDK-6500212 : (cl) ClassLoader.loadClass() fails when byte array is passed resolved since 2007!

I'm running the app with 1.6.0.jdk on MacOS X so that might cause the problem.

So I patched the ClassUtils as below:

   public static Class forName(String fqcn) throws UnknownClassException {  
     .....  
     if (clazz == null) {//Luan - patch for byte array class (class name =[B - ref http://bugs.sun.com/view_bug.do?bug_id=6500212  
          try {  
                     clazz = Class.forName(fqcn,false,Thread.currentThread().getContextClassLoader());  
                } catch (ClassNotFoundException e) {  
                     if (log.isTraceEnabled()) {  
              log.trace("Unable to load class named [" + fqcn + "] from the current thread context.");  
            }  
                }  
     }  
     if (clazz == null) {  
       String msg = "Unable to load class named [" + fqcn + "] from the thread context, current, or " +  
           "system/application ClassLoaders. All heuristics have been exhausted. Class could not be found.";  
       throw new UnknownClassException(msg);  
     }  
     return clazz;  
   }  

and it worked!