42a8595256
giving access to functionality that is not available in capability mode sandbox. The functionality can be precisely restricted. Start with the following services: - system.dns - provides API compatible to: - gethostbyname(3), - gethostbyname2(3), - gethostbyaddr(3), - getaddrinfo(3), - getnameinfo(3), - system.grp - provides getgrent(3)-compatible API, - system.pwd - provides getpwent(3)-compatible API, - system.random - allows to obtain entropy from /dev/random, - system.sysctl - provides sysctlbyname(3-compatible API. Sponsored by: The FreeBSD Foundation
289 lines
7.3 KiB
Groff
289 lines
7.3 KiB
Groff
.\" Copyright (c) 2013 The FreeBSD Foundation
|
|
.\" All rights reserved.
|
|
.\"
|
|
.\" This documentation was written by Pawel Jakub Dawidek under sponsorship
|
|
.\" from the FreeBSD Foundation.
|
|
.\"
|
|
.\" Redistribution and use in source and binary forms, with or without
|
|
.\" modification, are permitted provided that the following conditions
|
|
.\" are met:
|
|
.\" 1. Redistributions of source code must retain the above copyright
|
|
.\" notice, this list of conditions and the following disclaimer.
|
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
|
.\" notice, this list of conditions and the following disclaimer in the
|
|
.\" documentation and/or other materials provided with the distribution.
|
|
.\"
|
|
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
|
|
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
|
|
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
.\" SUCH DAMAGE.
|
|
.\"
|
|
.\" $FreeBSD$
|
|
.\"
|
|
.Dd October 26, 2013
|
|
.Dt LIBCAPSICUM 3
|
|
.Os
|
|
.Sh NAME
|
|
.Nm cap_init ,
|
|
.Nm cap_wrap ,
|
|
.Nm cap_unwrap ,
|
|
.Nm cap_sock ,
|
|
.Nm cap_clone ,
|
|
.Nm cap_close ,
|
|
.Nm cap_limit_get ,
|
|
.Nm cap_limit_set ,
|
|
.Nm cap_send_nvlist ,
|
|
.Nm cap_recv_nvlist ,
|
|
.Nm cap_xfer_nvlist ,
|
|
.Nm cap_service_open
|
|
.Nd "library for handling application capabilities"
|
|
.Sh LIBRARY
|
|
.Lb libcapsicum
|
|
.Sh SYNOPSIS
|
|
.In libcapsicum.h
|
|
.In nv.h
|
|
.Ft "cap_channel_t *"
|
|
.Fn cap_init "void"
|
|
.Ft "cap_channel_t *"
|
|
.Fn cap_wrap "int sock"
|
|
.Ft "int"
|
|
.Fn cap_unwrap "cap_channel_t *chan"
|
|
.Ft "int"
|
|
.Fn cap_sock "const cap_channel_t *chan"
|
|
.Ft "cap_channel_t *"
|
|
.Fn cap_clone "const cap_channel_t *chan"
|
|
.Ft "void"
|
|
.Fn cap_close "cap_channel_t *chan"
|
|
.Ft "int"
|
|
.Fn cap_limit_get "const cap_channel_t *chan" "nvlist_t **limitsp"
|
|
.Ft "int"
|
|
.Fn cap_limit_set "const cap_channel_t *chan" "nvlist_t *limits"
|
|
.Ft "int"
|
|
.Fn cap_send_nvlist "const cap_channel_t *chan" "const nvlist_t *nvl"
|
|
.Ft "nvlist_t *"
|
|
.Fn cap_recv_nvlist "const cap_channel_t *chan"
|
|
.Ft "nvlist_t *"
|
|
.Fn cap_xfer_nvlist "const cap_channel_t *chan" "nvlist_t *nvl"
|
|
.In libcapsicum_service.h
|
|
.Ft "cap_channel_t *"
|
|
.Fn cap_service_open "const cap_channel_t *chan" "const char *name"
|
|
.Sh DESCRIPTION
|
|
The
|
|
.Nm libcapsicum
|
|
library allows to manage application capabilities through the
|
|
.Xr casperd 8
|
|
daemon.
|
|
.Pp
|
|
The application capability (represented by the
|
|
.Vt cap_channel_t
|
|
type) is a communication channel between the caller and the
|
|
.Xr casperd 8
|
|
daemon or an instance of one of its services.
|
|
A capability to the
|
|
.Xr casperd 8
|
|
daemon obtained with the
|
|
.Fn cap_init
|
|
function allows to create capabilities to casper's services via the
|
|
.Fn cap_service_open
|
|
function.
|
|
.Pp
|
|
The
|
|
.Fn cap_init
|
|
function opens capability to the
|
|
.Xr casperd 8
|
|
daemon.
|
|
.Pp
|
|
The
|
|
.Fn cap_wrap
|
|
function creates
|
|
.Vt cap_channel_t
|
|
based on the given socket.
|
|
The function is used when capability is inherited through
|
|
.Xr execve 2
|
|
or send over
|
|
.Xr unix 4
|
|
domain socket as a regular file descriptor and has to be represented as
|
|
.Vt cap_channel_t
|
|
again.
|
|
.Pp
|
|
The
|
|
.Fn cap_unwrap
|
|
function is the opposite of the
|
|
.Fn cap_wrap
|
|
function.
|
|
It frees the
|
|
.Vt cap_channel_t
|
|
structure and returns
|
|
.Xr unix 4
|
|
domain socket associated with it.
|
|
.Pp
|
|
The
|
|
.Fn cap_clone
|
|
function clones the given capability.
|
|
.Pp
|
|
The
|
|
.Fn cap_close
|
|
function closes the given capability.
|
|
.Pp
|
|
The
|
|
.Fn cap_sock
|
|
function returns
|
|
.Xr unix 4
|
|
domain socket descriptor associated with the given capability for use with
|
|
system calls like
|
|
.Xr kevent 2 ,
|
|
.Xr poll 2
|
|
and
|
|
.Xr select 2 .
|
|
.Pp
|
|
The
|
|
.Fn cap_limit_get
|
|
function stores current limits of the given capability in the
|
|
.Fa limitsp
|
|
argument.
|
|
If the function return
|
|
.Va 0
|
|
and
|
|
.Dv NULL
|
|
is stored in
|
|
.Fa limitsp
|
|
it means there are no limits set.
|
|
.Pp
|
|
The
|
|
.Fn cap_limit_set
|
|
function sets limits for the given capability.
|
|
The limits are provided as nvlist.
|
|
The exact format depends on the service the capability represents.
|
|
.Pp
|
|
The
|
|
.Fn cap_send_nvlist
|
|
function sends the given nvlist over the given capability.
|
|
This is low level interface to communicate with casper services.
|
|
Most services should provide higher level API.
|
|
.Pp
|
|
The
|
|
.Fn cap_recv_nvlist
|
|
function receives the given nvlist over the given capability.
|
|
.Pp
|
|
The
|
|
.Fn cap_xfer_nvlist
|
|
function sends the given nvlist, destroys it and receives new nvlist in
|
|
response over the given capability.
|
|
It does not matter if the function succeeds or fails, the nvlist given
|
|
for sending will always be destroyed once the function returns.
|
|
.Pp
|
|
The
|
|
.Fn cap_service_open
|
|
function opens casper service of the given name through casper capability
|
|
obtained via the
|
|
.Fn cap_init
|
|
function.
|
|
The function returns capability that provides access to opened service.
|
|
.Sh RETURN VALUES
|
|
The
|
|
.Fn cap_clone ,
|
|
.Fn cap_init ,
|
|
.Fn cap_recv_nvlist ,
|
|
.Fn cap_service_open ,
|
|
.Fn cap_wrap
|
|
and
|
|
.Fn cap_xfer_nvlist
|
|
functions return
|
|
.Dv NULL
|
|
and set the
|
|
.Va errno
|
|
variable on failure.
|
|
.Pp
|
|
The
|
|
.Fn cap_limit_get ,
|
|
.Fn cap_limit_set
|
|
and
|
|
.Fn cap_send_nvlist
|
|
functions return
|
|
.Dv -1
|
|
and set the
|
|
.Va errno
|
|
variable on failure.
|
|
.Pp
|
|
The
|
|
.Fn cap_close ,
|
|
.Fn cap_sock
|
|
and
|
|
.Fn cap_unwrap
|
|
functions always succeed.
|
|
.Sh EXAMPLES
|
|
The following example first opens capability to the
|
|
.Xr casperd 8
|
|
daemon, then using this capability creates new capability to the
|
|
.Nm system.dns
|
|
casper service and uses the latter capability to resolve IP address.
|
|
.Bd -literal
|
|
cap_channel_t *capcas, *capdns;
|
|
nvlist_t *limits;
|
|
const char *ipstr = "127.0.0.1";
|
|
struct in_addr ip;
|
|
struct hostent *hp;
|
|
|
|
/* Open capability to the Casper daemon. */
|
|
capcas = cap_init();
|
|
if (capcas == NULL)
|
|
err(1, "Unable to contact Casper daemon");
|
|
|
|
/* Enter capability mode sandbox. */
|
|
if (cap_enter() < 0 && errno != ENOSYS)
|
|
err(1, "Unable to enter capability mode");
|
|
|
|
/* Use Casper capability to create capability to the system.dns service. */
|
|
capdns = cap_service_open(capcas, "system.dns");
|
|
if (capdns == NULL)
|
|
err(1, "Unable to open system.dns service");
|
|
|
|
/* Close Casper capability, we don't need it anymore. */
|
|
cap_close(capcas);
|
|
|
|
/* Limit system.dns to reverse DNS lookups and IPv4 addresses. */
|
|
limits = nvlist_create(0);
|
|
nvlist_add_string(limits, "type", "ADDR");
|
|
nvlist_add_number(limits, "family", (uint64_t)AF_INET);
|
|
if (cap_limit_set(capdns, limits) < 0)
|
|
err("Unable to limit access to the system.dns service");
|
|
|
|
/* Convert IP address in C-string to in_addr. */
|
|
if (!inet_aton(ipstr, &ip))
|
|
errx(1, "Unable to parse IP address %s.", ipstr);
|
|
|
|
/* Find hostname for the given IP address. */
|
|
hp = cap_gethostbyaddr(capdns, (const void *)&ip, sizeof(ip), AF_INET);
|
|
if (hp == NULL)
|
|
errx(1, "No name associated with %s.", ipstr);
|
|
|
|
printf("Name associated with %s is %s.\\n", ipstr, hp->h_name);
|
|
.Ed
|
|
.Sh SEE ALSO
|
|
.Xr cap_enter 2 ,
|
|
.Xr execve 2 ,
|
|
.Xr kevent 2 ,
|
|
.Xr poll 2 ,
|
|
.Xr select 2 ,
|
|
.Xr cap_gethostbyaddr 3 ,
|
|
.Xr err 3 ,
|
|
.Xr gethostbyaddr 3 ,
|
|
.Xr inet_aton 3 ,
|
|
.Xr nv 3 ,
|
|
.Xr capsicum 4 ,
|
|
.Xr unix 4 ,
|
|
.Xr casperd 8
|
|
.Sh AUTHORS
|
|
The
|
|
.Nm libcapsicum
|
|
library was implemented by
|
|
.An Pawel Jakub Dawidek Aq pawel@dawidek.net
|
|
under sponsorship from the FreeBSD Foundation.
|