This week's giveaway is in the Android forum.
We're giving away four copies of Android Security Essentials Live Lessons and have Godfrey Nolan on-line!
See this thread for details.
The moose likes Tomcat and the fly likes Tomcat 6.0.37 can not retrieve username and passwrod from CAC (DOD smart card) Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
JavaRanch » Java Forums » Products » Tomcat
Bookmark "Tomcat 6.0.37 can not retrieve username and passwrod from CAC (DOD smart card)" Watch "Tomcat 6.0.37 can not retrieve username and passwrod from CAC (DOD smart card)" New topic
Author

Tomcat 6.0.37 can not retrieve username and passwrod from CAC (DOD smart card)

AnhDung Nguyen
Greenhorn

Joined: Nov 04, 2013
Posts: 9
Hello,

First of, I apologize if i left out any info and please let me know what detail you need.

This is my first job with web app and i'm supporting a web site that authenticate user with either username/password or CAC log-in (DOD common access card).

I recently upgrade Tomcat from 6.0.18 to 6.0.37 to fix some vulnerabilities by security team. Everything work fine except the CAC log-in feature. After days of troubleshoot, the main different that i see between two version is the request header contain the username/password that it got from CAC so that it can then authenticate and log user in.
In Tomcat 6.0.18:
It look like this in the request body: targetUrl=null&username=<myUsername>&password=<CAC-myID>

In Tomcat 6.0.37:
It look like this in the request body: username=&password=&targetUrl=null

Basically, in Tomcat 6.0.37 it can not retrieve the info from CAC so that the site can process and authenticate. My question is what is the different in tomcat 6.0.37 that prevent username/password to be retrieve and what do i need to change so that username/password can be see from CAC.

Thank you very much!
Anh
Greg Charles
Sheriff

Joined: Oct 01, 2001
Posts: 2841
    
  11

Hi Anh,

Welcome to Java Ranch!

I'm going to have to do something like this soon, so I'm interested in this question. If I understand the process right, you have a third-party plugin, like ActivClient, that works with your browser to read the CAC, build up the request, and then send it to Tomcat on your server. I don't understand how Tomcat could be involved with creating that request though.

Now, I think there is also the need to establish a trust relationship. That is, Tomcat has to say it trusts DOD-signed certificates, and the client browser has to say it trusts whatever certificate you are using on Tomcat. If that trust relationship isn't established, I would expect the communication to fail right there, not send a request with an empty user name and password. Still, I'd look in that direction first. Maybe when you migrated Tomcat versions, you lost the certificate or the trust store, and that's the only problem.

Greg
AnhDung Nguyen
Greenhorn

Joined: Nov 04, 2013
Posts: 9
Hi greg,

Thanks for replying. I can tell the issue is at the *.jar file in conf/lib folder. I made a back up of this folder before install 6.0.37 tomcat then put it back after finish install. This works fine with usename/pw and CAC log-in. However the server still run on 6.0.18 lib files and browser show the app also run on 6.0.18.

But if I replace those files in lib folder with the files in lib folder of 6.0.37 Tomcat, everything works except the CAC login.

I can go back and forth with the jar file in lib folder in both versions.

I dont know what upgrade in tomcat 6.0.37 that prevent CAC info to be retrieved...
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 15964
    
  19

You guys are making me nervous. It sounds like this turkey is transmitting userids and passwords in the clear and on top of that, using some sort of security module that has to plug into the actual webapp as well as the client.

I'm not a big fan of security-as-part of the webapp. Sooner or later someone forgets to code a security check when they need to (or clueless maintenance people do something that bypasses it) and then the gates are wide open. I prefer the J2EE standard security where the server itself is the front line gatekeeper, since it examines EVERY request that comes through without the need for user-supplied logic.

What I hope this card really does is something like house a client security cert that can be picked up and transmitted on demand by the browser security plugin for the card when the server sends back an authentication request. That's relatively easy to configure: install the plugin on the browser and set up Tomcat (or better yet an Apache proxy) for client-side security certs.


Customer surveys are for companies who didn't pay proper attention to begin with.
Greg Charles
Sheriff

Joined: Oct 01, 2001
Posts: 2841
    
  11

Tim, can you be clearer about what's making you nervous? The process as I described it is using JavaEE standard security with client certificate validation. I'd like to understand more about what Anh is doing though. In particular, I don't understand how jars on the server are involved with the authentication. Which jars?
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 15964
    
  19

