Packaging changes for build system, added check for EPERM to detect

errors when process is not confined (or other error).
This commit is contained in:
Dominic Reynolds 2006-10-16 20:48:28 +00:00
parent 1a3dc3f609
commit b4abae7ebc
7 changed files with 223 additions and 48 deletions

View file

@ -0,0 +1,44 @@
# $Id: Makefile 10 2006-04-12 20:31:08Z steve-beattie $
# ----------------------------------------------------------------------
# Copyright (c) 1999, 2004, 2005, 2006 NOVELL (All rights reserved)
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of version 2 of the GNU General Public
# License published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, contact Novell, Inc.
# ----------------------------------------------------------------------
NAME = tomcat_apparmor
all:
COMMONDIR=../../../common/
include Make.rules
COMMONDIR_EXISTS=$(strip $(shell [ -d ${COMMONDIR} ] && echo true))
ifeq ($(COMMONDIR_EXISTS), true)
Make.rules: $(COMMONDIR)/Make.rules
ln -f $(COMMONDIR)/Make.rules .
po/Make.rules: $(COMMONDIR)/Make-po.rules
make -C po Make.rules
endif
LIB = lib
CATALINA_HOME = /usr/share/tomcat5
# By default build 1.4 bytecode
all:
ant -Dtarget=1.4 jar jni_so
clean:
ant clean
rm -f tomcat_apparmor.spec tomcat_apparmor-*.tar.gz
install: $(SPECFILE)
ant -Dversion=$(VERSION) -Drelease=$(RELEASE) -Dcatalina_home=${CATALINA_HOME} -Dinstall_lib=${LIB} install_jar install_jni

View file

@ -28,8 +28,7 @@
This package provides an implementation of a Tomcat 5.0 Valve that calls out
to the change_hat(2) function provided by libapparmor to allow a process to
change its security context. This code is intended as a proof of concept plugin
for AppArmor and Tomcat. Any feedback is greatly appreciated.
change its security context. Any feedback is greatly appreciated.
2. Requirements
@ -48,7 +47,8 @@ From the top level directory execute:
This will create a jar file and a shared library (for the JNI interface to the
libapparmor library) and place them under dist/.
libapparmor library) and place the jar file under dist/ and the shared library
under src/jni_src.
4. Installation
@ -63,11 +63,13 @@ libapparmor library) and place them under dist/.
- Copy the shared library to somehere in your library search path:
cp dist/libJNIChangeHat.so /usr/local/lib
cp dist/libJNIChangeHat.so /usr/lib
[Note: you must ensure that the target directory is in your search path or set
the env variable LD_LIBRARY_PATH to include this directory so that tomcat can
find this library at startup]
[Note: you must ensure that the target directory is passed to tomcat via the
java.library.path propert. This can be accomplished by setting the JAVA_OPTS
enviroment variable, export JAVA_OPTS=-Djava.library.path, or set via the
env variable LD_LIBRARY_PATH to include this directory so that tomcat can
find this library at startup]
- Configure the Tomcat server to use ChangeHatValve:

View file

