CMake conversion

This commit is contained in:
Mattia Biondi 2020-01-08 11:19:54 +01:00
parent b781a2286c
commit 28e4c7054d
42 changed files with 275 additions and 329 deletions

35
CMakeLists.txt Normal file
View File

@ -0,0 +1,35 @@
cmake_minimum_required(VERSION 3.13)
project(cado
VERSION 0.9.2
DESCRIPTION "Capability Ambient DO. Provide users just the capabilities they need."
HOMEPAGE_URL "https://github.com/rd235/cado"
LANGUAGES C)
include(GNUInstallDirs)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -pedantic")
set(LIBS_REQUIRED cap execs mhash pam pam_misc)
foreach(THISLIB IN LISTS LIBS_REQUIRED)
find_library(${THISLIB}_library ${THISLIB})
if(NOT ${THISLIB}_library)
message(FATAL_ERROR "library lib${THISLIB} not found")
endif()
endforeach(THISLIB)
if (WITHEDITOR)
set(EDITOR "${WITHEDITOR}")
else (WITHEDITOR)
set(EDITOR "/usr/bin/vi")
endif (WITHEDITOR)
configure_file(
"${PROJECT_SOURCE_DIR}/include/config.h.in"
"${PROJECT_SOURCE_DIR}/include/config.h"
)
add_subdirectory(man)
add_subdirectory(src)
add_custom_target(uninstall
"${CMAKE_COMMAND}" -P "${PROJECT_SOURCE_DIR}/Uninstall.cmake")

View File

@ -1,50 +0,0 @@
bin_PROGRAMS = cado cadrop scado caprint
cado_SOURCES = cado.c pam_check.c get_user_groups.c capset_from_namelist.c read_conf.c set_ambient_cap.c \
compute_digest.c file_utils.c scado_parse.c cado_scado_check.c
cado_LDADD = -lpam -lpam_misc -lcap -lmhash
cadrop_SOURCES = cadrop.c capset_from_namelist.c set_ambient_cap.c
cadrop_LDADD = -lcap
caprint_LDADD = -lcap
scado_SOURCES = scado.c pam_check.c file_utils.c compute_digest.c capset_from_namelist.c scado_parse.c
scado_LDADD = -lpam -lpam_misc -lcap -lmhash
common_nodist = cado_paths.h
BUILT_SOURCES = $(common_nodist)
man_MANS = cado.1 cadrop.1 caprint.1 scado.1 cado.conf.5
install-exec-hook:
(useradd -r -s /bin/nologin -g `getent passwd | grep cado | cut -f 3 -d ':'` cado ||\
useradd -r -s /bin/nologin -U cado) || true
(mkdir -p ${SPOOL_DIR} ; chown root:cado ${SPOOL_DIR} && chmod 4770 $(SPOOL_DIR))
chown :cado $(DESTDIR)$(bindir)/scado
chmod g+s $(DESTDIR)$(bindir)/scado
chown cado $(DESTDIR)$(bindir)/cado
chmod u+s $(DESTDIR)$(bindir)/cado
ldconfig $(DESTDIR)$(libdir)
$(DESTDIR)$(bindir)/cado -s
CLEANFILES = cado_paths.h
cado_paths.h: Makefile
@echo 'creating $@'
@sed >$@ 's/ *\\$$//' <<\END #\
/* This file has been automatically generated. Do not edit. */ \
#ifndef _CADO_PATHS_H \
#define _CADO_PATHS_H \
\
/* Spool directory path */ \
#define SPOOL_DIR "$(SPOOL_DIR)" \
\
/* Cado temporary exe directory path */ \
#define CADO_EXE_DIR "$(CADO_EXE_DIR)" \
\
#endif /* _SCADO_PATHS_H */\
END

11
PostInstall.cmake Normal file
View File

@ -0,0 +1,11 @@
execute_process(COMMAND bash "-c"
"(useradd -r -s /bin/nologin -g `getent passwd | grep cado | cut -f 3 -d ':'` cado || useradd -r -s /bin/nologin -U cado) || true;\
mkdir -p /usr/local/var/spool/cado;\
chown root:cado /usr/local/var/spool/cado && chmod 4770 /usr/local/var/spool/cado;\
chown :cado ${BINDIR}/scado;\
chmod g+s ${BINDIR}/scado;\
chown cado ${BINDIR}/cado;\
chmod u+s ${BINDIR}/cado;\
ldconfig ${LIBDIR};\
${BINDIR}/cado -s"
)