Greg Charles wrote:Tim, can you be clearer about what's making you nervous? The process as I described it is using JavaEE standard security with client certificate validation. I'd like to understand more about what Anh is doing though. In particular, I don't understand how jars on the server are involved with the authentication. Which jars?



It look like this in the request body: targetUrl=null&username=<myUsername>&password=<CAC-myID>


If the client is using a cert, a password is at best gilding the lily. A password that's going across in plain text, however, would more likely decrease security, not increase it.

The closest justification I can see to having a password and a cert would be in a case where the client plugin is maintaining a local security vault and the plugin wants to restrict access to that vault. In which case, the plugin would prompt client-side for the vault password. In other words, the physical client machine (holding the cert) is the primary requirement for authentication, but the password ensures that anyone who gains unauthorized access to the machine still has to supply a local password.
Greg Charles
Sheriff

Joined: Oct 01, 2001
Posts: 2841
    
  11

In that case, just Anh's making you nervous. I didn't say anything about sending a password, only that the server version doesn't normally have an influence on what the client sends in a request. Even Anh didn't say the password went in the clear. Is that implied by it being a GET?


Bill S. wrote:
Therefore, to be possess'd with double pomp,
To guard a title that was rich before,
To gild refined gold, to paint the lily,
To throw a perfume on the violet,
To smooth the ice, or add another hue
Unto the rainbow, or with taper-light
To seek the beauteous eye of heaven to garnish,
Is wasteful and ridiculous excess.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 15964
    
  19

You should be able to do a GET via SSL. It's mainly the lesser degree of security that passwords offer relative to certs that concerns me. And, of course, if someone slips up, the password is a lot more visible.
AnhDung Nguyen
Greenhorn

Joined: Nov 04, 2013
Posts: 9
Tim,

Indeed, the password is visible in clear text...

I did some more "shoot in the dark" and see that the two jar files catalina.jar and tomcat-coyote.jar in the cond/lib are the game changer here. By replace only those two files(instead of 16 files) my app show the diff version of tomcat and CAC log-in working or not. Anyone know what different in those two files between Tomcat 6.0.18 and 6.0.37?

And think these two files contain the two classes that are useed in the server.xml . They are protocol="org.apache.coyote.http11.Http11Protocol" for Connector and className="org.apache.catalina.realm.JNDIRealm" for Realm.

I'm going to extract them and compare; not sure how messy it will be but it just another shoot....

Thanks.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 15964
    
  19

catalina.jar basically IS Tomcat. So for all intents and purposes, you're converted your Tomcat 6.0.37 into Tomcat 6.0.18 with all pertinent bugs and security issues pertaining thereto.

The coyote connector is used to allow Apache HTTPD to proxy to Tomcat and provides the tunnel protocol services. Very likely it has dependencies on specific internals that vary depending on which version of Tomcat it's paired with.
AnhDung Nguyen
Greenhorn

