Re: Propagation of Subject with JAAS and SecurityManager enabled

2017-02-22 Thread kommersz
 
Thank you, Martin, for answering despite of the messed up email!

A short point to clarify: I am using JAASRealm, and a custom jaas.config file 
which  does not refer to AASMemoryLoginModule. So JAASMemoryLoginModule is also 
not called.
As for my custom login module, I checked it, and it does use the same Subject 
that is passed to it upon initialize(...), it just adds Principals to it, so it 
shall be imho ok.

My gut feeling still tells me that the current construct might not work, as it 
seems that the session (with the key Globals.SUBJECT_ATTR) is used for passing 
the Subject between different parts of the code - but at all the places where 
Globals.SUBJECT_ATTR is used to access the session, a new Subject is created, 
and put into the session under this key...

Martin Gainty  wrote:
>> 
>//in org.apache.catalina.security.SecurityUtil subject comes from the session 
>here is code from execute:
> 
> 
>// first argument is always the HttpServletRequest object  
>   if (targetArguments != null && targetArguments[0] instanceof 
> HttpServletRequest){HttpServletRequest request =  
>(HttpServletRequest)targetArguments[0]; 
> boolean hasSubject = false; //get the session but dont create the session if 
> already invalidatedHttpSession session = 
> request.getSession(false);if (session != null){   
>  subject = 
> (Subject)session.getAttribute(Globals.SUBJECT_ATTR);
> hasSubject = (subject != null);} //IF subject was null to 
> begin with AND//IF subject was not previously stored in session then create a 
> new Subjectif (subject == null){subject = 
> new Subject(); //if principal parameter is not null then add it to subject
> if (principal != null){
 subject.getPrincipals().add(principal);}   
 } //store subject for further referenceif (session != 
null && !hasSubject) {
session.setAttribute(Globals.SUBJECT_ATTR, subject);}   
 } Subject.doAsPrivileged(subject, pea, null);//end 