194
README
View File

@ -1,194 +0,0 @@
introducing CADO: Capability DO.
Cado permits to delegate capabilities to users.
Cado is a capability based sudo. Sudo allows authorized users to run programs
as root (or as another user), cado allows authorized users to run programs with
specific (ambient) capabilities.
Cado is more selective than sudo, users can be authorized to have only specific capabilities (and not others).
INSTALL:
get the source code, from the root of the source tree run:
$ autoreconf -if
$ ./configure
$ make
$ sudo make install
It installs two programs in /usr/local/bin: cado and caprint.
If you want to install the programs in /usr/bin run "./configure --prefix=/usr" instead of "./configure".
Cado needs a configuration file: /etc/cado.conf with the following syntax:
* lines beginning with # are comments
* all the other lines have two fields separated by :, the first field is a capability or a list of
capabilities, the second field is a list of users or groups (group names have @ as a prefix).
Capabilities can be written with or without the cap_ prefix (net_admin means cap_net_admin).
Example of /etc/cado.conf file:
---------------------------------------------
# Capability Ambient DO configuration file
# cado.conf
net_admin: @netadmin,renzo
cap_kill: renzo
--------------------------------------------
The file above allows the user renzo and all the members of the group named netadmin to run programs
neeeding the cap_net_admin capability.
The user renzo can also run programs requiring cap_kill.
The file /etc/cado.conf can be owned by root and have no rw permission for users.
It is also possible to use lists of capabilities:
setgid,setuid: giovanni
or exadecimal masks:
c0: giovanni,@idgroup
$ ls -l /etc/cado.conf
-rw------- 1 root root 100 Jun 19 17:11 /etc/cado.conf
IMPORTANT.
Cado has been designed to work using the minimum set of capability required for its services.
(following the principle of least privilege).
Cado itself is not a seuid executable, it uses the capability mechanism and it has an options to
set its own capabilities. So after each change in the /etc/cado.conf, the capability set should be
recomputed using the following command:
$ sudo cado -s
or
$ sudo cado -sv
(this latter command is verbose and shows the set of capabilties assigned to the capo executable file).
using the example configuration file above, capo would be assigned the following capabilities:
$ sudo cado -sv
Capability needed by cado:
2 0000000000000004 cap_dac_read_search
5 0000000000000020 cap_kill
12 0000000000001000 cap_net_admin
0000000000001024
$ /sbin/getcap /usr/local/bin/cado
/usr/local/bin/cado = cap_dac_read_search,cap_kill,cap_net_admin+p
-----------------------------------------------------------------
The syntax of cado is simple:
$ cado [options] set_of_capabilities command [args]
for example if the user renzo wants to run a shell having the cap_net_admin capability enabled he can type
the following command:
$ cado net_admin bash
Password:
$
the user will be requested to authenticate himself. If the user has the right to enable cap_net_admin (from the
cado.conf configuration file) and he typed in the correct password, cado starts a new shell with the requested
capability enabled.
It is possible define the set_of_capabilities using a list of capabilities (with or without the cap_prefix)
or exadecimal masks.
In the new shell the user can do all the operations permitted by the enabled capabilities,
in this case, for example, he will be allowed to change the networking configuration, add tuntap
interfaces and so on.
It is possible to show the ambient capability set of a program by reading the /proc/####/status file:
e.g.:
$ grep CapAmb /proc/$$/status
CapAmb: 0000000000001000
(cap_net_admin is the capability #12, the mask is 0x1000, i.e. 1ULL << 12)
-----------------------------------------------------------------
caprint is a simple program which shows the ambient capabilities of a running program.
(a pid of a running process can be specified as an optional parameter, otherwise it shows the capabilities
of caprint itself)
$ caprint
cap_net_admin
$ caprint -l
12 0000000000001000 cap_net_admin
There is an option -p that has been designed to add the current set of ambient capabilities to the shell prompt,
so it is easier for the user to recognize when a shell has some "extra power", so to avoid errors.
In .bashrc or .bash_profile (or in their system-side counterparts in /etc) it is possible to set rules like
the followings:
-----------
if which caprint >&/dev/null ; then
ambient=$(caprint -p)
fi
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$$ambient '
-----------
The prompt becomes something like:
renzo@host:~$net_admin#
-------------------------------------------------------------------
Some secondary features:
The -v feature shows the set of available capabilities:
$ cado -v
Allowed ambient capabilities:
5 0000000000000020 cap_kill
12 0000000000001000 cap_net_admin
0000000000001020
$ cado -v net_admin,kill bash
Allowed ambient capabilities:
5 0000000000000020 cap_kill
12 0000000000001000 cap_net_admin
0000000000001020
Requested ambient capabilities:
5 0000000000000020 cap_kill
12 0000000000001000 cap_net_admin
0000000000001020
Password:
It is useful to show which capability/ies cannot be granted:
$ cado net_admin,kill,setuid bash
cado: Permission denied
$ cado -v net_admin,kill,setuid bash
Allowed ambient capabilities:
5 0000000000000020 cap_kill
12 0000000000001000 cap_net_admin
0000000000001020
Requested ambient capabilities:
5 0000000000000020 cap_kill
7 0000000000000080 cap_setuid
12 0000000000001000 cap_net_admin
00000000000010a0
Unavailable ambient capabilities:
7 0000000000000080 cap_setuid
cado: Permission denied
It is possible to enable only the capability allowed by setting the -q option
(with or without -v). Using -q cado does not fail.
$ cado -qv net_admin,kill,setuid bash
Allowed ambient capabilities:
5 0000000000000020 cap_kill
12 0000000000001000 cap_net_admin
0000000000001020
Requested ambient capabilities:
5 0000000000000020 cap_kill
7 0000000000000080 cap_setuid
12 0000000000001000 cap_net_admin
00000000000010a0
Unavailable ambient capabilities:
7 0000000000000080 cap_setuid
Password:
Granted ambient capabilities:
5 0000000000000020 cap_kill
12 0000000000001000 cap_net_admin
0000000000001020
renzo@eipi:~/tests/cado/pre$kill,net_admin#

View File

@ -9,18 +9,21 @@ specific (ambient) capabilities.
Cado is more selective than sudo, users can be authorized to have only specific capabilities (and not others).
INSTALL:
## Install
get the source code, from the root of the source tree run:
```
$ autoreconf -if
$ ./configure
$ mkdir build
$ cd build
$ cmake ..
$ make
$ sudo make install
```
It installs two programs in /usr/local/bin: cado and caprint.
If you want to install the programs in /usr/bin run "./configure --prefix=/usr" instead of "./configure".
If you want to install the programs in /usr/bin run "cmake .. -DCMAKE_INSTALL_PREFIX:PATH=/usr" instead of "cmake ..".
## Configuration
Cado needs a configuration file: /etc/cado.conf with the following syntax:
- lines beginning with # are comments
@ -53,7 +56,7 @@ or exadecimal masks:
c0: giovanni,@idgroup
```
IMPORTANT.
## IMPORTANT
Cado has been designed to work using the minimum set of capability required for its services.
(following the principle of least privilege).
```
@ -83,9 +86,9 @@ Capability needed by cado:
0000000000001024
$ /sbin/getcap /usr/local/bin/cado
/usr/local/bin/cado = cap_dac_read_search,cap_kill,cap_net_admin+p
```
---
```
## How to use
The syntax of cado is simple:
```
$ cado [options] set_of_capabilities command [args]
@ -98,7 +101,7 @@ $ cado net_admin bash
Password:
$
```
the user will be requested to authenticate himself. If the user has the right to enable cap_net_admin (from the
cado.conf configuration file) and he typed in the correct password, cado starts a new shell with the requested
capability enabled.
@ -119,7 +122,7 @@ CapAmb: 0000000000001000
(cap_net_admin is the capability #12, the mask is 0x1000, i.e. 1ULL << 12)
---
## caprint
caprint is a simple program which shows the ambient capabilities of a running program.
(a pid of a running process can be specified as an optional parameter, otherwise it shows the capabilities
@ -132,7 +135,7 @@ cap_net_admin
$ caprint -l
12 0000000000001000 cap_net_admin
```
There is an option -p that has been designed to add the current set of ambient capabilities to the shell prompt,
so it is easier for the user to recognize when a shell has some "extra power", so to avoid errors.
@ -162,7 +165,7 @@ Allowed ambient capabilities:
5 0000000000000020 cap_kill
12 0000000000001000 cap_net_admin
0000000000001020
$ cado -v net_admin,kill bash
Allowed ambient capabilities:
5 0000000000000020 cap_kill
@ -174,12 +177,12 @@ Requested ambient capabilities:
0000000000001020
Password:
```
It is useful to show which capability/ies cannot be granted:
```
$ cado net_admin,kill,setuid bash
cado: Permission denied
$ cado -v net_admin,kill,setuid bash
Allowed ambient capabilities:
5 0000000000000020 cap_kill
@ -215,4 +218,4 @@ Granted ambient capabilities:
12 0000000000001000 cap_net_admin
0000000000001020
renzo@host:~/tests/cado/pre$kill,net_admin#
```
```

41
Uninstall.cmake Normal file
View File

@ -0,0 +1,41 @@
set(MANIFEST "${CMAKE_CURRENT_BINARY_DIR}/install_manifest.txt")
if(NOT EXISTS ${MANIFEST})
message(FATAL_ERROR "Cannot find install manifest: '${MANIFEST}'")
endif()
file(STRINGS ${MANIFEST} files)
foreach(file ${files})
if(EXISTS ${file})
message(STATUS "Removing file: '${file}'")
execute_process(
COMMAND bash "-c" "rm ${file}"
OUTPUT_VARIABLE remove_file
)
if(${remove_file})
message(FATAL_ERROR "Failed to remove file: '${file}'.")
endif()
else()
MESSAGE(STATUS "File '${file}' does not exist.")
endif()
endforeach(file)
message(STATUS "Removing user: 'cado'")
execute_process(
COMMAND bash "-c" "userdel cado"
OUTPUT_VARIABLE remove_user
)
if(${remove_user})
message(FATAL_ERROR "Failed to remove user: 'cado'.")
endif()
message(STATUS "Removing folder: '/usr/local/var/spool/cado'")
execute_process(
COMMAND bash "-c" "rm -r /usr/local/var/spool/cado"
OUTPUT_VARIABLE remove_spool_folder
)
if("${remove_spool_folder}")
message(FATAL_ERROR "Failed to remove folder: '/usr/local/var/spool/cado'.")
endif()

View File

@ -1,71 +0,0 @@
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.69])
AC_INIT([cado], [0.9.2], [info@v2.cs.unibo.it])
AM_INIT_AUTOMAKE([foreign dist-bzip2])
AC_CONFIG_SRCDIR([pam_check.h])
AC_CONFIG_HEADERS([config.h])
CFLAGS="$CFLAGS -Wall"
# Checks for programs.
AC_PROG_CC
AC_PROG_INSTALL
# Checks for libraries.
AC_CHECK_LIB([execs], [s2argv], [],
[
AC_MSG_ERROR([Could not find execs library (https://github.com/rd235/s2argv-execs)])
])
AC_CHECK_LIB([mhash], [mhash_init], [],
[
AC_MSG_ERROR([Could not find mhash library.])
])
# Checks for header files.
AC_CHECK_HEADERS([fcntl.h stdint.h stdlib.h string.h unistd.h])
AC_CHECK_HEADERS([sys/capability.h],
[],
[AC_MSG_ERROR([missing libcap header])])
AC_CHECK_HEADERS([security/pam_appl.h security/pam_misc.h],
[],
[AC_MSG_ERROR([missing PAM headers])])
AC_CHECK_HEADERS([execs.h],
[],
[AC_MSG_ERROR([missing execs headers])])
AC_CHECK_HEADERS([mhash.h],
[],
[AC_MSG_ERROR([missing mhash headers])])
# Checks for typedefs, structures, and compiler characteristics.
AC_TYPE_UID_T
AC_TYPE_PID_T
AC_TYPE_SSIZE_T
AC_TYPE_UINT64_T
# Checks for library functions.
AC_CHECK_FUNCS([strdup strtoull])
AC_DEFUN([CADO_CONF_VAR],
[AC_ARG_VAR([$1], [$2 @<:@$3@:>@])
if test "$$1" = ""; then
$1='$3'
fi
])
AC_ARG_WITH([editor],
[AC_HELP_STRING([--with-editor=EDITOR], [path to default editor])],
[editor_defined="$with-editor"],
[editor_defined="no"])
AS_IF([test "x$editor_defined" = "xno"], [
AC_PATH_PROG([editor_defined], [vi], [/usr/bin/vi])
])
AC_DEFINE_UNQUOTED([EDITOR], ["$editor_defined"], [default editor])
# Set the paths.
CADO_CONF_VAR([SPOOL_DIR], [the directory where all the user scado files reside],[${localstatedir}/spool/cado])
CADO_CONF_VAR([CADO_EXE_DIR], [the directory where all the temporary executable files reside],[/tmp])
AC_OUTPUT([Makefile])

84
include/config.h.in Normal file
View File

@ -0,0 +1,84 @@
/* default editor */
#cmakedefine EDITOR "/usr/bin/vi"
/* Define to 1 if you have the <execs.h> header file. */
#cmakedefine HAVE_EXECS_H 1
/* Define to 1 if you have the <fcntl.h> header file. */
#cmakedefine HAVE_FCNTL_H 1
/* Define to 1 if you have the `execs' library (-lexecs). */
#cmakedefine HAVE_LIBEXECS 1
/* Define to 1 if you have the `mhash' library (-lmhash). */
#cmakedefine HAVE_LIBMHASH 1
/* Define to 1 if you have the <mhash.h> header file. */
#cmakedefine HAVE_MHASH_H 1
/* Define to 1 if you have the <security/pam_appl.h> header file. */
#cmakedefine HAVE_SECURITY_PAM_APPL_H 1
/* Define to 1 if you have the <security/pam_misc.h> header file. */
#cmakedefine HAVE_SECURITY_PAM_MISC_H 1
/* Define to 1 if you have the <stdint.h> header file. */
#cmakedefine HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#cmakedefine HAVE_STDLIB_H 1
/* Define to 1 if you have the `strdup' function. */
#cmakedefine HAVE_STRDUP 1
/* Define to 1 if you have the <string.h> header file. */
#cmakedefine HAVE_STRING_H 1
/* Define to 1 if you have the `strtoull' function. */
#cmakedefine HAVE_STRTOULL 1
/* Define to 1 if you have the <sys/capability.h> header file. */
#cmakedefine HAVE_SYS_CAPABILITY_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#cmakedefine HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#cmakedefine HAVE_UNISTD_H 1
/* Name of package */
#cmakedefine PACKAGE "cado"
/* Define to the address where bug reports for this package should be sent. */
#cmakedefine PACKAGE_BUGREPORT "info@v2.cs.unibo.it"
/* Define to the full name of this package. */
#cmakedefine PACKAGE_NAME "cado"
/* Define to the full name and version of this package. */
#cmakedefine PACKAGE_STRING "cado 0.9.2"
/* Define to the one symbol short name of this package. */
#cmakedefine PACKAGE_TARNAME "cado"
/* Define to the version of this package. */
#cmakedefine PACKAGE_VERSION "0.9.2"
/* Version number of package */
#cmakedefine VERSION "0.9.2"
/* Define to `int' if <sys/types.h> doesn't define. */
#cmakedefine gid_t
/* Define to `int' if <sys/types.h> does not define. */
#cmakedefine pid_t
/* Define to `int' if <sys/types.h> does not define. */
#cmakedefine ssize_t
/* Define to `int' if <sys/types.h> doesn't define. */
#cmakedefine uid_t
/* Define to the type of an unsigned integer type of width exactly 64 bits if
such a type exists and the standard includes do not define it. */
#cmakedefine uint64_t

27
man/CMakeLists.txt Normal file
View File

@ -0,0 +1,27 @@
cmake_minimum_required(VERSION 3.13)
set(RONN_ORGANIZATION "VirtualSquare")
set(RONN_ARGS --organization=${RONN_ORGANIZATION})
# #ronn pages
file(GLOB VU_RONN_PAGES ${CMAKE_CURRENT_SOURCE_DIR}/*.[1-8].ronn)
set(VU_MAN_FILES)
foreach(VU_RONN_PATH IN LISTS VU_RONN_PAGES)
# VU_RONNPAGE: basename of VU_RONN_PATH
get_filename_component(VU_RONNPAGE ${VU_RONN_PATH} NAME)
# VU_MANPAGE: VU_RONNPAGE without the suffix
string(REGEX REPLACE "\.ronn$" "" VU_MANPAGE ${VU_RONNPAGE})
list(APPEND VU_MAN_FILES ${VU_MANPAGE})
endforeach(VU_RONN_PATH)
add_custom_target(${PROJECT_NAME}_manpages ALL make RONN_ARGS="${RONN_ARGS}" ${VU_MAN_FILES}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
### man pages
file(GLOB VU_MAN_PAGES ${CMAKE_CURRENT_SOURCE_DIR}/*.[1-8])
foreach(VU_MAN_PATH IN LISTS VU_MAN_PAGES)
get_filename_component(VU_MANPAGE ${VU_MAN_PATH} NAME)
string(REGEX REPLACE ".*\\." "" MAN_CHAPTER ${VU_MANPAGE})
install(FILES ${VU_MAN_PATH} DESTINATION ${CMAKE_INSTALL_MANDIR}/man${MAN_CHAPTER})
endforeach(VU_MAN_PATH)

16
man/Makefile Normal file
View File

@ -0,0 +1,16 @@
RONN=ronn
RONNOK := $(shell command -v ${RONN} 2> /dev/null)
none:
% : %.ronn
ifdef RONNOK
# copy copyright notice
grep "^\.\\\\\"" $< > $@ || true
# run ronn
$(RONN) -r ${RONN_ARGS} --pipe $< >> $@
# delete useless trailing "" in .TH
sed -i '/^\.TH /s/ ""$$//' $@
else
echo "${RONN} is not available. Manpage $@ cannot be updated" >/dev/stderr >&2
endif

View File

44
src/CMakeLists.txt Normal file
View File

@ -0,0 +1,44 @@
cmake_minimum_required(VERSION 3.13)
add_executable(
cado cado.c pam_check.c get_user_groups.c capset_from_namelist.c
read_conf.c set_ambient_cap.c compute_digest.c file_utils.c
scado_parse.c cado_scado_check.c
)
target_include_directories(cado PRIVATE ${PROJECT_SOURCE_DIR}/include)
target_link_libraries(
cado ${pam_library} ${pam_misc_library} ${cap_library} ${mhash_library}
${execs_library})
add_executable(cadrop cadrop.c capset_from_namelist.c set_ambient_cap.c)
target_include_directories(cadrop PRIVATE ${PROJECT_SOURCE_DIR}/include)
target_link_libraries(cadrop ${cap_library})
add_executable(
scado scado.c pam_check.c file_utils.c compute_digest.c
capset_from_namelist.c scado_parse.c
)
target_include_directories(scado PRIVATE ${PROJECT_SOURCE_DIR}/include)
target_link_libraries(
scado ${pam_library} ${pam_misc_library} ${cap_library} ${mhash_library}
${execs_library}
)
add_executable(caprint caprint.c)
target_include_directories(caprint PRIVATE ${PROJECT_SOURCE_DIR}/include)
target_link_libraries(caprint ${cap_library})
install(
TARGETS cado cadrop scado caprint
RUNTIME
DESTINATION ${CMAKE_INSTALL_BINDIR}
)
install(
CODE "execute_process(
COMMAND ${CMAKE_COMMAND}
-DBINDIR=${CMAKE_INSTALL_FULL_BINDIR}
-DLIBDIR=${CMAKE_INSTALL_FULL_LIBDIR}
-P ${PROJECT_SOURCE_DIR}/PostInstall.cmake
)"
)

View File