Hi there,
Working to solve my SecurityExceptions running on a shared hosting, I
tried to create a similar environment on my local Tomcat. The problem is
not solved, but what I got so far may be useful for some XWiki users.
After running "server.bat -security" I started getting errors related to
Log4J already described by other threads on the mailing list archive,
which I solved this way:
1. Take the log4j.properties from WEB-INF/lib/xwiki.jar and put it as
WEB-INF/classes. The Servlet API specs state that WEB-INF/classes comes
in the web app classpath before jar files placed in WEB-INF/lib.
2. Changed so the log file gets an absolute path under the web app context:
log4j.appender.file.File=C:/java/apache-tomcat-5.5.23/webapps/xwiki/xwiki.log
3. The default security config don't let an application write to its own
files, so I had to add to Tomcat calatina.polity
grant codeBase "file:${catalina.home}/webapps/xwiki/-" {
permission java.io.FilePermission
"c:/java/apache-tomcat-5.5.23/webapps/xwiki/-", "read,write,delete";
};
And them when I start XWiki I get the same error I get from my hosting
provider, that is:
javax.servlet.ServletException: Error number 3 in 0: Could not
initialize main XWiki context
Wrapped Exception: access denied (java.io.FilePermission
\WEB-INF\xwiki.cfg read)
Note that you could have used System Properties in the policy file, such as:
grant codeBase "file:${catalina.home}/webapps/xwiki/-" {
permission java.io.FilePermission
"${catalina.home}/webapps/xwiki/-", "read,write,delete";
};
And you could have specified a file path completely outside the context
tree, which would be better from a security standpoint.
Then I though: Why not adding a permission to "/WEB-INF/xwiki.cfg" so
the (buggy) XWiki configuration file access code works as it would
without a Security Manager?
The changes to catalina.policy become:
grant codeBase "file:${catalina.home}/webapps/xwiki/-" {
permission java.io.FilePermission
"${catalina.home}/webapps/xwiki/-", "read,write,delete";
permission java.io.FilePermission "/WEB-INF/xwiki.cfg",
"read";
};
And the result is:
javax.servlet.ServletException: Error number 3 in 0: Could not
initialize main XWiki context
Wrapped Exception: Error number 3001 in 3: Cannot load store class
com.xpn.xwiki.store.XWikiHibernateStore
Wrapped Exception: access denied (java.io.FilePermission
\WEB-INF\hibernate.cfg.xml read)
Hey, XWiki reads the Hibernate configuration file the same way it reads
it's own configuration file... I guess it shouldn't, but let's apply the
same workaround:
permission java.io.FilePermission "/WEB-INF/hibernate.cfg.xml",
"read";
And then I get:
com.xpn.xwiki.XWikiException: Error number 3 in 0: Could not initialize
main XWiki context
Wrapped Exception: Error number 3202 in 3: Exception while reading
document XWiki.XWikiPreferences
Wrapped Exception: Could not create a DBCP pool
com.xpn.xwiki.XWiki.getMainXWiki(XWiki.java:291)
com.xpn.xwiki.XWiki.getXWiki(XWiki.java:383)
com.xpn.xwiki.web.XWikiAction.execute(XWikiAction.java:96)
My DBCP Pool config should be ok because the same local XWiki instance
runs fine without a security manager. Probably I need something else
(that is, not a java.io.FilePermission) to reach the local MySQL
database. Hum, who knows using an embebed HSQLDB would be a workaround....
Digging into Tomcat logs, I found:
java.net.SocketException: java.security.AccessControlException: access
denied (java.net.SocketPermission 127.0.0.1:3306 connect,resolve)
at
com.mysql.jdbc.StandardSocketFactory.connect(StandardSocketFactory.java:151)
at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:280)
at com.mysql.jdbc.Connection.createNewIO(Connection.java:1765)
at com.mysql.jdbc.Connection.<init>(Connection.java:430)
at
com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:268)
Which leads to a new permission:
permission java.net.SocketPermission "127.0.0.1:3306", "connect,
resolve";
And now to a different exception:
com.xpn.xwiki.XWikiException: Error number 3 in 0: Could not initialize
main XWiki context
Wrapped Exception: Error number 3202 in 3: Exception while reading
document XWiki.XWikiPreferences
Wrapped Exception: net.sf.ehcache.CacheException: Cannot configure
CacheManager:
jar:file:/C:/java/apache-tomcat-5.5.23/webapps/xwiki/WEB-INF/lib/xwiki.jar!/ehcache.xml:12:
Could not set attribute "path".
com.xpn.xwiki.XWiki.getMainXWiki(XWiki.java:291)
com.xpn.xwiki.XWiki.getXWiki(XWiki.java:383)
com.xpn.xwiki.web.XWikiAction.execute(XWikiAction.java:96)
Another configuration file to migrate to WEB-INF/classes. Changed it so
ehcache never uses disk:
<ehcache>
<!--
<diskStore path="java.io.tmpdir"/>
-->
<defaultCache
maxElementsInMemory="10000"
eternal="false"
overflowToDisk="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
<!--
diskPersistent="true"
-->
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
/>
</ehcache>
And I got stuck to a reflection error inside Struts:
javax.servlet.ServletException: Error number 3 in 0: Could not
initialize main XWiki context
Wrapped Exception: Error number 3202 in 3: Exception while reading
document XWiki.XWikiPreferences
Wrapped Exception: access denied (java.lang.reflect.ReflectPermission
suppressAccessChecks)
org.apache.struts.action.RequestProcessor.processException(RequestProcessor.java:535)
Well, I know a number of Struts applications that run in shared hosting
plans. There should be a way out of this.
But as I was already messing with catalina.polocy, I added:
permission java.lang.reflect.ReflectPermission
"suppressAccessChecks";
And now finally XWiki starts fine.
But when trying to create a new page:
com.xpn.xwiki.XWikiException: Error number 3201 in 3: Exception while
saving document Main.Teste do SandBox
Wrapped Exception: Error number 3211 in 3: Exception while updating
archive Main.Teste do SandBox
Wrapped Exception: access denied (java.util.PropertyPermission user.name
read)
And here we go, more messing with catalina.policy:
permission java.util.PropertyPermission "user.name", "read";
No I can create new pages inside the Wiki, and add Comments and files to
the page. Looks like I found all it takes to run XWiki inside a Security
Manager. Here's the final form of my aditions to catalina.policy:
grant codeBase "file:${catalina.home}/webapps/xwiki/-" {
permission java.io.FilePermission
"${catalina.home}/webapps/xwiki/-", "read,write,delete";
permission java.io.FilePermission "/WEB-INF/xwiki.cfg",
"read";
permission java.io.FilePermission "/WEB-INF/hibernate.cfg.xml",
"read";
permission java.net.SocketPermission "127.0.0.1:3306", "connect,
resolve";
permission java.lang.reflect.ReflectPermission
"suppressAccessChecks";
permission java.util.PropertyPermission "user.name", "read";
};
And dont' forget changes to lig4j.properties and ehcache.xml which had
to be moved from WEB-INF/lib/xwiki.jar to WEB-INF/classes.
The problem is, I'm almost sure my ISP will refuse to add
[java.lang.reflect.ReflectPermission "suppressAccessChecks"]. Others
should be fine. So I'd be very grateful if someone helps me making
Struts not need this permission.
[]s, Fernando Lozano