SecurityUtil //org.apache.el.catalina.realm.JAASMemoryLoginModule.java://notice 
that it is responsibility of developer to pass in a valid subject to initialize 
method of JAASMemoryLoginModule public void initialize(Subject subject, 
CallbackHandler callbackHandler,Map sharedState, Map 
options) {log.debug("Init");// Save configuration values
this.subject = subject; did you verify you are passing valid subject to 
initialize method of JAASMemoryLoginModule
> ? 
>Martin 
>__  From: kommersz 
>
>Sent: Wednesday, February 22, 2017 5:17 AM
>To: users@tomcat.apache.org
>Subject: Propagation of Subject with JAAS and SecurityManager enabled
>
>(noticed that my previous post on the same was somewhat garbled - reposting 
>reformatted)
>
>Hi,
>
>I am playing around with the following things:
> - X.509 authentication
>- Security Manager enabled
>- Custom JAAS login module via JAASRealm
>
>My custom JAAS login module properly propagates a javax.security.auth.Subject 
>instance at commit() back. My aim is to use this javax.security.auth.Subject 
>as a basis for authorization checks - expect 
>org.apache.catalina.security.SecurityUtil to take this over.
>Curiously, by the time it comes to 
>org.apache.catalina.security.SecurityUtil.execute(...) applying 
>Subject.doAsPrivileged, it is done with another javax.security.auth.Subject 
>instance.
>
>Having looked a bit into it what is happening, I see the followings
>- org.apache.catalina.security.SecurityUtil.execute(...) looks for a subject 
>to be present in the session object with key Globals.SUBJECT_ATTR 
>("javax.security.auth.subject").
>- if it is not present, it will create a new blank Subject containing only one 
>Principal, which is extracted from the requests 
>org.apache.catalina.connector.Request object (and store it in the session 
>afterwards under Globals.SUBJECT_ATTR)
>- org.apache.catalina.connector.Requests setUserPrincipal(Principal 
>principal) sets the session object with key Globals.SUBJECT_ATTR to a newly 
>initialized javax.security.auth.Subject with a single Principal. 
>
>Summary: to me it seems that the mechanism currently used to propagate the 
>Subject to org.apache.catalina.security.SecurityUtil.execute(...) _always_ 
>creates a new empty Subject and adds a single user principal into it.
>
>Questions:
>- do I miss something about Subject propagation?
>If not:
>- is this intentionally planned like this?
>- would it not make sense to allow Subjects to be propagated to SecurityUtil 
>1:1 from JAAS Login modules to be used as the Subject for 

Re: Strange URL rewrite when reverse proxy with Apache HTTP Server

2017-02-22 Thread Aaron Gray
So this is interesting.

So from HTTP server #1 (172.1.1.1 example) I hit:
https://172.1.1.1:23270/static and I see this in the HTTP log:
172.1.1.1 - - [22/Feb/2017:10:14:48 -0800] "GET /static/ HTTP/1.1" 200 32
I see this in the Tomcat log:
172.1.1.1 - - [22/Feb/2017:10:14:48 -0800] "GET /static/ HTTP/1.1" 200 32
((( Yes I know they look identical, but the logformat is the same, so it
comes out looking the same, but they are  two diff log files totally )))

I then hit the https://loadbalancer.domain.com/static from my Win10 laptop
 (10.1.1.2 example)
and I see this in the HTTP server #1 log, but NOTHING in the tomcat access
log.
10.1.1.2 - - [22/Feb/2017:10:20:02 -0800] "-" 408 -

So 408.  Timeout.  Hmm... Why?  We KNOW that it can connect from http ->
tomcat:18080 perfectly.   So is it a timeout BACK to the F5?  That i dont
know yet.

On Tue, Feb 21, 2017 at 3:39 PM, André Warnier (tomcat) 
wrote:

> On 21.02.2017 23:28, Aaron Gray wrote:
>
>> Antonio:  The Tomcat server has no knowledge of the F5, or that it is
>> being
>> fronted by an Apache HTTP Server.  I do SSL termination in Apache HTTP
>> Server, and clear-text from HTTP to Tomcat.
>> My redirect port for the normal HTTP listen in Tomcat is commented out.
>>  > connectionTimeout="2" />
>>  
>>  
>>
>> Andre:
>> The URL I am using is https://loadbalancer.domain.com
>> It is listening on port 80 and 443, if you hit 80, internally it redirects
>> you to 443.  No SSL cert on the F5 load balancer.  It simply sends the
>> traffic to one of the two HTTP servers (round-robin, also tried
>> persistence, no difference).  The HTTP server is listening only for HTTPS
>> on 23270/tcp.
>>
>> Hitting https://loadbalancer.domain.com
>> I see my "Hello world!" which is all that is in index.html.  This is the
>> DocumentRoot of HTTP, and *not* proxied over at this time.
>>
>
> So in this case, there is no delay, and you get the Apache httpd-hosted
> "index.html" containing "Hello World. Right ?
>
>   Only
>
>> /SelfService and /static are proxied
>> /static just being my test of static content, but still served up by
>> Tomcat..
>>
>> It's exactly 30 seconds before the page cannot be loaded when trying
>> anything proxied to Tomcat, but also accessed via the F5 load balancer.
>> Not sure where the 30 seconds comes from; perhaps a load balancer time
>> out,
>> as I dont see a "30" in my httpd configurations or my tomcat server.xml
>>
>>
> You can certainly look at the Apache httpd logs, and the tomcat logs, to
> see if you get a request or not.
> In Apache httpd, you can set the loglevel individually for mod_proxy (if
> you are running v 2.4), and it should show something if it gets this
> request and forwards it to tomcat.
> In tomcat, you can either enable an access log (which will show if it
> receives this request), or you could temporarily remove/rename the /static
> webapp. This way, it should trigger an error "not found" which you would
> also see in the error log.
>
> There should be nothing between them to hinder it.  We have many load
>> balancers and this one specifically you dont need to open any firewall
>> requests for the specific networks the HTTP servers are on.  I did have to
>> get the firewall opened up to allow me to hit
>> https://loadbalancer.domain.com because the VIP for "
>> loadbalancer.domain.com"
>> is in the DMZ, and my Desktop & VPN networks cannot hit it on 80/443
>> without opening holes.  But beyond that, any connection from the F5 to the
>> HTTP Server should be 100% open bi-directional, since same subnet.
>>
>>
> But something isn't working, otherwise you would not be asking.
> So,
>
> a) hitting the tomcat webapps through httpd seems to be working fine
>   (browser -> httpd:23270 -> tomcat:18080 -> webapp or static)
>
> b) hitting a non-proxied-to-tomcat resource of httpd seems to work fine
> too, even through the F5
>   (browser -> F5:443 -> httpd:23270 -> html page)
>
> c) it is only when you do :
>   (browser -> F5:443 -> httpd:23270 -> tomcat:18080 -> webapp or static)
>   that you see this issue
>
> It would really help if you looked in the logs of both httpd and tomcat,
> and checked for differences betweens cases a, b and c above.
>
> I believe that the F5 message with the port 23270 is a minor issue, of
> information disclosure by the F5, that it should not disclose.
>
> But the reason why it returns this error is obviously that in that case,
> it does not get a response from his request to httpd.
> The reason for this response not coming back to the F5 (in case c only),
> can be due to either httpd or tomcat. But F5 doesn't know about tomcat. So
> for the F5, it is httpd which is not responding. Thus,
> - either httpd is never getting the request from the F5 (unlikely, because
> in b above it gets it and responds)
> - or httpd is getting the request from the F5, but not forwarding it to
> tomcat, but also not returning an immediate error response to F5 (which
> seems also 

Re: Getting application root path before servlet is initialized?

2017-02-22 Thread Antonio S . Cofiño

Dear Martin,


On 21/02/17 13:31, Martin Knoblauch wrote:

Hi,

  is there a way to find the absolute path of the application root before
the servlet is initialized?

Alternatively: is there a way to defer the initialization of a datasource
until the servlet is initialized?

Background: I have extended "org.apache.tomcat.jdbc.pool.DataSourceFactory"
to automatically set credentials so that they are not stored in the
"Catalina/localhost/XXX.xml" file. Instead they are taken from encrypted
values in a file below the application root. Works fine if I know that path
at "createDataSource" time.

In order to avoid hard coding that path, I need a programmatic to find that
value. Unfortunately the datasource is initialized before the servlet, so
"getRealPath()" is not working yet.

Environment is Tomcat 8 plus JDK 8. Plus an commercial application that I
do not want to name :-)

