Initial commit

This commit is contained in:
Your Name
2026-04-23 17:07:55 +08:00
commit b7e39e063b
16725 changed files with 1625565 additions and 0 deletions
+7
View File
@@ -0,0 +1,7 @@
*.pyc
*.pyo
/*.patch
*.swp
*.orig
*.rej
*~
+127
View File
@@ -0,0 +1,127 @@
.before-my-script: &before-my-script
- echo "$ERR_REPORT_USERNAME" > ~/.oe-send-error
- echo "$ERR_REPORT_EMAIL" >> ~/.oe-send-error
- export PATH=~/.local/bin:$PATH
- wget https://bootstrap.pypa.io/get-pip.py
- python3 get-pip.py
- python3 -m pip install kas
.after-my-script: &after-my-script
- cd $CI_PROJECT_DIR/poky
- . ./oe-init-build-env $CI_PROJECT_DIR/build
- for x in `ls $CI_PROJECT_DIR/build/tmp/log/error-report/ | grep error_report_`; do
- send-error-report -y tmp/log/error-report/$x
- done
- rm -fr $CI_PROJECT_DIR/build
stages:
- base
- parsec
- musl
- test
.base:
before_script:
- *before-my-script
stage: base
after_script:
- *after-my-script
.parsec:
before_script:
- *before-my-script
stage: parsec
after_script:
- *after-my-script
.musl:
before_script:
- *before-my-script
stage: musl
after_script:
- *after-my-script
.test:
before_script:
- *before-my-script
stage: test
after_script:
- *after-my-script
qemux86:
extends: .base
script:
- kas shell kas/$CI_JOB_NAME.yml -c "bitbake -k security-build-image integrity-image-minimal"
- kas build --target harden-image-minimal kas/$CI_JOB_NAME-harden.yml
qemux86-musl:
extends: .musl
needs: ['qemux86']
script:
- kas build --target security-build-image kas/$CI_JOB_NAME.yml
qemux86-parsec:
extends: .parsec
needs: ['qemux86']
script:
- kas build --target security-build-image kas/$CI_JOB_NAME.yml
qemux86-test:
extends: .test
needs: ['qemux86']
allow_failure: true
script:
- kas build --target security-test-image kas/$CI_JOB_NAME.yml
- kas build -c testimage --target security-test-image kas/$CI_JOB_NAME.yml
qemux86-64:
extends: .base
script:
- kas shell kas/$CI_JOB_NAME.yml -c "bitbake -k security-build-image security-tpm-image security-tpm2-image integrity-image-minimal"
- kas build --target dm-verity-image-initramfs kas/$CI_JOB_NAME-dm-verify.yml
- kas build --target security-build-image kas/$CI_JOB_NAME-alt.yml
qemux86-64-parsec:
extends: .parsec
needs: ['qemux86-64']
script:
- kas build --target security-build-image kas/$CI_JOB_NAME.yml
qemuarm:
extends: .base
script:
- kas build --target security-build-image kas/$CI_JOB_NAME.yml
qemuarm-parsec:
extends: .parsec
needs: ['qemuarm']
script:
- kas build --target security-build-image kas/$CI_JOB_NAME.yml
qemuarm64:
extends: .base
script:
- kas shell kas/$CI_JOB_NAME.yml -c "bitbake -k security-build-image security-tpm2-image integrity-image-minimal"
- kas build --target security-build-image kas/$CI_JOB_NAME-alt.yml
qemuarm64-musl:
extends: .musl
needs: ['qemuarm64']
script:
- kas build --target security-build-image kas/$CI_JOB_NAME.yml
qemuarm64-parsec:
extends: .parsec
needs: ['qemuarm64']
script:
- kas build --target security-build-image kas/$CI_JOB_NAME.yml
qemumips64:
extends: .base
script:
- kas build --target security-build-image kas/$CI_JOB_NAME.yml
qemuriscv64:
extends: .base
script:
- kas build --target security-build-image kas/$CI_JOB_NAME.yml
+17
View File
@@ -0,0 +1,17 @@
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
+94
View File
@@ -0,0 +1,94 @@
Meta-security
=============
The bbappend files for some recipes (e.g. linux-yocto) in this layer need
to have 'security' in DISTRO_FEATURES to have effect.
To enable them, add in configuration file the following line.
DISTRO_FEATURES:append = " security"
If meta-security is included, but security is not enabled as a
distro feature a warning is printed at parse time:
You have included the meta-security layer, but
'security' has not been enabled in your DISTRO_FEATURES. Some bbappend files
and preferred version setting may not take effect.
If you know what you are doing, this warning can be disabled by setting the following
variable in your configuration:
SKIP_META_SECURITY_SANITY_CHECK = 1
This layer provides security tools, hardening tools for Linux kernels
and libraries for implementing security mechanisms.
Dependencies
============
This layer depends on:
URI: git://git.openembedded.org/openembedded-core
branch: [same one as checked out for this layer]
URI: git://git.openembedded.org/meta-openembedded/meta-oe
branch: [same one as checked out for this layer]
Adding the security layer to your build
========================================
In order to use this layer, you need to make the build system aware of
it.
Assuming the security layer exists at the top-level of your
yocto build tree, you can add it to the build system by adding the
location of the security layer to bblayers.conf, along with any
other layers needed. e.g.:
BBLAYERS ?= " \
/path/to/oe-core/meta \
/path/to/meta-openembedded/meta-oe \
/path/to/layer/meta-security "
Optional Dynamic layer dependancy
======================================
URI: git://git.openembedded.org/meta-openembedded/meta-oe
URI: git://git.openembedded.org/meta-openembedded/meta-perl
URI: git://git.openembedded.org/meta-openembedded/meta-python
BBLAYERS += "/path/to/layer/meta-openembedded/meta-oe"
BBLAYERS += "/path/to/layer/meta-openembedded/meta-perl"
BBLAYERS += "/path/to/layer/meta-openembedded/meta-python"
This will activate the dynamic-layer mechanism.
Maintenance
======================================
Send pull requests, patches, comments or questions to yocto@lists.yoctoproject.org
When sending single patches, please using something like:
'git send-email -1 --to yocto@lists.yoctoproject.org --subject-prefix=meta-security][PATCH'
These values can be set as defaults for this repository:
$ git config sendemail.to yocto@lists.yoctoproject.org
$ git config format.subjectPrefix meta-security][PATCH
Now you can just do 'git send-email origin/master' to send all local patches.
For pull requests, please use create-pull-request and send-pull-request.
Maintainers: Armin Kuster <akuster808@gmail.com>
License
=======
All metadata is MIT licensed unless otherwise stated. Source code included
in tree for individual recipes is under the LICENSE stated in each recipe
(.bb file) unless otherwise stated.
+11
View File
@@ -0,0 +1,11 @@
#
# Copyright 2022 Armin Kuster <akuster808@gmail.com>
#
STAGING_AIDE_DIR ?= "${TMPDIR}/work-shared/${MACHINE}/aida"
AIDE_INCLUDE_DIRS ?= "/lib"
AIDE_SKIP_DIRS ?= "/lib/modules/.\*"
AIDE_SCAN_POSTINIT ?= "0"
AIDE_RESCAN_POSTINIT ?= "0"
@@ -0,0 +1,52 @@
#
# Copyright 2022 Armin Kuster <akuster808@gmail.com>
#
# This class creates the initial aide database durning
# the build cycle allowing for that set being skipped during boot
# It has an additional benefit of having not being tamper with
# after build.
#
# To have the aide db created during build
# 1. Extend local.conf:
# INHERIT += "adie-init-db"
#
# These are the defaults as defined in aide-base.bbclass
# They can be overriden in your local.conf or other distro include
#
# To define where the share directory should be.
# STAGING_AIDE_DIR = "${TMPDIR}/work-shared/${MACHINE}/aida"
#
# To define which directories should be inclued in a scan
# AIDE_INCLUDE_DIRS ?= "/lib"
#
# To exclude directories and files from being scanned
# AIDE_SKIP_DIRS ?= "/lib/modules/.\*"
#
# To controll if a db init should happen at postint
# AIDE_SCAN_POSTINIT ?= "0"
#
# To cotroll if a db recan should be run at postinit
# AIDE_RESCAN_POSTINIT ?= "0"
inherit aide-base
aide_init_db() {
for dir in ${AIDE_INCLUDE_DIRS}; do
echo "${IMAGE_ROOTFS}${dir} NORMAL" >> ${STAGING_AIDE_DIR}/aide.conf
done
for dir in ${AIDE_SKIP_DIRS}; do
echo "!${IMAGE_ROOTFS}${dir}" >> ${STAGING_AIDE_DIR}/aide.conf
done
${STAGING_AIDE_DIR}/bin/aide -c ${STAGING_AIDE_DIR}/aide.conf --init
gunzip ${STAGING_AIDE_DIR}/lib/aide.db.gz
# strip out native path
sed -i -e 's:${IMAGE_ROOTFS}::' ${STAGING_AIDE_DIR}/lib/aide.db
gzip -9 ${STAGING_AIDE_DIR}/lib/aide.db
cp -f ${STAGING_AIDE_DIR}/lib/aide.db.gz ${IMAGE_ROOTFS}${libdir}/aide
}
EXTRA_IMAGEDEPENDS:append = " aide-native"
ROOTFS_POSTPROCESS_COMMAND:append = " aide_init_db;"
@@ -0,0 +1,7 @@
check_security () {
${STAGING_BINDIR_NATIVE}/buck-security -sysroot ${IMAGE_ROOTFS} -log ${T}/log.do_checksecurity.${PID} -disable-checks "checksum,firewall,packages_problematic,services,sshd,usermask" -no-sudo > /dev/null
}
EXTRA_IMAGEDEPENDS += "buck-security-native"
ROOTFS_POSTPROCESS_COMMAND += "check_security;"
+200
View File
@@ -0,0 +1,200 @@
# SPDX-License-Identifier: MIT
#
# Copyright (C) 2020 BayLibre SAS
# Author: Bartosz Golaszewski <bgolaszewski@baylibre.com>
#
# This bbclass allows creating of dm-verity protected partition images. It
# generates a device image file with dm-verity hash data appended at the end
# plus the corresponding .env file containing additional information needed
# to mount the image such as the root hash in the form of ell variables. To
# assure data integrity, the root hash must be stored in a trusted location
# or cryptographically signed and verified.
#
# Optionally, we can store the hash data on a separate device or partition
# for improved compartmentalization and ease of use/deployment.
#
# Usage:
# DM_VERITY_IMAGE = "core-image-full-cmdline" # or other image
# DM_VERITY_IMAGE_TYPE = "ext4" # or ext2, ext3 & btrfs
# DM_VERITY_SEPARATE_HASH = "1" # optional; store hash on separate dev
# IMAGE_CLASSES += "dm-verity-img"
#
# Using the GPT UUIDs specified in the standard can also be useful in that
# they are displayed and translated in cfdisk output.
#
# DM_VERITY_ROOT_GUID = <UUID for your architecture and root-fs>
# DM_VERITY_RHASH_GUID = <UUID for your architecture and verity-hash>
# https://uapi-group.org/specifications/specs/discoverable_partitions_specification/
# The resulting image can then be used to implement the device mapper block
# integrity checking on the target device.
# Define the location where the DM_VERITY_IMAGE specific dm-verity root hash
# is stored where it can be installed into associated initramfs rootfs.
STAGING_VERITY_DIR ?= "${TMPDIR}/work-shared/${MACHINE}/dm-verity"
# Define the data block size to use in veritysetup.
DM_VERITY_IMAGE_DATA_BLOCK_SIZE ?= "1024"
# Define the hash block size to use in veritysetup.
DM_VERITY_IMAGE_HASH_BLOCK_SIZE ?= "4096"
# Should we store the hash data on a separate device/partition?
DM_VERITY_SEPARATE_HASH ?= "0"
# These are arch specific. We could probably intelligently auto-assign these?
# Take x86-64 values as defaults. No impact on functionality currently.
# See SD_GPT_ROOT_X86_64 and SD_GPT_ROOT_X86_64_VERITY in the spec.
# Note - these are passed directly to sgdisk so hyphens needed.
DM_VERITY_ROOT_GUID ?= "4f68bce3-e8cd-4db1-96e7-fbcaf984b709"
DM_VERITY_RHASH_GUID ?= "2c7357ed-ebd2-46d9-aec1-23d437ec2bf5"
# Process the output from veritysetup and generate the corresponding .env
# file. The output from veritysetup is not very machine-friendly so we need to
# convert it to some better format. Let's drop the first line (doesn't contain
# any useful info) and feed the rest to a script.
process_verity() {
local ENV="${STAGING_VERITY_DIR}/${IMAGE_BASENAME}.$TYPE.verity.env"
local WKS_INC="${STAGING_VERITY_DIR}/${IMAGE_BASENAME}.$TYPE.wks.in"
rm -f $ENV
# Each line contains a key and a value string delimited by ':'. Read the
# two parts into separate variables and process them separately. For the
# key part: convert the names to upper case and replace spaces with
# underscores to create correct shell variable names. For the value part:
# just trim all white-spaces.
IFS=":"
while read KEY VAL; do
printf '%s=%s\n' \
"$(echo "$KEY" | tr '[:lower:]' '[:upper:]' | sed 's/ /_/g')" \
"$(echo "$VAL" | tr -d ' \t')" >> $ENV
done
# Add partition size
echo "DATA_SIZE=$SIZE" >> $ENV
# Add whether we are storing the hash data separately
echo "SEPARATE_HASH=${DM_VERITY_SEPARATE_HASH}" >> $ENV
# Configured for single partition use of veritysetup? OK, we are done.
if [ ${DM_VERITY_SEPARATE_HASH} -eq 0 ]; then
return
fi
# Craft up the UUIDs that are part of the verity standard for root & hash
# while we are here and in shell. Re-read our output to get ROOT_HASH
# and then cut it in 1/2 ; HI for data UUID and LO for hash-data UUID.
# https://uapi-group.org/specifications/specs/discoverable_partitions_specification/
ROOT_HASH=$(cat $ENV | grep ^ROOT_HASH | sed 's/ROOT_HASH=//' | tr a-f A-F)
ROOT_HI=$(echo "obase=16;ibase=16;$ROOT_HASH/2^80" | /usr/bin/bc)
ROOT_LO=$(echo "obase=16;ibase=16;$ROOT_HASH%2^80" | /usr/bin/bc)
# Hyphenate as per UUID spec and as expected by wic+sgdisk parameters.
# Prefix with leading zeros, in case hash chunks weren't using highest bits
# "bc" needs upper case, /dev/disk/by-partuuid/ is lower case. <sigh>
ROOT_UUID=$(echo 00000000$ROOT_HI | sed 's/.*\(.\{32\}\)$/\1/' | \
sed 's/./-&/9;s/./-&/14;s/./-&/19;s/./-&/24' | tr A-F a-f )
RHASH_UUID=$(echo 00000000$ROOT_LO | sed 's/.*\(.\{32\}\)$/\1/' | \
sed 's/./-&/9;s/./-&/14;s/./-&/19;s/./-&/24' | tr A-F a-f )
# Emit the values needed for a veritysetup run in the initramfs
echo "ROOT_UUID=$ROOT_UUID" >> $ENV
echo "RHASH_UUID=$RHASH_UUID" >> $ENV
# Create wks.in fragment with build specific UUIDs for partitions.
# Unfortunately the wks.in does not support line continuations...
# First, the unappended filesystem data partition.
echo 'part / --source rawcopy --ondisk sda --sourceparams="file=${IMGDEPLOYDIR}/${DM_VERITY_IMAGE}-${MACHINE}.${DM_VERITY_IMAGE_TYPE}.verity" --part-name verityroot --part-type="${DM_VERITY_ROOT_GUID}"'" --uuid=\"$ROOT_UUID\"" > $WKS_INC
# note: no default mount point for hash data partition
echo 'part --source rawcopy --ondisk sda --sourceparams="file=${IMGDEPLOYDIR}/${DM_VERITY_IMAGE}-${MACHINE}.${DM_VERITY_IMAGE_TYPE}.vhash" --part-name verityhash --part-type="${DM_VERITY_RHASH_GUID}"'" --uuid=\"$RHASH_UUID\"" >> $WKS_INC
}
verity_setup() {
local TYPE=$1
local INPUT=${IMAGE_NAME}${IMAGE_NAME_SUFFIX}.$TYPE
local SIZE=$(stat --printf="%s" $INPUT)
local OUTPUT=$INPUT.verity
local OUTPUT_HASH=$INPUT.verity
local HASH_OFFSET=""
local SETUP_ARGS=""
local SAVED_ARGS="${STAGING_VERITY_DIR}/${IMAGE_BASENAME}.$TYPE.verity.args"
install -d ${STAGING_VERITY_DIR}
if [ ${DM_VERITY_IMAGE_DATA_BLOCK_SIZE} -ge ${DM_VERITY_IMAGE_HASH_BLOCK_SIZE} ]; then
align=${DM_VERITY_IMAGE_DATA_BLOCK_SIZE}
else
align=${DM_VERITY_IMAGE_HASH_BLOCK_SIZE}
fi
SIZE=$(expr \( $SIZE + $align - 1 \) / $align \* $align)
# Assume some users may want separate hash vs. appended hash
if [ ${DM_VERITY_SEPARATE_HASH} -eq 1 ]; then
OUTPUT_HASH=$INPUT.vhash
else
HASH_OFFSET="--hash-offset="$SIZE
fi
cp -a $INPUT $OUTPUT
SETUP_ARGS=" \
--data-block-size=${DM_VERITY_IMAGE_DATA_BLOCK_SIZE} \
--hash-block-size=${DM_VERITY_IMAGE_HASH_BLOCK_SIZE} \
$HASH_OFFSET format $OUTPUT $OUTPUT_HASH \
"
echo "veritysetup $SETUP_ARGS" > $SAVED_ARGS
# Let's drop the first line of output (doesn't contain any useful info)
# and feed the rest to another function.
veritysetup $SETUP_ARGS | tail -n +2 | process_verity
}
# make "dateless" symlink for the hash so the wks can find it.
verity_hash() {
cd ${IMGDEPLOYDIR}
ln -sf ${IMAGE_NAME}${IMAGE_NAME_SUFFIX}.${DM_VERITY_IMAGE_TYPE}.vhash \
${IMAGE_BASENAME}-${MACHINE}.${DM_VERITY_IMAGE_TYPE}.vhash
}
VERITY_TYPES = " \
ext2.verity ext3.verity ext4.verity \
btrfs.verity \
erofs.verity erofs-lz4.verity erofs-lz4hc.verity \
squashfs.verity squashfs-xz.verity squashfs-lzo.verity squashfs-lz4.verity squashfs-zst.verity \
"
IMAGE_TYPES += "${VERITY_TYPES}"
CONVERSIONTYPES += "verity"
CONVERSION_CMD:verity = "verity_setup ${type}"
CONVERSION_DEPENDS_verity = "cryptsetup-native"
IMAGE_CMD:vhash = "verity_hash"
python __anonymous() {
verity_image = d.getVar('DM_VERITY_IMAGE')
verity_type = d.getVar('DM_VERITY_IMAGE_TYPE')
verity_hash = d.getVar('DM_VERITY_SEPARATE_HASH')
image_fstypes = d.getVar('IMAGE_FSTYPES')
pn = d.getVar('PN')
if not verity_image or not verity_type:
bb.warn('dm-verity-img class inherited but not used')
return
if verity_image != pn:
return # This doesn't concern this image
if len(verity_type.split()) != 1:
bb.fatal('DM_VERITY_IMAGE_TYPE must contain exactly one type')
d.appendVar('IMAGE_FSTYPES', ' %s.verity' % verity_type)
if verity_hash == "1":
d.appendVar('IMAGE_FSTYPES', ' vhash')
# If we're using wic: we'll have to use partition images and not the rootfs
# source plugin so add the appropriate dependency.
if 'wic' in image_fstypes:
dep = ' %s:do_image_%s' % (pn, verity_type.replace("-", "_"))
d.appendVarFlag('do_image_wic', 'depends', dep)
}
@@ -0,0 +1,10 @@
addhandler security_bbappend_distrocheck
security_bbappend_distrocheck[eventmask] = "bb.event.SanityCheck"
python security_bbappend_distrocheck() {
skip_check = e.data.getVar('SKIP_META_SECURITY_SANITY_CHECK') == "1"
if 'security' not in e.data.getVar('DISTRO_FEATURES').split() and not skip_check:
bb.warn("You have included the meta-security layer, but \
'security' has not been enabled in your DISTRO_FEATURES. Some bbappend files \
and preferred version setting may not take effect. See the meta-security README \
for details on enabling security support.")
}
@@ -0,0 +1,57 @@
# meta-security Maintainers File
#
# This file contains a list of recipe maintainers.
#
# Please submit any patches against recipes in meta to the
# Yocto mail list (yocto@yoctoproject.org)
#
# If you have problems with or questions about a particular recipe, feel
# free to contact the maintainer directly (cc:ing the appropriate mailing list
# puts it in the archive and helps other people who might have the same
# questions in the future), but please try to do the following first:
#
# - look in the Yocto Project Bugzilla
# (http://bugzilla.yoctoproject.org/) to see if a problem has
# already been reported
#
# The format is as a bitbake variable override for each recipe
#
# RECIPE_MAINTAINER:pn-<recipe name> = "Full Name <address@domain>"
#
# Please keep this list in alphabetical order.
RECIPE_MAINTAINER:pn-aircrack-ng = "Armin Kuster <akuster808@gmail.com>"
RECIPE_MAINTAINER:pn-apparmor = "Armin Kuster <akuster808@gmail.com>"
RECIPE_MAINTAINER:pn-bastille = "Armin Kuster <akuster808@gmail.com>"
RECIPE_MAINTAINER:pn-buck-security = "Armin Kuster <akuster808@gmail.com>"
RECIPE_MAINTAINER:pn-ccs-tools = "Armin Kuster <akuster808@gmail.com>"
RECIPE_MAINTAINER:pn-checksec = "Armin Kuster <akuster808@gmail.com>"
RECIPE_MAINTAINER:pn-checksecurity = "Armin Kuster <akuster808@gmail.com>"
RECIPE_MAINTAINER:pn-clamav = "Armin Kuster <akuster808@gmail.com>"
RECIPE_MAINTAINER:pn-ding-libs = "Armin Kuster <akuster808@gmail.com>"
RECIPE_MAINTAINER:pn-ecryptfs-utils = "Armin Kuster <akuster808@gmail.com>"
RECIPE_MAINTAINER:pn-fscryptctl = "Armin Kuster <akuster808@gmail.com>"
RECIPE_MAINTAINER:pn-google-authenticator-libpam = "Armin Kuster <akuster808@gmail.com>"
RECIPE_MAINTAINER:pn-hash-perl = "Armin Kuster <akuster808@gmail.com>"
RECIPE_MAINTAINER:pn-isic = "Armin Kuster <akuster808@gmail.com>"
RECIPE_MAINTAINER:pn-keyutils = "Armin Kuster <akuster808@gmail.com>"
RECIPE_MAINTAINER:pn-libaes-siv = "Armin Kuster <akuster808@gmail.com>"
RECIPE_MAINTAINER:pn-libgssglue = "Armin Kuster <akuster808@gmail.com>"
RECIPE_MAINTAINER:pn-libhtp = "Armin Kuster <akuster808@gmail.com>"
RECIPE_MAINTAINER:pn-libmhash = "Armin Kuster <akuster808@gmail.com>"
RECIPE_MAINTAINER:pn-libmspack = "Armin Kuster <akuster808@gmail.com>"
RECIPE_MAINTAINER:pn-lib-perl = "Armin Kuster <akuster808@gmail.com>"
RECIPE_MAINTAINER:pn-libseccomp = "Armin Kuster <akuster808@gmail.com>"
RECIPE_MAINTAINER:pn-libwhisker2-perl = "Armin Kuster <akuster808@gmail.com>"
RECIPE_MAINTAINER:pn-ncrack = "Armin Kuster <akuster808@gmail.com>"
RECIPE_MAINTAINER:pn-nikto = "Armin Kuster <akuster808@gmail.com>"
RECIPE_MAINTAINER:pn-paxctl = "Armin Kuster <akuster808@gmail.com>"
RECIPE_MAINTAINER:pn-python3-fail2ban = "Armin Kuster <akuster808@gmail.com>"
RECIPE_MAINTAINER:pn-python3-scapy = "Armin Kuster <akuster808@gmail.com>"
RECIPE_MAINTAINER:pn-python-fail2ban = "Armin Kuster <akuster808@gmail.com>"
RECIPE_MAINTAINER:pn-python-scapy = "Armin Kuster <akuster808@gmail.com>"
RECIPE_MAINTAINER:pn-redhat-security = "Armin Kuster <akuster808@gmail.com>"
RECIPE_MAINTAINER:pn-samhain = "Armin Kuster <akuster808@gmail.com>"
RECIPE_MAINTAINER:pn-smack = "Armin Kuster <akuster808@gmail.com>"
RECIPE_MAINTAINER:pn-sssd = "Armin Kuster <akuster808@gmail.com>"
RECIPE_MAINTAINER:pn-suricata = "Armin Kuster <akuster808@gmail.com>"
RECIPE_MAINTAINER:pn-tripwire = "Armin Kuster <akuster808@gmail.com>"
+31
View File
@@ -0,0 +1,31 @@
# We have a conf and classes directory, add to BBPATH
BBPATH .= ":${LAYERDIR}"
# We have recipes-* directories, add to BBFILES
BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
${LAYERDIR}/recipes-*/*/*.bbappend"
BBFILE_COLLECTIONS += "security"
BBFILE_PATTERN_security = "^${LAYERDIR}/"
BBFILE_PRIORITY_security = "8"
LAYERSERIES_COMPAT_security = "mickledore"
LAYERDEPENDS_security = "core openembedded-layer"
BBFILES_DYNAMIC += " \
perl-layer:${LAYERDIR}/dynamic-layers/meta-perl/recipes-*/*/*.bb \
perl-layer:${LAYERDIR}/dynamic-layers/meta-perl/recipes-*/*/*.bbappend \
meta-python:${LAYERDIR}/dynamic-layers/meta-python/recipes-*/*/*.bb \
meta-python:${LAYERDIR}/dynamic-layers/meta-python/recipes-*/*/*.bbappend \
networking-layer:${LAYERDIR}/dynamic-layers/networking-layer/recipes-*/*/*.bb \
networking-layer:${LAYERDIR}/dynamic-layers/networking-layer/recipes-*/*/*.bbappend \
"
# Sanity check for meta-security layer.
# Setting SKIP_META_SECURITY_SANITY_CHECK to "1" would skip the bbappend files check.
INHERIT += "sanity-meta-security"
QB_KERNEL_CMDLINE_APPEND = " ${@bb.utils.contains('DISTRO_FEATURES', 'apparmor', 'apparmor=1 security=apparmor', '', d)}"
addpylib ${LAYERDIR}/lib oeqa
@@ -0,0 +1,37 @@
dm-verity and beaglebone-black
------------------------------
Set/uncomment the MACHINE line for "beaglebone-yocto" if you haven't yet.
In addition to the basic dm-verity settings, you'll also want in local.conf:
IMAGE_BOOT_FILES:remove = "zImage"
IMAGE_BOOT_FILES:append = " zImage-initramfs-${MACHINE}.bin;zImage"
WKS_FILES = "${MACHINE}-verity.wks.in"
Read-only issues: The beaglebone BSP by default declares the following:
SERIAL_CONSOLES ?= "115200;ttyS0 115200;ttyO0 115200;ttyAMA0"
SERIAL_CONSOLES_CHECK = "${SERIAL_CONSOLES}"
...which are variables used by sysV init, in order to determine the
appropriate /etc/inittab entries. The problem that arises is that by
default, an on-target runtime check of /proc/consoles is used to finalize
the /etc/inittab -- and of course that fails a build with read-only-rootfs
[see the pkg_postinst_ontarget rule in the sysvinit rule for details.]
If you don't need a serial console, the quick fix is to add in local.conf
SERIAL_CONSOLES = ""
If you do need/want a serial console, then probably a local bbappend to
manually set the /etc/inittab as desired is easiest.
After running "wic create -e core-image-minimal beaglebone-yocto-verity"
you should have a "direct" image ready to write to a u-SD card. Remember
that the "direct" image contains the bootloader and partition table
already, so you'll be writing it to a device such as /dev/sdb and not
just a partition -- like /dev/sdb1
Also recall that booting from u-SD requires pressing and holding the S2
(SYSBOOT) button during power-on in order to divert the boot from the normal
soldered on storage and to the removable u-SD card.
@@ -0,0 +1,43 @@
dm-verity and x86-64 and systemd - separate hash device
-------------------------------------------------------
Everything said in "dm-verity-systemd-x86-64.txt" applies here.
However booting under QEMU is not tested - only on real hardware.
So for your MACHINE you need to choose "genericx86-64".
Also, you'll need to point at the hash specific WKS file:
WKS_FILES += " systemd-bootdisk-dmverity-hash.wks.in"
The fundamental difference is to use a separate device/partition for
storage of the hash data -- instead of "hiding" it beyond the filesystem
in what is essentially a 5-10% oversized partition. This takes any manual
math calculations of size/offset out of the picture, and uses the kernel's
natural behaviour of compartmentalizing devices to ensure they are separate.
The example hash.wks file added here essentially adds a hash-only partition
directly after the filesystem partition. So the filesystem partition is
no longer "oversized" and no offsets are needed/used.
Since we are now using multiple partitions, we make a better effort to use
accepted GPT partition types and UUIDs based on the roothash. This means
easier sysadmin level use/debugging based on cfdisk output etc.
Generating the separate root hash image is driven off enabling this:
DM_VERITY_SEPARATE_HASH = "1"
Two other variables control the GPT UUIDs - set to x86-64 defaults:
DM_VERITY_ROOT_GUID ?= "4f68bce3-e8cd-4db1-96e7-fbcaf984b709"
DM_VERITY_RHASH_GUID ?= "2c7357ed-ebd2-46d9-aec1-23d437ec2bf5"
See: https://uapi-group.org/specifications/specs/discoverable_partitions_specification/
Finally, the UUIDs (not the "partition types" above) are based off of
the root node hash value as per the systemd "autodetect" proposed standard.
These will obviously change with every update/rebuild of the root image.
While not strictly coupled to any functionality at this point in time, it
does aid in easier debugging, and puts us in alignment with using systemd
inside the initramfs to replace manual veritysetup like configuration we
currently do in the initramfs today, should we decide to do so later on.
@@ -0,0 +1,77 @@
dm-verity and x86-64 and systemd
--------------------------------
In this example, we'll target combining qemux86-64 with dm-verity and
also systemd - systemd has dm-verity bindings and is more likely to be
used on x86.
While dm-verity in a qemu environment doesn't make practial sense as a
deployment - it can be a useful stepping stone for testing and getting to
a final physical deployment.
Set/uncomment the MACHINE line for "qemux86-64" if you haven't yet. It
should be the default if unspecified, but check to be sure. As of this
writing (kernel v6.1) the resulting qemux86-64 build can also be booted
successfully on physical hardware, but if you don't intend to use qemu,
you might instead want to choose "genericx86-64"
This will make use of wic/systemd-bootdisk-dmverity.wks.in -- note that it
contains a dependency on the meta-intel layer for microcode, so you'll need
to fetch and add that layer in addition to the meta-security related layers.
In addition to the basic dm-verity settings, choose systemd in local.conf:
DISTRO_FEATURES:append = " security systemd"
VIRTUAL-RUNTIME_init_manager = "systemd"
EFI_PROVIDER = "systemd-boot"
PACKAGECONFIG:append:pn-systemd = " cryptsetup"
Note the last line - you won't typically see that in on-line instructions
for enabling systemd. It is important for dm-verity, since it triggers
the build and installation of components like this onto the rootfs:
/lib/systemd/system-generators/systemd-veritysetup-generator
/lib/systemd/systemd-veritysetup
Now build the components for the wic image:
bitbake intel-microcode
bitbake core-image-minimal
Assemble the image:
------------------------------
build-qemu-x86_64$wic create systemd-bootdisk-dmverity -e core-image-minimal
INFO: Building wic-tools...
[...]
INFO: Creating image(s)...
INFO: The new image(s) can be found here:
./systemd-bootdisk-dmverity.wks-202304181413-sda.direct
The following build artifacts were used to create the image(s):
BOOTIMG_DIR: /home/paul/poky/build-qemu-x86_64/tmp/work/qemux86_64-poky-linux/core-image-minimal/1.0-r0/recipe-sysroot/usr/share
KERNEL_DIR: /home/paul/poky/build-qemu-x86_64/tmp/deploy/images/qemux86-64
NATIVE_SYSROOT: /home/paul/poky/build-qemu-x86_64/tmp/work/core2-64-poky-linux/wic-tools/1.0-r0/recipe-sysroot-native
INFO: The image(s) were created using OE kickstart file:
/home/paul/poky/meta-security/wic/systemd-bootdisk-dmverity.wks.in
build-qemu-x86_64$
------------------------------
The "runqemu" script defaults were acceptable for testing with only the
verity image needing to be specified, i.e.
runqemu \
nographic \
qemux86-64 \
tmp/deploy/images/qemux86-64/core-image-minimal-qemux86-64-*.rootfs.ext4.verity
You will see the above "direct" image file and also similarly named
individual partition images. To boot on UEFI enabled physical hardware,
you need to simply write the "direct" image file to a USB stick with dd
and the partition images can largely be ignored.
Further information on interacting with the systemd UEFI loader is here:
https://www.freedesktop.org/wiki/Software/systemd/systemd-boot/
+123
View File
@@ -0,0 +1,123 @@
dm-verity and Yocto/OE
----------------------
The dm-verity feature provides a level of data integrity and resistance to
data tampering. It does this by creating a hash for each data block of
the underlying device as the base of a hash tree. There are many
documents out there to further explain the implementaion, such as the
in-kernel one itself:
https://docs.kernel.org/admin-guide/device-mapper/verity.html
The goal of this document is not to reproduce that content, but instead to
capture the Yocto/OE specifics of the dm-verity infrastructure used here.
Ideally this should enable a person to build and deploy an image on one of
the supported reference platforms, and then further adapt to their own
platform and specific storage requirements.
Basic Settings
--------------
Largely everything is driven off of a dm-verity image class; a typical
block of non MACHINE specific settings are shown below:
INITRAMFS_IMAGE = "dm-verity-image-initramfs"
DM_VERITY_IMAGE = "core-image-minimal"
DM_VERITY_IMAGE_TYPE = "ext4"
IMAGE_CLASSES += "dm-verity-img"
INITRAMFS_IMAGE_BUNDLE = "1"
Kernel Configuration
--------------------
Kernel configuration for dm-verity happens automatically via IMAGE_CLASSES
which will source features/device-mapper/dm-verity.scc when dm-verity-img
is used. [See commit d9feafe991c]
IMPORTANT: As per the top level README, you *must* put security in the
DISTRO_FEATURES, or else you won't get the dm-verity kernel settings.
Supported Platforms
-------------------
In theory, you can use dm-verity anywhere - there is nothing arch/BSP
specific in the core kernel support. However, at the BSP level, one
eventually has to decide what device(s) are to be hashed, and where the
hash tables are stored.
To that end, the BSP storage specifics live in meta-security/wic dir and
represent the current set of example configurations that have been tested
and submitted at some point.
Getting Started
---------------
This document assumes you are starting from the basic auto-created
conf/local.conf and conf/bblayers.conf from the oe-init-build-env
Firstly, you need the meta-security layer to conf/bblayers.conf along with
the dependencies it has -- see the top level meta-security README for that.
Note that if you are using dm-verity for your rootfs, then it enforces a
read-only mount right at the kernel level, so be prepared for issues such
as failed creation of temporary files and similar.
Yocto does support additional checks and changes via setting:
EXTRA_IMAGE_FEATURES = "read-only-rootfs"
...but since read-only is enforced at the kernel level already, using
this feature isn't a hard requirement. It may be best to delay/defer
making use of this until after you've established basic booting.
For more details, see the associated documentation:
https://docs.yoctoproject.org/dev/dev-manual/read-only-rootfs.html
Also add the basic block of dm-verity settings shown above, and select
your MACHINE from one of the supported platforms.
If there is a dm-verity-<MACHINE>.txt file for your BSP, check that for
any additional platform specific recommended settings, such as the
WKS_FILES which can specify board specific storage layout discussed below.
Then you should be able to do a "bitbake core-image-minimal" just like any
other normal build. What you will notice, is the content in
tmp/deploy/images/<MACHINE>/ now have suffixes like "rootfs.ext4.verity"
While you can manually work with these images just like any other build,
this is where the BSP specific recipes in meta-security/wic can simplify
things and remove a bunch of manual steps that might be error prone.
Consider for example, the beaglebone black WIC file, which contains:
part /boot --source bootimg-partition --ondisk mmcblk0 --fstype=vfat
--label boot --active --align 4 --fixed-size 32 --sourceparams="loader=u-boot" --use-uuid
part / --source rawcopy --ondisk mmcblk0 --sourceparams="file=${IMGDEPLOYDIR}/${DM_VERITY_IMAGE}-${MACHINE}.${DM_VERITY_IMAGE_TYPE}.verity"
bootloader --append="console=ttyS0,115200"
As can be seen, it maps out the partitions, including the bootloader, and
saves doing a whole bunch of manual partitioning and dd steps.
This file is copied into tmp/deploy/images/<MACHINE>/ with bitbake
variables expanded with their corresponding values for wic to make use of.
Continuing with the beaglebone example, we'll see output similar to:
----------------------
$ wic create -e core-image-minimal beaglebone-yocto-verity
[...]
INFO: Creating image(s)...
INFO: The new image(s) can be found here:
./beaglebone-yocto-verity.wks-202303070223-mmcblk0.direct
The following build artifacts were used to create the image(s):
BOOTIMG_DIR: /home/paul/poky/build-bbb-verity/tmp/work/beaglebone_yocto-poky-linux-gnueabi/core-image-minimal/1.0-r0/recipe-sysroot/usr/share
KERNEL_DIR: /home/paul/poky/build-bbb-verity/tmp/deploy/images/beaglebone-yocto
NATIVE_SYSROOT: /home/paul/poky/build-bbb-verity/tmp/work/cortexa8hf-neon-poky-linux-gnueabi/wic-tools/1.0-r0/recipe-sysroot-native
INFO: The image(s) were created using OE kickstart file:
/home/paul/poky/meta-security/wic/beaglebone-yocto-verity.wks.in
----------------------
The "direct" image contains the partition table, bootloader, and dm-verity
enabled ext4 image all in one -- ready to write to a raw device, such as a
u-SD card in the case of the beaglebone.
+197
View File
@@ -0,0 +1,197 @@
Meta-security Docs
=============
In this section the contents of the layer is listed, along with a short
help for each package.
== bastille ==
Bastille is a system hardening / lockdown program which enhances the
security of a Unix host. It configures daemons, system settings and
firewalls to be more secure. It can shut off unneeded services
like rcp and rlogin, and helps create "chroot jails" that help limit the
vulnerability of common Internet services like Web services and DNS.
usage : The functionality of Bastille which is available is
restricted to a purely informational one. The command:
bastille -c --os Yocto
will cause a series of menus containing security questions
about the system to be displayed to the user. For each
question, a default response, specified in the configuration
file which is installed with Bastille, will be selected.
The user may select an alternate response. When the user
has completed the sequence of menus Bastille saves the
responses to the configuration file.
The command:
bastille -l lists the configuration files that Bastille
is able to locate.
The other functionality which Bastille is intended to provide
is actually unavailable. This is not due to errors in poky
installation or configuration of the application. The Bastille
distribution is no longer supported. Significant modifications
would be required to make it possible to make use of the
functionality which is currently unavailable.
Additional information about Bastille can be found in the package
README file and other documentation.
Alternatives to Bastille include buck-security and checksecurity,
described elsewhere in this file.
== redhat-security ==
Sometimes you want to check different aspects of a distribution for security problems.
This can be anything from file permissions to correctness of code. This is a collection of those tools.
Depending on what information the tool has to access, it may need to be run as root.
- rpm-chksec.sh : This will take an rpm name as input and verify each ELF file to see if its compiled with the intended flags
to most effectively use PIE and RELRO. Green is good, Orange could use work but is acceptable, and Red needs fixing.
It has a mode --all that is the equivalent of using rpm -qa and feeding the packages to it.
In this mode it will only give a summary result for the package. To find which files don't comply,
re-run using just the package name.
!!! WARNING !!! - in order to use this script you need to add to your conf/local.conf file the following lines:
IMAGE_ROOTFS_EXTRA_SPACE = "" - specifying the extra space of the image
IMAGE_FEATURES += "package management" - for the correct output of rpm -qa
- find-nodrop-groups.sh : This will scan a whole file system to see if a program makes calls to change UID
and GID without also calling setgroups or initgroups.
- rpm-drop-groups.sh : Same as above, but takes an rpm name instead.
- find-chroot.sh : This script scans the whole file system looking for ELF files that calls chroot(2) that also do not include a call to chdir.
Programs that fail to do this do not have the cwd inside the chroot. This means the app can escape the protection that was intended.
- find-chroot-py.sh : This test is like the one above except it examines python scripts for the same problem.
- find-execstack.sh : This program scans the whole file system for ELF programs that have marked the stack as being executable.
This means that if the program has another vulnerablity such as stack buffer overflow,
any code the attacker places there is executable. Any program found must be fixed.
- find-hidden-exec.sh : This program scans the whole file system looking for excutables that are hidden.
Anything found must be investigated since its highly unusual for executables to be hidden.
- find-sh4errors.sh : This program scans the whole file system looking for shell scripts.
It then does a sh -n on the script which causes bash to parse the file to see if there are any mistakes.
- selinux-check-devices.sh : This script checks the /dev directory to see if there are any devices that are not correctly labeled.
Anything found by this test should be reported so that selinux policy can be fixed.
This test is very hardware specific, so to be effective a lot of people with different hardware
should run this test each upstream kernel version release.
- selinux-ls-unconfined.sh : This script scans the running processes and looks for anything labeled with initrc_t or inetd.
These both mean that there are daemons that do not have policy and are therefore running unconfined.
These should be reported as SE Linux policy problems. Because it checks currently running daemons,
the more you have running, the better the test is.
- find-sh4tmp.sh : This script scans the whole filesystem to check if shell scripts are using well known tmp file names
instead of obscure ones created by something like mktemp.
- find-elf4tmp.sh : This script scans the whole file system for ELF files using /tmp. When it finds this,
it also looks to see if any of the known good random name generator functions is called by looking
at the symbol table. If not, it will output the string.
- lib-bin-check.sh : This will check all installed library packages to see if an application is also part of the package.
The relationship to security is that the SHA256 hash check will fail if a 32 bit version overwrites it.
Also, the less binaries on a system, the more secure it is by virtue of removing the chance for an exploitable bug.
usage : simply invoke the script name in the terminal.
== pax-utils ==
( This package can be found in oe-core )
pax-utils is a small set of various PaX aware and related utilities for
ELF binaries.
- scanelf : With this application you can print out information specific to the ELF structure of a binary.
For more help please consult the man pages or the readme file.
- pspax : is a user-space utility that scans the proc directory and list
ELF types, as well as their respective PaX flags and filenames and
attributes. Depending on build options, it may additionaly display the
process running set of capabilities.
- scanmacho : is a user-space utility to quickly scan given
Mach-Os, directories, or common system paths for different information. This
may include Mach-O types, their install_names, etc.
- dumpelf : is a user-space utility to dump all of the internal
ELF structures into the equivalent C structures for fun debugging and/or
reference purposes.
usage : simply invoke the script name in the terminal.
== buck-security ==
Buck-Security is a security scanner for Debian and Ubuntu Linux. It runs a couple of important checks and helps you to harden your Linux
system. This enables you to quickly overview the security status of your Linux system.
usage : !!! before starting to use this tool please run the following command: !!!
export GPG_TTY=`tty`
This command is needed for the usage of the comand --make-checksum, which creates
a checksum for the files in the system.
switch to directory /usr/local/buck-security.
before running the script, you should check the activated checks in conf/buck-security.conf file.
after altering the changes, save the file and simply run :
./buck-security
you can choose between different outputs : 1, 2(default) or 3.
More detailed usage can be found typing ./buck-security --help
== libseccomp ==
The libseccomp library provides and easy to use, platform independent, interface to the Linux Kernel's syscall filtering mechanism: seccomp.
The libseccomp API is designed to abstract away the underlying BPF based syscall filter language and present a more conventional
function-call based filtering interface that should be familiar to, and easily adopted by application developers.
usage : More detailed usage can be found in the man pages and README file of the package.
== checksecurity ==
checksecurity is a simple package which will scan your system for several simple security holes.
It uses a simple collection of plugins, all of which are shell scripts which are configured by environmental variables.
usage : To start checksecurity simply write in the terminal :
checksecurity
More detailed usage can be found in the man pages and README file of the package.
== nikto ==
Nikto is an Open Source (GPL) web server scanner which performs comprehensive tests against web servers for multiple items,
including over 6500 potentially dangerous files/CGIs, checks for outdated versions of over 1250 servers, and version specific
problems on over 270 servers. It also checks for server configuration items such as the presence of multiple index files,
HTTP server options, and will attempt to identify installed web servers and software.
usage : To start nikto simply write in the terminal :
nikto
More detailed usage can be found in the man pages and README file of the package.
License
=======
All metadata is MIT licensed unless otherwise stated. Source code included
in tree for individual recipes is under the LICENSE stated in each recipe
(.bb file) unless otherwise stated.
@@ -0,0 +1,18 @@
PACKAGES += "\
packagegroup-security-hardening \
"
RDEPENDS:packagegroup-core-security += "\
packagegroup-security-hardening \
"
SUMMARY:packagegroup-security-hardening = "Security Hardening tools"
RDEPENDS:packagegroup-security-hardening = " \
bastille \
"
RDEPENDS:packagegroup-security-scanners += "\
nikto \
checksecurity \
"
@@ -0,0 +1,29 @@
SUMMARY = "basic system security checks"
DESCRIPTION = "checksecurity is a simple package which will scan your system for several simple security holes."
SECTION = "security"
LICENSE = "GPL-2.0-only"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/GPL-2.0-only;md5=801f80980d171dd6425610833a22dbe6"
SRC_URI = "http://ftp.de.debian.org/debian/pool/main/c/checksecurity/checksecurity_${PV}+nmu1.tar.gz \
file://check-setuid-use-more-portable-find-args.patch \
"
SRC_URI[sha256sum] = "9803b3760e9ec48e06ebaf48cec081db48c6fe72254a476224e4c5c55ed97fb0"
S = "${WORKDIR}/checksecurity-${PV}+nmu1"
# allow for anylocal, no need to patch
LOGDIR="/etc/checksecurity"
do_compile() {
sed -i -e "s;LOGDIR=/var/log/setuid;LOGDIR=${LOGDIR};g" ${B}/etc/check-setuid.conf
sed -i -e "s;LOGDIR=/var/log/setuid;LOGDIR=${LOGDIR};g" ${B}/plugins/check-setuid
sed -i -e "s;LOGDIR:=/var/log/setuid;LOGDIR:=${LOGDIR};g" ${B}/plugins/check-setuid
}
do_install() {
oe_runmake PREFIX=${D}
}
RDEPENDS:${PN} = "perl libenv-perl perl-module-tie-array perl-module-getopt-long perl-module-file-glob perl-module-carp perl-module-env perl-module-tap-parser-iterator-array util-linux findutils coreutils"
@@ -0,0 +1,24 @@
From f3073b8e06a607677d47ad9a19533b2e33408a4f Mon Sep 17 00:00:00 2001
From: Christopher Larson <chris_larson@mentor.com>
Date: Wed, 5 Sep 2018 23:21:43 +0500
Subject: [PATCH] check-setuid: use more portable find args
Upstream-Status: Pending
Signed-off-by: Christopher Larson <chris_larson@mentor.com>
---
plugins/check-setuid | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
Index: checksecurity-2.0.16+nmu1/plugins/check-setuid
===================================================================
--- checksecurity-2.0.16+nmu1.orig/plugins/check-setuid
+++ checksecurity-2.0.16+nmu1/plugins/check-setuid
@@ -100,7 +100,7 @@ ionice -t -c3 \
find `mount | grep -vE "$CHECKSECURITY_FILTER" | cut -d ' ' -f 3` \
-ignore_readdir_race \
-xdev $PATHCHK \
- \( -type f -perm /06000 -o \( \( -type b -o -type c \) \
+ \( -type f \( -perm -4000 -o -perm -2000 \) -o \( \( -type b -o -type c \) \
$DEVCHK \) \) \
-printf "%8i %5m %3n %-10u %-10g %9s %t %h/%f\n" |
sort -k 12 >$TMPSETUID
@@ -0,0 +1,166 @@
#The functionality of Bastille that is actually available is restricted. Please
#consult the README file for the meta-security layer for additional information.
SUMMARY = "Linux hardening tool"
DESCRIPTION = "Bastille Linux is a Hardening and Reporting/Auditing Program which enhances the security of a Linux box, by configuring daemons, system settings and firewalling."
LICENSE = "GPL-2.0-only"
LIC_FILES_CHKSUM = "file://${S}/COPYING;md5=c93c0550bd3173f4504b2cbd8991e50b"
# Bash is needed for set +o privileged (check busybox), might also need ncurses
DEPENDS = "virtual/kernel"
RDEPENDS:${PN} = "perl bash tcl perl-module-getopt-long perl-module-text-wrap lib-perl perl-module-file-path perl-module-mime-base64 perl-module-file-find perl-module-errno perl-module-file-glob perl-module-tie-hash-namedcapture perl-module-file-copy perl-module-english perl-module-exporter perl-module-cwd libcurses-perl coreutils"
FILES:${PN} += "/run/lock/subsys/bastille"
SRC_URI = "http://sourceforge.net/projects/bastille-linux/files/bastille-linux/3.2.1/Bastille-3.2.1.tar.bz2 \
file://AccountPermission.pm \
file://FileContent.pm \
file://HPSpecific.pm \
file://Miscellaneous.pm \
file://ServiceAdmin.pm \
file://config \
file://fix_version_parse.patch \
file://fixed_defined_warnings.patch \
file://call_output_config.patch \
file://fix_missing_use_directives.patch \
file://fix_number_of_modules.patch \
file://remove_questions_text_file_references.patch \
file://simplify_B_place.patch \
file://find_existing_config.patch \
file://upgrade_options_processing.patch \
file://accept_os_flag_in_backend.patch \
file://allow_os_with_assess.patch \
file://edit_usage_message.patch \
file://organize_distro_discovery.patch \
file://do_not_apply_config.patch \
"
SRC_URI[md5sum] = "df803f7e38085aa5da79f85d0539f91b"
SRC_URI[sha256sum] = "0ea25191b1dc1c8f91e1b6f8cb5436a3aa1e57418809ef902293448efed5021a"
S = "${WORKDIR}/Bastille"
do_install () {
install -d ${D}${sbindir}
install -d ${D}${libdir}/perl5/site_perl/Curses
install -d ${D}${libdir}/Bastille
install -d ${D}${libdir}/Bastille/API
install -d ${D}${datadir}/Bastille
install -d ${D}${datadir}/Bastille/OSMap
install -d ${D}${datadir}/Bastille/OSMap/Modules
install -d ${D}${datadir}/Bastille/Questions
install -d ${D}${datadir}/Bastille/FKL/configs/
install -d ${D}${sysconfdir}/Bastille
install -m 0755 AutomatedBastille ${D}${sbindir}
install -m 0755 BastilleBackEnd ${D}${sbindir}
install -m 0755 InteractiveBastille ${D}${sbindir}
install -m 0644 Modules.txt ${D}${datadir}/Bastille
# New Weights file(s).
install -m 0644 Weights.txt ${D}${datadir}/Bastille
# Castle graphic
install -m 0644 bastille.jpg ${D}${datadir}/Bastille/
# Javascript file
install -m 0644 wz_tooltip.js ${D}${datadir}/Bastille/
install -m 0644 Credits ${D}${datadir}/Bastille
install -m 0644 FKL/configs/fkl_config_redhat.cfg ${D}${datadir}/Bastille/FKL/configs/
install -m 0755 RevertBastille ${D}${sbindir}
install -m 0755 bin/bastille ${D}${sbindir}
install -m 0644 bastille-firewall ${D}${datadir}/Bastille
install -m 0644 bastille-firewall-reset ${D}${datadir}/Bastille
install -m 0644 bastille-firewall-schedule ${D}${datadir}/Bastille
install -m 0644 bastille-tmpdir-defense.sh ${D}${datadir}/Bastille
install -m 0644 bastille-tmpdir.csh ${D}${datadir}/Bastille
install -m 0644 bastille-tmpdir.sh ${D}${datadir}/Bastille
install -m 0644 bastille-firewall.cfg ${D}${datadir}/Bastille
install -m 0644 bastille-ipchains ${D}${datadir}/Bastille
install -m 0644 bastille-netfilter ${D}${datadir}/Bastille
install -m 0644 bastille-firewall-early.sh ${D}${datadir}/Bastille
install -m 0644 bastille-firewall-pre-audit.sh ${D}${datadir}/Bastille
install -m 0644 complete.xbm ${D}${datadir}/Bastille
install -m 0644 incomplete.xbm ${D}${datadir}/Bastille
install -m 0644 disabled.xpm ${D}${datadir}/Bastille
install -m 0644 ifup-local ${D}${datadir}/Bastille
install -m 0644 hosts.allow ${D}${datadir}/Bastille
install -m 0644 Bastille/AccountSecurity.pm ${D}${libdir}/Bastille
install -m 0644 Bastille/Apache.pm ${D}${libdir}/Bastille
install -m 0644 Bastille/API.pm ${D}${libdir}/Bastille
install -m 0644 ${WORKDIR}/AccountPermission.pm ${D}${libdir}/Bastille/API
install -m 0644 ${WORKDIR}/FileContent.pm ${D}${libdir}/Bastille/API
install -m 0644 ${WORKDIR}/HPSpecific.pm ${D}${libdir}/Bastille/API
install -m 0644 ${WORKDIR}/ServiceAdmin.pm ${D}${libdir}/Bastille/API
install -m 0644 ${WORKDIR}/Miscellaneous.pm ${D}${libdir}/Bastille/API
install -m 0644 Bastille/BootSecurity.pm ${D}${libdir}/Bastille
install -m 0644 Bastille/ConfigureMiscPAM.pm ${D}${libdir}/Bastille
install -m 0644 Bastille/DisableUserTools.pm ${D}${libdir}/Bastille
install -m 0644 Bastille/DNS.pm ${D}${libdir}/Bastille
install -m 0644 Bastille/FilePermissions.pm ${D}${libdir}/Bastille
install -m 0644 Bastille/FTP.pm ${D}${libdir}/Bastille
install -m 0644 Bastille/Firewall.pm ${D}${libdir}/Bastille
install -m 0644 Bastille/OSX_API.pm ${D}${libdir}/Bastille
install -m 0644 Bastille/LogAPI.pm ${D}${libdir}/Bastille
install -m 0644 Bastille/HP_UX.pm ${D}${libdir}/Bastille
install -m 0644 Bastille/IOLoader.pm ${D}${libdir}/Bastille
install -m 0644 Bastille/Patches.pm ${D}${libdir}/Bastille
install -m 0644 Bastille/Logging.pm ${D}${libdir}/Bastille
install -m 0644 Bastille/MiscellaneousDaemons.pm ${D}${libdir}/Bastille
install -m 0644 Bastille/PatchDownload.pm ${D}${libdir}/Bastille
install -m 0644 Bastille/Printing.pm ${D}${libdir}/Bastille
install -m 0644 Bastille/PSAD.pm ${D}${libdir}/Bastille
install -m 0644 Bastille/RemoteAccess.pm ${D}${libdir}/Bastille
install -m 0644 Bastille/SecureInetd.pm ${D}${libdir}/Bastille
install -m 0644 Bastille/Sendmail.pm ${D}${libdir}/Bastille
install -m 0644 Bastille/TestDriver.pm ${D}${libdir}/Bastille
install -m 0644 Bastille/TMPDIR.pm ${D}${libdir}/Bastille
install -m 0644 Bastille/test_AccountSecurity.pm ${D}${libdir}/Bastille
install -m 0644 Bastille/test_Apache.pm ${D}${libdir}/Bastille
install -m 0644 Bastille/test_DNS.pm ${D}${libdir}/Bastille
install -m 0644 Bastille/test_FTP.pm ${D}${libdir}/Bastille
install -m 0644 Bastille/test_HP_UX.pm ${D}${libdir}/Bastille
install -m 0644 Bastille/test_MiscellaneousDaemons.pm ${D}${libdir}/Bastille
install -m 0644 Bastille/test_Patches.pm ${D}${libdir}/Bastille
install -m 0644 Bastille/test_SecureInetd.pm ${D}${libdir}/Bastille
install -m 0644 Bastille/test_Sendmail.pm ${D}${libdir}/Bastille
install -m 0644 Bastille/test_BootSecurity.pm ${D}${libdir}/Bastille
install -m 0644 Bastille/test_DisableUserTools.pm ${D}${libdir}/Bastille
install -m 0644 Bastille/test_FilePermissions.pm ${D}${libdir}/Bastille
install -m 0644 Bastille/test_Logging.pm ${D}${libdir}/Bastille
install -m 0644 Bastille/test_Printing.pm ${D}${libdir}/Bastille
install -m 0644 Bastille/IPFilter.pm ${D}${libdir}/Bastille
install -m 0644 Bastille_Curses.pm ${D}${libdir}/perl5/site_perl
install -m 0644 Bastille_Tk.pm ${D}${libdir}/perl5/site_perl
install -m 0644 Curses/Widgets.pm ${D}${libdir}/perl5/site_perl/Curses
install -m 0644 OSMap/LINUX.bastille ${D}${datadir}/Bastille/OSMap
install -m 0644 OSMap/LINUX.system ${D}${datadir}/Bastille/OSMap
install -m 0644 OSMap/LINUX.service ${D}${datadir}/Bastille/OSMap
install -m 0644 OSMap/HP-UX.bastille ${D}${datadir}/Bastille/OSMap
install -m 0644 OSMap/HP-UX.system ${D}${datadir}/Bastille/OSMap
install -m 0644 OSMap/HP-UX.service ${D}${datadir}/Bastille/OSMap
install -m 0644 OSMap/OSX.bastille ${D}${datadir}/Bastille/OSMap
install -m 0644 OSMap/OSX.system ${D}${datadir}/Bastille/OSMap
install -m 0777 ${WORKDIR}/config ${D}${sysconfdir}/Bastille/config
for file in `cat Modules.txt` ; do
install -m 0644 Questions/$file.txt ${D}${datadir}/Bastille/Questions
done
${THISDIR}/files/set_required_questions.py ${D}${sysconfdir}/Bastille/config ${D}${datadir}/Bastille/Questions
ln -s RevertBastille ${D}${sbindir}/UndoBastille
# Create /var/log/Bastille in runtime.
if [ "${@bb.utils.filter('DISTRO_FEATURES', 'systemd', d)}" ]; then
install -d ${D}${nonarch_libdir}/tmpfiles.d
echo "d ${localstatedir}/log/Bastille - - - -" > ${D}${nonarch_libdir}/tmpfiles.d/Bastille.conf
fi
if [ "${@bb.utils.filter('DISTRO_FEATURES', 'sysvinit', d)}" ]; then
install -d ${D}${sysconfdir}/default/volatiles
echo "d root root 0755 ${localstatedir}/log/Bastille none" > ${D}${sysconfdir}/default/volatiles/99_Bastille
fi
}
FILES:${PN} += "${datadir}/Bastille \
${libdir}/Bastille \
${libdir}/perl* \
${sysconfdir}/* \
${nonarch_libdir}/tmpfiles.d"
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,166 @@
package Bastille::API::Miscellaneous;
use strict;
use File::Path;
use Bastille::API;
use Bastille::API::HPSpecific;
use Bastille::API::FileContent;
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw(
PrepareToRun
B_is_package_installed
);
our @EXPORT = @EXPORT_OK;
###########################################################################
#
# PrepareToRun sets up Bastille to run. It checks the ARGV array for
# special options and runs ConfigureForDistro to set necessary file
# locations and other global variables.
#
###########################################################################
sub PrepareToRun {
# Make sure we're root!
if ( $> != 0 ) {
&B_log("ERROR","Bastille must run as root!\n");
exit(1);
}
# Make any directories that don't exist...
foreach my $dir (keys %GLOBAL_BDIR) {
my $BdirPath = $GLOBAL_BDIR{$dir};
if ( $BdirPath =~ /^\s*\// ) { #Don't make relative directories
mkpath ($BdirPath,0,0700);
}
}
if(&GetDistro =~ "^HP-UX") {
&B_check_system;
}
&B_log("ACTION","\n########################################################\n" .
"# Begin Bastille Run #\n" .
"########################################################\n\n");
#read sum file if it exists.
&B_read_sums;
# No longer necessary as flags are no longer in sum file, and sums are
# are now checked "real time"
# check the integrity of the files listed
# for my $file (sort keys %GLOBAL_SUM) {
# &B_check_sum($file);
# }
# write out the newly flagged sums
# &B_write_sums;
}
###########################################################################
# &B_is_package_installed($package);
#
# This function checks for the existence of the package named.
#
# TODO: Allow $package to be an expression.
# TODO: Allow optional $version, $release, $epoch arguments so we can
# make sure that the given package is at least as recent as some
# given version number.
#
# scalar return values:
# 0: $package is not installed
# 1: $package is installed
###########################################################################
sub B_is_package_installed($) {
no strict;
my $package = $_[0];
# Create a "global" variable with values scoped to this function
# We do this to avoid having to repeatedly swlist/rpm
# when we run B_is_package_installed
local %INSTALLED_PACKAGE_LIST;
my $distro = &GetDistro;
if ($distro =~ /^HP-UX/) {
if (&checkProcsForService('swagent','ignore_warning') == SECURE_CANT_CHANGE()) {
&B_log("WARNING","Software Distributor Agent(swagent) is not running. Can not tell ".
"if package: $package is installed or not. Bastille will assume not. ".
"If the package is actually installed, Bastille may report or configure incorrectly.".
"To use Bastille-results as-is, please check to ensure $package is not installed, ".
"or re-run with the swagent running to get correct results.");
return 0; #FALSE
}
my $swlist=&getGlobal('BIN','swlist');
if (%INSTALLED_PACKAGE_LIST == () ) { # re-use prior results
if (open(SWLIST, "$swlist -a state -l fileset |")) {
while (my $line = <SWLIST>){
if ($line =~ /^ {2}\S+\.(\S+)\s*(\w+)/) {
$INSTALLED_PACKAGE_LIST{$1} = $2;
}
}
close SWLIST;
} else {
&B_log("ERROR","B_is_package_installed was unable to run the swlist command: $swlist,\n");
return FALSE;
}
}
# Now find the entry
if ($INSTALLED_PACKAGE_LIST{$package} == 'configured') {
return TRUE;
} else {
return FALSE;
}
} #End HP-UX Section
# This routine only works on RPM-based distros: Red Hat, Fedora, Mandrake and SuSE
elsif ( ($distro !~ /^RH/) and ($distro !~ /^MN/) and($distro !~ /^SE/) ) {
return 0;
} else { #This is a RPM-based distro
# Run an rpm command -- librpm is extremely messy, dynamic and not
# so much a perl thing. It's actually barely a C/C++ thing...
if (open RPM,"rpm -q $package") {
# We should get only one line back, but let's parse a few
# just in case.
my @lines = <RPM>;
close RPM;
#
# This is what we're trying to parse:
# $ rpm -q jay
# package jay is not installed
# $ rpm -q bash
# bash-2.05b-305.1
#
foreach $line (@lines) {
if ($line =~ /^package\s$package\sis\snot\sinstalled/) {
return 0;
}
elsif ($line =~ /^$package\-/) {
return 1;
}
}
# If we've read every line without finding one of these, then
# our parsing is broken
&B_log("ERROR","B_is_package_installed was unable to find a definitive RPM present or not present line.\n");
return 0;
} else {
&B_log("ERROR","B_is_package_installed was unable to run the RPM command,\n");
return 0;
}
}
}
1;
@@ -0,0 +1,690 @@
package Bastille::API::ServiceAdmin;
use strict;
use Bastille::API;
use Bastille::API::HPSpecific;
use Bastille::API::FileContent;
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw(
B_chkconfig_on
B_chkconfig_off
B_service_start
B_service_stop
B_service_restart
B_is_service_off
checkServiceOnLinux
remoteServiceCheck
remoteNISPlusServiceCheck
B_create_nsswitch_file
);
our @EXPORT = @EXPORT_OK;
#######
# &B_chkconfig_on and &B_chkconfig_off() are great for systems that didn't use
# a more modern init system. This is a bit of a problem on Fedora, though,
# which used upstart from Fedora 9 to Fedora 14, then switched to a new
# Red Hat-created system called systemd for Fedora 15 and 16 (so far).
# OpenSUSE also moved to systemd, starting with 12.1. Version 11.4 did not
# use systemd.
# It is also a problem on Ubuntu, starting at version 6.10, where they also
# used upstart.
#####
###########################################################################
# &B_chkconfig_on ($daemon_name) creates the symbolic links that are
# named in the "# chkconfig: ___ _ _ " portion of the init.d files. We
# need this utility, in place of the distro's chkconfig, because of both
# our need to add revert functionality and our need to harden distros that
# are not mounted on /.
#
# It uses the following global variables to find the links and the init
# scripts, respectively:
#
# &getGlobal('DIR', "rcd") -- directory where the rc_.d subdirs can be found
# &getGlobal('DIR', "initd") -- directory the rc_.d directories link to
#
# Here an example of where you might use this:
#
# You'd like to tell the system to run the firewall at boot:
# B_chkconfig_on("bastille-firewall")
#
###########################################################################
# PW: Blech. Copied B_chkconfig_off() and changed a few things,
# then changed a few more things....
sub B_chkconfig_on {
my $startup_script=$_[0];
my $retval=1;
my $chkconfig_line;
my ($runlevelinfo,@runlevels);
my ($start_order,$stop_order,$filetolink);
&B_log("ACTION","# chkconfig_on enabling $startup_script\n");
# In Debian system there is no chkconfig script, run levels are checked
# one by one (jfs)
if (&GetDistro =~/^DB.*/) {
$filetolink = &getGlobal('DIR', "initd") . "/$startup_script";
if (-x $filetolink)
{
foreach my $level ("0","1","2","3","4","5","6" ) {
my $link = '';
$link = &getGlobal('DIR', "rcd") . "/rc" . "$level" . ".d/K50" . "$startup_script";
$retval=symlink($filetolink,$link);
}
}
return $retval;
}
#
# On SUSE, chkconfig-based rc scripts have been replaced with a whole different
# system. chkconfig on SUSE is actually a shell script that does some stuff and then
# calls insserv, their replacement.
#
if (&GetDistro =~ /^SE/) {
# only try to chkconfig on if init script is found
if ( -e (&getGlobal('DIR', "initd") . "/$startup_script") ) {
$chkconfig_line=&getGlobal('BIN','chkconfig');
&B_System("$chkconfig_line $startup_script on", "$chkconfig_line $startup_script off");
# chkconfig doesn't take affect until reboot, need to restart service also
B_service_restart("$startup_script");
return 1; #success
}
return 0; #failure
}
#
# Run through the init script looking for the chkconfig line...
#
$retval = open CHKCONFIG,&getGlobal('DIR', "initd") . "/$startup_script";
unless ($retval) {
&B_log("ACTION","# Didn't chkconfig_on $startup_script because we couldn't open " . &getGlobal('DIR', "initd") . "/$startup_script\n");
}
else {
READ_LOOP:
while (my $line=<CHKCONFIG>) {
# We're looking for lines like this one:
# # chkconfig: 2345 10 90
# OR this
# # chkconfig: - 10 90
if ($line =~ /^#\s*chkconfig:\s*([-\d]+)\s*(\d+)\s*(\d+)/ ) {
$runlevelinfo = $1;
$start_order = $2;
$stop_order = $3;
# handle a run levels arg of '-'
if ( $runlevelinfo eq '-' ) {
&B_log("ACTION","chkconfig_on saw '-' for run levels for \"$startup_script\", is defaulting to levels 3,4,5\n");
$runlevelinfo = '345';
}
@runlevels = split(//,$runlevelinfo);
# make sure the orders have 2 digits
$start_order =~ s/^(\d)$/0$1/;
$stop_order =~ s/^(\d)$/0$1/;
last READ_LOOP;
}
}
close CHKCONFIG;
# Do we have what we need?
if ( (scalar(@runlevels) < 1) || (! $start_order =~ /^\d{2}$/) || (! $stop_order =~ /^\d{2}$/) ) {
# problem
&B_log("ERROR","# B_chkconfig_on $startup_script failed -- no valid run level/start/stop info found\n");
return(-1);
}
# Now, run through creating symlinks...
&B_log("ACTION","# chkconfig_on will use run levels ".join(",",@runlevels)." for \"$startup_script\" with S order $start_order and K order $stop_order\n");
$retval=0;
# BUG: we really ought to readdir() on &getGlobal('DIR', "rcd") to get all levels
foreach my $level ( "0","1","2","3","4","5","6" ) {
my $link = '';
# we make K links in run levels not specified in the chkconfig line
$link = &getGlobal('DIR', "rcd") . "/rc" . $level . ".d/K$stop_order" . $startup_script;
my $klink = $link;
# now we see if this is a specified run level; if so, make an S link
foreach my $markedlevel ( @runlevels ) {
if ( $level == $markedlevel) {
$link = &getGlobal('DIR', "rcd") . "/rc" . $level . ".d/S$start_order" . $startup_script;
}
}
my $target = &getGlobal('DIR', "initd") ."/" . $startup_script;
my $local_return;
if ( (-e "$klink") && ($klink ne $link) ) {
# there's a K link, but this level needs an S link
unless ($GLOBAL_LOGONLY) {
$local_return = unlink("$klink");
if ( ! $local_return ) {
# unlinking old, bad $klink failed
&B_log("ERROR","Unlinking $klink failed\n");
} else {
&B_log("ACTION","Removed link $klink\n");
# If we removed the link, add a link command to the revert file
&B_revert_log (&getGlobal('BIN','ln') . " -s $target $klink\n");
} # close what to do if unlink works
} # if not GLOBAL_LOGONLY
} # if $klink exists and ne $link
# OK, we've disposed of any old K links, make what we need
if ( (! ( -e "$link" )) && ($link ne '') ) {
# link doesn't exist and the start/stop number is OK; make it
unless ($GLOBAL_LOGONLY) {
# create the link
$local_return = &B_symlink($target,$link);
if ($local_return) {
$retval++;
&B_log("ACTION","Created link $link\n");
} else {
&B_log("ERROR","Couldn't create $link when trying to chkconfig on $startup_script\n");
}
}
} # link doesn't exist
} # foreach level
}
if ($retval < @runlevels) {
$retval=0;
}
$retval;
}
###########################################################################
# &B_chkconfig_off ($daemon_name) deletes the symbolic links that are
# named in the "# chkconfig: ___ _ _ " portion of the init.d files. We
# need this utility, in place of the distro's chkconfig, because of both
# our need to add revert functionality and our need to harden distros that
# are not mounted on /.
#
# chkconfig allows for a REVERT of its work by writing to an executable
# file &getGlobal('BFILE', "removed-symlinks").
#
# It uses the following global variables to find the links and the init
# scripts, respectively:
#
# &getGlobal('DIR', "rcd") -- directory where the rc_.d subdirs can be found
# &getGlobal('DIR', "initd") -- directory the rc_.d directories link to
#
# Here an example of where you might use this:
#
# You'd like to tell stop running sendmail in daemon mode on boot:
# B_chkconfig_off("sendmail")
#
###########################################################################
sub B_chkconfig_off {
my $startup_script=$_[0];
my $retval=1;
my $chkconfig_line;
my @runlevels;
my ($start_order,$stop_order,$filetolink);
if (&GetDistro =~/^DB.*/) {
$filetolink = &getGlobal('DIR', "initd") . "/$startup_script";
if (-x $filetolink)
{
# Three ways to do this in Debian:
# 1.- have the initd script set to 600 mode
# 2.- Remove the links in rcd (re-installing the package
# will break it)
# 3.- Use update-rc.d --remove (same as 2.)
# (jfs)
&B_chmod(0600,$filetolink);
$retval=6;
# The second option
#foreach my $level ("0","1","2","3","4","5","6" ) {
#my $link = '';
#$link = &getGlobal('DIR', "rcd") . "/rc" . "$level" . ".d/K50" . "$startup_script";
#unlink($link);
#}
}
}
#
# On SUSE, chkconfig-based rc scripts have been replaced with a whole different
# system. chkconfig on SUSE is actually a shell script that does some stuff and then
# calls insserv, their replacement.
#
elsif (&GetDistro =~ /^SE/) {
# only try to chkconfig off if init script is found
if ( -e (&getGlobal('DIR', "initd") . "/$startup_script") ) {
$chkconfig_line=&getGlobal('BIN','chkconfig');
&B_System("$chkconfig_line $startup_script on", "$chkconfig_line $startup_script off");
# chkconfig doesn't take affect until reboot, need to stop service
# since expectation is that the daemons are disabled even without a reboot
B_service_stop("$startup_script");
return 1; #success
}
return 0; #failure
}
else {
# Run through the init script looking for the chkconfig line...
$retval = open CHKCONFIG,&getGlobal('DIR', "initd") . "/$startup_script";
unless ($retval) {
&B_log("ACTION","Didn't chkconfig_off $startup_script because we couldn't open " . &getGlobal('DIR', "initd") . "/$startup_script\n");
}
else {
READ_LOOP:
while (my $line=<CHKCONFIG>) {
# We're looking for lines like this one:
# # chkconfig: 2345 10 90
if ($line =~ /^#\s*chkconfig:\s*([-\d]+)\s*(\d+)\s*(\d+)/ ) {
@runlevels=split //,$1;
$start_order=$2;
$stop_order=$3;
# Change single digit run levels to double digit -- otherwise,
# the alphabetic ordering chkconfig depends on fails.
if ($start_order =~ /^\d$/ ) {
$start_order = "0" . $start_order;
&B_log("ACTION","chkconfig_off converted start order to $start_order\n");
}
if ($stop_order =~ /^\d$/ ) {
$stop_order = "0" . $stop_order;
&B_log("ACTION","chkconfig_off converted stop order to $stop_order\n");
}
last READ_LOOP;
}
}
close CHKCONFIG;
# If we never found a chkconfig line, can we just run through all 5
# rcX.d dirs from 1 to 5...?
# unless ( $start_order and $stop_order ) {
# @runlevels=("1","2","3","4","5");
# $start_order = "*"; $stop_order="*";
# }
# Now, run through removing symlinks...
$retval=0;
# Handle the special case that the run level specified is solely "-"
if ($runlevels[0] =~ /-/) {
@runlevels = ( "0","1","2","3","4","5","6" );
}
foreach my $level ( @runlevels ) {
my $link = &getGlobal('DIR', "rcd") . "/rc" . $level . ".d/S$start_order" . $startup_script;
my $new_link = &getGlobal('DIR', "rcd") . "/rc" . $level . ".d/K$stop_order" . $startup_script;
my $target = &getGlobal('DIR', "initd") ."/" . $startup_script;
my $local_return;
# Replace the S__ link in this level with a K__ link.
if ( -e $link ) {
unless ($GLOBAL_LOGONLY) {
$local_return=unlink $link;
if ($local_return) {
$local_return=symlink $target,$new_link;
unless ($local_return) {
&B_log("ERROR","Linking $target to $new_link failed.\n");
}
}
else { # unlinking failed
&B_log("ERROR","Unlinking $link failed\n");
}
}
if ($local_return) {
$retval++;
&B_log("ACTION","Removed link $link\n");
#
# If we removed the link, add a link command to the revert file
# Write out the revert information for recreating the S__
# symlink and deleting the K__ symlink.
&B_revert_log(&getGlobal('BIN',"ln") . " -s $target $link\n");
&B_revert_log(&getGlobal('BIN',"rm") . " -f $new_link\n");
}
else {
&B_log("ERROR","B_chkconfig_off $startup_script failed\n");
}
}
} # foreach
} # else-unless
} # else-DB
if ($retval < @runlevels) {
$retval=0;
}
$retval;
}
###########################################################################
# &B_service_start ($daemon_name)
# Starts service on RedHat/SUSE-based Linux distributions which have the
# service command:
#
# service $daemon_name start
#
# Other Linux distros that also support this method of starting
# services can be added to use this function.
#
# Here an example of where you might use this:
#
# You'd like to tell the system to start the vsftpd daemon:
# &B_service_start("vsftpd")
#
# Uses &B_System in HP_API.pm
# To match how the &B_System command works this method:
# returns 1 on success
# returns 0 on failure
###########################################################################
sub B_service_start {
my $daemon=$_[0];
if ( (&GetDistro !~ /^SE/) and (&GetDistro !~ /^RH/) and
(&GetDistro !~ /^RHFC/) and (&GetDistro !~ /^MN/) ) {
&B_log("ERROR","Tried to call service_start on a system lacking a service command! Internal Bastille error.");
return undef;
}
# only start service if init script is found
if ( -e (&getGlobal('DIR', 'initd') . "/$daemon") ) {
&B_log("ACTION","# service_start enabling $daemon\n");
my $service_cmd=&getGlobal('BIN', 'service');
if ($service_cmd) {
# Start the service,
# Also provide &B_System revert command
return (&B_System("$service_cmd $daemon start",
"$service_cmd $daemon stop"));
}
}
# init script not found, do not try to start, return failure
return 0;
}
###########################################################################
# &B_service_stop ($daemon_name)
# Stops service on RedHat/SUSE-based Linux distributions which have the
# service command:
#
# service $daemon_name stop
#
# Other Linux distros that also support this method of starting
# services can be added to use this function.
# Stops service.
#
#
# Here an example of where you might use this:
#
# You'd like to tell the system to stop the vsftpd daemon:
# &B_service_stop("vsftpd")
#
# Uses &B_System in HP_API.pm
# To match how the &B_System command works this method:
# returns 1 on success
# returns 0 on failure
###########################################################################
sub B_service_stop {
my $daemon=$_[0];
if ( (&GetDistro !~ /^SE/) and (&GetDistro !~ /^RH/) and
(&GetDistro !~ /^RHFC/) and (&GetDistro !~ /^MN/) ) {
&B_log("ERROR","Tried to call service_stop on a system lacking a service command! Internal Bastille error.");
return undef;
}
# only stop service if init script is found
if ( -e (&getGlobal('DIR', 'initd') . "/$daemon") ) {
&B_log("ACTION","# service_stop disabling $daemon\n");
my $service_cmd=&getGlobal('BIN', 'service');
if ($service_cmd) {
# Stop the service,
# Also provide &B_System revert command
return (&B_System("$service_cmd $daemon stop",
"$service_cmd $daemon start"));
}
}
# init script not found, do not try to stop, return failure
return 0;
}
###########################################################################
# &B_service_restart ($daemon_name)
# Restarts service on RedHat/SUSE-based Linux distributions which have the
# service command:
#
# service $daemon_name restart
#
# Other Linux distros that also support this method of starting
# services can be added to use this function.
#
# Here an example of where you might use this:
#
# You'd like to tell the system to restart the vsftpd daemon:
# &B_service_restart("vsftpd")
#
# Uses &B_System in HP_API.pm
# To match how the &B_System command works this method:
# returns 1 on success
# returns 0 on failure
###########################################################################
sub B_service_restart {
my $daemon=$_[0];
if ( (&GetDistro !~ /^SE/) and (&GetDistro !~ /^RH/) and
(&GetDistro !~ /^RHFC/) and (&GetDistro !~ /^MN/) ) {
&B_log("ERROR","Tried to call service_restart on a system lacking a service command! Internal Bastille error.");
return undef;
}
# only restart service if init script is found
if ( -e (&getGlobal('DIR', 'initd') . "/$daemon") ) {
&B_log("ACTION","# service_restart re-enabling $daemon\n");
my $service_cmd=&getGlobal('BIN', 'service');
if ($service_cmd) {
# Restart the service
return (&B_System("$service_cmd $daemon restart",
"$service_cmd $daemon restart"));
}
}
# init script not found, do not try to restart, return failure
return 0;
}
###########################################################################
# &B_is_service_off($;$)
#
# Runs the specified test to determine whether or not the question should
# be answered.
#
# return values:
# NOTSECURE_CAN_CHANGE()/0: service is on
# SECURE_CANT_CHANGE()/1: service is off
# undef: test is not defined
###########################################################################
sub B_is_service_off ($){
my $service=$_[0];
if(&GetDistro =~ "^HP-UX"){
#die "Why do I think I'm on HPUX?!\n";
return &checkServiceOnHPUX($service);
}
elsif ( (&GetDistro =~ "^RH") || (&GetDistro =~ "^SE") ) {
return &checkServiceOnLinux($service);
}
else {
&B_log("DEBUG","B_is_service off called for unsupported OS");
# not yet implemented for other distributions of Linux
# when GLOBAL_SERVICE, GLOBAL_SERVTYPE and GLOBAL_PROCESS are filled
# in for Linux, then
# at least inetd and inittab services should be similar to the above,
# whereas chkconfig would be used on some Linux distros to determine
# if non-inetd/inittab services are running at boot time. Looking at
# processes should be similar.
return undef;
}
}
###########################################################################
# &checkServiceOnLinux($service);
#
# Checks if the given service is running on a Linux system. This is
# called by B_is_Service_Off(), which is the function that Bastille
# modules should call.
#
# Return values:
# NOTSECURE_CAN_CHANGE() if the service is on
# SECURE_CANT_CHANGE() if the service is off
# undef if the state of the service cannot be determined
#
###########################################################################
sub checkServiceOnLinux($) {
my $service=$_[0];
# get the list of parameters which could be used to initiate the service
# (could be in /etc/rc.d/rc?.d, /etc/inetd.conf, or /etc/inittab, so we
# check all of them)
my @params = @{ &getGlobal('SERVICE', $service) };
my $chkconfig = &getGlobal('BIN', 'chkconfig');
my $grep = &getGlobal('BIN', 'grep');
my $inittab = &getGlobal('FILE', 'inittab');
my $serviceType = &getGlobal('SERVTYPE', $service);;
# A kludge to get things running because &getGlobal('SERVICE' doesn't
# return the expected values.
@params = ();
push (@params, $service);
foreach my $param (@params) {
&B_log("DEBUG","Checking to see if service $service is off.\n");
if ($serviceType =~ /rc/) {
my $on = &B_Backtick("$chkconfig --list $param 2>&1");
if ($on =~ /^$param:\s+unknown/) {
# This service isn't installed on the system
return NOT_INSTALLED();
}
if ($on =~ /^error reading information on service $param: No such file or directory/) {
# This service isn't installed on the system
return NOT_INSTALLED();
}
if ($on =~ /^error/) {
# This probably
&B_log("DEBUG","chkconfig returned: $param=$on\n");
return undef;
}
$on =~ s/^$param\s+//; # remove the service name and spaces
$on =~ s/[0-6]:off\s*//g; # remove any runlevel:off entries
$on =~ s/:on\s*//g; # remove the :on from the runlevels
# what remains is a list of runlevels in which the service is on,
# or a null string if it is never turned on
chomp $on; # newline should be gone already (\s)
&B_log("DEBUG","chkconfig returned: $param=$on\n");
if ($on =~ /^\d+$/) {
# service is not off
########################### BREAK out, don't skip question
return NOTSECURE_CAN_CHANGE();
}
}
elsif ($serviceType =~ /inet/) {
my $on = &B_Backtick("$chkconfig --list $param 2>&1");
if ($on =~ /^$param:\s+unknown/) {
# This service isn't installed on the system
return NOT_INSTALLED();
}
if ($on =~ /^error reading information on service $param: No such file or directory/) {
# This service isn't installed on the system
return NOT_INSTALLED();
}
if ($on =~ /^error/ ) {
# Something else is wrong?
# return undef
return undef;
}
if ($on =~ tr/\n// > 1) {
$on =~ s/^xinetd.+\n//;
}
$on =~ s/^\s*$param:?\s+//; # remove the service name and spaces
chomp $on; # newline should be gone already (\s)
&B_log("DEBUG","chkconfig returned: $param=$on\n");
if ($on =~ /^on$/) {
# service is not off
########################### BREAK out, don't skip question
return NOTSECURE_CAN_CHANGE();
}
}
else {
# perhaps the service is started by inittab
my $inittabline = &B_Backtick("$grep -E '^[^#].{0,3}:.*:.+:.*$param' $inittab");
if ($inittabline =~ /.+/) { # . matches anything except newlines
# service is not off
&B_log("DEBUG","Checking inittab; found $inittabline\n");
########################### BREAK out, don't skip question
return NOTSECURE_CAN_CHANGE();
}
}
} # foreach my $param
# boot-time parameters are not set; check processes
# Note the checkProcsforService returns INCONSISTENT() if a process is found
# assuming the checks above
return &checkProcsForService($service);
}
1;
@@ -0,0 +1,34 @@
Upstream-Status: Inappropriate [No upstream maintenance]
Signed-off-by: Anne Mulhern <mulhern@yoctoproject.org>
---
Index: Bastille/BastilleBackEnd
===================================================================
--- Bastille.orig/BastilleBackEnd 2013-08-21 12:40:54.000000000 -0400
+++ Bastille/BastilleBackEnd 2013-08-21 12:43:21.895950001 -0400
@@ -52,11 +52,13 @@
my $force = 0;
my $debug = 0;
my $alternate_config=undef;
+my $os_version=undef;
if( Getopt::Long::GetOptions( "n" => \$nodisclaim,
"v" => \$verbose,
"force" => \$force,
"f=s" => \$alternate_config,
+ "os=s" => \$os_version,
"debug" => \$debug) ) {
$error = 0; # no parse error
@@ -66,7 +68,8 @@
&setOptions(
debug => $debug,
- verbose => $verbose);
+ verbose => $verbose,
+ os => $os_version);
&ConfigureForDistro;
if ( $error ) { # GetOptions couldn't parse all of the args
@@ -0,0 +1,43 @@
Upstream-Status: Inappropriate [No upstream maintenance]
Signed-off-by: Anne Mulhern <mulhern@yoctoproject.org>
---
Index: Bastille/bin/bastille
===================================================================
--- Bastille.orig/bin/bastille 2013-08-21 08:59:06.647950000 -0400
+++ Bastille/bin/bastille 2013-08-21 15:55:53.193631711 -0400
@@ -195,7 +195,6 @@
systemFileLocations
isAssessing='no'
-nonXArg='no'
if [ $PERL_V_MAJ -eq $MIN_V_MAJ -a $PERL_V_MIN -lt $MIN_V_MIN -o $PERL_V_MAJ -lt $MIN_V_MAJ ]; then # invalid Perl
printErr
@@ -316,12 +315,10 @@
'--os')
options_left="$options_left --os"
optarg='yes'
- nonXArg='yes'
;;
'-f')
options_left="$options_left -f"
optarg='yes'
- nonXArg='yes'
;;
# Non-exclusive (undocumented and unsupported) options follow:
# There is no validity/combination checking done with these.
@@ -345,11 +342,6 @@
fi
done
-#Detect case where -f or --os attempted use with --assess
- if [ \( x$nonXArg = xyes \) -a \( x$isAssessing = xyes \) ]; then
- printUsage
- exit 2
- fi
# We have a valid version of perl! Verify that all the required
# modules can be found.
@@ -0,0 +1,19 @@
Upstream-Status: Inappropriate [No upstream maintenance]
Signed-off-by: Anne Mulhern <mulhern@yoctoproject.org>
---
Index: Bastille/Bastille_Curses.pm
===================================================================
--- Bastille.orig/Bastille_Curses.pm 2013-08-21 08:58:53.899950000 -0400
+++ Bastille/Bastille_Curses.pm 2013-08-21 09:20:20.295950005 -0400
@@ -84,7 +84,7 @@
}
# Output answers to the script and display
- &checkAndSaveConfig(&getGlobal('BFILE', "config"));
+ &outputConfig;
# Run Bastille
@@ -0,0 +1,106 @@
# Q: Would you like to enforce password aging? [Y]
AccountSecurity.passwdage="Y"
# Q: Should Bastille disable clear-text r-protocols that use IP-based authentication? [Y]
AccountSecurity.protectrhost="Y"
# Q: Should we disallow root login on tty's 1-6? [N]
AccountSecurity.rootttylogins="Y"
# Q: What umask would you like to set for users on the system? [077]
AccountSecurity.umask="077"
# Q: Do you want to set the default umask? [Y]
AccountSecurity.umaskyn="Y"
# Q: Would you like to deactivate the Apache web server? [Y]
Apache.apacheoff="Y"
# Q: Would you like to password protect single-user mode? [Y]
BootSecurity.passsum="Y"
# Q: Should we restrict console access to a small group of user accounts? [N]
ConfigureMiscPAM.consolelogin="Y"
# Q: Which accounts should be able to login at console? [root]
ConfigureMiscPAM.consolelogin_accounts="root"
# Q: Would you like to put limits on system resource usage? [N]
ConfigureMiscPAM.limitsconf="Y"
# Q: Would you like to set more restrictive permissions on the administration utilities? [N]
FilePermissions.generalperms_1_1="Y"
# Q: Would you like to disable SUID status for mount/umount?
FilePermissions.suidmount="Y"
# Q: Would you like to disable SUID status for ping? [Y]
FilePermissions.suidping="Y"
# Q: Would you like to disable SUID status for traceroute? [Y]
FilePermissions.suidtrace="Y"
# Q: Do you need the advanced networking options?
Firewall.ip_advnetwork="Y"
# Q: Should Bastille run the firewall and enable it at boot time? [N]
Firewall.ip_enable_firewall="Y"
# Q: Would you like to run the packet filtering script? [N]
Firewall.ip_intro="Y"
# Q: Interfaces for DHCP queries: [ ]
Firewall.ip_s_dhcpiface=" "
# Q: DNS servers: [0.0.0.0/0]
Firewall.ip_s_dns="10.184.9.1"
# Q: ICMP allowed types: [destination-unreachable echo-reply time-exceeded]
Firewall.ip_s_icmpallowed="destination-unreachable echo-reply time-exceeded"
# Q: ICMP services to audit: [ ]
Firewall.ip_s_icmpaudit=" "
# Q: ICMP types to disallow outbound: [destination-unreachable time-exceeded]
Firewall.ip_s_icmpout="destination-unreachable time-exceeded"
# Q: Internal interfaces: [ ]
Firewall.ip_s_internaliface=" "
# Q: TCP service names or port numbers to allow on private interfaces: [ ]
Firewall.ip_s_internaltcp=" "
# Q: UDP service names or port numbers to allow on private interfaces: [ ]
Firewall.ip_s_internaludp=" "
# Q: Masqueraded networks: [ ]
Firewall.ip_s_ipmasq=" "
# Q: Kernel modules to masquerade: [ftp raudio vdolive]
Firewall.ip_s_kernelmasq="ftp raudio vdolive"
# Q: NTP servers to query: [ ]
Firewall.ip_s_ntpsrv=" "
# Q: Force passive mode? [N]
Firewall.ip_s_passiveftp="N"
# Q: Public interfaces: [eth+ ppp+ slip+]
Firewall.ip_s_publiciface="eth+ ppp+ slip+"
# Q: TCP service names or port numbers to allow on public interfaces:[ ]
Firewall.ip_s_publictcp=" "
# Q: UDP service names or port numbers to allow on public interfaces:[ ]
Firewall.ip_s_publicudp=" "
# Q: Reject method: [DENY]
Firewall.ip_s_rejectmethod="DENY"
# Q: Enable source address verification? [Y]
Firewall.ip_s_srcaddr="Y"
# Q: TCP services to audit: [telnet ftp imap pop3 finger sunrpc exec login linuxconf ssh]
Firewall.ip_s_tcpaudit="telnet ftp imap pop3 finger sunrpc exec login linuxconf ssh"
# Q: TCP services to block: [2049 2065:2090 6000:6020 7100]
Firewall.ip_s_tcpblock="2049 2065:2090 6000:6020 7100"
# Q: Trusted interface names: [lo]
Firewall.ip_s_trustiface="lo"
# Q: UDP services to audit: [31337]
Firewall.ip_s_udpaudit="31337"
# Q: UDP services to block: [2049 6770]
Firewall.ip_s_udpblock="2049 6770"
# Q: Would you like to add additional logging? [Y]
Logging.morelogging="Y"
# Q: Would you like to set up process accounting? [N]
Logging.pacct="N"
# Q: Do you have a remote logging host? [N]
Logging.remotelog="N"
# Q: Would you like to disable acpid and/or apmd? [Y]
MiscellaneousDaemons.apmd="Y"
# Q: Would you like to deactivate NFS and Samba? [Y]
MiscellaneousDaemons.remotefs="Y"
# Q: Would you like to disable printing? [N]
Printing.printing="Y"
# Q: Would you like to disable printing? [N]
Printing.printing_cups="Y"
# Q: Would you like to display "Authorized Use" messages at log-in time? [Y]
SecureInetd.banners="Y"
# Q: Should Bastille ensure inetd's FTP service does not run on this system? [y]
SecureInetd.deactivate_ftp="Y"
# Q: Should Bastille ensure the telnet service does not run on this system? [y]
SecureInetd.deactivate_telnet="Y"
# Q: Who is responsible for granting authorization to use this machine?
SecureInetd.owner="its owner"
# Q: Would you like to set a default-deny on TCP Wrappers and xinetd? [N]
SecureInetd.tcpd_default_deny="Y"
# Q: Do you want to stop sendmail from running in daemon mode? [Y]
Sendmail.sendmaildaemon="Y"
# Q: Would you like to install TMPDIR/TMP scripts? [N]
TMPDIR.tmpdir="N"
@@ -0,0 +1,40 @@
Upstream-Status: Inappropriate [No upstream maintenance]
Signed-off-by: Anne Mulhern <mulhern@yoctoproject.org>
---
Index: Bastille/Bastille_Curses.pm
===================================================================
--- Bastille.orig/Bastille_Curses.pm 2013-08-27 16:43:39.130959000 -0400
+++ Bastille/Bastille_Curses.pm 2013-08-27 16:43:39.794959000 -0400
@@ -83,11 +83,6 @@
# Output answers to the script and display
&outputConfig;
- # Run Bastille
-
- &Run_Bastille_with_Config;
-
-
# Display Credits
open CREDITS,"/usr/share/Bastille/Credits";
Index: Bastille/InteractiveBastille
===================================================================
--- Bastille.orig/InteractiveBastille 2013-08-27 16:43:39.434959000 -0400
+++ Bastille/InteractiveBastille 2013-08-27 17:18:55.758959000 -0400
@@ -531,10 +531,10 @@
" Please address bug reports and suggestions to jay\@bastille-linux.org\n" .
"\n";
- $InterfaceEndScreenDescription = "We will now implement the choices you have made here.\n\n" .
+ $InterfaceEndScreenDescription = "We will now record the choices you have made here.\n\n" .
"Answer NO if you want to go back and make changes!\n";
- $InterfaceEndScreenQuestion = "Are you finished answering the questions, i.e. may we make the changes?";
- $InterfaceEndScreenNoEpilogue = "Please use Back/Next buttons to move among the questions you wish to\nchange.\n\nChoose YES on this question later to implement your choices.\n";
+ $InterfaceEndScreenQuestion = "Are you finished answering the questions, i.e. may we record the answers and exit?";
+ $InterfaceEndScreenNoEpilogue = "Please use Back/Next buttons to move among the questions you wish to\nchange.\n\nChoose YES on this question later to record your choices.\n";
require Bastille_Curses;
} elsif ($GLOBAL_AUDITONLY) {
@@ -0,0 +1,32 @@
Upstream-Status: Inappropriate [No upstream maintenance]
Signed-off-by: Anne Mulhern <mulhern@yoctoproject.org>
---
Index: Bastille/bin/bastille
===================================================================
--- Bastille.orig/bin/bastille 2013-08-25 14:16:35.614779001 -0400
+++ Bastille/bin/bastille 2013-08-25 14:16:38.674779000 -0400
@@ -60,7 +60,7 @@
printUsage () {
cat >&2 << EOF
$ERRSPACES Usage: bastille [ -b | -c | -x ] [ --os <version>] [ -f <alternate config> ]
-$ERRSPACES bastille [-r | -l | -h | --assess | --assessnobrowser ]
+$ERRSPACES bastille [-r | -l | -h | --assess | --assessnobrowser ] [ --os <version> ]
$ERRSPACES -b : use a saved config file to apply changes
$ERRSPACES directly to system
$ERRSPACES -c : use the Curses (non-X11) GUI, not available on HP-UX
Index: Bastille/Bastille/API.pm
===================================================================
--- Bastille.orig/Bastille/API.pm 2013-08-25 08:15:40.266779002 -0400
+++ Bastille/Bastille/API.pm 2013-08-25 14:18:22.750778811 -0400
@@ -206,7 +206,7 @@
#options before interactive or Bastille runs, so this check is often redundant
$GLOBAL_ERROR{"usage"}="\n".
"$spc Usage: bastille [ -b | -c | -x ] [ --os <version> ] [ -f <alternate config> ]\n".
- "$spc bastille [ -r | --assess | --assessnobowser ]\n\n".
+ "$spc bastille [ -r | --assess | --assessnobowser ] [ --os <version> ]\n\n".
"$spc --assess : check status of system and report in browser\n".
"$spc --assessnobrowser : check status of system and list report locations\n".
"$spc -b : use a saved config file to apply changes\n".
@@ -0,0 +1,64 @@
Upstream-Status: Inappropriate [No upstream maintenance]
Signed-off-by: Anne Mulhern <mulhern@yoctoproject.org>
---
Index: Bastille/bin/bastille
===================================================================
--- Bastille.orig/bin/bastille 2013-06-20 14:58:01.065796000 -0400
+++ Bastille/bin/bastille 2013-08-20 15:16:18.472378000 -0400
@@ -102,8 +102,9 @@
# defines OS specific file locations based on uname
systemFileLocations
+ config_files=`find $config_repository -type f -name \*config 2>/dev/null`
+
if [ -f $last_config ]; then
- config_files=`find $config_repository -type f -name \*config 2>/dev/null`
for config_cursor in `echo $config_files`
do
if /usr/bin/diff $last_config $config_cursor >/dev/null 2>&1
@@ -112,8 +113,8 @@
fi
done
if [ -n "$match" ]; then
- echo "The last bastille run corresponds to the following profiles:"
- echo "$match"
+ printf "The last Bastille run corresponds to the following profiles:\n"
+ printf "$match"
else
cat >&2 << EOF
NOTE: The last config file applied,
@@ -122,18 +123,28 @@
$ERRSPACES $config_repository.
$ERRSPACES This probably means that Bastille was last run interactively and
$ERRSPACES changes were made to the config file, but they have not yet been
-$ERRSPACES applied, or that the source config file was moved. If you do have pending
+$ERRSPACES applied, or that the source config file was moved. If you do have pending
$ERRSPACES changes in a config file, you can apply them by running
$ERRSPACES 'bastille -b -f <config file>.'
EOF
fi
else
- echo "NOTE: The system is in its pre-bastilled state.\n"
+ for config_cursor in `echo $config_files`
+ do
+ match="$match $config_cursor\n"
+ done
+ if [ -n "$match" ]; then
+ printf "The following Bastille profiles were located:\n"
+ printf "$match"
+ else
+ printf "No Bastille profiles were located.\n"
+ fi
+ printf "No log files of profiles from previous executions of Bastille have been found. It is likely that Bastille has not been run on this machine.\n"
fi
-
}
+
# First, make sure we're root
if [ `PATH="/usr/bin:/bin"; id -u` -ne 0 ]; then
echo "ERROR: Bastille must be run as root user" >&2
@@ -0,0 +1,54 @@
Upstream-Status: Inappropriate [No upstream maintenance]
Signed-off-by: Anne Mulhern <mulhern@yoctoproject.org>
---
Index: Bastille/Bastille/Firewall.pm
===================================================================
--- Bastille.orig/Bastille/Firewall.pm 2008-09-14 19:56:54.000000000 -0400
+++ Bastille/Bastille/Firewall.pm 2013-08-20 16:28:44.588378000 -0400
@@ -21,6 +21,7 @@
package Bastille::Firewall;
use Bastille::API;
+use Bastille::API::AccountPermission;
use Bastille::API::FileContent;
use Bastille::API::ServiceAdmin;
Index: Bastille/Bastille/SecureInetd.pm
===================================================================
--- Bastille.orig/Bastille/SecureInetd.pm 2008-09-14 19:56:58.000000000 -0400
+++ Bastille/Bastille/SecureInetd.pm 2013-08-20 16:45:02.252378001 -0400
@@ -12,6 +12,7 @@
use lib "/usr/lib";
use Bastille::API;
+use Bastille::API::AccountPermission;
use Bastille::API::HPSpecific;
use Bastille::API::ServiceAdmin;
use Bastille::API::FileContent;
Index: Bastille/Bastille/ConfigureMiscPAM.pm
===================================================================
--- Bastille.orig/Bastille/ConfigureMiscPAM.pm 2005-09-12 23:47:28.000000000 -0400
+++ Bastille/Bastille/ConfigureMiscPAM.pm 2013-08-20 18:36:07.340378001 -0400
@@ -5,6 +5,7 @@
use lib "/usr/lib";
use Bastille::API;
+use Bastille::API::FileContent;
# To DO:
#
Index: Bastille/Bastille/Printing.pm
===================================================================
--- Bastille.orig/Bastille/Printing.pm 2008-09-14 19:56:58.000000000 -0400
+++ Bastille/Bastille/Printing.pm 2013-08-20 19:05:01.532378002 -0400
@@ -5,6 +5,7 @@
use lib "/usr/lib";
use Bastille::API;
+use Bastille::API::AccountPermission;
use Bastille::API::HPSpecific;
use Bastille::API::ServiceAdmin;
use Bastille::API::FileContent;
@@ -0,0 +1,38 @@
Upstream-Status: Inappropriate [No upstream maintenance]
Signed-off-by: Anne Mulhern <mulhern@yoctoproject.org>
---
Index: Bastille/Bastille_Curses.pm
===================================================================
--- Bastille.orig/Bastille_Curses.pm 2013-08-24 18:21:54.445288000 -0400
+++ Bastille/Bastille_Curses.pm 2013-08-24 18:29:16.981288000 -0400
@@ -36,9 +36,6 @@
use Curses;
use Curses::Widgets;
- # Number_Modules is the number of modules loaded in by Load_Questions
- $Number_Modules=0;
-
#
# Highlighted button is the button currently chosen in the button bar
# We preserve this from question to question...
@@ -397,7 +394,7 @@
my $title;
if ($module) {
- $title=$module . " of $Number_Modules";
+ $title=$module;
}
txt_field( 'window' => $window,
@@ -488,7 +485,7 @@
my $title;
if ($module) {
- $title=$module . " of $Number_Modules";
+ $title=$module;
}
noecho;
@@ -0,0 +1,27 @@
Upstream-Status: Inappropriate [No upstream maintenance]
Signed-off-by: Anne Mulhern <mulhern@yoctoproject.org>
---
Index: Bastille/bin/bastille
===================================================================
--- Bastille.orig/bin/bastille
+++ Bastille/bin/bastille
@@ -162,11 +162,12 @@ fi
# We check that the version is at least the minimum
PERL_VERSION=`${CURRENT_PERL_PATH}/perl -version |
- head -2 | # the second line contains the version
+ head -n 2 | # the second line contains the version
tr " " "\n" | # split words into separate lines
- sed -e "s/^v//" | # to get rid of the v in v5.6.0
- grep "^[1-9]\." | # find a "word" that starts with number dot
- sed -e "s/_/./"` # substitute _patchlevel with .patchlevel
+ grep "^(v" | # find a "word" that starts with '(v'
+ sed -e "s/^(v//" -e "s/)//" -e "s/_/./"`
+ # to get rid of the (v in v5.6.0
+ # substitute _patchlevel with .patchlevel
# (used in 5.005_03 and prior)
# everything before the first .
@@ -0,0 +1,65 @@
From c59b84ca3bda8e4244d47901b6966f28dd675434 Mon Sep 17 00:00:00 2001
From: Andrei Dinu <andrei.adrianx.dinu@intel.com>
Date: Thu, 23 May 2013 15:12:23 +0300
Subject: [PATCH] added yocto-standard to bastille
In order to make Bastille functional and avoid errors
regarding distros, if not any given distro is identified,
yocto-standard distro is added to the distro variable
in Bastille.
Fixed also some warnings regarding defined statements
in API.pm.
Upstream-Status: Inappropriate [No upstream maintenance]
Signed-off-by: Andrei Dinu <andrei.adrianx.dinu@intel.com>
Signed-off-by: Anne Mulhern <mulhern@yoctoproject.org>
---
Bastille/API.pm | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
Index: Bastille/Bastille/API.pm
===================================================================
--- Bastille.orig/Bastille/API.pm 2008-09-14 19:56:53.000000000 -0400
+++ Bastille/Bastille/API.pm 2013-08-21 08:55:26.715950001 -0400
@@ -445,8 +445,8 @@
$release=`/usr/bin/uname -sr`;
}
else {
- print STDERR "$err Could not determine operating system version!\n";
- $distro="unknown";
+ print STDERR "$err Could not determine operating system version!\n";
+ $distro="unknown"
}
# Figure out what kind of system we're on.
@@ -1284,7 +1284,7 @@
my $sumFile = &getGlobal('BFILE',"sum.csv");
- if ( defined %GLOBAL_SUM ) {
+ if ( %GLOBAL_SUM ) {
open( SUM, "> $sumFile") or &B_log("ERROR","Unable to open $sumFile for write.\n$!\n");
@@ -1318,7 +1318,7 @@
my $file = $_[0];
my $cksum = &getGlobal('BIN',"cksum");
- if (not(defined(%GLOBAL_SUM))) {
+ if (not(%GLOBAL_SUM)) {
&B_read_sums;
}
@@ -1375,7 +1375,7 @@
sub B_isFileinSumDB($) {
my $file = $_[0];
- if (not(defined(%GLOBAL_SUM))) {
+ if (not(%GLOBAL_SUM)) {
&B_log("DEBUG","Reading in DB from B_isFileinSumDB");
&B_read_sums;
}
@@ -0,0 +1,476 @@
Upstream-Status: Inappropriate [No upstream maintenance]
Signed-off-by: Anne Mulhern <mulhern@yoctoproject.org>
---
Index: Bastille/Bastille/API.pm
===================================================================
--- Bastille.orig/Bastille/API.pm 2013-08-22 04:32:38.269968002 -0400
+++ Bastille/Bastille/API.pm 2013-08-22 11:29:53.137968002 -0400
@@ -141,7 +141,7 @@
checkProcsForService
- $GLOBAL_OS $GLOBAL_ACTUAL_OS $CLI
+ $CLI
$GLOBAL_LOGONLY $GLOBAL_VERBOSE $GLOBAL_DEBUG $GLOBAL_AUDITONLY $GLOBAL_AUDIT_NO_BROWSER $errorFlag
%GLOBAL_BIN %GLOBAL_DIR %GLOBAL_FILE
%GLOBAL_BDIR %GLOBAL_BFILE
@@ -198,7 +198,7 @@
my $err ="ERROR: ";
my $spc =" ";
my $GLOBAL_OS="None";
-my $GLOBAL_ACTUAL_OS="None";
+my $GLOBAL_INFERRED_OS="None";
my %GLOBAL_SUMS=();
my $CLI='';
@@ -306,7 +306,7 @@
###########################################################################
#
-# GetDistro checks to see if the target is a known distribution and reports
+# InferDistro checks to see if the target is a known distribution and reports
# said distribution.
#
# This is used throughout the script, but also by ConfigureForDistro.
@@ -314,205 +314,194 @@
#
###########################################################################
-sub GetDistro() {
+sub InferDistro() {
my ($release,$distro);
- # Only read files for the distro once.
- # if the --os option was used then
- if ($GLOBAL_OS eq "None") {
- if ( -e "/etc/mandrake-release" ) {
- open(MANDRAKE_RELEASE,"/etc/mandrake-release");
- $release=<MANDRAKE_RELEASE>;
-
- if ( ($release =~ /^Mandrake Linux release (\d+\.\d+\w*)/) or ($release =~ /^Linux Mandrake release (\d+\.\d+\w*)/) ) {
- $distro="MN$1";
- }
- elsif ( $release =~ /^Mandrakelinux release (\d+\.\d+)\b/ ) {
- $distro="MN$1";
- }
- else {
- print STDERR "$err Couldn't determine Mandrake/Mandriva version! Setting to 10.1!\n";
- $distro="MN10.1";
- }
-
- close(MANDRAKE_RELEASE);
- }
- elsif ( -e "/etc/immunix-release" ) {
- open(IMMUNIX_RELEASE,"/etc/immunix-release");
- $release=<IMMUNIX_RELEASE>;
- unless ($release =~ /^Immunix Linux release (\d+\.\d+\w*)/) {
- print STDERR "$err Couldn't determine Immunix version! Setting to 6.2!\n";
- $distro="RH6.2";
- }
- else {
- $distro="RH$1";
- }
- close(*IMMUNIX_RELEASE);
- }
- elsif ( -e '/etc/fedora-release' ) {
- open(FEDORA_RELEASE,'/etc/fedora-release');
- $release=<FEDORA_RELEASE>;
- close FEDORA_RELEASE;
- if ($release =~ /^Fedora Core release (\d+\.?\d*)/) {
- $distro = "RHFC$1";
- }
- elsif ($release =~ /^Fedora release (\d+\.?\d*)/) {
- $distro = "RHFC$1";
- }
- else {
- print STDERR "$err Could not determine Fedora version! Setting to Fedora Core 8\n";
- $distro='RHFC8';
- }
+ if ( -e "/etc/mandrake-release" ) {
+ open(MANDRAKE_RELEASE,"/etc/mandrake-release");
+ $release=<MANDRAKE_RELEASE>;
+
+ if ( ($release =~ /^Mandrake Linux release (\d+\.\d+\w*)/) or ($release =~ /^Linux Mandrake release (\d+\.\d+\w*)/) ) {
+ $distro="MN$1";
+ }
+ elsif ( $release =~ /^Mandrakelinux release (\d+\.\d+)\b/ ) {
+ $distro="MN$1";
+ }
+ else {
+ print STDERR "$err Could not infer Mandrake/Mandriva version! Setting to 10.1!\n";
+ $distro="MN10.1";
+ }
+
+ close(MANDRAKE_RELEASE);
+ }
+ elsif ( -e "/etc/immunix-release" ) {
+ open(IMMUNIX_RELEASE,"/etc/immunix-release");
+ $release=<IMMUNIX_RELEASE>;
+ unless ($release =~ /^Immunix Linux release (\d+\.\d+\w*)/) {
+ print STDERR "$err Could not infer Immunix version! Setting to 6.2!\n";
+ $distro="RH6.2";
+ }
+ else {
+ $distro="RH$1";
}
- elsif ( -e "/etc/redhat-release" ) {
- open(*REDHAT_RELEASE,"/etc/redhat-release");
- $release=<REDHAT_RELEASE>;
- if ($release =~ /^Red Hat Linux release (\d+\.?\d*\w*)/) {
- $distro="RH$1";
- }
- elsif ($release =~ /^Red Hat Linux .+ release (\d+)\.?\d*([AEW]S)/) {
- $distro="RHEL$1$2";
- }
- elsif ($release =~ /^Red Hat Enterprise Linux ([AEW]S) release (\d+)/) {
- $distro="RHEL$2$1";
+ close(*IMMUNIX_RELEASE);
+ }
+ elsif ( -e '/etc/fedora-release' ) {
+ open(FEDORA_RELEASE,'/etc/fedora-release');
+ $release=<FEDORA_RELEASE>;
+ close FEDORA_RELEASE;
+ if ($release =~ /^Fedora Core release (\d+\.?\d*)/) {
+ $distro = "RHFC$1";
+ }
+ elsif ($release =~ /^Fedora release (\d+\.?\d*)/) {
+ $distro = "RHFC$1";
+ }
+ else {
+ print STDERR "$err Could not infer Fedora version! Setting to Fedora Core 8\n";
+ $distro='RHFC8';
+ }
+ }
+ elsif ( -e "/etc/redhat-release" ) {
+ open(*REDHAT_RELEASE,"/etc/redhat-release");
+ $release=<REDHAT_RELEASE>;
+ if ($release =~ /^Red Hat Linux release (\d+\.?\d*\w*)/) {
+ $distro="RH$1";
+ }
+ elsif ($release =~ /^Red Hat Linux .+ release (\d+)\.?\d*([AEW]S)/) {
+ $distro="RHEL$1$2";
+ }
+ elsif ($release =~ /^Red Hat Enterprise Linux ([AEW]S) release (\d+)/) {
+ $distro="RHEL$2$1";
+ }
+ elsif ($release =~ /^CentOS release (\d+\.\d+)/) {
+ my $version = $1;
+ if ($version =~ /^4\./) {
+ $distro='RHEL4AS';
}
- elsif ($release =~ /^CentOS release (\d+\.\d+)/) {
- my $version = $1;
- if ($version =~ /^4\./) {
- $distro='RHEL4AS';
- }
- elsif ($version =~ /^3\./) {
- $distro='RHEL3AS';
- }
- else {
- print STDERR "$err Could not determine CentOS version! Setting to Red Hat Enterprise 4 AS.\n";
- $distro='RHEL4AS';
- }
- }
- else {
- # JJB/HP - Should this be B_log?
- print STDERR "$err Couldn't determine Red Hat version! Setting to 9!\n";
- $distro="RH9";
- }
- close(REDHAT_RELEASE);
-
- }
- elsif ( -e "/etc/debian_version" ) {
- $stable="3.1"; #Change this when Debian stable changes
- open(*DEBIAN_RELEASE,"/etc/debian_version");
- $release=<DEBIAN_RELEASE>;
- unless ($release =~ /^(\d+\.\d+\w*)/) {
- print STDERR "$err System is not running a stable Debian GNU/Linux version. Setting to $stable.\n";
- $distro="DB$stable";
+ elsif ($version =~ /^3\./) {
+ $distro='RHEL3AS';
}
else {
- $distro="DB$1";
- }
- close(DEBIAN_RELEASE);
- }
- elsif ( -e "/etc/SuSE-release" ) {
- open(*SUSE_RELEASE,"/etc/SuSE-release");
- $release=<SUSE_RELEASE>;
- if ($release =~ /^SuSE Linux (\d+\.\d+\w*)/i) {
- $distro="SE$1";
- }
- elsif ($release =~ /^SUSE LINUX Enterprise Server (\d+\.?\d?\w*)/i) {
- $distro="SESLES$1";
- }
- elsif ($release =~ /^SUSE Linux Enterprise Server (\d+\.?\d?\w*)/i) {
- $distro="SESLES$1";
- }
- elsif ($release =~ /^openSuSE (\d+\.\d+\w*)/i) {
- $distro="SE$1";
+ print STDERR "$err Could not infer CentOS version! Setting to Red Hat Enterprise 4 AS.\n";
+ $distro='RHEL4AS';
}
- else {
- print STDERR "$err Couldn't determine SuSE version! Setting to 10.3!\n";
- $distro="SE10.3";
- }
- close(SUSE_RELEASE);
- }
- elsif ( -e "/etc/turbolinux-release") {
- open(*TURBOLINUX_RELEASE,"/etc/turbolinux-release");
- $release=<TURBOLINUX_RELEASE>;
- unless ($release =~ /^Turbolinux Workstation (\d+\.\d+\w*)/) {
- print STDERR "$err Couldn't determine TurboLinux version! Setting to 7.0!\n";
- $distro="TB7.0";
- }
- else {
- $distro="TB$1";
- }
- close(TURBOLINUX_RELEASE);
+ }
+ else {
+ # JJB/HP - Should this be B_log?
+ print STDERR "$err Could not infer Red Hat version! Setting to 9!\n";
+ $distro="RH9";
+ }
+ close(REDHAT_RELEASE);
+
+ }
+ elsif ( -e "/etc/debian_version" ) {
+ $stable="3.1"; #Change this when Debian stable changes
+ open(*DEBIAN_RELEASE,"/etc/debian_version");
+ $release=<DEBIAN_RELEASE>;
+ unless ($release =~ /^(\d+\.\d+\w*)/) {
+ print STDERR "$err System is not running a stable Debian GNU/Linux version. Setting to $stable.\n";
+ $distro="DB$stable";
+ }
+ else {
+ $distro="DB$1";
+ }
+ close(DEBIAN_RELEASE);
+ }
+ elsif ( -e "/etc/SuSE-release" ) {
+ open(*SUSE_RELEASE,"/etc/SuSE-release");
+ $release=<SUSE_RELEASE>;
+ if ($release =~ /^SuSE Linux (\d+\.\d+\w*)/i) {
+ $distro="SE$1";
+ }
+ elsif ($release =~ /^SUSE LINUX Enterprise Server (\d+\.?\d?\w*)/i) {
+ $distro="SESLES$1";
+ }
+ elsif ($release =~ /^SUSE Linux Enterprise Server (\d+\.?\d?\w*)/i) {
+ $distro="SESLES$1";
+ }
+ elsif ($release =~ /^openSuSE (\d+\.\d+\w*)/i) {
+ $distro="SE$1";
+ }
+ else {
+ print STDERR "$err Could not infer SuSE version! Setting to 10.3!\n";
+ $distro="SE10.3";
}
+ close(SUSE_RELEASE);
+ }
+ elsif ( -e "/etc/turbolinux-release") {
+ open(*TURBOLINUX_RELEASE,"/etc/turbolinux-release");
+ $release=<TURBOLINUX_RELEASE>;
+ unless ($release =~ /^Turbolinux Workstation (\d+\.\d+\w*)/) {
+ print STDERR "$err Could not infer TurboLinux version! Setting to 7.0!\n";
+ $distro="TB7.0";
+ }
else {
- # We're either on Mac OS X, HP-UX or an unsupported O/S.
- if ( -x '/usr/bin/uname') {
+ $distro="TB$1";
+ }
+ close(TURBOLINUX_RELEASE);
+ }
+ else {
+ # We're either on Mac OS X, HP-UX or an unsupported O/S.
+ if ( -x '/usr/bin/uname') {
# uname is in /usr/bin on Mac OS X and HP-UX
- $release=`/usr/bin/uname -sr`;
- }
- else {
- print STDERR "$err Could not determine operating system version!\n";
- $distro="unknown"
- }
-
- # Figure out what kind of system we're on.
- if ($release ne "") {
- if ($release =~ /^Darwin\s+(\d+)\.(\d+)/) {
- if ($1 == 6 ) {
- $distro = "OSX10.2";
- }
- elsif ($1 == 7) {
- $distro = "OSX10.3";
- }
- elsif ($1 == 8) {
- $distro = "OSX10.3";
- }
- else {
- $distro = "unknown";
- }
+ $release=`/usr/bin/uname -sr`;
+ }
+ else {
+ print STDERR "$err Could not infer operating system version from filesystem context. Setting inferred distro to 'unknown'.\n";
+ $distro="unknown";
+ }
+
+ # Figure out what kind of system we're on.
+ if ($release ne "") {
+ if ($release =~ /^Darwin\s+(\d+)\.(\d+)/) {
+ if ($1 == 6 ) {
+ $distro = "OSX10.2";
}
- elsif ( $release =~ /(^HP-UX)\s*B\.(\d+\.\d+)/ ) {
- $distro="$1$2";
+ elsif ($1 == 7) {
+ $distro = "OSX10.3";
}
+ elsif ($1 == 8) {
+ $distro = "OSX10.3";
+ }
else {
- print STDERR "$err Could not determine operating system version!\n";
- $distro="unknown";
+ print STDERR "$err Could not infer operating system version from filesystem context. Setting inferred distro to 'unknown'.\n";
+ $distro = "unknown";
}
}
+ elsif ( $release =~ /(^HP-UX)\s*B\.(\d+\.\d+)/ ) {
+ $distro="$1$2";
+ }
+ else {
+ print STDERR "$err Could not infer operating system version from filesystem context. Setting inferred distro to 'unknown'.\n";
+ $distro="unknown";
+ }
}
-
- $GLOBAL_OS=$distro;
- } elsif (not (defined $GLOBAL_OS)) {
- print "ERROR: GLOBAL OS Scoping Issue\n";
- } else {
- $distro = $GLOBAL_OS;
}
-
return $distro;
}
###################################################################################
-# &getActualDistro; #
+# &getInferredDistro; #
# #
# This subroutine returns the actual os version in which is running on. This #
# os version is independent of the --os switch feed to bastille. #
# #
###################################################################################
-sub getActualDistro {
- # set local variable to $GLOBAL_OS
+sub getInferredDistro {
+ if ($GLOBAL_INFERRED_OS eq "None") {
+ $GLOBAL_INFERRED_OS = &InferDistro;
+ }
+ return $GLOBAL_INFERRED_OS;
+}
- if ($GLOBAL_ACTUAL_OS eq "None") {
- my $os = $GLOBAL_OS;
- # undef GLOBAL_OS so that the GetDistro routine will return
- # the actualDistro, it might otherwise return the distro set
- # by the --os switch.
- $GLOBAL_OS = "None";
- $GLOBAL_ACTUAL_OS = &GetDistro;
- # reset the GLOBAL_OS variable
- $GLOBAL_OS = $os;
+sub GetDistro {
+ if ($GLOBAL_OS eq "None") {
+ return &getInferredDistro;
}
- return $GLOBAL_ACTUAL_OS;
+ return $GLOBAL_OS;
}
+
# These are helper routines which used to be included inside GetDistro
sub is_OS_supported($) {
my $os=$_[0];
@@ -556,7 +545,8 @@
"SE7.2","SE7.3", "SE8.0","SE8.1","SE9.0","SE9.1",
"SE9.2","SE9.3","SE10.0","SE10.1","SE10.2","SE10.3",
"SESLES8","SESLES9","SESLES10",
- "TB7.0"
+ "TB7.0",
+ "Yocto"
],
"HP-UX" => [
@@ -882,23 +872,19 @@
###########################################################################
sub ConfigureForDistro {
- my $retval=1;
-
- # checking to see if the os version given is in fact supported
my $distro = &GetDistro;
- # checking to see if the actual os version is in fact supported
- my $actualDistro = &getActualDistro;
+ my $inferredDistro = &getInferredDistro;
+
+ if (! ($inferredDistro eq $distro) ) {
+ print STDERR "WARNING: Inferred distro $inferredDistro is not the same as specified distro $distro. Using specified distro.\n";
+ }
+
$ENV{'LOCALE'}=''; # So that test cases checking for english results work ok.
- if ((! &is_OS_supported($distro)) or (! &is_OS_supported($actualDistro)) ) {
- # if either is not supported then print out a list of supported versions
- if (! &is_OS_supported($distro)) {
- print STDERR "$err '$distro' is not a supported operating system.\n";
- }
- else {
- print STDERR "$err Bastille is unable to operate correctly on this\n";
- print STDERR "$spc $distro operating system.\n";
- }
+
+ if (! &is_OS_supported($distro)) {
+ print STDERR "$err '$distro' is not a supported operating system.\n";
+
my %supportedOSHash = &getSupportedOSHash;
print STDERR "$spc Valid operating system versions are as follows:\n";
@@ -930,7 +916,7 @@
# intend via setting the Perl umask
umask(077);
- &getFileAndServiceInfo($distro,$actualDistro);
+ &getFileAndServiceInfo($distro,$distro);
# &dumpFileInfo; # great for debuging file location issues
# &dumpServiceInfo; # great for debuging service information issues
@@ -942,7 +928,7 @@
"$spc You must use Bastille\'s -n flag (for example:\n" .
"$spc bastille -f -n) or \'touch $nodisclaim_file \'\n";
- return $retval;
+ return 1;
}
Index: Bastille/Bastille/LogAPI.pm
===================================================================
--- Bastille.orig/Bastille/LogAPI.pm 2013-08-22 04:32:38.269968002 -0400
+++ Bastille/Bastille/LogAPI.pm 2013-08-22 04:32:47.509968002 -0400
@@ -111,7 +111,7 @@
# do this here to prevent bootstrapping problem, where we need to
# write an error that the errorlog location isn't defined.
my $logdir="/var/log/Bastille";
- if(&getActualDistro =~ "^HP-UX"){
+ if(&getInferredDistro =~ "^HP-UX"){
$logdir = "/var/opt/sec_mgmt/bastille/log/";
}
@@ -0,0 +1,30 @@
Upstream-Status: Inappropriate [No upstream maintenance]
Signed-off-by: Anne Mulhern <mulhern@yoctoproject.org>
---
Index: Bastille/OSMap/LINUX.bastille
===================================================================
--- Bastille.orig/OSMap/LINUX.bastille 2008-01-25 18:31:35.000000000 -0500
+++ Bastille/OSMap/LINUX.bastille 2013-08-22 04:48:32.677968002 -0400
@@ -12,7 +12,6 @@
bfile,InteractiveBastille,'/usr/sbin/InteractiveBastille'
bfile,BastilleBackEnd,'/usr/sbin/BastilleBackEnd'
-bfile,Questions,'/usr/share/Bastille/Questions.txt'
bfile,QuestionsModules,'/usr/share/Bastille/Modules.txt'
bfile,TODO,'/var/log/Bastille/TODO'
bfile,TODOFlag,'/var/log/Bastille/TODOFlag.txt'
Index: Bastille/OSMap/OSX.bastille
===================================================================
--- Bastille.orig/OSMap/OSX.bastille 2007-09-11 18:09:26.000000000 -0400
+++ Bastille/OSMap/OSX.bastille 2013-08-22 04:48:47.245968001 -0400
@@ -10,7 +10,6 @@
bdir,share,'/usr/share/Bastille'
bfile,BastilleBackEnd,'/var/root/Bastille/BastilleBackEnd'
-bfile,Questions,'/usr/share/Bastille/Questions.txt'
bfile,QuestionsModules,'/usr/share/Bastille/Modules.txt'
bfile,TODO,'/var/log/Bastille/TODO'
bfile,TODOFlag,'/var/log/Bastille/TODOFlag.txt'
@@ -0,0 +1,157 @@
#!/usr/bin/env python3
#Signed-off-by: Anne Mulhern <mulhern@yoctoproject.org>
import argparse, os, shutil, sys, tempfile, traceback
from os import path
def get_config(lines):
"""
From a sequence of lines retrieve the question file name, question identifier
pairs.
"""
for l in lines:
if not l.startswith("#"):
try:
(coord, value) = l.split("=")
try:
(fname, ident) = coord.split(".")
yield fname, ident
except ValueError as e:
raise ValueError("Badly formatted coordinates %s in line %s." % (coord, l.strip()))
except ValueError as e:
raise ValueError("Skipping badly formatted line %s, %s" % (l.strip(), e))
def check_contains(line, name):
"""
Check if the value field for REQUIRE_DISTRO contains the given name.
@param name line The REQUIRE_DISTRO line
@param name name The name to look for in the value field of the line.
"""
try:
(label, distros) = line.split(":")
return name in distros.split()
except ValueError as e:
raise ValueError("Error splitting REQUIRE_DISTRO line: %s" % e)
def add_requires(the_ident, distro, lines):
"""
Yield a sequence of lines the same as lines except that where
the_ident matches a question identifier change the REQUIRE_DISTRO so that
it includes the specified distro.
@param name the_ident The question identifier to be matched.
@param name distro The distribution to added to the questions REQUIRE_DISTRO
field.
@param lines The sequence to be processed.
"""
for l in lines:
yield l
if l.startswith("LABEL:"):
try:
(label, ident) = l.split(":")
if ident.strip() == the_ident:
break
except ValueError as e:
raise ValueError("Unexpected line %s in questions file." % l.strip())
for l in lines:
if l.startswith("REQUIRE_DISTRO"):
if not check_contains(l, distro):
yield l.rstrip() + " " + distro + "\n"
else:
yield l
break;
else:
yield l
for l in lines:
yield l
def xform_file(qfile, distro, qlabel):
"""
Transform a Questions file.
@param name qfile The designated questions file.
@param name distro The distribution to add to the required distributions.
@param name qlabel The question label for which the distro is to be added.
"""
questions_in = open(qfile)
questions_out = tempfile.NamedTemporaryFile(mode="w+", delete=False)
for l in add_requires(qlabel, distro, questions_in):
questions_out.write(l)
questions_out.close()
questions_in.close()
shutil.copystat(qfile, questions_out.name)
os.remove(qfile)
shutil.move(questions_out.name, qfile)
def handle_args(parser):
parser.add_argument('config_file',
help = "Configuration file path.")
parser.add_argument('questions_dir',
help = "Directory containing Questions files.")
parser.add_argument('--distro', '-d',
help = "The distribution, the default is Yocto.",
default = "Yocto")
parser.add_argument('--debug', '-b',
help = "Print debug information.",
action = 'store_true')
return parser.parse_args()
def check_args(args):
args.config_file = os.path.abspath(args.config_file)
args.questions_dir = os.path.abspath(args.questions_dir)
if not os.path.isdir(args.questions_dir):
raise ValueError("Specified Questions directory %s does not exist or is not a directory." % args.questions_dir)
if not os.path.isfile(args.config_file):
raise ValueError("Specified configuration file %s not found." % args.config_file)
def main():
opts = handle_args(argparse.ArgumentParser(description="A simple script that sets required questions based on the question/answer pairs in a configuration file."))
try:
check_args(opts)
except ValueError as e:
if opts.debug:
traceback.print_exc()
else:
sys.exit("Fatal error:\n%s" % e)
try:
config_in = open(opts.config_file)
for qfile, qlabel in get_config(config_in):
questions_file = os.path.join(opts.questions_dir, qfile + ".txt")
xform_file(questions_file, opts.distro, qlabel)
config_in.close()
except IOError as e:
if opts.debug:
traceback.print_exc()
else:
sys.exit("Fatal error reading or writing file:\n%s" % e)
except ValueError as e:
if opts.debug:
traceback.print_exc()
else:
sys.exit("Fatal error:\n%s" % e)
if __name__ == "__main__":
main()
@@ -0,0 +1,40 @@
Upstream-Status: Inappropriate [No upstream maintenance]
Signed-off-by: Anne Mulhern <mulhern@yoctoproject.org>
---
Index: Bastille/Bastille/API.pm
===================================================================
--- Bastille.orig/Bastille/API.pm 2013-08-21 08:59:17.939950001 -0400
+++ Bastille/Bastille/API.pm 2013-08-21 08:59:30.983950001 -0400
@@ -1679,24 +1679,22 @@
use File::Copy;
- my $original_source=$source;
$source = &getGlobal('BDIR', "share") . $source;
- my $original_target=$target;
if ( -e $target and -f $target ) {
- &B_backup_file($original_target);
- &B_log("ACTION","About to copy $original_source to $original_target -- had to backup target\n");
+ &B_backup_file($target);
+ &B_log("ACTION","About to copy $source to $target -- had to backup target\n");
$had_to_backup_target=1;
}
$retval=copy($source,$target);
if ($retval) {
- &B_log("ACTION","placed file $original_source as $original_target\n");
+ &B_log("ACTION","placed file $source as $target\n");
#
# We want to add a line to the &getGlobal('BFILE', "created-files") so that the
# file we just put at $original_target gets deleted.
- &B_revert_log(&getGlobal('BIN',"rm") . " $original_target\n");
+ &B_revert_log(&getGlobal('BIN',"rm") . " $target\n");
} else {
- &B_log("ERROR","Failed to place $original_source as $original_target\n");
+ &B_log("ERROR","Failed to place $source as $target\n");
}
# We add the file to the GLOBAL_SUMS hash if it is not already present
@@ -0,0 +1,91 @@
Upstream-Status: Inappropriate [No upstream maintenance]
Signed-off-by: Anne Mulhern <mulhern@yoctoproject.org>
---
Index: Bastille/Bastille/API.pm
===================================================================
--- Bastille.orig/Bastille/API.pm 2013-08-21 11:41:09.235950000 -0400
+++ Bastille/Bastille/API.pm 2013-08-21 11:41:16.183950000 -0400
@@ -271,9 +271,15 @@
# setOptions takes six arguments, $GLOBAL_DEBUG, $GLOBAL_LOGONLY,
# $GLOBAL_VERBOSE, $GLOBAL_AUDITONLY, $GLOBAL_AUDIT_NO_BROWSER, and GLOBAL_OS;
###########################################################################
-sub setOptions($$$$$$) {
- ($GLOBAL_DEBUG,$GLOBAL_LOGONLY,$GLOBAL_VERBOSE,$GLOBAL_AUDITONLY,
- $GLOBAL_AUDIT_NO_BROWSER,$GLOBAL_OS) = @_;
+sub setOptions {
+ my %opts = @_;
+
+ $GLOBAL_DEBUG = $opts{debug};
+ $GLOBAL_LOGONLY = $opts{logonly};
+ $GLOBAL_VERBOSE = $opts{verbose};
+ $GLOBAL_AUDITONLY = $opts{auditonly};
+ $GLOBAL_AUDIT_NO_BROWSER = $opts{audit_no_browser};
+ $GLOBAL_OS = $opts{os};
if ($GLOBAL_AUDIT_NO_BROWSER) {
$GLOBAL_AUDITONLY = 1;
}
Index: Bastille/BastilleBackEnd
===================================================================
--- Bastille.orig/BastilleBackEnd 2013-08-21 11:41:09.235950000 -0400
+++ Bastille/BastilleBackEnd 2013-08-21 12:40:54.055950001 -0400
@@ -50,15 +50,13 @@
my $nodisclaim = 0;
my $verbose = 0;
my $force = 0;
-my $log_only = 0;
my $debug = 0;
my $alternate_config=undef;
if( Getopt::Long::GetOptions( "n" => \$nodisclaim,
"v" => \$verbose,
"force" => \$force,
-# "log" => \$log_only, # broken
- "f:s" => \$alternate_config,
+ "f=s" => \$alternate_config,
"debug" => \$debug) ) {
$error = 0; # no parse error
@@ -66,7 +64,9 @@
$error = 1; # parse error
}
-&setOptions($debug,$log_only,$verbose);
+&setOptions(
+ debug => $debug,
+ verbose => $verbose);
&ConfigureForDistro;
if ( $error ) { # GetOptions couldn't parse all of the args
Index: Bastille/InteractiveBastille
===================================================================
--- Bastille.orig/InteractiveBastille 2013-08-21 11:41:09.235950000 -0400
+++ Bastille/InteractiveBastille 2013-08-21 12:40:30.531950001 -0400
@@ -234,8 +234,8 @@
"a" => \$audit,
"force" => \$force,
"log" => \$log_only,
- "os:s" => \$os_version,
- "f:s" => \$alternate_config,
+ "os=s" => \$os_version,
+ "f=s" => \$alternate_config,
"debug" => \$debug) ) {
$error = 0; # no parse error
} else {
@@ -293,7 +293,13 @@
$UseRequiresRules = 'N';
}
-&setOptions($debug,$log_only,$verbose,$audit,$auditnobrowser,$os_version);
+&setOptions(
+ debug => $debug,
+ logonly => $log_only,
+ verbose => $verbose,
+ auditonly => $audit,
+ audit_no_browser => $auditnobrowser,
+ os => $os_version);
&ConfigureForDistro;
# ensuring mutually exclusive options are exclusive
@@ -0,0 +1,36 @@
From d1cb702d5147abea0d3208a4d554c61a6f2decd6 Mon Sep 17 00:00:00 2001
From: Scott Ellis <scott@jumpnowtek.com>
Date: Fri, 28 Dec 2018 11:08:25 -0500
Subject: [PATCH] Set custom paths
Upstream-Status: Inappropriate
Signed-off-by: Scott Ellis <scott@jumpnowtek.com>
---
nikto.conf | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/program/nikto.conf b/program/nikto.conf
index bf36c58..8c55415 100644
--- a/nikto.conf
+++ b/nikto.conf
@@ -61,11 +61,11 @@ CIRT=107.170.99.251
CHECKMETHODS=HEAD GET
# If you want to specify the location of any of the files, specify them here
-# EXECDIR=/opt/nikto # Location of Nikto
-# PLUGINDIR=/opt/nikto/plugins # Location of plugin dir
-# DBDIR=/opt/nikto/databases # Location of database dir
-# TEMPLATEDIR=/opt/nikto/templates # Location of template dir
-# DOCDIR=/opt/nikto/docs # Location of docs dir
+EXECDIR=/usr/bin/nikto # Location of Nikto
+PLUGINDIR=/etc/nikto/plugins # Location of plugin dir
+DBDIR=/etc/nikto/databases # Location of database dir
+TEMPLATEDIR=/etc/nikto/templates # Location of template dir
+DOCDIR=/usr/share/doc/nikto # Location of docs dir
# Default plugin macros
# Remove plugins designed to be run standalone
--
2.7.4
@@ -0,0 +1,118 @@
SUMMARY = "web server scanner"
DESCRIPTION = "Nikto is an Open Source web server scanner which performs comprehensive tests against web servers"
SECTION = "security"
HOMEPAGE = "https://cirt.net/Nikto2"
LICENSE = "GPL-2.0-only"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/GPL-2.0-only;md5=801f80980d171dd6425610833a22dbe6"
SRCREV = "f1bbd1a8756c076c8fd4f4dd0bc34a8ef215ae79"
SRC_URI = "git://github.com/sullo/nikto.git;branch=master;protocol=https \
file://location.patch"
S = "${WORKDIR}/git/program"
do_install() {
install -d ${D}${bindir}
install -d ${D}${datadir}
install -d ${D}${datadir}/man/man1
install -d ${D}${datadir}/doc/nikto
install -d ${D}${sysconfdir}/nikto
install -d ${D}${sysconfdir}/nikto/databases
install -d ${D}${sysconfdir}/nikto/plugins
install -d ${D}${sysconfdir}/nikto/templates
install -m 0644 databases/db_404_strings ${D}${sysconfdir}/nikto/databases
install -m 0644 databases/db_content_search ${D}${sysconfdir}/nikto/databases
install -m 0644 databases/db_dictionary ${D}${sysconfdir}/nikto/databases
install -m 0644 databases/db_dir_traversal ${D}${sysconfdir}/nikto/databases
install -m 0644 databases/db_domino ${D}${sysconfdir}/nikto/databases
install -m 0644 databases/db_drupal ${D}${sysconfdir}/nikto/databases
install -m 0644 databases/db_embedded ${D}${sysconfdir}/nikto/databases
install -m 0644 databases/db_favicon ${D}${sysconfdir}/nikto/databases
install -m 0644 databases/db_headers ${D}${sysconfdir}/nikto/databases
install -m 0644 databases/db_httpoptions ${D}${sysconfdir}/nikto/databases
install -m 0644 databases/db_multiple_index ${D}${sysconfdir}/nikto/databases
install -m 0644 databases/db_outdated ${D}${sysconfdir}/nikto/databases
install -m 0644 databases/db_parked_strings ${D}${sysconfdir}/nikto/databases
install -m 0644 databases/db_realms ${D}${sysconfdir}/nikto/databases
install -m 0644 databases/db_server_msgs ${D}${sysconfdir}/nikto/databases
install -m 0644 databases/db_tests ${D}${sysconfdir}/nikto/databases
install -m 0644 databases/db_variables ${D}${sysconfdir}/nikto/databases
install -m 0644 plugins/LW2.pm ${D}${sysconfdir}/nikto/plugins
install -m 0644 plugins/nikto_apache_expect_xss.plugin ${D}${sysconfdir}/nikto/plugins
install -m 0644 plugins/nikto_apacheusers.plugin ${D}${sysconfdir}/nikto/plugins
install -m 0644 plugins/nikto_auth.plugin ${D}${sysconfdir}/nikto/plugins
install -m 0644 plugins/nikto_cgi.plugin ${D}${sysconfdir}/nikto/plugins
install -m 0644 plugins/nikto_clientaccesspolicy.plugin ${D}${sysconfdir}/nikto/plugins
install -m 0644 plugins/nikto_content_search.plugin ${D}${sysconfdir}/nikto/plugins
install -m 0644 plugins/nikto_cookies.plugin ${D}${sysconfdir}/nikto/plugins
install -m 0644 plugins/nikto_core.plugin ${D}${sysconfdir}/nikto/plugins
install -m 0644 plugins/nikto_dictionary_attack.plugin ${D}${sysconfdir}/nikto/plugins
install -m 0644 plugins/nikto_dir_traversal.plugin ${D}${sysconfdir}/nikto/plugins
install -m 0644 plugins/nikto_dishwasher.plugin ${D}${sysconfdir}/nikto/plugins
install -m 0644 plugins/nikto_docker_registry.plugin ${D}${sysconfdir}/nikto/plugins
install -m 0644 plugins/nikto_domino.plugin ${D}${sysconfdir}/nikto/plugins
install -m 0644 plugins/nikto_drupal.plugin ${D}${sysconfdir}/nikto/plugins
install -m 0644 plugins/nikto_embedded.plugin ${D}${sysconfdir}/nikto/plugins
install -m 0644 plugins/nikto_favicon.plugin ${D}${sysconfdir}/nikto/plugins
install -m 0644 plugins/nikto_fileops.plugin ${D}${sysconfdir}/nikto/plugins
install -m 0644 plugins/nikto_headers.plugin ${D}${sysconfdir}/nikto/plugins
install -m 0644 plugins/nikto_httpoptions.plugin ${D}${sysconfdir}/nikto/plugins
install -m 0644 plugins/nikto_ms10_070.plugin ${D}${sysconfdir}/nikto/plugins
install -m 0644 plugins/nikto_msgs.plugin ${D}${sysconfdir}/nikto/plugins
install -m 0644 plugins/nikto_multiple_index.plugin ${D}${sysconfdir}/nikto/plugins
install -m 0644 plugins/nikto_negotiate.plugin ${D}${sysconfdir}/nikto/plugins
install -m 0644 plugins/nikto_origin_reflection.plugin ${D}${sysconfdir}/nikto/plugins
install -m 0644 plugins/nikto_outdated.plugin ${D}${sysconfdir}/nikto/plugins
install -m 0644 plugins/nikto_parked.plugin ${D}${sysconfdir}/nikto/plugins
install -m 0644 plugins/nikto_paths.plugin ${D}${sysconfdir}/nikto/plugins
install -m 0644 plugins/nikto_put_del_test.plugin ${D}${sysconfdir}/nikto/plugins
install -m 0644 plugins/nikto_report_csv.plugin ${D}${sysconfdir}/nikto/plugins
install -m 0644 plugins/nikto_report_html.plugin ${D}${sysconfdir}/nikto/plugins
install -m 0644 plugins/nikto_report_json.plugin ${D}${sysconfdir}/nikto/plugins
install -m 0644 plugins/nikto_report_nbe.plugin ${D}${sysconfdir}/nikto/plugins
install -m 0644 plugins/nikto_report_sqlg.plugin ${D}${sysconfdir}/nikto/plugins
install -m 0644 plugins/nikto_report_text.plugin ${D}${sysconfdir}/nikto/plugins
install -m 0644 plugins/nikto_report_xml.plugin ${D}${sysconfdir}/nikto/plugins
install -m 0644 plugins/nikto_robots.plugin ${D}${sysconfdir}/nikto/plugins
install -m 0644 plugins/nikto_siebel.plugin ${D}${sysconfdir}/nikto/plugins
install -m 0644 plugins/nikto_sitefiles.plugin ${D}${sysconfdir}/nikto/plugins
install -m 0644 plugins/nikto_ssl.plugin ${D}${sysconfdir}/nikto/plugins
install -m 0644 plugins/nikto_strutshock.plugin ${D}${sysconfdir}/nikto/plugins
install -m 0644 plugins/nikto_tests.plugin ${D}${sysconfdir}/nikto/plugins
install -m 0644 templates/htm_close.tmpl ${D}${sysconfdir}/nikto/templates
install -m 0644 templates/htm_end.tmpl ${D}${sysconfdir}/nikto/templates
install -m 0644 templates/htm_host_head.tmpl ${D}${sysconfdir}/nikto/templates
install -m 0644 templates/htm_host_im.tmpl ${D}${sysconfdir}/nikto/templates
install -m 0644 templates/htm_host_item.tmpl ${D}${sysconfdir}/nikto/templates
install -m 0644 templates/htm_start.tmpl ${D}${sysconfdir}/nikto/templates
install -m 0644 templates/htm_stop.tmpl ${D}${sysconfdir}/nikto/templates
install -m 0644 templates/htm_start.tmpl ${D}${sysconfdir}/nikto/templates
install -m 0644 templates/htm_summary.tmpl ${D}${sysconfdir}/nikto/templates
install -m 0644 templates/xml_end.tmpl ${D}${sysconfdir}/nikto/templates
install -m 0644 templates/xml_host_head.tmpl ${D}${sysconfdir}/nikto/templates
install -m 0644 templates/xml_host_im.tmpl ${D}${sysconfdir}/nikto/templates
install -m 0644 templates/xml_host_item.tmpl ${D}${sysconfdir}/nikto/templates
install -m 0644 templates/xml_start.tmpl ${D}${sysconfdir}/nikto/templates
install -m 0644 templates/xml_summary.tmpl ${D}${sysconfdir}/nikto/templates
install -m 0644 nikto.conf ${D}${sysconfdir}
install -m 0755 nikto.pl ${D}${bindir}/nikto
install -m 0644 replay.pl ${D}${bindir}
install -m 0644 docs/nikto.1 ${D}${datadir}/man/man1
install -m 0644 docs/CHANGES.txt ${D}${datadir}/doc/nikto
install -m 0644 docs/LICENSE.txt ${D}${datadir}/doc/nikto
install -m 0644 docs/nikto.dtd ${D}${datadir}/doc/nikto
install -m 0644 docs/nikto_manual.html ${D}${datadir}/doc/nikto
}
RDEPENDS:${PN} = "perl libnet-ssleay-perl libwhisker2-perl \
perl-module-getopt-long perl-module-time-local \
perl-module-io-socket perl-module-overloading \
perl-module-base perl-module-b perl-module-bytes"
@@ -0,0 +1,10 @@
RDEPENDS:packagegroup-security-utils += "\
python3-privacyidea \
python3-fail2ban \
"
RDEPENDS:packagegroup-meta-security-ptest-packages += "\
python3-fail2ban-ptest \
"
@@ -0,0 +1,98 @@
#!/bin/sh
### BEGIN INIT INFO
# Provides: fail2ban
# Required-Start: $local_fs $remote_fs
# Required-Stop: $local_fs $remote_fs
# Should-Start: $time $network $syslog iptables firehol shorewall ferm
# Should-Stop: $network $syslog iptables firehol shorewall ferm
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start/Stop fail2ban
# Description: Start/Stop fail2ban, a daemon to ban hosts that cause multiple authentication errors
### END INIT INFO
# Source function library.
. /etc/init.d/functions
# Check that the config file exists
[ -f /etc/fail2ban/fail2ban.conf ] || exit 0
check_privsep_dir() {
# Create the PrivSep empty dir if necessary
if [ ! -d /var/run/fail2ban ]; then
mkdir /var/run/fail2ban
chmod 0755 /var/run/fail2ban
fi
}
FAIL2BAN="/usr/bin/fail2ban-client"
prog=fail2ban-server
lockfile=${LOCKFILE-/var/lock/subsys/fail2ban}
socket=${SOCKET-/var/run/fail2ban/fail2ban.sock}
pidfile=${PIDFILE-/var/run/fail2ban/fail2ban.pid}
RETVAL=0
start() {
echo -n $"Starting fail2ban: "
check_privsep_dir
${FAIL2BAN} -x start > /dev/null
RETVAL=$?
if [ $RETVAL = 0 ]; then
touch ${lockfile}
success
else
failure
fi
echo
return $RETVAL
}
stop() {
echo -n $"Stopping fail2ban: "
${FAIL2BAN} stop > /dev/null
RETVAL=$?
if [ $RETVAL = 0 ]; then
rm -f ${lockfile} ${pidfile}
success
else
failure
fi
echo
return $RETVAL
}
reload() {
echo "Reloading fail2ban: "
${FAIL2BAN} reload
RETVAL=$?
echo
return $RETVAL
}
# See how we were called.
case "$1" in
start)
status -p ${pidfile} ${prog} >/dev/null 2>&1 && exit 0
start
;;
stop)
stop
;;
reload)
reload
;;
restart)
stop
start
;;
status)
status -p ${pidfile} ${prog}
RETVAL=$?
[ $RETVAL = 0 ] && ${FAIL2BAN} status
;;
*)
echo $"Usage: fail2ban {start|stop|restart|reload|status}"
RETVAL=2
esac
exit $RETVAL
@@ -0,0 +1,3 @@
#!/bin/sh
##PYTHON## bin/fail2ban-testcases
@@ -0,0 +1,62 @@
SUMMARY = "Daemon to ban hosts that cause multiple authentication errors."
DESCRIPTION = "Fail2Ban scans log files like /var/log/auth.log and bans IP addresses having too \
many failed login attempts. It does this by updating system firewall rules to reject new \
connections from those IP addresses, for a configurable amount of time. Fail2Ban comes \
out-of-the-box ready to read many standard log files, such as those for sshd and Apache, \
and is easy to configure to read any log file you choose, for any error you choose."
HOMEPAGE = "http://www.fail2ban.org"
LICENSE = "GPL-2.0-only"
LIC_FILES_CHKSUM = "file://COPYING;md5=ecabc31e90311da843753ba772885d9f"
DEPENDS = "python3-native"
SRCREV = "e1d3006b0330e9777705a7baafe3989d442ed120"
SRC_URI = "git://github.com/fail2ban/fail2ban.git;branch=master;protocol=https \
file://initd \
file://run-ptest \
"
UPSTREAM_CHECK_GITTAGREGEX = "(?P<pver>\d+(\.\d+)+)"
inherit update-rc.d ptest setuptools3_legacy
S = "${WORKDIR}/git"
do_compile () {
cd ${S}
#remove symlink to python3
# otherwise 2to3 is run against it
rm -f bin/fail2ban-python
./fail2ban-2to3
}
do_install:append () {
rm -f ${D}/${bindir}/fail2ban-python
install -d ${D}/${sysconfdir}/fail2ban
install -d ${D}/${sysconfdir}/init.d
install -m 0755 ${WORKDIR}/initd ${D}${sysconfdir}/init.d/fail2ban-server
chown -R root:root ${D}/${bindir}
rm -rf ${D}/run
}
do_install_ptest:append () {
install -d ${D}${PTEST_PATH}
install -d ${D}${PTEST_PATH}/bin
sed -i -e 's/##PYTHON##/${PYTHON_PN}/g' ${D}${PTEST_PATH}/run-ptest
install -D ${S}/bin/* ${D}${PTEST_PATH}/bin
rm -f ${D}${PTEST_PATH}/bin/fail2ban-python
}
INITSCRIPT_PACKAGES = "${PN}"
INITSCRIPT_NAME = "fail2ban-server"
INITSCRIPT_PARAMS = "defaults 25"
INSANE_SKIP:${PN}:append = "already-stripped"
RDEPENDS:${PN} = "${VIRTUAL-RUNTIME_base-utils-syslog} iptables sqlite3 python3-core python3-pyinotify"
RDEPENDS:${PN} += " python3-logging python3-fcntl python3-json"
RDEPENDS:${PN}-ptest = "python3-core python3-io python3-modules python3-fail2ban"
@@ -0,0 +1,38 @@
SUMMARY = "identity, multifactor authentication (OTP), authorization, audit"
DESCRIPTION = "privacyIDEA is an open solution for strong two-factor authentication like OTP tokens, SMS, smartphones or SSH keys. Using privacyIDEA you can enhance your existing applications like local login (PAM, Windows Credential Provider), VPN, remote access, SSH connections, access to web sites or web portals with a second factor during authentication. Thus boosting the security of your existing applications."
HOMEPAGE = "http://www.privacyidea.org/"
LICENSE = "AGPL-3.0-only"
LIC_FILES_CHKSUM = "file://LICENSE;md5=c0acfa7a8a03b718abee9135bc1a1c55"
PYPI_PACKAGE = "privacyIDEA"
SRC_URI[sha256sum] = "e0dae763575c6300ccaebe6dcc8d3f119cb3e25c11302b1e78a96a12e8ab2b38"
inherit pypi setuptools3
do_install:append () {
rm -fr ${D}${libdir}/${PYTHON_DIR}/site-packages/tests
}
USERADD_PACKAGES = "${PN}"
GROUPADD_PARAM:${PN} = "--system privacyidea"
USERADD_PARAM:${PN} = "--system -g privacyidea -o -r -d /opt/${BPN} \
--shell /bin/false privacyidea"
FILES:${PN} += " ${prefix}/etc/privacyidea/* ${prefix}/lib/privacyidea/*"
RDEPENDS:${PN} += " bash perl freeradius-mysql freeradius-utils"
RDEPENDS:${PN} += "python3 python3-alembic python3-babel python3-bcrypt"
RDEPENDS:${PN} += "python3-beautifulsoup4 python3-cbor2 python3-certifi python3-cffi python3-chardet"
RDEPENDS:${PN} += "python3-click python3-configobj python3-croniter python3-cryptography python3-defusedxml"
RDEPENDS:${PN} += "python3-ecdsa python3-flask python3-flask-babel python3-flask-migrate"
RDEPENDS:${PN} += "python3-flask-script python3-flask-sqlalchemy python3-flask-versioned"
RDEPENDS:${PN} += "python3-future python3-httplib2 python3-huey python3-idna python3-ipaddress"
RDEPENDS:${PN} += "python3-itsdangerous python3-jinja2 python3-ldap python3-lxml python3-mako"
RDEPENDS:${PN} += "python3-markupsafe python3-netaddr python3-oauth2client python3-passlib python3-pillow"
RDEPENDS:${PN} += "python3-pyasn1 python3-pyasn1-modules python3-pycparser python3-pyjwt python3-pymysql"
RDEPENDS:${PN} += "python3-pyopenssl python3-pyrad python3-dateutil python3-editor python3-gnupg"
RDEPENDS:${PN} += "python3-pytz python3-pyyaml python3-qrcode python3-redis python3-requests python3-rsa"
RDEPENDS:${PN} += "python3-six python3-smpplib python3-soupsieve python3-soupsieve "
RDEPENDS:${PN} += "python3-sqlalchemy python3-sqlsoup python3-urllib3 python3-werkzeug"
@@ -0,0 +1,11 @@
SUMMARY = "Add version info to file paths."
SECTION = "devel/python"
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://LICENSE;md5=038e1390e94fe637991fa5569daa62bc"
PYPI_PACKAGE = "oauth2client"
SRC_URI[sha256sum] = "d486741e451287f69568a4d26d70d9acd73a2bbfa275746c535b4209891cccc6"
inherit pypi setuptools3
RDEPENDS:${PN} = "python3-six python3-rsa python3-httplib2 python3-pyasn1 python3-pyasn1-modules"
@@ -0,0 +1,4 @@
RDEPENDS:packagegroup-security-utils += "\
${@bb.utils.contains("DISTRO_FEATURES", "pam", "sssd", "",d)} \
"
@@ -0,0 +1,28 @@
nsupdate path is needed for various exec call
but don't run natvie tests on it.
Upstream-Status: Inappropriate [OE specific]
Signed-off-by: Armin Kuster <akuster808@gmail.com>
Index: sssd-2.5.0/src/external/nsupdate.m4
===================================================================
--- sssd-2.5.0.orig/src/external/nsupdate.m4
+++ sssd-2.5.0/src/external/nsupdate.m4
@@ -3,16 +3,4 @@ AC_MSG_CHECKING(for executable nsupdate)
if test -x "$NSUPDATE"; then
AC_DEFINE_UNQUOTED([NSUPDATE_PATH], ["$NSUPDATE"], [The path to nsupdate])
AC_MSG_RESULT(yes)
-
- AC_MSG_CHECKING(for nsupdate 'realm' support')
- if AC_RUN_LOG([echo realm |$NSUPDATE >&2]); then
- AC_MSG_RESULT([yes])
- else
- AC_MSG_RESULT([no])
- AC_MSG_ERROR([nsupdate does not support 'realm'])
- fi
-
-else
- AC_MSG_RESULT([no])
- AC_MSG_ERROR([nsupdate is not available])
fi
@@ -0,0 +1,25 @@
When calculate value of ldblibdir, it checks whether the directory of
$ldblibdir exists. If not, it assigns ldblibdir with ${libdir}/ldb. It is not
suitable for cross compile. Fix it that only re-assign ldblibdir when its value
is empty.
Upstream-Status: Inappropriate [cross compile specific]
Signed-off-by: Kai Kang <kai.kang@windriver.com>
---
src/external/libldb.m4 | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/external/libldb.m4 b/src/external/libldb.m4
index c400add..5e5f06d 100644
--- a/src/external/libldb.m4
+++ b/src/external/libldb.m4
@@ -19,7 +19,7 @@ if test x"$with_ldb_lib_dir" != x; then
ldblibdir=$with_ldb_lib_dir
else
ldblibdir="`$PKG_CONFIG --variable=modulesdir ldb`"
- if ! test -d $ldblibdir; then
+ if test -z $ldblibdir; then
ldblibdir="${libdir}/ldb"
fi
fi
@@ -0,0 +1,27 @@
from ../sssd-2.5.0/src/util/sss_pam_data.c:27:
| ../sssd-2.5.0/src/util/debug.h:88:44: error: unknown type name 'uid_t'; did you mean 'uint_t'?
| 88 | int chown_debug_file(const char *filename, uid_t uid, gid_t gid);
| | ^~~~~
| | uint_t
| ../sssd-2.5.0/src/util/debug.h:88:55: error: unknown type name 'gid_t'
| 88 | int chown_debug_file(const char *filename, uid_t uid, gid_t gid);
| | ^~~~~
| make[2]: *** [Makefile:22529: src/util/libsss_iface_la-sss_pam_data.lo] Error 1
| make[2]: *** Waiting for unfinished jobs....
Upstream-Status: Pending
Signed-off-by: Armin Kuster <akuster808@gmail.com>
Index: sssd-2.7.1/src/util/debug.h
===================================================================
--- sssd-2.7.1.orig/src/util/debug.h
+++ sssd-2.7.1/src/util/debug.h
@@ -24,6 +24,8 @@
#include "config.h"
#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
#include <stdbool.h>
#include <sys/types.h>
@@ -0,0 +1,53 @@
fix musl build failures
Missing _PATH_HOSTS and some NETDB defines when musl is enabled.
These are work arounds for now while we figure out where the real fix should reside (musl, gcompact, sssd):
./sssd-2.5.1/src/providers/fail_over.c:1199:19: error: '_PATH_HOSTS' undeclared (first use in this function)
| 1199 | _PATH_HOSTS);
| | ^~~~~~~~~~~
and
i./sssd-2.5.1/src/sss_client/nss_ipnetworks.c:415:21: error: 'NETDB_INTERNAL' undeclared (first use in this function)
| 415 | *h_errnop = NETDB_INTERNAL;
Upstream-Status: Pending
Signed-off-by: Armin Kuster <akuster808@gmail.com>
Index: sssd-2.5.1/src/providers/fail_over.c
===================================================================
--- sssd-2.5.1.orig/src/providers/fail_over.c
+++ sssd-2.5.1/src/providers/fail_over.c
@@ -31,6 +31,10 @@
#include <talloc.h>
#include <netdb.h>
+#if !defined(_PATH_HOSTS)
+#define _PATH_HOSTS "/etc/hosts"
+#endif
+
#include "util/dlinklist.h"
#include "util/refcount.h"
#include "util/util.h"
Index: sssd-2.5.1/src/sss_client/sss_cli.h
===================================================================
--- sssd-2.5.1.orig/src/sss_client/sss_cli.h
+++ sssd-2.5.1/src/sss_client/sss_cli.h
@@ -44,6 +44,14 @@ typedef int errno_t;
#define EOK 0
#endif
+#ifndef NETDB_INTERNAL
+# define NETDB_INTERNAL (-1)
+#endif
+
+#ifndef NETDB_SUCCESS
+# define NETDB_SUCCESS (0)
+#endif
+
#define SSS_NSS_PROTOCOL_VERSION 1
#define SSS_PAM_PROTOCOL_VERSION 3
#define SSS_SUDO_PROTOCOL_VERSION 1
@@ -0,0 +1,19 @@
don't run generate-sbus-code
Upstream-Status: Inappropriate [OE Specific]
Signed-off-by: Armin Kuster <akuster808@gmail.com>
Index: sssd-2.7.1/Makefile.am
===================================================================
--- sssd-2.7.1.orig/Makefile.am
+++ sssd-2.7.1/Makefile.am
@@ -1023,8 +1023,6 @@ generate-sbus-code:
.PHONY: generate-sbus-code
-BUILT_SOURCES += generate-sbus-code
-
EXTRA_DIST += \
sbus_generate.sh.in \
src/sbus/codegen/dbus.xml \
@@ -0,0 +1,15 @@
[sssd]
services = nss, pam
domains = shadowutils
[nss]
[pam]
[domain/shadowutils]
id_provider = files
auth_provider = proxy
proxy_pam_target = sssd-shadowutils
proxy_fast_alias = True
@@ -0,0 +1 @@
d root root 0750 /var/log/sssd none
@@ -0,0 +1,157 @@
SUMMARY = "system security services daemon"
DESCRIPTION = "SSSD is a system security services daemon"
HOMEPAGE = "https://pagure.io/SSSD/sssd/"
SECTION = "base"
LICENSE = "GPL-3.0-or-later"
LIC_FILES_CHKSUM = "file://COPYING;md5=d32239bcb673463ab874e80d47fae504"
DEPENDS = "acl attr cyrus-sasl libtdb ding-libs libpam c-ares krb5 autoconf-archive"
DEPENDS:append = " libldb dbus libtalloc libpcre2 glib-2.0 popt e2fsprogs libtevent"
DEPENDS:append = " openldap bind p11-kit jansson softhsm openssl libunistring"
DEPENDS:append:libc-musl = " musl-nscd"
# If no crypto has been selected, default to DEPEND on nss, since that's what
# sssd will pick if no active choice is made during configure
DEPENDS += "${@bb.utils.contains('PACKAGECONFIG', 'nss', '', \
bb.utils.contains('PACKAGECONFIG', 'crypto', '', 'nss', d), d)}"
SRC_URI = "https://github.com/SSSD/sssd/releases/download/${PV}/sssd-${PV}.tar.gz \
file://sssd.conf \
file://volatiles.99_sssd \
file://no_gen.patch \
file://fix_gid.patch \
file://drop_ntpdate_chk.patch \
file://fix-ldblibdir.patch \
file://musl_fixup.patch \
"
SRC_URI[sha256sum] = "10ef90c63fdbfda905145077679035bd5ad16b24daad13160de8d0ff82ea9950"
UPSTREAM_CHECK_URI = "https://github.com/SSSD/${BPN}/releases"
inherit autotools pkgconfig gettext python3-dir features_check systemd
REQUIRED_DISTRO_FEATURES = "pam"
SSSD_UID ?= "root"
SSSD_GID ?= "root"
CACHED_CONFIGUREVARS = "ac_cv_member_struct_ldap_conncb_lc_arg=no \
ac_cv_prog_HAVE_PYTHON3=${PYTHON_DIR} \
"
PACKAGECONFIG ?="nss autofs sudo infopipe"
PACKAGECONFIG += "${@bb.utils.contains('DISTRO_FEATURES', 'selinux', 'selinux', '', d)}"
PACKAGECONFIG += "${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'systemd', '', d)}"
PACKAGECONFIG[autofs] = "--with-autofs, --with-autofs=no"
PACKAGECONFIG[crypto] = ", , libcrypto"
PACKAGECONFIG[curl] = "--with-kcm, --without-kcm, curl jansson"
PACKAGECONFIG[infopipe] = "--with-infopipe, --with-infopipe=no, "
PACKAGECONFIG[manpages] = "--with-manpages, --with-manpages=no, libxslt-native docbook-xml-dtd4-native docbook-xsl-stylesheets-native"
PACKAGECONFIG[nl] = "--with-libnl, --with-libnl=no, libnl"
PACKAGECONFIG[nss] = ", ,nss,"
PACKAGECONFIG[oidc_child] = "--with-oidc-child, --without-oidc-child"
PACKAGECONFIG[python3] = "--with-python3-bindings, --without-python3-bindings"
PACKAGECONFIG[samba] = "--with-samba, --with-samba=no, samba"
PACKAGECONFIG[selinux] = "--with-selinux, --with-selinux=no --with-semanage=no, libselinux"
PACKAGECONFIG[ssh] = "--with-ssh, --with-ssh=no, "
PACKAGECONFIG[sudo] = "--with-sudo, --with-sudo=no, "
PACKAGECONFIG[systemd] = "--with-initscript=systemd,--with-initscript=sysv"
EXTRA_OECONF += " \
--disable-cifs-idmap-plugin \
--without-nfsv4-idmapd-plugin \
--without-ipa-getkeytab \
--without-python2-bindings \
--enable-pammoddir=${base_libdir}/security \
--without-python2-bindings \
--with-xml-catalog-path=${STAGING_ETCDIR_NATIVE}/xml/catalog \
--with-pid-path=/run \
"
do_configure:prepend() {
mkdir -p ${AUTOTOOLS_AUXDIR}/build
cp ${STAGING_DATADIR_NATIVE}/gettext/config.rpath ${AUTOTOOLS_AUXDIR}/build/
# additional_libdir defaults to /usr/lib so replace with staging_libdir globally
sed -i -e "s#\$additional_libdir#\${STAGING_LIBDIR}#" ${S}/src/build_macros.m4
}
do_compile:prepend () {
echo '#define NSUPDATE_PATH "${bindir}"' >> ${B}/config.h
}
do_install () {
oe_runmake install DESTDIR="${D}"
rmdir --ignore-fail-on-non-empty "${D}/${bindir}"
install -d ${D}/${sysconfdir}/${BPN}
install -d ${D}/${PYTHON_SITEPACKAGES_DIR}
mv ${D}/${BPN} ${D}/${PYTHON_SITEPACKAGES_DIR}
install -m 600 ${WORKDIR}/${BPN}.conf ${D}/${sysconfdir}/${BPN}
# /var/log/sssd needs to be created in runtime. Use rmdir to catch if
# upstream stops creating /var/log/sssd, or adds something else in
# /var/log.
rmdir ${D}${localstatedir}/log/${BPN} ${D}${localstatedir}/log
rmdir --ignore-fail-on-non-empty ${D}${localstatedir}
if ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'true', 'false', d)}; then
install -d ${D}${sysconfdir}/tmpfiles.d
echo "d /var/log/sssd 0750 - - - -" > ${D}${sysconfdir}/tmpfiles.d/sss.conf
fi
if [ "${@bb.utils.filter('DISTRO_FEATURES', 'sysvinit', d)}" ]; then
install -d ${D}${sysconfdir}/default/volatiles
echo "d ${SSSD_UID}:${SSSD_GID} 0755 ${localstatedir}/log/${BPN} none" > ${D}${sysconfdir}/default/volatiles/99_${BPN}
fi
# Remove /run as it is created on startup
rm -rf ${D}/run
# rm -fr ${D}/sssd
rm -f ${D}${systemd_system_unitdir}/sssd-secrets.*
}
pkg_postinst_ontarget:${PN} () {
if [ -e /etc/init.d/populate-volatile.sh ] ; then
${sysconfdir}/init.d/populate-volatile.sh update
fi
chown ${SSSD_UID}:${SSSD_GID} ${sysconfdir}/${BPN}/${BPN}.conf
}
CONFFILES:${PN} = "${sysconfdir}/${BPN}/${BPN}.conf"
INITSCRIPT_NAME = "sssd"
INITSCRIPT_PARAMS = "start 02 5 3 2 . stop 20 0 1 6 ."
SYSTEMD_SERVICE:${PN} = " \
${@bb.utils.contains('PACKAGECONFIG', 'autofs', 'sssd-autofs.service sssd-autofs.socket', '', d)} \
${@bb.utils.contains('PACKAGECONFIG', 'curl', 'sssd-kcm.service sssd-kcm.socket', '', d)} \
${@bb.utils.contains('PACKAGECONFIG', 'infopipe', 'sssd-ifp.service ', '', d)} \
${@bb.utils.contains('PACKAGECONFIG', 'ssh', 'sssd-ssh.service sssd-ssh.socket', '', d)} \
${@bb.utils.contains('PACKAGECONFIG', 'sudo', 'sssd-sudo.service sssd-sudo.socket', '', d)} \
sssd-nss.service \
sssd-nss.socket \
sssd-pam-priv.socket \
sssd-pam.service \
sssd-pam.socket \
sssd.service \
"
SYSTEMD_AUTO_ENABLE = "disable"
PACKAGES =+ "libsss-sudo"
ALLOW_EMPTY:libsss-sudo = "1"
FILES:${PN} += "${base_libdir}/security/pam_sss*.so \
${nonarch_libdir}/tmpfiles.d \
${datadir}/dbus-1/system-services/*.service \
${libdir}/krb5/* \
${libdir}/ldb/* \
${PYTHON_SITEPACKAGES_DIR}/sssd \
"
FILES:libsss-sudo = "${libdir}/libsss_sudo.so"
RDEPENDS:${PN} = "bind bind-utils dbus libldb libpam libsss-sudo"
+8
View File
@@ -0,0 +1,8 @@
header:
version: 9
includes:
- kas-security-base.yml
local_conf_header:
alt: |
DISTRO_FEATURES:append = " systemd"
+67
View File
@@ -0,0 +1,67 @@
header:
version: 9
distro: poky
repos:
meta-security:
layers:
../meta-security:
meta-tpm:
meta-integrity:
meta-hardening:
poky:
url: https://git.yoctoproject.org/git/poky
refspec: master
layers:
meta:
meta-poky:
meta-yocto-bsp:
meta-openembedded:
url: http://git.openembedded.org/meta-openembedded
refspec: master
layers:
meta-oe:
meta-perl:
meta-python:
meta-networking:
meta-filesystems:
local_conf_header:
base: |
CONF_VERSION = "2"
SOURCE_MIRROR_URL = "http://downloads.yoctoproject.org/mirror/sources/"
INHERIT += "buildstats buildstats-summary buildhistory"
INHERIT += "report-error"
IMAGE_CLASSES += "testimage"
BB_NUMBER_THREADS="24"
BB_NUMBER_PARSE_THREADS="12"
BB_TASK_NICE_LEVEL = '5'
BB_TASK_NICE_LEVEL_task-testimage = '0'
BB_TASK_IONICE_LEVEL = '2.7'
BB_TASK_IONICE_LEVEL_task-testimage = '2.1'
TEST_QEMUBOOT_TIMEOUT = "1500"
EXTRA_IMAGE_FEATURES ?= "debug-tweaks"
PACKAGE_CLASSES = "package_ipk"
DISTRO_FEATURES:append = " security pam apparmor smack ima tpm tpm2"
MACHINE_FEATURES:append = " tpm tpm2"
diskmon: |
BB_DISKMON_DIRS = "\
STOPTASKS,${TMPDIR},1G,100K \
STOPTASKS,${DL_DIR},1G,100K \
STOPTASKS,${SSTATE_DIR},1G,100K \
STOPTASKS,/tmp,100M,100K \
HALT,${TMPDIR},100M,1K \
HALT,${DL_DIR},100M,1K \
HALT,${SSTATE_DIR},100M,1K \
HALT,/tmp,10M,1K"
bblayers_conf_header:
base: |
BBPATH = "${TOPDIR}"
BBFILES ?= ""
+14
View File
@@ -0,0 +1,14 @@
header:
version: 9
includes:
- kas-security-base.yml
local_conf_header:
dm-verify: |
DISTRO_FEATURES:append = " integrity"
DM_VERITY_IMAGE = "core-image-minimal"
DM_VERITY_IMAGE_TYPE = "ext4"
IMAGE_CLASSES += "dm-verity-img"
INITRAMFS_IMAGE_BUNDLE = "1"
INITRAMFS_IMAGE = "dm-verity-image-initramfs"
+17
View File
@@ -0,0 +1,17 @@
header:
version: 9
includes:
- kas-security-base.yml
repos:
meta-security:
layers:
meta-parsec:
meta-clang:
url: https://github.com/kraj/meta-clang.git
refspec: master
local_conf_header:
meta-parsec: |
IMAGE_INSTALL:append = " parsec-service parsec-tool"
+6
View File
@@ -0,0 +1,6 @@
header:
version: 8
includes:
- kas-security-parsec.yml
machine: qemuarm
+6
View File
@@ -0,0 +1,6 @@
header:
version: 8
includes:
- kas-security-base.yml
machine: qemuarm
+6
View File
@@ -0,0 +1,6 @@
header:
version: 8
includes:
- kas-security-alt.yml
machine: qemuarm64
+10
View File
@@ -0,0 +1,10 @@
header:
version: 8
includes:
- kas-security-base.yml
local_conf_header:
musl: |
TCLIBC = "musl"
machine: qemuarm64
+6
View File
@@ -0,0 +1,6 @@
header:
version: 8
includes:
- kas-security-parsec.yml
machine: qemuarm64
+6
View File
@@ -0,0 +1,6 @@
header:
version: 8
includes:
- kas-security-base.yml
machine: qemuarm64
+6
View File
@@ -0,0 +1,6 @@
header:
version: 8
includes:
- kas-security-alt.yml
machine: qemumips64
+14
View File
@@ -0,0 +1,14 @@
header:
version: 8
includes:
- kas-security-base.yml
local_conf_header:
multi: |
require conf/multilib.conf
MULTILIBS = "multilib:lib64 multilib:lib32"
DEFAULTTUNE = "mips64-n32"
DEFAULTTUNE:virtclass-multilib-lib64 = "mips64"
DEFAULTTUNE:virtclass-multilib-lib32 = "mips32r2"
machine: qemumips64
+6
View File
@@ -0,0 +1,6 @@
header:
version: 8
includes:
- kas-security-base.yml
machine: qemumips64
+6
View File
@@ -0,0 +1,6 @@
header:
version: 8
includes:
- kas-security-base.yml
machine: qemuriscv64
+6
View File
@@ -0,0 +1,6 @@
header:
version: 8
includes:
- kas-security-alt.yml
machine: qemux86-64
@@ -0,0 +1,6 @@
header:
version: 8
includes:
- kas-security-dm.yml
machine: qemux86-64
+6
View File
@@ -0,0 +1,6 @@
header:
version: 8
includes:
- kas-security-parsec.yml
machine: qemux86-64
+6
View File
@@ -0,0 +1,6 @@
header:
version: 8
includes:
- kas-security-base.yml
machine: qemux86-64
+10
View File
@@ -0,0 +1,10 @@
header:
version: 8
includes:
- kas-security-base.yml
local_conf_header:
meta-security: |
DISTRO = "harden"
machine: qemux86
+10
View File
@@ -0,0 +1,10 @@
header:
version: 8
includes:
- kas-security-base.yml
local_conf_header:
musl: |
TCLIBC = "musl"
machine: qemux86
+6
View File
@@ -0,0 +1,6 @@
header:
version: 8
includes:
- kas-security-parsec.yml
machine: qemux86
+6
View File
@@ -0,0 +1,6 @@
header:
version: 8
includes:
- kas-security-base.yml
machine: qemux86
+6
View File
@@ -0,0 +1,6 @@
header:
version: 8
includes:
- kas-security-base.yml
machine: qemux86
@@ -0,0 +1,26 @@
# Copyright (C) 2022 Armin Kuster <akuster808@gmail.com>
#
import re
from oeqa.runtime.case import OERuntimeTestCase
from oeqa.core.decorator.depends import OETestDepends
from oeqa.runtime.decorator.package import OEHasPackage
class AideTest(OERuntimeTestCase):
@OEHasPackage(['aide'])
@OETestDepends(['ssh.SSHTest.test_ssh'])
def test_aide_help(self):
status, output = self.target.run('aide --help')
msg = ('Aide help command does not work as expected. '
'Status and output:%s and %s' % (status, output))
self.assertEqual(status, 0, msg = msg)
@OETestDepends(['aide.AideTest.test_aide_help'])
def test_aide_dbinit(self):
status, output = self.target.run('aide --init')
match = re.search('Number of entries:', output)
if not match:
msg = ('Aide db init failed: output is:\n%s' % output)
self.assertEqual(status, 0, msg = msg)
@@ -0,0 +1,46 @@
# Copyright (C) 2019 Armin Kuster <akuster808@gmail.com>
#
import re
from oeqa.runtime.case import OERuntimeTestCase
from oeqa.core.decorator.depends import OETestDepends
from oeqa.runtime.decorator.package import OEHasPackage
class ApparmorTest(OERuntimeTestCase):
@OEHasPackage(['apparmor'])
@OETestDepends(['ssh.SSHTest.test_ssh'])
def test_apparmor_help(self):
status, output = self.target.run('aa-status --help')
msg = ('apparmor command does not work as expected. '
'Status and output:%s and %s' % (status, output))
self.assertEqual(status, 0, msg = msg)
@OETestDepends(['apparmor.ApparmorTest.test_apparmor_help'])
def test_apparmor_aa_status(self):
status, output = self.target.run('aa-status')
match = re.search('apparmor module is loaded.', output)
if not match:
msg = ('aa-status failed. '
'Status and output:%s and %s' % (status, output))
self.assertEqual(status, 0, msg = msg)
@OETestDepends(['apparmor.ApparmorTest.test_apparmor_aa_status'])
def test_apparmor_aa_complain(self):
status, output = self.target.run('aa-complain /etc/apparmor.d/*')
match = re.search('apparmor module is loaded.', output)
if not match:
msg = ('aa-complain failed. '
'Status and output:%s and %s' % (status, output))
self.assertEqual(status, 0, msg = msg)
@OETestDepends(['apparmor.ApparmorTest.test_apparmor_aa_complain'])
def test_apparmor_aa_enforce(self):
status, output = self.target.run('aa-enforce /etc/apparmor.d/*')
match = re.search('apparmor module is loaded.', output)
if not match:
msg = ('aa-enforce failed. '
'Status and output:%s and %s' % (status, output))
self.assertEqual(status, 0, msg = msg)
@@ -0,0 +1,34 @@
# Copyright (C) 2019 Armin Kuster <akuster808@gmail.com>
#
import re
from oeqa.runtime.case import OERuntimeTestCase
from oeqa.core.decorator.depends import OETestDepends
from oeqa.runtime.decorator.package import OEHasPackage
class CheckSecTest(OERuntimeTestCase):
@OEHasPackage(['checksec'])
@OETestDepends(['ssh.SSHTest.test_ssh'])
def test_checksec_help(self):
status, output = self.target.run('checksec --help ')
msg = ('checksec command does not work as expected. '
'Status and output:%s and %s' % (status, output))
self.assertEqual(status, 0, msg = msg)
@OETestDepends(['checksec.CheckSecTest.test_checksec_help'])
def test_checksec_xml(self):
status, output = self.target.run('checksec --format=xml --proc=1')
msg = ('checksec xml failed. Output: %s' % output)
self.assertEqual(status, 0, msg = msg)
@OETestDepends(['checksec.CheckSecTest.test_checksec_xml'])
@OEHasPackage(['binutils'])
def test_checksec_fortify(self):
status, output = self.target.run('checksec --fortify-proc 1')
match = re.search('FORTIFY_SOURCE support:', output)
if not match:
msg = ('checksec : fortify-proc failed. '
'Status and output:%s and %s' % (status, output))
self.assertEqual(status, 1, msg = msg)
@@ -0,0 +1,55 @@
# Copyright (C) 2019 - 2022 Armin Kuster <akuster808@gmail.com>
#
import re
from tempfile import mkstemp
from oeqa.runtime.case import OERuntimeTestCase
from oeqa.core.decorator.depends import OETestDepends
from oeqa.runtime.decorator.package import OEHasPackage
class ClamavTest(OERuntimeTestCase):
@classmethod
def setUpClass(cls):
cls.tmp_fd, cls.tmp_path = mkstemp()
with os.fdopen(cls.tmp_fd, 'w') as f:
# use gooled public dns
f.write("nameserver 8.8.8.8")
f.write(os.linesep)
f.write("nameserver 8.8.4.4")
f.write(os.linesep)
f.write("nameserver 127.0.0.1")
f.write(os.linesep)
@classmethod
def tearDownClass(cls):
os.remove(cls.tmp_path)
@OEHasPackage(['clamav'])
@OETestDepends(['ssh.SSHTest.test_ssh'])
def test_freshclam_help(self):
status, output = self.target.run('freshclam --help ')
msg = ('freshclam --hlep command does not work as expected. ',
'Status and output:%s and %s' % (status, output))
self.assertEqual(status, 0, msg = msg)
@OETestDepends(['clamav.ClamavTest.test_freshclam_help'])
@OEHasPackage(['openssh-scp', 'dropbear'])
def test_ping_clamav_net(self):
dst = '/etc/resolv.conf'
self.tc.target.run('rm -f %s' % dst)
(status, output) = self.tc.target.copyTo(self.tmp_path, dst)
msg = 'File could not be copied. Output: %s' % output
self.assertEqual(status, 0, msg=msg)
status, output = self.target.run('ping -c 1 database.clamav.net')
msg = ('ping database.clamav.net failed: output is:\n%s' % output)
self.assertEqual(status, 0, msg = msg)
@OETestDepends(['clamav.ClamavTest.test_ping_clamav_net'])
def test_freshclam_download(self):
status, output = self.target.run('freshclam --show-progress')
msg = ('freshclam : DB dowbload failed. '
'Status and output:%s and %s' % (status, output))
self.assertEqual(status, 0, msg = msg)
@@ -0,0 +1,18 @@
# Copyright (C) 2022 Armin Kuster <akuster808@gmail.com>
#
import re
from oeqa.runtime.case import OERuntimeTestCase
from oeqa.core.decorator.depends import OETestDepends
from oeqa.runtime.decorator.package import OEHasPackage
class FirejailTest(OERuntimeTestCase):
@OEHasPackage(['firejail'])
@OEHasPackage(['libseccomp'])
@OETestDepends(['ssh.SSHTest.test_ssh'])
def test_firejail_basic(self):
status, output = self.target.run('firejail --help')
msg = ('Firejail --help command does not work as expected. '
'Status and output:%s and %s' % (status, output))
self.assertEqual(status, 0, msg = msg)
@@ -0,0 +1,43 @@
# Copyright (C) 2019 Armin Kuster <akuster808@gmail.com>
#
import re
import os
from oeqa.runtime.case import OERuntimeTestCase
from oeqa.core.decorator.depends import OETestDepends
from oeqa.runtime.decorator.package import OEHasPackage
class SamhainTest(OERuntimeTestCase):
@OEHasPackage(['samhain-standalone'])
@OETestDepends(['ssh.SSHTest.test_ssh'])
def test_samhain_help(self):
machine = self.td.get('MACHINE', '')
status, output = self.target.run('echo "127.0.0.1 %s.localdomain %s" >> /etc/hosts' % (machine, machine))
msg = ("samhain can't append hosts. "
'Status and output:%s and %s' % (status, output))
self.assertEqual(status, 0, msg = msg)
status, output = self.target.run('samhain --help')
msg = ('samhain command does not work as expected. '
'Status and output:%s and %s' % (status, output))
self.assertEqual(status, 0, msg = msg)
@OETestDepends(['samhain.SamhainTest.test_samhain_help'])
def test_samhain_init_db(self):
status, output = self.target.run('samhain -t init')
match = re.search('FAILED: 0 ', output)
if not match:
msg = ('samhain database init had an unexpected failure. '
'Status and output:%s and %s' % (status, output))
self.assertEqual(status, 0, msg = msg)
@OETestDepends(['samhain.SamhainTest.test_samhain_init_db'])
def test_samhain_db_check(self):
status, output = self.target.run('samhain -t check')
match = re.search('FAILED: 0 ', output)
if not match:
msg = ('samhain errors found in db. '
'Status and output:%s and %s' % (status, output))
self.assertEqual(status, 0, msg = msg)
@@ -0,0 +1,417 @@
import unittest
import re
import os
import string
from oeqa.runtime.case import OERuntimeTestCase
from oeqa.core.decorator.depends import OETestDepends
from oeqa.runtime.decorator.package import OEHasPackage
from oeqa.core.decorator.data import skipIfNotFeature
MAX_LABEL_LEN = 255
LABEL = "a" * MAX_LABEL_LEN
class SmackBasicTest(OERuntimeTestCase):
''' base smack test '''
@classmethod
def setUpClass(cls):
cls.current_label = ""
cls.uid = 1000
status, output = cls.tc.target.run("grep smack /proc/mounts | awk '{print $2}'")
cls.smack_path = output
@skipIfNotFeature('smack',
'Test requires smack to be in DISTRO_FEATURES')
@OEHasPackage(['smack-test'])
@OETestDepends(['ssh.SSHTest.test_ssh'])
def test_smack_basic(self):
status,output = self.target.run("cat /proc/self/attr/current")
self.current_label = output.strip()
@OETestDepends(['smack.SmackBasicTest.test_smack_basic'])
def test_add_access_label(self):
''' Test if chsmack can correctly set a SMACK label '''
filename = "/tmp/test_access_label"
self.target.run("touch %s" %filename)
status, output = self.target.run("chsmack -a %s %s" %(LABEL, filename))
self.assertEqual(
status, 0,
"Cannot set smack access label. "
"Status and output: %d %s" %(status, output))
status, output = self.target.run("chsmack %s" %filename)
self.target.run("rm %s" %filename)
m = re.search('(access=")\S+(?=")', output)
if m is None:
self.fail("Did not find access attribute")
else:
label_retrieved = re.split("access=\"", output)[1][:-1]
self.assertEqual(
LABEL, label_retrieved,
"label not set correctly. expected and gotten: "
"%s %s" %(LABEL,label_retrieved))
@OETestDepends(['smack.SmackBasicTest.test_smack_basic'])
def test_add_exec_label(self):
'''Test if chsmack can correctly set a SMACK Exec label'''
filename = "/tmp/test_exec_label"
self.target.run("touch %s" %filename)
status, output = self.target.run("chsmack -e %s %s" %(LABEL, filename))
self.assertEqual(
status, 0,
"Cannot set smack exec label. "
"Status and output: %d %s" %(status, output))
status, output = self.target.run("chsmack %s" %filename)
self.target.run("rm %s" %filename)
m= re.search('(execute=")\S+(?=")', output)
if m is None:
self.fail("Did not find execute attribute")
else:
label_retrieved = re.split("execute=\"", output)[1][:-1]
self.assertEqual(
LABEL, label_retrieved,
"label not set correctly. expected and gotten: " +
"%s %s" %(LABEL,label_retrieved))
@OETestDepends(['smack.SmackBasicTest.test_smack_basic'])
def test_add_mmap_label(self):
'''Test if chsmack can correctly set a SMACK mmap label'''
filename = "/tmp/test_exec_label"
self.target.run("touch %s" %filename)
status, output = self.target.run("chsmack -m %s %s" %(LABEL, filename))
self.assertEqual(
status, 0,
"Cannot set smack mmap label. "
"Status and output: %d %s" %(status, output))
status, output = self.target.run("chsmack %s" %filename)
self.target.run("rm %s" %filename)
m = re.search('(mmap=")\S+(?=")', output)
if m is None:
self.fail("Did not find mmap attribute")
else:
label_retrieved = re.split("mmap=\"", output)[1][:-1]
self.assertEqual(
LABEL, label_retrieved,
"label not set correctly. expected and gotten: " +
"%s %s" %(LABEL,label_retrieved))
@OETestDepends(['smack.SmackBasicTest.test_smack_basic'])
def test_add_transmutable(self):
'''Test if chsmack can correctly set a SMACK transmutable mode'''
directory = "~/test_transmutable"
self.target.run("mkdir -p %s" %directory)
status, output = self.target.run("chsmack -t %s" %directory)
self.assertEqual(status, 0, "Cannot set smack transmutable. "
"Status and output: %d %s" %(status, output))
status, output = self.target.run("chsmack %s" %directory)
self.target.run("rmdir %s" %directory)
m = re.search('(transmute=")\S+(?=")', output)
if m is None:
self.fail("Did not find transmute attribute")
else:
label_retrieved = re.split("transmute=\"", output)[1][:-1]
self.assertEqual(
"TRUE", label_retrieved,
"label not set correctly. expected and gotten: " +
"%s %s" %(LABEL,label_retrieved))
@OETestDepends(['smack.SmackBasicTest.test_smack_basic'])
def test_privileged_change_self_label(self):
'''Test if privileged process (with CAP_MAC_ADMIN privilege)
can change its label.
'''
labelf = "/proc/self/attr/current"
command = "/bin/sh -c 'echo PRIVILEGED >%s'; cat %s" %(labelf, labelf)
status, output = self.target.run(
"/usr/sbin/notroot.py 0 %s %s" %(self.current_label, command))
self.assertIn("PRIVILEGED", output,
"Privilege process did not change label.Output: %s" %output)
@OETestDepends(['smack.SmackBasicTest.test_smack_basic'])
def test_unprivileged_change_self_label(self):
'''Test if unprivileged process (without CAP_MAC_ADMIN privilege)
cannot change its label'''
command = "/bin/sh -c 'echo %s >/proc/self/attr/current'" %LABEL
status, output = self.target.run(
"/usr/sbin/notroot.py %d %s %s"
%(self.uid, self.current_label, command) +
" 2>&1 | grep 'Operation not permitted'" )
self.assertEqual(
status, 0,
"Unprivileged process should not be able to change its label")
@OETestDepends(['smack.SmackBasicTest.test_smack_basic'])
def test_unprivileged_change_file_label(self):
'''Test if unprivileged process cannot change file labels'''
status, chsmack = self.target.run("which chsmack")
status, touch = self.target.run("which touch")
filename = "/tmp/test_unprivileged_change_file_label"
self.target.run("touch %s" % filename)
self.target.run("/usr/sbin/notroot.py %d %s" %(self.uid, self.current_label))
status, output = self.target.run(
"/usr/sbin/notroot.py " +
"%d unprivileged %s -a %s %s 2>&1 " %(self.uid, chsmack, LABEL, filename) +
"| grep 'Operation not permitted'" )
self.target.run("rm %s" % filename)
self.assertEqual( status, 0, "Unprivileged process changed label for %s" %filename)
@OETestDepends(['smack.SmackBasicTest.test_smack_basic'])
def test_load_smack_rule(self):
'''Test if new smack access rules can be loaded'''
# old 23 character format requires special spaces formatting
# 12345678901234567890123456789012345678901234567890123
ruleA="TheOne TheOther rwxat"
ruleB="TheOne TheOther r----"
clean="TheOne TheOther -----"
modeA = "rwxat"
modeB = "r"
status, output = self.target.run('echo -n "%s" > %s/load' %(ruleA, self.smack_path))
status, output = self.target.run( 'cat %s/load | grep "^TheOne" | grep " TheOther "' %self.smack_path)
self.assertEqual(status, 0, "Rule A was not added")
mode = list(filter(bool, output.split(" ")))[2].strip()
self.assertEqual( mode, modeA, "Mode A was not set correctly; mode: %s" %mode)
status, output = self.target.run( 'echo -n "%s" > %s/load' %(ruleB, self.smack_path))
status, output = self.target.run( 'cat %s/load | grep "^TheOne" | grep " TheOther "' %self.smack_path)
mode = list(filter(bool, output.split(" ")))[2].strip()
self.assertEqual( mode, modeB, "Mode B was not set correctly; mode: %s" %mode)
self.target.run('echo -n "%s" > %s/load' %(clean, self.smack_path))
@OETestDepends(['smack.SmackBasicTest.test_smack_basic'])
def test_smack_onlycap(self):
'''Test if smack onlycap label can be set
test needs to change the running label of the current process,
so whole test takes places on image
'''
status, output = self.target.run("sh /usr/sbin/test_smack_onlycap.sh")
self.assertEqual(status, 0, output)
@OETestDepends(['smack.SmackBasicTest.test_smack_basic'])
def test_smack_netlabel(self):
test_label="191.191.191.191 TheOne"
expected_label="191.191.191.191/32 TheOne"
status, output = self.target.run( "echo -n '%s' > %s/netlabel" %(test_label, self.smack_path))
self.assertEqual( status, 0, "Netlabel /32 could not be set. Output: %s" %output)
status, output = self.target.run("cat %s/netlabel" %self.smack_path)
self.assertIn( expected_label, output, "Did not find expected label in output: %s" %output)
test_label="253.253.253.0/24 TheOther"
status, output = self.target.run( "echo -n '%s' > %s/netlabel" %(test_label, self.smack_path))
self.assertEqual( status, 0, "Netlabel /24 could not be set. Output: %s" %output)
status, output = self.target.run("cat %s/netlabel" %self.smack_path)
self.assertIn(
test_label, output,
"Did not find expected label in output: %s" %output)
@OETestDepends(['smack.SmackBasicTest.test_smack_basic'])
def test_smack_cipso(self):
'''Test if smack cipso rules can be set'''
# 12345678901234567890123456789012345678901234567890123456
ruleA="TheOneA 2 0 "
ruleB="TheOneB 3 1 55 "
ruleC="TheOneC 4 2 17 33 "
status, output = self.target.run(
"echo -n '%s' > %s/cipso" %(ruleA, self.smack_path))
self.assertEqual(status, 0,
"Could not set cipso label A. Ouput: %s" %output)
status, output = self.target.run(
"cat %s/cipso | grep '^TheOneA'" %self.smack_path)
self.assertEqual(status, 0, "Cipso rule A was not set")
self.assertIn(" 2", output, "Rule A was not set correctly")
status, output = self.target.run(
"echo -n '%s' > %s/cipso" %(ruleB, self.smack_path))
self.assertEqual(status, 0,
"Could not set cipso label B. Ouput: %s" %output)
status, output = self.target.run(
"cat %s/cipso | grep '^TheOneB'" %self.smack_path)
self.assertEqual(status, 0, "Cipso rule B was not set")
self.assertIn("/55", output, "Rule B was not set correctly")
status, output = self.target.run(
"echo -n '%s' > %s/cipso" %(ruleC, self.smack_path))
self.assertEqual(
status, 0,
"Could not set cipso label C. Ouput: %s" %output)
status, output = self.target.run(
"cat %s/cipso | grep '^TheOneC'" %self.smack_path)
self.assertEqual(status, 0, "Cipso rule C was not set")
self.assertIn("/17,33", output, "Rule C was not set correctly")
@OETestDepends(['smack.SmackBasicTest.test_smack_basic'])
def test_smack_direct(self):
status, initial_direct = self.target.run(
"cat %s/direct" %self.smack_path)
test_direct="17"
status, output = self.target.run(
"echo '%s' > %s/direct" %(test_direct, self.smack_path))
self.assertEqual(status, 0 ,
"Could not set smack direct. Output: %s" %output)
status, new_direct = self.target.run("cat %s/direct" %self.smack_path)
# initial label before checking
status, output = self.target.run(
"echo '%s' > %s/direct" %(initial_direct, self.smack_path))
self.assertEqual(
test_direct, new_direct.strip(),
"Smack direct label does not match.")
@OETestDepends(['smack.SmackBasicTest.test_smack_basic'])
def test_smack_ambient(self):
test_ambient = "test_ambient"
status, initial_ambient = self.target.run("cat %s/ambient" %self.smack_path)
status, output = self.target.run(
"echo '%s' > %s/ambient" %(test_ambient, self.smack_path))
self.assertEqual(status, 0,
"Could not set smack ambient. Output: %s" %output)
status, output = self.target.run("cat %s/ambient" %self.smack_path)
# Filter '\x00', which is sometimes added to the ambient label
new_ambient = ''.join(filter(lambda x: x in string.printable, output))
initial_ambient = ''.join(filter(lambda x: x in string.printable, initial_ambient))
status, output = self.target.run(
"echo '%s' > %s/ambient" %(initial_ambient, self.smack_path))
self.assertEqual(
test_ambient, new_ambient.strip(),
"Ambient label does not match")
@OETestDepends(['smack.SmackBasicTest.test_smack_basic'])
def test_smackload(self):
'''Test if smackload command works'''
rule="testobject testsubject rwx"
status, output = self.target.run("echo -n '%s' > /tmp/rules" %rule)
status, output = self.target.run("smackload /tmp/rules")
self.assertEqual( status, 0, "Smackload failed to load rule. Output: %s" %output)
status, output = self.target.run( "cat %s/load | grep '%s'" %(self.smack_path, rule))
self.assertEqual(status, 0, "Smackload rule was loaded correctly")
@OETestDepends(['smack.SmackBasicTest.test_smack_basic'])
def test_smackcipso(self):
'''Test if smackcipso command works'''
# 12345678901234567890123456789012345678901234567890123456
rule="cipsolabel 2 2 "
status, output = self.target.run("echo '%s' | smackcipso" %rule)
self.assertEqual( status, 0, "Smackcipso failed to load rule. Output: %s" %output)
status, output = self.target.run(
"cat %s/cipso | grep 'cipsolabel'" %self.smack_path)
self.assertEqual(status, 0, "smackcipso rule was loaded correctly")
self.assertIn( "2/2", output, "Rule was not set correctly. Got: %s" %output)
@OETestDepends(['smack.SmackBasicTest.test_smack_basic'])
def test_smack_enforce_file_access(self):
'''Test if smack file access is enforced (rwx)
test needs to change the running label of the current process,
so whole test takes places on image
'''
status, output = self.target.run("sh /usr/sbin/smack_test_file_access.sh")
self.assertEqual(status, 0, output)
@OETestDepends(['smack.SmackBasicTest.test_smack_basic'])
def test_smack_transmute_dir(self):
'''Test if smack transmute attribute works
test needs to change the running label of the current process,
so whole test takes places on image
'''
test_dir = "/tmp/smack_transmute_dir"
label="transmute_label"
status, initial_label = self.target.run("cat /proc/self/attr/current")
self.target.run("mkdir -p %s" % test_dir)
self.target.run("chsmack -a %s %s" % (label, test_dir))
self.target.run("chsmack -t %s" % test_dir)
self.target.run("echo -n '%s %s rwxat' | smackload" %(initial_label, label) )
self.target.run("touch %s/test" % test_dir)
status, output = self.target.run("chsmack %s/test" % test_dir)
self.assertIn( 'access="%s"' %label, output,
"Did not get expected label. Output: %s" % output)
@OETestDepends(['smack.SmackBasicTest.test_smack_basic'])
def test_smack_tcp_sockets(self):
'''Test if smack is enforced on tcp sockets
whole test takes places on image, depends on tcp_server/tcp_client'''
status, output = self.target.run("sh /usr/sbin/test_smack_tcp_sockets.sh")
self.assertEqual(status, 0, output)
@OETestDepends(['smack.SmackBasicTest.test_smack_basic'])
def test_smack_udp_sockets(self):
'''Test if smack is enforced on udp sockets
whole test takes places on image, depends on udp_server/udp_client'''
status, output = self.target.run("sh /usr/sbin/test_smack_udp_sockets.sh")
self.assertEqual(status, 0, output)
@OETestDepends(['smack.SmackBasicTest.test_smack_basic'])
def test_smack_labels(self):
'''Check for correct Smack labels.'''
expected = '''
/tmp/ access="*"
/etc/ access="System::Shared" transmute="TRUE"
/etc/passwd access="System::Shared"
/etc/terminfo access="System::Shared" transmute="TRUE"
/etc/skel/ access="System::Shared" transmute="TRUE"
/etc/skel/.profile access="System::Shared"
/var/log/ access="System::Log" transmute="TRUE"
/var/tmp/ access="*"
'''
files = ' '.join([x.split()[0] for x in expected.split('\n') if x])
files_wildcard = ' '.join([x + '/*' for x in files.split()])
# Auxiliary information.
status, output = self.target.run(
'set -x; mount; ls -l -d %s; find %s | xargs ls -d -l; find %s | xargs chsmack' % (
' '.join([x.rstrip('/') for x in files.split()]), files, files
)
)
msg = "File status:\n" + output
status, output = self.target.run('chsmack %s' % files)
self.assertEqual(
status, 0, msg="status and output: %s and %s\n%s" % (status,output, msg))
self.longMessage = True
self.maxDiff = None
self.assertEqual(output.strip().split('\n'), expected.strip().split('\n'), msg=msg)
@@ -0,0 +1,37 @@
# Copyright (C) 2019 Armin Kuster <akuster808@gmail.com>
#
import re
from oeqa.runtime.case import OERuntimeTestCase
from oeqa.core.decorator.depends import OETestDepends
from oeqa.runtime.decorator.package import OEHasPackage
class SSSDTest(OERuntimeTestCase):
@OEHasPackage(['sssd'])
@OETestDepends(['ssh.SSHTest.test_ssh'])
def test_sssd_help(self):
status, output = self.target.run('sssctl --help')
msg = ('sssctl command does not work as expected. '
'Status and output:%s and %s' % (status, output))
self.assertEqual(status, 1, msg = msg)
@OETestDepends(['sssd.SSSDTest.test_sssd_help'])
def test_sssd_sssctl_conf_perms_chk(self):
status, output = self.target.run('sssctl domain-status')
match = re.search('ConfDB initialization has failed', output)
if match:
msg = ('sssctl domain-status failed, check sssd.conf perms. '
'Status and output:%s and %s' % (status, output))
self.assertEqual(status, 0, msg = msg)
@OETestDepends(['sssd.SSSDTest.test_sssd_sssctl_conf_perms_chk'])
def test_sssd_sssctl_deamon(self):
status, output = self.target.run('sssctl domain-list')
match = re.search('No domains configured, fatal error!', output)
if match:
msg = ('sssctl domain-list failed, sssd.conf not setup correctly. '
'Status and output:%s and %s' % (status, output))
self.assertEqual(status, 0, msg = msg)
@@ -0,0 +1,76 @@
# Copyright (C) 2019 Armin Kuster <akuster808@gmail.com>
#
import re
from tempfile import mkstemp
from oeqa.runtime.case import OERuntimeTestCase
from oeqa.core.decorator.depends import OETestDepends
from oeqa.runtime.decorator.package import OEHasPackage
class SuricataTest(OERuntimeTestCase):
@classmethod
def setUpClass(cls):
cls.tmp_fd, cls.tmp_path = mkstemp()
with os.fdopen(cls.tmp_fd, 'w') as f:
# use google public dns
f.write("nameserver 8.8.8.8")
f.write(os.linesep)
f.write("nameserver 8.8.4.4")
f.write(os.linesep)
f.write("nameserver 127.0.0.1")
f.write(os.linesep)
@classmethod
def tearDownClass(cls):
os.remove(cls.tmp_path)
@OEHasPackage(['suricata'])
@OETestDepends(['ssh.SSHTest.test_ssh'])
def test_suricata_help(self):
status, output = self.target.run('suricata --help')
msg = ('suricata command does not work as expected. '
'Status and output:%s and %s' % (status, output))
self.assertEqual(status, 1, msg = msg)
@OETestDepends(['suricata.SuricataTest.test_suricata_help'])
def test_ping_openinfosecfoundation_org(self):
dst = '/etc/resolv.conf'
self.tc.target.run('rm -f %s' % dst)
(status, output) = self.tc.target.copyTo(self.tmp_path, dst)
msg = 'File could not be copied. Output: %s' % output
self.assertEqual(status, 0, msg=msg)
status, output = self.target.run('ping -c 1 openinfosecfoundation.org')
msg = ('ping openinfosecfoundation.org failed: output is:\n%s' % output)
self.assertEqual(status, 0, msg = msg)
@OEHasPackage(['python3-suricata-update'])
@OETestDepends(['suricata.SuricataTest.test_ping_openinfosecfoundation_org'])
def test_suricata_update(self):
status, output = self.tc.target.run('suricata-update')
msg = ('suricata-update had an unexpected failure. '
'Status and output:%s and %s' % (status, output))
self.assertEqual(status, 0, msg = msg)
@OETestDepends(['suricata.SuricataTest.test_suricata_update'])
def test_suricata_update_sources_list(self):
status, output = self.tc.target.run('suricata-update list-sources')
msg = ('suricata-update list-sources had an unexpected failure. '
'Status and output:%s and %s' % (status, output))
self.assertEqual(status, 0, msg = msg)
@OETestDepends(['suricata.SuricataTest.test_suricata_update_sources_list'])
def test_suricata_update_sources(self):
status, output = self.tc.target.run('suricata-update update-sources')
msg = ('suricata-update update-sources had an unexpected failure. '
'Status and output:%s and %s' % (status, output))
self.assertEqual(status, 0, msg = msg)
@OETestDepends(['suricata.SuricataTest.test_suricata_update_sources'])
def test_suricata_update_enable_source(self):
status, output = self.tc.target.run('suricata-update enable-source oisf/trafficid')
msg = ('suricata-update enable-source oisf/trafficid had an unexpected failure. '
'Status and output:%s and %s' % (status, output))
self.assertEqual(status, 0, msg = msg)
@@ -0,0 +1,47 @@
# Copyright (C) 2019 Armin Kuster <akuster808@gmail.com>
#
import re
from oeqa.runtime.case import OERuntimeTestCase
from oeqa.core.decorator.depends import OETestDepends
from oeqa.runtime.decorator.package import OEHasPackage
class TripwireTest(OERuntimeTestCase):
@OEHasPackage(['tripwire'])
@OETestDepends(['ssh.SSHTest.test_ssh'])
def test_tripwire_help(self):
status, output = self.target.run('tripwire --help')
msg = ('tripwire command does not work as expected. '
'Status and output:%s and %s' % (status, output))
self.assertEqual(status, 8, msg = msg)
@OETestDepends(['tripwire.TripwireTest.test_tripwire_help'])
def test_tripwire_twinstall(self):
status, output = self.target.run('/etc/tripwire/twinstall.sh')
match = re.search('The database was successfully generated.', output)
if not match:
msg = ('/etc/tripwire/twinstall.sh failed. '
'Status and output:%s and %s' % (status, output))
self.assertEqual(status, 0, msg = msg)
@OETestDepends(['tripwire.TripwireTest.test_tripwire_twinstall'])
def test_tripwire_twadmin(self):
status, output = self.target.run('twadmin --create-cfgfile --cfgfile /etc/tripwire/twcfg.enc --site-keyfile /etc/tripwire/site.key -Q tripwire /etc/tripwire/twcfg.txt')
status, output = self.target.run('twadmin --create-polfile --cfgfile /etc/tripwire/twcfg.enc --polfile /etc/tripwire/twpol.enc --site-keyfile /etc/tripwire/site.key -Q tripwire /etc/tripwire/twpol.txt')
match = re.search('Wrote policy file: /etc/tripwire/twpol.enc', output)
if not match:
msg = ('twadmin --create-profile ; failed. '
'Status and output:%s and %s' % (status, output))
self.assertEqual(status, 0, msg = msg)
@OETestDepends(['tripwire.TripwireTest.test_tripwire_twadmin'])
def test_tripwire_init(self):
status, hostname = self.target.run('hostname')
status, output = self.target.run('tripwire --init --cfgfile /etc/tripwire/twcfg.enc --polfile /etc/tripwire/tw.pol --site-keyfile /etc/tripwire/site.key --local-keyfile /etc/tripwire/%s-local.key -P tripwire' % hostname)
match = re.search('The database was successfully generated.', output)
if not match:
msg = ('tripwire --init; Failed for host: %s. '
'Status and output:%s and %s' % (hostname, status, output))
self.assertEqual(status, 0, msg = msg)
@@ -0,0 +1,27 @@
import os
import re
from oeqa.selftest.case import OESelftestTestCase
from oeqa.utils.commands import bitbake, get_bb_var
class CveCheckerTests(OESelftestTestCase):
def test_cve_checker(self):
image = "core-image-sato"
deploy_dir = get_bb_var("DEPLOY_DIR_IMAGE")
image_link_name = get_bb_var('IMAGE_LINK_NAME', image)
manifest_link = os.path.join(deploy_dir, "%s.cve" % image_link_name)
self.logger.info('CVE_CHECK_MANIFEST = "%s"' % manifest_link)
if (not 'cve-check' in get_bb_var('INHERIT')):
add_cve_check_config = 'INHERIT += "cve-check"'
self.append_config(add_cve_check_config)
self.append_config('CVE_CHECK_MANIFEST = "%s"' % manifest_link)
result = bitbake("-k -c cve_check %s" % image, ignore_status=True)
if (not 'cve-check' in get_bb_var('INHERIT')):
self.remove_config(add_cve_check_config)
isfile = os.path.isfile(manifest_link)
self.assertEqual(True, isfile, 'Failed to create cve data file : %s' % manifest_link)
+86
View File
@@ -0,0 +1,86 @@
# This is an example for Security hardening an OE or Poky image
Meta-hardening
=============
This layer provides examples for hardening OE/Yocto images.
This layer does not provide 100% security protection. This is only
a framework from which a user can build from and can possible contribute to.
The goal here is to capture use cases and examples the community decided shares for
everyones benefit.
Building the meta-hardening layer
-------------------------------
In order to add hardening support to the poky/OE build this layer should be added
to your projects bblayers.conf file.
By default the hardening components are disabled. This conforms to the
Yocto Project compatible guideline that indicate that simply including a
layer should not change the system behavior.
In order to use the components in this layer to take affect the 'harden' keyword must
set the DISTRO as in "DISTRO = harden". This enables the "NO ROOT access" idea or framework.
If one wants the a more complete example of a hardened image, one must also build the image:
harden-image-minimal
There are default example userid and passwards:
These can be over written in your local.conf via:
ROOT_DEFAULT_PASSWORD ?= "1SimplePw!"
DEFAULT_ADMIN_ACCOUNT ?= "myadmin"
example:
local.conf
DISTRO = "harden"
The default user and password are:
User: "myadmin"
Password: "1SimplePw!"
bitbake {qemu machine} harden-image-minimal
Dependencies
============
Branch: master
This layer depends on:
URI: git://git.yoctoproject.org/poky
or this normal combo:
URI: git://git.openembedded.org/meta-openembedded/meta-oe
URI: git://git.openembedded.org/bitbake
plus:
URI: git://git.openembedded.org/meta-openembedded
layers: meta-oe
Maintenance
-----------
Send pull requests, patches, comments or questions to yocto@lists.yoctoproject.org
When sending single patches, please using something like:
'git send-email -1 --to yocto@lists.yoctoproject.org --subject-prefix=meta-hardening][PATCH'
These values can be set as defaults for this repository:
$ git config sendemail.to yocto@lists.yoctoproject.org
$ git config format.subjectPrefix meta-hardening][PATCH
Now you can just do 'git send-email origin/master' to send all local patches.
Maintainers: Armin Kuster <akuster808@gmail.com>
License
=======
All metadata is MIT licensed unless otherwise stated. Source code included
in tree for individual recipes is under the LICENSE stated in each recipe
(.bb file) unless otherwise stated.
@@ -0,0 +1,11 @@
DISTRO = "harden"
DISTRO_NAME = "Simple Security hardening example"
DISTRO_VERSION = "1.0"
DISTRO_FEATURES = " acl xattr pci ext2 pam ipv4 ipv6 ipsec largefile usbhost"
VIRTUAL-RUNTIME_base-utils-syslog ?= "rsyslog"
IMAGE_ROOTFS_EXTRA_SPACE = "524288"
EXTRA_IMAGE_FEATURES:remove = "debug-tweaks"
DISABLE_ROOT ?= "True"
@@ -0,0 +1,13 @@
# We have a conf and classes directory, add to BBPATH
BBPATH .= ":${LAYERDIR}"
# We have a recipes directory, add to BBFILES
BBFILES += "${LAYERDIR}/recipes*/*/*.bb ${LAYERDIR}/recipes*/*/*.bbappend"
BBFILE_COLLECTIONS += "harden-layer"
BBFILE_PATTERN_harden-layer = "^${LAYERDIR}/"
BBFILE_PRIORITY_harden-layer = "6"
LAYERSERIES_COMPAT_harden-layer = "mickledore"
LAYERDEPENDS_harden-layer = "core openembedded-layer"
@@ -0,0 +1,13 @@
do_install:append:harden () {
# to hardend
sed -i -e 's:#AllowTcpForwarding yes:AllowTcpForwarding no:' ${D}${sysconfdir}/ssh/sshd_config
sed -i -e 's:ClientAliveCountMax 4:ClientAliveCountMax 2:' ${D}${sysconfdir}/ssh/sshd_config
sed -i -e 's:#LogLevel INFO:LogLevel VERBOSE:' ${D}${sysconfdir}/ssh/sshd_config
sed -i -e 's:#MaxSessions.*:MaxSessions 2:' ${D}${sysconfdir}/ssh/sshd_config
sed -i -e 's:#TCPKeepAlive yes:TCPKeepAlive no:' ${D}${sysconfdir}/ssh/sshd_config
sed -i -e 's:#AllowAgentForwarding yes:AllowAgentForwarding no:' ${D}${sysconfdir}/ssh/sshd_config
if [ "${@bb.utils.contains('DISABLE_ROOT', 'True', 'yes', 'no', d)}" = "yes" ]; then
sed -i -e 's:#PermitRootLogin.*:PermitRootLogin prohibit-password:' ${D}${sysconfdir}/ssh/sshd_config
fi
}
@@ -0,0 +1,4 @@
do_install:append:harden () {
sed -i 's/umask.*/umask 027/g' ${D}/${sysconfdir}/profile
}
@@ -0,0 +1,26 @@
SUMMARY = "A small image for an example hardening OE."
IMAGE_INSTALL = "packagegroup-core-boot packagegroup-hardening"
IMAGE_INSTALL:append = " os-release"
IMAGE_FEATURES = ""
IMAGE_LINGUAS = " "
LICENSE = "MIT"
IMAGE_ROOTFS_SIZE ?= "8192"
inherit core-image
IMAGE_CLASSES:append = " extrausers"
ROOT_DEFAULT_PASSWORD ?= "1SimplePw!"
DEFAULT_ADMIN_ACCOUNT ?= "myadmin"
DEFAULT_ADMIN_GROUP ?= "wheel"
DEFAULT_ADMIN_ACCOUNT_PASSWORD ?= "1SimplePw!"
EXTRA_USERS_PARAMS = "${@bb.utils.contains('DISABLE_ROOT', 'True', "usermod -L root;", "usermod -P '${ROOT_DEFAULT_PASSWORD}' root;", d)}"
EXTRA_USERS_PARAMS:append = " useradd ${DEFAULT_ADMIN_ACCOUNT};"
EXTRA_USERS_PARAMS:append = " groupadd ${DEFAULT_ADMIN_GROUP};"
EXTRA_USERS_PARAMS:append = " usermod -P '${DEFAULT_ADMIN_ACCOUNT_PASSWORD}' ${DEFAULT_ADMIN_ACCOUNT};"
EXTRA_USERS_PARAMS:append = " usermod -aG ${DEFAULT_ADMIN_GROUP} ${DEFAULT_ADMIN_ACCOUNT};"
@@ -0,0 +1,41 @@
#!/bin/sh
### BEGIN INIT INFO
# Provides: mountall
# Required-Start: mountvirtfs
# Required-Stop:
# Default-Start: S
# Default-Stop:
# Short-Description: Mount all filesystems.
# Description:
### END INIT INFO
. /etc/default/rcS
#
# Mount local filesystems in /etc/fstab. For some reason, people
# might want to mount "proc" several times, and mount -v complains
# about this. So we mount "proc" filesystems without -v.
#
test "$VERBOSE" != no && echo "Mounting local filesystems..."
mkdir -p /home
mkdir -p /var
mount -at nonfs,nosmbfs,noncpfs 2>/dev/null
#
# We might have mounted something over /dev, see if /dev/initctl is there.
#
if test ! -p /dev/initctl
then
rm -f /dev/initctl
mknod -m 600 /dev/initctl p
fi
kill -USR1 1
#
# Execute swapon command again, in case we want to swap to
# a file on a now mounted filesystem.
#
[ -x /sbin/swapon ] && swapon -a
: exit 0

Some files were not shown because too many files have changed in this diff Show More