@ -3,10 +3,16 @@
<property name="src" location="src"/>
<property name="jni_src" location="src/jni_src"/>
<property name="build" location="build"/>
<property name="install_root" location="/"/>
<property name="catalina_home" location="/usr/share/tomcat5"/>
<property name="lib" location="lib"/>
<property name="install_lib" value="/lib"/>
<property name="dist" location="dist"/>
<property name="jarfile" location="${dist}/${ant.project.name}.jar"/>
<property name="compile.debug" value="true"/>
<property name="compile.debug" value="false"/>
<property name="target" value="1.4"/>
<property name="version" value="2.0"/>
<property name="release" value="1"/>
<fileset id="lib.jars" dir="${lib}">
<include name="**/*.jar"/>
@ -35,7 +41,8 @@
<mkdir dir="${build}"/>
<mkdir dir="${lib}"/>
<javac srcdir="${src}" destdir="${build}" includeAntRuntime="no"
classpathref="lib.path" debug="${compile.debug}">
classpathref="lib.path" debug="${compile.debug}"
source="${target}" target="${target}">
</javac>
</target>
@ -46,7 +53,11 @@
-->
<target name="jni_so" depends="compile" description="Build JNI library">
<mkdir dir="${dist}"/>
<exec dir="${jni_src}" executable="/usr/bin/make"/>
<exec dir="${jni_src}" executable="/usr/bin/make">
<arg value="DESTDIR=${dist}"/>
<arg value="VERSION=${version}"/>
<arg value="RELEASE=${release}"/>
</exec>
</target>
<target name="jar" depends="compile" description="Build jar">
@ -57,8 +68,20 @@
</jar>
</target>
<target name="run" depends="jar" description="Run jar file">
<java jar="${jarfile}" fork="yes" failonerror="true"/>
<target name="install_jni" depends="jni_so" description="Install jni so">
<exec dir="${jni_src}" executable="/usr/bin/make">
<arg value="install"/>
<arg value="DESTDIR=${install_root}"/>
<arg value="LIB=${install_lib}"/>
<arg value="VERSION=${version}"/>
<arg value="RELEASE=${release}"/>
</exec>
</target>
<target name="install_jar" depends="jni_so" description="Install jar file">
<mkdir dir="${install_root}/${catalina_home}/server/lib/"/>
<copy file="${jarfile}" tofile="${install_root}/${catalina_home}/server/lib/${ant.project.name}.jar"/>
<chmod perm="644" file="${install_root}/${catalina_home}/server/lib/${ant.project.name}.jar"/>
</target>
<target name="clean" description="Remove build and dist directories">

View file