Joined: Nov 04, 2013
Posts: 9
I'm not converting. I installed Tomcat 6.0.37 to replace 6.0.18. but the CAC authentication some how doesn't work with lib/*jar of Tomcat 6.0.37. That is why i brought back the tomcat 6.0.18 lib/*jar and everything work fine. But it doesn't look right to me to install 6.0.37 and still use 6.0.18 lib. plus the browser show it run on 6.0.18 (i see cataina.jar decide the version number).

I see the server.xml has the configuration for CAC authentication which are Connector and Realm. and i guess Connector and Realm use libraries in catalina.jar and tomcat-coyote.jar. So if there are things change in these two files, is there anything that i can change in server.xml to make it work with the new 6.0.37?
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 15964
    
  19

Trust me. if you are launching a Tomcat with a 6.0.18 catalina.jar in it you are NOT running Tomcat 6.0.37. As I said, the core of Tomcat is the catalina jar. Everything else is just refinements.

The Realm API is version-independent. As far as I can recall, you can still use a user-created Tomcat 4 Realm module unchanged with Tomcat 7. Of course, I cannot guarantee details of the base class implementations, but at the source level, I don't remember any changes.
AnhDung Nguyen
Greenhorn

Joined: Nov 04, 2013
Posts: 9
Tim Holloway wrote:Trust me. if you are launching a Tomcat with a 6.0.18 catalina.jar in it you are NOT running Tomcat 6.0.37. As I said, the core of Tomcat is the catalina jar. Everything else is just refinements.


I can't be more agreed on this. That is why i'm stick with 6.0.37 lib/*jar files version. and it's killing me . There are no code change so I think no compile is needed. So i only aim to configuration...
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 15964
    
  19

I went back and reviewed where we started. If the reason for upgrading Tomcat to 6.0.37 was due to security issues in 6.0.18, then using the 6.0.18 catalina.jar just returns the very security holes that you are trying to seal.

As I said, the Realm API hasn't changed in a very, very long time and should not be expected to change for a point release. So cynic that I am, I can't help but wonder if the security module you're having trouble with wasn't coded specifically to abuse the 6.0.18 security hole and that's the reason it won't work under 6.0.37.

I really think you need to have a talk with the people who wrote that module.
AnhDung Nguyen
Greenhorn

Joined: Nov 04, 2013
Posts: 9
Update,
I create a test page and edit the security-constraint in web.xml and be able to access that. I can now pin point to the
<security-constraint>
.
.
.
<auth-constraint>
<role-name>MyRole</role-name>
</auth-constraint>
.
.
.
</security-constraint>

if I remove that auth-constraint I can view my test page otherwise it gave me HTTP500 error.
Does anymore know what happen with auth-constraint in Tomcat 6.0.37 ?

Thanks!
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 15964
    
  19

Check the logfiles, especially the localhost log. A 500 error can be expected to produce a stacktrace.

Check the version of the DTD or schema that your web.xml uses. I wouldn't expect it to be an issue when moving point releases, but if you're using a completely different J2EE schema than the one supported by Tomcat6, that won't help.

Your example is a bit sparse, but it's not a complete usage of a role reference, so make sure that you are coding all of the other items needed such as the URL pattern controlled by that role. Also make sure it's a role defined in a security-role element.

Other than the logfile, everything I've mentioned is a shot in the dark, since most of that stuff is based on canned components that are unlikely to have changed that much between Tomcat minor versions. But it's a good idea to check anyway, just in case one of the fixes closed a loophole for defective definitions.
AnhDung Nguyen
Greenhorn

Joined: Nov 04, 2013
Posts: 9
the web.xml has customize config so I use the same from 6.0.18. it's web-app_2_3.dtd where as Tomcat 6.0.37 show web-app version="2.5" should i take that line and put it on my current web.xml?

localhost log is empty but catalina log is the one I monitor. there is error with:

org.apache.coyote.http11.Http11Processsor process
SEVERE: Error processing request
java.lang.ArrayIndexOutOfBoundsException: 0 >= 0
.
.
.

I also extract the tomcat-coyote.jar to compare org.apache.coyote.http11.Http11Processsor class between two Tomcat version and see the size diff. so I guess something was change in 6.0.37 the affect auth-constraint...
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 15964
    
  19

I recommend updating the DTD version, although it probably won't help. Except for ensuring that your web.xml is coded according to the 2.5 syntax.

I don't know any reason why the coyote connector should care about the web.xml security configuration. Coyote's purpose is to transport web requests between Apache httpd and Tomcat using its own private binary protocols. Actual authentication and authorization are things that the core Tomcat (catalina) code should be doing.

I doubt you are ever going to get anywhere by attempting to mix and match chunks of code from 2 different versions of Tomcat. You really need to get a security module that works properly for the version of Tomcat you intend to use. AND - unless you intend to be working somewhere else by that time - that includes Tomcat 7, since Tomcat 8 will be here before long and then Tomcat 6 support will begin to die.

Your determination does you credit, but in the end, this isn't a problem that you can be reasonably be expected to solve. Neither of the 2 offending subsystems are items that you really should be wasting time trying to modify to get things to work; you don't have the resources for that, you are probably not being paid enough to do it, and even if you did get it working, it would be nothing but a temporary lash-up.
AnhDung Nguyen
Greenhorn

Joined: Nov 04, 2013
Posts: 9
I narrow thing down a bit and see that the page /process.jsp is protected in web.xml but process.jsp need to be access in order to process username that retrieved from TOMCATLDAP. If I take the process.jsp out of <web-resource-collection> then process.jsp code is shown but username is null.
This configuration works in Tomcat 6.0.18. I wont know where it need to modify for Tomcat 6.0.37... Please help!
Below is the config for Connector and JNDIRealm in server.xml file:


<Connector port="443"
maxHTTPHeaderSize="8192"
allowUnsafeLegacyRenegotiation="true"
protocol="org.apache.coyote.http11.Http11Protocol"
SSLEnabled="true"
enableLookups="false"
disableUploadTimeout="true"
acceptCount="200"
maxThreads="150"
scheme="https"
secure="true"
keystoreFile="C:\Tomcat 6.0\cert\xxxx.keystore"
keystorePass="changeit"
truststoreFile="D:\Sun\SDK\jdk\jre\lib\security\cacerts"
truststorePass="changeit"
clientAuth="false"
sslProtocol="TLS"
ciphers="xxxxxxxxx"
address="0.0.0.0"/>



<Realm className="org.apache.catalina.realm.JNDIRealm"
connectionURL="ldap://xxx.xx.xx.xxx/"
alternateURL="ldap://xxx.xx.xx.xxx/"
connectionName="CN=xxxxxx,OU=xxxxxxx,OU=xxxxx,DC=xxxx,DC=xxxx,DC=local" connectionPassword="MyPassword"
authentication="simple"
referrals="follow"
userSubtree="true"
userBase="OU=xxxxx,DC=xxxx,DC=xxxx,DC=local"
userRoleName="xxx"
userSearch="(altSecurityIdentities={0})" roleBase="CN=xxxxxxx,OU=xxxxxx,OU=Accounts,DC=xxxxxxx,DC=xxxx,DC=local" roleSubtree="true"
roleName="cn"
roleSearch="(member={0})" />

web.xml security config:

<security-constraint>
<web-resource-collection>
<web-resource-name>Myapp</web-resource-name>
<url-pattern>/process.jsp</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>User</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
<login-config>
<auth-method>CLIENT-CERT</auth-method>
<realm-name>TOMCATLDAP</realm-name>
</login-config>
<security-role>
<role-name>User</role-name>
</security-role>
AnhDung Nguyen
Greenhorn

Joined: Nov 04, 2013
Posts: 9
I finally find a way to get round this however it not perfect... the security-constraint from web.xml as:
<security-constraint>
<web-resource-collection>
<web-resource-name>Myapp</web-resource-name>
<url-pattern>/process.jsp</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>User</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>

It protect the process.jsp page which trigger the smart card to get username from AD then process.jsp can log user in. The root cause that i had for the pas few days was process.jsp can't be access that's why the authentication die when the username can't reach process.jsp. But if I take the process.jsp out of <security-constraint>(protected page) then smart card doesn't get trigger and no username at all.

What I did is to set the clientAuth="true" so that the smart card get trigger every time the pages on the website are access/click so that username are always return no matter if it is needed; i also remove process.jsp from <security-constraint> so that username can reach process.jsp and do the magic to log users in. and it WORKS! The problem is now every click on the website trigger the smart card and it very annoy.

Anyone know why the protected page can not be access even the smart card authentication went through?(this is for Tomcat 6.0.37; no problem on 6.0.18, not sure it a bug or security fix... ) OR can you suggest a better work around...

Thank you!
Anh
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 15964
    
  19

I do not know enough about your setup to be able to say anything that would be of specific help, but I can state a few basic facts about J2EE standard security.

First and foremost: If you are using the J2EE standard (container-based) security system, the webapp has ZERO control over the login process. None. The login process is handled by the container not the webapp. In the case of Tomcat, that means that Tomcat does the login. It consults whatever Realm module has been plugged into the webapp context for authentication and authorization details. It fetches and processes the login and loginfail pages directly, nor via URL (If you make a direct URL request for "login.jsp" the form will display but it will not process correctly).

So if you are expecting "/process.jsp" to handle a container login, it simply won't work. Either you won't be logged in at the container level or you won't get to that JSP until AFTER the container has logged you in. The transport-guarantee determines which of those two things will happen.

The CAC card appears to contain a client-side security certificate that can be injected into the user's browser and presented on demand from the server. However transport security and user authentication are two completely different things. You can have secure transport and never login. You can theoretically at least log in and still be in insecure transport, although that's not wise. In any event, the container security Realm does not apply to transport security.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Tomcat 6.0.37 can not retrieve username and passwrod from CAC (DOD smart card)
 
Similar Threads
Servlets BASIC security question
OCSP revocation checking
Java for log in authentication? (looking for tutorial that applies to situation)
retieving the logged on user's password in weblogic10
Server Side Java and CAC authentication