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 November 15, 2021 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 86The functions 87.Fn cap_bind , 88.Fn cap_connect , 89.Fn cap_gethostbyname , 90.Fn cap_gethostbyname2 , 91.Fn cap_gethostbyaddr 92and 93.Fn cap_getnameinfo 94provide a set of APIs equivalent to 95.Xr bind 2 , 96.Xr connect 2 , 97.Xr gethostbyname 3 , 98.Xr gethostbyname2 3 , 99.Xr gethostbyaddr 3 100and 101.Xr getnameinfo 3 102except that a connection to the 103.Nm system.net 104service needs to be provided. 105.Sh LIMITS 106By default, the cap_net capability provides unrestricted access to the network 107namespace. 108Applications typically only require access to a small portion of the network 109namespace: 110The 111.Fn cap_net_limit 112function can be used to restrict access to the network. 113The 114.Fn cap_net_limit_init 115returns an opaque limit handle used to store a list of capabilities. 116The 117.Fv mode 118restricts the functionality of the service. 119Modes are encoded using the following flags: 120.Pp 121.Bd -literal -offset indent -compact 122CAPNET_ADDR2NAME reverse DNS lookups are allowed with 123 cap_getnameinfo 124CAPNET_NAME2ADDR name resolution is allowed with 125 cap_getaddrinfo 126CAPNET_DEPRECATED_ADDR2NAME reverse DNS lookups are allowed with 127 cap_gethostbyaddr 128CAPNET_DEPRECATED_NAME2ADDR name resolution is allowed with 129 cap_gethostbyname and cap_gethostbyname2 130CAPNET_BIND bind syscall is allowed 131CAPNET_CONNECT connect syscall is allowed 132CAPNET_CONNECTDNS connect syscall is allowed to the values 133 returned from privies call to 134 the cap_getaddrinfo or cap_gethostbyname 135.Ed 136.Pp 137.Fn cap_net_limit_addr2name_family 138limits the 139.Fn cap_getnameinfo 140and 141.Fn cap_gethostbyaddr 142to do reverse DNS lookups to specific family (AF_INET, AF_INET6, etc.) 143.Pp 144.Fn cap_net_limit_addr2name 145limits the 146.Fn cap_getnameinfo 147and 148.Fn cap_gethostbyaddr 149to do reverse DNS lookups only on those specific structures. 150.Pp 151.Fn cap_net_limit_name2addr_family 152limits the 153.Fn cap_getaddrinfo , 154.Fn cap_gethostbyname 155and 156.Fn cap_gethostbyname2 157to do the name resolution on specific family (AF_INET, AF_INET6, etc.) 158.Pp 159.Fn cap_net_limit_addr2name 160restricts 161.Fn cap_getaddrinfo , 162.Fn cap_gethostbyname 163and 164.Fn cap_gethostbyname2 165to a set of domains. 166.Pp 167.Fn cap_net_limit_bind 168limits 169.Fn cap_bind 170to bind only on those specific structures. 171.Pp 172.Fn cap_net_limit_connect 173limits 174.Fn cap_connect 175to connect only on those specific structures. 176If the CAPNET_CONNECTDNS is set the limits are extended to the values returned 177by 178.Fn cap_getaddrinfo , 179.Fn cap_gethostbyname 180and 181.Fn cap_gethostbyname2 182In case of the 183.Fn cap_getaddrinfo 184the restriction is strict. 185In case of the 186.Fn cap_gethostbyname 187and 188.Fn cap_gethostbyname2 189any port will be accepted in the 190.Fn cap_connect 191function. 192.Pp 193.Fn cap_net_limit 194applies a set of sysctl limits to the capability, denying access to sysctl 195variables not belonging to the set. 196.Pp 197Once a set of limits is applied, subsequent calls to 198.Fn cap_net_limit 199will fail unless the new set is a subset of the current set. 200.Pp 201The 202.Fn cap_net_limit 203will consume the limits. 204If the 205.Fn cap_net_limit 206was not called the rights may be freed using 207.Fn cap_net_free . 208Multiple calls to 209.Fn cap_net_limit_addr2name_family , 210.Fn cap_net_limit_addr2name , 211.Fn cap_net_limit_name2addr_family , 212.Fn cap_net_limit_name2addr , 213.Fn cap_net_limit_connect , 214and 215.Fn cap_net_limit_bind 216is supported, each call is extending preview capabilities. 217.Sh EXAMPLES 218The following example first opens a capability to casper and then uses this 219capability to create the 220.Nm system.net 221casper service and uses it to resolve a host and connect to it. 222.Bd -literal 223cap_channel_t *capcas, *capnet; 224cap_net_limit_t *limit; 225int familylimit, error, s; 226const char *host = "example.com"; 227struct addrinfo hints, *res; 228 229/* Open capability to Casper. */ 230capcas = cap_init(); 231if (capcas == NULL) 232 err(1, "Unable to contact Casper"); 233 234/* Cache NLA for gai_strerror. */ 235caph_cache_catpages(); 236 237/* Enter capability mode sandbox. */ 238if (caph_enter_casper() < 0) 239 err(1, "Unable to enter capability mode"); 240 241/* Use Casper capability to create capability to the system.net service. */ 242capnet = cap_service_open(capcas, "system.net"); 243if (capnet == NULL) 244 err(1, "Unable to open system.net service"); 245 246/* Close Casper capability. */ 247cap_close(capcas); 248 249/* Limit system.net to reserve IPv4 addresses, to host example.com . */ 250limit = cap_net_limit_init(capnet, CAPNET_NAME2ADDR | CAPNET_CONNECTDNS); 251if (limit == NULL) 252 err(1, "Unable to create limits."); 253cap_net_limit_name2addr(limit, host, "80"); 254familylimit = AF_INET; 255cap_net_limit_name2addr_family(limit, &familylimit, 1); 256if (cap_net_limit(limit) < 0) 257 err(1, "Unable to apply limits."); 258 259/* Find IP addresses for the given host. */ 260memset(&hints, 0, sizeof(hints)); 261hints.ai_family = AF_INET; 262hints.ai_socktype = SOCK_STREAM; 263 264error = cap_getaddrinfo(capnet, host, "80", &hints, &res); 265if (error != 0) 266 errx(1, "cap_getaddrinfo(): %s: %s", host, gai_strerror(error)); 267 268s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); 269if (s < 0) 270 err(1, "Unable to create socket"); 271 272if (cap_connect(capnet, s, res->ai_addr, res->ai_addrlen) < 0) 273 err(1, "Unable to connect to host"); 274.Ed 275.Sh SEE ALSO 276.Xr bind 2 , 277.Xr cap_enter 2 , 278.Xr connect 2 , 279.Xr caph_enter 3 , 280.Xr err 3 , 281.Xr gethostbyaddr 3 , 282.Xr gethostbyname 3 , 283.Xr gethostbyname2 3 , 284.Xr getnameinfo 3 , 285.Xr capsicum 4 , 286.Xr nv 9 287.Sh AUTHORS 288.An Mariusz Zaborski Aq Mt oshogbo@FreeBSD.org 289