1.\" Copyright (c) 2020 Mariusz Zaborski <oshogbo@FreeBSD.org> 2.\" 3.\" Redistribution and use in source and binary forms, with or without 4.\" modification, are permitted provided that the following conditions 5.\" are met: 6.\" 1. Redistributions of source code must retain the above copyright 7.\" notice, this list of conditions and the following disclaimer. 8.\" 2. Redistributions in binary form must reproduce the above copyright 9.\" notice, this list of conditions and the following disclaimer in the 10.\" documentation and/or other materials provided with the distribution. 11.\" 12.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 13.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 14.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 15.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 16.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 17.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 18.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 19.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 20.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 21.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 22.\" SUCH DAMAGE. 23.\" 24.\" $FreeBSD$ 25.\" 26.Dd August 15, 2020 27.Dt CAP_NET 3 28.Os 29.Sh NAME 30.Nm cap_bind , 31.Nm cap_connect , 32.Nm cap_getaddrinfo , 33.Nm cap_gethostbyaddr , 34.Nm cap_gethostbyname , 35.Nm cap_gethostbyname2 , 36.Nm cap_getnameinfo , 37.Nm cap_net_free , 38.Nm cap_net_limit , 39.Nm cap_net_limit_addr2name , 40.Nm cap_net_limit_addr2name_family , 41.Nm cap_net_limit_bind , 42.Nm cap_net_limit_connect , 43.Nm cap_net_limit_init , 44.Nm cap_net_limit_name2addr , 45.Nm cap_net_limit_name2addr_family , 46.Nd "library for networking in capability mode" 47.Sh LIBRARY 48.Lb libcap_net 49.Sh SYNOPSIS 50.In sys/nv.h 51.In libcasper.h 52.In casper/cap_net.h 53.Ft int 54.Fn cap_bind "cap_channel_t *chan" "int s" "const struct sockaddr *addr" "socklen_t addrlen" 55.Ft int 56.Fn cap_connect "cap_channel_t *chan" "int s" "const struct sockaddr *name" "socklen_t namelen" 57.Ft int 58.Fn cap_getaddrinfo "cap_channel_t *chan" "const char *hostname" "const char *servname" "const struct addrinfo *hints" "struct addrinfo **res" 59.Ft int 60.Fn cap_getnameinfo "cap_channel_t *chan" "const struct sockaddr *sa" "socklen_t salen" "char *host" "size_t hostlen" "char *serv" "size_t servlen" "int flags" 61.Ft "struct hostent *" 62.Fn cap_gethostbyname "const cap_channel_t *chan" "const char *name" 63.Ft "struct hostent *" 64.Fn cap_gethostbyname2 "const cap_channel_t *chan" "const char *name" "int af" 65.Ft "struct hostent *" 66.Fn cap_gethostbyaddr "const cap_channel_t *chan" "const void *addr" "socklen_t len" "int af" 67.Ft "cap_net_limit_t *" 68.Fn cap_net_limit_init "cap_channel_t *chan" "uint64_t mode" 69.Ft int 70.Fn cap_net_limit "cap_net_limit_t *limit" 71.Ft void 72.Fn cap_net_free "cap_net_limit_t *limit" 73.Ft "cap_net_limit_t *" 74.Fn cap_net_limit_addr2name_family "cap_net_limit_t *limit" "int *family" "size_t size" 75.Ft "cap_net_limit_t *" 76.Fn cap_net_limit_addr2name "cap_net_limit_t *limit" "const struct sockaddr *sa" "socklen_t salen" 77.Ft "cap_net_limit_t *" 78.Fn cap_net_limit_name2addr_family "cap_net_limit_t *limit" "int *family" "size_t size" 79.Ft "cap_net_limit_t *" 80.Fn cap_net_limit_name2addr "cap_net_limit_t *limit" "const char *name" "const char *serv" 81.Ft "cap_net_limit_t *" 82.Fn cap_net_limit_connect "cap_net_limit_t *limit" "const struct sockaddr *sa" "socklen_t salen" 83.Ft "cap_net_limit_t *" 84.Fn cap_net_limit_bind "cap_net_limit_t *limit" "const struct sockaddr *sa" "socklen_t salen" 85.Sh DESCRIPTION 86.Pp 87The functions 88.Fn cap_bind, 89.Fn cap_connect, 90.Fn cap_gethostbyname , 91.Fn cap_gethostbyname2 , 92.Fn cap_gethostbyaddr 93and 94.Fn cap_getnameinfo 95are respectively equivalent to 96.Xr bind 2 , 97.Xr connect 2 , 98.Xr gethostbyname 3 , 99.Xr gethostbyname2 3 , 100.Xr gethostbyaddr 3 101and 102.Xr getnameinfo 3 103except that the connection to the 104.Nm system.net 105service needs to be provided. 106.Sh LIMITS 107By default, the cap_net capability provides unrestricted access to the network 108namespace. 109Applications typically only require access to a small portion of the network 110namespace: 111.Fn cap_net_limit 112interface can be used to restrict access to the network. 113.Fn cap_net_limit_init 114returns an opaque limit handle used to store a list of capabilities. 115The 116.Fv mode 117restricts the functionality of the service. 118Modes are encoded using the following flags: 119.Pp 120.Bd -literal -offset indent -compact 121CAPNET_ADDR2NAME reverse DNS lookups are allowed with 122 cap_getnameinfo 123CAPNET_NAME2ADDR name resolution is allowed with 124 cap_getaddrinfo 125CAPNET_DEPRECATED_ADDR2NAME reverse DNS lookups are allowed with 126 cap_gethostbyaddr 127CAPNET_DEPRECATED_NAME2ADDR name resolution is allowed with 128 cap_gethostbyname and cap_gethostbyname2 129CAPNET_BIND bind syscall is allowed 130CAPNET_CONNECT connect syscall is allowed 131CAPNET_CONNECTDNS connect syscall is allowed to the values 132 returned from privies call to 133 the cap_getaddrinfo or cap_gethostbyname 134.Ed 135.Pp 136.Fn cap_net_limit_addr2name_family 137limits the 138.Fn cap_getnameinfo 139and 140.Fn cap_gethostbyaddr 141to do reverse DNS lookups to specific family (AF_INET, AF_INET6, etc.) 142.Pp 143.Fn cap_net_limit_addr2name 144limits the 145.Fn cap_getnameinfo 146and 147.Fn cap_gethostbyaddr 148to do reverse DNS lookups only on those specific structures. 149.Pp 150.Fn cap_net_limit_name2addr_family 151limits the 152.Fn cap_getaddrinfo , 153.Fn cap_gethostbyname 154and 155.Fn cap_gethostbyname2 156to do the name resolution on specific family (AF_INET, AF_INET6, etc.) 157.Pp 158.Fn cap_net_limit_addr2name 159restricts 160.Fn cap_getaddrinfo , 161.Fn cap_gethostbyname 162and 163.Fn cap_gethostbyname2 164to a set of domains. 165.Pp 166.Fn cap_net_limit_bind 167limits 168.Fn cap_bind 169to bind only on those specific structures. 170.Pp 171.Fn cap_net_limit_connect 172limits 173.Fn cap_connect 174to connect only on those specific structures. 175If the CAPNET_CONNECTDNS is set the limits are extended to the values returned 176by 177.Fn cap_getaddrinfo , 178.Fn cap_gethostbyname 179and 180.Fn cap_gethostbyname2 181In case of the 182.Fn cap_getaddrinfo 183the restriction is strict. 184In case of the 185.Fn cap_gethostbyname 186and 187.Fn cap_gethostbyname2 188any port will be accepted in the 189.Fn cap_connect 190function. 191.Pp 192.Fn cap_net_limit 193applies a set of sysctl limits to the capability, denying access to sysctl 194variables not belonging to the set. 195.Pp 196Once a set of limits is applied, subsequent calls to 197.Fn cap_net_limit 198will fail unless the new set is a subset of the current set. 199.Pp 200The 201.Fn cap_net_limit 202will consume the limits. 203If the 204.Fn cap_net_limit 205was not called the rights may be freed using 206.Fn cap_net_free . 207Multiple calls to 208.Fn cap_net_limit_addr2name_family , 209.Fn cap_net_limit_addr2name , 210.Fn cap_net_limit_name2addr_family , 211.Fn cap_net_limit_name2addr , 212.Fn cap_net_limit_connect , 213and 214.Fn cap_net_limit_bind 215is supported, each call is extending preview capabilities. 216.Sh EXAMPLES 217The following example first opens a capability to casper and then uses this 218capability to create the 219.Nm system.net 220casper service and uses it to resolve a host and connect to it. 221.Bd -literal 222cap_channel_t *capcas, *capnet; 223cap_net_limit_t *limit; 224int familylimit, error, s; 225const char *host = "example.com"; 226struct addrinfo hints, *res; 227 228/* Open capability to Casper. */ 229capcas = cap_init(); 230if (capcas == NULL) 231 err(1, "Unable to contact Casper"); 232 233/* Cache NLA for gai_strerror. */ 234caph_cache_catpages(); 235 236/* Enter capability mode sandbox. */ 237if (caph_enter_casper() < 0) 238 err(1, "Unable to enter capability mode"); 239 240/* Use Casper capability to create capability to the system.net service. */ 241capnet = cap_service_open(capcas, "system.net"); 242if (capnet == NULL) 243 err(1, "Unable to open system.net service"); 244 245/* Close Casper capability. */ 246cap_close(capcas); 247 248/* Limit system.net to reserve IPv4 addresses, to host example.com . */ 249limit = cap_net_limit_init(capnet, CAPNET_NAME2ADDR | CAPNET_CONNECTDNS); 250if (limit == NULL) 251 err(1, "Unable to create limits."); 252cap_net_limit_name2addr(limit, host, "80"); 253familylimit = AF_INET; 254cap_net_limit_name2addr_family(limit, &familylimit, 1); 255if (cap_net_limit(limit) < 0) 256 err(1, "Unable to apply limits."); 257 258/* Find IP addresses for the given host. */ 259memset(&hints, 0, sizeof(hints)); 260hints.ai_family = AF_INET; 261hints.ai_socktype = SOCK_STREAM; 262 263error = cap_getaddrinfo(capnet, host, "80", &hints, &res); 264if (error != 0) 265 errx(1, "cap_getaddrinfo(): %s: %s", host, gai_strerror(error)); 266 267s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); 268if (s < 0) 269 err(1, "Unable to create socket"); 270 271if (cap_connect(capnet, s, res->ai_addr, res->ai_addrlen) < 0) 272 err(1, "Unable to connect to host"); 273.Ed 274.Sh SEE ALSO 275.Xr bind 2 , 276.Xr cap_enter 2 , 277.Xr connect 2 , 278.Xr caph_enter 3 , 279.Xr err 3 , 280.Xr gethostbyaddr 3 , 281.Xr gethostbyname 3 , 282.Xr gethostbyname2 3 , 283.Xr getnameinfo 3 , 284.Xr capsicum 4 , 285.Xr nv 9 286.Sh AUTHORS 287.An Mariusz Zaborski Aq Mt oshogbo@FreeBSD.org 288