@ -18,9 +18,11 @@ import java.nio.*;
**/
public class JNIChangeHat
{
public static int EPERM = 1;
public static int ENOMEM = 12;
public static int EACCES = 13;
public static int EFAULT = 14;
// Native 'c' function delcaration
public native int changehat_in(String subdomain, int magic_token);

View file

@ -12,7 +12,6 @@ package com.novell.apparmor.catalina.valves;
import com.novell.apparmor.JNIChangeHat;
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import org.apache.catalina.HttpRequest;
@ -127,14 +126,15 @@ public final class ChangeHatValve extends ValveBase {
if ( !( request instanceof HttpRequest)
|| !(response instanceof HttpResponse) ) {
container.getLogger().log(this.getClass().toString()
+ "[APPARMOR] Non HttpRequest received. Not changing context. ["
+ request.getInfo() + "]", container.getLogger().ERROR);
+ "[APPARMOR] Non HttpRequest received. Not changing context. "
+ "[" + request.getInfo() + "]", container.getLogger().ERROR);
context.invokeNext(request, response);
return;
}
HttpRequest httpRequest = (HttpRequest) request;
HttpServletRequest servletRequest = (HttpServletRequest) httpRequest.getRequest();
HttpServletRequest servletRequest = (HttpServletRequest)
httpRequest.getRequest();
String hatname = ChangeHatValve.DEFAULT_HAT;;
if ( getMediationType() == ChangeHatValve.SERVLET_PATH_MEDIATION ) {
@ -146,7 +146,8 @@ public final class ChangeHatValve extends ValveBase {
/*
* Select the AppArmor container for this request:
*
* 1. try hat name from either URI or ServletPath (based on configuration)
* 1. try hat name from either URI or ServletPath
* (based on configuration)
*
* 2. try hat name of the defined DEFAULT_HAT
*
@ -157,27 +158,35 @@ public final class ChangeHatValve extends ValveBase {
container.getLogger().log("[APPARMOR] ChangeHat to [" + hatname
+ "] cookie [" + cookie + "]", container.getLogger().DEBUG);
result = changehat_wrapper.changehat_in(hatname, cookie);
if ( result == JNIChangeHat.EACCES ) {
changehat_wrapper.changehat_out(cookie);
result = changehat_wrapper.changehat_in(ChangeHatValve.DEFAULT_HAT, cookie);
if ( result != 0 ) {
changehat_wrapper.changehat_out(cookie);
container.getLogger().log("[APPARMOR] ChangeHat to [" + hatname
+ "] failed. Running in parent context.",
container.getLogger().ERROR);
} else {
inSubHat = true;
}
} else if ( result != 0 ) {
changehat_wrapper.changehat_out(cookie);
container.getLogger().log("[APPARMOR] ChangeHat to [" + hatname
+ "] failed. Running in parent context.",
container.getLogger().ERROR);
if ( result == JNIChangeHat.EPERM ) {
container.getLogger().log("[APPARMOR] change_hat valve " +
"configured but Tomcat process is not confined by an " +
"AppArmor profile.", container.getLogger().ERROR);
context.invokeNext(request, response);
} else {
inSubHat = true;
if ( result == JNIChangeHat.EACCES ) {
changehat_wrapper.changehat_out(cookie);
result = changehat_wrapper.changehat_in(ChangeHatValve.DEFAULT_HAT,
cookie);
if ( result != 0 ) {
changehat_wrapper.changehat_out(cookie);
container.getLogger().log("[APPARMOR] ChangeHat to [" + hatname
+ "] failed. Running in parent context.",
container.getLogger().ERROR);
} else {
inSubHat = true;
}
} else if ( result != 0 ) {
changehat_wrapper.changehat_out(cookie);
container.getLogger().log("[APPARMOR] ChangeHat to [" + hatname
+ "] failed. Running in parent context.",
container.getLogger().ERROR);
} else {
inSubHat = true;
}
context.invokeNext(request, response);
if ( inSubHat ) changehat_wrapper.changehat_out(cookie);
}
context.invokeNext(request, response);
if ( inSubHat ) changehat_wrapper.changehat_out(cookie);
}
}

View file

@ -1,21 +1,30 @@
INCLUDE=/usr/lib/java/include
INCLUDE=/usr/lib/jvm/java/include
TOP=../..
CLASSPATH=${TOP}/build
CFLAGS=-g -O2 -Wall -Wstrict-prototypes -pipe -fpic -D_REENTRANT
CFLAGS=-g -O2 -Wall -Wstrict-prototypes -Wl,-soname,$@.${SO_VERS} -pipe -fpic -D_REENTRANT
INCLUDES=-I$(INCLUDE) -I$(INCLUDE)/linux
CLASSFILE=${CLASSPATH}/com/novell/apparmor/JNIChangeHat.class
CLASSFILE=${CLASSPATH}/com/novell/apparmor/${JAVA_CLASSNAME}.class
DESTDIR=${TOP}/dist
SO_VERS = 1
LIB = lib/
LIBDIR = /usr/${LIB}
JAVA_CLASSNAME=JNIChangeHat
TARGET=lib${JAVA_CLASSNAME}
all:
make jnichangehat
jnichangehat: libJNIChangehat.so
all: ${TARGET}.so
clean:
rm -f ${TOP}/dist/*.so JNIChangeHat.java com_novell_apparmor_JNIChangeHat.h
rm -f *.so *.so.${SO_VERS} ${JAVA_CLASSNAME}.java com_novell_apparmor_${JAVA_CLASSNAME}.h
${JAVA_CLASSNAME}.java com_novell_apparmor_${JAVA_CLASSNAME}.h: ${CLASSFILE}
javah -jni -classpath ${CLASSPATH} com.novell.apparmor.${JAVA_CLASSNAME}
JNIChangeHat.java com_novell_apparmor_JNIChangeHat.h: ${CLASSFILE}
javah -jni -classpath ${CLASSPATH} com.novell.apparmor.JNIChangeHat
${TARGET}.so: ${JAVA_CLASSNAME}.c ${JAVA_CLASSNAME}.java com_novell_apparmor_${JAVA_CLASSNAME}.h
gcc ${INCLUDES} ${CFLAGS} -shared -o ${TARGET}.so ${JAVA_CLASSNAME}.c -lapparmor
libJNIChangehat.so: JNIChangeHat.c JNIChangeHat.java com_novell_apparmor_JNIChangeHat.h
gcc ${INCLUDES} ${CFLAGS} -shared -o ${TOP}/dist/libJNIChangeHat.so JNIChangeHat.c -lapparmor
install: ${TARGET}.so
install -d $(DESTDIR)/${LIB} $(DESTDIR)${LIBDIR}
mv -f $(TARGET).so $(TARGET)-$(VERSION)-$(RELEASE).so.$(SO_VERS)
install -m 755 $(TARGET)-$(VERSION)-$(RELEASE).so.$(SO_VERS) ${DESTDIR}/${LIB}
ln -sf /${LIB}/$(TARGET)-$(VERSION)-$(RELEASE).so.$(SO_VERS) ${DESTDIR}/${LIB}/$(TARGET).so.$(SO_VERS)
ln -sf /${LIB}/$(TARGET).so.$(SO_VERS) ${DESTDIR}${LIBDIR}/$(TARGET).so

View file

@ -0,0 +1,86 @@
# $Id:$
# ----------------------------------------------------------------------
# Copyright (c) 2006 NOVELL (All rights reserved)
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of version 2 of the GNU General Public
# License published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, contact Novell, Inc.
# ----------------------------------------------------------------------
# norootforbuild
# Check first to see if distro is already defined.
%if ! %{?distro:1}0
%define distro suse
%endif
Summary: Tomcat 5 plugin for AppArmor change_hat
Name: tomcat_apparmor
Version: @@immunix_version@@
Release: @@repo_version@@
Group: System/Libraries
Source0: %{name}-%{version}-@@repo_version@@.tar.gz
License: LGPL
BuildRoot: %{?_tmppath:}%{!?_tmppath:/var/tmp}/%{name}-%{version}-build
Url: http://developer.novell.com/wiki/index.php/Novell_AppArmor
Prereq: tomcat5, servletapi5, libapparmor
BuildRequires: tomcat5, servletapi5 ant, java, libapparmor, java2-devel-packages, apparmor-docs
Provides: tomcat_apparmor
%description
tomcat_apparmor - is a plugin for Apache Tomcat version 5.x that provides
support for AppArmor change_hat for creating AppArmor containers that are
bound to discrete elements of processing within the Tomcat servlet
container. The AppArmor containers, or "hats", can be created for invidual
URL processing or per servlet.
%if %{distro} == "suse"
%define CATALINA_HOME /usr/share/tomcat5
%endif
%define APPARMOR_DOC_DIR /usr/share/doc/packages/apparmor-docs/
%define JNI_SO libJNIChangeHat.so
%define JAR_FILE changeHatValve.jar
%prep
%setup -q
%build
[ "${RPM_BUILD_ROOT}" != "/" ] && rm -rf ${RPM_BUILD_ROOT}
ant -Ddist=${RPM_BUILD_DIR}/%{name}-%{version} -Dtarget=1.4 jar jni_so
%install
ant -Ddist=${RPM_BUILD_DIR}/%{name}-%{version} -Dversion=%{version} -Drelease=%{release} -Dcatalina_home=%{CATALINA_HOME} -Dinstall_root=${RPM_BUILD_ROOT} -Dinstall_lib=%{_lib} install_jar install_jni
mkdir -p ${RPM_BUILD_ROOT}%{APPARMOR_DOC_DIR}
install ${RPM_BUILD_DIR}/%{name}-%{version}/README.tomcat_apparmor ${RPM_BUILD_ROOT}%{APPARMOR_DOC_DIR}
%clean
[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
%files
%defattr(-,root,root)
%{CATALINA_HOME}/server/lib/%{JAR_FILE}
/%{_lib}/lib*
/%{_libdir}/lib*
%{APPARMOR_DOC_DIR}/README.tomcat_apparmor
%post
ldconfig
%postun
ldconfig
%changelog
* Mon Oct 9 2006 - dreynolds@suse.de
- Initial package creation.