Thanks in advance
Martin
For this purpose I use the ant properties interpolation on tomcat 
configuration xml-files

http://tomcat.apache.org/tomcat-7.0-doc/config/index.html

It may be you requirements needs a more elaborated solution, but this a 
convenient way to do it.


Regards
Antonio


-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org



Re: Getting application root path before servlet is initialized?

2017-02-22 Thread Daniel Küppers

Am 22.02.2017 um 11:19 schrieb Martin Knoblauch:

On Tue, Feb 21, 2017 at 8:55 PM, Mark Thomas  wrote:


On 21/02/2017 13:31, Martin Knoblauch wrote:

Hi,

  is there a way to find the absolute path of the application root before
the servlet is initialized?

Alternatively: is there a way to defer the initialization of a datasource
until the servlet is initialized?

Background: I have extended "org.apache.tomcat.jdbc.pool.

DataSourceFactory"

to automatically set credentials so that they are not stored in the
"Catalina/localhost/XXX.xml" file. Instead they are taken from encrypted
values in a file below the application root. Works fine if I know that

path

at "createDataSource" time.

And the decryption key for that file is stored where?

https://wiki.apache.org/tomcat/FAQ/Password



  Thanks for link. It clearly reflects my opinion as well, but the customer
demand is:

- no plain-text credentials (Big multinational company security policies -
fight them if you need the fun). And yes, this is all about making auditors
happy
- minimize the locations where credentials are stored. This is only lightly
related to the decrypt issue. Having to store identical stuff in more than
one place is opening up all other sorts of practical issues

  So, yes - any mechanism that can decrypt needs to store the key somewhere
and this just shifts away the problem from securing one item to securing
another one. In my case the application (that I will not reveal here)
stores encrypted DB credentials in its configuration and provides an API to
retrieve them decrypted. I guess, the key is somewhere in the source code
(likely obfuscated to prevent casual hacking by debugging). the less I know
... :-)


In order to avoid hard coding that path, I need a programmatic to find
that

value. Unfortunately the datasource is initialized before the servlet, so
"getRealPath()" is not working yet.

Environment is Tomcat 8 plus JDK 8. Plus an commercial application that I
do not want to name :-)

Ignoring what I suspect is a fundamental flaw in this plan, you probably
want a ServletContextListener and contextInitialized()



Thanks again for the hint. Will have a look. In the meanwhile  I found a
way by looking at

this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath();

Adding some assumptions about the classpath (which are required to be true
in this whole context) this gives me the needed information :-)

Thanks
Martin


Mark


I could imagine that the use of a secure key-value store would be 
helpfull in this scenario.
vault is a great solution for this. quick googling [1] brings a tomcat 
implementation for vault.

If youre not allready familiar with vault, give it a try [2].

Daniel

[1] https://github.com/januslabs/tomcat-vault
[2] https://www.hashicorp.com/vault.html

-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org



Re: Getting application root path before servlet is initialized?

2017-02-22 Thread Martin Knoblauch
On Tue, Feb 21, 2017 at 8:55 PM, Mark Thomas  wrote:

> On 21/02/2017 13:31, Martin Knoblauch wrote:
> > Hi,
> >
> >  is there a way to find the absolute path of the application root before
> > the servlet is initialized?
> >
> > Alternatively: is there a way to defer the initialization of a datasource
> > until the servlet is initialized?
> >
> > Background: I have extended "org.apache.tomcat.jdbc.pool.
> DataSourceFactory"
> > to automatically set credentials so that they are not stored in the
> > "Catalina/localhost/XXX.xml" file. Instead they are taken from encrypted
> > values in a file below the application root. Works fine if I know that
> path
> > at "createDataSource" time.
>
> And the decryption key for that file is stored where?
>
> https://wiki.apache.org/tomcat/FAQ/Password
>
>
 Thanks for link. It clearly reflects my opinion as well, but the customer
demand is:

- no plain-text credentials (Big multinational company security policies -
fight them if you need the fun). And yes, this is all about making auditors
happy
- minimize the locations where credentials are stored. This is only lightly
related to the decrypt issue. Having to store identical stuff in more than
one place is opening up all other sorts of practical issues

 So, yes - any mechanism that can decrypt needs to store the key somewhere
and this just shifts away the problem from securing one item to securing
another one. In my case the application (that I will not reveal here)
stores encrypted DB credentials in its configuration and provides an API to
retrieve them decrypted. I guess, the key is somewhere in the source code
(likely obfuscated to prevent casual hacking by debugging). the less I know
... :-)

> In order to avoid hard coding that path, I need a programmatic to find
> that
> > value. Unfortunately the datasource is initialized before the servlet, so
> > "getRealPath()" is not working yet.
> >
> > Environment is Tomcat 8 plus JDK 8. Plus an commercial application that I
> > do not want to name :-)
>
> Ignoring what I suspect is a fundamental flaw in this plan, you probably
> want a ServletContextListener and contextInitialized()
>
>
Thanks again for the hint. Will have a look. In the meanwhile  I found a
way by looking at

this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath();

Adding some assumptions about the classpath (which are required to be true
in this whole context) this gives me the needed information :-)

Thanks
Martin

> Mark
>
>


Propagation of Subject with JAAS and SecurityManager enabled

2017-02-22 Thread kommersz
(noticed that my previous post on the same was somewhat garbled - reposting 
reformatted) Hi, I am playing around with the following things: - X.509 
authentication- Security Manager enabled- Custom JAAS login module via 
JAASRealm My custom JAAS login module properly propagates a 
javax.security.auth.Subject instance at commit() back. My aim is to use this 
javax.security.auth.Subject as a basis for authorization checks - expect 
org.apache.catalina.security.SecurityUtil to take this over. Curiously, by the 
time it comes to org.apache.catalina.security.SecurityUtil.execute(...) 
applying Subject.doAsPrivileged, it is done with another 
javax.security.auth.Subject instance. Having looked a bit into it what is 
happening, I see the followings:- 
org.apache.catalina.security.SecurityUtil.execute(...) looks for a subject to 
be present in the session object with key Globals.SUBJECT_ATTR 
("javax.security.auth.subject").- if it is not present, it will create a new 
blank Subject containing only one P
 rincipal, which is extracted from the requests 
org.apache.catalina.connector.Request object (and store it in the session 
afterwards under Globals.SUBJECT_ATTR)- 
org.apache.catalina.connector.Requests setUserPrincipal(Principal 
principal) sets the session object with key Globals.SUBJECT_ATTR to a newly 
initialized javax.security.auth.Subject with a single Principal. Summary: to me 
it seems that the mechanism currently used to propagate the Subject to 
org.apache.catalina.security.SecurityUtil.execute(...) _always_ creates a new 
empty Subject and adds a single user principal into it. Questions:- do I miss 
something about Subject propagation?If not:- is this intentionally planned like 
this?- would it not make sense to allow Subjects to be propagated to 
SecurityUtil 1:1 from JAAS Login modules to be used as the Subject for 
privileged execution? Btw, I am on 7.0.68, but seems that the relevant pieces 
of code has not been changed by 7.0.75 - most recent version checked. Thank you
  for any help upfront! Regards,Gabor